13 #include "gmath/gmath.h"
18 static IconRenderer *iconrend;
20 static std::map<std::string, FSNode*> node_cache;
21 static FSNode *cur_node;
22 static int start_child;
24 static dtx_font *fat_font;
25 #define FAT_FONT_SZ 32
28 bool init_fs(const char *path)
30 iconrend = new ShapesIcons;
31 if(!iconrend->init()) {
35 if(!(fat_font = dtx_open_font("data/fat.font", FAT_FONT_SZ))) {
36 fprintf(stderr, "failed to open font file data/fat.font\n");
40 cur_node = get_fsnode(path);
47 std::map<std::string, FSNode*>::iterator it = node_cache.begin();
48 while(it != node_cache.end()) {
49 FSNode *node = it++->second;
56 static Vec3 icon_pos(int row, int col, int ncols, float row_spacing, float radius)
58 float angle = 2.0 * M_PI * (float)col / (float)ncols;
59 float x = sin(angle) * radius;
60 float z = -cos(angle) * radius;
61 float y = (float)row * row_spacing;
65 static float icon_angle(int col, int ncols, float max_angle = 0.0f)
68 return max_angle * ((float)col / (float)(ncols - 1) - 0.5);
70 return 2.0 * M_PI * (float)col / (float)ncols;
75 static const float row_spacing = 2.0;
76 static const float radius = 0.6;
77 static const float umax = 0.42;
78 static const float max_icon_angle = M_PI * 2.0 * umax;
80 int max_ncols = std::max<int>(1, umax * 16);
83 base_xform.rotate(time_sec, 0, 0);
84 base_xform.rotate(0, 0, time_sec * 0.5);
85 base_xform.translate(0, 1.65, 0);
88 glDisable(GL_TEXTURE_2D);
90 int nchildren = (int)cur_node->children.size();
91 int ncols = std::min(cur_node->nfiles, max_ncols);
93 int first = start_child % ncols;
96 for(int i=0; i<nchildren; i++) {
97 int idx = (i + first) % nchildren;
98 FSNode *node = cur_node->children[idx];
100 if(node->type == FSTYPE_DIR) {
104 float angle = icon_angle(col, ncols, max_icon_angle);
106 Mat4 xform = base_xform;
107 xform.translate(0, row * row_spacing, -radius);
108 xform.rotate_y(angle);
111 glMultMatrixf(xform[0]);
112 iconrend->draw(node);
116 xform = Mat4::identity;
117 xform.translate(-dtx_string_width(node->path.get_name()) / 2.0, 0, 0);
119 xform.translate(0, 1.54 + row * row_spacing, -radius);
120 xform.rotate_y(angle);
121 glMultMatrixf(xform[0]);
123 dtx_string(node->path.get_name());
133 FSNode *get_fsnode(const char *path)
135 char *abspath = make_abs_path(path);
137 FSNode *node = node_cache[abspath];
143 if(stat(node->path, &st) == -1) {
144 fprintf(stderr, "failed to stat: %s\n", node->path.get_path());
148 node->size = st.st_size;
150 switch(st.st_mode & S_IFMT) {
152 node->type = FSTYPE_FILE;
156 node->type = FSTYPE_DIR;
161 node->type = FSTYPE_DEV;
165 node->type = FSTYPE_UNKNOWN;
167 node_cache[abspath] = node;
173 FSNode *get_fsnode(const char *dir, const char *name)
176 return get_fsnode(name);
178 if(!name || *name == '/') {
182 int len = strlen(dir) + 1 + strlen(name);
183 char *buf = new char[len + 1];
184 sprintf(buf, "%s/%s", dir, name);
185 FSNode *res = get_fsnode(buf);
190 // ---- FSNode implementation ----
193 type = FSTYPE_UNKNOWN;
199 bool FSNode::expand()
201 if(type != FSTYPE_DIR) {
205 DIR *dir = opendir(path);
207 fprintf(stderr, "failed to open dir: %s: %s\n", path.get_path(), strerror(errno));
212 while((dent = readdir(dir))) {
213 if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) {
217 FSNode *node = get_fsnode(path, dent->d_name);
220 children.push_back(node);
231 printf("expanded %d children\n", (int)children.size());
233 parent = get_fsnode(path.get_parent());