X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vrfileman;a=blobdiff_plain;f=src%2Ffs.cc;h=c7df966e18a5dd6fc6d5f6ebe6c84565549f60e4;hp=b8f7420d75717af9be87e221e6e3360b8043fec1;hb=5e07bfd4d034dc3d974c8db008c6446e62838d39;hpb=f6a327e85904bea1ab1ae49ccd521de3a372b68b diff --git a/src/fs.cc b/src/fs.cc index b8f7420..c7df966 100644 --- a/src/fs.cc +++ b/src/fs.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,9 @@ #include "opengl.h" #include "app.h" #include "drawtext.h" +#include "sdr.h" + +static void draw_node_name(FSNode *node, float angle, float ypos, float dist, bool full); static IconRenderer *iconrend; @@ -22,21 +26,57 @@ static int start_child; static dtx_font *fat_font; #define FAT_FONT_SZ 32 +static unsigned int glow_link_sdr; +static unsigned int chrome_font_sdr, glow_font_sdr; -bool init_fs() +bool init_fs(const char *path) { iconrend = new ShapesIcons; if(!iconrend->init()) { return false; } - if(!(fat_font = dtx_open_font("data/fat.font", FAT_FONT_SZ))) { - fprintf(stderr, "failed to open font file data/fat.font\n"); + if(!(fat_font = dtx_open_font_glyphmap("data/fat.glyphmap")) || + dtx_get_glyphmap_ptsize(dtx_get_glyphmap(fat_font, 0)) != FAT_FONT_SZ) { + + dtx_set(DTX_PADDING, 64); + + if(!(fat_font = dtx_open_font("data/fat.font", 0))) { + fprintf(stderr, "failed to open font file data/fat.font\n"); + return false; + } + dtx_prepare_range(fat_font, FAT_FONT_SZ * 8, 32, 127); + dtx_calc_font_distfield(fat_font, 1, 8); + dtx_save_glyphmap("data/fat.glyphmap", dtx_get_glyphmap(fat_font, 0)); + } + dtx_use_font(fat_font, FAT_FONT_SZ); + + struct dtx_glyphmap *fat_gmap = dtx_get_glyphmap(fat_font, 0); + Vec2 pixsz; + pixsz.x = 1.0 / dtx_get_glyphmap_width(fat_gmap); + pixsz.y = 1.0 / dtx_get_glyphmap_height(fat_gmap); + + if(!(chrome_font_sdr = create_program_load("sdr/chrome_font.v.glsl", "sdr/chrome_font.p.glsl"))) { + return false; + } + set_uniform_float(chrome_font_sdr, "height", dtx_line_height()); + set_uniform_float(chrome_font_sdr, "smoothness", 0.01); + set_uniform_float2(chrome_font_sdr, "pix_sz", pixsz.x, pixsz.y); + + if(!(glow_font_sdr = create_program_load("sdr/dfont.v.glsl", "sdr/glow_font.p.glsl"))) { return false; } + set_uniform_float(glow_font_sdr, "smoothness", 0.01); + set_uniform_float2(glow_font_sdr, "pix_sz", pixsz.x, pixsz.y); - cur_node = get_fsnode(0); + if(!(glow_link_sdr = create_program_load("sdr/glink.v.glsl", "sdr/glink.p.glsl"))) { + return false; + } + + if(!(cur_node = get_fsnode(path))) { + return false; + } cur_node->expand(); return true; } @@ -49,47 +89,125 @@ void cleanup_fs() delete node; } node_cache.clear(); + dtx_close_font(fat_font); delete iconrend; } -static Vec3 icon_pos(int row, int col, int ncols, float row_spacing, float radius) +static float icon_angle(int col, int ncols, float max_angle = 0.0f) { - float angle = 2.0 * M_PI * (float)col / (float)ncols; - float x = sin(angle) * radius; - float z = -cos(angle) * radius; - float y = (float)row * row_spacing; - return Vec3(x, y, z); + if(max_angle > 0) { + return max_angle * ((float)col / (float)(ncols - 1) - 0.5); + } + return 2.0 * M_PI * (float)col / (float)ncols; } void draw_fs() { - static const int ncols = 8; - static const float row_spacing = 2.0; - static const float radius = 5; + static const float row_spacing = 0.25; + static const float radius = 0.6; + static const float umax = 0.42; + static const float max_icon_angle = M_PI * 2.0 * umax; - Mat4 base_xform; - base_xform.rotate(time_sec, 0, 0); - base_xform.rotate(0, 0, time_sec * 0.5); - base_xform.translate(0, 2, 0); + int max_ncols = std::max(1, umax * 12); + + glPushMatrix(); + glTranslatef(0, cam_height, 0); + + Mat4 rot_xform; + rot_xform.rotate(time_sec, 0, 0); + rot_xform.rotate(0, 0, time_sec * 0.5); - glUseProgram(0); glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - int first = start_child % ncols; int nchildren = (int)cur_node->children.size(); + int ncols = std::min(cur_node->nfiles, max_ncols); + + int first = start_child % ncols; int col = 0, row = 0; + int num_dirs = 0; + // count directories ... + for(int i=0; ichildren[i]; + if(node->type == FSTYPE_DIR) { + ++num_dirs; + } + } + + // draw the directory link lines + glUseProgram(glow_link_sdr); + set_uniform_float(glow_link_sdr, "tsec", time_sec); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + for(int i=0; ichildren[i]; + + if(node->type != FSTYPE_DIR) { + continue; + } + + float angle = (float)col++ / (float)(num_dirs - 1) * max_icon_angle - max_icon_angle * 0.5; + + Mat4 xform; + xform.rotate_y(angle); + xform.translate(0, -0.3, 0); + + glPushMatrix(); + glMultMatrixf(xform[0]); + glDepthMask(0); + + set_uniform_float(glow_link_sdr, "phase", col * 42.0); + + glBegin(GL_QUADS); + glColor3f(0.2, 0.3, 0.8); + glTexCoord2f(0, 0); + glVertex3f(-0.2, 0, 0.05); + glTexCoord2f(1, 0); + glVertex3f(0.2, 0, 0.05); + glTexCoord2f(1, 1); + glVertex3f(0.2, 0, -5.0); + glTexCoord2f(0, 1); + glVertex3f(-0.2, 0, -5.0); + glColor3f(1, 1, 1); + glEnd(); + glPopMatrix(); + + glDepthMask(1); + } + + // draw the directory labels + glUseProgram(glow_font_sdr); + col = 0; + for(int i=0; ichildren[i]; + + if(node->type != FSTYPE_DIR) { + continue; + } + + float angle = (float)col++ / (float)(num_dirs - 1) * max_icon_angle - max_icon_angle * 0.5; + + draw_node_name(node, angle, -0.3, radius, false); + } + + // then draw file icons + glDisable(GL_BLEND); + glUseProgram(0); + col = 0; for(int i=0; ichildren[idx]; if(node->type == FSTYPE_DIR) { + ++num_dirs; continue; } - float angle = -2.0 * M_PI * (float)col / (float)ncols; + float angle = icon_angle(col, ncols, max_icon_angle); - Mat4 xform = base_xform; + Mat4 xform = rot_xform; xform.translate(0, row * row_spacing, -radius); xform.rotate_y(angle); @@ -98,24 +216,67 @@ void draw_fs() iconrend->draw(node); glPopMatrix(); - glPushMatrix(); - xform = Mat4::identity; - xform.translate(-dtx_string_width(node->path.get_name()) / 2.0, 0, 0); - xform.scale(0.01); - xform.translate(0, 1 + row * row_spacing, -radius); - xform.rotate_y(angle); - glMultMatrixf(xform[0]); + if(++col >= ncols) { + col = 0; + ++row; + } + } - dtx_string(node->path.get_name()); - glPopMatrix(); + // then draw the file labels + glUseProgram(chrome_font_sdr); + col = 0; + row = 0; + for(int i=0; ichildren[idx]; + + if(node->type == FSTYPE_DIR) { + ++num_dirs; + continue; + } + + float angle = icon_angle(col, ncols, max_icon_angle); + + draw_node_name(node, angle, row * row_spacing - 0.1, radius, false); if(++col >= ncols) { col = 0; ++row; } } + + glPopMatrix(); +} + +static void draw_node_name(FSNode *node, float angle, float ypos, float dist, bool full) +{ + dtx_use_font(fat_font, FAT_FONT_SZ); + int line_height = dtx_line_height(); + + int nlines = full ? node->name_lines.size() : 1; + for(int i=0; iname_lines[i].c_str() : node->short_name.c_str(); + glPushMatrix(); + Mat4 xform; + xform.translate(-dtx_string_width(name) / 2.0, -line_height * i, 0); + if(node->type == FSTYPE_DIR) { + xform.rotate_z(deg_to_rad(90)); + xform.rotate_x(deg_to_rad(-90)); + xform.scale(0.0017); + } else { + xform.scale(0.0012); + } + xform.translate(0, ypos, -dist); + xform.rotate_y(angle); + glMultMatrixf(xform[0]); + + dtx_string(name); + glPopMatrix(); + } } +#define MAX_NAME_SZ 16 + FSNode *get_fsnode(const char *path) { char *abspath = make_abs_path(path); @@ -125,6 +286,30 @@ FSNode *get_fsnode(const char *path) node = new FSNode; node->path = path; + const char *name = node->path.get_name(); + if(name) { + const char *ptr = name; + while(*ptr) { + if(ptr - name >= MAX_NAME_SZ) { + int len = ptr - name; + std::string s = std::string(name, len); + if(node->short_name.empty()) { + node->short_name = s; + node->short_name[len - 1] = node->short_name[len - 2] = '.'; + } + node->name_lines.push_back(s); + name = ptr; + } + ++ptr; + } + if(*name) { + if(node->short_name.empty()) { + node->short_name = name; + } + node->name_lines.push_back(name); + } + } + struct stat st; if(stat(node->path, &st) == -1) { fprintf(stderr, "failed to stat: %s\n", node->path.get_path()); @@ -179,6 +364,7 @@ FSNode::FSNode() type = FSTYPE_UNKNOWN; size = 0; parent = 0; + nfiles = ndirs = 0; } bool FSNode::expand() @@ -203,6 +389,15 @@ bool FSNode::expand() if(!node) continue; children.push_back(node); + switch(node->type) { + case FSTYPE_FILE: + ++nfiles; + break; + case FSTYPE_DIR: + ++ndirs; + default: + break; + } } printf("expanded %d children\n", (int)children.size());