commit 1e24e8b24d8dd6676dab036a858e5404c2dfdb10
parent 78088f20cdb93ead1b980f3a4092ce0a1227aafa
Author: lumidify <nobody@lumidify.org>
Date: Thu, 1 Apr 2021 20:12:19 +0200
Add scrollbar dragging
Diffstat:
M | ledit.c | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++---- |
1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/ledit.c b/ledit.c
@@ -93,7 +93,7 @@ static int cur_subline = 0;
static int cur_index = 0;
static int trailing = 0;
static int total_height = 0;
-static int cur_display_offset = 0;
+static double cur_display_offset = 0;
static void
init_line(struct line *l) {
@@ -189,6 +189,24 @@ static void change_keyboard(char *lang);
PangoAttrList *basic_attrs;
static void
+get_scroll_pos_height(double *pos, double *height) {
+ *height = ((double)state.h / total_height) * state.h;
+ *pos = (cur_display_offset / (total_height - state.h)) * (state.h - *height);
+}
+
+static void
+set_scroll_pos(double pos) {
+ cur_display_offset = pos * (total_height / (double)state.h);
+ if (cur_display_offset < 0)
+ cur_display_offset = 0;
+ if (cur_display_offset + state.h > total_height)
+ cur_display_offset = total_height - state.h;
+}
+
+static int scroll_dragging = 0;
+static int scroll_grab_handle = 0;
+
+static void
mainloop(void) {
XEvent event;
int xkb_event_type;
@@ -255,6 +273,18 @@ mainloop(void) {
switch (event.xbutton.button) {
case Button1:
button_press(event);
+ double scroll_h, scroll_y;
+ get_scroll_pos_height(&scroll_y, &scroll_h);
+ int x = event.xbutton.x;
+ int y = event.xbutton.y;
+ if (x >= state.w - 10) {
+ scroll_dragging = 1;
+ scroll_grab_handle = y;
+ if (y < scroll_y || y > scroll_y + scroll_h) {
+ double new_scroll_y = y - scroll_h / 2;
+ set_scroll_pos(new_scroll_y);
+ }
+ }
break;
case Button4:
cur_display_offset -= 10;
@@ -272,11 +302,21 @@ mainloop(void) {
need_redraw = 1;
break;
case ButtonRelease:
- if (event.xbutton.button == Button1)
+ if (event.xbutton.button == Button1) {
button_release();
+ scroll_dragging = 0;
+ }
break;
case MotionNotify:
drag_motion(event);
+ if (scroll_dragging) {
+ double scroll_h, scroll_y;
+ get_scroll_pos_height(&scroll_y, &scroll_h);
+ scroll_y += event.xbutton.y - scroll_grab_handle;
+ scroll_grab_handle = event.xbutton.y;
+ set_scroll_pos(scroll_y);
+ }
+ need_redraw = 1;
break;
case KeyPress:
need_redraw = 1;
@@ -374,8 +414,8 @@ mainloop(void) {
}
}
if (total_height > state.h) {
- double scroll_h = ((double)state.h / total_height) * state.h;
- double scroll_y = ((double)cur_display_offset / (total_height - state.h)) * (state.h - scroll_h);
+ double scroll_h, scroll_y;
+ get_scroll_pos_height(&scroll_y, &scroll_h);
XFillRectangle(state.dpy, state.back_buf, state.gc, state.w - 10, (int)round(scroll_y), 10, (int)round(scroll_h));
}