diff options
-rw-r--r-- | buffer.c | 4 | ||||
-rw-r--r-- | ide-autocomplete.c | 9 | ||||
-rw-r--r-- | main.c | 113 | ||||
-rw-r--r-- | node.c | 30 | ||||
-rw-r--r-- | ted.c | 7 | ||||
-rw-r--r-- | ted.h | 20 | ||||
-rw-r--r-- | ui.c | 25 |
7 files changed, 107 insertions, 101 deletions
@@ -3014,8 +3014,8 @@ void buffer_render(TextBuffer *buffer, Rect r) { if (buffer->is_line_buffer) { // handle clicks // this is only done for line buffers, so that ctrl+click works properly (and happens in one frame). - for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - buffer_handle_click(ted, buffer, ted->mouse_clicks[SDL_BUTTON_LEFT][i], ted->mouse_click_times[SDL_BUTTON_LEFT][i]); + arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], MouseClick, click) { + buffer_handle_click(ted, buffer, click->pos, click->times); } } diff --git a/ide-autocomplete.c b/ide-autocomplete.c index b8898d5..ee0ebf3 100644 --- a/ide-autocomplete.c +++ b/ide-autocomplete.c @@ -608,11 +608,10 @@ void autocomplete_frame(Ted *ted) { } } - - for (uint i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - vec2 click = ted->mouse_clicks[SDL_BUTTON_LEFT][i]; - if (rect_contains_point(ac->rect, click)) { - i32 entry = scroll + (i32)((click.y - start_y) / char_height); + arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], MouseClick, click) { + vec2 pos = click->pos; + if (rect_contains_point(ac->rect, pos)) { + i32 entry = scroll + (i32)((pos.y - start_y) / char_height); if (entry >= 0 && entry < (i32)ncompletions) { // entry was clicked on! use this completion. autocomplete_complete(ted, ac->completions[ac->suggested[entry]]); @@ -1,6 +1,6 @@ /* TODO: -- use dynamic arrays for mouse_presses etc. +- cache buffer settings FUTURE FEATURES: - autodetect indentation (tabs vs spaces) @@ -602,8 +602,11 @@ int main(int argc, char **argv) { ted->mouse_pos = Vec2((float)mouse_x, (float)mouse_y); } - memset(ted->nmouse_clicks, 0, sizeof ted->nmouse_clicks); - memset(ted->nmouse_releases, 0, sizeof ted->nmouse_releases); + for (size_t i = 0; i < arr_count(ted->mouse_clicks); ++i) + arr_clear(ted->mouse_clicks[i]); + for (size_t i = 0; i < arr_count(ted->mouse_releases); ++i) + arr_clear(ted->mouse_releases[i]); + ted->scroll_total_x = ted->scroll_total_y = 0; ted_update_window_dimensions(ted); @@ -656,63 +659,65 @@ int main(int argc, char **argv) { ted_press_key(ted, KEYCODE_X2, key_modifier); } - if (button < arr_count(ted->nmouse_clicks) - && ted->nmouse_clicks[button] < arr_count(ted->mouse_clicks[button])) { - vec2 pos = Vec2(x, y); - bool add = true; - if (*ted->message_shown) { - if (rect_contains_point(message_box_rect(ted), pos)) { - // clicked on message - if (button == SDL_BUTTON_LEFT) { - // dismiss message - *ted->message_shown = '\0'; - } - // don't let anyone else use this event - add = false; + if (button >= arr_count(ted->mouse_clicks)) break; + + vec2 pos = Vec2(x, y); + bool add = true; + if (*ted->message_shown) { + if (rect_contains_point(message_box_rect(ted), pos)) { + // clicked on message + if (button == SDL_BUTTON_LEFT) { + // dismiss message + *ted->message_shown = '\0'; } + // don't let anyone else use this event + add = false; } - - if (add) { - // handle mouse click - // 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) { - for (u32 i = 0; i < TED_MAX_NODES; ++i) { - if (ted->nodes_used[i]) { - Node *node = &ted->nodes[i]; - if (node->tabs) { - buffer = &ted->buffers[node->tabs[node->active_tab]]; - if (buffer_handle_click(ted, buffer, pos, times)) { - add = false; - break; - } + } + + if (add) { + // handle mouse click + // 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) { + for (u32 i = 0; i < TED_MAX_NODES; ++i) { + if (ted->nodes_used[i]) { + Node *node = &ted->nodes[i]; + if (node->tabs) { + buffer = &ted->buffers[node->tabs[node->active_tab]]; + if (buffer_handle_click(ted, buffer, pos, times)) { + add = false; + break; } } } - if (ted->build_shown) - if (buffer_handle_click(ted, &ted->build_buffer, pos, times)) // handle build buffer clicks - add = false; - } - if (add) { - ted->mouse_clicks[button][ted->nmouse_clicks[button]] = pos; - ted->mouse_click_times[button][ted->nmouse_clicks[button]] = times; - ++ted->nmouse_clicks[button]; } + if (add && ted->build_shown) + if (buffer_handle_click(ted, &ted->build_buffer, pos, times)) // handle build buffer clicks + add = false; } } + if (add) { + MouseClick click = { + .pos = pos, + .times = times, + }; + arr_add(ted->mouse_clicks[button], click); + } } break; case SDL_MOUSEBUTTONUP: { if (ted->recording_macro) break; // ignore mouse input during macros Uint8 button = event.button.button; - if (button < arr_count(ted->nmouse_releases)) { - vec2 pos = Vec2((float)event.button.x, (float)event.button.y); - if (ted->nmouse_releases[button] < arr_count(ted->mouse_releases[button])) { - ted->mouse_releases[button][ted->nmouse_releases[button]++] = pos; - } - } + if (button >= arr_count(ted->mouse_releases)) break; + + vec2 pos = Vec2((float)event.button.x, (float)event.button.y); + MouseRelease release = { + .pos = pos + }; + arr_add(ted->mouse_releases[button], release); } break; case SDL_MOUSEMOTION: { if (ted->recording_macro) @@ -989,11 +994,9 @@ int main(int argc, char **argv) { ted->cursor = ted->cursor_resize_v; } else { Rect gap = rect4(x1, y - padding, x2, y); - for (uint i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - if (rect_contains_point(gap, ted->mouse_clicks[SDL_BUTTON_LEFT][i])) { - // start resizing build output - ted->resizing_build_output = true; - } + if (ted_clicked_in_rect(ted, gap)) { + // start resizing build output + ted->resizing_build_output = true; } if (rect_contains_point(gap, ted->mouse_pos)) { ted->cursor = ted->cursor_resize_v; @@ -1027,7 +1030,7 @@ int main(int argc, char **argv) { } // stop dragging tab if mouse was released - if (ted->nmouse_releases[SDL_BUTTON_LEFT]) + if (arr_len(ted->mouse_releases[SDL_BUTTON_LEFT])) ted->dragging_tab_node = NULL; if (ted->menu) { @@ -1177,6 +1180,12 @@ int main(int argc, char **argv) { } + + for (size_t i = 0; i < arr_count(ted->mouse_clicks); ++i) + arr_clear(ted->mouse_clicks[i]); + for (size_t i = 0; i < arr_count(ted->mouse_releases); ++i) + arr_clear(ted->mouse_releases[i]); + if (ted->find) find_close(ted); build_stop(ted); @@ -215,26 +215,24 @@ void node_frame(Ted *ted, Node *node, Rect r) { u16 ntabs = (u16)arr_len(node->tabs); float tab_width = r.size.x / ntabs; if (!ted->menu) { - for (u16 c = 0; c < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++c) { - vec2 click = ted->mouse_clicks[SDL_BUTTON_LEFT][c]; - if (rect_contains_point(tab_bar_rect, click)) { + 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 - u16 tab_index = (u16)((click.x - r.pos.x) / tab_width); + u16 tab_index = (u16)((click->pos.x - r.pos.x) / tab_width); if (tab_index < arr_len(node->tabs)) { ted->active_node = node; node_switch_to_tab(ted, node, tab_index); ted->dragging_tab_node = node; ted->dragging_tab_idx = tab_index; - ted->dragging_tab_origin = click; + ted->dragging_tab_origin = click->pos; } } } if (ted->dragging_tab_node) { // check if user dropped tab here - for (u16 c = 0; c < ted->nmouse_releases[SDL_BUTTON_LEFT]; ++c) { - vec2 release = ted->mouse_releases[SDL_BUTTON_LEFT][c]; - if (rect_contains_point(tab_bar_rect, release)) { - u16 tab_index = (u16)roundf((release.x - r.pos.x) / tab_width); + arr_foreach_ptr(ted->mouse_releases[SDL_BUTTON_LEFT], MouseRelease, release) { + if (rect_contains_point(tab_bar_rect, release->pos)) { + u16 tab_index = (u16)roundf((release->pos.x - r.pos.x) / tab_width); if (tab_index <= arr_len(node->tabs)) { Node *drag_node = ted->dragging_tab_node; u16 drag_index = ted->dragging_tab_idx; @@ -264,11 +262,10 @@ void node_frame(Ted *ted, Node *node, Rect r) { } } } - for (u16 c = 0; c < ted->nmouse_clicks[SDL_BUTTON_MIDDLE]; ++c) { + arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_MIDDLE], MouseClick, click) { // middle-click to close tab - vec2 click = ted->mouse_clicks[SDL_BUTTON_MIDDLE][c]; - if (rect_contains_point(tab_bar_rect, click)) { - u16 tab_index = (u16)((click.x - r.pos.x) / tab_width); + if (rect_contains_point(tab_bar_rect, click->pos)) { + u16 tab_index = (u16)((click->pos.x - r.pos.x) / tab_width); if (tab_index < arr_len(node->tabs)) { u16 buffer_idx = node->tabs[tab_index]; TextBuffer *buffer = &ted->buffers[buffer_idx]; @@ -388,11 +385,8 @@ void node_frame(Ted *ted, Node *node, Rect r) { if (rect_contains_point(r_between, ted->mouse_pos)) { ted->cursor = resize_cursor; } - for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - if (rect_contains_point(r_between, ted->mouse_clicks[SDL_BUTTON_LEFT][i])) { - ted->resizing_split = node; - } - } + if (ted_clicked_in_rect(ted, r_between)) + ted->resizing_split = node; node_frame(ted, a, r1); node_frame(ted, b, r2); @@ -80,6 +80,13 @@ u32 ted_get_key_modifier(Ted *ted) { | alt_down << KEY_MODIFIER_ALT_BIT; } +bool ted_clicked_in_rect(Ted *ted, Rect rect) { + arr_foreach_ptr(ted->mouse_clicks[SDL_BUTTON_LEFT], MouseClick, click) { + if (rect_contains_point(rect, click->pos)) + return true; + } + return false; +} void ted_set_message(Ted *ted, MessageType type, const char *fmt, ...) { va_list args; @@ -748,6 +748,15 @@ typedef struct { #define TED_MACRO_MAX 256 +typedef struct { + vec2 pos; + u8 times; +} MouseClick; + +typedef struct { + vec2 pos; +} MouseRelease; + /// (almost) all data used by the ted application typedef struct Ted { /// all running LSP servers @@ -777,14 +786,9 @@ typedef struct Ted { float window_width, window_height; vec2 mouse_pos; u32 mouse_state; - /// `nmouse_clicks[i]` = length of `mouse_clicks[i]` - u8 nmouse_clicks[4]; /// `mouse_clicks[SDL_BUTTON_RIGHT]`, for example, is all the right mouse-clicks that have happened this frame - vec2 mouse_clicks[4][32]; - /// number of times mouse was clicked at each position - u8 mouse_click_times[4][32]; - u8 nmouse_releases[4]; - vec2 mouse_releases[4][32]; + MouseClick *mouse_clicks[4]; + 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. @@ -1650,6 +1654,8 @@ bool ted_is_shift_down(Ted *ted); bool ted_is_alt_down(Ted *ted); /// see \ref KEY_MODIFIER_CTRL, etc. u32 ted_get_key_modifier(Ted *ted); +/// was there a click in this rectangle this frame? +bool ted_clicked_in_rect(Ted *ted, Rect rect); /// display a message to the user void ted_set_message(Ted *ted, MessageType type, PRINTF_FORMAT_STRING const char *fmt, ...) ATTRIBUTE_PRINTF(3, 4); /// display an error to the user @@ -81,13 +81,11 @@ char *selector_update(Ted *ted, Selector *s) { // check if this entry was clicked on Rect entry_rect; if (selector_entry_pos(ted, s, i, &entry_rect)) { - for (uint c = 0; c < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++c) { - if (rect_contains_point(entry_rect, ted->mouse_clicks[SDL_BUTTON_LEFT][c])) { - // this option was selected - s->cursor = i; // indicate the index of the selected entry using s->cursor - ret = str_dup(s->entries[i].name); - break; - } + if (ted_clicked_in_rect(ted, entry_rect)) { + // this option was selected + s->cursor = i; // indicate the index of the selected entry using s->cursor + ret = str_dup(s->entries[i].name); + break; } } } @@ -552,12 +550,7 @@ void button_render(Ted *ted, Rect button, const char *text, u32 color) { } bool button_update(Ted *ted, Rect button) { - for (u16 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - if (rect_contains_point(button, ted->mouse_clicks[SDL_BUTTON_LEFT][i])) { - return true; - } - } - return false; + return ted_clicked_in_rect(ted, button); } static void popup_get_rects(Ted const *ted, u32 options, Rect *popup, Rect *button_yes, Rect *button_no, Rect *button_cancel) { @@ -656,10 +649,8 @@ vec2 checkbox_frame(Ted *ted, bool *value, const char *label, vec2 pos) { Rect checkbox_rect = rect(pos, Vec2(checkbox_size, checkbox_size)); - for (u32 i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { - if (rect_contains_point(checkbox_rect, ted->mouse_clicks[SDL_BUTTON_LEFT][i])) { - *value = !*value; - } + if (ted_clicked_in_rect(ted, checkbox_rect)) { + *value = !*value; } checkbox_rect.pos = vec2_add(checkbox_rect.pos, Vec2(0.5f, 0.5f)); |