Scroll most lists by finger dragging list contents

This commit is contained in:
Sergii Pylypenko
2019-08-31 23:34:02 +03:00
committed by pelya
parent d65c932893
commit 17ee6fa299
7 changed files with 64 additions and 10 deletions

View File

@@ -86,7 +86,7 @@ public:
this->vscroll->SetCount(ObjectClass::GetUIClassCount());
NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BO_SELECT_MATRIX);
matrix->SetScrollbar(this->GetScrollbar(WID_BO_SELECT_SCROLL));
matrix->SetScrollbar(this->GetScrollbar(WID_BO_SELECT_SCROLL), WID_BO_SELECT_SCROLL);
this->SelectOtherClass(_selected_object_class);
if (this->CanRestoreSelectedObject()) {

View File

@@ -1031,7 +1031,7 @@ public:
this->vscroll->SetPosition(Clamp(_railstation.station_class - 2, 0, max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0)));
NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BRAS_MATRIX);
matrix->SetScrollbar(this->vscroll2);
matrix->SetScrollbar(this->vscroll2, this->vscroll2 ? WID_BRAS_MATRIX_SCROLL : -1);
matrix->SetCount(_railstation.station_count);
matrix->SetClicked(_railstation.station_type);
}
@@ -1851,7 +1851,7 @@ struct BuildRailWaypointWindow : PickerWindowBase {
this->CreateNestedTree();
NWidgetMatrix *matrix = this->GetWidget<NWidgetMatrix>(WID_BRW_WAYPOINT_MATRIX);
matrix->SetScrollbar(this->GetScrollbar(WID_BRW_SCROLL));
matrix->SetScrollbar(this->GetScrollbar(WID_BRW_SCROLL), WID_BRW_SCROLL);
this->FinishInitNested(TRANSPORT_RAIL);

View File

@@ -101,6 +101,17 @@ static void ScrollbarClickPositioning(Window *w, NWidgetScrollbar *sb, int x, in
pos = y;
button_size = NWidgetScrollbar::GetVerticalDimension().height;
}
if (_scrollbar_finger_drag) {
w->mouse_capture_widget = sb->index;
_cursorpos_drag_start.x = x;
_cursorpos_drag_start.y = y;
_scrollbar_size = max(1, (int) sb->current_y * sb->GetCount() / sb->GetCapacity());
_scrollbar_start_pos = sb->GetPosition() * _scrollbar_size / sb->GetCount();
w->SetDirty();
return;
}
if (pos < mi + button_size) {
/* Pressing the upper button? */
SetBit(sb->disp_flags, NDB_SCROLLBAR_UP);
@@ -1748,9 +1759,20 @@ void NWidgetMatrix::SetCount(int count)
* Assign a scrollbar to this matrix.
* @param sb The scrollbar to assign to us.
*/
void NWidgetMatrix::SetScrollbar(Scrollbar *sb)
void NWidgetMatrix::SetScrollbar(Scrollbar *sb, int index)
{
this->sb = sb;
this->sb_index = index;
}
Scrollbar *NWidgetMatrix::GetScrollbar()
{
return this->sb;
}
int NWidgetMatrix::GetScrollbarWidget()
{
return this->sb_index;
}
void NWidgetMatrix::SetupSmallestSize(Window *w, bool init_array)

View File

@@ -520,7 +520,9 @@ public:
void SetColour(Colours colour);
void SetClicked(int clicked);
void SetCount(int count);
void SetScrollbar(Scrollbar *sb);
void SetScrollbar(Scrollbar *sb, int index);
Scrollbar *GetScrollbar();
int GetScrollbarWidget();
void SetupSmallestSize(Window *w, bool init_array);
void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl);
@@ -534,6 +536,7 @@ protected:
int clicked; ///< The currently clicked widget.
int count; ///< Amount of valid widgets.
Scrollbar *sb; ///< The scrollbar we're associated with.
int sb_index; ///< The scrollbar widget index.
private:
int widget_w; ///< The width of the child widget including inter spacing.
int widget_h; ///< The height of the child widget including inter spacing.

View File

@@ -78,6 +78,7 @@ Point _cursorpos_drag_start;
int _scrollbar_start_pos;
int _scrollbar_size;
bool _scrollbar_finger_drag;
byte _scroller_click_timeout = 0;
bool _scrolling_viewport; ///< A viewport is being scrolled with the mouse.
@@ -2113,9 +2114,34 @@ static void HandleMouseDragNoTitlebars()
_focused_window->window_class != WC_MAIN_TOOLBAR_RIGHT &&
_focused_window->window_class != WC_BUILD_CONFIRMATION &&
FindWindowByClass(WC_DROPDOWN_MENU) == NULL) {
StartWindowDrag(_focused_window);
_drag_delta.x += _cursor.pos.x - _left_button_down_pos.x;
_drag_delta.y += _cursor.pos.y - _left_button_down_pos.y;
if (abs(_cursor.pos.x - _left_button_down_pos.x) < abs(_cursor.pos.y - _left_button_down_pos.y)) {
int widgetId = GetWidgetFromPos(_focused_window, _left_button_down_pos.x - _focused_window->left, _left_button_down_pos.y - _focused_window->top);
if (widgetId >= 0) {
NWidgetBase *widget = _focused_window->GetWidget<NWidgetBase>(widgetId);
NWidgetScrollbar *scroll = NULL;
if (widget && widget->type == WWT_MATRIX) {
NWidgetLeaf *list = _focused_window->GetWidget<NWidgetLeaf>(widgetId);
if (list && list->scrollbar_index >= 0) {
scroll = _focused_window->GetWidget<NWidgetScrollbar>(list->scrollbar_index);
}
}
if (widget && widget->type == NWID_MATRIX) {
NWidgetMatrix *list = _focused_window->GetWidget<NWidgetMatrix>(widgetId);
if (list && list->GetScrollbar() && list->GetScrollbarWidget() >= 0) {
scroll = _focused_window->GetWidget<NWidgetScrollbar>(list->GetScrollbarWidget());
}
}
if (scroll && scroll->IsVertical() && scroll->GetCount() > scroll->GetCapacity()) {
_scrollbar_finger_drag = true;
ScrollbarClickHandler(_focused_window, scroll, _left_button_down_pos.x, _left_button_down_pos.y);
}
}
}
if (_focused_window->mouse_capture_widget == -1) {
StartWindowDrag(_focused_window);
_drag_delta.x += _cursor.pos.x - _left_button_down_pos.x;
_drag_delta.y += _cursor.pos.y - _left_button_down_pos.y;
}
}
}
@@ -2593,6 +2619,9 @@ static void HandleScrollbarScrolling(Window *w)
} else {
i = _cursor.pos.y - _cursorpos_drag_start.y;
}
if (_scrollbar_finger_drag) {
i = -i;
}
if (sb->disp_flags & ND_SCROLLBAR_BTN) {
if (_scroller_click_timeout == 1) {
@@ -2624,6 +2653,7 @@ static EventState HandleActiveWidget()
/* Abort if no button is clicked any more. */
if (!_left_button_down) {
w->mouse_capture_widget = -1;
_scrollbar_finger_drag = false;
w->SetDirty();
return ES_HANDLED;
}

View File

@@ -906,6 +906,7 @@ extern Point _cursorpos_drag_start;
extern int _scrollbar_start_pos;
extern int _scrollbar_size;
extern bool _scrollbar_finger_drag;
extern byte _scroller_click_timeout;
enum {
SCROLLER_CLICK_DELAY = 6 ///< Delay in video frames between scrollbar doing scroll, we don't want to get to the bottom of the list in an instant

View File

@@ -5,7 +5,5 @@
- Misclicking station from orders dialog should hide the dialog for 3 times.
- Draggable combo boxes.
- Create auto-save when the app is put to background, and load it on the next start.