diff options
-rw-r--r-- | buffer.c | 12 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | node.c | 46 | ||||
-rw-r--r-- | ted.h | 4 |
4 files changed, 56 insertions, 11 deletions
@@ -2068,6 +2068,13 @@ u32 buffer_last_rendered_line(TextBuffer *buffer) { // Render the text buffer in the given rectangle void buffer_render(TextBuffer *buffer, Rect r) { + if (r.size.x < 1 || r.size.y < 1) { + // rectangle less than 1 pixel + // set x1,y1,x2,y2 to an size 0 rectangle + buffer->x1 = buffer->x2 = r.pos.x; + buffer->y1 = buffer->y2 = r.pos.y; + } + float x1, y1, x2, y2; rect_coords(r, &x1, &y1, &x2, &y2); // Correct the scroll, because the window size might have changed @@ -2096,6 +2103,8 @@ void buffer_render(TextBuffer *buffer, Rect r) { float line_number_width = ndigits_u64(buffer->nlines) * char_width + padding; TextRenderState text_state = text_render_state_default; + text_state.min_x = x1; + text_state.max_x = x2; text_state.min_y = y1; text_state.max_y = y2; @@ -2121,7 +2130,10 @@ void buffer_render(TextBuffer *buffer, Rect r) { x1 += border_thickness; } + if (x2 < x1) x2 = x1; + if (y2 < y1) y2 = y1; buffer->x1 = x1; buffer->y1 = y1; buffer->x2 = x2; buffer->y2 = y2; + if (x1 == x2 || y1 == y2) return; // 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)) { @@ -380,7 +380,7 @@ int main(int argc, char **argv) { { // get mouse position int mouse_x = 0, mouse_y = 0; - SDL_GetMouseState(&mouse_x, &mouse_y); + ted->mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y); ted->mouse_pos = V2((float)mouse_x, (float)mouse_y); } bool ctrl_down = keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL]; @@ -528,8 +528,7 @@ int main(int argc, char **argv) { // default to arrow cursor ted->cursor = ted->cursor_arrow; - - if (!(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LMASK)) { + if (!(ted->mouse_state & SDL_BUTTON_LMASK)) { // originally this was done on SDL_MOUSEBUTTONUP events but for some reason // I was getting a bunch of those even when I was holding down the mouse. // This makes it much smoother. @@ -96,6 +96,8 @@ static void node_join(Ted *ted, Node *node) { } static void node_close(Ted *ted, u16 node_idx) { + ted->resizing_split = NULL; + assert(node_idx < TED_MAX_NODES); assert(ted->nodes_used[node_idx]); i32 parent_idx = node_parent(ted, node_idx); @@ -172,9 +174,9 @@ static bool node_tab_close(Ted *ted, Node *node, u16 index) { } static void node_frame(Ted *ted, Node *node, Rect r) { + Settings const *settings = &ted->settings; if (node->tabs) { bool is_active = node == ted->active_node; - Settings const *settings = &ted->settings; u32 const *colors = settings->colors; Font *font = ted->font; float const border_thickness = settings->border_thickness; @@ -265,28 +267,56 @@ static void node_frame(Ted *ted, Node *node, Rect r) { buffer_rect.size.y -= tab_bar_height; buffer_render(buffer, buffer_rect); } else { + float padding = settings->padding; // this node is a split Node *a = &ted->nodes[node->split_a]; Node *b = &ted->nodes[node->split_b]; Rect r1 = r, r2 = r; + SDL_Cursor *resize_cursor = node->split_vertical ? ted->cursor_resize_v : ted->cursor_resize_h; + if (node == ted->resizing_split) { + if (!(ted->mouse_state & SDL_BUTTON_LMASK)) { + // let go of mouse + ted->resizing_split = NULL; + } else { + // resize the split + float mouse_coord = node->split_vertical ? ted->mouse_pos.y : ted->mouse_pos.x; + float rect_coord1 = (node->split_vertical ? rect_y1 : rect_x1)(r); + float rect_coord2 = (node->split_vertical ? rect_y2 : rect_x2)(r); + // make sure the split doesn't make one of the sides too small + float min_split = 10.0f / (node->split_vertical ? r.size.y : r.size.x); + node->split_pos = clampf(normf(mouse_coord, rect_coord1, rect_coord2), min_split, 1-min_split); + } + } + Rect r_between; // rectangle of space between r1 and r2 if (node->split_vertical) { float split_pos = r.size.y * node->split_pos; - r1.size.y = split_pos; - r2.pos.y += split_pos; - r2.size.y = r.size.y - split_pos; + r1.size.y = split_pos - padding; + r2.pos.y += split_pos + padding; + r2.size.y = r.size.y - split_pos - padding; + r_between = rect(V2(r.pos.x, r.pos.y + split_pos - padding), V2(r.size.x, 2 * padding)); } else { float split_pos = r.size.x * node->split_pos; - r1.size.x = split_pos; - r2.pos.x += split_pos; - r2.size.x = r.size.x - split_pos; + r1.size.x = split_pos - padding; + r2.pos.x += split_pos + padding; + r2.size.x = r.size.x - split_pos - padding; + r_between = rect(V2(r.pos.x + split_pos - padding, r.pos.y), V2(2 * padding, r.size.y)); + } + 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; + } + } + node_frame(ted, a, r1); node_frame(ted, b, r2); } } static void node_split(Ted *ted, Node *node, bool vertical) { - if (node_depth(ted, (u16)(node - ted->nodes)) >= 6) return; // prevent splitting too deep + if (node_depth(ted, (u16)(node - ted->nodes)) >= 5) return; // prevent splitting too deep if (arr_len(node->tabs) > 1) { // need at least 2 tabs to split i32 left_idx = ted_new_node(ted); @@ -241,6 +241,7 @@ typedef struct Ted { float window_width, window_height; u32 key_modifier; // which of shift, alt, ctrl are down right now. v2 mouse_pos; + u32 mouse_state; u8 nmouse_clicks[4]; // nmouse_clicks[i] = length of mouse_clicks[i] 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 @@ -278,6 +279,9 @@ typedef struct Ted { SDL_Cursor *cursor_arrow, *cursor_ibeam, *cursor_resize_h, *cursor_resize_v; SDL_Cursor *cursor; // which cursor to use this frame + // if not NULL, points to the node whose split the user is currently resizing. + Node *resizing_split; + char **tag_selector_entries; // an array of all tags (see tag_selector_open) // points to a selector if any is open, otherwise NULL. |