diff options
author | crupest <crupest@outlook.com> | 2021-05-11 16:51:52 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-05-11 16:51:52 +0800 |
commit | f54032b94817bc5a03be68d39758e9b3d67a1b59 (patch) | |
tree | 4c40cf74302678a07873adab4d5d5ad6348b403b /src/ui | |
parent | 5c050b44558856ad0fe41dab95f97ea0a59d77eb (diff) | |
download | cru-f54032b94817bc5a03be68d39758e9b3d67a1b59.tar.gz cru-f54032b94817bc5a03be68d39758e9b3d67a1b59.tar.bz2 cru-f54032b94817bc5a03be68d39758e9b3d67a1b59.zip |
...
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/render/ScrollBar.cpp | 20 | ||||
-rw-r--r-- | src/ui/render/ScrollRenderObject.cpp | 70 |
2 files changed, 76 insertions, 14 deletions
diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp index 84a6fbe9..4bde6d19 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -122,7 +122,7 @@ void ScrollBar::InstallHandlers(controls::Control* control) { event_guard_.Clear(); if (control != nullptr) { event_guard_ += - control->MouseDownEvent()->Bubble()->PrependShortCircuitHandler( + control->MouseDownEvent()->Tunnel()->PrependShortCircuitHandler( [control, this](event::MouseButtonEventArgs& event) { if (event.GetButton() == mouse_buttons::left && IsEnabled() && IsExpanded()) { @@ -176,7 +176,7 @@ void ScrollBar::InstallHandlers(controls::Control* control) { }); event_guard_ += - control->MouseUpEvent()->Bubble()->PrependShortCircuitHandler( + control->MouseUpEvent()->Tunnel()->PrependShortCircuitHandler( [control, this](event::MouseButtonEventArgs& event) { if (mouse_press_ != std::nullopt) { mouse_press_ = std::nullopt; @@ -201,7 +201,7 @@ void ScrollBar::InstallHandlers(controls::Control* control) { }); event_guard_ += - control->MouseMoveEvent()->Bubble()->PrependShortCircuitHandler( + control->MouseMoveEvent()->Tunnel()->PrependShortCircuitHandler( [this](event::MouseEventArgs& event) { if (move_thumb_start_) { auto new_scroll_position = CalculateNewScrollPosition( @@ -247,7 +247,7 @@ void ScrollBar::InstallHandlers(controls::Control* control) { }); event_guard_ += - control->MouseLeaveEvent()->Bubble()->PrependShortCircuitHandler( + control->MouseLeaveEvent()->Tunnel()->PrependShortCircuitHandler( [this](event::MouseEventArgs&) { if (IsExpanded() && !move_thumb_start_) { if (mouse_hover_ != std::nullopt) { @@ -556,13 +556,11 @@ float HorizontalScrollBar::CalculateNewScrollPosition( } bool HorizontalScrollBar::CanScrollUp() { - return render_object_->GetScrollOffset().x > 0.0; + return render_object_->HorizontalCanScrollUp(); } bool HorizontalScrollBar::CanScrollDown() { - return render_object_->GetScrollOffset().x < - render_object_->GetFirstChild()->GetSize().width - - render_object_->GetViewRect().width; + return render_object_->HorizontalCanScrollDown(); } VerticalScrollBar::VerticalScrollBar( @@ -705,13 +703,11 @@ float VerticalScrollBar::CalculateNewScrollPosition( } bool VerticalScrollBar::CanScrollUp() { - return render_object_->GetScrollOffset().y > 0.0; + return render_object_->VerticalCanScrollUp(); } bool VerticalScrollBar::CanScrollDown() { - return render_object_->GetScrollOffset().y < - render_object_->GetFirstChild()->GetSize().height - - render_object_->GetViewRect().height; + return render_object_->VerticalCanScrollDown(); } ScrollBarDelegate::ScrollBarDelegate( diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp index fd5143ff..d0cdfdf6 100644 --- a/src/ui/render/ScrollRenderObject.cpp +++ b/src/ui/render/ScrollRenderObject.cpp @@ -41,10 +41,10 @@ Point CoerceScroll(const Point& scroll_offset, const Size& content_size, ScrollRenderObject::ScrollRenderObject() : RenderObject(ChildMode::Single) { scroll_bar_delegate_ = std::make_unique<ScrollBarDelegate>(this); scroll_bar_delegate_->ScrollAttemptEvent()->AddHandler( - [this](const struct Scroll& scroll) { this->Scroll(scroll); }); + [this](const struct Scroll& scroll) { this->ApplyScroll(scroll); }); } -void ScrollRenderObject::Scroll(const struct Scroll& scroll) { +void ScrollRenderObject::ApplyScroll(const struct Scroll& scroll) { auto direction = scroll.direction; switch (scroll.kind) { @@ -151,6 +151,17 @@ void ScrollRenderObject::ScrollToContain(const Rect& rect, SetScrollOffset(new_scroll_x, new_scroll_y); } +void ScrollRenderObject::SetMouseWheelScrollEnabled(bool enable) { + if (enable == is_mouse_wheel_enabled_) return; + if (const auto control = GetAttachedControl()) { + if (enable) { + InstallMouseWheelHandler(control); + } else { + InstallMouseWheelHandler(nullptr); + } + } +} + Size ScrollRenderObject::OnMeasureContent(const MeasureRequirement& requirement, const MeasureSize& preferred_size) { if (const auto child = GetSingleChild()) { @@ -186,8 +197,63 @@ void ScrollRenderObject::OnLayoutContent(const Rect& content_rect) { void ScrollRenderObject::OnAttachedControlChanged(controls::Control* control) { if (control) { scroll_bar_delegate_->InstallHandlers(control); + if (is_mouse_wheel_enabled_) { + InstallMouseWheelHandler(control); + } } else { + InstallMouseWheelHandler(nullptr); scroll_bar_delegate_->UninstallHandlers(); } } + +void ScrollRenderObject::InstallMouseWheelHandler(controls::Control* control) { + guard_.Clear(); + + if (control != nullptr) { + guard_ += control->MouseWheelEvent()->Bubble()->PrependShortCircuitHandler( + [this](event::MouseWheelEventArgs& args) { + const auto delta = args.GetDelta(); + if (delta > 0) { + if (VerticalCanScrollDown()) { + ApplyScroll( + Scroll{Direction::Vertical, ScrollKind::Relative, delta}); + return true; + } else if (HorizontalCanScrollDown()) { + ApplyScroll( + Scroll{Direction::Horizontal, ScrollKind::Relative, delta}); + return true; + } + } else if (delta < 0) { + if (VerticalCanScrollUp()) { + ApplyScroll( + Scroll{Direction::Vertical, ScrollKind::Relative, delta}); + return true; + } else if (HorizontalCanScrollUp()) { + ApplyScroll( + Scroll{Direction::Horizontal, ScrollKind::Relative, delta}); + return true; + } + } + return false; + }); + } +} + +bool ScrollRenderObject::HorizontalCanScrollUp() { + return GetScrollOffset().x > 0.0; +} + +bool ScrollRenderObject::HorizontalCanScrollDown() { + return GetScrollOffset().x < + GetFirstChild()->GetSize().width - GetViewRect().width; +} + +bool ScrollRenderObject::VerticalCanScrollUp() { + return GetScrollOffset().y > 0.0; +} + +bool ScrollRenderObject::VerticalCanScrollDown() { + return GetScrollOffset().y < + GetFirstChild()->GetSize().height - GetViewRect().height; +} } // namespace cru::ui::render |