aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ui/render/ScrollBar.cpp20
-rw-r--r--src/ui/render/ScrollRenderObject.cpp70
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