aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/controls
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-11-08 17:45:41 +0800
committercrupest <crupest@outlook.com>2020-11-08 17:45:41 +0800
commit2188845a7acffa653015a1000139ec0a9a3984bc (patch)
tree7e8ed6eca5868a0943af6fcad6467115f369987c /include/cru/ui/controls
parent93265251d56c91b05f160423077ce95339786f87 (diff)
downloadcru-2188845a7acffa653015a1000139ec0a9a3984bc.tar.gz
cru-2188845a7acffa653015a1000139ec0a9a3984bc.tar.bz2
cru-2188845a7acffa653015a1000139ec0a9a3984bc.zip
...
Diffstat (limited to 'include/cru/ui/controls')
-rw-r--r--include/cru/ui/controls/Base.hpp10
-rw-r--r--include/cru/ui/controls/Button.hpp7
-rw-r--r--include/cru/ui/controls/Container.hpp2
-rw-r--r--include/cru/ui/controls/ContentControl.hpp26
-rw-r--r--include/cru/ui/controls/Control.hpp151
-rw-r--r--include/cru/ui/controls/FlexLayout.hpp2
-rw-r--r--include/cru/ui/controls/LayoutControl.hpp19
-rw-r--r--include/cru/ui/controls/NoChildControl.hpp20
-rw-r--r--include/cru/ui/controls/StackLayout.hpp2
-rw-r--r--include/cru/ui/controls/TextBlock.hpp2
-rw-r--r--include/cru/ui/controls/TextBox.hpp3
-rw-r--r--include/cru/ui/controls/Window.hpp36
12 files changed, 265 insertions, 15 deletions
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/controls/ContentControl.hpp b/include/cru/ui/controls/ContentControl.hpp
new file mode 100644
index 00000000..47720a87
--- /dev/null
+++ b/include/cru/ui/controls/ContentControl.hpp
@@ -0,0 +1,26 @@
+#pragma once
+#include "Control.hpp"
+
+namespace cru::ui::controls {
+class ContentControl : public Control {
+ protected:
+ ContentControl() = default;
+
+ public:
+ ContentControl(const ContentControl& other) = delete;
+ ContentControl(ContentControl&& other) = delete;
+ ContentControl& operator=(const ContentControl& other) = delete;
+ ContentControl& operator=(ContentControl&& other) = delete;
+ ~ContentControl() override = default;
+
+ Control* GetChild() const;
+ void SetChild(Control* child);
+
+ protected:
+ virtual void OnChildChanged(Control* old_child, Control* new_child);
+
+ private:
+ using Control::AddChild;
+ using Control::RemoveChild;
+};
+} // namespace cru::ui::controls
diff --git a/include/cru/ui/controls/Control.hpp b/include/cru/ui/controls/Control.hpp
new file mode 100644
index 00000000..96aad2bd
--- /dev/null
+++ b/include/cru/ui/controls/Control.hpp
@@ -0,0 +1,151 @@
+#pragma once
+#include "Base.hpp"
+
+#include "../events/UiEvent.hpp"
+#include "../render/Base.hpp"
+#include "cru/common/Event.hpp"
+
+#include <string_view>
+
+namespace cru::ui::controls {
+class Control : public Object {
+ friend host::WindowHost;
+
+ protected:
+ Control();
+
+ public:
+ Control(const Control& other) = delete;
+ Control(Control&& other) = delete;
+ Control& operator=(const Control& other) = delete;
+ Control& operator=(Control&& other) = delete;
+ ~Control() override;
+
+ public:
+ virtual std::u16string_view GetControlType() const = 0;
+
+ //*************** region: tree ***************
+ public:
+ host::WindowHost* GetWindowHost() const;
+
+ Control* GetParent() const { return parent_; }
+
+ const std::vector<Control*>& GetChildren() const { return children_; }
+
+ // Traverse the tree rooted the control including itself.
+ void TraverseDescendants(const std::function<void(Control*)>& predicate);
+
+ public:
+ virtual render::RenderObject* GetRenderObject() const = 0;
+
+ //*************** region: focus ***************
+ public:
+ bool HasFocus();
+
+ void SetFocus();
+
+ //*************** region: mouse ***************
+ public:
+ bool IsMouseOver() const { return is_mouse_over_; }
+
+ bool CaptureMouse();
+
+ bool ReleaseMouse();
+
+ bool IsMouseCaptured();
+
+ //*************** region: cursor ***************
+ // Cursor is inherited from parent recursively if not set.
+ public:
+ // null for not set
+ std::shared_ptr<platform::gui::ICursor> GetCursor();
+
+ // will not return nullptr
+ std::shared_ptr<platform::gui::ICursor> GetInheritedCursor();
+
+ // null to unset
+ void SetCursor(std::shared_ptr<platform::gui::ICursor> cursor);
+
+ //*************** region: events ***************
+ public:
+ // Raised when mouse enter 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 enter event. You
+ // can use `IsMouseCaptured` to get more info.
+ event::RoutedEvent<event::MouseEventArgs>* MouseEnterEvent() {
+ return &mouse_enter_event_;
+ }
+ // 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.
+ event::RoutedEvent<event::MouseEventArgs>* MouseLeaveEvent() {
+ return &mouse_leave_event_;
+ }
+ // Raised when mouse is move in the control.
+ event::RoutedEvent<event::MouseEventArgs>* MouseMoveEvent() {
+ return &mouse_move_event_;
+ }
+ // Raised when a mouse button is pressed in the control.
+ event::RoutedEvent<event::MouseButtonEventArgs>* MouseDownEvent() {
+ return &mouse_down_event_;
+ }
+ // Raised when a mouse button is released in the control.
+ event::RoutedEvent<event::MouseButtonEventArgs>* MouseUpEvent() {
+ return &mouse_up_event_;
+ }
+ event::RoutedEvent<event::MouseWheelEventArgs>* MouseWheelEvent() {
+ return &mouse_wheel_event_;
+ }
+ event::RoutedEvent<event::KeyEventArgs>* KeyDownEvent() {
+ return &key_down_event_;
+ }
+ event::RoutedEvent<event::KeyEventArgs>* KeyUpEvent() {
+ return &key_up_event_;
+ }
+ event::RoutedEvent<event::FocusChangeEventArgs>* GainFocusEvent() {
+ return &gain_focus_event_;
+ }
+ event::RoutedEvent<event::FocusChangeEventArgs>* LoseFocusEvent() {
+ return &lose_focus_event_;
+ }
+
+ private:
+ event::RoutedEvent<event::MouseEventArgs> mouse_enter_event_;
+ event::RoutedEvent<event::MouseEventArgs> mouse_leave_event_;
+ event::RoutedEvent<event::MouseEventArgs> mouse_move_event_;
+ event::RoutedEvent<event::MouseButtonEventArgs> mouse_down_event_;
+ event::RoutedEvent<event::MouseButtonEventArgs> mouse_up_event_;
+ event::RoutedEvent<event::MouseWheelEventArgs> mouse_wheel_event_;
+
+ event::RoutedEvent<event::KeyEventArgs> key_down_event_;
+ event::RoutedEvent<event::KeyEventArgs> key_up_event_;
+
+ event::RoutedEvent<event::FocusChangeEventArgs> gain_focus_event_;
+ event::RoutedEvent<event::FocusChangeEventArgs> lose_focus_event_;
+
+ //*************** region: tree ***************
+ protected:
+ void AddChild(Control* control, Index position);
+ void RemoveChild(Index position);
+ virtual void OnAddChild(Control* child, Index position);
+ virtual void OnRemoveChild(Control* child, Index position);
+ virtual void OnParentChanged(Control* old_parent, Control* new_parent);
+ virtual void OnAttachToHost(host::WindowHost* host);
+ virtual void OnDetachFromHost(host::WindowHost* host);
+
+ protected:
+ virtual void OnMouseHoverChange(bool newHover) { CRU_UNUSED(newHover) }
+
+ private:
+ Control* parent_ = nullptr;
+ std::vector<Control*> children_;
+
+ host::WindowHost* window_host_ = nullptr;
+
+ private:
+ bool is_mouse_over_ = false;
+
+ std::shared_ptr<platform::gui::ICursor> cursor_ = nullptr;
+};
+} // 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/controls/LayoutControl.hpp b/include/cru/ui/controls/LayoutControl.hpp
new file mode 100644
index 00000000..cbdb8aa2
--- /dev/null
+++ b/include/cru/ui/controls/LayoutControl.hpp
@@ -0,0 +1,19 @@
+#pragma once
+#include "Control.hpp"
+
+namespace cru::ui::controls {
+class LayoutControl : public Control {
+ protected:
+ LayoutControl() = default;
+
+ public:
+ LayoutControl(const LayoutControl& other) = delete;
+ LayoutControl(LayoutControl&& other) = delete;
+ LayoutControl& operator=(const LayoutControl& other) = delete;
+ LayoutControl& operator=(LayoutControl&& other) = delete;
+ ~LayoutControl() override = default;
+
+ using Control::AddChild;
+ using Control::RemoveChild;
+};
+} // namespace cru::ui
diff --git a/include/cru/ui/controls/NoChildControl.hpp b/include/cru/ui/controls/NoChildControl.hpp
new file mode 100644
index 00000000..562137f1
--- /dev/null
+++ b/include/cru/ui/controls/NoChildControl.hpp
@@ -0,0 +1,20 @@
+#pragma once
+#include "Control.hpp"
+
+namespace cru::ui::controls {
+class NoChildControl : public Control {
+ protected:
+ NoChildControl() = default;
+
+ public:
+ NoChildControl(const NoChildControl& other) = delete;
+ NoChildControl(NoChildControl&& other) = delete;
+ NoChildControl& operator=(const NoChildControl& other) = delete;
+ NoChildControl& operator=(NoChildControl&& other) = delete;
+ ~NoChildControl() override = default;
+
+ private:
+ using Control::AddChild;
+ using Control::RemoveChild;
+};
+} // namespace cru::ui
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/controls/Window.hpp b/include/cru/ui/controls/Window.hpp
new file mode 100644
index 00000000..616e2ee7
--- /dev/null
+++ b/include/cru/ui/controls/Window.hpp
@@ -0,0 +1,36 @@
+#pragma once
+#include "LayoutControl.hpp"
+
+namespace cru::ui::controls {
+class Window final : public LayoutControl {
+ public:
+ static constexpr std::u16string_view control_type = u"Window";
+
+ public:
+ static Window* CreateOverlapped();
+
+ private:
+ Window();
+
+ public:
+ Window(const Window& other) = delete;
+ Window(Window&& other) = delete;
+ Window& operator=(const Window& other) = delete;
+ Window& operator=(Window&& other) = delete;
+ ~Window() override;
+
+ public:
+ std::u16string_view GetControlType() const final;
+
+ render::RenderObject* GetRenderObject() const override;
+
+ protected:
+ void OnAddChild(Control* child, Index position) override;
+ void OnRemoveChild(Control* child, Index position) override;
+
+ private:
+ std::unique_ptr<host::WindowHost> window_host_;
+
+ std::unique_ptr<render::StackLayoutRenderObject> render_object_;
+};
+} // namespace cru::ui