diff options
-rw-r--r-- | arr.c | 4 | ||||
-rw-r--r-- | main.c | 9 | ||||
-rw-r--r-- | node.c | 63 | ||||
-rw-r--r-- | ted.h | 2 |
4 files changed, 64 insertions, 14 deletions
@@ -195,6 +195,10 @@ static void *arr_remove_(void *arr, size_t member_size, size_t index) { #define arr_qsort(a, cmp) qsort((a), arr_len(a), sizeof *(a), (cmp)) #define arr_remove_last(a) do { assert(a); if (--arr_hdr_(a)->len == 0) arr_free(a); } while (0) #define arr_remove(a, i) (void)((a) = arr_remove_((a), sizeof *(a), (i))) +#define arr_insert(a, i, x) do { u32 _index = (i); (a) = arr_cast_typeof(a) arr_grow1_((a), sizeof *(a)); \ + if (a) { memmove((a) + _index + 1, (a) + _index, (arr_len(a) - _index) * sizeof *(a));\ + (a)[_index] = x; \ + ++arr_hdr_(a)->len; } } while (0) #define arr_pop_last(a) ((a)[--arr_hdr_(a)->len]) #define arr_size_in_bytes(a) (arr_len(a) * sizeof *(a)) #define arr_lastp(a) ((a) ? &(a)[arr_len(a)-1] : NULL) @@ -1,5 +1,4 @@ // @TODO: -// - move tabs between nodes // - :split-swap // - fix: ctrl+f something, then switch to another tab (hl rects still showing up) @@ -391,6 +390,7 @@ int main(int argc, char **argv) { bool alt_down = keyboard_state[SDL_SCANCODE_LALT] || keyboard_state[SDL_SCANCODE_RALT]; memset(ted->nmouse_clicks, 0, sizeof ted->nmouse_clicks); + memset(ted->nmouse_releases, 0, sizeof ted->nmouse_releases); ted->scroll_total_x = ted->scroll_total_y = 0; ted_update_window_dimensions(ted); @@ -494,6 +494,13 @@ int main(int argc, char **argv) { } } } break; + case SDL_MOUSEBUTTONUP: { + Uint8 button = event.button.button; + v2 pos = V2((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; + } + } break; case SDL_MOUSEMOTION: { float x = (float)event.motion.x, y = (float)event.motion.y; if (ted->drag_buffer != ted->active_buffer) @@ -198,7 +198,7 @@ static void node_frame(Ted *ted, Node *node, Rect r) { if (rect_contains_point(tab_bar_rect, click)) { // click on tab to switch to it u16 tab_index = (u16)((click.x - r.pos.x) / tab_width); - if (tab_index >= 0 && tab_index < arr_len(node->tabs)) { + if (tab_index < arr_len(node->tabs)) { ted->active_node = node; node_switch_to_tab(ted, node, tab_index); ted->dragging_tab_node = node; @@ -207,25 +207,62 @@ static void node_frame(Ted *ted, Node *node, Rect r) { } } } + if (ted->dragging_tab_node) { + // check if user dropped tab here + for (u16 c = 0; c < ted->nmouse_releases[SDL_BUTTON_LEFT]; ++c) { + v2 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); + if (tab_index <= arr_len(node->tabs)) { + Node *drag_node = ted->dragging_tab_node; + u16 drag_index = ted->dragging_tab_idx; + u16 tab = drag_node->tabs[drag_index]; + + // remove the old tab + arr_remove(drag_node->tabs, drag_index); + if (node == drag_node) { + // fix index if we move tab from one place to another in the same node + if (tab_index > drag_index) + --tab_index; + } + // insert the tab here + arr_insert(node->tabs, tab_index, tab); + if (arr_len(drag_node->tabs) == 0) { + // removed the last tab from a node; close it + node_close(ted, (u16)(drag_node - ted->nodes)); + } else { + // make sure active tab is valid + drag_node->active_tab = clamp_u16(drag_node->active_tab, 0, (u16)arr_len(drag_node->tabs) - 1); + } + + ted->dragging_tab_node = NULL; // stop dragging + // switch to this buffer + ted_switch_to_buffer(ted, tab); + } + } + } + } for (u16 c = 0; c < ted->nmouse_clicks[SDL_BUTTON_MIDDLE]; ++c) { // middle-click to close tab v2 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); - u16 buffer_idx = node->tabs[tab_index]; - TextBuffer *buffer = &ted->buffers[buffer_idx]; - // close that tab - if (buffer_unsaved_changes(buffer)) { - // make sure unsaved changes dialog is opened - ted_switch_to_buffer(ted, buffer_idx); - command_execute(ted, CMD_TAB_CLOSE, 1); - } else { - if (!node_tab_close(ted, node, tab_index)) { - return; // node closed + if (tab_index < arr_len(node->tabs)) { + u16 buffer_idx = node->tabs[tab_index]; + TextBuffer *buffer = &ted->buffers[buffer_idx]; + // close that tab + if (buffer_unsaved_changes(buffer)) { + // make sure unsaved changes dialog is opened + ted_switch_to_buffer(ted, buffer_idx); + command_execute(ted, CMD_TAB_CLOSE, 1); + } else { + if (!node_tab_close(ted, node, tab_index)) { + return; // node closed + } } + ntabs = (u16)arr_len(node->tabs); + tab_width = r.size.x / ntabs; } - ntabs = (u16)arr_len(node->tabs); - tab_width = r.size.x / ntabs; } } } @@ -247,6 +247,8 @@ typedef struct Ted { v2 mouse_clicks[4][32]; // mouse_clicks[SDL_BUTTON_RIGHT], for example, is all the right mouse-clicks that have happened this frame // number of times mouse was clicked at each position u8 mouse_click_times[4][32]; + u8 nmouse_releases[4]; + v2 mouse_releases[4][32]; int scroll_total_x, scroll_total_y; // total amount scrolled in the x and y direction this frame Menu menu; FileSelector file_selector; |