emacs-diffs
[Top][All Lists]
Advanced

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

master 8c1a068159: Allow dragging scroll bar for overscroll on Haiku


From: Po Lu
Subject: master 8c1a068159: Allow dragging scroll bar for overscroll on Haiku
Date: Sun, 13 Mar 2022 01:48:04 -0500 (EST)

branch: master
commit 8c1a06815927cc4fc6114cddc4a6bf96f613ed5e
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Allow dragging scroll bar for overscroll on Haiku
    
    * src/haiku_support.cc (class EmacsScrollBar): New fields
    `in_overscroll', `can_overscroll', `last_overscroll',
    `last_reported_overscroll_value' and `max_value'.
    (ValueChanged): Make very sure extraneous value are not
    generated.
    (MouseUp): Clear overscroll if enabled.
    (MouseMoved): If overscroll is enabled and dragging downwards
    fails to dislodge the maximum value, enable overscrolling.
    (BView_scroll_bar_update): New parameter `can_overscroll'
    * src/haiku_support.h: Update prototypes.
    * src/haikuterm.c (haiku_set_scroll_bar_thumb)
    (haiku_set_horizontal_scroll_bar_thumb): Adjust parameters to
    scroll bar update functions.
    (haiku_read_socket): Take ceiling of bar position if
    horizontal.
---
 src/haiku_support.cc | 126 +++++++++++++++++++++++++++++++++++++++++++++++----
 src/haiku_support.h  |   2 +-
 src/haikuterm.c      |  11 +++--
 3 files changed, 124 insertions(+), 15 deletions(-)

diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 6b33245f64..ecd93dd226 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -1565,6 +1565,11 @@ public:
 
   /* True if button events should be passed to the parent.  */
   bool handle_button = false;
+  bool in_overscroll = false;
+  bool can_overscroll = false;
+  BPoint last_overscroll;
+  int last_reported_overscroll_value;
+  int max_value;
 
   EmacsScrollBar (int x, int y, int x1, int y1, bool horizontal_p) :
     BScrollBar (BRect (x, y, x1, y1), NULL, NULL, 0, 0, horizontal_p ?
@@ -1580,23 +1585,54 @@ public:
   void
   MessageReceived (BMessage *msg)
   {
-    int32 portion, range;
+    int32 portion, range, dragging, value;
     float proportion;
 
     if (msg->what == SCROLL_BAR_UPDATE)
       {
-       old_value = msg->GetInt32 ("emacs:units", 0);
        portion = msg->GetInt32 ("emacs:portion", 0);
        range = msg->GetInt32 ("emacs:range", 0);
+       dragging = msg->GetInt32 ("emacs:dragging", 0);
        proportion = (float) portion / range;
+       value = msg->GetInt32 ("emacs:units", 0);
+       can_overscroll = msg->GetBool ("emacs:overscroll", false);
+       value = std::max (0, value);
 
-       if (!msg->GetBool ("emacs:dragging", false))
+       if (dragging != 1)
          {
-           /* Unlike on Motif, PORTION isn't included in the total
-              range of the scroll bar.  */
-           this->SetRange (0, range - portion);
-           this->SetValue (old_value);
-           this->SetProportion (proportion);
+           if (in_overscroll || dragging != -1)
+             {
+               /* Set the value to the smallest possible one.
+                  Otherwise, the call to SetRange could lead to
+                  spurious updates.  */
+               old_value = 0;
+               SetValue (0);
+
+               /* Unlike on Motif, PORTION isn't included in the total
+                  range of the scroll bar.  */
+
+               SetRange (0, range - portion);
+               SetProportion (proportion);
+               max_value = range - portion;
+
+               if (in_overscroll || value > max_value)
+                 value = max_value;
+
+               old_value = roundf (value);
+               SetValue (old_value);
+             }
+           else
+             {
+               value = Value ();
+
+               old_value = 0;
+               SetValue (0);
+               SetRange (0, range - portion);
+               SetProportion (proportion);
+               old_value = value;
+               SetValue (value);
+               max_value = range - portion;
+             }
          }
       }
 
@@ -1609,6 +1645,8 @@ public:
     struct haiku_scroll_bar_value_event rq;
     struct haiku_scroll_bar_part_event part;
 
+    new_value = Value ();
+
     if (dragging)
       {
        if (new_value != old_value)
@@ -1781,6 +1819,8 @@ public:
     struct haiku_scroll_bar_drag_event rq;
     BView *parent;
 
+    in_overscroll = false;
+
     if (handle_button)
       {
        handle_button = false;
@@ -1804,7 +1844,13 @@ public:
   MouseMoved (BPoint point, uint32 transit, const BMessage *msg)
   {
     struct haiku_menu_bar_left_event rq;
+    struct haiku_scroll_bar_value_event value_event;
+    int range, diff, value, trough_size;
+    BRect bounds;
     BPoint conv;
+    uint32 buttons;
+
+    GetMouse (NULL, &buttons, false);
 
     if (transit == B_EXITED_VIEW)
       {
@@ -1821,6 +1867,61 @@ public:
          }
       }
 
+    if (in_overscroll)
+      {
+       diff = point.y - last_overscroll.y;
+
+       if (diff < 0)
+         {
+           in_overscroll = false;
+           goto allow;
+         }
+
+       range = max_value;
+       bounds = Bounds ();
+       bounds.InsetBy (1.0, 1.0);
+       value = Value ();
+       trough_size = BE_RECT_HEIGHT (bounds);
+       trough_size -= BE_RECT_WIDTH (bounds) / 2;
+       if (info.double_arrows)
+         trough_size -= BE_RECT_WIDTH (bounds) / 2;
+
+       value += ((double) range / trough_size) * diff * 2;
+
+       if (value != last_reported_overscroll_value)
+         {
+           last_reported_overscroll_value = value;
+           last_overscroll = point;
+
+           value_event.scroll_bar = this;
+           value_event.window = Window ();
+           value_event.position = value;
+
+           haiku_write (SCROLL_BAR_VALUE_EVENT, &value_event);
+           return;
+         }
+      }
+    else if (can_overscroll && (buttons == B_PRIMARY_MOUSE_BUTTON))
+      {
+       value = Value ();
+
+       if (value >= max_value)
+         {
+           BScrollBar::MouseMoved (point, transit, msg);
+
+           if (value == Value () && Proportion () < 1.0f)
+             {
+               in_overscroll = true;
+               last_overscroll = point;
+               last_reported_overscroll_value = value;
+
+               MouseMoved (point, transit, msg);
+               return;
+             }
+         }
+      }
+
+  allow:
     BScrollBar::MouseMoved (point, transit, msg);
   }
 };
@@ -2314,9 +2415,13 @@ BView_move_frame (void *view, int x, int y, int x1, int 
y1)
   vw->UnlockLooper ();
 }
 
+/* DRAGGING can either be 0 (which means to update everything), 1
+   (which means to update nothing), or -1 (which means to update only
+   the thumb size and range).  */
+
 void
 BView_scroll_bar_update (void *sb, int portion, int whole, int position,
-                        bool dragging)
+                        int dragging, bool can_overscroll)
 {
   BScrollBar *bar = (BScrollBar *) sb;
   BMessage msg = BMessage (SCROLL_BAR_UPDATE);
@@ -2324,7 +2429,8 @@ BView_scroll_bar_update (void *sb, int portion, int 
whole, int position,
   msg.AddInt32 ("emacs:range", whole);
   msg.AddInt32 ("emacs:units", position);
   msg.AddInt32 ("emacs:portion", portion);
-  msg.AddBool ("emacs:dragging", dragging);
+  msg.AddInt32 ("emacs:dragging", dragging);
+  msg.AddBool ("emacs:overscroll", can_overscroll);
 
   mr.SendMessage (&msg);
 }
diff --git a/src/haiku_support.h b/src/haiku_support.h
index e7c55d4d75..8b21fafad7 100644
--- a/src/haiku_support.h
+++ b/src/haiku_support.h
@@ -629,7 +629,7 @@ extern "C"
 
   extern void
   BView_scroll_bar_update (void *sb, int portion, int whole, int position,
-                          bool dragging);
+                          int dragging, bool can_overscroll);
 
   extern int
   BScrollBar_default_size (int horizontal_p);
diff --git a/src/haikuterm.c b/src/haikuterm.c
index cd0dcb0834..c98ab13e1a 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -485,7 +485,10 @@ haiku_set_scroll_bar_thumb (struct scroll_bar *bar, int 
portion,
     }
 
   BView_scroll_bar_update (scroll_bar, lrint (size),
-                          BE_SB_MAX, ceil (value), bar->dragging);
+                          BE_SB_MAX, ceil (value),
+                          (scroll_bar_adjust_thumb_portion_p
+                           ? bar->dragging : bar->dragging ? -1 : 0),
+                          !scroll_bar_adjust_thumb_portion_p);
 }
 
 static void
@@ -505,7 +508,7 @@ haiku_set_horizontal_scroll_bar_thumb (struct scroll_bar 
*bar, int portion,
     bar->page_size = size;
 
   BView_scroll_bar_update (scroll_bar, lrint (size), BE_SB_MAX,
-                          ceil (value), bar->dragging);
+                          ceil (value), bar->dragging, false);
 }
 
 static struct scroll_bar *
@@ -3282,8 +3285,8 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
 
                if (bar->horizontal)
                  {
-                   portion = bar->total * ((float) b->position
-                                           / BE_SB_MAX);
+                   portion = bar->total * ceil ((double) b->position
+                                                / BE_SB_MAX);
                    whole = (bar->total
                             * ((float) (BE_SB_MAX - bar->page_size)
                                / BE_SB_MAX));



reply via email to

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