aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/ui')
-rw-r--r--include/cru/ui/Base.h18
-rw-r--r--include/cru/ui/DeleteLater.h3
-rw-r--r--include/cru/ui/components/Component.h6
-rw-r--r--include/cru/ui/components/Menu.h31
-rw-r--r--include/cru/ui/components/PopupButton.h1
-rw-r--r--include/cru/ui/controls/Control.h83
-rw-r--r--include/cru/ui/controls/Popup.h22
-rw-r--r--include/cru/ui/controls/RootControl.h34
-rw-r--r--include/cru/ui/controls/TextHostControlService.h2
-rw-r--r--include/cru/ui/controls/Window.h188
-rw-r--r--include/cru/ui/events/RoutedEvent.h20
-rw-r--r--include/cru/ui/host/LayoutPaintCycler.h39
-rw-r--r--include/cru/ui/host/WindowHost.h172
-rw-r--r--include/cru/ui/render/RenderObject.h2
-rw-r--r--include/cru/ui/render/ScrollBar.h8
15 files changed, 233 insertions, 396 deletions
diff --git a/include/cru/ui/Base.h b/include/cru/ui/Base.h
index 3f270b39..9e24cfa2 100644
--- a/include/cru/ui/Base.h
+++ b/include/cru/ui/Base.h
@@ -35,12 +35,9 @@ namespace colors = cru::platform::colors;
namespace controls {
class Control;
+class Window;
} // namespace controls
-namespace host {
-class WindowHost;
-}
-
//-------------------- region: basic types --------------------
enum class Direction { Horizontal, Vertical };
enum class Alignment { Start, End, Center, Stretch };
@@ -67,21 +64,12 @@ struct CornerRadius {
return *this;
}
+ bool operator==(const CornerRadius& other) const = default;
+
Point left_top;
Point right_top;
Point left_bottom;
Point right_bottom;
};
-inline bool operator==(const CornerRadius& left, const CornerRadius& right) {
- return left.left_top == right.left_top &&
- left.left_bottom == right.left_bottom &&
- left.right_top == right.right_top &&
- left.right_bottom == right.right_bottom;
-}
-
-inline bool operator!=(const CornerRadius& left, const CornerRadius& right) {
- return !(left == right);
-}
-
} // namespace cru::ui
diff --git a/include/cru/ui/DeleteLater.h b/include/cru/ui/DeleteLater.h
index ddbf2ce1..95301bc0 100644
--- a/include/cru/ui/DeleteLater.h
+++ b/include/cru/ui/DeleteLater.h
@@ -13,9 +13,6 @@ class CRU_UI_API DeleteLaterImpl {
virtual ~DeleteLaterImpl();
void DeleteLater();
- protected:
- virtual void OnPrepareDelete();
-
private:
bool delete_later_scheduled_;
};
diff --git a/include/cru/ui/components/Component.h b/include/cru/ui/components/Component.h
index 6d31ae79..d8966a89 100644
--- a/include/cru/ui/components/Component.h
+++ b/include/cru/ui/components/Component.h
@@ -10,9 +10,6 @@ namespace cru::ui::components {
*/
class CRU_UI_API Component : public Object, public DeleteLaterImpl {
public:
- Component() = default;
- ~Component() = default;
-
virtual controls::Control* GetRootControl() = 0;
bool IsDeleteByParent() const { return delete_by_parent_; }
@@ -21,9 +18,6 @@ class CRU_UI_API Component : public Object, public DeleteLaterImpl {
}
void DeleteIfDeleteByParent(bool delete_later = true);
- protected:
- void OnPrepareDelete() override;
-
private:
bool delete_by_parent_ = false;
};
diff --git a/include/cru/ui/components/Menu.h b/include/cru/ui/components/Menu.h
index 554a8898..92731f2e 100644
--- a/include/cru/ui/components/Menu.h
+++ b/include/cru/ui/components/Menu.h
@@ -1,11 +1,10 @@
#pragma once
+#include "../controls/Button.h"
+#include "../controls/Control.h"
+#include "../controls/FlexLayout.h"
+#include "../controls/TextBlock.h"
+#include "../controls/Window.h"
#include "Component.h"
-#include "cru/base/Base.h"
-#include "cru/ui/controls/Button.h"
-#include "cru/ui/controls/Control.h"
-#include "cru/ui/controls/FlexLayout.h"
-#include "cru/ui/controls/Popup.h"
-#include "cru/ui/controls/TextBlock.h"
#include <functional>
#include <vector>
@@ -16,11 +15,6 @@ class CRU_UI_API MenuItem : public Component {
MenuItem();
explicit MenuItem(std::string text);
- CRU_DELETE_COPY(MenuItem)
- CRU_DELETE_MOVE(MenuItem)
-
- ~MenuItem();
-
public:
controls::Control* GetRootControl() override { return &container_; }
@@ -39,10 +33,6 @@ class CRU_UI_API MenuItem : public Component {
class CRU_UI_API Menu : public Component {
public:
Menu();
-
- CRU_DELETE_COPY(Menu)
- CRU_DELETE_MOVE(Menu)
-
~Menu();
public:
@@ -58,7 +48,8 @@ class CRU_UI_API Menu : public Component {
void AddTextItem(std::string text, std::function<void()> on_click) {
AddTextItemAt(std::move(text), GetItemCount(), std::move(on_click));
}
- void AddTextItemAt(std::string text, Index index, std::function<void()> on_click);
+ void AddTextItemAt(std::string text, Index index,
+ std::function<void()> on_click);
void SetOnItemClick(std::function<void(Index)> on_item_click) {
on_item_click_ = std::move(on_item_click);
@@ -74,16 +65,12 @@ class CRU_UI_API Menu : public Component {
class CRU_UI_API PopupMenu : public Component {
public:
explicit PopupMenu(controls::Control* attached_control = nullptr);
-
- CRU_DELETE_COPY(PopupMenu)
- CRU_DELETE_MOVE(PopupMenu)
-
~PopupMenu();
public:
controls::Control* GetRootControl() override;
- controls::Popup* GetPopup() { return &popup_; }
+ controls::Window* GetPopup() { return popup_; }
Menu* GetMenu() { return &menu_; }
// position relative to screen left top.
@@ -99,7 +86,7 @@ class CRU_UI_API PopupMenu : public Component {
private:
controls::Control* attached_control_;
- controls::Popup popup_;
+ controls::Window* popup_;
Menu menu_;
};
} // namespace cru::ui::components
diff --git a/include/cru/ui/components/PopupButton.h b/include/cru/ui/components/PopupButton.h
index 5fa69044..0e3d5314 100644
--- a/include/cru/ui/components/PopupButton.h
+++ b/include/cru/ui/components/PopupButton.h
@@ -4,7 +4,6 @@
#include "cru/ui/components/Menu.h"
#include "cru/ui/controls/Button.h"
#include "cru/ui/controls/IconButton.h"
-#include "cru/ui/controls/Popup.h"
#include "cru/ui/controls/TextBlock.h"
namespace cru::ui::components {
diff --git a/include/cru/ui/controls/Control.h b/include/cru/ui/controls/Control.h
index 77f5f392..684bc960 100644
--- a/include/cru/ui/controls/Control.h
+++ b/include/cru/ui/controls/Control.h
@@ -4,6 +4,8 @@
#include "../events/UiEvents.h"
#include "../render/RenderObject.h"
#include "../style/StyleRuleSet.h"
+#include "cru/ui/events/KeyEventArgs.h"
+#include "cru/ui/events/MouseWheelEventArgs.h"
#include "cru/ui/render/MeasureRequirement.h"
namespace cru::ui::controls {
@@ -31,9 +33,11 @@ class CRU_UI_API Control : public Object, public DeleteLaterImpl {
public:
virtual std::string GetControlType() const = 0;
+ std::string GetDebugId() const;
+
//*************** region: tree ***************
public:
- host::WindowHost* GetWindowHost() const { return window_host_; }
+ Window* GetWindow();
Control* GetParent() const { return parent_; }
void SetParent(Control* parent);
@@ -48,6 +52,8 @@ class CRU_UI_API Control : public Object, public DeleteLaterImpl {
void RemoveFromParent();
+ controls::Control* HitTest(const Point& point);
+
public:
virtual render::RenderObject* GetRenderObject() const = 0;
@@ -107,83 +113,30 @@ class CRU_UI_API Control : public Object, public DeleteLaterImpl {
// the mouse, this event is raised as regular. But if mouse is captured by
// another control, the control will not receive any mouse enter event. You
// can use `IsMouseCaptured` to get more info.
- events::RoutedEvent<events::MouseEventArgs>* MouseEnterEvent() {
- return &mouse_enter_event_;
- }
+ CRU_DEFINE_ROUTED_EVENT(MouseEnter, events::MouseEventArgs)
+
// Raised when mouse is leave the control. Even when the control itself
// captures the mouse, this event is raised as regular. But if mouse is
// captured by another control, the control will not receive any mouse leave
// event. You can use `IsMouseCaptured` to get more info.
- events::RoutedEvent<events::MouseEventArgs>* MouseLeaveEvent() {
- return &mouse_leave_event_;
- }
- // Raised when mouse is move in the control.
- events::RoutedEvent<events::MouseEventArgs>* MouseMoveEvent() {
- return &mouse_move_event_;
- }
- // Raised when a mouse button is pressed in the control.
- events::RoutedEvent<events::MouseButtonEventArgs>* MouseDownEvent() {
- return &mouse_down_event_;
- }
- // Raised when a mouse button is released in the control.
- events::RoutedEvent<events::MouseButtonEventArgs>* MouseUpEvent() {
- return &mouse_up_event_;
- }
- events::RoutedEvent<events::MouseWheelEventArgs>* MouseWheelEvent() {
- return &mouse_wheel_event_;
- }
- events::RoutedEvent<events::KeyEventArgs>* KeyDownEvent() {
- return &key_down_event_;
- }
- events::RoutedEvent<events::KeyEventArgs>* KeyUpEvent() {
- return &key_up_event_;
- }
- events::RoutedEvent<events::FocusChangeEventArgs>* GainFocusEvent() {
- return &gain_focus_event_;
- }
- events::RoutedEvent<events::FocusChangeEventArgs>* LoseFocusEvent() {
- return &lose_focus_event_;
- }
+ CRU_DEFINE_ROUTED_EVENT(MouseLeave, events::MouseEventArgs)
- private:
- events::RoutedEvent<events::MouseEventArgs> mouse_enter_event_;
- events::RoutedEvent<events::MouseEventArgs> mouse_leave_event_;
- events::RoutedEvent<events::MouseEventArgs> mouse_move_event_;
- events::RoutedEvent<events::MouseButtonEventArgs> mouse_down_event_;
- events::RoutedEvent<events::MouseButtonEventArgs> mouse_up_event_;
- events::RoutedEvent<events::MouseWheelEventArgs> mouse_wheel_event_;
-
- events::RoutedEvent<events::KeyEventArgs> key_down_event_;
- events::RoutedEvent<events::KeyEventArgs> key_up_event_;
-
- events::RoutedEvent<events::FocusChangeEventArgs> gain_focus_event_;
- events::RoutedEvent<events::FocusChangeEventArgs> lose_focus_event_;
+ CRU_DEFINE_ROUTED_EVENT(MouseMove, events::MouseEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(MouseDown, events::MouseButtonEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(MouseUp, events::MouseButtonEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(MouseWheel, events::MouseWheelEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(KeyDown, events::KeyEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(KeyUp, events::KeyEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(GainFocus, events::FocusChangeEventArgs)
+ CRU_DEFINE_ROUTED_EVENT(LoseFocus, events::FocusChangeEventArgs)
//*************** region: tree ***************
protected:
virtual void OnParentChanged(Control* old_parent, Control* new_parent) {}
- virtual void OnWindowHostChanged(host::WindowHost* old_host,
- host::WindowHost* new_host) {}
-
- protected:
- virtual void OnMouseHoverChange(bool newHover) { CRU_UNUSED(newHover) }
-
- void OnPrepareDelete() override;
-
- private:
- void OnParentChangedCore(Control* old_parent, Control* new_parent);
- void OnWindowHostChangedCore(host::WindowHost* old_host,
- host::WindowHost* new_host);
-
private:
- bool in_destruction_ = false;
-
Control* parent_ = nullptr;
- host::WindowHost* window_host_ = nullptr;
-
- private:
bool is_mouse_over_ = false;
std::shared_ptr<platform::gui::ICursor> cursor_ = nullptr;
diff --git a/include/cru/ui/controls/Popup.h b/include/cru/ui/controls/Popup.h
deleted file mode 100644
index 7c57d257..00000000
--- a/include/cru/ui/controls/Popup.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-#include "RootControl.h"
-
-#include "cru/platform/gui/Base.h"
-
-#include <memory>
-
-namespace cru::ui::controls {
-class CRU_UI_API Popup : public RootControl {
- public:
- static constexpr std::string_view kControlType = "Popup";
-
- explicit Popup(Control* attached_control = nullptr);
-
- CRU_DELETE_COPY(Popup)
- CRU_DELETE_MOVE(Popup)
-
- ~Popup() override;
-
- std::string GetControlType() const override { return std::string(kControlType); }
-};
-} // namespace cru::ui::controls
diff --git a/include/cru/ui/controls/RootControl.h b/include/cru/ui/controls/RootControl.h
deleted file mode 100644
index e662b655..00000000
--- a/include/cru/ui/controls/RootControl.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-#include "LayoutControl.h"
-
-#include "cru/base/Event.h"
-#include "cru/platform/gui/Window.h"
-#include "cru/ui/host/WindowHost.h"
-#include "cru/ui/render/StackLayoutRenderObject.h"
-
-namespace cru::ui::controls {
-class CRU_UI_API RootControl
- : public LayoutControl<render::StackLayoutRenderObject> {
- protected:
- explicit RootControl(Control* attached_control);
-
- public:
- CRU_DELETE_COPY(RootControl)
- CRU_DELETE_MOVE(RootControl)
- ~RootControl() override;
-
- public:
- platform::gui::INativeWindow* GetNativeWindow();
-
- protected:
- void SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value);
-
- private:
- std::unique_ptr<host::WindowHost> window_host_;
-
- Control* attached_control_;
-
- EventHandlerRevokerListGuard
- gain_focus_on_create_and_destroy_when_lose_focus_event_guard_;
-};
-} // namespace cru::ui::controls
diff --git a/include/cru/ui/controls/TextHostControlService.h b/include/cru/ui/controls/TextHostControlService.h
index 454be09b..40ba017a 100644
--- a/include/cru/ui/controls/TextHostControlService.h
+++ b/include/cru/ui/controls/TextHostControlService.h
@@ -201,6 +201,8 @@ class CRU_UI_API TextHostControlService : public Object {
platform::gui::TimerAutoCanceler caret_timer_canceler_;
int caret_blink_duration_ = k_default_caret_blink_duration;
+ platform::gui::TimerAutoCanceler scroll_to_caret_timer_canceler_;
+
helper::ShortcutHub shortcut_hub_;
// true if left mouse is down and selecting
diff --git a/include/cru/ui/controls/Window.h b/include/cru/ui/controls/Window.h
index c4ba94d9..e25694ba 100644
--- a/include/cru/ui/controls/Window.h
+++ b/include/cru/ui/controls/Window.h
@@ -1,20 +1,188 @@
#pragma once
-#include "cru/ui/controls/RootControl.h"
+#include "../render/StackLayoutRenderObject.h"
+#include "LayoutControl.h"
-#include "cru/base/Base.h"
+#include <cru/base/Base.h>
+#include <cru/base/Event.h>
+#include <cru/base/Guard.h>
+#include <cru/base/log/Logger.h>
+#include <cru/platform/gui/UiApplication.h>
+#include <cru/platform/gui/Window.h>
namespace cru::ui::controls {
-class CRU_UI_API Window final : public RootControl {
+class CRU_UI_API Window
+ : public LayoutControl<render::StackLayoutRenderObject> {
+ CRU_DEFINE_CLASS_LOG_TAG("cru::ui::controls::Window")
public:
- static constexpr std::string_view control_type = "Window";
+ static constexpr std::string_view kControlType = "Window";
- public:
- explicit Window(Control* attached_control = nullptr);
- CRU_DELETE_COPY(Window)
- CRU_DELETE_MOVE(Window)
+ Window();
~Window() override;
- public:
- std::string GetControlType() const final { return std::string(control_type); }
+ static Window* CreatePopup();
+
+ std::string GetControlType() const override;
+
+ void SetAttachedControl(Control* control);
+
+ platform::gui::INativeWindow* GetNativeWindow();
+
+ void InvalidateLayout();
+ void InvalidatePaint();
+
+ void Repaint();
+ void Relayout();
+ void RelayoutWithSize(const Size& available_size = Size::Infinite(),
+ bool set_window_size_to_fit_content = false);
+
+ void SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value);
+
+ // If true, preferred size of root render object is set to window size when
+ // measure. Default is true.
+ bool IsLayoutPreferToFillWindow() const;
+ void SetLayoutPreferToFillWindow(bool value);
+
+ // Get current control that mouse hovers on. This ignores the mouse-capture
+ // control. Even when mouse is captured by another control, this function
+ // return the control under cursor. You can use `GetMouseCaptureControl` to
+ // get more info.
+ Control* GetMouseHoverControl() const { return mouse_hover_control_; }
+
+ Control* GetFocusControl();
+ void SetFocusControl(Control* control);
+
+ Control* GetMouseCaptureControl();
+ bool SetMouseCaptureControl(Control* control);
+
+ std::shared_ptr<platform::gui::ICursor> GetOverrideCursor();
+ void SetOverrideCursor(std::shared_ptr<platform::gui::ICursor> cursor);
+
+ bool IsInEventHandling();
+ void UpdateCursor();
+
+ CRU_DEFINE_EVENT(AfterLayout, std::nullptr_t)
+
+ private:
+ std::unique_ptr<platform::gui::INativeWindow> CreateNativeWindow();
+
+ void OnNativeDestroy(platform::gui::INativeWindow* window, std::nullptr_t);
+ void OnNativePaint(platform::gui::INativeWindow* window, std::nullptr_t);
+ void OnNativeResize(platform::gui::INativeWindow* window, const Size& size);
+ void OnNativeFocus(platform::gui::INativeWindow* window,
+ cru::platform::gui::FocusChangeType focus);
+ void OnNativeMouseEnterLeave(platform::gui::INativeWindow* window,
+ cru::platform::gui::MouseEnterLeaveType enter);
+ void OnNativeMouseMove(platform::gui::INativeWindow* window,
+ const Point& point);
+ void OnNativeMouseDown(platform::gui::INativeWindow* window,
+ const platform::gui::NativeMouseButtonEventArgs& args);
+ void OnNativeMouseUp(platform::gui::INativeWindow* window,
+ const platform::gui::NativeMouseButtonEventArgs& args);
+ void OnNativeMouseWheel(platform::gui::INativeWindow* window,
+ const platform::gui::NativeMouseWheelEventArgs& args);
+ void OnNativeKeyDown(platform::gui::INativeWindow* window,
+ const platform::gui::NativeKeyEventArgs& args);
+ void OnNativeKeyUp(platform::gui::INativeWindow* window,
+ const platform::gui::NativeKeyEventArgs& args);
+
+ void DispatchFocusControlChangeEvent(Control* old_control,
+ Control* new_control, bool is_window);
+ void DispatchMouseHoverControlChangeEvent(Control* old_control,
+ Control* new_control,
+ const Point& point, bool no_leave,
+ bool no_enter);
+
+ template <typename EventArgs, typename... Args>
+ void DispatchEvent(Control* const original_sender,
+ events::RoutedEvent<EventArgs>* (Control::*event_ptr)(),
+ Control* const last_receiver, Args&&... args) {
+ constexpr auto kLogTag = "cru::ui::controls::DispatchEvent";
+
+ event_handling_count_++;
+ Guard event_handling_count_guard([this] { event_handling_count_--; });
+
+ if (original_sender == nullptr || original_sender == last_receiver) return;
+
+ std::string log = "Begin dispatching routed event " +
+ (original_sender->*event_ptr)()->GetName() + ":\n\tTunnel:";
+
+ Guard logging_guard([&] {
+ log += "\nEnd dispatching routed event " +
+ (original_sender->*event_ptr)()->GetName() + ".";
+ CRU_LOG_TAG_DEBUG("{}", log);
+ });
+
+ std::vector<Control*> receive_list;
+
+ auto parent = original_sender;
+ while (parent != last_receiver) {
+ receive_list.push_back(parent);
+ parent = parent->GetParent();
+ }
+
+ auto handled = false;
+
+ // tunnel
+ for (auto i = receive_list.crbegin(); i != receive_list.crend(); ++i) {
+ auto control = *i;
+ log += " ";
+ log += control->GetDebugId();
+ EventArgs event_args(control, original_sender,
+ std::forward<Args>(args)...);
+ (control->*event_ptr)()->tunnel_.Raise(event_args);
+ if (event_args.IsHandled()) {
+ log += " marked as handled.";
+ handled = true;
+ break;
+ }
+ }
+
+ // bubble
+ if (!handled) {
+ log += "\n\tBubble:";
+ for (auto control : receive_list) {
+ log += " ";
+ log += control->GetDebugId();
+ EventArgs event_args(control, original_sender,
+ std::forward<Args>(args)...);
+ (control->*event_ptr)()->bubble_.Raise(event_args);
+ if (event_args.IsHandled()) {
+ log += " marked as handled.";
+ break;
+ }
+ }
+ }
+
+ log += "\n\tDirect:";
+ // direct
+ for (auto control : receive_list) {
+ log += " ";
+ log += control->GetDebugId();
+ EventArgs event_args(control, original_sender,
+ std::forward<Args>(args)...);
+ (control->*event_ptr)()->direct_.Raise(event_args);
+ }
+ }
+
+ private:
+ int event_handling_count_;
+
+ std::unique_ptr<platform::gui::INativeWindow> native_window_;
+
+ Control* focus_control_;
+ Control* mouse_hover_control_;
+ Control* mouse_captured_control_;
+
+ std::shared_ptr<platform::gui::ICursor> override_cursor_;
+
+ bool layout_prefer_to_fill_window_;
+
+ platform::gui::TimerAutoCanceler repaint_schedule_canceler_;
+ platform::gui::TimerAutoCanceler relayout_schedule_canceler_;
+
+ Control* attached_control_;
+
+ EventHandlerRevokerListGuard
+ gain_focus_on_create_and_destroy_when_lose_focus_event_guard_;
};
} // namespace cru::ui::controls
diff --git a/include/cru/ui/events/RoutedEvent.h b/include/cru/ui/events/RoutedEvent.h
index aa3331a6..58e50d63 100644
--- a/include/cru/ui/events/RoutedEvent.h
+++ b/include/cru/ui/events/RoutedEvent.h
@@ -8,6 +8,8 @@ namespace cru::ui::events {
// EventArgs must be reference because the IsHandled property must be settable.
template <typename TEventArgs>
class CRU_UI_API RoutedEvent {
+ friend controls::Window;
+
public:
static_assert(std::is_base_of_v<UiEventArgs, TEventArgs>,
"TEventArgs must be subclass of UiEventArgs.");
@@ -16,13 +18,29 @@ class CRU_UI_API RoutedEvent {
using EventArgs = TEventArgs&;
+ explicit RoutedEvent(std::string name) : name_(std::move(name)) {}
+
+ std::string GetName() const { return name_; }
+
IEvent<TEventArgs&>* Direct() { return &direct_; }
IEvent<TEventArgs&>* Bubble() { return &bubble_; }
IEvent<TEventArgs&>* Tunnel() { return &tunnel_; }
private:
+ std::string name_;
+
Event<TEventArgs&> direct_;
Event<TEventArgs&> bubble_;
Event<TEventArgs&> tunnel_;
};
-} // namespace cru::ui::event
+
+#define CRU_DEFINE_ROUTED_EVENT(name, arg_type) \
+ private: \
+ ::cru::ui::events::RoutedEvent<arg_type> name##Event_{#name}; \
+ \
+ public: \
+ ::cru::ui::events::RoutedEvent<arg_type>* name##Event() { \
+ return &name##Event_; \
+ }
+
+} // namespace cru::ui::events
diff --git a/include/cru/ui/host/LayoutPaintCycler.h b/include/cru/ui/host/LayoutPaintCycler.h
deleted file mode 100644
index e4ff7aa8..00000000
--- a/include/cru/ui/host/LayoutPaintCycler.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-#include "../Base.h"
-
-#include "cru/platform/gui/UiApplication.h"
-
-#include <chrono>
-
-namespace cru::ui::host {
-class CRU_UI_API LayoutPaintCycler {
- public:
- explicit LayoutPaintCycler(WindowHost* host);
-
- CRU_DELETE_COPY(LayoutPaintCycler)
- CRU_DELETE_MOVE(LayoutPaintCycler)
-
- ~LayoutPaintCycler();
-
- public:
- void InvalidateLayout();
- void InvalidatePaint();
-
- bool IsLayoutDirty() { return layout_dirty_; }
-
- private:
- void OnCycle();
-
- private:
- WindowHost* host_;
-
- platform::gui::TimerAutoCanceler timer_canceler_;
-
- bool layout_dirty_ = true;
- bool paint_dirty_ = true;
-
- std::chrono::steady_clock::time_point last_cycle_time_;
- std::chrono::steady_clock::duration cycle_threshold_ =
- std::chrono::milliseconds(1000) / 144;
-};
-} // namespace cru::ui::host
diff --git a/include/cru/ui/host/WindowHost.h b/include/cru/ui/host/WindowHost.h
deleted file mode 100644
index 13b06b07..00000000
--- a/include/cru/ui/host/WindowHost.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#pragma once
-#include "../Base.h"
-
-#include "../render/RenderObject.h"
-#include "cru/base/Event.h"
-#include "cru/platform/gui/Cursor.h"
-#include "cru/platform/gui/UiApplication.h"
-#include "cru/platform/gui/Window.h"
-
-#include <functional>
-#include <memory>
-
-namespace cru::ui::host {
-class LayoutPaintCycler;
-
-struct AfterLayoutEventArgs {};
-
-// The bridge between control tree and native window.
-class CRU_UI_API WindowHost : public Object {
- friend controls::Control;
- CRU_DEFINE_CLASS_LOG_TAG("WindowHost")
-
- private:
- static int event_handling_depth_;
-
- public:
- static bool IsInEventHandling() { return event_handling_depth_ > 0; }
- static void EnterEventHandling();
- static void LeaveEventHandling();
-
- public:
- explicit WindowHost(controls::Control* root_control);
- ~WindowHost() override;
-
- public:
- platform::gui::INativeWindow* GetNativeWindow() {
- return native_window_.get();
- }
-
- // Mark the layout as invalid, and arrange a re-layout later.
- // This method could be called more than one times in a message cycle. But
- // layout only takes place once.
- void InvalidateLayout();
-
- // Mark the paint as invalid, and arrange a re-paint later.
- // This method could be called more than one times in a message cycle. But
- // paint only takes place once.
- void InvalidatePaint();
-
- IEvent<AfterLayoutEventArgs>* AfterLayoutEvent() {
- return &after_layout_event_;
- }
-
- void Relayout();
- void RelayoutWithSize(const Size& available_size = Size::Infinite(),
- bool set_window_size_to_fit_content = false);
-
- void Repaint();
-
- // Is layout is invalid, wait for relayout and then run the action. Otherwist
- // run it right now.
- void RunAfterLayoutStable(std::function<void()> action);
-
- // If true, preferred size of root render object is set to window size when
- // measure. Default is true.
- bool IsLayoutPreferToFillWindow() const;
- void SetLayoutPreferToFillWindow(bool value);
-
- // Get current control that mouse hovers on. This ignores the mouse-capture
- // control. Even when mouse is captured by another control, this function
- // return the control under cursor. You can use `GetMouseCaptureControl` to
- // get more info.
- controls::Control* GetMouseHoverControl() const {
- return mouse_hover_control_;
- }
-
- //*************** region: focus ***************
-
- controls::Control* GetFocusControl();
-
- void SetFocusControl(controls::Control* control);
-
- //*************** region: focus ***************
-
- // Pass nullptr to release capture. If mouse is already capture by a control,
- // this capture will fail and return false. If control is identical to the
- // capturing control, capture is not changed and this function will return
- // true.
- //
- // When capturing control changes,
- // appropriate event will be sent. If mouse is not on the capturing control
- // and capture is released, mouse enter event will be sent to the mouse-hover
- // control. If mouse is not on the capturing control and capture is set, mouse
- // leave event will be sent to the mouse-hover control.
- bool CaptureMouseFor(controls::Control* control);
-
- // Return null if not captured.
- controls::Control* GetMouseCaptureControl();
-
- controls::Control* HitTest(const Point& point);
-
- void UpdateCursor();
-
- IEvent<platform::gui::INativeWindow*>* NativeWindowChangeEvent() {
- return &native_window_change_event_;
- }
-
- std::shared_ptr<platform::gui::ICursor> GetOverrideCursor();
- void SetOverrideCursor(std::shared_ptr<platform::gui::ICursor> cursor);
-
- private:
- std::unique_ptr<platform::gui::INativeWindow> CreateNativeWindow();
-
- //*************** region: native messages ***************
- void OnNativeDestroy(platform::gui::INativeWindow* window, std::nullptr_t);
- void OnNativePaint(platform::gui::INativeWindow* window, std::nullptr_t);
- void OnNativeResize(platform::gui::INativeWindow* window, const Size& size);
-
- void OnNativeFocus(platform::gui::INativeWindow* window,
- cru::platform::gui::FocusChangeType focus);
-
- void OnNativeMouseEnterLeave(platform::gui::INativeWindow* window,
- cru::platform::gui::MouseEnterLeaveType enter);
- void OnNativeMouseMove(platform::gui::INativeWindow* window,
- const Point& point);
- void OnNativeMouseDown(platform::gui::INativeWindow* window,
- const platform::gui::NativeMouseButtonEventArgs& args);
- void OnNativeMouseUp(platform::gui::INativeWindow* window,
- const platform::gui::NativeMouseButtonEventArgs& args);
- void OnNativeMouseWheel(platform::gui::INativeWindow* window,
- const platform::gui::NativeMouseWheelEventArgs& args);
-
- void OnNativeKeyDown(platform::gui::INativeWindow* window,
- const platform::gui::NativeKeyEventArgs& args);
- void OnNativeKeyUp(platform::gui::INativeWindow* window,
- const platform::gui::NativeKeyEventArgs& args);
-
- //*************** region: event dispatcher helper ***************
-
- void DispatchMouseHoverControlChangeEvent(controls::Control* old_control,
- controls::Control* new_control,
- const Point& point, bool no_leave,
- bool no_enter);
-
- void OnControlDetach(controls::Control* control);
-
- private:
- controls::Control* root_control_ = nullptr;
- render::RenderObject* root_render_object_ = nullptr;
-
- std::unique_ptr<platform::gui::INativeWindow> native_window_;
-
- std::unique_ptr<LayoutPaintCycler> layout_paint_cycler_;
-
- Event<AfterLayoutEventArgs> after_layout_event_;
- std::vector<std::function<void()> > after_layout_stable_action_;
-
- std::vector<EventHandlerRevokerGuard> event_revoker_guards_;
-
- controls::Control* mouse_hover_control_ = nullptr;
-
- controls::Control* focus_control_;
-
- controls::Control* mouse_captured_control_ = nullptr;
-
- bool layout_prefer_to_fill_window_ = false;
-
- Event<platform::gui::INativeWindow*> native_window_change_event_;
-
- std::shared_ptr<platform::gui::ICursor> override_cursor_;
-};
-} // namespace cru::ui::host
diff --git a/include/cru/ui/render/RenderObject.h b/include/cru/ui/render/RenderObject.h
index 34761b51..c299ea24 100644
--- a/include/cru/ui/render/RenderObject.h
+++ b/include/cru/ui/render/RenderObject.h
@@ -137,7 +137,7 @@ class CRU_UI_API RenderObject : public Object {
virtual RenderObject* HitTest(const Point& point) = 0;
public:
- host::WindowHost* GetWindowHost();
+ controls::Window* GetWindow();
void InvalidateLayout();
void InvalidatePaint();
diff --git a/include/cru/ui/render/ScrollBar.h b/include/cru/ui/render/ScrollBar.h
index 13c7d8b0..2325acd1 100644
--- a/include/cru/ui/render/ScrollBar.h
+++ b/include/cru/ui/render/ScrollBar.h
@@ -5,11 +5,9 @@
#include "cru/platform/graphics/Brush.h"
#include "cru/platform/graphics/Geometry.h"
#include "cru/platform/graphics/Painter.h"
-#include "cru/platform/gui/Cursor.h"
#include "cru/platform/gui/UiApplication.h"
#include "cru/ui/Base.h"
#include "cru/ui/controls/Control.h"
-#include "cru/ui/helper/ClickDetector.h"
#include <memory>
#include <optional>
@@ -38,8 +36,8 @@ enum class ScrollBarAreaKind {
enum class ScrollBarBrushUsageKind { Arrow, ArrowBackground, Slot, Thumb };
enum class ScrollBarBrushStateKind { Normal, Hover, Press, Disable };
-std::string CRU_UI_API GenerateScrollBarThemeColorKey(ScrollBarBrushUsageKind usage,
- ScrollBarBrushStateKind state);
+std::string CRU_UI_API GenerateScrollBarThemeColorKey(
+ ScrollBarBrushUsageKind usage, ScrollBarBrushStateKind state);
class CRU_UI_API ScrollBar : public Object {
public:
@@ -139,7 +137,7 @@ class CRU_UI_API ScrollBar : public Object {
Event<Scroll> scroll_attempt_event_;
- bool cursor_overrided_ = false;
+ bool cursor_overridden_ = false;
platform::gui::TimerAutoCanceler auto_collapse_timer_canceler_;
};