From 413e8f4ba1c5937de40f6366a88c26f540cbb222 Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 6 Aug 2023 10:59:07 -0400 Subject: new menu system all done --- ide-definitions.c | 21 ++++-- ide-rename-symbol.c | 93 +++++++++++++++++++++--- main.c | 4 +- menu.c | 199 ++++++++++++++++------------------------------------ ted-internal.h | 2 + ted.h | 9 --- util.c | 28 +++++++- util.h | 10 +++ 8 files changed, 202 insertions(+), 164 deletions(-) diff --git a/ide-definitions.c b/ide-definitions.c index c37ae69..ea268e2 100644 --- a/ide-definitions.c +++ b/ide-definitions.c @@ -261,7 +261,7 @@ void definitions_send_request_if_needed(Ted *ted) { defs->last_request_query = query; } -void definitions_selector_open(Ted *ted) { +static void definitions_selector_open(Ted *ted) { Definitions *defs = &ted->definitions; definitions_clear_entries(defs); LSP *lsp = ted->prev_active_buffer @@ -279,15 +279,16 @@ void definitions_selector_open(Ted *ted) { } -void definitions_selector_close(Ted *ted) { +static bool definitions_selector_close(Ted *ted) { Definitions *defs = &ted->definitions; definitions_clear_entries(defs); ted_cancel_lsp_request(ted, &defs->last_request); free(defs->last_request_query); defs->last_request_query = NULL; + return true; } -void definitions_selector_update(Ted *ted) { +static void definitions_selector_update(Ted *ted) { Definitions *defs = &ted->definitions; Selector *sel = &defs->selector; sel->enable_cursor = true; @@ -328,9 +329,21 @@ void definitions_selector_update(Ted *ted) { } } -void definitions_selector_render(Ted *ted, Rect bounds) { +static void definitions_selector_render(Ted *ted) { + Rect bounds = selection_menu_render_bg(ted); Definitions *defs = &ted->definitions; Selector *sel = &defs->selector; sel->bounds = bounds; selector_render(ted, sel); } + +void definitions_init(Ted *ted) { + MenuInfo info = { + .open = definitions_selector_open, + .close = definitions_selector_close, + .render = definitions_selector_render, + .update = definitions_selector_update, + }; + strbuf_cpy(info.name, MENU_GOTO_DEFINITION); + menu_register(ted, &info); +} diff --git a/ide-rename-symbol.c b/ide-rename-symbol.c index b3ef52b..7d1e2ad 100644 --- a/ide-rename-symbol.c +++ b/ide-rename-symbol.c @@ -4,10 +4,6 @@ struct RenameSymbol { LSPServerRequestID request_id; }; -void rename_symbol_init(Ted *ted) { - ted->rename_symbol = calloc(1, sizeof *ted->rename_symbol); -} - void rename_symbol_quit(Ted *ted) { rename_symbol_clear(ted); free(ted->rename_symbol); @@ -31,10 +27,6 @@ void rename_symbol_at_cursor(Ted *ted, TextBuffer *buffer, const char *new_name) } -bool rename_symbol_is_loading(Ted *ted) { - return ted->rename_symbol->request_id.id != 0; -} - void rename_symbol_clear(Ted *ted) { RenameSymbol *rs = ted->rename_symbol; ted_cancel_lsp_request(ted, &rs->request_id); @@ -48,6 +40,79 @@ void rename_symbol_frame(Ted *ted) { } } +static void rename_symbol_menu_open(Ted *ted) { + ted_switch_to_buffer(ted, &ted->line_buffer); +} + +static void rename_symbol_menu_update(Ted *ted) { + TextBuffer *line_buffer = &ted->line_buffer; + if (line_buffer->line_buffer_submitted) { + char *new_name = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0)); + rename_symbol_at_cursor(ted, ted->prev_active_buffer, new_name); + free(new_name); + } +} + +static void rename_symbol_menu_render(Ted *ted) { + RenameSymbol *rs = ted->rename_symbol; + // highlight symbol + TextBuffer *buffer = ted->prev_active_buffer; + if (!buffer) { + menu_close(ted); + return; + } + if (rs->request_id.id) { + // already entered a new name + return; + } + const Settings *settings = buffer_settings(buffer); + const float padding = settings->padding; + const u32 *colors = settings->colors; + const float line_buffer_height = ted_line_buffer_height(ted); + + u32 sym_start=0, sym_end=0; + BufferPos cursor_pos = buffer->cursor_pos; + buffer_word_span_at_pos(buffer, cursor_pos, &sym_start, &sym_end); + BufferPos bpos0 = { + .line = cursor_pos.line, + .index = sym_start + }; + BufferPos bpos1 = { + .line = cursor_pos.line, + .index = sym_end + }; + // symbol should span from pos0 to pos1 + vec2 p0 = buffer_pos_to_pixels(buffer, bpos0); + vec2 p1 = buffer_pos_to_pixels(buffer, bpos1); + p1.y += text_font_char_height(buffer_font(buffer)); + Rect highlight = rect_endpoints(p0, p1); + gl_geometry_rect_border(highlight, settings->border_thickness, colors[COLOR_BORDER]); + gl_geometry_rect(highlight, colors[COLOR_HOVER_HL]); + + const float width = ted_get_menu_width(ted); + const float height = line_buffer_height + 2 * padding; + Rect bounds = { + .pos = {(ted->window_width - width) / 2, padding}, + .size = {width, height}, + }; + gl_geometry_rect(bounds, colors[COLOR_MENU_BG]); + gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]); + gl_geometry_draw(); + bounds = rect_shrink(bounds, padding); + const char *text = "Rename symbol to..."; + text_utf8(ted->font_bold, text, bounds.pos.x, bounds.pos.y, colors[COLOR_TEXT]); + bounds = rect_shrink_left(bounds, text_get_size_vec2(ted->font_bold, text).x + padding); + text_render(ted->font_bold); + + buffer_render(&ted->line_buffer, bounds); +} + +static bool rename_symbol_menu_close(Ted *ted) { + rename_symbol_clear(ted); + buffer_clear(&ted->line_buffer); + return true; +} + void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) { RenameSymbol *rs = ted->rename_symbol; if (response->request.type != LSP_REQUEST_RENAME @@ -125,3 +190,15 @@ void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) { if (menu_is_open(ted, MENU_RENAME_SYMBOL)) menu_close(ted); } + +void rename_symbol_init(Ted *ted) { + ted->rename_symbol = calloc(1, sizeof *ted->rename_symbol); + MenuInfo menu = { + .open = rename_symbol_menu_open, + .close = rename_symbol_menu_close, + .update = rename_symbol_menu_update, + .render = rename_symbol_menu_render, + }; + strbuf_cpy(menu.name, MENU_RENAME_SYMBOL); + menu_register(ted, &menu); +} diff --git a/main.c b/main.c index 24a775e..5728bf1 100644 --- a/main.c +++ b/main.c @@ -1,8 +1,6 @@ /* TODO: -- rework menus - deal with really long paths in file menus -- internalize Autocomplete, SignatureHelp, etc. FUTURE FEATURES: - autodetect indentation (tabs vs spaces) @@ -506,6 +504,7 @@ int main(int argc, char **argv) { gl_geometry_init(); text_init(); menu_init(ted); + definitions_init(ted); autocomplete_init(ted); signature_help_init(ted); usages_init(ted); @@ -1228,7 +1227,6 @@ int main(int argc, char **argv) { SDL_GL_DeleteContext(glctx); SDL_DestroyWindow(window); SDL_Quit(); - definitions_selector_close(ted); for (u16 i = 0; i < TED_MAX_BUFFERS; ++i) if (ted->buffers_used[i]) buffer_free(&ted->buffers[i]); diff --git a/menu.c b/menu.c index 8facbc5..b658086 100644 --- a/menu.c +++ b/menu.c @@ -20,11 +20,10 @@ void menu_close(Ted *ted) { if (!menu_is_any_open(ted)) return; const MenuInfo *menu = &ted->all_menus[ted->menu_open_idx]; - bool will_close = true; - if (menu->close) - will_close = menu->close(ted); - if (!will_close) - return; + if (menu->close) { + if (!menu->close(ted)) + return; + } ted_switch_to_buffer(ted, ted->prev_active_buffer); TextBuffer *buffer = ted->active_buffer; @@ -33,25 +32,14 @@ void menu_close(Ted *ted) { buffer->scroll_x = ted->prev_active_buffer_scroll.x; buffer->scroll_y = ted->prev_active_buffer_scroll.y; } - /* - switch (ted->menu) { - case MENU_GOTO_DEFINITION: - definitions_selector_close(ted); - break; - case MENU_SHELL: - buffer_clear(&ted->line_buffer); - break; - case MENU_RENAME_SYMBOL: - rename_symbol_clear(ted); - buffer_clear(&ted->line_buffer); - break; - }*/ ted->menu_open_idx = 0; ted->menu_context = NULL; ted->selector_open = NULL; } void menu_open_with_context(Ted *ted, const char *menu_name, void *context) { + if (menu_is_open(ted, menu_name)) + return; u32 menu_idx = U32_MAX; if (*menu_name) { for (u32 i = 0; i < arr_len(ted->all_menus); ++i) { @@ -66,13 +54,8 @@ void menu_open_with_context(Ted *ted, const char *menu_name, void *context) { return; } - if (menu_is_open(ted, menu_name)) - return; - if (menu_is_any_open(ted)) menu_close(ted); - - if (ted->find) find_close(ted); autocomplete_close(ted); @@ -87,19 +70,6 @@ void menu_open_with_context(Ted *ted, const char *menu_name, void *context) { *ted->warn_overwrite = 0; // clear warn_overwrite buffer_clear(&ted->line_buffer); if (info->open) info->open(ted); - /* - switch (menu) { - case MENU_GOTO_DEFINITION: - definitions_selector_open(ted); - break; - case MENU_SHELL: - ted_switch_to_buffer(ted, &ted->line_buffer); - ted->shell_history_pos = arr_len(ted->shell_history); - break; - case MENU_RENAME_SYMBOL: - ted_switch_to_buffer(ted, &ted->line_buffer); - break; - }*/ } void menu_open(Ted *ted, const char *menu_name) { @@ -124,37 +94,9 @@ void menu_update(Ted *ted) { const MenuInfo *info = &ted->all_menus[ted->menu_open_idx]; if (info->update) info->update(ted); - - /* - TextBuffer *line_buffer = &ted->line_buffer; - const Settings *settings = ted_active_settings(ted); - const u32 *colors = settings->colors; - switch (menu) { - case MENU_GOTO_DEFINITION: { - definitions_selector_update(ted); - } break; - case MENU_SHELL: - if (line_buffer->line_buffer_submitted) { - char *command = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0)); - if (ted->shell_history_pos == arr_len(ted->shell_history) || line_buffer->modified) { - arr_add(ted->shell_history, command); - } - menu_close(ted); - strbuf_cpy(ted->build_dir, ted->cwd); - build_start_with_command(ted, command); - } - break; - case MENU_RENAME_SYMBOL: - if (line_buffer->line_buffer_submitted) { - char *new_name = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0)); - rename_symbol_at_cursor(ted, ted->prev_active_buffer, new_name); - free(new_name); - } - break; - }*/ } -static Rect selection_menu_render_bg(Ted *ted) { +Rect selection_menu_render_bg(Ted *ted) { const Settings *settings = ted_active_settings(ted); const float menu_width = ted_get_menu_width(ted); const float padding = settings->padding; @@ -191,79 +133,6 @@ void menu_render(Ted *ted) { if (info->render) info->render(ted); - - /* - Font *font_bold = ted->font_bold, *font = ted->font; - const float char_height = text_font_char_height(font); - const float char_height_bold = text_font_char_height(font_bold); - const float line_buffer_height = ted_line_buffer_height(ted); - - switch (menu) { - case MENU_NONE: assert(0); break; - case MENU_GOTO_DEFINITION: { - definitions_selector_render(ted, rect4(x1, y1, x2, y2)); - } break; - case MENU_SHELL: { - bounds.size.y = line_buffer_height + 2 * padding; - gl_geometry_rect(bounds, colors[COLOR_MENU_BG]); - gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]); - gl_geometry_draw(); - bounds = rect_shrink(bounds, padding); - rect_coords(bounds, &x1, &y1, &x2, &y2); - const char *text = "Run"; - text_utf8(font_bold, text, x1, y1, colors[COLOR_TEXT]); - x1 += text_get_size_vec2(font_bold, text).x + padding; - text_render(font_bold); - - buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y2)); - } break; - case MENU_RENAME_SYMBOL: { - // highlight symbol - TextBuffer *buffer = ted->prev_active_buffer; - if (!buffer) { - menu_close(ted); - return; - } - if (rename_symbol_is_loading(ted)) { - // already entered a new name - return; - } - - u32 sym_start=0, sym_end=0; - BufferPos cursor_pos = buffer->cursor_pos; - buffer_word_span_at_pos(buffer, cursor_pos, &sym_start, &sym_end); - BufferPos bpos0 = { - .line = cursor_pos.line, - .index = sym_start - }; - BufferPos bpos1 = { - .line = cursor_pos.line, - .index = sym_end - }; - // symbol should span from pos0 to pos1 - vec2 p0 = buffer_pos_to_pixels(buffer, bpos0); - vec2 p1 = buffer_pos_to_pixels(buffer, bpos1); - p1.y += text_font_char_height(buffer_font(buffer)); - Rect highlight = rect_endpoints(p0, p1); - gl_geometry_rect_border(highlight, settings->border_thickness, colors[COLOR_BORDER]); - gl_geometry_rect(highlight, colors[COLOR_HOVER_HL]); - - float height = line_buffer_height + 2 * padding; - bounds.size.y = height; - gl_geometry_rect(bounds, colors[COLOR_MENU_BG]); - gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]); - gl_geometry_draw(); - bounds = rect_shrink(bounds, padding); - rect_coords(bounds, &x1, &y1, &x2, &y2); - const char *text = "Rename symbol to..."; - text_utf8(font_bold, text, x1, y1, colors[COLOR_TEXT]); - x1 += text_get_size_vec2(font_bold, text).x + padding; - text_render(font_bold); - - buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y2)); - } break; - } - */ } void menu_shell_move(Ted *ted, int direction) { @@ -634,6 +503,51 @@ static bool goto_line_menu_close(Ted *ted) { return true; } +static void shell_menu_open(Ted *ted) { + ted_switch_to_buffer(ted, &ted->line_buffer); + ted->shell_history_pos = arr_len(ted->shell_history); +} + +static void shell_menu_update(Ted *ted) { + TextBuffer *line_buffer = &ted->line_buffer; + if (line_buffer->line_buffer_submitted) { + char *command = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0)); + if (ted->shell_history_pos == arr_len(ted->shell_history) || line_buffer->modified) { + arr_add(ted->shell_history, command); + } + menu_close(ted); + strbuf_cpy(ted->build_dir, ted->cwd); + build_start_with_command(ted, command); + } +} + +static void shell_menu_render(Ted *ted) { + const float line_buffer_height = ted_line_buffer_height(ted); + const Settings *settings = ted_active_settings(ted); + const float padding = settings->padding; + const u32 *colors = settings->colors; + const float width = ted_get_menu_width(ted); + const float height = line_buffer_height + 2 * padding; + Rect bounds = { + .pos = {(ted->window_width - width) / 2, padding}, + .size = {width, height}, + }; + gl_geometry_rect(bounds, colors[COLOR_MENU_BG]); + gl_geometry_rect_border(bounds, settings->border_thickness, colors[COLOR_BORDER]); + gl_geometry_draw(); + bounds = rect_shrink(bounds, padding); + const char *text = "Run"; + text_utf8(ted->font_bold, text, bounds.pos.x, bounds.pos.y, colors[COLOR_TEXT]); + bounds = rect_shrink_left(bounds, text_get_size_vec2(ted->font_bold, text).x + padding); + text_render(ted->font_bold); + buffer_render(&ted->line_buffer, bounds); +} + +static bool shell_menu_close(Ted *ted) { + buffer_clear(&ted->line_buffer); + return true; +} + void menu_register(Ted *ted, const MenuInfo *infop) { MenuInfo info = *infop; if (!*info.name) { @@ -701,6 +615,15 @@ void menu_init(Ted *ted) { }; strbuf_cpy(goto_line_menu.name, MENU_GOTO_LINE); menu_register(ted, &goto_line_menu); + + MenuInfo shell_menu = { + .open = shell_menu_open, + .update = shell_menu_update, + .render = shell_menu_render, + .close = shell_menu_close, + }; + strbuf_cpy(shell_menu.name, MENU_SHELL); + menu_register(ted, &shell_menu); } void menu_quit(Ted *ted) { diff --git a/ted-internal.h b/ted-internal.h index 83a088d..b2f54bf 100644 --- a/ted-internal.h +++ b/ted-internal.h @@ -749,6 +749,7 @@ void autocomplete_frame(Ted *ted); void autocomplete_process_lsp_response(Ted *ted, const LSPResponse *response); // === ide-definitions.c === +void definitions_init(Ted *ted); /// go to the definition of `name`. /// if `lsp` is NULL, tags will be used. /// Note: the document position is required for LSP requests because of overloading (where the name @@ -808,6 +809,7 @@ void menu_shell_move(Ted *ted, int direction); void menu_shell_up(Ted *ted); /// move to next command void menu_shell_down(Ted *ted); +Rect selection_menu_render_bg(Ted *ted); // === node.c === void node_free(Node *node); diff --git a/ted.h b/ted.h index b47c403..be5fb4c 100644 --- a/ted.h +++ b/ted.h @@ -742,13 +742,6 @@ void autocomplete_close(Ted *ted); // === ide-definitions.c === /// cancel the last go-to-definition / find symbols request. void definition_cancel_lookup(Ted *ted); -/// open the definitions menu -void definitions_selector_open(Ted *ted); -/// update the definitions menu -void definitions_selector_update(Ted *ted); -void definitions_selector_render(Ted *ted, Rect bounds); -/// close the definitions menu -void definitions_selector_close(Ted *ted); // === ide-document-link.c === /// get document link at this position in the active buffer. @@ -768,8 +761,6 @@ void hover_close(Ted *ted); // === ide-rename-symbol.c === void rename_symbol_at_cursor(Ted *ted, TextBuffer *buffer, const char *new_name); -/// returns true if we are currently waiting for the LSP to send us a response -bool rename_symbol_is_loading(Ted *ted); void rename_symbol_clear(Ted *ted); // === ide-signature-help.c === diff --git a/util.c b/util.c index 2f32015..a16f7a5 100644 --- a/util.c +++ b/util.c @@ -925,7 +925,6 @@ bool rect_clip_to_rect(Rect *clipped, Rect clipper) { return clipped->size.x > 0 && clipped->size.y > 0; } -// removes `amount` from all sides of r Rect rect_shrink(Rect r, float amount) { r.pos.x += amount; r.pos.y += amount; @@ -936,7 +935,32 @@ Rect rect_shrink(Rect r, float amount) { return r; } -// adds `amount` to all sides of r +Rect rect_shrink_left(Rect r, float amount) { + r.pos.x += amount; + r.size.x -= amount; + r.size.x = maxf(r.size.x, 0); + return r; +} + +Rect rect_shrink_top(Rect r, float amount) { + r.pos.y += amount; + r.size.y -= amount; + r.size.y = maxf(r.size.y, 0); + return r; +} + +Rect rect_shrink_right(Rect r, float amount) { + r.size.x -= amount; + r.size.x = maxf(r.size.x, 0); + return r; +} + +Rect rect_shrink_bottom(Rect r, float amount) { + r.size.y -= amount; + r.size.y = maxf(r.size.y, 0); + return r; +} + Rect rect_grow(Rect r, float amount) { r.pos.x -= amount; r.pos.y -= amount; diff --git a/util.h b/util.h index 1278e87..aba98bc 100644 --- a/util.h +++ b/util.h @@ -212,7 +212,17 @@ void rect_coords(Rect r, float *x1, float *y1, float *x2, float *y2); void rect_print(Rect r); float rects_intersect(Rect r1, Rect r2); bool rect_clip_to_rect(Rect *clipped, Rect clipper); +/// removes `amount` from all sides of r Rect rect_shrink(Rect r, float amount); +/// removes `amount` from the left side of r +Rect rect_shrink_left(Rect r, float amount); +/// removes `amount` from the top side of r +Rect rect_shrink_top(Rect r, float amount); +/// removes `amount` from the right side of r +Rect rect_shrink_right(Rect r, float amount); +/// removes `amount` from the bottom side of r +Rect rect_shrink_bottom(Rect r, float amount); +/// adds `amount` to all sides of r Rect rect_grow(Rect r, float amount); vec4 color_rgba_to_hsva(vec4 rgba); vec4 color_hsva_to_rgba(vec4 hsva); -- cgit v1.2.3