diff --git a/Userland/Applications/PixelPaint/LayerListWidget.cpp b/Userland/Applications/PixelPaint/LayerListWidget.cpp index 8c76b4c9e1..d987e3ff6d 100644 --- a/Userland/Applications/PixelPaint/LayerListWidget.cpp +++ b/Userland/Applications/PixelPaint/LayerListWidget.cpp @@ -175,15 +175,24 @@ void LayerListWidget::mousemove_event(GUI::MouseEvent& event) return; Gfx::IntPoint translated_event_point = { 0, vertical_scrollbar().value() + event.y() }; - auto delta = translated_event_point - m_moving_event_origin; + + if (delta.y() == 0) + return; + auto& gadget = m_gadgets[m_moving_gadget_index.value()]; VERIFY(gadget.is_moving); - gadget.movement_delta = delta; - auto adjusted_rect = gadget.rect; - adjusted_rect.translate_by(gadget.movement_delta); - scroll_into_view(adjusted_rect, false, true); + gadget.movement_delta.set_y(delta.y()); + auto inner_rect_max_height = widget_inner_rect().height() - 2 + vertical_scrollbar().max(); + + if (delta.y() < 0 && gadget.rect.y() < -delta.y()) + gadget.movement_delta.set_y(-gadget.rect.y()); + else if (delta.y() > 0 && gadget.rect.bottom() + delta.y() > inner_rect_max_height) + gadget.movement_delta.set_y(inner_rect_max_height - gadget.rect.bottom()); + + m_automatic_scroll_delta = automatic_scroll_delta_from_position(event.position()); + set_automatic_scrolling_timer(vertical_scrollbar().is_scrollable() && !m_automatic_scroll_delta.is_null()); relayout_gadgets(); } @@ -203,6 +212,7 @@ void LayerListWidget::mouseup_event(GUI::MouseEvent& event) new_index = m_image->layer_count() - 1; m_moving_gadget_index = {}; + set_automatic_scrolling_timer(false); auto old_layer_index = to_layer_index(old_index); auto new_layer_index = to_layer_index(new_index); @@ -224,6 +234,34 @@ void LayerListWidget::context_menu_event(GUI::ContextMenuEvent& event) on_context_menu_request(event); } +void LayerListWidget::on_automatic_scrolling_timer_fired() +{ + auto& gadget = m_gadgets[m_moving_gadget_index.value()]; + VERIFY(gadget.is_moving); + + if (m_automatic_scroll_delta.y() == 0) + return; + + if (vertical_scrollbar().is_min() && m_automatic_scroll_delta.y() < 0) + return; + + if (vertical_scrollbar().is_max() && m_automatic_scroll_delta.y() > 0) + return; + + vertical_scrollbar().set_value(vertical_scrollbar().value() + m_automatic_scroll_delta.y()); + gadget.movement_delta.set_y(gadget.movement_delta.y() + m_automatic_scroll_delta.y()); + + auto inner_rect_max_height = widget_inner_rect().height() - 2 + vertical_scrollbar().max(); + auto gadget_absolute_position = gadget.rect.y() + gadget.movement_delta.y(); + + if (gadget_absolute_position < 0) + gadget.movement_delta.set_y(-gadget.rect.y()); + else if (gadget_absolute_position + gadget.rect.height() >= inner_rect_max_height) + gadget.movement_delta.set_y(inner_rect_max_height - gadget.rect.bottom()); + else + relayout_gadgets(); +} + void LayerListWidget::image_did_add_layer(size_t layer_index) { if (m_moving_gadget_index.has_value()) { diff --git a/Userland/Applications/PixelPaint/LayerListWidget.h b/Userland/Applications/PixelPaint/LayerListWidget.h index 6b16d93912..646773ac71 100644 --- a/Userland/Applications/PixelPaint/LayerListWidget.h +++ b/Userland/Applications/PixelPaint/LayerListWidget.h @@ -45,6 +45,7 @@ private: virtual void image_did_modify_layer_properties(size_t) override; virtual void image_did_modify_layer_bitmap(size_t) override; virtual void image_did_modify_layer_stack() override; + virtual void on_automatic_scrolling_timer_fired() override; void rebuild_gadgets(); void relayout_gadgets(); @@ -72,6 +73,8 @@ private: Optional m_moving_gadget_index; Gfx::IntPoint m_moving_event_origin; + Gfx::IntPoint m_automatic_scroll_delta; + size_t m_selected_gadget_index { 0 }; };