فهرست منبع

LibGUI: Use autoscroll from AbstractView when rubberbanding in IconView

We can re-use the logic used for automatic scrolling in AbstractView
when we're doing rubberband scrolling in IconView. This removes some
duplicated code.
Marcus Nilsson 3 سال پیش
والد
کامیت
28a2a01dc3
2فایلهای تغییر یافته به همراه17 افزوده شده و 44 حذف شده
  1. 14 42
      Userland/Libraries/LibGUI/IconView.cpp
  2. 3 2
      Userland/Libraries/LibGUI/IconView.h

+ 14 - 42
Userland/Libraries/LibGUI/IconView.cpp

@@ -241,8 +241,7 @@ void IconView::mouseup_event(MouseEvent& event)
 {
 {
     if (m_rubber_banding && event.button() == MouseButton::Primary) {
     if (m_rubber_banding && event.button() == MouseButton::Primary) {
         m_rubber_banding = false;
         m_rubber_banding = false;
-        if (m_out_of_view_timer)
-            m_out_of_view_timer->stop();
+        set_automatic_scrolling_timer(false);
         update(to_widget_rect(Gfx::IntRect::from_two_points(m_rubber_band_origin, m_rubber_band_current)));
         update(to_widget_rect(Gfx::IntRect::from_two_points(m_rubber_band_origin, m_rubber_band_current)));
     }
     }
     AbstractView::mouseup_event(event);
     AbstractView::mouseup_event(event);
@@ -324,32 +323,17 @@ bool IconView::update_rubber_banding(const Gfx::IntPoint& input_position)
     return false;
     return false;
 }
 }
 
 
-#define SCROLL_OUT_OF_VIEW_HOT_MARGIN 20
-
 void IconView::mousemove_event(MouseEvent& event)
 void IconView::mousemove_event(MouseEvent& event)
 {
 {
     if (!model())
     if (!model())
         return AbstractView::mousemove_event(event);
         return AbstractView::mousemove_event(event);
 
 
+    m_rubber_band_scroll_delta = automatic_scroll_delta_from_position(event.position());
+
     if (m_rubber_banding) {
     if (m_rubber_banding) {
-        auto in_view_rect = widget_inner_rect();
-        in_view_rect.shrink(SCROLL_OUT_OF_VIEW_HOT_MARGIN, SCROLL_OUT_OF_VIEW_HOT_MARGIN);
-        if (!in_view_rect.contains(event.position())) {
-            if (!m_out_of_view_timer) {
-                m_out_of_view_timer = add<Core::Timer>();
-                m_out_of_view_timer->set_interval(100);
-                m_out_of_view_timer->on_timeout = [this] {
-                    scroll_out_of_view_timer_fired();
-                };
-            }
+        m_out_of_view_position = event.position();
+        set_automatic_scrolling_timer(!m_rubber_band_scroll_delta.is_null());
 
 
-            m_out_of_view_position = event.position();
-            if (!m_out_of_view_timer->is_active())
-                m_out_of_view_timer->start();
-        } else {
-            if (m_out_of_view_timer)
-                m_out_of_view_timer->stop();
-        }
         if (update_rubber_banding(event.position()))
         if (update_rubber_banding(event.position()))
             return;
             return;
     }
     }
@@ -357,27 +341,15 @@ void IconView::mousemove_event(MouseEvent& event)
     AbstractView::mousemove_event(event);
     AbstractView::mousemove_event(event);
 }
 }
 
 
-void IconView::scroll_out_of_view_timer_fired()
-{
-    auto scroll_to = to_content_position(m_out_of_view_position);
-    // Adjust the scroll-to position by SCROLL_OUT_OF_VIEW_HOT_MARGIN / 2
-    // depending on which direction we're scrolling. This allows us to
-    // start scrolling before we actually leave the visible area, which
-    // is important when there is no space to further move the mouse. The
-    // speed of scrolling is determined by the distance between the mouse
-    // pointer and the widget's inner rect shrunken by the hot margin
-    auto in_view_rect = widget_inner_rect().shrunken(SCROLL_OUT_OF_VIEW_HOT_MARGIN, SCROLL_OUT_OF_VIEW_HOT_MARGIN);
-    int adjust_x = 0, adjust_y = 0;
-    if (m_out_of_view_position.y() > in_view_rect.bottom())
-        adjust_y = (SCROLL_OUT_OF_VIEW_HOT_MARGIN / 2) + min(SCROLL_OUT_OF_VIEW_HOT_MARGIN, m_out_of_view_position.y() - in_view_rect.bottom());
-    else if (m_out_of_view_position.y() < in_view_rect.top())
-        adjust_y = -(SCROLL_OUT_OF_VIEW_HOT_MARGIN / 2) + max(-SCROLL_OUT_OF_VIEW_HOT_MARGIN, m_out_of_view_position.y() - in_view_rect.top());
-    if (m_out_of_view_position.x() > in_view_rect.right())
-        adjust_x = (SCROLL_OUT_OF_VIEW_HOT_MARGIN / 2) + min(SCROLL_OUT_OF_VIEW_HOT_MARGIN, m_out_of_view_position.x() - in_view_rect.right());
-    else if (m_out_of_view_position.x() < in_view_rect.left())
-        adjust_x = -(SCROLL_OUT_OF_VIEW_HOT_MARGIN / 2) + max(-SCROLL_OUT_OF_VIEW_HOT_MARGIN, m_out_of_view_position.x() - in_view_rect.left());
-
-    AbstractScrollableWidget::scroll_into_view({ scroll_to.translated(adjust_x, adjust_y), { 1, 1 } }, true, true);
+void IconView::on_automatic_scrolling_timer_fired()
+{
+    AbstractView::on_automatic_scrolling_timer_fired();
+
+    if (m_rubber_band_scroll_delta.is_null())
+        return;
+
+    vertical_scrollbar().increase_slider_by(m_rubber_band_scroll_delta.y());
+    horizontal_scrollbar().increase_slider_by(m_rubber_band_scroll_delta.x());
     update_rubber_banding(m_out_of_view_position);
     update_rubber_banding(m_out_of_view_position);
 }
 }
 
 

+ 3 - 2
Userland/Libraries/LibGUI/IconView.h

@@ -61,6 +61,8 @@ private:
 
 
     virtual void move_cursor(CursorMovement, SelectionUpdate) override;
     virtual void move_cursor(CursorMovement, SelectionUpdate) override;
 
 
+    virtual void on_automatic_scrolling_timer_fired() override;
+
     struct ItemData {
     struct ItemData {
         Gfx::IntRect text_rect;
         Gfx::IntRect text_rect;
         Optional<Gfx::IntRect> text_rect_wrapped;
         Optional<Gfx::IntRect> text_rect_wrapped;
@@ -122,7 +124,6 @@ private:
     void update_item_rects(int item_index, ItemData& item_data) const;
     void update_item_rects(int item_index, ItemData& item_data) const;
     void get_item_rects(int item_index, ItemData& item_data, const Gfx::Font&) const;
     void get_item_rects(int item_index, ItemData& item_data, const Gfx::Font&) const;
     bool update_rubber_banding(const Gfx::IntPoint&);
     bool update_rubber_banding(const Gfx::IntPoint&);
-    void scroll_out_of_view_timer_fired();
     int items_per_page() const;
     int items_per_page() const;
 
 
     void rebuild_item_cache() const;
     void rebuild_item_cache() const;
@@ -156,10 +157,10 @@ private:
     bool m_always_wrap_item_labels { false };
     bool m_always_wrap_item_labels { false };
 
 
     bool m_rubber_banding { false };
     bool m_rubber_banding { false };
-    RefPtr<Core::Timer> m_out_of_view_timer;
     Gfx::IntPoint m_out_of_view_position;
     Gfx::IntPoint m_out_of_view_position;
     Gfx::IntPoint m_rubber_band_origin;
     Gfx::IntPoint m_rubber_band_origin;
     Gfx::IntPoint m_rubber_band_current;
     Gfx::IntPoint m_rubber_band_current;
+    Gfx::IntPoint m_rubber_band_scroll_delta;
 
 
     FlowDirection m_flow_direction { FlowDirection::LeftToRight };
     FlowDirection m_flow_direction { FlowDirection::LeftToRight };