From 518851c0cde788a807e640377a7093ab4e8c5b5f Mon Sep 17 00:00:00 2001 From: pommicket Date: Sat, 5 Aug 2023 22:58:57 -0400 Subject: more dynamic menus (menus are currently broken) --- buffer.c | 6 ++-- command.c | 12 +++---- find.c | 2 +- ide-rename-symbol.c | 3 +- main.c | 8 ++--- menu.c | 92 +++++++++++++++++++++++++++++++++++++++++++---------- node.c | 2 +- ted-internal.h | 6 ++-- ted.c | 2 +- ted.h | 54 +++++++++++++++++-------------- 10 files changed, 126 insertions(+), 61 deletions(-) diff --git a/buffer.c b/buffer.c index 070a40e..65461e7 100644 --- a/buffer.c +++ b/buffer.c @@ -2904,7 +2904,7 @@ bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times) { } if (buffer_pixels_to_pos(buffer, click, &buffer_pos)) { // user clicked on buffer - if (!ted->menu || buffer->is_line_buffer) { + if (!menu_is_any_open(ted) || buffer->is_line_buffer) { ted_switch_to_buffer(ted, buffer); } if (buffer == ted->active_buffer) { @@ -3080,7 +3080,7 @@ void buffer_render(TextBuffer *buffer, Rect r) { } // change cursor to ibeam when it's hovering over the buffer - if ((!ted->menu || buffer == &ted->line_buffer) && rect_contains_point(rect4(x1, y1, x2, y2), ted->mouse_pos)) { + if ((!menu_is_any_open(ted) || buffer == &ted->line_buffer) && rect_contains_point(rect4(x1, y1, x2, y2), ted->mouse_pos)) { ted->cursor = ted->cursor_ibeam; } @@ -3090,7 +3090,7 @@ void buffer_render(TextBuffer *buffer, Rect r) { buffer->center_cursor_next_frame = false; } - if (rect_contains_point(rect4(x1, y1, x2, y2), ted->mouse_pos) && !ted->menu) { + if (rect_contains_point(rect4(x1, y1, x2, y2), ted->mouse_pos) && !menu_is_any_open(ted)) { // scroll with mouse wheel double scroll_speed = 2.5; buffer_scroll(buffer, ted->scroll_total_x * scroll_speed, ted->scroll_total_y * scroll_speed); diff --git a/command.c b/command.c index 65ca61f..084981a 100644 --- a/command.c +++ b/command.c @@ -203,14 +203,14 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen break; case CMD_UP: if (ted->selector_open) selector_up(ted, ted->selector_open, argument); - else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) + else if (menu_is_open(ted, MENU_SHELL) && buffer == &ted->line_buffer) menu_shell_up(ted); else if (buffer) buffer_cursor_move_up(buffer, argument); autocomplete_close(ted); break; case CMD_DOWN: if (ted->selector_open) selector_down(ted, ted->selector_open, argument); - else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) + else if (menu_is_open(ted, MENU_SHELL) && buffer == &ted->line_buffer) menu_shell_down(ted); else if (buffer) buffer_cursor_move_down(buffer, argument); autocomplete_close(ted); @@ -328,7 +328,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen if (ted->replace && buffer == &ted->find_buffer) { ted_switch_to_buffer(ted, &ted->replace_buffer); buffer_select_all(buffer); - } else if (ted->menu == MENU_COMMAND_SELECTOR && buffer == &ted->argument_buffer) { + } else if (menu_is_open(ted, MENU_COMMAND_SELECTOR) && buffer == &ted->argument_buffer) { buffer = &ted->line_buffer; ted_switch_to_buffer(ted, buffer); buffer_select_all(buffer); @@ -345,7 +345,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen if (ted->replace && buffer == &ted->replace_buffer) { ted_switch_to_buffer(ted, &ted->find_buffer); buffer_select_all(buffer); - } else if (ted->menu == MENU_COMMAND_SELECTOR && buffer == &ted->line_buffer) { + } else if (menu_is_open(ted, MENU_COMMAND_SELECTOR) && buffer == &ted->line_buffer) { buffer = &ted->argument_buffer; ted_switch_to_buffer(ted, buffer); buffer_select_all(buffer); @@ -563,7 +563,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen break; case CMD_TAB_CLOSE: { - if (ted->menu) { + if (menu_is_any_open(ted)) { menu_close(ted); } else if (ted->find) { find_close(ted); @@ -629,7 +629,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen *ted->message_shown = '\0'; } else if (autocomplete_is_open(ted)) { autocomplete_close(ted); - } else if (ted->menu) { + } else if (menu_is_any_open(ted)) { menu_escape(ted); } else { if (ted->find) { diff --git a/find.c b/find.c index d6eb406..759cd05 100644 --- a/find.c +++ b/find.c @@ -457,7 +457,7 @@ void find_menu_frame(Ted *ted, Rect menu_bounds) { } void find_open(Ted *ted, bool replace) { - if (ted->menu) return; + if (menu_is_any_open(ted)) return; if (ted->active_buffer == &ted->build_buffer) return; if (!ted->find) ted->prev_active_buffer = ted->active_buffer; diff --git a/ide-rename-symbol.c b/ide-rename-symbol.c index 2d95df8..b3ef52b 100644 --- a/ide-rename-symbol.c +++ b/ide-rename-symbol.c @@ -122,7 +122,6 @@ void rename_symbol_process_lsp_response(Ted *ted, const LSPResponse *response) { } rename_symbol_clear(ted); - printf("aeiou\n"); - if (ted->menu == MENU_RENAME_SYMBOL) + if (menu_is_open(ted, MENU_RENAME_SYMBOL)) menu_close(ted); } diff --git a/main.c b/main.c index 55fb94a..6e3f46b 100644 --- a/main.c +++ b/main.c @@ -683,7 +683,7 @@ int main(int argc, char **argv) { // we need to do this here, and not in buffer_render, because ctrl+click (go to definition) // could switch to a different buffer. // line buffer click handling, IS done in buffer_render (yes this is less than ideal) - if (!ted->menu) { + if (!menu_is_any_open(ted)) { for (u32 i = 0; i < TED_MAX_NODES; ++i) { if (ted->nodes_used[i]) { Node *node = &ted->nodes[i]; @@ -864,7 +864,7 @@ int main(int argc, char **argv) { buffer_scroll(active_buffer, +scroll_amount_x, 0); } - if (ted->menu) { + if (menu_is_any_open(ted)) { menu_update(ted); } @@ -1031,7 +1031,7 @@ int main(int argc, char **argv) { if (arr_len(ted->mouse_releases[SDL_BUTTON_LEFT])) ted->dragging_tab_node = NULL; - if (ted->menu) { + if (menu_is_any_open(ted)) { menu_render(ted); } @@ -1187,7 +1187,7 @@ int main(int argc, char **argv) { if (ted->find) find_close(ted); build_stop(ted); - if (ted->menu) + if (menu_is_any_open(ted)) menu_close(ted); hover_quit(ted); signature_help_quit(ted); diff --git a/menu.c b/menu.c index 426f5df..3ec19a6 100644 --- a/menu.c +++ b/menu.c @@ -2,7 +2,30 @@ #include "ted-internal.h" +bool menu_is_open(Ted *ted, const char *menu_name) { + if (!menu_is_any_open(ted)) + return false; + return streq(ted->all_menus[ted->menu_open_idx].name, menu_name); +} + +bool menu_is_any_open(Ted *ted) { + return ted->menu_open_idx > 0; +} + +void *menu_get_context(Ted *ted) { + return ted->menu_context; +} + 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; + ted_switch_to_buffer(ted, ted->prev_active_buffer); TextBuffer *buffer = ted->active_buffer; ted->prev_active_buffer = NULL; @@ -10,6 +33,7 @@ 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_NONE: assert(0); break; case MENU_OPEN: @@ -43,21 +67,38 @@ void menu_close(Ted *ted) { rename_symbol_clear(ted); buffer_clear(&ted->line_buffer); break; - } - ted->menu = MENU_NONE; + }*/ + ted->menu_open_idx = 0; + ted->menu_context = NULL; ted->selector_open = NULL; } -void menu_open(Ted *ted, Menu menu) { - if (ted->menu == menu) +void menu_open_with_context(Ted *ted, const char *menu_name, void *context) { + u32 menu_idx = U32_MAX; + for (u32 i = 0; i < arr_len(ted->all_menus); ++i) { + if (streq(ted->all_menus[i].name, menu_name)) { + menu_idx = i; + break; + } + } + if (menu_idx == U32_MAX) { + ted_error(ted, "No such menu: %s", menu_name); + return; + } + + if (menu_is_open(ted, menu_name)) return; - if (ted->menu) + if (menu_is_any_open(ted)) menu_close(ted); + if (ted->find) find_close(ted); autocomplete_close(ted); - ted->menu = menu; + + const MenuInfo *info = &ted->all_menus[ted->menu_open_idx]; + ted->menu_open_idx = menu_idx; + ted->menu_context = context; TextBuffer *prev_buf = ted->prev_active_buffer = ted->active_buffer; if (prev_buf) ted->prev_active_buffer_scroll = Vec2d(prev_buf->scroll_x, prev_buf->scroll_y); @@ -65,6 +106,7 @@ void menu_open(Ted *ted, Menu menu) { ted_switch_to_buffer(ted, NULL); *ted->warn_overwrite = 0; // clear warn_overwrite buffer_clear(&ted->line_buffer); + /* switch (menu) { case MENU_NONE: assert(0); break; case MENU_OPEN: @@ -102,10 +144,17 @@ void menu_open(Ted *ted, Menu menu) { case MENU_RENAME_SYMBOL: ted_switch_to_buffer(ted, &ted->line_buffer); break; - } + }*/ + if (info->open) info->open(ted); +} + +void menu_open(Ted *ted, const char *menu_name) { + menu_open_with_context(ted, menu_name, NULL); } void menu_escape(Ted *ted) { + if (!menu_is_any_open(ted)) return; + if (*ted->warn_overwrite) { // just close "are you sure you want to overwrite?" *ted->warn_overwrite = 0; @@ -116,11 +165,16 @@ void menu_escape(Ted *ted) { } void menu_update(Ted *ted) { - Menu menu = ted->menu; + if (!menu_is_any_open(ted)) return; + + 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; - TextBuffer *line_buffer = &ted->line_buffer; - assert(menu); switch (menu) { case MENU_NONE: break; @@ -316,25 +370,28 @@ void menu_update(Ted *ted) { free(new_name); } break; - } + }*/ } void menu_render(Ted *ted) { - Menu menu = ted->menu; - assert(menu); const Settings *settings = ted_active_settings(ted); const u32 *colors = settings->colors; const float window_width = ted->window_width, window_height = ted->window_height; + const MenuInfo *info = &ted->all_menus[ted->menu_open_idx]; + // render backdrop + gl_geometry_rect(rect(Vec2(0, 0), Vec2(window_width, window_height)), colors[COLOR_MENU_BACKDROP]); + gl_geometry_draw(); + + 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); const float padding = settings->padding; - // render backdrop - gl_geometry_rect(rect(Vec2(0, 0), Vec2(window_width, window_height)), colors[COLOR_MENU_BACKDROP]); - gl_geometry_draw(); - if (*ted->warn_overwrite) { const char *path = ted->warn_overwrite; const char *filename = path_filename(path); @@ -496,6 +553,7 @@ void menu_render(Ted *ted) { buffer_render(&ted->line_buffer, rect4(x1, y1, x2, y2)); } break; } + */ } void menu_shell_move(Ted *ted, int direction) { diff --git a/node.c b/node.c index ac452e9..c44f1ad 100644 --- a/node.c +++ b/node.c @@ -218,7 +218,7 @@ void node_frame(Ted *ted, Node *node, Rect r) { { // tab bar u16 ntabs = (u16)arr_len(node->tabs); float tab_width = r.size.x / ntabs; - if (!ted->menu) { + if (!menu_is_any_open(ted)) { arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], MouseClick, click) { if (rect_contains_point(tab_bar_rect, click->pos)) { // click on tab to switch to it diff --git a/ted-internal.h b/ted-internal.h index 11bdbcf..bb76a3c 100644 --- a/ted-internal.h +++ b/ted-internal.h @@ -447,8 +447,10 @@ struct Ted { MouseRelease *mouse_releases[4]; /// total amount scrolled this frame int scroll_total_x, scroll_total_y; - /// currently open menu, or \ref MENU_NONE if no menu is open. - Menu menu; + MenuInfo *all_menus; + /// index of currently open menu, or 0 if no menu is open + u32 menu_open_idx; + void *menu_context; FileSelector file_selector; Selector command_selector; /// general-purpose line buffer for inputs -- used for menus diff --git a/ted.c b/ted.c index 10567eb..e2d4285 100644 --- a/ted.c +++ b/ted.c @@ -676,7 +676,7 @@ void ted_reload_all(Ted *ted) { } } } - if (ted->menu == MENU_ASK_RELOAD) { + if (menu_is_open(ted, MENU_ASK_RELOAD)) { menu_close(ted); } } diff --git a/ted.h b/ted.h index b05b43e..1213724 100644 --- a/ted.h +++ b/ted.h @@ -224,28 +224,24 @@ typedef enum { MESSAGE_ERROR = 0x30000, } MessageType; -typedef enum { - /// No menu is open - MENU_NONE, - /// "Open file" - MENU_OPEN, - /// "Save file as" - MENU_SAVE_AS, - /// "X has unsaved changes" - MENU_WARN_UNSAVED, - /// "X has been changed by another program" - MENU_ASK_RELOAD, - /// "Go to definition of..." - MENU_GOTO_DEFINITION, - /// "Go to line" - MENU_GOTO_LINE, - /// "Command palette" - MENU_COMMAND_SELECTOR, - /// "Run a shell command" - MENU_SHELL, - /// "Rename symbol" - MENU_RENAME_SYMBOL, -} Menu; +/// "Open file" +#define MENU_OPEN "ted-open-file" +/// "Save file as" +#define MENU_SAVE_AS "ted-save-as" +/// "X has unsaved changes" +#define MENU_WARN_UNSAVED "ted-warn-unsaved" +/// "X has been changed by another program" +#define MENU_ASK_RELOAD "ted-ask-reload" +/// "Go to definition of..." +#define MENU_GOTO_DEFINITION "ted-goto-defn" +/// "Go to line" +#define MENU_GOTO_LINE "ted-goto-line" +/// "Command palette" +#define MENU_COMMAND_SELECTOR "ted-cmd-sel" +/// "Run a shell command" +#define MENU_SHELL "ted-shell" +/// "Rename symbol" +#define MENU_RENAME_SYMBOL "ted-rename-sym" /// Information about a programming language /// @@ -266,7 +262,9 @@ typedef struct { typedef struct { /// identifier used to open the menu. - char name[16]; + /// + /// try to pick a unique name. + char name[24]; /// if non-NULL this will be called right after the menu is opened void (*open)(Ted *ted); /// if non-NULL this will be called every frame @@ -796,7 +794,15 @@ void macro_execute(Ted *ted, u32 index); // === menu.c === void menu_close(Ted *ted); -void menu_open(Ted *ted, Menu menu); +void menu_open(Ted *ted, const char *menu_name); +void menu_open_with_context(Ted *ted, const char *menu_name, void *context); +/// get the `context` value passed to the last \ref menu_open_with_context, +/// or `NULL` if no menu is open. +void *menu_get_context(Ted *ted); +/// is this menu open? +bool menu_is_open(Ted *ted, const char *menu_name); +/// is any menu open? +bool menu_is_any_open(Ted *ted); /// process a :escape command (by default this happens when the escape key is pressed) void menu_escape(Ted *ted); /// get rectangle which menu takes up -- cgit v1.2.3