[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));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 8c1a068159: Allow dragging scroll bar for overscroll on Haiku,
Po Lu <=