1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:47:34 +00:00

PixelPaint: Implement automatic scrolling in LayerListWidget

The previous implementation of automatic scrolling in LayerListWidget
relied on mousemove events to perform the scrolling, which didn't
produce the expected behavior. Instead use the new auto scroll timer.
This commit is contained in:
Marcus Nilsson 2021-09-16 19:05:47 +02:00 committed by Andreas Kling
parent eec411c508
commit dc9b18da22
2 changed files with 46 additions and 5 deletions

View file

@ -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()) {