From 74bb9cd27242b9320f99ff4d2b50c3051576cc14 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 8 Feb 2022 16:53:51 +0800 Subject: ... --- include/cru/ui/host/LayoutPaintCycler.h | 40 ++++++++ include/cru/ui/host/LayoutPaintCycler.hpp | 40 -------- include/cru/ui/host/WindowHost.h | 164 ++++++++++++++++++++++++++++++ include/cru/ui/host/WindowHost.hpp | 164 ------------------------------ 4 files changed, 204 insertions(+), 204 deletions(-) create mode 100644 include/cru/ui/host/LayoutPaintCycler.h delete mode 100644 include/cru/ui/host/LayoutPaintCycler.hpp create mode 100644 include/cru/ui/host/WindowHost.h delete mode 100644 include/cru/ui/host/WindowHost.hpp (limited to 'include/cru/ui/host') diff --git a/include/cru/ui/host/LayoutPaintCycler.h b/include/cru/ui/host/LayoutPaintCycler.h new file mode 100644 index 00000000..e95ed81d --- /dev/null +++ b/include/cru/ui/host/LayoutPaintCycler.h @@ -0,0 +1,40 @@ +#pragma once +#include "../Base.h" + +#include "cru/platform/gui/TimerHelper.h" +#include "cru/platform/gui/UiApplication.h" + +#include + +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/LayoutPaintCycler.hpp b/include/cru/ui/host/LayoutPaintCycler.hpp deleted file mode 100644 index 1d44ad06..00000000 --- a/include/cru/ui/host/LayoutPaintCycler.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "../Base.hpp" - -#include "cru/platform/gui/TimerHelper.hpp" -#include "cru/platform/gui/UiApplication.hpp" - -#include - -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 new file mode 100644 index 00000000..caa50397 --- /dev/null +++ b/include/cru/ui/host/WindowHost.h @@ -0,0 +1,164 @@ +#pragma once +#include "../Base.h" + +#include "../render/Base.h" +#include "cru/common/Event.h" +#include "cru/platform/gui/Cursor.h" +#include "cru/platform/gui/UiApplication.h" +#include "cru/platform/gui/Window.h" + +#include +#include +#include + +namespace cru::ui::host { +class LayoutPaintCycler; + +struct AfterLayoutEventArgs {}; + +// The bridge between control tree and native window. +class CRU_UI_API WindowHost : public Object { + CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::host::WindowHost") + + public: + explicit WindowHost(controls::Control* root_control); + + CRU_DELETE_COPY(WindowHost) + CRU_DELETE_MOVE(WindowHost) + + ~WindowHost() override; + + public: + platform::gui::INativeWindow* GetNativeWindow() { return native_window_; } + + // 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* AfterLayoutEvent() { + return &after_layout_event_; + } + + void Relayout(); + void RelayoutWithSize(const Size& available_size = Size::Infinate(), + 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 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* NativeWindowChangeEvent() { + return &native_window_change_event_; + } + + std::shared_ptr GetOverrideCursor(); + void SetOverrideCursor(std::shared_ptr cursor); + + private: + gsl::not_null 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); + + private: + controls::Control* root_control_ = nullptr; + render::RenderObject* root_render_object_ = nullptr; + + platform::gui::INativeWindow* native_window_ = nullptr; + + std::unique_ptr layout_paint_cycler_; + + Event after_layout_event_; + std::vector > after_layout_stable_action_; + + std::vector 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 native_window_change_event_; + + std::shared_ptr override_cursor_; +}; +} // namespace cru::ui::host diff --git a/include/cru/ui/host/WindowHost.hpp b/include/cru/ui/host/WindowHost.hpp deleted file mode 100644 index 7832174c..00000000 --- a/include/cru/ui/host/WindowHost.hpp +++ /dev/null @@ -1,164 +0,0 @@ -#pragma once -#include "../Base.hpp" - -#include "../render/Base.hpp" -#include "cru/common/Event.hpp" -#include "cru/platform/gui/Cursor.hpp" -#include "cru/platform/gui/UiApplication.hpp" -#include "cru/platform/gui/Window.hpp" - -#include -#include -#include - -namespace cru::ui::host { -class LayoutPaintCycler; - -struct AfterLayoutEventArgs {}; - -// The bridge between control tree and native window. -class CRU_UI_API WindowHost : public Object { - CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::host::WindowHost") - - public: - explicit WindowHost(controls::Control* root_control); - - CRU_DELETE_COPY(WindowHost) - CRU_DELETE_MOVE(WindowHost) - - ~WindowHost() override; - - public: - platform::gui::INativeWindow* GetNativeWindow() { return native_window_; } - - // 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* AfterLayoutEvent() { - return &after_layout_event_; - } - - void Relayout(); - void RelayoutWithSize(const Size& available_size = Size::Infinate(), - 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 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* NativeWindowChangeEvent() { - return &native_window_change_event_; - } - - std::shared_ptr GetOverrideCursor(); - void SetOverrideCursor(std::shared_ptr cursor); - - private: - gsl::not_null 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); - - private: - controls::Control* root_control_ = nullptr; - render::RenderObject* root_render_object_ = nullptr; - - platform::gui::INativeWindow* native_window_ = nullptr; - - std::unique_ptr layout_paint_cycler_; - - Event after_layout_event_; - std::vector > after_layout_stable_action_; - - std::vector 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 native_window_change_event_; - - std::shared_ptr override_cursor_; -}; -} // namespace cru::ui::host -- cgit v1.2.3