emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 170cae0e90: Fix scroll bar portion on Haiku scroll bars


From: Po Lu
Subject: master 170cae0e90: Fix scroll bar portion on Haiku scroll bars
Date: Thu, 10 Mar 2022 20:37:54 -0500 (EST)

branch: master
commit 170cae0e9080697e1efa1678bc1504890bcf4a6e
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Fix scroll bar portion on Haiku scroll bars
    
    * src/haiku_support.cc (EmacsScrollBar): Set steps to
    appropriate value.
    (ValueChanged): Test new value against old value before sending
    value event.
    (MessageReceived): Handle portion and range.
    (BView_scroll_bar_update): New argument for portion.
    * src/haiku_support.h: Update prototypes.
    * src/haikuterm.c (haiku_set_scroll_bar_thumb):
    (haiku_set_horizontal_scroll_bar_thumb): New functions.
    (haiku_set_horizontal_scroll_bar):
    (haiku_set_vertical_scroll_bar): Use those functions to set
    scroll bar values.
    (haiku_read_socket): Handle new meanings of scroll bar values.
    * src/haikuterm.h (struct scroll_bar):
---
 src/haiku_support.cc |  31 +++++++++++---
 src/haiku_support.h  |   3 +-
 src/haikuterm.c      | 118 ++++++++++++++++++++++++++++++++++++++++++---------
 src/haikuterm.h      |   2 +
 4 files changed, 127 insertions(+), 27 deletions(-)

diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 2f2adfd8f8..6f5196dc1c 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -1571,16 +1571,26 @@ public:
     vw->SetResizingMode (B_FOLLOW_NONE);
     horizontal = horizontal_p;
     get_scroll_bar_info (&info);
+    SetSteps (5000, 10000);
   }
 
   void
   MessageReceived (BMessage *msg)
   {
+    int32 portion, range;
+
     if (msg->what == SCROLL_BAR_UPDATE)
       {
        old_value = msg->GetInt32 ("emacs:units", 0);
-       this->SetRange (0, msg->GetInt32 ("emacs:range", 0));
-       this->SetValue (msg->GetInt32 ("emacs:units", 0));
+       portion = msg->GetInt32 ("emacs:portion", 0);
+       range = msg->GetInt32 ("emacs:range", 0);
+
+       if (!msg->GetBool ("emacs:dragging", false))
+         {
+           this->SetRange (0, range);
+           this->SetValue (old_value);
+           this->SetProportion ((float) portion / range);
+         }
       }
 
     BScrollBar::MessageReceived (msg);
@@ -1612,11 +1622,15 @@ public:
        return;
       }
 
-    rq.scroll_bar = this;
-    rq.window = Window ();
-    rq.position = new_value;
+    if (new_value != old_value)
+      {
+       rq.scroll_bar = this;
+       rq.window = Window ();
+       rq.position = new_value;
+       old_value = new_value;
 
-    haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
+       haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
+      }
   }
 
   BRegion
@@ -2269,13 +2283,16 @@ BView_move_frame (void *view, int x, int y, int x1, int 
y1)
 }
 
 void
-BView_scroll_bar_update (void *sb, int portion, int whole, int position)
+BView_scroll_bar_update (void *sb, int portion, int whole, int position,
+                        bool dragging)
 {
   BScrollBar *bar = (BScrollBar *) sb;
   BMessage msg = BMessage (SCROLL_BAR_UPDATE);
   BMessenger mr = BMessenger (bar);
   msg.AddInt32 ("emacs:range", whole);
   msg.AddInt32 ("emacs:units", position);
+  msg.AddInt32 ("emacs:portion", portion);
+  msg.AddBool ("emacs:dragging", dragging);
 
   mr.SendMessage (&msg);
 }
diff --git a/src/haiku_support.h b/src/haiku_support.h
index fb86372c4f..e7c55d4d75 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -628,7 +628,8 @@ extern "C"
   BView_move_frame (void *view, int x, int y, int x1, int y1);
 
   extern void
-  BView_scroll_bar_update (void *sb, int portion, int whole, int position);
+  BView_scroll_bar_update (void *sb, int portion, int whole, int position,
+                          bool dragging);
 
   extern int
   BScrollBar_default_size (int horizontal_p);
diff --git a/src/haikuterm.c b/src/haikuterm.c
index d3168129ce..b100952f11 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -40,6 +40,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <cairo.h>
 #endif
 
+/* Minimum and maximum values used for Haiku scroll bars.  */
+#define BE_SB_MAX 10000000
+
 struct haiku_display_info *x_display_list = NULL;
 extern frame_parm_handler haiku_frame_parm_handlers[];
 
@@ -428,6 +431,78 @@ haiku_mouse_or_wdesc_frame (void *window)
     }
 }
 
+/* Set the thumb size and position of scroll bar BAR.  We are
+   currently displaying PORTION out of a whole WHOLE, and our position
+   POSITION.  */
+
+static void
+haiku_set_scroll_bar_thumb (struct scroll_bar *bar, int portion,
+                           int position, int whole)
+{
+  void *scroll_bar = bar->scroll_bar;
+  float top, shown;
+  int size, value;
+
+  if (scroll_bar_adjust_thumb_portion_p)
+    {
+      /* We use an estimate of 30 chars per line rather than the real
+         `portion' value.  This has the disadvantage that the thumb
+         size is not very representative, but it makes our life a lot
+         easier.  Otherwise, we have to constantly adjust the thumb
+         size, which we can't always do quickly enough: while
+         dragging, the size of the thumb might prevent the user from
+         dragging the thumb all the way to the end.  */
+      portion = WINDOW_TOTAL_LINES (XWINDOW (bar->window)) * 30;
+      /* When the thumb is at the bottom, position == whole.  So we
+         need to increase `whole' to make space for the thumb.  */
+      whole += portion;
+    }
+
+  if (whole <= 0)
+    top = 0, shown = 1;
+  else
+    {
+      top = (float) position / whole;
+      shown = (float) portion / whole;
+    }
+
+  /* Slider size.  Must be in the range [1 .. MAX - MIN] where MAX
+     is the scroll bar's maximum and MIN is the scroll bar's minimum
+     value.  */
+  size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX);
+
+  /* Position.  Must be in the range [MIN .. MAX - SLIDER_SIZE].  */
+  value = top * BE_SB_MAX;
+  value = min (value, BE_SB_MAX - size);
+
+  if (!bar->dragging)
+    bar->page_size = size;
+
+  BView_scroll_bar_update (scroll_bar, size, BE_SB_MAX, value,
+                          bar->dragging);
+}
+
+static void
+haiku_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, int portion,
+                                      int position, int whole)
+{
+  void *scroll_bar = bar->scroll_bar;
+  float shown, top;
+  int size, value;
+
+  shown = (float) portion / whole;
+  top = (float) position / (whole - portion);
+
+  size = clip_to_bounds (1, shown * BE_SB_MAX, BE_SB_MAX);
+  value = clip_to_bounds (0, top * (BE_SB_MAX - size), BE_SB_MAX - size);
+
+  if (!bar->dragging)
+    bar->page_size = size;
+
+  BView_scroll_bar_update (scroll_bar, shown, BE_SB_MAX, value,
+                          bar->dragging);
+}
+
 static struct scroll_bar *
 haiku_scroll_bar_from_widget (void *scroll_bar, void *window)
 {
@@ -2211,7 +2286,6 @@ haiku_set_horizontal_scroll_bar (struct window *w, int 
portion, int whole, int p
   if (NILP (w->horizontal_scroll_bar))
     {
       bar = haiku_scroll_bar_create (w, left, top, width, height, true);
-      BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
       bar->update = position;
       bar->position = position;
       bar->total = whole;
@@ -2234,13 +2308,9 @@ haiku_set_horizontal_scroll_bar (struct window *w, int 
portion, int whole, int p
          bar->width = width;
          bar->height = height;
        }
-
-      if (!bar->dragging)
-       {
-         BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
-         BView_invalidate (bar->scroll_bar);
-       }
     }
+
+  haiku_set_horizontal_scroll_bar_thumb (bar, portion, position, whole);
   bar->position = position;
   bar->total = whole;
   XSETVECTOR (barobj, bar);
@@ -2271,7 +2341,6 @@ haiku_set_vertical_scroll_bar (struct window *w,
   if (NILP (w->vertical_scroll_bar))
     {
       bar = haiku_scroll_bar_create (w, left, top, width, height, false);
-      BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
       bar->position = position;
       bar->total = whole;
     }
@@ -2293,15 +2362,9 @@ haiku_set_vertical_scroll_bar (struct window *w,
          bar->width = width;
          bar->height = height;
        }
-
-      if (!bar->dragging)
-       {
-         BView_scroll_bar_update (bar->scroll_bar, portion, whole, position);
-         bar->update = position;
-         BView_invalidate (bar->scroll_bar);
-       }
     }
 
+  haiku_set_scroll_bar_thumb (bar, portion, position, whole);
   bar->position = position;
   bar->total = whole;
 
@@ -3191,6 +3254,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
            struct haiku_scroll_bar_value_event *b = buf;
            struct scroll_bar *bar
              = haiku_scroll_bar_from_widget (b->scroll_bar, b->window);
+           int portion, whole;
 
            if (!bar)
              continue;
@@ -3205,13 +3269,29 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
 
            if (bar->position != b->position)
              {
-               inev.kind = bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT 
:
-                 SCROLL_BAR_CLICK_EVENT;
+               inev.kind = (bar->horizontal
+                            ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT :
+                            SCROLL_BAR_CLICK_EVENT);
                inev.part = bar->horizontal ?
                  scroll_bar_horizontal_handle : scroll_bar_handle;
 
-               XSETINT (inev.x, b->position);
-               XSETINT (inev.y, bar->total);
+               if (bar->horizontal)
+                 {
+                   portion = bar->total * ((float) b->position
+                                           / BE_SB_MAX);
+                   whole = (bar->total
+                            * ((float) (BE_SB_MAX - bar->page_size)
+                               / BE_SB_MAX));
+                   portion = min (portion, whole);
+                 }
+               else
+                 {
+                   whole = BE_SB_MAX - bar->page_size;
+                   portion = min (b->position, whole);
+                 }
+
+               XSETINT (inev.x, portion);
+               XSETINT (inev.y, whole);
                XSETWINDOW (inev.frame_or_window, w);
              }
            break;
diff --git a/src/haikuterm.h b/src/haikuterm.h
index a2520858f5..64fd0ec2b7 100644
--- a/src/haikuterm.h
+++ b/src/haikuterm.h
@@ -213,6 +213,8 @@ struct scroll_bar
 
   /* True if the scroll bar is horizontal.  */
   bool horizontal;
+
+  int page_size;
 };
 
 #define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]