summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-08-04 20:52:10 -0400
committerpommicket <pommicket@gmail.com>2023-08-04 20:52:10 -0400
commitce199f9384f9f9376417110574a07cfd731e3a79 (patch)
treed87a14a789eea521252447cd6dd477295e5612b9
parent4cdbd1c8caf7fbd9ed584049312241a0e039e115 (diff)
use dynamic arrays for mouse_clicks/mouse_releases
simplifies code
-rw-r--r--buffer.c4
-rw-r--r--ide-autocomplete.c9
-rw-r--r--main.c113
-rw-r--r--node.c30
-rw-r--r--ted.c7
-rw-r--r--ted.h20
-rw-r--r--ui.c25
7 files changed, 107 insertions, 101 deletions
diff --git a/buffer.c b/buffer.c
index df9f7f6..39bc1dd 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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]]);
diff --git a/main.c b/main.c
index 98c830d..23e6071 100644
--- a/main.c
+++ b/main.c
@@ -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);
diff --git a/node.c b/node.c
index 43e83fc..7d8a71a 100644
--- a/node.c
+++ b/node.c
@@ -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);
diff --git a/ted.c b/ted.c
index 2322987..e952ece 100644
--- a/ted.c
+++ b/ted.c
@@ -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;
diff --git a/ted.h b/ted.h
index 629a2c1..2a78e1f 100644
--- a/ted.h
+++ b/ted.h
@@ -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
diff --git a/ui.c b/ui.c
index abcfad7..636f164 100644
--- a/ui.c
+++ b/ui.c
@@ -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));