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));
 			}