summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--buffer.c12
-rw-r--r--main.c5
-rw-r--r--node.c46
-rw-r--r--ted.h4
4 files changed, 56 insertions, 11 deletions
diff --git a/buffer.c b/buffer.c
index c14389b..c7e5ce3 100644
--- a/buffer.c
+++ b/buffer.c
@@ -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)) {
diff --git a/main.c b/main.c
index 70200f2..724c2e8 100644
--- a/main.c
+++ b/main.c
@@ -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.
diff --git a/node.c b/node.c
index 7ecfef5..f8c6d55 100644
--- a/node.c
+++ b/node.c
@@ -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);
diff --git a/ted.h b/ted.h
index cdfa433..798734f 100644
--- a/ted.h
+++ b/ted.h
@@ -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.