icon name shortening and rudimentary directory visualization
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Wed, 10 Aug 2016 06:06:40 +0000 (09:06 +0300)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Wed, 10 Aug 2016 06:06:40 +0000 (09:06 +0300)
src/app.cc
src/app.h
src/fs.cc
src/fs.h

index f5b9894..08f6e8a 100644 (file)
@@ -18,10 +18,10 @@ long time_msec;
 double time_sec;
 Mat4 view_matrix;
 
 double time_sec;
 Mat4 view_matrix;
 
-static bool should_swap;
+float cam_height = 1.65;
 
 static float cam_theta, cam_phi;
 
 static float cam_theta, cam_phi;
-static float cam_height = 1.65;
+static bool should_swap;
 
 static bool bnstate[16];
 static int prev_x, prev_y;
 
 static bool bnstate[16];
 static int prev_x, prev_y;
index c3d5f03..97f8f8b 100644 (file)
--- a/src/app.h
+++ b/src/app.h
@@ -9,6 +9,7 @@ extern float win_aspect;
 extern long time_msec;
 extern double time_sec;
 
 extern long time_msec;
 extern double time_sec;
 
+extern float cam_height;
 extern Mat4 view_matrix;
 
 
 extern Mat4 view_matrix;
 
 
index 1d3b46d..ae5b31a 100644 (file)
--- a/src/fs.cc
+++ b/src/fs.cc
@@ -16,6 +16,8 @@
 #include "drawtext.h"
 #include "sdr.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;
 
 static std::map<std::string, FSNode*> node_cache;
 static IconRenderer *iconrend;
 
 static std::map<std::string, FSNode*> node_cache;
@@ -73,15 +75,6 @@ void cleanup_fs()
        delete iconrend;
 }
 
        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) {
 static float icon_angle(int col, int ncols, float max_angle = 0.0f)
 {
        if(max_angle > 0) {
@@ -99,10 +92,12 @@ void draw_fs()
 
        int max_ncols = std::max<int>(1, umax * 12);
 
 
        int max_ncols = std::max<int>(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);
 
 
        glDisable(GL_TEXTURE_2D);
 
@@ -111,12 +106,55 @@ void draw_fs()
 
        int first = start_child % ncols;
        int col = 0, row = 0;
 
        int first = start_child % ncols;
        int col = 0, row = 0;
+       int num_dirs = 0;
+
+       // count directories ...
+       for(int i=0; i<nchildren; i++) {
+               FSNode *node = cur_node->children[i];
+               if(node->type == FSTYPE_DIR) {
+                       ++num_dirs;
+               }
+       }
+
+       // ... and draw them
+       glLineWidth(5.0);
+       for(int i=0; i<nchildren; i++) {
+               FSNode *node = cur_node->children[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);
+
+               glUseProgram(0);
+               glPushMatrix();
+               glMultMatrixf(xform[0]);
+
+               glBegin(GL_LINES);
+               glColor3f(0.2, 0.3, 0.8);
+               glVertex3f(0, 0, -0.3);
+               glVertex3f(0, 0, -2);
+               glColor3f(1, 1, 1);
+               glEnd();
+               glPopMatrix();
 
 
+               draw_node_name(node, angle, -0.3, radius, false);
+       }
+       glLineWidth(1.0);
+
+       // then draw files
+       col = 0;
        for(int i=0; i<nchildren; i++) {
                int idx = (i + first) % nchildren;
                FSNode *node = cur_node->children[idx];
 
                if(node->type == FSTYPE_DIR) {
        for(int i=0; i<nchildren; i++) {
                int idx = (i + first) % nchildren;
                FSNode *node = cur_node->children[idx];
 
                if(node->type == FSTYPE_DIR) {
+                       ++num_dirs;
                        continue;
                }
 
                        continue;
                }
 
@@ -124,7 +162,7 @@ void draw_fs()
 
                float angle = icon_angle(col, ncols, max_icon_angle);
 
 
                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);
 
                xform.translate(0, row * row_spacing, -radius);
                xform.rotate_y(angle);
 
@@ -133,26 +171,48 @@ void draw_fs()
                iconrend->draw(node);
                glPopMatrix();
 
                iconrend->draw(node);
                glPopMatrix();
 
+               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; i<nlines; i++) {
+               const char *name = full ? node->name_lines[i].c_str() : node->short_name.c_str();
                glPushMatrix();
                glPushMatrix();
-               xform = Mat4::identity;
-               xform.translate(-dtx_string_width(node->path.get_name()) / 2.0, 0, 0);
-               xform.scale(0.0012);
-               xform.translate(0, 1.54 + row * row_spacing, -radius);
+               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]);
 
                glUseProgram(font_sdr);
                xform.rotate_y(angle);
                glMultMatrixf(xform[0]);
 
                glUseProgram(font_sdr);
-               set_uniform_float(font_sdr, "height", dtx_line_height());
-               dtx_string(node->path.get_name());
+               set_uniform_float(font_sdr, "height", line_height);
+               dtx_string(name);
                glPopMatrix();
                glPopMatrix();
-
-               if(++col >= ncols) {
-                       col = 0;
-                       ++row;
-               }
        }
 }
 
        }
 }
 
+#define MAX_NAME_SZ    16
+
 FSNode *get_fsnode(const char *path)
 {
        char *abspath = make_abs_path(path);
 FSNode *get_fsnode(const char *path)
 {
        char *abspath = make_abs_path(path);
@@ -162,6 +222,30 @@ FSNode *get_fsnode(const char *path)
                node = new FSNode;
                node->path = 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());
                struct stat st;
                if(stat(node->path, &st) == -1) {
                        fprintf(stderr, "failed to stat: %s\n", node->path.get_path());
index c1b171e..4174bb1 100644 (file)
--- a/src/fs.h
+++ b/src/fs.h
@@ -1,8 +1,9 @@
 #ifndef FS_H_
 #define FS_H_
 
 #ifndef FS_H_
 #define FS_H_
 
-#include <vector>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <vector>
+#include <string>
 #include "fspath.h"
 
 enum FSNodeType {
 #include "fspath.h"
 
 enum FSNodeType {
@@ -16,6 +17,8 @@ class FSNode {
 public:
        FSNodeType type;
        FSPath path;
 public:
        FSNodeType type;
        FSPath path;
+       std::string short_name;
+       std::vector<std::string> name_lines;
        size_t size;
 
        FSNode *parent;
        size_t size;
 
        FSNode *parent;