]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve scroll bar button handling on Haiku
authorPo Lu <luangruo@yahoo.com>
Sat, 26 Feb 2022 06:56:31 +0000 (06:56 +0000)
committerPo Lu <luangruo@yahoo.com>
Sat, 26 Feb 2022 06:57:00 +0000 (06:57 +0000)
* src/haiku_io.c (haiku_len): Add `SCROLL_BAR_PART_EVENT'.
* src/haiku_support.cc (class EmacsScrollBar): New fields
`dragging' and `current_state', along with `old_value' and
`current_part'.
(EmacsScrollBar): Set horizontal flag to `horizontal_p'.
(MessageReceived): Set old_value when receiving
SCROLL_BAR_UPDATE message.
(ValueChanged): Don't allow scroll bar values to change while
dragging.
(MouseUp, MouseDown): Calculate button under mouse and act
accordingly.
* src/haiku_support.h (enum haiku_event_type): New event
`SCROLL_BAR_PART_EVENT'.
(enum haiku_scroll_bar_part): New enumerator.
(struct haiku_scroll_bar_part_event): New struct.
* src/haikuterm.c (haiku_read_socket): Handle
SCROLL_BAR_PART_EVENTs.

src/haiku_io.c
src/haiku_support.cc
src/haiku_support.h
src/haikuterm.c

index cade69f3387b97930e5cf9e3d97cd456ed1111dc..ff684df43370f341311e4cea3788263593b24c19 100644 (file)
@@ -98,6 +98,8 @@ haiku_len (enum haiku_event_type type)
       return sizeof (struct haiku_dummy_event);
     case MENU_BAR_LEFT:
       return sizeof (struct haiku_menu_bar_left_event);
+    case SCROLL_BAR_PART_EVENT:
+      return sizeof (struct haiku_scroll_bar_part_event);
     }
 
   emacs_abort ();
index 43b996b7959f6ec626ebd3524fa6386258521889..ab33e38dc7079490a0f9d3fc3d21fadcb7992d8d 100644 (file)
@@ -1558,6 +1558,10 @@ class EmacsScrollBar : public BScrollBar
 {
 public:
   void *scroll_bar;
+  int dragging = 0;
+  bool horizontal;
+  enum haiku_scroll_bar_part current_part;
+  float old_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 ?
@@ -1565,6 +1569,7 @@ public:
   {
     BView *vw = (BView *) this;
     vw->SetResizingMode (B_FOLLOW_NONE);
+    horizontal = horizontal_p;
   }
 
   void
@@ -1572,6 +1577,7 @@ public:
   {
     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));
       }
@@ -1583,20 +1589,133 @@ public:
   ValueChanged (float new_value)
   {
     struct haiku_scroll_bar_value_event rq;
+    struct haiku_scroll_bar_part_event part;
+
+    if (dragging)
+      {
+       if (new_value != old_value)
+         {
+           if (dragging > 1)
+             {
+               SetValue (old_value);
+
+               part.scroll_bar = scroll_bar;
+               part.part = current_part;
+               haiku_write (SCROLL_BAR_PART_EVENT, &part);
+             }
+           else
+             dragging++;
+         }
+
+       return;
+      }
+
     rq.scroll_bar = scroll_bar;
     rq.position = new_value;
 
     haiku_write (SCROLL_BAR_VALUE_EVENT, &rq);
   }
 
+  BRegion
+  ButtonRegionFor (enum haiku_scroll_bar_part button)
+  {
+    BRegion region;
+    BRect bounds;
+    BRect rect;
+    float button_size;
+    scroll_bar_info info;
+
+    get_scroll_bar_info (&info);
+
+    bounds = Bounds ();
+    bounds.InsetBy (0.0, 0.0);
+
+    if (horizontal)
+      button_size = bounds.Height () + 1.0f;
+    else
+      button_size = bounds.Width () + 1.0f;
+
+    rect = BRect (bounds.left, bounds.top,
+                 bounds.left + button_size - 1.0f,
+                 bounds.top + button_size - 1.0f);
+
+    if (button == HAIKU_SCROLL_BAR_UP_BUTTON)
+      {
+       if (!horizontal)
+         {
+           region.Include (rect);
+           if (info.double_arrows)
+             region.Include (rect.OffsetToCopy (bounds.left,
+                                                bounds.bottom - 2 * button_size + 1));
+         }
+       else
+         {
+           region.Include (rect);
+           if (info.double_arrows)
+             region.Include (rect.OffsetToCopy (bounds.right - 2 * button_size,
+                                                bounds.top));
+         }
+      }
+    else
+      {
+       if (!horizontal)
+         {
+           region.Include (rect.OffsetToCopy (bounds.left, bounds.bottom - button_size));
+
+           if (info.double_arrows)
+             region.Include (rect.OffsetByCopy (0.0, button_size));
+         }
+       else
+         {
+           region.Include (rect.OffsetToCopy (bounds.right - button_size, bounds.top));
+
+           if (info.double_arrows)
+             region.Include (rect.OffsetByCopy (button_size, 0.0));
+         }
+      }
+
+    return region;
+  }
+
   void
   MouseDown (BPoint pt)
   {
     struct haiku_scroll_bar_drag_event rq;
+    struct haiku_scroll_bar_part_event part;
+    BRegion r;
+
+    r = ButtonRegionFor (HAIKU_SCROLL_BAR_UP_BUTTON);
+
+    if (r.Contains (pt))
+      {
+       part.scroll_bar = scroll_bar;
+       part.part = HAIKU_SCROLL_BAR_UP_BUTTON;
+       dragging = 1;
+       current_part = HAIKU_SCROLL_BAR_UP_BUTTON;
+
+       haiku_write (SCROLL_BAR_PART_EVENT, &part);
+       goto out;
+      }
+
+    r = ButtonRegionFor (HAIKU_SCROLL_BAR_DOWN_BUTTON);
+
+    if (r.Contains (pt))
+      {
+       part.scroll_bar = scroll_bar;
+       part.part = HAIKU_SCROLL_BAR_DOWN_BUTTON;
+       dragging = 1;
+       current_part = HAIKU_SCROLL_BAR_DOWN_BUTTON;
+
+       haiku_write (SCROLL_BAR_PART_EVENT, &part);
+       goto out;
+      }
+
     rq.dragging_p = 1;
     rq.scroll_bar = scroll_bar;
 
     haiku_write (SCROLL_BAR_DRAG_EVENT, &rq);
+
+  out:
     BScrollBar::MouseDown (pt);
   }
 
@@ -1608,6 +1727,8 @@ public:
     rq.scroll_bar = scroll_bar;
 
     haiku_write (SCROLL_BAR_DRAG_EVENT, &rq);
+    dragging = false;
+
     BScrollBar::MouseUp (pt);
   }
 
index 4de71075c0e574252f276752ef8b2f5b5fdb16c7..714cb18ae792696fb28b4f87201d3e2b65fd46cf 100644 (file)
@@ -76,6 +76,7 @@ enum haiku_event_type
     ICONIFICATION,
     MOVE_EVENT,
     SCROLL_BAR_VALUE_EVENT,
+    SCROLL_BAR_PART_EVENT,
     SCROLL_BAR_DRAG_EVENT,
     WHEEL_MOVE_EVENT,
     MENU_BAR_RESIZE,
@@ -304,6 +305,18 @@ struct haiku_scroll_bar_drag_event
   int dragging_p;
 };
 
+enum haiku_scroll_bar_part
+  {
+    HAIKU_SCROLL_BAR_UP_BUTTON,
+    HAIKU_SCROLL_BAR_DOWN_BUTTON
+  };
+
+struct haiku_scroll_bar_part_event
+{
+  void *scroll_bar;
+  enum haiku_scroll_bar_part part;
+};
+
 struct haiku_menu_bar_resize_event
 {
   void *window;
index 5e2259e49a833eee81cf44f18f83d08b375c42a4..badc3f5801d203b020f64f9da6273c2b43055399 100644 (file)
@@ -3150,6 +3150,32 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
              }
            break;
          }
+       case SCROLL_BAR_PART_EVENT:
+         {
+           struct haiku_scroll_bar_part_event *b = buf;
+           struct scroll_bar *bar = b->scroll_bar;
+
+           inev.kind = (bar->horizontal ? HORIZONTAL_SCROLL_BAR_CLICK_EVENT
+                        : SCROLL_BAR_CLICK_EVENT);
+
+           bar->dragging = 0;
+
+           switch (b->part)
+             {
+             case HAIKU_SCROLL_BAR_UP_BUTTON:
+               inev.part = scroll_bar_up_arrow;
+               break;
+             case HAIKU_SCROLL_BAR_DOWN_BUTTON:
+               inev.part = scroll_bar_down_arrow;
+               break;
+             }
+
+           XSETINT (inev.x, 0);
+           XSETINT (inev.y, 0);
+           inev.frame_or_window = bar->window;
+
+           break;
+         }
        case SCROLL_BAR_DRAG_EVENT:
          {
            struct haiku_scroll_bar_drag_event *b = buf;