diff options
author | Marcus Nilsson <brainbomb@gmail.com> | 2021-09-19 21:31:19 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-09-29 23:58:55 +0200 |
commit | d660e86d132404ea19e652c07489cc40f1255f13 (patch) | |
tree | 230b821ca20c57e8d9f4c07d5b6494ed18e84bde /Userland/Libraries | |
parent | 53cfc6ec9f63e0f52301fea4a949a1f9029125b9 (diff) | |
download | serenity-d660e86d132404ea19e652c07489cc40f1255f13.zip |
LibGUI: Implement automatic scrolling in AbstractView
This adds automatic scrolling when dragging items in TreeViews and other
widgets that inherit from AbstractView when the overloaded
accepts_drag() returns true. This is implemented in FileSystemModel to
allow directories and files to be dragged.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibGUI/AbstractScrollableWidget.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/AbstractTableView.cpp | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/AbstractTableView.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/AbstractView.cpp | 27 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/AbstractView.h | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/FileSystemModel.cpp | 6 |
6 files changed, 45 insertions, 7 deletions
diff --git a/Userland/Libraries/LibGUI/AbstractScrollableWidget.h b/Userland/Libraries/LibGUI/AbstractScrollableWidget.h index 4f977b3f31..b18eca59bf 100644 --- a/Userland/Libraries/LibGUI/AbstractScrollableWidget.h +++ b/Userland/Libraries/LibGUI/AbstractScrollableWidget.h @@ -52,7 +52,7 @@ public: void scroll_to_bottom(); void set_automatic_scrolling_timer(bool active); - Gfx::IntPoint automatic_scroll_delta_from_position(const Gfx::IntPoint&) const; + virtual Gfx::IntPoint automatic_scroll_delta_from_position(const Gfx::IntPoint&) const; int width_occupied_by_vertical_scrollbar() const; int height_occupied_by_horizontal_scrollbar() const; @@ -75,6 +75,7 @@ protected: void set_content_size(const Gfx::IntSize&); void set_size_occupied_by_fixed_elements(const Gfx::IntSize&); virtual void on_automatic_scrolling_timer_fired() {}; + int autoscroll_threshold() const { return m_autoscroll_threshold; } private: class AbstractScrollableWidgetScrollbar final : public Scrollbar { diff --git a/Userland/Libraries/LibGUI/AbstractTableView.cpp b/Userland/Libraries/LibGUI/AbstractTableView.cpp index 58856b21fe..f3efa24bbb 100644 --- a/Userland/Libraries/LibGUI/AbstractTableView.cpp +++ b/Userland/Libraries/LibGUI/AbstractTableView.cpp @@ -460,4 +460,14 @@ bool AbstractTableView::is_navigation(GUI::KeyEvent& event) return false; } } + +Gfx::IntPoint AbstractTableView::automatic_scroll_delta_from_position(const Gfx::IntPoint& pos) const +{ + if (pos.y() > column_header().height() + autoscroll_threshold()) + return AbstractScrollableWidget::automatic_scroll_delta_from_position(pos); + + Gfx::IntPoint position_excluding_header = { pos.x(), pos.y() - column_header().height() }; + return AbstractScrollableWidget::automatic_scroll_delta_from_position(position_excluding_header); +} + } diff --git a/Userland/Libraries/LibGUI/AbstractTableView.h b/Userland/Libraries/LibGUI/AbstractTableView.h index 4bfa470027..916ecf05c2 100644 --- a/Userland/Libraries/LibGUI/AbstractTableView.h +++ b/Userland/Libraries/LibGUI/AbstractTableView.h @@ -100,6 +100,8 @@ protected: void move_cursor_relative(int vertical_steps, int horizontal_steps, SelectionUpdate); + virtual Gfx::IntPoint automatic_scroll_delta_from_position(const Gfx::IntPoint& pos) const override; + private: void layout_headers(); bool is_navigation(GUI::KeyEvent&); diff --git a/Userland/Libraries/LibGUI/AbstractView.cpp b/Userland/Libraries/LibGUI/AbstractView.cpp index 0c1e5e2ddc..1e71261c28 100644 --- a/Userland/Libraries/LibGUI/AbstractView.cpp +++ b/Userland/Libraries/LibGUI/AbstractView.cpp @@ -335,6 +335,8 @@ void AbstractView::mouseup_event(MouseEvent& event) if (!model()) return; + set_automatic_scrolling_timer(false); + if (m_might_drag) { // We were unsure about unselecting items other than the current one // in mousedown_event(), because we could be seeing a start of a drag. @@ -759,13 +761,19 @@ void AbstractView::drag_move_event(DragEvent& event) { if (!model()) return; + auto index = index_at_event_position(event.position()); ModelIndex new_drop_candidate_index; - if (index.is_valid()) { - bool acceptable = model()->accepts_drag(index, event.mime_types()); - if (acceptable) - new_drop_candidate_index = index; + bool acceptable = model()->accepts_drag(index, event.mime_types()); + + if (acceptable && index.is_valid()) + new_drop_candidate_index = index; + + if (acceptable) { + m_automatic_scroll_delta = automatic_scroll_delta_from_position(event.position()); + set_automatic_scrolling_timer(!m_automatic_scroll_delta.is_null()); } + if (m_drop_candidate_index != new_drop_candidate_index) { m_drop_candidate_index = new_drop_candidate_index; update(); @@ -780,6 +788,17 @@ void AbstractView::drag_leave_event(Event&) m_drop_candidate_index = {}; update(); } + + set_automatic_scrolling_timer(false); +} + +void AbstractView::on_automatic_scrolling_timer_fired() +{ + if (m_automatic_scroll_delta.is_null()) + return; + + vertical_scrollbar().set_value(vertical_scrollbar().value() + m_automatic_scroll_delta.y()); + horizontal_scrollbar().set_value(horizontal_scrollbar().value() + m_automatic_scroll_delta.x()); } } diff --git a/Userland/Libraries/LibGUI/AbstractView.h b/Userland/Libraries/LibGUI/AbstractView.h index aae627a7e3..ded681917e 100644 --- a/Userland/Libraries/LibGUI/AbstractView.h +++ b/Userland/Libraries/LibGUI/AbstractView.h @@ -142,6 +142,8 @@ protected: virtual void hide_event(HideEvent&) override; virtual void focusin_event(FocusEvent&) override; + virtual void on_automatic_scrolling_timer_fired() override; + virtual void clear_selection(); virtual void set_selection(ModelIndex const&); virtual void set_selection_start_index(ModelIndex const&); @@ -202,6 +204,8 @@ private: bool m_is_dragging { false }; bool m_draw_item_text_with_shadow { false }; bool m_suppress_update_on_selection_change { false }; + + Gfx::IntPoint m_automatic_scroll_delta {}; }; } diff --git a/Userland/Libraries/LibGUI/FileSystemModel.cpp b/Userland/Libraries/LibGUI/FileSystemModel.cpp index cb4b437030..bede6e23ec 100644 --- a/Userland/Libraries/LibGUI/FileSystemModel.cpp +++ b/Userland/Libraries/LibGUI/FileSystemModel.cpp @@ -711,10 +711,12 @@ String FileSystemModel::column_name(int column) const bool FileSystemModel::accepts_drag(ModelIndex const& index, Vector<String> const& mime_types) const { - if (!index.is_valid()) - return false; if (!mime_types.contains_slow("text/uri-list")) return false; + + if (!index.is_valid()) + return true; + auto& node = this->node(index); return node.is_directory(); } |