aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/ui/render/ScrollBar.hpp9
-rw-r--r--src/ui/render/ScrollBar.cpp58
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) {