diff options
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 173 |
1 files changed, 5 insertions, 168 deletions
@@ -32,172 +32,18 @@ static Rect menu_rect(Ted *ted) { ); } -// where is the ith entry in the file selector on the screen? -// returns false if it's completely offscreen -static bool file_selector_entry_pos(Ted const *ted, FileSelector const *fs, - u32 i, Rect *r) { - Rect bounds = fs->bounds; - float char_height = text_font_char_height(ted->font); - *r = rect(V2(bounds.pos.x, bounds.pos.y + char_height * (float)i), - V2(bounds.size.x, char_height)); - return rect_clip_to_rect(r, bounds); -} - -// clear the entries in the file selector -static void file_selector_clear_entries(FileSelector *fs) { - for (u32 i = 0; i < fs->n_entries; ++i) { - free(fs->entries[i].name); - } - free(fs->entries); - fs->entries = NULL; - fs->n_entries = 0; -} - -static void file_selector_free(FileSelector *fs) { - file_selector_clear_entries(fs); -} - -static int qsort_file_entry_cmp(void const *av, void const *bv) { - FileEntry const *a = av, *b = bv; - // put directories first - if (a->type > b->type) { - return -1; - } - if (a->type < b->type) { - return +1; - } - return strcmp_case_insensitive(a->name, b->name); -} - -// returns the entry of the selected file, or a NULL entry (check .name == NULL) -// if none was selected -static FileEntry file_selector_update(Ted *ted, FileSelector *fs, String32 const search_term32) { - char *search_term = search_term32.len ? str32_to_utf8_cstr(search_term32) : NULL; - - // check if an entry was clicked on - for (u32 i = 0; i < fs->n_entries; ++i) { - Rect r = {0}; - if (file_selector_entry_pos(ted, fs, i, &r)) { - for (u32 c = 0; c < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++c) { - if (rect_contains_point(r, ted->mouse_clicks[SDL_BUTTON_LEFT][c])) { - // this option was selected - free(search_term); - return fs->entries[i]; - } - } - } else break; - } - - // free previous entries - file_selector_clear_entries(fs); - // get new entries - char **files = fs_list_directory("."); - if (files) { - u32 nfiles; - for (nfiles = 0; files[nfiles]; ++nfiles); - - // filter entries - bool increment = true; - for (u32 i = 0; i < nfiles; i += increment, increment = true) { - // remove if the file name does not contain the search term, - bool remove = search_term && *search_term && !stristr(files[i], search_term); - // or if this is just the current directory - remove |= streq(files[i], "."); - if (remove) { - // remove this one - free(files[i]); - --nfiles; - if (nfiles) { - files[i] = files[nfiles]; - } - increment = false; - } - } - - if (nfiles) { - FileEntry *entries = ted_calloc(ted, nfiles, sizeof *entries); - if (entries) { - fs->n_entries = nfiles; - fs->entries = entries; - for (u32 i = 0; i < nfiles; ++i) { - entries[i].name = files[i]; - entries[i].type = fs_path_type(files[i]); - } - } - qsort(entries, nfiles, sizeof *entries, qsort_file_entry_cmp); - } - } else { - #if DEBUG - static bool have_warned; - if (!have_warned) { - debug_println("Warning: fs_list_directory failed."); - have_warned = true; - } - #endif - } - - free(search_term); - FileEntry ret = {0}; - return ret; -} - -static void file_selector_render(Ted const *ted, FileSelector const *fs) { - Settings const *settings = &ted->settings; - u32 const *colors = settings->colors; - Rect bounds = fs->bounds; - u32 n_entries = fs->n_entries; - FileEntry const *entries = fs->entries; - Font *font = ted->font; - float char_height = text_font_char_height(ted->font); - float x1, y1, x2, y2; - rect_coords(bounds, &x1, &y1, &x2, &y2); - float x = x1, y = y1; - for (u32 i = 0; i < n_entries; ++i) { - // highlight entry user is mousing over - if (y >= y2) break; - Rect r = rect4(x, y, x2, minf(y + char_height, y2)); - y += char_height; - if (rect_contains_point(r, ted->mouse_pos)) { - glBegin(GL_QUADS); - gl_color_rgba(colors[COLOR_MENU_HL]); - rect_render(r); - glEnd(); - } - } - - x = x1; y = y1; - TextRenderState text_render_state = {.min_x = x1, .max_x = x2, .min_y = y1, .max_y = y2, .render = true}; - // render file names themselves - for (u32 i = 0; i < n_entries; ++i) { - if (y >= y2) break; - switch (entries[i].type) { - case FS_FILE: - gl_color_rgba(colors[COLOR_TEXT]); - break; - case FS_DIRECTORY: - gl_color_rgba(colors[COLOR_TEXT_FOLDER]); - break; - default: - gl_color_rgba(colors[COLOR_TEXT_OTHER]); - break; - } - text_render_with_state(font, &text_render_state, entries[i].name, x, y); - y += char_height; - } -} - static void menu_update(Ted *ted, Menu menu) { switch (menu) { case MENU_NONE: break; case MENU_OPEN: { - FileEntry selected_entry = file_selector_update(ted, &ted->file_selector, - buffer_get_line(&ted->line_buffer, 0)); - if (selected_entry.name) { + char *selected_file = file_selector_update(ted, &ted->file_selector); + if (selected_file) { // open that file! - if (ted_open_file(ted, selected_entry.name)) { + if (ted_open_file(ted, selected_file)) { menu_close(ted, false); file_selector_free(&ted->file_selector); } + free(selected_file); } } break; } @@ -206,9 +52,7 @@ static void menu_update(Ted *ted, Menu menu) { static void menu_render(Ted *ted, Menu menu) { Settings *settings = &ted->settings; u32 *colors = settings->colors; - Font *font = ted->font; float window_width = ted->window_width, window_height = ted->window_height; - float char_height = text_font_char_height(font); // render backdrop glBegin(GL_QUADS); @@ -241,16 +85,9 @@ static void menu_render(Ted *ted, Menu menu) { menu_x2 -= inner_padding; menu_y2 -= inner_padding; - float line_buffer_height = char_height * 1.5f; - float line_buffer_x1 = menu_x1, - line_buffer_y1 = menu_y1, - line_buffer_x2 = menu_x2, - line_buffer_y2 = line_buffer_y1 + line_buffer_height; - - buffer_render(&ted->line_buffer, line_buffer_x1, line_buffer_y1, line_buffer_x2, line_buffer_y2); FileSelector *fs = &ted->file_selector; - fs->bounds = rect4(menu_x1, line_buffer_y2, menu_x2, menu_y2); + fs->bounds = rect4(menu_x1, menu_y1, menu_x2, menu_y2); file_selector_render(ted, fs); } } |