diff options
-rw-r--r-- | include/cru/ui/render/ScrollBar.hpp | 9 | ||||
-rw-r--r-- | src/ui/render/ScrollBar.cpp | 58 |
2 files changed, 58 insertions, 9 deletions
diff --git a/include/cru/ui/render/ScrollBar.hpp b/include/cru/ui/render/ScrollBar.hpp index e3dabb57..fc2910c4 100644 --- a/include/cru/ui/render/ScrollBar.hpp +++ b/include/cru/ui/render/ScrollBar.hpp @@ -4,6 +4,7 @@ #include "cru/common/Event.hpp" #include "cru/platform/graphics/Base.hpp" #include "cru/platform/graphics/Painter.hpp" +#include "cru/platform/gui/Cursor.hpp" #include "cru/platform/gui/UiApplication.hpp" #include "cru/ui/Base.hpp" #include "cru/ui/controls/Control.hpp" @@ -40,7 +41,7 @@ class ScrollBar : public Object { CRU_DELETE_COPY(ScrollBar) CRU_DELETE_MOVE(ScrollBar) - ~ScrollBar() override = default; + ~ScrollBar() override; public: Direction GetDirection() const { return direction_; } @@ -89,6 +90,10 @@ class ScrollBar : public Object { virtual float CalculateNewScrollPosition(const Rect& thumb_original_rect, const Point& mouse_offset) = 0; + private: + void SetCursor(); + void RestoreCursor(); + protected: gsl::not_null<ScrollRenderObject*> render_object_; @@ -111,6 +116,8 @@ class ScrollBar : public Object { EventRevokerListGuard event_guard_; Event<Scroll> scroll_attempt_event_; + + std::optional<std::shared_ptr<platform::gui::ICursor>> old_cursor_; }; class HorizontalScrollBar : public ScrollBar { diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp index fa53292e..ee4b9e0d 100644 --- a/src/ui/render/ScrollBar.cpp +++ b/src/ui/render/ScrollBar.cpp @@ -6,6 +6,7 @@ #include "cru/platform/graphics/Factory.hpp" #include "cru/platform/graphics/Painter.hpp" #include "cru/platform/gui/Base.hpp" +#include "cru/platform/gui/Cursor.hpp" #include "cru/ui/Base.hpp" #include "cru/ui/events/UiEvent.hpp" #include "cru/ui/render/ScrollRenderObject.hpp" @@ -45,6 +46,8 @@ ScrollBar::ScrollBar(gsl::not_null<ScrollRenderObject*> render_object, graphics_factory->CreateSolidColorBrush(colors::black); } +ScrollBar::~ScrollBar() { RestoreCursor(); } + void ScrollBar::SetEnabled(bool value) { if (value == is_enabled_) return; if (!value) { @@ -150,19 +153,38 @@ void ScrollBar::InstallHandlers(controls::Control* control) { return true; } - if (IsEnabled() && !IsExpanded()) { - auto trigger_expand_area = GetCollapsedTriggerExpandAreaRect(); - if (trigger_expand_area && - trigger_expand_area->IsPointInside( - event.GetPoint(this->render_object_))) { - SetExpanded(true); - event.SetHandled(); - return true; + if (IsEnabled()) { + if (IsExpanded()) { + auto hit_test_result = + ExpandedHitTest(event.GetPoint(this->render_object_)); + if (hit_test_result) { + SetCursor(); + } else { + RestoreCursor(); + } + } else { + auto trigger_expand_area = + GetCollapsedTriggerExpandAreaRect(); + if (trigger_expand_area && + trigger_expand_area->IsPointInside( + event.GetPoint(this->render_object_))) { + SetExpanded(true); + SetCursor(); + event.SetHandled(); + return true; + } } } return false; }); + + event_guard_ += + control->MouseLeaveEvent()->Bubble()->PrependShortCircuitHandler( + [this](event::MouseEventArgs&) { + if (IsExpanded() && !move_thumb_start_) RestoreCursor(); + return false; + }); } } @@ -225,6 +247,26 @@ void ScrollBar::OnDraw(platform::graphics::IPainter* painter, } } +void ScrollBar::SetCursor() { + if (!old_cursor_) { + if (const auto control = render_object_->GetAttachedControl()) { + old_cursor_ = control->GetCursor(); + control->SetCursor( + GetUiApplication()->GetCursorManager()->GetSystemCursor( + platform::gui::SystemCursorType::Arrow)); + } + } +} + +void ScrollBar::RestoreCursor() { + if (old_cursor_) { + if (const auto control = render_object_->GetAttachedControl()) { + control->SetCursor(*old_cursor_); + } + old_cursor_ = std::nullopt; + } +} + std::optional<ScrollBarAreaKind> ScrollBar::ExpandedHitTest( const Point& point) { for (auto kind : kScrollBarAreaKindList) { |