X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vrfileman;a=blobdiff_plain;f=src%2Ffs.cc;h=c7df966e18a5dd6fc6d5f6ebe6c84565549f60e4;hp=5795cd0669be469814690358afc7be2f49e5d3e2;hb=5e07bfd4d034dc3d974c8db008c6446e62838d39;hpb=d5b4970b66b1d6b4726dd360a452a0b5b3160f22 diff --git a/src/fs.cc b/src/fs.cc index 5795cd0..c7df966 100644 --- a/src/fs.cc +++ b/src/fs.cc @@ -16,6 +16,8 @@ #include "drawtext.h" #include "sdr.h" +static void draw_node_name(FSNode *node, float angle, float ypos, float dist, bool full); + static IconRenderer *iconrend; static std::map node_cache; @@ -24,7 +26,8 @@ static int start_child; static dtx_font *fat_font; #define FAT_FONT_SZ 32 -static unsigned int font_sdr; +static unsigned int glow_link_sdr; +static unsigned int chrome_font_sdr, glow_font_sdr; bool init_fs(const char *path) @@ -49,10 +52,27 @@ bool init_fs(const char *path) } dtx_use_font(fat_font, FAT_FONT_SZ); - if(!(font_sdr = create_program_load("sdr/dfont.v.glsl", "sdr/dfont.p.glsl"))) { + 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); + + if(!(glow_link_sdr = create_program_load("sdr/glink.v.glsl", "sdr/glink.p.glsl"))) { return false; } - set_uniform_float(font_sdr, "smoothness", 0.01); if(!(cur_node = get_fsnode(path))) { return false; @@ -73,15 +93,6 @@ void cleanup_fs() delete iconrend; } -static Vec3 icon_pos(int row, int col, int ncols, float row_spacing, float radius) -{ - 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); -} - static float icon_angle(int col, int ncols, float max_angle = 0.0f) { if(max_angle > 0) { @@ -99,32 +110,104 @@ void draw_fs() int max_ncols = std::max(1, umax * 12); - Mat4 base_xform; - base_xform.rotate(time_sec, 0, 0); - base_xform.rotate(0, 0, time_sec * 0.5); - base_xform.translate(0, 1.65, 0); + 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); glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 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; } - glUseProgram(0); - 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); @@ -133,26 +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.001); - xform.translate(0, 1.54 + row * row_spacing, -radius); - xform.rotate_y(angle); - glMultMatrixf(xform[0]); + if(++col >= ncols) { + col = 0; + ++row; + } + } - glUseProgram(font_sdr); - set_uniform_float(font_sdr, "height", dtx_line_height()); - 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); @@ -162,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());