]> git.mdlowis.com Git - projs/tide.git/commitdiff
Generalized scrollbar behavior to hopefully apply to picker and editor with ease
authorMichael D. Lowis <mike.lowis@gentex.com>
Fri, 24 Mar 2017 17:07:35 +0000 (13:07 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Fri, 24 Mar 2017 17:07:35 +0000 (13:07 -0400)
inc/win.h
lib/view.c
lib/win.c
term.c
xedit.c

index fa7b94b88c6912ad95e69e83a5307300e720103b..4b59f67a726c554d5a5d003640af30d2fbc07f6c 100644 (file)
--- a/inc/win.h
+++ b/inc/win.h
@@ -44,8 +44,12 @@ Sel* win_sel(WinRegion id);
 bool win_btnpressed(MouseBtn btn);\r
 WinRegion win_getregion(void);\r
 void win_setregion(WinRegion id);\r
+void win_setscroll(double offset, double visible);\r
 \r
+/* These functions must be implemented by any appliation that wishes \r
+   to use this module */\r
 void onupdate(void);\r
+void onscroll(double percent);\r
 void onmouseleft(WinRegion id, size_t count, size_t row, size_t col);\r
 void onmousemiddle(WinRegion id, size_t count, size_t row, size_t col);\r
 void onmouseright(WinRegion id, size_t count, size_t row, size_t col);\r
index a816b221dfb4886b88a68c56d71093f330ffffa7..89b890667a1619009a2780926b6a5fef2260e331 100644 (file)
@@ -148,6 +148,8 @@ static void sync_view(View* view, size_t csr) {
         first = scroll_up(view);
     while (csr > last && last < buf_end(&(view->buffer)))
         last = scroll_dn(view);
+    while (buf_end(&(view->buffer)) && last > buf_end(&(view->buffer)))
+        last = scroll_up(view);
     view->sync_needed = false;
     if (view->sync_center) {
         sync_center(view, csr);
@@ -155,6 +157,14 @@ static void sync_view(View* view, size_t csr) {
     }
 }
 
+void view_jumpto(View* view, size_t off) {
+    size_t csrx, csry;
+    if (!view->nrows) return;
+    view->rows[0]->off = off;
+    view_update(view, &csrx, &csry);
+    sync_view(view, off);
+}
+
 static size_t getoffset(View* view, size_t row, size_t col) {
     Row* scrrow = view_getrow(view, row);
     if (!scrrow) return SIZE_MAX;
index b34f0a58c113c94d53badb4c2161804cb0a59351..939bfa969b7a738c281611635ccdf7b3ddec0144 100644 (file)
--- a/lib/win.c
+++ b/lib/win.c
@@ -21,6 +21,8 @@ static void onshutdown(void);
 static void onwheelup(WinRegion id, size_t count, size_t row, size_t col);
 static void onwheeldn(WinRegion id, size_t count, size_t row, size_t col);
 
+static double ScrollOffset = 0.0;
+static double ScrollVisible = 1.0;
 static XFont Font;
 static XConfig Config = {
     .redraw       = onredraw,
@@ -101,6 +103,11 @@ Sel* win_sel(WinRegion id) {
     return &(Regions[id].view.selection);
 }
 
+void win_setscroll(double offset, double visible) {
+    ScrollOffset  = offset;
+    ScrollVisible = visible;
+}
+
 static void layout(int width, int height) {
     size_t fheight = x11_font_height(Font);
     size_t fwidth  = x11_font_width(Font);
@@ -164,17 +171,9 @@ static void onredraw(int width, int height) {
     }
     
     /* draw the scroll region */
-    View* view = win_view(EDIT);
-    size_t bend = buf_end(win_buf(EDIT));
-    if (bend == 0) bend = 1;
-    size_t vbeg = view->rows[0]->off;
-    size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen;
-    size_t vtot = ((vend - vbeg) * 100) / bend;
-    if (vend > bend) vtot += 1;
-    size_t voff = (vbeg * 100 / bend);
     size_t thumbreg = (Regions[SCROLL].height - Regions[SCROLL].y + 9);
-    size_t thumboff = (thumbreg * voff / 100) + (Regions[SCROLL].y - 2);
-    size_t thumbsz  = (thumbreg * vtot / 100);
+    size_t thumboff = (size_t)((thumbreg * ScrollOffset) + (Regions[SCROLL].y - 2));
+    size_t thumbsz  = (size_t)(thumbreg * ScrollVisible);
     if (thumbsz < 5) thumbsz = 5;
     x11_draw_rect(CLR_BASE01, Regions[SCROLL].width, Regions[SCROLL].y - 2, 1, Regions[SCROLL].height);
     x11_draw_rect(CLR_BASE00, 0, Regions[SCROLL].y - 2, Regions[SCROLL].width, thumbreg);
@@ -228,12 +227,9 @@ static void onclick(MouseAct act, MouseBtn btn, int x, int y) {
             case MOUSE_BTN_LEFT:
                 view_scroll(win_view(EDIT), -row);
                 break;
-            case MOUSE_BTN_MIDDLE: {
-                    size_t bend = buf_end(win_buf(EDIT));
-                    size_t csrx, csry, chunksz = (bend > 0 ? bend : 1) / Regions[SCROLL].height;
-                    win_view(EDIT)->rows[0]->off = buf_bol(win_buf(EDIT), (y - Regions[SCROLL].y) * chunksz);
-                    view_update(win_view(EDIT), &csrx, &csry);
-                }
+            case MOUSE_BTN_MIDDLE: 
+                onscroll((double)(y - Regions[SCROLL].y) /
+                         (double)(Regions[SCROLL].height - Regions[SCROLL].y()));
                 break;
             case MOUSE_BTN_RIGHT:
                 view_scroll(win_view(EDIT), +row); 
diff --git a/term.c b/term.c
index 73c58d2b91ad1ae727e31159a6d3642334857e11..cbe35db40fcc3de23359dfe95666d02356e2a98e 100644 (file)
--- a/term.c
+++ b/term.c
@@ -27,6 +27,10 @@ void onmouseright(WinRegion id, size_t count, size_t row, size_t col) {
 //    }
 //};
 
+void onscroll(double percent) {
+
+}
+
 /* Keyboard Handling
  *****************************************************************************/
 
diff --git a/xedit.c b/xedit.c
index cca5d1d96e3a441d5983e56f442d1ebb0eb311e1..79831af52f1cf211b9577ba136c8124016893ce5 100644 (file)
--- a/xedit.c
+++ b/xedit.c
@@ -500,6 +500,12 @@ static KeyBinding Bindings[] = {
     { 0, 0, 0 }
 };
 
+void onscroll(double percent) {
+    size_t bend = buf_end(win_buf(EDIT));
+    size_t off  = (size_t)((double)bend * percent);
+    view_jumpto(win_view(EDIT), (off >= bend ? bend : off));    
+}
+
 void onupdate(void) {
     static char status_bytes[256];
     memset(status_bytes, 0, sizeof(status_bytes));
@@ -516,6 +522,17 @@ void onupdate(void) {
     size_t remlen = sizeof(status_bytes) - strlen(status_bytes) - 1;
     strncat(status, path, remlen);
     win_settext(STATUS, status_bytes);
+    
+    /* calculate and update scroll region */
+    View* view = win_view(EDIT);
+    size_t bend = buf_end(win_buf(EDIT));
+    if (bend == 0) bend = 1;
+    if (!view->rows) return;
+    size_t vbeg = view->rows[0]->off;
+    size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen;
+    double scroll_vis = (double)(vend - vbeg) / (double)bend;
+    double scroll_off = ((double)vbeg / (double)bend);
+    win_setscroll(scroll_off, scroll_vis);
 }
 
 #ifndef TEST