mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 13:37:45 +00:00
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.
This commit is contained in:
parent
89592601b6
commit
28a2a01dc3
2 changed files with 16 additions and 43 deletions
|
@ -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)
|
set_automatic_scrolling_timer(false);
|
||||||
m_out_of_view_timer->stop();
|
|
||||||
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);
|
||||||
|
|
||||||
if (m_rubber_banding) {
|
m_rubber_band_scroll_delta = automatic_scroll_delta_from_position(event.position());
|
||||||
auto in_view_rect = widget_inner_rect();
|
|
||||||
in_view_rect.shrink(SCROLL_OUT_OF_VIEW_HOT_MARGIN, SCROLL_OUT_OF_VIEW_HOT_MARGIN);
|
if (m_rubber_banding) {
|
||||||
if (!in_view_rect.contains(event.position())) {
|
m_out_of_view_position = event.position();
|
||||||
if (!m_out_of_view_timer) {
|
set_automatic_scrolling_timer(!m_rubber_band_scroll_delta.is_null());
|
||||||
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();
|
|
||||||
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()
|
void IconView::on_automatic_scrolling_timer_fired()
|
||||||
{
|
{
|
||||||
auto scroll_to = to_content_position(m_out_of_view_position);
|
AbstractView::on_automatic_scrolling_timer_fired();
|
||||||
// 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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue