1
0
Fork 0

Codechange: Change scrolling_scrollbar to mouse_capture_widget, and dispatch OnClick() event if widget is not a scrollbar.

This allows any widget to support mouse capture.
pull/7258/head
Peter Nelson 2019-02-14 06:25:17 +00:00 committed by Charles Pigott
parent 66d23e3e86
commit de9f54ccc1
3 changed files with 55 additions and 36 deletions

View File

@ -99,7 +99,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
_scroller_click_timeout = 3; _scroller_click_timeout = 3;
sb->UpdatePosition(rtl ? 1 : -1); sb->UpdatePosition(rtl ? 1 : -1);
} }
w->scrolling_scrollbar = sb->index; w->mouse_capture_widget = sb->index;
} else if (pos >= ma - button_size) { } else if (pos >= ma - button_size) {
/* Pressing the lower button? */ /* Pressing the lower button? */
SetBit(sb->disp_flags, NDB_SCROLLBAR_DOWN); SetBit(sb->disp_flags, NDB_SCROLLBAR_DOWN);
@ -108,7 +108,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
_scroller_click_timeout = 3; _scroller_click_timeout = 3;
sb->UpdatePosition(rtl ? -1 : 1); sb->UpdatePosition(rtl ? -1 : 1);
} }
w->scrolling_scrollbar = sb->index; w->mouse_capture_widget = sb->index;
} else { } else {
Point pt = HandleScrollbarHittest(sb, mi, ma, sb->type == NWID_HSCROLLBAR); Point pt = HandleScrollbarHittest(sb, mi, ma, sb->type == NWID_HSCROLLBAR);
@ -119,7 +119,7 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
} else { } else {
_scrollbar_start_pos = pt.x - mi - button_size; _scrollbar_start_pos = pt.x - mi - button_size;
_scrollbar_size = ma - mi - button_size * 2; _scrollbar_size = ma - mi - button_size * 2;
w->scrolling_scrollbar = sb->index; w->mouse_capture_widget = sb->index;
_cursorpos_drag_start = _cursor.pos; _cursorpos_drag_start = _cursor.pos;
} }
} }
@ -2038,7 +2038,7 @@ void NWidgetScrollbar::Draw(const Window *w)
bool up_lowered = HasBit(this->disp_flags, NDB_SCROLLBAR_UP); bool up_lowered = HasBit(this->disp_flags, NDB_SCROLLBAR_UP);
bool down_lowered = HasBit(this->disp_flags, NDB_SCROLLBAR_DOWN); bool down_lowered = HasBit(this->disp_flags, NDB_SCROLLBAR_DOWN);
bool middle_lowered = !(this->disp_flags & ND_SCROLLBAR_BTN) && w->scrolling_scrollbar == this->index; bool middle_lowered = !(this->disp_flags & ND_SCROLLBAR_BTN) && w->mouse_capture_widget == this->index;
if (this->type == NWID_HSCROLLBAR) { if (this->type == NWID_HSCROLLBAR) {
DrawHorizontalScrollbar(r, this->colour, up_lowered, middle_lowered, down_lowered, this); DrawHorizontalScrollbar(r, this->colour, up_lowered, middle_lowered, down_lowered, this);

View File

@ -1846,7 +1846,7 @@ void Window::InitNested(WindowNumber window_number)
* Empty constructor, initialization has been moved to #InitNested() called from the constructor of the derived class. * Empty constructor, initialization has been moved to #InitNested() called from the constructor of the derived class.
* @param desc The description of the window. * @param desc The description of the window.
*/ */
Window::Window(WindowDesc *desc) : window_desc(desc), scrolling_scrollbar(-1) Window::Window(WindowDesc *desc) : window_desc(desc), mouse_capture_widget(-1)
{ {
} }
@ -1934,7 +1934,7 @@ static void DecreaseWindowCounters()
NWidgetScrollbar *sb = static_cast<NWidgetScrollbar*>(nwid); NWidgetScrollbar *sb = static_cast<NWidgetScrollbar*>(nwid);
if (sb->disp_flags & (ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN)) { if (sb->disp_flags & (ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN)) {
sb->disp_flags &= ~(ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN); sb->disp_flags &= ~(ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN);
w->scrolling_scrollbar = -1; w->mouse_capture_widget = -1;
sb->SetDirty(w); sb->SetDirty(w);
} }
} }
@ -2386,47 +2386,66 @@ static void StartWindowSizing(Window *w, bool to_left)
} }
/** /**
* handle scrollbar scrolling with the mouse. * Handle scrollbar scrolling with the mouse.
* @param w window with active scrollbar.
*/
static void HandleScrollbarScrolling(Window *w)
{
int i;
NWidgetScrollbar *sb = w->GetWidget<NWidgetScrollbar>(w->mouse_capture_widget);
bool rtl = false;
if (sb->type == NWID_HSCROLLBAR) {
i = _cursor.pos.x - _cursorpos_drag_start.x;
rtl = _current_text_dir == TD_RTL;
} else {
i = _cursor.pos.y - _cursorpos_drag_start.y;
}
if (sb->disp_flags & ND_SCROLLBAR_BTN) {
if (_scroller_click_timeout == 1) {
_scroller_click_timeout = 3;
sb->UpdatePosition(rtl == HasBit(sb->disp_flags, NDB_SCROLLBAR_UP) ? 1 : -1);
w->SetDirty();
}
return;
}
/* Find the item we want to move to and make sure it's inside bounds. */
int pos = min(max(0, i + _scrollbar_start_pos) * sb->GetCount() / _scrollbar_size, max(0, sb->GetCount() - sb->GetCapacity()));
if (rtl) pos = max(0, sb->GetCount() - sb->GetCapacity() - pos);
if (pos != sb->GetPosition()) {
sb->SetPosition(pos);
w->SetDirty();
}
}
/**
* Handle active widget (mouse draggin on widget) with the mouse.
* @return State of handling the event. * @return State of handling the event.
*/ */
static EventState HandleScrollbarScrolling() static EventState HandleActiveWidget()
{ {
Window *w; Window *w;
FOR_ALL_WINDOWS_FROM_BACK(w) { FOR_ALL_WINDOWS_FROM_BACK(w) {
if (w->scrolling_scrollbar >= 0) { if (w->mouse_capture_widget >= 0) {
/* Abort if no button is clicked any more. */ /* Abort if no button is clicked any more. */
if (!_left_button_down) { if (!_left_button_down) {
w->scrolling_scrollbar = -1; w->mouse_capture_widget = -1;
w->SetDirty(); w->SetDirty();
return ES_HANDLED; return ES_HANDLED;
} }
int i; /* If cursor hasn't moved, there is nothing to do. */
NWidgetScrollbar *sb = w->GetWidget<NWidgetScrollbar>(w->scrolling_scrollbar); if (_cursor.delta.x == 0 && _cursor.delta.y == 0) return ES_HANDLED;
bool rtl = false;
if (sb->type == NWID_HSCROLLBAR) { /* Handle scrollbar internally, or dispatch click event */
i = _cursor.pos.x - _cursorpos_drag_start.x; WidgetType type = w->GetWidget<NWidgetBase>(w->mouse_capture_widget)->type;
rtl = _current_text_dir == TD_RTL; if (type == NWID_VSCROLLBAR || type == NWID_HSCROLLBAR) {
HandleScrollbarScrolling(w);
} else { } else {
i = _cursor.pos.y - _cursorpos_drag_start.y; Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top };
} w->OnClick(pt, w->mouse_capture_widget, 0);
if (sb->disp_flags & ND_SCROLLBAR_BTN) {
if (_scroller_click_timeout == 1) {
_scroller_click_timeout = 3;
sb->UpdatePosition(rtl == HasBit(sb->disp_flags, NDB_SCROLLBAR_UP) ? 1 : -1);
w->SetDirty();
}
return ES_HANDLED;
}
/* Find the item we want to move to and make sure it's inside bounds. */
int pos = min(max(0, i + _scrollbar_start_pos) * sb->GetCount() / _scrollbar_size, max(0, sb->GetCount() - sb->GetCapacity()));
if (rtl) pos = max(0, sb->GetCount() - sb->GetCapacity() - pos);
if (pos != sb->GetPosition()) {
sb->SetPosition(pos);
w->SetDirty();
} }
return ES_HANDLED; return ES_HANDLED;
} }
@ -2845,7 +2864,7 @@ static void MouseLoop(MouseClick click, int mousewheel)
if (VpHandlePlaceSizingDrag() == ES_HANDLED) return; if (VpHandlePlaceSizingDrag() == ES_HANDLED) return;
if (HandleMouseDragDrop() == ES_HANDLED) return; if (HandleMouseDragDrop() == ES_HANDLED) return;
if (HandleWindowDragging() == ES_HANDLED) return; if (HandleWindowDragging() == ES_HANDLED) return;
if (HandleScrollbarScrolling() == ES_HANDLED) return; if (HandleActiveWidget() == ES_HANDLED) return;
if (HandleViewportScroll() == ES_HANDLED) return; if (HandleViewportScroll() == ES_HANDLED) return;
HandleMouseOver(); HandleMouseOver();

View File

@ -327,7 +327,7 @@ public:
NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade. NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade.
Dimension unshaded_size; ///< Last known unshaded size (only valid while shaded). Dimension unshaded_size; ///< Last known unshaded size (only valid while shaded).
int scrolling_scrollbar; ///< Widgetindex of just being dragged scrollbar. -1 if none is active. int mouse_capture_widget; ///< Widgetindex of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture.
Window *parent; ///< Parent window. Window *parent; ///< Parent window.
Window *z_front; ///< The window in front of us in z-order. Window *z_front; ///< The window in front of us in z-order.