static void cb_keyboard(GLFWwindow* window, int k, int scancode, int action, int mods) { if(action != 1) return; if(k == '-') opt_levels--; if(k == '=') opt_levels++; if(k == '0') opt_levels = 4; if(k == GLFW_KEY_ESCAPE) exit(0); if(k == 'Q') exit(0); if(k == 'A') opt_apparent = !opt_apparent; if(k == 'C') opt_count = !opt_count; if(k == 'B') opt_bytes = !opt_bytes; if(k == 'F') fuzz = (fuzz == 0) ? opt_fuzz : 0; if(k == 'G') opt_gradient = !opt_gradient; if(k == ',') if(opt_ring_gap > 0) opt_ring_gap --; if(k == '.') opt_ring_gap ++; if(k == 'P') palette = (palette + 1) % 5; if(k == GLFW_KEY_BACKSPACE) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } }
void cb_mouse_button(GLFWwindow* window, int b, int action, int mods) { if(action != 1) return; double x, y; glfwGetCursorPos(window, &x, &y); sc2fb(window, &x, &y); if(b == 0) { duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 3) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } }
static int handle_event(XEvent e) { KeySym k; int x, y, b; switch(e.type) { case ConfigureNotify: win_w = e.xconfigure.width; win_h = e.xconfigure.height; cairo_xlib_surface_set_size(cs, win_w, win_h); redraw = 1; break; case Expose: if(e.xexpose.count < 1) redraw = 1; break; case KeyPress: k = XLookupKeysym(&e.xkey, 0); if(k == XK_minus) opt_levels--; if(k == XK_equal) opt_levels++; if(k == XK_0) opt_levels = 4; if(k == XK_Escape) return 1; if(k == XK_q) return 1; if(k == XK_a) opt_apparent = !opt_apparent; if(k == XK_b) opt_bytes = !opt_bytes; if(k == XK_f) fuzz = (fuzz == 0) ? opt_fuzz : 0; if(k == XK_comma) if(opt_ring_gap > 0) opt_ring_gap --; if(k == XK_period) opt_ring_gap ++; if(k == XK_p) { palette = (palette + 1) % 4; } if(k == XK_BackSpace) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } redraw = 1; break; case ButtonPress: x = e.xbutton.x; y = e.xbutton.y; b = e.xbutton.button; if(b == 1) { duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 3) { duc_dir *dir2 = duc_dir_openat(dir, ".."); if(dir2) { duc_dir_close(dir); dir = dir2; } } if(b == 4) opt_levels --; if(b == 5) opt_levels ++; redraw = 1; break; case MotionNotify: tooltip_x = e.xmotion.x; tooltip_y = e.xmotion.y; tooltip_moved = 1; break; default: break; } return 0; }
static duc_dir *do_dir(duc_dir *dir, int depth) { int top = 0; int cur = 0; for(;;) { int attr_size, attr_name, attr_class, attr_graph, attr_bar, attr_cursor; if(opt_color) { attr_size = COLOR_PAIR(PAIR_SIZE); attr_name = COLOR_PAIR(PAIR_NAME); attr_bar = COLOR_PAIR(PAIR_BAR); attr_cursor = COLOR_PAIR(PAIR_CURSOR); attr_graph = COLOR_PAIR(PAIR_GRAPH); attr_class = COLOR_PAIR(PAIR_CLASS); } else { attr_size = 0; attr_name = A_BOLD; attr_class = 0; attr_graph = 0; attr_bar = A_REVERSE; attr_cursor = A_REVERSE; use_default_colors(); } duc_size_type st = opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL; /* Iterate all dirents to find largest size */ duc_dir_seek(dir, 0); off_t size_max = 1; struct duc_dirent *e; while( (e = duc_dir_read(dir, st)) != NULL) { off_t size = opt_apparent ? e->size.apparent : e->size.actual; if(size > size_max) size_max = size; } int count = duc_dir_get_count(dir); int pgsize = rows - 2; /* Check boundaries */ if(cur < 0) cur = 0; if(cur > count - 1) cur = count - 1; if(cur < top) top = cur; if(cur > top + pgsize - 1) top = cur - pgsize + 1; if(top < 0) top = 0; /* Draw header */ char *path = duc_dir_get_path(dir); attrset(attr_bar); mvhline(0, 0, ' ', cols); mvprintw(0, 1, " %s ", path); attrset(0); free(path); /* Draw footer */ struct duc_size size; duc_dir_get_size(dir, &size); char siz[32], cnt[32]; duc_human_size(&size, st, opt_bytes, siz, sizeof siz); duc_human_number(count, opt_bytes, cnt, sizeof cnt); attrset(attr_bar); mvhline(rows-1, 0, ' ', cols); mvprintw(rows-1, 0, " Total %sB in %s files/directories", siz, cnt); attrset(0); /* Draw dirents */ duc_dir_seek(dir, top); int i; int y = 1; for(i=top; i<top + pgsize; i++) { struct duc_dirent *e = duc_dir_read(dir, st); attrset(cur == i ? attr_cursor : 0); mvhline(y, 0, ' ', cols); if(e) { off_t size = opt_apparent ? e->size.apparent : e->size.actual; size_t max_size_len = opt_bytes ? 12 : 7; char class = duc_file_type_char(e->type); char siz[32]; duc_human_size(&e->size, st, opt_bytes, siz, sizeof siz); if(cur != i) attrset(attr_size); printw("%*s", max_size_len, siz); printw(" "); char *p = e->name; if(cur != i) attrset(attr_name); while(*p) { if(*(uint8_t *)p >= 32) { printw("%c", *p); } else { printw("^%c", *p+64); } p++; } if(cur != i) attrset(attr_class); printw("%c", class); int w = cols - 30; if(w > cols / 2) w = cols / 2; if(opt_graph && w > 2) { int j; off_t g = w * size / size_max; if(cur != i) attrset(attr_graph); mvprintw(y, cols - w - 4, " ["); for(j=0; j<w; j++) printw("%s", j < g ? "=" : " "); printw("] "); } } else { attrset(A_DIM); mvprintw(y, 0, "~"); } y++; } duc_dir *dir2 = NULL; /* Handle key */ int c = getch(); switch(c) { case 'k': case KEY_UP: cur--; break; case 'j': case KEY_DOWN: cur++; break; case 21: cur -= pgsize/2; break; case KEY_PPAGE: cur -= pgsize; break; case 4: cur += pgsize/2; break; case KEY_NPAGE: cur += pgsize; break; case KEY_RESIZE: getmaxyx(stdscr, rows, cols); break; case 'a': opt_apparent ^= 1; break; case 'b': opt_bytes ^= 1; break; case 'c': opt_color ^= 1; break; case 'g': opt_graph ^= 1; break; case 'h': help(); break; case 27: case 'q': exit(0); break; case KEY_BACKSPACE: case KEY_LEFT: if(depth > 0) { return NULL; } else { dir2 = duc_dir_openat(dir, ".."); if(dir2) { do_dir(dir2, 0); duc_dir_close(dir2); } } break; case KEY_RIGHT: case '\r': case '\n': duc_dir_seek(dir, cur); struct duc_dirent *e = duc_dir_read(dir, st); if(e->type == DUC_FILE_TYPE_DIR) { dir2 = duc_dir_openent(dir, e); if(dir2) { do_dir(dir2, depth + 1); duc_dir_close(dir2); } } break; default: break; } }