From 4a0c86d94a06e72be0988062d49a19c05142434a Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 27 Feb 2021 22:16:28 +0800 Subject: ... --- include/cru/ui/Base.hpp | 4 +- include/cru/ui/render/ScrollBar.hpp | 144 ++++++++++++++++++++++++++ include/cru/ui/render/ScrollBarDelegate.hpp | 142 -------------------------- include/cru/ui/render/ScrollRenderObject.hpp | 2 +- src/ui/CMakeLists.txt | 4 +- src/ui/render/ScrollBar.cpp | 143 ++++++++++++++++++++++++++ src/ui/render/ScrollBarDelegate.cpp | 145 --------------------------- src/ui/render/ScrollRenderObject.cpp | 2 +- 8 files changed, 294 insertions(+), 292 deletions(-) create mode 100644 include/cru/ui/render/ScrollBar.hpp delete mode 100644 include/cru/ui/render/ScrollBarDelegate.hpp create mode 100644 src/ui/render/ScrollBar.cpp delete mode 100644 src/ui/render/ScrollBarDelegate.cpp diff --git a/include/cru/ui/Base.hpp b/include/cru/ui/Base.hpp index b2939a0b..fbdfec77 100644 --- a/include/cru/ui/Base.hpp +++ b/include/cru/ui/Base.hpp @@ -43,9 +43,11 @@ class RenderObject; namespace style { class StyleRuleSet; class StyleRuleSetBind; -} +} // namespace style //-------------------- region: basic types -------------------- +enum class Direction { Horizontal, Vertical }; + namespace internal { constexpr int align_start = 0; constexpr int align_end = align_start + 1; diff --git a/include/cru/ui/render/ScrollBar.hpp b/include/cru/ui/render/ScrollBar.hpp new file mode 100644 index 00000000..a9be49a3 --- /dev/null +++ b/include/cru/ui/render/ScrollBar.hpp @@ -0,0 +1,144 @@ +#pragma once +#include "Base.hpp" +#include "cru/common/Base.hpp" +#include "cru/common/Event.hpp" +#include "cru/platform/graphics/Base.hpp" +#include "cru/platform/graphics/Painter.hpp" +#include "cru/platform/gui/UiApplication.hpp" +#include "cru/ui/Base.hpp" +#include "cru/ui/controls/Control.hpp" + +#include +#include +#include + +namespace cru::ui::render { +class ScrollRenderObject; + +enum class ScrollKind { Absolute, Page, Line }; + +struct Scroll { + Direction direction; + ScrollKind kind; + float offset; +}; + +enum class ScrollBarAreaKind { + UpArrow, // Line up + DownArrow, // Line down + UpThumb, // Page up + DownThumb, // Page down + Thumb +}; + +class ScrollBar : public Object { + public: + explicit ScrollBar(gsl::not_null render_object); + + CRU_DELETE_COPY(ScrollBar) + CRU_DELETE_MOVE(ScrollBar) + + ~ScrollBar() override = default; + + public: + bool IsEnabled() const { return is_enabled_; } + void SetEnabled(bool value); + + void Draw(platform::graphics::IPainter* painter); + + virtual std::optional HitTest(const Point& point) = 0; + + IEvent* ScrollAttemptEvent() { return &scroll_attempt_event_; } + + void InstallHandlers(controls::Control* control); + void UninstallHandlers() { InstallHandlers(nullptr); } + + gsl::not_null> + GetCollapseThumbBrush() const; + + protected: + virtual void OnDraw(platform::graphics::IPainter* painter, bool expand) = 0; + + protected: + gsl::not_null render_object_; + + private: + bool is_enabled_ = true; + + bool is_expanded_ = false; + + std::shared_ptr collapse_thumb_brush_; + + EventRevokerListGuard event_guard_; + + Event scroll_attempt_event_; +}; + +class HorizontalScrollBar : public ScrollBar { + public: + explicit HorizontalScrollBar( + gsl::not_null render_object); + + CRU_DELETE_COPY(HorizontalScrollBar) + CRU_DELETE_MOVE(HorizontalScrollBar) + + ~HorizontalScrollBar() override = default; + + public: + std::optional HitTest(const Point& point) override; + + protected: + void OnDraw(platform::graphics::IPainter* painter, bool expand) override; +}; + +class VerticalScrollBar : public ScrollBar { + public: + explicit VerticalScrollBar(gsl::not_null render_object); + + CRU_DELETE_COPY(VerticalScrollBar) + CRU_DELETE_MOVE(VerticalScrollBar) + + ~VerticalScrollBar() override = default; + + public: + std::optional HitTest(const Point& point) override; + + protected: + void OnDraw(platform::graphics::IPainter* painter, bool expand) override; +}; + +// A delegate to draw scrollbar and register related events. +class ScrollBarDelegate : public Object { + public: + explicit ScrollBarDelegate(gsl::not_null render_object); + + CRU_DELETE_COPY(ScrollBarDelegate) + CRU_DELETE_MOVE(ScrollBarDelegate) + + ~ScrollBarDelegate() override = default; + + public: + bool IsHorizontalBarEnabled() const { return horizontal_bar_.IsEnabled(); } + void SetHorizontalBarEnabled(bool value) { + horizontal_bar_.SetEnabled(value); + } + + bool IsVerticalBarEnabled() const { return horizontal_bar_.IsEnabled(); } + void SetVerticalBarEnabled(bool value) { horizontal_bar_.SetEnabled(value); } + + IEvent* ScrollAttemptEvent() { return &scroll_attempt_event_; } + + void DrawScrollBar(platform::graphics::IPainter* painter); + + void InstallHandlers(controls::Control* control); + void UninstallHandlers() { InstallHandlers(nullptr); } + + private: + gsl::not_null render_object_; + + HorizontalScrollBar horizontal_bar_; + VerticalScrollBar vertical_bar_; + + Event scroll_attempt_event_; +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/ScrollBarDelegate.hpp b/include/cru/ui/render/ScrollBarDelegate.hpp deleted file mode 100644 index e5c63f6d..00000000 --- a/include/cru/ui/render/ScrollBarDelegate.hpp +++ /dev/null @@ -1,142 +0,0 @@ -#pragma once -#include "Base.hpp" -#include "cru/common/Base.hpp" -#include "cru/common/Event.hpp" -#include "cru/platform/graphics/Base.hpp" -#include "cru/platform/graphics/Painter.hpp" -#include "cru/platform/gui/UiApplication.hpp" -#include "cru/ui/controls/Control.hpp" - -#include -#include -#include - -namespace cru::ui::render { -class ScrollRenderObject; - -enum class ScrollBarAreaKind { - UpArrow, // Line up - DownArrow, // Line down - UpThumb, // Page up - DownThumb, // Page down - Thumb -}; - -class ScrollBar : public Object { - public: - explicit ScrollBar(gsl::not_null render_object); - - CRU_DELETE_COPY(ScrollBar) - CRU_DELETE_MOVE(ScrollBar) - - ~ScrollBar() override = default; - - public: - bool IsEnabled() const { return is_enabled_; } - void SetEnabled(bool value); - - void Draw(platform::graphics::IPainter* painter); - - virtual std::optional HitTest(const Point& point) = 0; - - IEvent* ScrollAttemptEvent() { return &scroll_attempt_event_; } - - void InstallHandlers(controls::Control* control); - void UninstallHandlers() { InstallHandlers(nullptr); } - - gsl::not_null> - GetCollapseThumbBrush() const; - - protected: - virtual void OnDraw(platform::graphics::IPainter* painter, bool expand) = 0; - - protected: - gsl::not_null render_object_; - - private: - bool is_enabled_ = true; - - bool is_expanded_ = false; - - std::shared_ptr collapse_thumb_brush_; - - EventRevokerListGuard event_guard_; - - Event scroll_attempt_event_; -}; - -class HorizontalScrollBar : public ScrollBar { - public: - explicit HorizontalScrollBar( - gsl::not_null render_object); - - CRU_DELETE_COPY(HorizontalScrollBar) - CRU_DELETE_MOVE(HorizontalScrollBar) - - ~HorizontalScrollBar() override = default; - - public: - std::optional HitTest(const Point& point) override; - - protected: - void OnDraw(platform::graphics::IPainter* painter, bool expand) override; -}; - -class VerticalScrollBar : public ScrollBar { - public: - explicit VerticalScrollBar(gsl::not_null render_object); - - CRU_DELETE_COPY(VerticalScrollBar) - CRU_DELETE_MOVE(VerticalScrollBar) - - ~VerticalScrollBar() override = default; - - public: - std::optional HitTest(const Point& point) override; - - protected: - void OnDraw(platform::graphics::IPainter* painter, bool expand) override; -}; - -struct ScrollBarScrollAttemptArgs { - float x_offset; - float y_offset; -}; - -// A delegate to draw scrollbar and register related events. -class ScrollBarDelegate : public Object { - public: - explicit ScrollBarDelegate(gsl::not_null render_object); - - CRU_DELETE_COPY(ScrollBarDelegate) - CRU_DELETE_MOVE(ScrollBarDelegate) - - ~ScrollBarDelegate() override = default; - - public: - bool IsHorizontalBarEnabled() const { return horizontal_bar_.IsEnabled(); } - void SetHorizontalBarEnabled(bool value) { - horizontal_bar_.SetEnabled(value); - } - - bool IsVerticalBarEnabled() const { return horizontal_bar_.IsEnabled(); } - void SetVerticalBarEnabled(bool value) { horizontal_bar_.SetEnabled(value); } - - IEvent* ScrollAttemptEvent() { - return &scroll_attempt_event_; - } - - void DrawScrollBar(platform::graphics::IPainter* painter); - - void InstallHandlers(controls::Control* control); - void UninstallHandlers() { InstallHandlers(nullptr); } - - private: - gsl::not_null render_object_; - - HorizontalScrollBar horizontal_bar_; - VerticalScrollBar vertical_bar_; - - Event scroll_attempt_event_; -}; -} // namespace cru::ui::render diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp index 5a431527..6a6ef198 100644 --- a/include/cru/ui/render/ScrollRenderObject.hpp +++ b/include/cru/ui/render/ScrollRenderObject.hpp @@ -2,7 +2,7 @@ #include "RenderObject.hpp" #include "cru/platform/graphics/util/Painter.hpp" -#include "cru/ui/render/ScrollBarDelegate.hpp" +#include "cru/ui/render/ScrollBar.hpp" #include #include diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 6153bc07..7d2792d6 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -33,7 +33,7 @@ add_library(cru_ui STATIC render/FlexLayoutRenderObject.cpp render/LayoutHelper.cpp render/RenderObject.cpp - render/ScrollBarDelegate.cpp + render/ScrollBar.cpp render/ScrollRenderObject.cpp render/StackLayoutRenderObject.cpp render/TextRenderObject.cpp @@ -78,7 +78,7 @@ target_sources(cru_ui PUBLIC ${CRU_UI_INCLUDE_DIR}/render/LayoutRenderObject.hpp ${CRU_UI_INCLUDE_DIR}/render/MeasureRequirement.hpp ${CRU_UI_INCLUDE_DIR}/render/RenderObject.hpp - ${CRU_UI_INCLUDE_DIR}/render/ScrollBarDelegate.hpp + ${CRU_UI_INCLUDE_DIR}/render/ScrollBar.hpp ${CRU_UI_INCLUDE_DIR}/render/ScrollRenderObject.hpp ${CRU_UI_INCLUDE_DIR}/render/StackLayoutRenderObject.hpp ${CRU_UI_INCLUDE_DIR}/render/TextRenderObject.hpp diff --git a/src/ui/render/ScrollBar.cpp b/src/ui/render/ScrollBar.cpp new file mode 100644 index 00000000..487f0b91 --- /dev/null +++ b/src/ui/render/ScrollBar.cpp @@ -0,0 +1,143 @@ +#include "cru/ui/render/ScrollBar.hpp" + +#include "../Helper.hpp" +#include "cru/common/Base.hpp" +#include "cru/platform/GraphBase.hpp" +#include "cru/platform/graphics/Factory.hpp" +#include "cru/platform/graphics/Painter.hpp" +#include "cru/ui/render/ScrollRenderObject.hpp" + +#include +#include + +namespace cru::ui::render { +constexpr float kScrollBarCollapseThumbWidth = 2; + +ScrollBar::ScrollBar(gsl::not_null render_object) + : render_object_(render_object) { + // TODO: Use theme resource and delete this. + auto collapse_thumb_brush = GetUiApplication() + ->GetInstance() + ->GetGraphFactory() + ->CreateSolidColorBrush(); + collapse_thumb_brush->SetColor(colors::gray.WithAlpha(128)); + collapse_thumb_brush_ = std::move(collapse_thumb_brush); +} + +void ScrollBar::SetEnabled(bool value) { + CRU_UNUSED(value) + // TODO: Implement this. +} + +void ScrollBar::Draw(platform::graphics::IPainter* painter) { + if (is_enabled_) { + OnDraw(painter, is_expanded_); + } +} + +void ScrollBar::InstallHandlers(controls::Control* control) { + CRU_UNUSED(control); + // TODO: Implement this. +} + +gsl::not_null> +ScrollBar::GetCollapseThumbBrush() const { + // TODO: Read theme resource. + return collapse_thumb_brush_; +} + +HorizontalScrollBar::HorizontalScrollBar( + gsl::not_null render_object) + : ScrollBar(render_object) {} + +std::optional HorizontalScrollBar::HitTest( + const Point& point) { + // TODO: Implement this. + CRU_UNUSED(point); + return std::nullopt; +} + +void HorizontalScrollBar::OnDraw(platform::graphics::IPainter* painter, + bool expand) { + const auto child = render_object_->GetFirstChild(); + if (child == nullptr) return; + + const auto view_rect = render_object_->GetViewRect(); + const auto padding_rect = render_object_->GetPaddingRect(); + const auto child_size = child->GetSize(); + + if (view_rect.width >= child_size.width) return; + + const float start_percentage = view_rect.left / child_size.width; + const float length_percentage = view_rect.width / child_size.width; + // const float end_percentage = start_percentage + length_percentage; + + if (expand) { + // TODO: Implement this. + } else { + Rect thumb_rect{padding_rect.left + padding_rect.width * start_percentage, + padding_rect.GetBottom() - kScrollBarCollapseThumbWidth, + padding_rect.width * length_percentage, + kScrollBarCollapseThumbWidth}; + painter->FillRectangle(thumb_rect, GetCollapseThumbBrush().get().get()); + } +} + +VerticalScrollBar::VerticalScrollBar( + gsl::not_null render_object) + : ScrollBar(render_object) {} + +std::optional VerticalScrollBar::HitTest( + const Point& point) { + // TODO: Implement this. + CRU_UNUSED(point); + return std::nullopt; +} + +void VerticalScrollBar::OnDraw(platform::graphics::IPainter* painter, + bool expand) { + const auto child = render_object_->GetFirstChild(); + if (child == nullptr) return; + + const auto view_rect = render_object_->GetViewRect(); + const auto padding_rect = render_object_->GetPaddingRect(); + const auto child_size = child->GetSize(); + + if (view_rect.height >= child_size.height) return; + + const float start_percentage = view_rect.top / child_size.height; + const float length_percentage = view_rect.height / child_size.height; + // const float end_percentage = start_percentage + length_percentage; + + if (expand) { + // TODO: Implement this. + } else { + Rect thumb_rect{padding_rect.GetRight() - kScrollBarCollapseThumbWidth, + padding_rect.top + padding_rect.height * start_percentage, + kScrollBarCollapseThumbWidth, + padding_rect.height * length_percentage}; + painter->FillRectangle(thumb_rect, GetCollapseThumbBrush().get().get()); + } +} + +ScrollBarDelegate::ScrollBarDelegate( + gsl::not_null render_object) + : render_object_(render_object), + horizontal_bar_(render_object), + vertical_bar_(render_object) { + horizontal_bar_.ScrollAttemptEvent()->AddHandler( + [this](auto scroll) { this->scroll_attempt_event_.Raise(scroll); }); + vertical_bar_.ScrollAttemptEvent()->AddHandler( + [this](auto scroll) { this->scroll_attempt_event_.Raise(scroll); }); +} + +void ScrollBarDelegate::DrawScrollBar(platform::graphics::IPainter* painter) { + horizontal_bar_.Draw(painter); + vertical_bar_.Draw(painter); +} + +void ScrollBarDelegate::InstallHandlers(controls::Control* control) { + horizontal_bar_.InstallHandlers(control); + vertical_bar_.InstallHandlers(control); +} +} // namespace cru::ui::render diff --git a/src/ui/render/ScrollBarDelegate.cpp b/src/ui/render/ScrollBarDelegate.cpp deleted file mode 100644 index 2814c567..00000000 --- a/src/ui/render/ScrollBarDelegate.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "cru/ui/render/ScrollBarDelegate.hpp" - -#include "../Helper.hpp" -#include "cru/common/Base.hpp" -#include "cru/platform/GraphBase.hpp" -#include "cru/platform/graphics/Factory.hpp" -#include "cru/platform/graphics/Painter.hpp" -#include "cru/ui/render/ScrollRenderObject.hpp" - -#include -#include - -namespace cru::ui::render { -constexpr float kScrollBarCollapseThumbWidth = 2; - -ScrollBar::ScrollBar(gsl::not_null render_object) - : render_object_(render_object) { - // TODO: Use theme resource and delete this. - auto collapse_thumb_brush = GetUiApplication() - ->GetInstance() - ->GetGraphFactory() - ->CreateSolidColorBrush(); - collapse_thumb_brush->SetColor(colors::gray.WithAlpha(128)); - collapse_thumb_brush_ = std::move(collapse_thumb_brush); -} - -void ScrollBar::SetEnabled(bool value) { - CRU_UNUSED(value) - // TODO: Implement this. -} - -void ScrollBar::Draw(platform::graphics::IPainter* painter) { - if (is_enabled_) { - OnDraw(painter, is_expanded_); - } -} - -void ScrollBar::InstallHandlers(controls::Control* control) { - CRU_UNUSED(control); - // TODO: Implement this. -} - -gsl::not_null> -ScrollBar::GetCollapseThumbBrush() const { - // TODO: Read theme resource. - return collapse_thumb_brush_; -} - -HorizontalScrollBar::HorizontalScrollBar( - gsl::not_null render_object) - : ScrollBar(render_object) {} - -std::optional HorizontalScrollBar::HitTest( - const Point& point) { - // TODO: Implement this. - CRU_UNUSED(point); - return std::nullopt; -} - -void HorizontalScrollBar::OnDraw(platform::graphics::IPainter* painter, - bool expand) { - const auto child = render_object_->GetFirstChild(); - if (child == nullptr) return; - - const auto view_rect = render_object_->GetViewRect(); - const auto padding_rect = render_object_->GetPaddingRect(); - const auto child_size = child->GetSize(); - - if (view_rect.width >= child_size.width) return; - - const float start_percentage = view_rect.left / child_size.width; - const float length_percentage = view_rect.width / child_size.width; - // const float end_percentage = start_percentage + length_percentage; - - if (expand) { - // TODO: Implement this. - } else { - Rect thumb_rect{padding_rect.left + padding_rect.width * start_percentage, - padding_rect.GetBottom() - kScrollBarCollapseThumbWidth, - padding_rect.width * length_percentage, - kScrollBarCollapseThumbWidth}; - painter->FillRectangle(thumb_rect, GetCollapseThumbBrush().get().get()); - } -} - -VerticalScrollBar::VerticalScrollBar( - gsl::not_null render_object) - : ScrollBar(render_object) {} - -std::optional VerticalScrollBar::HitTest( - const Point& point) { - // TODO: Implement this. - CRU_UNUSED(point); - return std::nullopt; -} - -void VerticalScrollBar::OnDraw(platform::graphics::IPainter* painter, - bool expand) { - const auto child = render_object_->GetFirstChild(); - if (child == nullptr) return; - - const auto view_rect = render_object_->GetViewRect(); - const auto padding_rect = render_object_->GetPaddingRect(); - const auto child_size = child->GetSize(); - - if (view_rect.height >= child_size.height) return; - - const float start_percentage = view_rect.top / child_size.height; - const float length_percentage = view_rect.height / child_size.height; - // const float end_percentage = start_percentage + length_percentage; - - if (expand) { - // TODO: Implement this. - } else { - Rect thumb_rect{padding_rect.GetRight() - kScrollBarCollapseThumbWidth, - padding_rect.top + padding_rect.height * start_percentage, - kScrollBarCollapseThumbWidth, - padding_rect.height * length_percentage}; - painter->FillRectangle(thumb_rect, GetCollapseThumbBrush().get().get()); - } -} - -ScrollBarDelegate::ScrollBarDelegate( - gsl::not_null render_object) - : render_object_(render_object), - horizontal_bar_(render_object), - vertical_bar_(render_object) { - horizontal_bar_.ScrollAttemptEvent()->AddHandler([this](float offset) { - this->scroll_attempt_event_.Raise({offset, 0}); - }); - vertical_bar_.ScrollAttemptEvent()->AddHandler([this](float offset) { - this->scroll_attempt_event_.Raise({0, offset}); - }); -} - -void ScrollBarDelegate::DrawScrollBar(platform::graphics::IPainter* painter) { - horizontal_bar_.Draw(painter); - vertical_bar_.Draw(painter); -} - -void ScrollBarDelegate::InstallHandlers(controls::Control* control) { - horizontal_bar_.InstallHandlers(control); - vertical_bar_.InstallHandlers(control); -} -} // namespace cru::ui::render diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp index 18b0adbf..a9ec729d 100644 --- a/src/ui/render/ScrollRenderObject.cpp +++ b/src/ui/render/ScrollRenderObject.cpp @@ -3,7 +3,7 @@ #include "cru/platform/graphics/Painter.hpp" #include "cru/platform/graphics/util/Painter.hpp" #include "cru/ui/controls/Control.hpp" -#include "cru/ui/render/ScrollBarDelegate.hpp" +#include "cru/ui/render/ScrollBar.hpp" #include #include -- cgit v1.2.3