diff options
37 files changed, 209 insertions, 190 deletions
diff --git a/demos/main/main.cpp b/demos/main/main.cpp index 5546f3dd..dd3e31e9 100644 --- a/demos/main/main.cpp +++ b/demos/main/main.cpp @@ -2,19 +2,19 @@ #include "cru/platform/gui/UiApplication.hpp" #include "cru/platform/gui/Window.hpp" #include "cru/ui/Base.hpp" -#include "cru/ui/Window.hpp" -#include "cru/ui/host/WindowHost.hpp" #include "cru/ui/controls/Button.hpp" #include "cru/ui/controls/FlexLayout.hpp" #include "cru/ui/controls/TextBlock.hpp" #include "cru/ui/controls/TextBox.hpp" +#include "cru/ui/controls/Window.hpp" +#include "cru/ui/host/WindowHost.hpp" using cru::platform::gui::CreateUiApplication; -using cru::ui::Window; using cru::ui::controls::Button; using cru::ui::controls::FlexLayout; using cru::ui::controls::TextBlock; using cru::ui::controls::TextBox; +using cru::ui::controls::Window; int main() { #ifdef CRU_DEBUG diff --git a/include/cru/platform/gui/UiApplication.hpp b/include/cru/platform/gui/UiApplication.hpp index ff947dfc..ba85020a 100644 --- a/include/cru/platform/gui/UiApplication.hpp +++ b/include/cru/platform/gui/UiApplication.hpp @@ -1,12 +1,24 @@ #pragma once #include "Base.hpp" +#include "cru/common/Bitmask.hpp" + #include <chrono> #include <functional> #include <memory> #include <vector> namespace cru::platform::gui { +namespace details { +struct CreateWindowFlagTag; +} + +using CreateWindowFlag = Bitmask<details::CreateWindowFlagTag>; + +struct CreateWindowFlags { + static constexpr CreateWindowFlag NoCaptionAndBorder{0b1}; +}; + // The entry point of a ui application. struct IUiApplication : public virtual INativeResource { public: @@ -43,7 +55,12 @@ struct IUiApplication : public virtual INativeResource { virtual void CancelTimer(long long id) = 0; virtual std::vector<INativeWindow*> GetAllWindow() = 0; - virtual INativeWindow* CreateWindow(INativeWindow* parent) = 0; + + INativeWindow* CreateWindow(INativeWindow* parent) { + return this->CreateWindow(parent, CreateWindowFlag(0)); + }; + virtual INativeWindow* CreateWindow(INativeWindow* parent, + CreateWindowFlag flags) = 0; virtual cru::platform::graphics::IGraphFactory* GetGraphFactory() = 0; diff --git a/include/cru/ui/Base.hpp b/include/cru/ui/Base.hpp index 39fbb035..8595258d 100644 --- a/include/cru/ui/Base.hpp +++ b/include/cru/ui/Base.hpp @@ -26,9 +26,11 @@ namespace mouse_buttons = cru::platform::gui::mouse_buttons; namespace colors = cru::platform::colors; //-------------------- region: forward declaration -------------------- + +namespace controls { class Window; class Control; -class ClickDetector; +} // namespace controls namespace host { class WindowHost; diff --git a/include/cru/ui/controls/Base.hpp b/include/cru/ui/controls/Base.hpp index b550601b..82c31d1e 100644 --- a/include/cru/ui/controls/Base.hpp +++ b/include/cru/ui/controls/Base.hpp @@ -2,7 +2,7 @@ #include "../Base.hpp" namespace cru::ui::controls { -using ButtonStateStyle = BorderStyle; +using ButtonStateStyle = ui::BorderStyle; struct ButtonStyle { // corresponds to ClickState::None @@ -16,9 +16,9 @@ struct ButtonStyle { }; struct TextBoxBorderStyle { - BorderStyle normal; - BorderStyle hover; - BorderStyle focus; - BorderStyle focus_hover; + ui::BorderStyle normal; + ui::BorderStyle hover; + ui::BorderStyle focus; + ui::BorderStyle focus_hover; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/Button.hpp b/include/cru/ui/controls/Button.hpp index a4f727d6..e8285507 100644 --- a/include/cru/ui/controls/Button.hpp +++ b/include/cru/ui/controls/Button.hpp @@ -1,8 +1,7 @@ #pragma once -#include "../ContentControl.hpp" -#include "Base.hpp" +#include "ContentControl.hpp" -#include "../ClickDetector.hpp" +#include "../helper/ClickDetector.hpp" namespace cru::ui::controls { class Button : public ContentControl { @@ -37,6 +36,6 @@ class Button : public ContentControl { ButtonStyle style_; - ClickDetector click_detector_; + helper::ClickDetector click_detector_; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/Container.hpp b/include/cru/ui/controls/Container.hpp index 304d402c..d9cb8aec 100644 --- a/include/cru/ui/controls/Container.hpp +++ b/include/cru/ui/controls/Container.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../ContentControl.hpp" +#include "ContentControl.hpp" namespace cru::ui::controls { class Container : public ContentControl { diff --git a/include/cru/ui/ContentControl.hpp b/include/cru/ui/controls/ContentControl.hpp index ba5b6b2f..47720a87 100644 --- a/include/cru/ui/ContentControl.hpp +++ b/include/cru/ui/controls/ContentControl.hpp @@ -1,7 +1,7 @@ #pragma once #include "Control.hpp" -namespace cru::ui { +namespace cru::ui::controls { class ContentControl : public Control { protected: ContentControl() = default; @@ -23,4 +23,4 @@ class ContentControl : public Control { using Control::AddChild; using Control::RemoveChild; }; -} // namespace cru::ui +} // namespace cru::ui::controls diff --git a/include/cru/ui/Control.hpp b/include/cru/ui/controls/Control.hpp index fe50624a..96aad2bd 100644 --- a/include/cru/ui/Control.hpp +++ b/include/cru/ui/controls/Control.hpp @@ -1,13 +1,13 @@ #pragma once #include "Base.hpp" -#include "UiEvent.hpp" +#include "../events/UiEvent.hpp" +#include "../render/Base.hpp" #include "cru/common/Event.hpp" -#include "render/Base.hpp" #include <string_view> -namespace cru::ui { +namespace cru::ui::controls { class Control : public Object { friend host::WindowHost; @@ -148,4 +148,4 @@ class Control : public Object { std::shared_ptr<platform::gui::ICursor> cursor_ = nullptr; }; -} // namespace cru::ui +} // namespace cru::ui::controls diff --git a/include/cru/ui/controls/FlexLayout.hpp b/include/cru/ui/controls/FlexLayout.hpp index 0ffedba5..a6c6a40c 100644 --- a/include/cru/ui/controls/FlexLayout.hpp +++ b/include/cru/ui/controls/FlexLayout.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../LayoutControl.hpp" +#include "LayoutControl.hpp" namespace cru::ui::controls { class FlexLayout : public LayoutControl { diff --git a/include/cru/ui/LayoutControl.hpp b/include/cru/ui/controls/LayoutControl.hpp index 69d5cd0b..cbdb8aa2 100644 --- a/include/cru/ui/LayoutControl.hpp +++ b/include/cru/ui/controls/LayoutControl.hpp @@ -1,7 +1,7 @@ #pragma once #include "Control.hpp" -namespace cru::ui { +namespace cru::ui::controls { class LayoutControl : public Control { protected: LayoutControl() = default; diff --git a/include/cru/ui/NoChildControl.hpp b/include/cru/ui/controls/NoChildControl.hpp index 0d8a8e34..562137f1 100644 --- a/include/cru/ui/NoChildControl.hpp +++ b/include/cru/ui/controls/NoChildControl.hpp @@ -1,7 +1,7 @@ #pragma once #include "Control.hpp" -namespace cru::ui { +namespace cru::ui::controls { class NoChildControl : public Control { protected: NoChildControl() = default; diff --git a/include/cru/ui/controls/StackLayout.hpp b/include/cru/ui/controls/StackLayout.hpp index c0b95044..373b4681 100644 --- a/include/cru/ui/controls/StackLayout.hpp +++ b/include/cru/ui/controls/StackLayout.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../LayoutControl.hpp" +#include "LayoutControl.hpp" namespace cru::ui::controls { class StackLayout : public LayoutControl { diff --git a/include/cru/ui/controls/TextBlock.hpp b/include/cru/ui/controls/TextBlock.hpp index 8a9a3bff..fdfdb2fa 100644 --- a/include/cru/ui/controls/TextBlock.hpp +++ b/include/cru/ui/controls/TextBlock.hpp @@ -1,5 +1,5 @@ #pragma once -#include "../NoChildControl.hpp" +#include "NoChildControl.hpp" namespace cru::ui::controls { template <typename TControl> diff --git a/include/cru/ui/controls/TextBox.hpp b/include/cru/ui/controls/TextBox.hpp index 5976f6da..91d38c61 100644 --- a/include/cru/ui/controls/TextBox.hpp +++ b/include/cru/ui/controls/TextBox.hpp @@ -1,6 +1,5 @@ #pragma once -#include "../NoChildControl.hpp" -#include "Base.hpp" +#include "NoChildControl.hpp" #include <memory> diff --git a/include/cru/ui/Window.hpp b/include/cru/ui/controls/Window.hpp index 70423a14..616e2ee7 100644 --- a/include/cru/ui/Window.hpp +++ b/include/cru/ui/controls/Window.hpp @@ -1,7 +1,7 @@ #pragma once #include "LayoutControl.hpp" -namespace cru::ui { +namespace cru::ui::controls { class Window final : public LayoutControl { public: static constexpr std::u16string_view control_type = u"Window"; diff --git a/include/cru/ui/UiEvent.hpp b/include/cru/ui/events/UiEvent.hpp index c0b2a902..660b33f5 100644 --- a/include/cru/ui/UiEvent.hpp +++ b/include/cru/ui/events/UiEvent.hpp @@ -1,5 +1,5 @@ #pragma once -#include "Base.hpp" +#include "../Base.hpp" #include "cru/common/Event.hpp" #include "cru/platform/gui/Keyboard.hpp" diff --git a/include/cru/ui/ClickDetector.hpp b/include/cru/ui/helper/ClickDetector.hpp index 4ffe5d05..0df77c60 100644 --- a/include/cru/ui/ClickDetector.hpp +++ b/include/cru/ui/helper/ClickDetector.hpp @@ -1,10 +1,10 @@ #pragma once -#include "Control.hpp" +#include "../controls/Control.hpp" -namespace cru::ui { +namespace cru::ui::helper { class ClickEventArgs : Object { public: - ClickEventArgs(Control* sender, const Point& down_point, + ClickEventArgs(controls::Control* sender, const Point& down_point, const Point& up_point, MouseButton button) : sender_(sender), down_point_(down_point), @@ -16,13 +16,13 @@ class ClickEventArgs : Object { ~ClickEventArgs() override = default; - Control* GetSender() const { return sender_; } + controls::Control* GetSender() const { return sender_; } Point GetDownPoint() const { return down_point_; } Point GetUpPoint() const { return up_point_; } MouseButton GetButton() const { return button_; } private: - Control* sender_; + controls::Control* sender_; Point down_point_; Point up_point_; MouseButton button_; @@ -39,14 +39,14 @@ class ClickDetector : public Object { CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::ClickDetector") public: - explicit ClickDetector(Control* control); + explicit ClickDetector(controls::Control* control); CRU_DELETE_COPY(ClickDetector) CRU_DELETE_MOVE(ClickDetector) ~ClickDetector() override = default; - Control* GetControl() const { return control_; } + controls::Control* GetControl() const { return control_; } ClickState GetState() const { return state_; } @@ -69,7 +69,7 @@ class ClickDetector : public Object { void SetState(ClickState state); private: - Control* control_; + controls::Control* control_; ClickState state_; @@ -84,4 +84,4 @@ class ClickDetector : public Object { Point down_point_; MouseButton button_; }; -} // namespace cru::ui +} // namespace cru::ui::helper diff --git a/include/cru/ui/ShortcutHub.hpp b/include/cru/ui/helper/ShortcutHub.hpp index 1145c661..a4ff2da2 100644 --- a/include/cru/ui/ShortcutHub.hpp +++ b/include/cru/ui/helper/ShortcutHub.hpp @@ -1,10 +1,9 @@ #pragma once -#include "Base.hpp" +#include "../Base.hpp" -#include "cru/common/Base.hpp" +#include "../events/UiEvent.hpp" #include "cru/common/Event.hpp" #include "cru/platform/gui/Keyboard.hpp" -#include "cru/ui/UiEvent.hpp" #include <cstddef> #include <functional> @@ -16,7 +15,7 @@ #include <unordered_map> #include <vector> -namespace cru::ui { +namespace cru::ui::helper { class ShortcutKeyBind { public: @@ -57,12 +56,12 @@ class ShortcutKeyBind { platform::gui::KeyCode key_; platform::gui::KeyModifier modifier_; }; -} // namespace cru::ui +} // namespace cru::ui::helper namespace std { template <> -struct hash<cru::ui::ShortcutKeyBind> { - std::size_t operator()(const cru::ui::ShortcutKeyBind& value) const { +struct hash<cru::ui::helper::ShortcutKeyBind> { + std::size_t operator()(const cru::ui::helper::ShortcutKeyBind& value) const { std::size_t result = 0; cru::hash_combine(result, static_cast<int>(value.GetKey())); cru::hash_combine(result, static_cast<int>(value.GetModifier())); @@ -71,7 +70,7 @@ struct hash<cru::ui::ShortcutKeyBind> { }; } // namespace std -namespace cru::ui { +namespace cru::ui::helper { struct Shortcut { // Just for debug. std::u16string name; @@ -112,7 +111,7 @@ class ShortcutHub : public Object { const std::vector<ShortcutInfo>& GetShortcutByKeyBind( const ShortcutKeyBind& key_bind) const; - void Install(Control* control); + void Install(controls::Control* control); void Uninstall(); private: @@ -127,4 +126,4 @@ class ShortcutHub : public Object { EventRevokerListGuard event_guard_; }; -} // namespace cru::ui +} // namespace cru::ui::helper diff --git a/include/cru/ui/host/WindowHost.hpp b/include/cru/ui/host/WindowHost.hpp index 81eabb52..56f37382 100644 --- a/include/cru/ui/host/WindowHost.hpp +++ b/include/cru/ui/host/WindowHost.hpp @@ -1,10 +1,10 @@ #pragma once #include "../Base.hpp" +#include "../render/Base.hpp" #include "cru/common/Event.hpp" #include "cru/platform/gui/UiApplication.hpp" #include "cru/platform/gui/Window.hpp" -#include "../render/Base.hpp" #include <functional> #include <memory> @@ -19,7 +19,7 @@ class WindowHost : public Object { CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::host::WindowHost") public: - WindowHost(Control* root_control); + WindowHost(controls::Control* root_control); CRU_DELETE_COPY(WindowHost) CRU_DELETE_MOVE(WindowHost) @@ -61,13 +61,15 @@ class WindowHost : public Object { // 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_; } + controls::Control* GetMouseHoverControl() const { + return mouse_hover_control_; + } //*************** region: focus *************** - Control* GetFocusControl(); + controls::Control* GetFocusControl(); - void SetFocusControl(Control* control); + void SetFocusControl(controls::Control* control); //*************** region: focus *************** @@ -81,12 +83,12 @@ class WindowHost : public Object { // 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(Control* control); + bool CaptureMouseFor(controls::Control* control); // Return null if not captured. - Control* GetMouseCaptureControl(); + controls::Control* GetMouseCaptureControl(); - Control* HitTest(const Point& point); + controls::Control* HitTest(const Point& point); void UpdateCursor(); @@ -94,23 +96,19 @@ class WindowHost : public Object { //*************** 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 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 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 OnNativeMouseDown(platform::gui::INativeWindow* window, + const platform::gui::NativeMouseButtonEventArgs& args); + void OnNativeMouseUp(platform::gui::INativeWindow* window, + const platform::gui::NativeMouseButtonEventArgs& args); void OnNativeKeyDown(platform::gui::INativeWindow* window, const platform::gui::NativeKeyEventArgs& args); @@ -119,13 +117,13 @@ class WindowHost : public Object { //*************** region: event dispatcher helper *************** - void DispatchMouseHoverControlChangeEvent(Control* old_control, - Control* new_control, + void DispatchMouseHoverControlChangeEvent(controls::Control* old_control, + controls::Control* new_control, const Point& point, bool no_leave, bool no_enter); private: - Control* root_control_ = nullptr; + controls::Control* root_control_ = nullptr; render::RenderObject* root_render_object_ = nullptr; platform::gui::INativeWindow* native_window_ = nullptr; @@ -137,12 +135,12 @@ class WindowHost : public Object { std::vector<EventRevokerGuard> event_revoker_guards_; - Control* mouse_hover_control_ = nullptr; + controls::Control* mouse_hover_control_ = nullptr; - Control* focus_control_; + controls::Control* focus_control_; - Control* mouse_captured_control_ = nullptr; + controls::Control* mouse_captured_control_ = nullptr; bool layout_prefer_to_fill_window_ = true; }; -} // namespace cru::ui +} // namespace cru::ui::host diff --git a/include/cru/ui/render/RenderObject.hpp b/include/cru/ui/render/RenderObject.hpp index 635a541e..2b166efc 100644 --- a/include/cru/ui/render/RenderObject.hpp +++ b/include/cru/ui/render/RenderObject.hpp @@ -62,8 +62,10 @@ class RenderObject : public Object { RenderObject& operator=(RenderObject&& other) = delete; ~RenderObject() override = default; - Control* GetAttachedControl() const { return control_; } - void SetAttachedControl(Control* new_control) { control_ = new_control; } + controls::Control* GetAttachedControl() const { return control_; } + void SetAttachedControl(controls::Control* new_control) { + control_ = new_control; + } host::WindowHost* GetWindowHost() const { return window_host_; } @@ -135,7 +137,9 @@ class RenderObject : public Object { // Add offset before pass point to children. virtual RenderObject* HitTest(const Point& point) = 0; - IEvent<host::WindowHost*>* AttachToHostEvent() { return &attach_to_host_event_; } + IEvent<host::WindowHost*>* AttachToHostEvent() { + return &attach_to_host_event_; + } IEvent<std::nullptr_t>* DetachFromHostEvent() { return &detach_from_host_event_; } @@ -208,7 +212,7 @@ class RenderObject : public Object { void SetWindowHostRecursive(host::WindowHost* host); private: - Control* control_ = nullptr; + controls::Control* control_ = nullptr; host::WindowHost* window_host_ = nullptr; RenderObject* parent_ = nullptr; diff --git a/include/cru/win/gui/UiApplication.hpp b/include/cru/win/gui/UiApplication.hpp index 0f733cd4..4cf46858 100644 --- a/include/cru/win/gui/UiApplication.hpp +++ b/include/cru/win/gui/UiApplication.hpp @@ -41,7 +41,7 @@ class WinUiApplication : public WinNativeResource, void CancelTimer(long long id) override; std::vector<INativeWindow*> GetAllWindow() override; - INativeWindow* CreateWindow(INativeWindow* parent) override; + INativeWindow* CreateWindow(INativeWindow* parent, CreateWindowFlag flag) override; cru::platform::graphics::IGraphFactory* GetGraphFactory() override; diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 449fb4d9..2f0eb10d 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -4,23 +4,23 @@ add_library(cru_ui STATIC Helper.hpp host/RoutedEventDispatch.hpp - ClickDetector.cpp - ContentControl.cpp - Control.cpp Helper.cpp - LayoutControl.cpp - NoChildControl.cpp - ShortcutHub.cpp - UiEvent.cpp UiManager.cpp - Window.cpp controls/Button.cpp controls/Container.cpp + controls/ContentControl.cpp + controls/Control.cpp controls/FlexLayout.cpp + controls/LayoutControl.cpp + controls/NoChildControl.cpp controls/StackLayout.cpp controls/TextBlock.cpp controls/TextBox.cpp controls/TextControlService.hpp + controls/Window.cpp + events/UiEvent.cpp + helper/ClickDetector.cpp + helper/ShortcutHub.cpp host/LayoutPaintCycler.cpp host/WindowHost.cpp render/BorderRenderObject.cpp @@ -34,23 +34,23 @@ add_library(cru_ui STATIC ) target_sources(cru_ui PUBLIC ${CRU_UI_INCLUDE_DIR}/Base.hpp - ${CRU_UI_INCLUDE_DIR}/ClickDetector.hpp - ${CRU_UI_INCLUDE_DIR}/ContentControl.hpp - ${CRU_UI_INCLUDE_DIR}/Control.hpp ${CRU_UI_INCLUDE_DIR}/DebugFlags.hpp - ${CRU_UI_INCLUDE_DIR}/LayoutControl.hpp - ${CRU_UI_INCLUDE_DIR}/NoChildControl.hpp - ${CRU_UI_INCLUDE_DIR}/ShortcutHub.hpp - ${CRU_UI_INCLUDE_DIR}/UiEvent.hpp ${CRU_UI_INCLUDE_DIR}/UiManager.hpp - ${CRU_UI_INCLUDE_DIR}/Window.hpp ${CRU_UI_INCLUDE_DIR}/controls/Base.hpp ${CRU_UI_INCLUDE_DIR}/controls/Button.hpp ${CRU_UI_INCLUDE_DIR}/controls/Container.hpp + ${CRU_UI_INCLUDE_DIR}/controls/ContentControl.hpp + ${CRU_UI_INCLUDE_DIR}/controls/Control.hpp ${CRU_UI_INCLUDE_DIR}/controls/FlexLayout.hpp + ${CRU_UI_INCLUDE_DIR}/controls/LayoutControl.hpp + ${CRU_UI_INCLUDE_DIR}/controls/NoChildControl.hpp ${CRU_UI_INCLUDE_DIR}/controls/StackLayout.hpp ${CRU_UI_INCLUDE_DIR}/controls/TextBox.hpp ${CRU_UI_INCLUDE_DIR}/controls/TextBlock.hpp + ${CRU_UI_INCLUDE_DIR}/controls/Window.hpp + ${CRU_UI_INCLUDE_DIR}/events/UiEvent.hpp + ${CRU_UI_INCLUDE_DIR}/helper/ClickDetector.hpp + ${CRU_UI_INCLUDE_DIR}/helper/ShortcutHub.hpp ${CRU_UI_INCLUDE_DIR}/host/LayoutPaintCycler.hpp ${CRU_UI_INCLUDE_DIR}/host/WindowHost.hpp ${CRU_UI_INCLUDE_DIR}/render/Base.hpp diff --git a/src/ui/LayoutControl.cpp b/src/ui/LayoutControl.cpp deleted file mode 100644 index 351026f9..00000000 --- a/src/ui/LayoutControl.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "cru/ui/LayoutControl.hpp" - -#include "cru/ui/Window.hpp" - -namespace cru::ui { -} // namespace cru::ui diff --git a/src/ui/NoChildControl.cpp b/src/ui/NoChildControl.cpp deleted file mode 100644 index 8adbe3bc..00000000 --- a/src/ui/NoChildControl.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "cru/ui/NoChildControl.hpp" - -namespace cru::ui {} diff --git a/src/ui/controls/Button.cpp b/src/ui/controls/Button.cpp index 5f7ed143..b7407ec2 100644 --- a/src/ui/controls/Button.cpp +++ b/src/ui/controls/Button.cpp @@ -5,9 +5,9 @@ #include "cru/platform/graphics/Brush.hpp" #include "cru/platform/gui/Cursor.hpp" #include "cru/platform/gui/UiApplication.hpp" -#include "cru/ui/render/BorderRenderObject.hpp" #include "cru/ui/UiManager.hpp" -#include "cru/ui/Window.hpp" +#include "cru/ui/helper/ClickDetector.hpp" +#include "cru/ui/render/BorderRenderObject.hpp" namespace cru::ui::controls { using cru::platform::gui::SystemCursorType; @@ -21,8 +21,7 @@ void Set(render::BorderRenderObject* o, const ButtonStateStyle& s) { o->SetBackgroundBrush(s.background_brush); } -std::shared_ptr<platform::gui::ICursor> GetSystemCursor( - SystemCursorType type) { +std::shared_ptr<platform::gui::ICursor> GetSystemCursor(SystemCursorType type) { return GetUiApplication()->GetCursorManager()->GetSystemCursor(type); } } // namespace @@ -36,21 +35,21 @@ Button::Button() : click_detector_(this) { render_object_->SetBorderEnabled(true); click_detector_.StateChangeEvent()->AddHandler( - [this](const ClickState& state) { + [this](const helper::ClickState& state) { switch (state) { - case ClickState::None: + case helper::ClickState::None: Set(render_object_.get(), style_.normal); SetCursor(GetSystemCursor(SystemCursorType::Arrow)); break; - case ClickState::Hover: + case helper::ClickState::Hover: Set(render_object_.get(), style_.hover); SetCursor(GetSystemCursor(SystemCursorType::Hand)); break; - case ClickState::Press: + case helper::ClickState::Press: Set(render_object_.get(), style_.press); SetCursor(GetSystemCursor(SystemCursorType::Hand)); break; - case ClickState::PressInactive: + case helper::ClickState::PressInactive: Set(render_object_.get(), style_.press_cancel); SetCursor(GetSystemCursor(SystemCursorType::Arrow)); break; diff --git a/src/ui/ContentControl.cpp b/src/ui/controls/ContentControl.cpp index 19b1b06f..653882c0 100644 --- a/src/ui/ContentControl.cpp +++ b/src/ui/controls/ContentControl.cpp @@ -1,8 +1,6 @@ -#include "cru/ui/ContentControl.hpp" +#include "cru/ui/controls/ContentControl.hpp" -#include "cru/ui/Window.hpp" - -namespace cru::ui { +namespace cru::ui::controls { Control* ContentControl::GetChild() const { if (GetChildren().empty()) return nullptr; return GetChildren()[0]; @@ -24,4 +22,4 @@ void ContentControl::OnChildChanged(Control* old_child, Control* new_child) { CRU_UNUSED(old_child) CRU_UNUSED(new_child) } -} // namespace cru::ui +} // namespace cru::ui::controls diff --git a/src/ui/Control.cpp b/src/ui/controls/Control.cpp index 23a3cef2..c1316a62 100644 --- a/src/ui/Control.cpp +++ b/src/ui/controls/Control.cpp @@ -1,4 +1,4 @@ -#include "cru/ui/Control.hpp" +#include "cru/ui/controls/Control.hpp" #include "cru/common/Base.hpp" #include "cru/platform/gui/Cursor.hpp" @@ -9,7 +9,7 @@ #include <memory> -namespace cru::ui { +namespace cru::ui::controls { using platform::gui::ICursor; using platform::gui::IUiApplication; using platform::gui::SystemCursorType; @@ -154,4 +154,4 @@ void Control::OnParentChanged(Control* old_parent, Control* new_parent) { void Control::OnAttachToHost(host::WindowHost* host) { CRU_UNUSED(host) } void Control::OnDetachFromHost(host::WindowHost* host) { CRU_UNUSED(host) } -} // namespace cru::ui +} // namespace cru::ui::controls diff --git a/src/ui/controls/LayoutControl.cpp b/src/ui/controls/LayoutControl.cpp new file mode 100644 index 00000000..85417beb --- /dev/null +++ b/src/ui/controls/LayoutControl.cpp @@ -0,0 +1,3 @@ +#include "cru/ui/controls/LayoutControl.hpp" + +namespace cru::ui::controls {} diff --git a/src/ui/controls/NoChildControl.cpp b/src/ui/controls/NoChildControl.cpp new file mode 100644 index 00000000..c62c5819 --- /dev/null +++ b/src/ui/controls/NoChildControl.cpp @@ -0,0 +1,3 @@ +#include "cru/ui/controls/NoChildControl.hpp" + +namespace cru::ui::controls {} diff --git a/src/ui/controls/TextControlService.hpp b/src/ui/controls/TextControlService.hpp index a7e4e440..8ad95dec 100644 --- a/src/ui/controls/TextControlService.hpp +++ b/src/ui/controls/TextControlService.hpp @@ -8,10 +8,10 @@ #include "cru/platform/gui/UiApplication.hpp" #include "cru/platform/gui/Window.hpp" #include "cru/ui/Base.hpp" -#include "cru/ui/Control.hpp" #include "cru/ui/DebugFlags.hpp" -#include "cru/ui/ShortcutHub.hpp" -#include "cru/ui/UiEvent.hpp" +#include "cru/ui/controls/Control.hpp" +#include "cru/ui/events/UiEvent.hpp" +#include "cru/ui/helper/ShortcutHub.hpp" #include "cru/ui/host/WindowHost.hpp" #include "cru/ui/render/CanvasRenderObject.hpp" #include "cru/ui/render/ScrollRenderObject.hpp" @@ -472,7 +472,7 @@ class TextControlService : public Object { platform::gui::TimerAutoCanceler caret_timer_canceler_; int caret_blink_duration_ = k_default_caret_blink_duration; - ShortcutHub shortcut_hub_; + helper::ShortcutHub shortcut_hub_; // nullopt means not selecting std::optional<MouseButton> select_down_button_; diff --git a/src/ui/Window.cpp b/src/ui/controls/Window.cpp index c49140a4..7ce40dfe 100644 --- a/src/ui/Window.cpp +++ b/src/ui/controls/Window.cpp @@ -1,11 +1,11 @@ -#include "cru/ui/Window.hpp" +#include "cru/ui/controls/Window.hpp" #include "cru/common/Base.hpp" #include "cru/ui/host/WindowHost.hpp" #include "cru/ui/render/Base.hpp" #include "cru/ui/render/StackLayoutRenderObject.hpp" -namespace cru::ui { +namespace cru::ui::controls { Window* Window::CreateOverlapped() { return new Window(); } Window::Window() : render_object_(new render::StackLayoutRenderObject()) { @@ -29,4 +29,4 @@ void Window::OnRemoveChild(Control* child, Index position) { CRU_UNUSED(child); render_object_->RemoveChild(position); } -} // namespace cru::ui +} // namespace cru::ui::controls diff --git a/src/ui/UiEvent.cpp b/src/ui/events/UiEvent.cpp index 74dd54dc..b35f15a7 100644 --- a/src/ui/UiEvent.cpp +++ b/src/ui/events/UiEvent.cpp @@ -1,4 +1,4 @@ -#include "cru/ui/UiEvent.hpp" +#include "cru/ui/events/UiEvent.hpp" #include "cru/ui/render/RenderObject.hpp" diff --git a/src/ui/ClickDetector.cpp b/src/ui/helper/ClickDetector.cpp index 09f208cd..4059f890 100644 --- a/src/ui/ClickDetector.cpp +++ b/src/ui/helper/ClickDetector.cpp @@ -1,11 +1,11 @@ -#include "cru/ui/ClickDetector.hpp" +#include "cru/ui/helper/ClickDetector.hpp" #include "cru/common/Logger.hpp" #include <optional> -namespace cru::ui { -ClickDetector::ClickDetector(Control* control) { +namespace cru::ui::helper { +ClickDetector::ClickDetector(controls::Control* control) { Expects(control); control_ = control; @@ -128,4 +128,4 @@ void ClickDetector::SetState(ClickState state) { state_ = state; state_change_event_.Raise(state); } -} // namespace cru::ui +} // namespace cru::ui::helper diff --git a/src/ui/ShortcutHub.cpp b/src/ui/helper/ShortcutHub.cpp index c9ce6cdd..823072f2 100644 --- a/src/ui/ShortcutHub.cpp +++ b/src/ui/helper/ShortcutHub.cpp @@ -1,15 +1,15 @@ -#include "cru/ui/ShortcutHub.hpp" +#include "cru/ui/helper/ShortcutHub.hpp" #include "cru/common/Logger.hpp" -#include "cru/ui/Control.hpp" #include "cru/ui/DebugFlags.hpp" +#include "cru/ui/controls/Control.hpp" #include <algorithm> #include <functional> #include <iterator> #include <optional> -namespace cru::ui { +namespace cru::ui::helper { int ShortcutHub::RegisterShortcut(Shortcut shortcut) { const int id = current_id_++; map_[shortcut.key_bind].push_back({id, std::move(shortcut.name), @@ -62,7 +62,7 @@ const std::vector<ShortcutInfo>& ShortcutHub::GetShortcutByKeyBind( return empty_list_; } -void ShortcutHub::Install(Control* control) { +void ShortcutHub::Install(controls::Control* control) { if (!event_guard_.IsEmpty()) { log::Error(u"Shortcut hub is already installed. Failed to install."); return; @@ -117,4 +117,4 @@ void ShortcutHub::OnKeyDown(event::KeyEventArgs& event) { } } } -} // namespace cru::ui +} // namespace cru::ui::helper diff --git a/src/ui/host/RoutedEventDispatch.hpp b/src/ui/host/RoutedEventDispatch.hpp index de94a598..52507fc7 100644 --- a/src/ui/host/RoutedEventDispatch.hpp +++ b/src/ui/host/RoutedEventDispatch.hpp @@ -1,8 +1,7 @@ #pragma once -#include "cru/ui/Control.hpp" - #include "cru/common/Logger.hpp" #include "cru/ui/DebugFlags.hpp" +#include "cru/ui/controls/Control.hpp" #include <vector> @@ -21,10 +20,11 @@ namespace cru::ui { // "original_sender", which is unchanged. And "args" will be perfectly forwarded // as the rest arguments. template <typename EventArgs, typename... Args> -void DispatchEvent(const std::u16string_view& event_name, - Control* const original_sender, - event::RoutedEvent<EventArgs>* (Control::*event_ptr)(), - Control* const last_receiver, Args&&... args) { +void DispatchEvent( + const std::u16string_view& event_name, + controls::Control* const original_sender, + event::RoutedEvent<EventArgs>* (controls::Control::*event_ptr)(), + controls::Control* const last_receiver, Args&&... args) { CRU_UNUSED(event_name) if (original_sender == last_receiver) { @@ -36,7 +36,7 @@ void DispatchEvent(const std::u16string_view& event_name, return; } - std::vector<Control*> receive_list; + std::vector<controls::Control*> receive_list; auto parent = original_sender; while (parent != last_receiver) { diff --git a/src/ui/host/WindowHost.cpp b/src/ui/host/WindowHost.cpp index e04fdf31..1702c4ed 100644 --- a/src/ui/host/WindowHost.cpp +++ b/src/ui/host/WindowHost.cpp @@ -8,7 +8,7 @@ #include "cru/platform/gui/UiApplication.hpp" #include "cru/platform/gui/Window.hpp" #include "cru/ui/DebugFlags.hpp" -#include "cru/ui/Window.hpp" +#include "cru/ui/controls/Window.hpp" #include "cru/ui/host/LayoutPaintCycler.hpp" #include "cru/ui/render/MeasureRequirement.hpp" #include "cru/ui/render/RenderObject.hpp" @@ -43,7 +43,7 @@ CRU_DEFINE_EVENT_NAME(KeyUp) } // namespace event_names namespace { -bool IsAncestor(Control* control, Control* ancestor) { +bool IsAncestor(controls::Control* control, controls::Control* ancestor) { while (control != nullptr) { if (control == ancestor) return true; control = control->GetParent(); @@ -52,8 +52,8 @@ bool IsAncestor(Control* control, Control* ancestor) { } // Ancestor at last. -std::vector<Control*> GetAncestorList(Control* control) { - std::vector<Control*> l; +std::vector<controls::Control*> GetAncestorList(controls::Control* control) { + std::vector<controls::Control*> l; while (control != nullptr) { l.push_back(control); control = control->GetParent(); @@ -61,7 +61,8 @@ std::vector<Control*> GetAncestorList(Control* control) { return l; } -Control* FindLowestCommonAncestor(Control* left, Control* right) { +controls::Control* FindLowestCommonAncestor(controls::Control* left, + controls::Control* right) { if (left == nullptr || right == nullptr) return nullptr; auto&& left_list = GetAncestorList(left); @@ -102,13 +103,13 @@ inline void BindNativeEvent( } } // namespace -WindowHost::WindowHost(Control* root_control) +WindowHost::WindowHost(controls::Control* root_control) : root_control_(root_control), focus_control_(root_control) { const auto ui_application = IUiApplication::GetInstance(); auto native_window = ui_application->CreateWindow(nullptr); native_window_ = native_window; - root_control_->TraverseDescendants([this](Control* control) { + root_control_->TraverseDescendants([this](controls::Control* control) { control->window_host_ = this; control->OnAttachToHost(this); }); @@ -195,9 +196,9 @@ void WindowHost::Repaint() { painter->EndDraw(); } -Control* WindowHost::GetFocusControl() { return focus_control_; } +controls::Control* WindowHost::GetFocusControl() { return focus_control_; } -void WindowHost::SetFocusControl(Control* control) { +void WindowHost::SetFocusControl(controls::Control* control) { if (focus_control_ == control) return; if (control == nullptr) control = root_control_; @@ -206,13 +207,13 @@ void WindowHost::SetFocusControl(Control* control) { focus_control_ = control; DispatchEvent(event_names::LoseFocus, old_focus_control, - &Control::LoseFocusEvent, nullptr, false); + &controls::Control::LoseFocusEvent, nullptr, false); - DispatchEvent(event_names::GainFocus, control, &Control::GainFocusEvent, - nullptr, false); + DispatchEvent(event_names::GainFocus, control, + &controls::Control::GainFocusEvent, nullptr, false); } -bool WindowHost::CaptureMouseFor(Control* control) { +bool WindowHost::CaptureMouseFor(controls::Control* control) { if (!native_window_) return false; if (control == mouse_captured_control_) return true; @@ -240,7 +241,7 @@ bool WindowHost::CaptureMouseFor(Control* control) { return true; } -Control* WindowHost::GetMouseCaptureControl() { +controls::Control* WindowHost::GetMouseCaptureControl() { return mouse_captured_control_; } @@ -275,9 +276,9 @@ void WindowHost::OnNativeFocus(INativeWindow* window, focus == platform::gui::FocusChangeType::Gain ? DispatchEvent(event_names::GainFocus, focus_control_, - &Control::GainFocusEvent, nullptr, true) + &controls::Control::GainFocusEvent, nullptr, true) : DispatchEvent(event_names::LoseFocus, focus_control_, - &Control::LoseFocusEvent, nullptr, true); + &controls::Control::LoseFocusEvent, nullptr, true); } void WindowHost::OnNativeMouseEnterLeave( @@ -286,7 +287,7 @@ void WindowHost::OnNativeMouseEnterLeave( if (type == platform::gui::MouseEnterLeaveType::Leave) { DispatchEvent(event_names::MouseLeave, mouse_hover_control_, - &Control::MouseLeaveEvent, nullptr); + &controls::Control::MouseLeaveEvent, nullptr); mouse_hover_control_ = nullptr; } } @@ -306,13 +307,14 @@ void WindowHost::OnNativeMouseMove(INativeWindow* window, const Point& point) { mouse_captured_control_); bool a = IsAncestor(o, n); if (a) { - DispatchEvent(event_names::MouseLeave, o, &Control::MouseLeaveEvent, n); + DispatchEvent(event_names::MouseLeave, o, + &controls::Control::MouseLeaveEvent, n); } else { - DispatchEvent(event_names::MouseEnter, n, &Control::MouseEnterEvent, o, - point); + DispatchEvent(event_names::MouseEnter, n, + &controls::Control::MouseEnterEvent, o, point); } DispatchEvent(event_names::MouseMove, mouse_captured_control_, - &Control::MouseMoveEvent, nullptr, point); + &controls::Control::MouseMoveEvent, nullptr, point); UpdateCursor(); return; } @@ -320,7 +322,7 @@ void WindowHost::OnNativeMouseMove(INativeWindow* window, const Point& point) { DispatchMouseHoverControlChangeEvent( old_mouse_hover_control, new_mouse_hover_control, point, false, false); DispatchEvent(event_names::MouseMove, new_mouse_hover_control, - &Control::MouseMoveEvent, nullptr, point); + &controls::Control::MouseMoveEvent, nullptr, point); UpdateCursor(); } @@ -329,10 +331,11 @@ void WindowHost::OnNativeMouseDown( const platform::gui::NativeMouseButtonEventArgs& args) { CRU_UNUSED(window) - Control* control = + controls::Control* control = mouse_captured_control_ ? mouse_captured_control_ : HitTest(args.point); - DispatchEvent(event_names::MouseDown, control, &Control::MouseDownEvent, - nullptr, args.point, args.button, args.modifier); + DispatchEvent(event_names::MouseDown, control, + &controls::Control::MouseDownEvent, nullptr, args.point, + args.button, args.modifier); } void WindowHost::OnNativeMouseUp( @@ -340,44 +343,44 @@ void WindowHost::OnNativeMouseUp( const platform::gui::NativeMouseButtonEventArgs& args) { CRU_UNUSED(window) - Control* control = + controls::Control* control = mouse_captured_control_ ? mouse_captured_control_ : HitTest(args.point); - DispatchEvent(event_names::MouseUp, control, &Control::MouseUpEvent, nullptr, - args.point, args.button, args.modifier); + DispatchEvent(event_names::MouseUp, control, &controls::Control::MouseUpEvent, + nullptr, args.point, args.button, args.modifier); } void WindowHost::OnNativeKeyDown( INativeWindow* window, const platform::gui::NativeKeyEventArgs& args) { CRU_UNUSED(window) - DispatchEvent(event_names::KeyDown, focus_control_, &Control::KeyDownEvent, - nullptr, args.key, args.modifier); + DispatchEvent(event_names::KeyDown, focus_control_, + &controls::Control::KeyDownEvent, nullptr, args.key, + args.modifier); } void WindowHost::OnNativeKeyUp(INativeWindow* window, const platform::gui::NativeKeyEventArgs& args) { CRU_UNUSED(window) - DispatchEvent(event_names::KeyUp, focus_control_, &Control::KeyUpEvent, - nullptr, args.key, args.modifier); + DispatchEvent(event_names::KeyUp, focus_control_, + &controls::Control::KeyUpEvent, nullptr, args.key, + args.modifier); } -void WindowHost::DispatchMouseHoverControlChangeEvent(Control* old_control, - Control* new_control, - const Point& point, - bool no_leave, - bool no_enter) { +void WindowHost::DispatchMouseHoverControlChangeEvent( + controls::Control* old_control, controls::Control* new_control, + const Point& point, bool no_leave, bool no_enter) { if (new_control != old_control) // if the mouse-hover-on control changed { const auto lowest_common_ancestor = FindLowestCommonAncestor(old_control, new_control); if (!no_leave && old_control != nullptr) DispatchEvent(event_names::MouseLeave, old_control, - &Control::MouseLeaveEvent, + &controls::Control::MouseLeaveEvent, lowest_common_ancestor); // dispatch mouse leave event. if (!no_enter && new_control != nullptr) { DispatchEvent(event_names::MouseEnter, new_control, - &Control::MouseEnterEvent, lowest_common_ancestor, + &controls::Control::MouseEnterEvent, lowest_common_ancestor, point); // dispatch mouse enter event. } } @@ -391,7 +394,7 @@ void WindowHost::UpdateCursor() { } } -Control* WindowHost::HitTest(const Point& point) { +controls::Control* WindowHost::HitTest(const Point& point) { const auto render_object = root_render_object_->HitTest(point); if (render_object) { const auto control = render_object->GetAttachedControl(); diff --git a/src/win/gui/UiApplication.cpp b/src/win/gui/UiApplication.cpp index 5041a6c0..f4541dd0 100644 --- a/src/win/gui/UiApplication.cpp +++ b/src/win/gui/UiApplication.cpp @@ -36,8 +36,8 @@ WinUiApplication::WinUiApplication() { log::Logger::GetInstance()->AddSource( std::make_unique<::cru::platform::win::WinStdOutLoggerSource>()); - graph_factory_ = - std::make_unique<cru::platform::graphics::win::direct::DirectGraphFactory>(); + graph_factory_ = std::make_unique< + cru::platform::graphics::win::direct::DirectGraphFactory>(); god_window_ = std::make_unique<GodWindow>(this); timer_manager_ = std::make_unique<TimerManager>(god_window_.get()); @@ -99,13 +99,17 @@ std::vector<INativeWindow*> WinUiApplication::GetAllWindow() { return result; } -INativeWindow* WinUiApplication::CreateWindow(INativeWindow* parent) { +INativeWindow* WinUiApplication::CreateWindow(INativeWindow* parent, + CreateWindowFlag flag) { WinNativeWindow* p = nullptr; if (parent != nullptr) { p = CheckPlatform<WinNativeWindow>(parent, GetPlatformId()); } return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(), - WS_OVERLAPPEDWINDOW, p); + flag & CreateWindowFlags::NoCaptionAndBorder + ? WS_POPUP + : WS_OVERLAPPEDWINDOW, + p); } cru::platform::graphics::IGraphFactory* WinUiApplication::GetGraphFactory() { |