aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/graph/geometry.hpp2
-rw-r--r--include/cru/platform/native/ui_application.hpp6
-rw-r--r--include/cru/ui/base.hpp5
-rw-r--r--include/cru/ui/control.hpp21
-rw-r--r--include/cru/ui/controls/button.hpp17
-rw-r--r--include/cru/ui/controls/container.hpp4
-rw-r--r--include/cru/ui/controls/flex_layout.hpp4
-rw-r--r--include/cru/ui/controls/text_block.hpp12
-rw-r--r--include/cru/ui/render/border_render_object.hpp30
-rw-r--r--include/cru/ui/render/flex_layout_render_object.hpp2
-rw-r--r--include/cru/ui/render/render_object.hpp7
-rw-r--r--include/cru/ui/render/text_render_object.hpp38
-rw-r--r--include/cru/ui/render/window_render_object.hpp2
-rw-r--r--include/cru/ui/ui_event.hpp (renamed from include/cru/ui/event/ui_event.hpp)13
-rw-r--r--include/cru/ui/ui_manager.hpp17
-rw-r--r--include/cru/ui/window.hpp16
-rw-r--r--include/cru/win/native/ui_application.hpp3
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/main.cpp14
-rw-r--r--src/platform/native/CMakeLists.txt8
-rw-r--r--src/platform/native/ui_application.cpp5
-rw-r--r--src/ui/CMakeLists.txt8
-rw-r--r--src/ui/control.cpp19
-rw-r--r--src/ui/controls/button.cpp22
-rw-r--r--src/ui/controls/container.cpp4
-rw-r--r--src/ui/controls/text_block.cpp14
-rw-r--r--src/ui/helper.cpp15
-rw-r--r--src/ui/helper.hpp17
-rw-r--r--src/ui/render/border_render_object.cpp41
-rw-r--r--src/ui/render/flex_layout_render_object.cpp4
-rw-r--r--src/ui/render/render_object.cpp16
-rw-r--r--src/ui/render/text_render_object.cpp29
-rw-r--r--src/ui/render/window_render_object.cpp32
-rw-r--r--src/ui/routed_event_dispatch.hpp26
-rw-r--r--src/ui/ui_manager.cpp48
-rw-r--r--src/ui/window.cpp33
-rw-r--r--src/win/exception.cpp4
-rw-r--r--src/win/native/ui_application.cpp11
-rw-r--r--src/win/native/window.cpp3
-rw-r--r--src/win/native/window_render_target.cpp1
40 files changed, 321 insertions, 254 deletions
diff --git a/include/cru/platform/graph/geometry.hpp b/include/cru/platform/graph/geometry.hpp
index 689b2ab9..a49453dd 100644
--- a/include/cru/platform/graph/geometry.hpp
+++ b/include/cru/platform/graph/geometry.hpp
@@ -10,7 +10,7 @@ struct IGeometry : virtual IGraphResource {
// After called Build, calling every method will throw a
-class IGeometryBuilder : virtual IGraphResource {
+struct IGeometryBuilder : virtual IGraphResource {
virtual void BeginFigure(const Point& point) = 0;
virtual void LineTo(const Point& point) = 0;
virtual void QuadraticBezierTo(const Point& control_point,
diff --git a/include/cru/platform/native/ui_application.hpp b/include/cru/platform/native/ui_application.hpp
index c1f10d15..b69b1f52 100644
--- a/include/cru/platform/native/ui_application.hpp
+++ b/include/cru/platform/native/ui_application.hpp
@@ -16,6 +16,12 @@ struct ICursorManager;
// The entry point of a ui application.
struct IUiApplication : public virtual INativeResource {
public:
+ static IUiApplication* GetInstance() { return instance; }
+
+ protected:
+ static IUiApplication* instance;
+
+ public:
// Block current thread and run the message loop. Return the exit code when
// message loop gets a quit message (possibly posted by method RequestQuit).
virtual int Run() = 0;
diff --git a/include/cru/ui/base.hpp b/include/cru/ui/base.hpp
index a5e656ff..581e6f8f 100644
--- a/include/cru/ui/base.hpp
+++ b/include/cru/ui/base.hpp
@@ -1,5 +1,6 @@
#pragma once
-#include "cru/platform/graphic_base.hpp"
+#include "cru/common/base.hpp"
+#include "cru/platform/graph_base.hpp"
#include "cru/platform/matrix.hpp"
#include "cru/platform/native/basic_types.hpp"
@@ -17,7 +18,7 @@ using cru::platform::native::MouseButton;
namespace colors {
using cru::platform::colors::black;
-using cru::platform::colors::white;
using cru::platform::colors::skyblue;
+using cru::platform::colors::white;
} // namespace colors
} // namespace cru::ui
diff --git a/include/cru/ui/control.hpp b/include/cru/ui/control.hpp
index cf4f9053..1fe49261 100644
--- a/include/cru/ui/control.hpp
+++ b/include/cru/ui/control.hpp
@@ -1,15 +1,18 @@
#pragma once
#include "base.hpp"
-#include "cru/common/base.hpp"
-#include "cru/platform/native/basic_types.hpp"
-#include "cru/platform/native/cursor.hpp"
-#include "event/ui_event.hpp"
+#include "cru/common/event.hpp"
+#include "ui_event.hpp"
+#include <functional>
#include <memory>
#include <string_view>
#include <vector>
+namespace cru::platform::native {
+struct ICursor;
+}
+
namespace cru::ui {
class Window;
namespace render {
@@ -30,7 +33,7 @@ class Control : public Object {
~Control() override = default;
public:
- virtual std::wstring_view GetControlType() const = 0;
+ virtual std::string_view GetControlType() const = 0;
//*************** region: tree ***************
public:
@@ -74,13 +77,13 @@ class Control : public Object {
// Cursor is inherited from parent recursively if not set.
public:
// null for not set
- std::shared_ptr<platform::native::Cursor> GetCursor();
+ std::shared_ptr<platform::native::ICursor> GetCursor();
// will not return nullptr
- std::shared_ptr<platform::native::Cursor> GetInheritedCursor();
+ std::shared_ptr<platform::native::ICursor> GetInheritedCursor();
// null to unset
- void SetCursor(std::shared_ptr<platform::native::Cursor> cursor);
+ void SetCursor(std::shared_ptr<platform::native::ICursor> cursor);
//*************** region: events ***************
public:
@@ -163,6 +166,6 @@ class Control : public Object {
bool right;
} click_map_;
- std::shared_ptr<platform::native::Cursor> cursor_ = nullptr;
+ std::shared_ptr<platform::native::ICursor> cursor_ = nullptr;
};
} // namespace cru::ui
diff --git a/include/cru/ui/controls/button.hpp b/include/cru/ui/controls/button.hpp
index d4a03e1d..60b1243f 100644
--- a/include/cru/ui/controls/button.hpp
+++ b/include/cru/ui/controls/button.hpp
@@ -3,24 +3,19 @@
#include "../click_detector.hpp"
#include "../render/border_render_object.hpp"
-#include "cru/platform/graph/brush.hpp"
#include "cru/platform/native/basic_types.hpp"
#include <memory>
-namespace cru::ui::render {
-class BorderRenderObject;
-}
-
namespace cru::ui::controls {
using render::CornerRadius;
struct ButtonStateStyle {
- std::shared_ptr<platform::graph::Brush> border_brush;
+ std::shared_ptr<platform::graph::IBrush> border_brush;
Thickness border_thickness;
CornerRadius border_radius;
- std::shared_ptr<platform::graph::Brush> foreground_brush;
- std::shared_ptr<platform::graph::Brush> background_brush;
+ std::shared_ptr<platform::graph::IBrush> foreground_brush;
+ std::shared_ptr<platform::graph::IBrush> background_brush;
};
struct ButtonStyle {
@@ -47,7 +42,7 @@ enum class ButtonState {
class Button : public ContentControl {
public:
- static constexpr auto control_type = L"Button";
+ static constexpr std::string_view control_type = "Button";
static Button* Create() { return new Button(); }
@@ -61,7 +56,7 @@ class Button : public ContentControl {
Button& operator=(Button&& other) = delete;
~Button() override = default;
- std::wstring_view GetControlType() const override final {
+ std::string_view GetControlType() const final {
return control_type;
}
@@ -96,7 +91,7 @@ class Button : public ContentControl {
}
private:
- std::shared_ptr<render::BorderRenderObject> render_object_{};
+ std::unique_ptr<render::BorderRenderObject> render_object_{};
ButtonState state_ = ButtonState::Normal;
diff --git a/include/cru/ui/controls/container.hpp b/include/cru/ui/controls/container.hpp
index 3c877067..efc099f7 100644
--- a/include/cru/ui/controls/container.hpp
+++ b/include/cru/ui/controls/container.hpp
@@ -7,7 +7,7 @@ class BorderRenderObject;
namespace cru::ui::controls {
class Container : public ContentControl {
- static constexpr auto control_type = L"Container";
+ static constexpr std::string_view control_type = "Container";
protected:
Container();
@@ -19,7 +19,7 @@ class Container : public ContentControl {
~Container() override;
public:
- std::wstring_view GetControlType() const override final {
+ std::string_view GetControlType() const final {
return control_type;
}
diff --git a/include/cru/ui/controls/flex_layout.hpp b/include/cru/ui/controls/flex_layout.hpp
index d8d92d08..ff8ec53b 100644
--- a/include/cru/ui/controls/flex_layout.hpp
+++ b/include/cru/ui/controls/flex_layout.hpp
@@ -15,7 +15,7 @@ using render::FlexMainAlignment;
class FlexLayout : public LayoutControl {
public:
- static constexpr auto control_type = L"FlexLayout";
+ static constexpr std::string_view control_type = "FlexLayout";
static FlexLayout* Create() { return new FlexLayout(); }
@@ -29,7 +29,7 @@ class FlexLayout : public LayoutControl {
FlexLayout& operator=(FlexLayout&& other) = delete;
~FlexLayout() override = default;
- std::wstring_view GetControlType() const override final {
+ std::string_view GetControlType() const final {
return control_type;
}
diff --git a/include/cru/ui/controls/text_block.hpp b/include/cru/ui/controls/text_block.hpp
index 45cd12b9..708b62f1 100644
--- a/include/cru/ui/controls/text_block.hpp
+++ b/include/cru/ui/controls/text_block.hpp
@@ -10,7 +10,7 @@ class TextRenderObject;
namespace cru::ui::controls {
class TextBlock : public NoChildControl {
public:
- static constexpr auto control_type = L"TextBlock";
+ static constexpr std::string_view control_type = "TextBlock";
static TextBlock* Create() { return new TextBlock(); }
@@ -22,18 +22,18 @@ class TextBlock : public NoChildControl {
TextBlock(TextBlock&& other) = delete;
TextBlock& operator=(const TextBlock& other) = delete;
TextBlock& operator=(TextBlock&& other) = delete;
- ~TextBlock() override = default;
+ ~TextBlock() override;
- std::wstring_view GetControlType() const override final {
+ std::string_view GetControlType() const final {
return control_type;
}
render::RenderObject* GetRenderObject() const override;
- std::wstring GetText() const;
- void SetText(std::wstring text);
+ std::string GetText() const;
+ void SetText(std::string text);
private:
- std::shared_ptr<render::TextRenderObject> render_object_;
+ std::unique_ptr<render::TextRenderObject> render_object_;
};
} // namespace cru::ui::controls
diff --git a/include/cru/ui/render/border_render_object.hpp b/include/cru/ui/render/border_render_object.hpp
index 5520ab2e..726510a8 100644
--- a/include/cru/ui/render/border_render_object.hpp
+++ b/include/cru/ui/render/border_render_object.hpp
@@ -1,13 +1,11 @@
#pragma once
-#include "cru/platform/graph/brush.hpp"
-#include "cru/ui/base.hpp"
#include "render_object.hpp"
#include <memory>
namespace cru::platform::graph {
-class Brush;
-class IGeometry;
+struct IBrush;
+struct IGeometry;
} // namespace cru::platform::graph
namespace cru::ui::render {
@@ -55,19 +53,19 @@ class BorderRenderObject : public RenderObject {
bool IsBorderEnabled() const { return is_border_enabled_; }
void SetBorderEnabled(bool enabled) { is_border_enabled_ = enabled; }
- std::shared_ptr<platform::graph::Brush> GetBorderBrush() {
+ std::shared_ptr<platform::graph::IBrush> GetBorderBrush() {
return border_brush_;
}
- void SetBorderBrush(std::shared_ptr<platform::graph::Brush> brush) {
+ void SetBorderBrush(std::shared_ptr<platform::graph::IBrush> brush) {
if (brush == border_brush_) return;
border_brush_ = std::move(brush);
InvalidatePaint();
}
- platform::Thickness GetBorderThickness() { return border_thickness_; }
+ Thickness GetBorderThickness() { return border_thickness_; }
- void SetBorderThickness(const platform::Thickness thickness) {
+ void SetBorderThickness(const Thickness thickness) {
if (thickness == border_thickness_) return;
border_thickness_ = thickness;
InvalidateLayout();
@@ -81,27 +79,27 @@ class BorderRenderObject : public RenderObject {
RecreateGeometry();
}
- std::shared_ptr<platform::graph::Brush> GetForegroundBrush() {
+ std::shared_ptr<platform::graph::IBrush> GetForegroundBrush() {
return foreground_brush_;
}
- void SetForegroundBrush(std::shared_ptr<platform::graph::Brush> brush) {
+ void SetForegroundBrush(std::shared_ptr<platform::graph::IBrush> brush) {
if (brush == foreground_brush_) return;
foreground_brush_ = std::move(brush);
InvalidatePaint();
}
- std::shared_ptr<platform::graph::Brush> GetBackgroundBrush() {
+ std::shared_ptr<platform::graph::IBrush> GetBackgroundBrush() {
return background_brush_;
}
- void SetBackgroundBrush(std::shared_ptr<platform::graph::Brush> brush) {
+ void SetBackgroundBrush(std::shared_ptr<platform::graph::IBrush> brush) {
if (brush == background_brush_) return;
background_brush_ = std::move(brush);
InvalidatePaint();
}
- void Draw(platform::graph::Painter* painter) override;
+ void Draw(platform::graph::IPainter* painter) override;
RenderObject* HitTest(const Point& point) override;
@@ -123,12 +121,12 @@ class BorderRenderObject : public RenderObject {
private:
bool is_border_enabled_ = false;
- std::shared_ptr<platform::graph::Brush> border_brush_;
+ std::shared_ptr<platform::graph::IBrush> border_brush_;
platform::Thickness border_thickness_;
CornerRadius border_radius_;
- std::shared_ptr<platform::graph::Brush> foreground_brush_;
- std::shared_ptr<platform::graph::Brush> background_brush_;
+ std::shared_ptr<platform::graph::IBrush> foreground_brush_;
+ std::shared_ptr<platform::graph::IBrush> background_brush_;
// The ring. Used for painting.
std::unique_ptr<platform::graph::IGeometry> geometry_;
diff --git a/include/cru/ui/render/flex_layout_render_object.hpp b/include/cru/ui/render/flex_layout_render_object.hpp
index 7b71b96e..5a8d09ba 100644
--- a/include/cru/ui/render/flex_layout_render_object.hpp
+++ b/include/cru/ui/render/flex_layout_render_object.hpp
@@ -78,7 +78,7 @@ class FlexLayoutRenderObject : public RenderObject {
InvalidateLayout();
}
- void Draw(platform::graph::Painter* painter) override;
+ void Draw(platform::graph::IPainter* painter) override;
RenderObject* HitTest(const Point& point) override;
diff --git a/include/cru/ui/render/render_object.hpp b/include/cru/ui/render/render_object.hpp
index befaa3ec..55b7f2da 100644
--- a/include/cru/ui/render/render_object.hpp
+++ b/include/cru/ui/render/render_object.hpp
@@ -1,7 +1,6 @@
#pragma once
-#include "cru/common/base.hpp"
-
#include "../base.hpp"
+
#include "cru/common/event.hpp"
#include <vector>
@@ -12,7 +11,7 @@ class Control;
}
namespace cru::platform::graph {
-class Painter;
+struct IPainter;
}
namespace cru::ui::render {
@@ -75,7 +74,7 @@ class RenderObject : public Object {
void Measure(const Size& available_size);
void Layout(const Rect& rect);
- virtual void Draw(platform::graph::Painter* painter) = 0;
+ virtual void Draw(platform::graph::IPainter* painter) = 0;
virtual RenderObject* HitTest(const Point& point) = 0;
diff --git a/include/cru/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp
index a10e3b74..6c01ed93 100644
--- a/include/cru/ui/render/text_render_object.hpp
+++ b/include/cru/ui/render/text_render_object.hpp
@@ -6,33 +6,33 @@
// forward declarations
namespace cru::platform::graph {
-class Brush;
-class Font;
-class TextLayout;
+struct IBrush;
+struct IFont;
+struct ITextLayout;
} // namespace cru::platform::graph
namespace cru::ui::render {
class TextRenderObject : public RenderObject {
public:
- TextRenderObject(std::shared_ptr<platform::graph::Brush> brush,
- std::shared_ptr<platform::graph::Font> font,
- std::shared_ptr<platform::graph::Brush> selection_brush);
+ TextRenderObject(std::shared_ptr<platform::graph::IBrush> brush,
+ std::shared_ptr<platform::graph::IFont> font,
+ std::shared_ptr<platform::graph::IBrush> selection_brush);
TextRenderObject(const TextRenderObject& other) = delete;
TextRenderObject(TextRenderObject&& other) = delete;
TextRenderObject& operator=(const TextRenderObject& other) = delete;
TextRenderObject& operator=(TextRenderObject&& other) = delete;
~TextRenderObject() override = default;
- std::wstring GetText() const;
- void SetText(std::wstring new_text);
+ std::string GetText() const;
+ void SetText(std::string new_text);
- std::shared_ptr<platform::graph::Brush> GetBrush() const { return brush_; }
- void SetBrush(std::shared_ptr<platform::graph::Brush> new_brush) {
+ std::shared_ptr<platform::graph::IBrush> GetBrush() const { return brush_; }
+ void SetBrush(std::shared_ptr<platform::graph::IBrush> new_brush) {
new_brush.swap(brush_);
}
- std::shared_ptr<platform::graph::Font> GetFont() const;
- void SetFont(std::shared_ptr<platform::graph::Font> font);
+ std::shared_ptr<platform::graph::IFont> GetFont() const;
+ void SetFont(std::shared_ptr<platform::graph::IFont> font);
std::optional<TextRange> GetSelectionRange() const {
return selection_range_;
@@ -41,14 +41,14 @@ class TextRenderObject : public RenderObject {
selection_range_ = std::move(new_range);
}
- std::shared_ptr<platform::graph::Brush> GetSelectionBrush() const {
+ std::shared_ptr<platform::graph::IBrush> GetSelectionBrush() const {
return selection_brush_;
}
- void SetSelectionBrush(std::shared_ptr<platform::graph::Brush> new_brush) {
+ void SetSelectionBrush(std::shared_ptr<platform::graph::IBrush> new_brush) {
new_brush.swap(selection_brush_);
}
- void Draw(platform::graph::Painter* painter) override;
+ void Draw(platform::graph::IPainter* painter) override;
RenderObject* HitTest(const Point& point) override;
@@ -59,11 +59,11 @@ class TextRenderObject : public RenderObject {
void OnAfterLayout() override;
private:
- std::shared_ptr<platform::graph::Brush> brush_;
- std::shared_ptr<platform::graph::Font> font_;
- std::shared_ptr<platform::graph::TextLayout> text_layout_;
+ std::shared_ptr<platform::graph::IBrush> brush_;
+ std::shared_ptr<platform::graph::IFont> font_;
+ std::unique_ptr<platform::graph::ITextLayout> text_layout_;
std::optional<TextRange> selection_range_ = std::nullopt;
- std::shared_ptr<platform::graph::Brush> selection_brush_;
+ std::shared_ptr<platform::graph::IBrush> selection_brush_;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/window_render_object.hpp b/include/cru/ui/render/window_render_object.hpp
index 2260c293..8f35ad80 100644
--- a/include/cru/ui/render/window_render_object.hpp
+++ b/include/cru/ui/render/window_render_object.hpp
@@ -21,7 +21,7 @@ class WindowRenderObject : public RenderObject {
void Relayout();
- void Draw(platform::graph::Painter* painter) override;
+ void Draw(platform::graph::IPainter* painter) override;
RenderObject* HitTest(const Point& point) override;
diff --git a/include/cru/ui/event/ui_event.hpp b/include/cru/ui/ui_event.hpp
index b962ff76..7a688d6d 100644
--- a/include/cru/ui/event/ui_event.hpp
+++ b/include/cru/ui/ui_event.hpp
@@ -1,15 +1,12 @@
#pragma once
-#include "cru/common/base.hpp"
-
-#include "../base.hpp"
-#include "cru/common/event.hpp"
+#include "base.hpp"
#include <memory>
#include <optional>
#include <type_traits>
namespace cru::platform::graph {
-class Painter;
+struct IPainter;
}
namespace cru::ui {
@@ -127,7 +124,7 @@ class MouseWheelEventArgs : public MouseEventArgs {
class PaintEventArgs : public UiEventArgs {
public:
PaintEventArgs(Object* sender, Object* original_sender,
- platform::graph::Painter* painter)
+ platform::graph::IPainter* painter)
: UiEventArgs(sender, original_sender), painter_(painter) {}
PaintEventArgs(const PaintEventArgs& other) = default;
PaintEventArgs(PaintEventArgs&& other) = default;
@@ -135,10 +132,10 @@ class PaintEventArgs : public UiEventArgs {
PaintEventArgs& operator=(PaintEventArgs&& other) = default;
~PaintEventArgs() = default;
- platform::graph::Painter* GetPainter() const { return painter_; }
+ platform::graph::IPainter* GetPainter() const { return painter_; }
private:
- platform::graph::Painter* painter_;
+ platform::graph::IPainter* painter_;
};
class FocusChangeEventArgs : public UiEventArgs {
diff --git a/include/cru/ui/ui_manager.hpp b/include/cru/ui/ui_manager.hpp
index 5501c62c..199ff28d 100644
--- a/include/cru/ui/ui_manager.hpp
+++ b/include/cru/ui/ui_manager.hpp
@@ -1,14 +1,13 @@
#pragma once
#include "base.hpp"
-#include "cru/common/base.hpp"
#include "controls/button.hpp"
#include <memory>
namespace cru::platform::graph {
-class Brush;
-class Font;
+struct IBrush;
+struct IFont;
} // namespace cru::platform::graph
namespace cru::ui {
@@ -23,12 +22,12 @@ class PredefineResources : public Object {
~PredefineResources() override = default;
// region Button
- std::shared_ptr<platform::graph::Brush> button_normal_border_brush;
+ std::shared_ptr<platform::graph::IBrush> button_normal_border_brush;
// region TextBlock
- std::shared_ptr<platform::graph::Brush> text_block_selection_brush;
- std::shared_ptr<platform::graph::Brush> text_block_text_brush;
- std::shared_ptr<platform::graph::Font> text_block_font;
+ std::shared_ptr<platform::graph::IBrush> text_block_selection_brush;
+ std::shared_ptr<platform::graph::IBrush> text_block_text_brush;
+ std::shared_ptr<platform::graph::IFont> text_block_font;
};
struct ThemeResources {
@@ -53,9 +52,7 @@ class UiManager : public Object {
return predefine_resources_.get();
}
- ThemeResources* GetThemeResources() {
- return &theme_resource_;
- }
+ ThemeResources* GetThemeResources() { return &theme_resource_; }
private:
std::unique_ptr<PredefineResources> predefine_resources_;
diff --git a/include/cru/ui/window.hpp b/include/cru/ui/window.hpp
index 4f44fed4..35d6772e 100644
--- a/include/cru/ui/window.hpp
+++ b/include/cru/ui/window.hpp
@@ -2,14 +2,13 @@
#include "content_control.hpp"
#include "cru/common/self_resolvable.hpp"
-#include "cru/platform/native/native_event.hpp"
-#include "event/ui_event.hpp"
+#include "cru/platform/native/event.hpp"
#include <memory>
#include <vector>
namespace cru::platform::native {
-class INativeWindow;
+struct INativeWindow;
}
namespace cru::ui {
@@ -21,7 +20,7 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
friend class Control;
public:
- static constexpr auto control_type = L"Window";
+ static constexpr std::string_view control_type = "Window";
public:
static Window* CreateOverlapped();
@@ -39,7 +38,7 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
~Window() override;
public:
- std::wstring_view GetControlType() const override final;
+ std::string_view GetControlType() const override final;
render::RenderObject* GetRenderObject() const override;
@@ -90,9 +89,10 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
void OnNativePaint(std::nullptr_t);
void OnNativeResize(const Size& size);
- void OnNativeFocus(bool focus);
+ void OnNativeFocus(cru::platform::native::FocusChangeType focus);
- void OnNativeMouseEnterLeave(bool enter);
+ void OnNativeMouseEnterLeave(
+ cru::platform::native::MouseEnterLeaveType enter);
void OnNativeMouseMove(const Point& point);
void OnNativeMouseDown(
const platform::native::NativeMouseButtonEventArgs& args);
@@ -115,7 +115,7 @@ class Window final : public ContentControl, public SelfResolvable<Window> {
platform::native::INativeWindow* native_window_;
std::vector<EventRevokerGuard> event_revoker_guards_;
- std::shared_ptr<render::WindowRenderObject> render_object_;
+ std::unique_ptr<render::WindowRenderObject> render_object_;
Control* mouse_hover_control_;
diff --git a/include/cru/win/native/ui_application.hpp b/include/cru/win/native/ui_application.hpp
index 65bdc9e4..80e358e4 100644
--- a/include/cru/win/native/ui_application.hpp
+++ b/include/cru/win/native/ui_application.hpp
@@ -23,10 +23,9 @@ class WinUiApplication : public WinNativeResource,
private:
static WinUiApplication* instance;
- private:
+ public:
WinUiApplication();
- public:
CRU_DELETE_COPY(WinUiApplication)
CRU_DELETE_MOVE(WinUiApplication)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 59ca69d4..d486336b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -9,4 +9,4 @@ endif()
add_subdirectory(ui)
add_executable(demo main.cpp)
-target_link_libraries(demo PRIVATE cru_ui)
+target_link_libraries(demo PRIVATE cru_ui cru_win_native)
diff --git a/src/main.cpp b/src/main.cpp
index 7fca1fce..07aff285 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,12 +1,12 @@
#include "cru/platform/heap_debug.hpp"
-#include "cru/platform/native/native_window.hpp"
-#include "cru/platform/native/ui_application.hpp"
+#include "cru/platform/native/window.hpp"
#include "cru/ui/controls/button.hpp"
#include "cru/ui/controls/flex_layout.hpp"
#include "cru/ui/controls/text_block.hpp"
#include "cru/ui/window.hpp"
+#include "cru/win/native/ui_application.hpp"
-using cru::platform::native::UiApplication;
+using cru::platform::native::win::WinUiApplication;
using cru::ui::Rect;
using cru::ui::Thickness;
using cru::ui::Window;
@@ -14,13 +14,13 @@ using cru::ui::controls::Button;
using cru::ui::controls::FlexLayout;
using cru::ui::controls::TextBlock;
-
int main() {
#ifdef CRU_DEBUG
cru::platform::SetupHeapDebug();
#endif
- std::unique_ptr<UiApplication> application(UiApplication::CreateInstance());
+ std::unique_ptr<WinUiApplication> application =
+ std::make_unique<WinUiApplication>();
const auto window = Window::CreateOverlapped();
@@ -30,12 +30,12 @@ int main() {
const auto button = Button::Create();
const auto text_block1 = TextBlock::Create();
- text_block1->SetText(L"Hello World!");
+ text_block1->SetText("Hello World!");
button->SetChild(text_block1);
flex_layout->AddChild(button, 0);
const auto text_block2 = TextBlock::Create();
- text_block2->SetText(L"Hello World!");
+ text_block2->SetText("Hello World!");
flex_layout->AddChild(text_block2, 1);
window->GetNativeWindow()->SetVisible(true);
diff --git a/src/platform/native/CMakeLists.txt b/src/platform/native/CMakeLists.txt
index be3e73a5..c3ca3d7e 100644
--- a/src/platform/native/CMakeLists.txt
+++ b/src/platform/native/CMakeLists.txt
@@ -1,10 +1,12 @@
set(CRU_PLATFORM_NATIVE_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/platform/native)
-add_library(cru_platform_native INTERFACE)
-target_sources(cru_platform_native INTERFACE
+add_library(cru_platform_native STATIC
+ ui_application.cpp
+)
+target_sources(cru_platform_native PUBLIC
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/basic_types.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/cursor.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/event.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/window.hpp
${CRU_PLATFORM_NATIVE_INCLUDE_DIR}/ui_application.hpp
)
-target_link_libraries(cru_platform_native INTERFACE cru_platform_graph)
+target_link_libraries(cru_platform_native PUBLIC cru_platform_graph)
diff --git a/src/platform/native/ui_application.cpp b/src/platform/native/ui_application.cpp
new file mode 100644
index 00000000..b4794182
--- /dev/null
+++ b/src/platform/native/ui_application.cpp
@@ -0,0 +1,5 @@
+#include "cru/platform/native/ui_application.hpp"
+
+namespace cru::platform::native {
+IUiApplication* IUiApplication::instance = nullptr;
+}
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index 18d1ca16..51d36e0d 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -1,11 +1,13 @@
set(CRU_UI_INCLUDE_DIR ${CRU_INCLUDE_DIR}/cru/ui)
add_library(cru_ui STATIC
+ helper.hpp
routed_event_dispatch.hpp
click_detector.cpp
content_control.cpp
- control.cpp
+ control.cpp
+ helper.cpp
layout_control.cpp
no_child_control.cpp
ui_manager.cpp
@@ -27,13 +29,13 @@ target_sources(cru_ui PUBLIC
${CRU_UI_INCLUDE_DIR}/control.hpp
${CRU_UI_INCLUDE_DIR}/layout_control.hpp
${CRU_UI_INCLUDE_DIR}/no_child_control.hpp
+ ${CRU_UI_INCLUDE_DIR}/ui_event.hpp
${CRU_UI_INCLUDE_DIR}/ui_manager.hpp
${CRU_UI_INCLUDE_DIR}/window.hpp
${CRU_UI_INCLUDE_DIR}/controls/button.hpp
${CRU_UI_INCLUDE_DIR}/controls/container.hpp
${CRU_UI_INCLUDE_DIR}/controls/flex_layout.hpp
${CRU_UI_INCLUDE_DIR}/controls/text_block.hpp
- ${CRU_UI_INCLUDE_DIR}/event/ui_event.hpp
${CRU_UI_INCLUDE_DIR}/render/border_render_object.hpp
${CRU_UI_INCLUDE_DIR}/render/flex_layout_render_object.hpp
${CRU_UI_INCLUDE_DIR}/render/render_object.hpp
@@ -43,5 +45,5 @@ target_sources(cru_ui PUBLIC
target_link_libraries(cru_ui PUBLIC cru_base)
if(WIN32)
-target_link_libraries(cru_ui PUBLIC cru_win_native)
+target_link_libraries(cru_ui PUBLIC cru_platform_native)
endif()
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 8e8819de..5f760939 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -2,10 +2,9 @@
#include "cru/platform/native/basic_types.hpp"
#include "cru/platform/native/cursor.hpp"
-#include "cru/platform/native/native_window.hpp"
#include "cru/platform/native/ui_application.hpp"
+#include "cru/platform/native/window.hpp"
#include "cru/ui/base.hpp"
-#include "cru/ui/event/ui_event.hpp"
#include "cru/ui/window.hpp"
#include "routed_event_dispatch.hpp"
@@ -13,9 +12,9 @@
#include <memory>
namespace cru::ui {
-using platform::native::Cursor;
-using platform::native::SystemCursor;
-using platform::native::UiApplication;
+using platform::native::ICursor;
+using platform::native::IUiApplication;
+using platform::native::SystemCursorType;
Control::Control() {
MouseEnterEvent()->Direct()->AddHandler(
@@ -85,20 +84,20 @@ bool Control::IsMouseCaptured() {
return GetWindow()->GetMouseCaptureControl() == this;
}
-std::shared_ptr<Cursor> Control::GetCursor() { return cursor_; }
+std::shared_ptr<ICursor> Control::GetCursor() { return cursor_; }
-std::shared_ptr<Cursor> Control::GetInheritedCursor() {
+std::shared_ptr<ICursor> Control::GetInheritedCursor() {
Control* control = this;
while (control != nullptr) {
const auto cursor = control->GetCursor();
if (cursor != nullptr) return cursor;
control = control->GetParent();
}
- return UiApplication::GetInstance()->GetCursorManager()->GetSystemCursor(
- SystemCursor::Arrow);
+ return IUiApplication::GetInstance()->GetCursorManager()->GetSystemCursor(
+ SystemCursorType::Arrow);
}
-void Control::SetCursor(std::shared_ptr<Cursor> cursor) {
+void Control::SetCursor(std::shared_ptr<ICursor> cursor) {
cursor_ = std::move(cursor);
const auto window = GetWindow();
if (window != nullptr) {
diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp
index 2822f6db..b7f972be 100644
--- a/src/ui/controls/button.cpp
+++ b/src/ui/controls/button.cpp
@@ -1,18 +1,16 @@
#include "cru/ui/controls/button.hpp"
#include <memory>
+#include "../helper.hpp"
#include "cru/platform/graph/brush.hpp"
-#include "cru/platform/graph/graph_factory.hpp"
#include "cru/platform/native/cursor.hpp"
-#include "cru/platform/native/native_window.hpp"
#include "cru/platform/native/ui_application.hpp"
#include "cru/ui/render/border_render_object.hpp"
#include "cru/ui/ui_manager.hpp"
#include "cru/ui/window.hpp"
namespace cru::ui::controls {
-using platform::native::GetSystemCursor;
-using platform::native::SystemCursor;
+using cru::platform::native::SystemCursorType;
namespace {
void Set(render::BorderRenderObject* o, const ButtonStateStyle& s) {
@@ -22,12 +20,17 @@ void Set(render::BorderRenderObject* o, const ButtonStateStyle& s) {
o->SetForegroundBrush(s.foreground_brush);
o->SetBackgroundBrush(s.background_brush);
}
+
+std::shared_ptr<platform::native::ICursor> GetSystemCursor(
+ SystemCursorType type) {
+ return GetUiApplication()->GetCursorManager()->GetSystemCursor(type);
+}
} // namespace
Button::Button() : click_detector_(this) {
style_ = UiManager::GetInstance()->GetThemeResources()->button_style;
- render_object_.reset(new render::BorderRenderObject);
+ render_object_ = std::make_unique<render::BorderRenderObject>();
render_object_->SetAttachedControl(this);
Set(render_object_.get(), style_.normal);
render_object_->SetBorderEnabled(true);
@@ -75,21 +78,20 @@ void Button::OnStateChange(ButtonState oldState, ButtonState newState) {
switch (newState) {
case ButtonState::Normal:
Set(render_object_.get(), style_.normal);
- SetCursor(GetSystemCursor(SystemCursor::Arrow));
+ SetCursor(GetSystemCursor(SystemCursorType::Arrow));
break;
case ButtonState::Hover:
Set(render_object_.get(), style_.hover);
- SetCursor(GetSystemCursor(SystemCursor::Hand));
+ SetCursor(GetSystemCursor(SystemCursorType::Hand));
break;
case ButtonState::Press:
Set(render_object_.get(), style_.press);
- SetCursor(GetSystemCursor(SystemCursor::Hand));
+ SetCursor(GetSystemCursor(SystemCursorType::Hand));
break;
case ButtonState::PressCancel:
Set(render_object_.get(), style_.press_cancel);
- SetCursor(GetSystemCursor(SystemCursor::Arrow));
+ SetCursor(GetSystemCursor(SystemCursorType::Arrow));
break;
}
- GetWindow()->GetNativeWindow()->Repaint();
}
} // namespace cru::ui::controls
diff --git a/src/ui/controls/container.cpp b/src/ui/controls/container.cpp
index 7ebee4b4..2075d4ba 100644
--- a/src/ui/controls/container.cpp
+++ b/src/ui/controls/container.cpp
@@ -1,11 +1,11 @@
#include "cru/ui/controls/container.hpp"
-#include "cru/platform/graph/graph_factory.hpp"
+#include "cru/platform/graph/factory.hpp"
#include "cru/ui/render/border_render_object.hpp"
namespace cru::ui::controls {
Container::Container() {
- render_object_.reset(new render::BorderRenderObject);
+ render_object_ = std::make_unique<render::BorderRenderObject>();
render_object_->SetBorderEnabled(false);
}
diff --git a/src/ui/controls/text_block.cpp b/src/ui/controls/text_block.cpp
index 71903981..333b44c8 100644
--- a/src/ui/controls/text_block.cpp
+++ b/src/ui/controls/text_block.cpp
@@ -9,20 +9,22 @@ using render::TextRenderObject;
TextBlock::TextBlock() {
const auto predefined_resources =
UiManager::GetInstance()->GetPredefineResources();
- render_object_.reset(
- new TextRenderObject(predefined_resources->text_block_text_brush,
- predefined_resources->text_block_font,
- predefined_resources->text_block_selection_brush));
+ render_object_ = std::make_unique<TextRenderObject>(
+ predefined_resources->text_block_text_brush,
+ predefined_resources->text_block_font,
+ predefined_resources->text_block_selection_brush);
render_object_->SetAttachedControl(this);
}
+TextBlock::~TextBlock() = default;
+
render::RenderObject* TextBlock::GetRenderObject() const {
return render_object_.get();
}
-std::wstring TextBlock::GetText() const { return render_object_->GetText(); }
+std::string TextBlock::GetText() const { return render_object_->GetText(); }
-void TextBlock::SetText(std::wstring text) {
+void TextBlock::SetText(std::string text) {
render_object_->SetText(std::move(text));
}
} // namespace cru::ui::controls
diff --git a/src/ui/helper.cpp b/src/ui/helper.cpp
new file mode 100644
index 00000000..4d5d8665
--- /dev/null
+++ b/src/ui/helper.cpp
@@ -0,0 +1,15 @@
+#include "helper.hpp"
+
+#include "cru/platform/graph/factory.hpp"
+#include "cru/platform/native/ui_application.hpp"
+
+namespace cru::ui {
+using cru::platform::graph::IGraphFactory;
+using cru::platform::native::IUiApplication;
+
+IGraphFactory* GetGraphFactory() {
+ return IUiApplication::GetInstance()->GetGraphFactory();
+}
+
+IUiApplication* GetUiApplication() { return IUiApplication::GetInstance(); }
+} // namespace cru::ui
diff --git a/src/ui/helper.hpp b/src/ui/helper.hpp
new file mode 100644
index 00000000..4fd14aa6
--- /dev/null
+++ b/src/ui/helper.hpp
@@ -0,0 +1,17 @@
+#pragma once
+#include "cru/ui/base.hpp"
+
+namespace cru::platform {
+namespace graph {
+struct IGraphFactory;
+}
+namespace native {
+struct ICursor;
+struct IUiApplication;
+} // namespace native
+} // namespace cru::platform
+
+namespace cru::ui {
+cru::platform::graph::IGraphFactory* GetGraphFactory();
+cru::platform::native::IUiApplication* GetUiApplication();
+} // namespace cru::ui
diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp
index 5b203391..16f2828a 100644
--- a/src/ui/render/border_render_object.cpp
+++ b/src/ui/render/border_render_object.cpp
@@ -1,9 +1,10 @@
#include "cru/ui/render/border_render_object.hpp"
+#include "../helper.hpp"
#include "cru/common/logger.hpp"
+#include "cru/platform/graph/factory.hpp"
#include "cru/platform/graph/geometry.hpp"
-#include "cru/platform/graph/graph_factory.hpp"
-#include "cru/platform/graph/util/painter_util.hpp"
+#include "cru/platform/graph/util/painter.hpp"
#include <algorithm>
#include <cassert>
@@ -16,13 +17,13 @@ BorderRenderObject::BorderRenderObject() {
BorderRenderObject::~BorderRenderObject() {}
-void BorderRenderObject::Draw(platform::graph::Painter* painter) {
+void BorderRenderObject::Draw(platform::graph::IPainter* painter) {
if (background_brush_ != nullptr)
painter->FillGeometry(border_inner_geometry_.get(),
background_brush_.get());
if (is_border_enabled_) {
if (border_brush_ == nullptr) {
- log::Warn(L"Border is enabled but brush is null");
+ log::Warn("Border is enabled but brush is null");
} else {
painter->FillGeometry(geometry_.get(), border_brush_.get());
}
@@ -79,14 +80,14 @@ void BorderRenderObject::OnMeasureCore(const Size& available_size) {
auto coerced_margin_border_padding_size = margin_border_padding_size;
if (coerced_margin_border_padding_size.width > available_size.width) {
log::Warn(
- L"Measure: horizontal length of padding, border and margin is bigger "
- L"than available length.");
+ "Measure: horizontal length of padding, border and margin is bigger "
+ "than available length.");
coerced_margin_border_padding_size.width = available_size.width;
}
if (coerced_margin_border_padding_size.height > available_size.height) {
log::Warn(
- L"Measure: vertical length of padding, border and margin is bigger "
- L"than available length.");
+ "Measure: vertical length of padding, border and margin is bigger "
+ "than available length.");
coerced_margin_border_padding_size.height = available_size.height;
}
@@ -117,14 +118,14 @@ void BorderRenderObject::OnLayoutCore(const Rect& rect) {
if (coerced_content_available_size.width < 0) {
log::Warn(
- L"Layout: horizontal length of padding, border and margin is bigger "
- L"than available length.");
+ "Layout: horizontal length of padding, border and margin is bigger "
+ "than available length.");
coerced_content_available_size.width = 0;
}
if (coerced_content_available_size.height < 0) {
log::Warn(
- L"Layout: vertical length of padding, border and margin is bigger "
- L"than available length.");
+ "Layout: vertical length of padding, border and margin is bigger "
+ "than available length.");
coerced_content_available_size.height = 0;
}
@@ -177,7 +178,7 @@ void BorderRenderObject::RecreateGeometry() {
r.left_bottom - Point{t.left, t.bottom},
r.right_bottom - Point{t.right, t.bottom});
- auto f = [](platform::graph::GeometryBuilder* builder, const Rect& rect,
+ auto f = [](platform::graph::IGeometryBuilder* builder, const Rect& rect,
const CornerRadius& corner) {
builder->BeginFigure(Point(rect.left + corner.left_top.x, rect.top));
builder->LineTo(Point(rect.GetRight() - corner.right_top.x, rect.top));
@@ -204,24 +205,24 @@ void BorderRenderObject::RecreateGeometry() {
const Rect outer_rect{margin.left, margin.top,
size.width - margin.GetHorizontalTotal(),
size.height - margin.GetVerticalTotal()};
- const auto graph_factory = platform::graph::GraphFactory::GetInstance();
- std::unique_ptr<platform::graph::GeometryBuilder> builder{
+ const auto graph_factory = GetGraphFactory();
+ std::unique_ptr<platform::graph::IGeometryBuilder> builder{
graph_factory->CreateGeometryBuilder()};
f(builder.get(), outer_rect, outer_radius);
- border_outer_geometry_.reset(builder->Build());
+ border_outer_geometry_ = builder->Build();
builder.reset();
const Rect inner_rect = outer_rect.Shrink(border_thickness_);
- builder.reset(graph_factory->CreateGeometryBuilder());
+ builder = graph_factory->CreateGeometryBuilder();
f(builder.get(), inner_rect, inner_radius);
- border_inner_geometry_.reset(builder->Build());
+ border_inner_geometry_ = builder->Build();
builder.reset();
- builder.reset(graph_factory->CreateGeometryBuilder());
+ builder = graph_factory->CreateGeometryBuilder();
f(builder.get(), outer_rect, outer_radius);
f(builder.get(), inner_rect, inner_radius);
- geometry_.reset(builder->Build());
+ geometry_ = builder->Build();
builder.reset();
}
} // namespace cru::ui::render
diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp
index a16aec69..3370ffc1 100644
--- a/src/ui/render/flex_layout_render_object.cpp
+++ b/src/ui/render/flex_layout_render_object.cpp
@@ -1,6 +1,6 @@
#include "cru/ui/render/flex_layout_render_object.hpp"
-#include "cru/platform/graph/util/painter_util.hpp"
+#include "cru/platform/graph/util/painter.hpp"
#include <algorithm>
#include <cassert>
@@ -11,7 +11,7 @@ FlexLayoutRenderObject::FlexLayoutRenderObject() {
SetChildMode(ChildMode::Multiple);
}
-void FlexLayoutRenderObject::Draw(platform::graph::Painter* painter) {
+void FlexLayoutRenderObject::Draw(platform::graph::IPainter* painter) {
for (const auto child : GetChildren()) {
auto offset = child->GetOffset();
platform::graph::util::WithTransform(
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index a28b4f03..8e65dad0 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -62,14 +62,14 @@ void RenderObject::OnMeasureCore(const Size& available_size) {
auto coerced_margin_padding_size = margin_padding_size;
if (coerced_margin_padding_size.width > available_size.width) {
log::Warn(
- L"Measure: horizontal length of padding and margin is bigger than "
- L"available length.");
+ "Measure: horizontal length of padding and margin is bigger than "
+ "available length.");
coerced_margin_padding_size.width = available_size.width;
}
if (coerced_margin_padding_size.height > available_size.height) {
log::Warn(
- L"Measure: vertical length of padding and margin is bigger than "
- L"available length.");
+ "Measure: vertical length of padding and margin is bigger than "
+ "available length.");
coerced_margin_padding_size.height = available_size.height;
}
@@ -90,14 +90,14 @@ void RenderObject::OnLayoutCore(const Rect& rect) {
if (coerced_content_available_size.width < 0) {
log::Warn(
- L"Layout: horizontal length of padding and margin is bigger than "
- L"available length.");
+ "Layout: horizontal length of padding and margin is bigger than "
+ "available length.");
coerced_content_available_size.width = 0;
}
if (coerced_content_available_size.height < 0) {
log::Warn(
- L"Layout: vertical length of padding and margin is bigger than "
- L"available length.");
+ "Layout: vertical length of padding and margin is bigger than "
+ "available length.");
coerced_content_available_size.height = 0;
}
diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp
index a21dc028..9afb9f6e 100644
--- a/src/ui/render/text_render_object.cpp
+++ b/src/ui/render/text_render_object.cpp
@@ -1,17 +1,20 @@
#include "cru/ui/render/text_render_object.hpp"
-#include "cru/platform/graph/graph_factory.hpp"
+#include "../helper.hpp"
+#include "cru/platform/graph/factory.hpp"
#include "cru/platform/graph/text_layout.hpp"
-#include "cru/platform/graph/util/painter_util.hpp"
+#include "cru/platform/graph/util/painter.hpp"
#include <algorithm>
#include <cassert>
+//TODO: Null Check!!!
+
namespace cru::ui::render {
TextRenderObject::TextRenderObject(
- std::shared_ptr<platform::graph::Brush> brush,
- std::shared_ptr<platform::graph::Font> font,
- std::shared_ptr<platform::graph::Brush> selection_brush) {
+ std::shared_ptr<platform::graph::IBrush> brush,
+ std::shared_ptr<platform::graph::IFont> font,
+ std::shared_ptr<platform::graph::IBrush> selection_brush) {
assert(brush);
assert(font);
assert(selection_brush);
@@ -22,32 +25,32 @@ TextRenderObject::TextRenderObject(
font.swap(font_);
selection_brush.swap(selection_brush_);
- const auto graph_factory = platform::graph::GraphFactory::GetInstance();
- text_layout_.reset(graph_factory->CreateTextLayout(font_, L""));
+ const auto graph_factory = GetGraphFactory();
+ text_layout_ = graph_factory->CreateTextLayout(font_, "");
}
-std::wstring TextRenderObject::GetText() const {
+std::string TextRenderObject::GetText() const {
return text_layout_->GetText();
}
-void TextRenderObject::SetText(std::wstring new_text) {
+void TextRenderObject::SetText(std::string new_text) {
text_layout_->SetText(std::move(new_text));
}
-std::shared_ptr<platform::graph::Font> TextRenderObject::GetFont() const {
+std::shared_ptr<platform::graph::IFont> TextRenderObject::GetFont() const {
return text_layout_->GetFont();
}
-void TextRenderObject::SetFont(std::shared_ptr<platform::graph::Font> font) {
+void TextRenderObject::SetFont(std::shared_ptr<platform::graph::IFont> font) {
text_layout_->SetFont(std::move(font));
}
-void TextRenderObject::Draw(platform::graph::Painter* painter) {
+void TextRenderObject::Draw(platform::graph::IPainter* painter) {
platform::graph::util::WithTransform(
painter,
platform::Matrix::Translation(GetMargin().left + GetPadding().left,
GetMargin().top + GetPadding().top),
- [this](platform::graph::Painter* p) {
+ [this](platform::graph::IPainter* p) {
if (this->selection_range_.has_value()) {
const auto&& rects =
text_layout_->TextRangeRect(this->selection_range_.value());
diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp
index 64bec1e7..8e48b7c9 100644
--- a/src/ui/render/window_render_object.cpp
+++ b/src/ui/render/window_render_object.cpp
@@ -1,9 +1,10 @@
#include "cru/ui/render/window_render_object.hpp"
+#include "../helper.hpp"
#include "cru/common/logger.hpp"
-#include "cru/platform/graph/util/painter_util.hpp"
-#include "cru/platform/native/native_window.hpp"
+#include "cru/platform/graph/util/painter.hpp"
#include "cru/platform/native/ui_application.hpp"
+#include "cru/platform/native/window.hpp"
#include "cru/ui/window.hpp"
#include <cassert>
@@ -20,7 +21,7 @@ class WindowRenderHost : public IRenderHost,
void InvalidateLayout() override;
void InvalidatePaint() override {
- render_object_->GetWindow()->GetNativeWindow()->Repaint();
+ render_object_->GetWindow()->GetNativeWindow()->RequestRepaint();
}
IEvent<AfterLayoutEventArgs>* AfterLayoutEvent() override {
@@ -37,17 +38,16 @@ class WindowRenderHost : public IRenderHost,
void WindowRenderHost::InvalidateLayout() {
if (!need_layout_) {
- log::Debug(L"A relayout is required.");
- platform::native::UiApplication::GetInstance()->InvokeLater(
- [resolver = this->CreateResolver()] {
- if (const auto host = resolver.Resolve()) {
- host->render_object_->Relayout();
- host->need_layout_ = false;
- host->after_layout_event_.Raise(AfterLayoutEventArgs{});
- log::Debug(L"A relayout finished.");
- host->InvalidatePaint();
- }
- });
+ log::Debug("A relayout is required.");
+ GetUiApplication()->InvokeLater([resolver = this->CreateResolver()] {
+ if (const auto host = resolver.Resolve()) {
+ host->render_object_->Relayout();
+ host->need_layout_ = false;
+ host->after_layout_event_.Raise(AfterLayoutEventArgs{});
+ log::Debug("A relayout finished.");
+ host->InvalidatePaint();
+ }
+ });
need_layout_ = true;
}
}
@@ -66,13 +66,13 @@ void WindowRenderObject::Relayout() {
Layout(Rect{Point{}, client_size});
}
-void WindowRenderObject::Draw(platform::graph::Painter* painter) {
+void WindowRenderObject::Draw(platform::graph::IPainter* painter) {
painter->Clear(colors::white);
if (const auto child = GetChild()) {
auto offset = child->GetOffset();
platform::graph::util::WithTransform(
painter, platform::Matrix::Translation(offset.x, offset.y),
- [child](platform::graph::Painter* p) { child->Draw(p); });
+ [child](platform::graph::IPainter* p) { child->Draw(p); });
}
}
diff --git a/src/ui/routed_event_dispatch.hpp b/src/ui/routed_event_dispatch.hpp
index a5270575..666be9ac 100644
--- a/src/ui/routed_event_dispatch.hpp
+++ b/src/ui/routed_event_dispatch.hpp
@@ -20,13 +20,13 @@ 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::wstring_view& event_name,
+void DispatchEvent(const std::string_view& event_name,
Control* const original_sender,
event::RoutedEvent<EventArgs>* (Control::*event_ptr)(),
Control* const last_receiver, Args&&... args) {
#ifdef CRU_DEBUG
bool do_log = true;
- if (event_name == L"MouseMove") do_log = false;
+ if (event_name == "MouseMove") do_log = false;
#endif
if (original_sender == last_receiver) {
@@ -34,8 +34,8 @@ void DispatchEvent(const std::wstring_view& event_name,
#ifdef CRU_DEBUG
if (do_log)
log::Debug(
- L"Routed event {} no need to dispatch (original_sender == "
- L"last_receiver). Original sender is {}.",
+ "Routed event {} no need to dispatch (original_sender == "
+ "last_receiver). Original sender is {}.",
event_name, original_sender->GetControlType());
#endif
*/
@@ -52,14 +52,14 @@ void DispatchEvent(const std::wstring_view& event_name,
#ifdef CRU_DEBUG
if (do_log) {
- std::wstring log = L"Dispatch routed event ";
+ std::string log = "Dispatch routed event ";
log += event_name;
- log += L". Path (parent first): ";
+ log += ". Path (parent first): ";
auto i = receive_list.crbegin();
const auto end = --receive_list.crend();
for (; i != end; ++i) {
log += (*i)->GetControlType();
- log += L" -> ";
+ log += " -> ";
}
log += (*i)->GetControlType();
log::Debug(log);
@@ -85,8 +85,8 @@ void DispatchEvent(const std::wstring_view& event_name,
#ifdef CRU_DEBUG
if (do_log)
log::Debug(
- L"Routed event is short-circuit in TUNNEL at {}-st control (count "
- L"from parent).",
+ "Routed event is short-circuit in TUNNEL at {}-st control (count "
+ "from parent).",
count);
#endif
break;
@@ -106,9 +106,9 @@ void DispatchEvent(const std::wstring_view& event_name,
#ifdef CRU_DEBUG
if (do_log)
log::Debug(
- L"Routed event is short-circuit in BUBBLE at {}-st control "
- L"(count "
- L"from parent).",
+ "Routed event is short-circuit in BUBBLE at {}-st control "
+ "(count "
+ "from parent).",
count);
#endif
break;
@@ -124,7 +124,7 @@ void DispatchEvent(const std::wstring_view& event_name,
}
#ifdef CRU_DEBUG
- if (do_log) log::Debug(L"Routed event dispatch finished.");
+ if (do_log) log::Debug("Routed event dispatch finished.");
#endif
}
} // namespace cru::ui
diff --git a/src/ui/ui_manager.cpp b/src/ui/ui_manager.cpp
index f60f6355..6c61083b 100644
--- a/src/ui/ui_manager.cpp
+++ b/src/ui/ui_manager.cpp
@@ -1,27 +1,35 @@
#include "cru/ui/ui_manager.hpp"
#include "cru/platform/graph/brush.hpp"
+#include "cru/platform/graph/factory.hpp"
#include "cru/platform/graph/font.hpp"
-#include "cru/platform/graph/graph_factory.hpp"
#include "cru/platform/native/ui_application.hpp"
+#include "helper.hpp"
namespace cru::ui {
using namespace cru::platform::graph;
+
+namespace {
+std::unique_ptr<ISolidColorBrush> CreateSolidColorBrush(IGraphFactory* factory,
+ const Color& color) {
+ auto brush = factory->CreateSolidColorBrush();
+ brush->SetColor(color);
+ return brush;
+}
+} // namespace
+
PredefineResources::PredefineResources() {
- const auto graph_factory = GraphFactory::GetInstance();
-
- button_normal_border_brush.reset(
- static_cast<Brush*>(graph_factory->CreateSolidColorBrush(colors::black)));
- text_block_selection_brush.reset(static_cast<Brush*>(
- graph_factory->CreateSolidColorBrush(colors::skyblue)));
- text_block_text_brush.reset(
- static_cast<Brush*>(graph_factory->CreateSolidColorBrush(colors::black)));
- text_block_font.reset(graph_factory->CreateFont(L"等线", 24.0f));
+ const auto factory = GetGraphFactory();
+
+ button_normal_border_brush = CreateSolidColorBrush(factory, colors::black);
+ text_block_selection_brush = CreateSolidColorBrush(factory, colors::skyblue);
+ text_block_text_brush = CreateSolidColorBrush(factory, colors::black);
+ text_block_font = factory->CreateFont("等线", 24.0f);
}
UiManager* UiManager::GetInstance() {
static UiManager* instance = new UiManager();
- platform::native::UiApplication::GetInstance()->AddOnQuitHandler([] {
+ GetUiApplication()->AddOnQuitHandler([] {
delete instance;
instance = nullptr;
});
@@ -29,15 +37,15 @@ UiManager* UiManager::GetInstance() {
}
UiManager::UiManager() : predefine_resources_(new PredefineResources()) {
- const auto factory = GraphFactory::GetInstance();
- theme_resource_.button_style.normal.border_brush = std::shared_ptr<platform::graph::Brush>(
- factory->CreateSolidColorBrush(Color::FromHex(0x00bfff)));
- theme_resource_.button_style.hover.border_brush = std::shared_ptr<platform::graph::Brush>(
- factory->CreateSolidColorBrush(Color::FromHex(0x47d1ff)));
- theme_resource_.button_style.press.border_brush = std::shared_ptr<platform::graph::Brush>(
- factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff)));
- theme_resource_.button_style.press_cancel.border_brush = std::shared_ptr<platform::graph::Brush>(
- factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff)));
+ const auto factory = GetGraphFactory();
+ theme_resource_.button_style.normal.border_brush =
+ CreateSolidColorBrush(factory, Color::FromHex(0x00bfff));
+ theme_resource_.button_style.hover.border_brush =
+ CreateSolidColorBrush(factory, Color::FromHex(0x47d1ff));
+ theme_resource_.button_style.press.border_brush =
+ CreateSolidColorBrush(factory, Color::FromHex(0x91e4ff));
+ theme_resource_.button_style.press_cancel.border_brush =
+ CreateSolidColorBrush(factory, Color::FromHex(0x91e4ff));
theme_resource_.button_style.normal.border_thickness =
theme_resource_.button_style.hover.border_thickness =
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index 25dffe11..73cbc60b 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -1,8 +1,8 @@
#include "cru/ui/window.hpp"
#include "cru/platform/graph/painter.hpp"
-#include "cru/platform/native/native_window.hpp"
#include "cru/platform/native/ui_application.hpp"
+#include "cru/platform/native/window.hpp"
#include "cru/ui/render/window_render_object.hpp"
#include "routed_event_dispatch.hpp"
@@ -10,11 +10,15 @@
#include <list>
namespace cru::ui {
+using cru::platform::native::FocusChangeType;
+using cru::platform::native::IUiApplication;
+using cru::platform::native::MouseEnterLeaveType;
+
namespace event_names {
#ifdef CRU_DEBUG
-#define CRU_DEFINE_EVENT_NAME(name) constexpr const wchar_t* name = L#name;
+#define CRU_DEFINE_EVENT_NAME(name) constexpr const char* name = #name;
#else
-#define CRU_DEFINE_EVENT_NAME(name) constexpr const wchar_t* name = nullptr;
+#define CRU_DEFINE_EVENT_NAME(name) constexpr const char* name = nullptr;
#endif
CRU_DEFINE_EVENT_NAME(LoseFocus)
@@ -97,8 +101,7 @@ Window::Window(tag_overlapped_constructor)
focus_control_(this),
mouse_captured_control_(nullptr) {
window_ = this;
- native_window_ =
- platform::native::UiApplication::GetInstance()->CreateWindow(nullptr);
+ native_window_ = IUiApplication::GetInstance()->CreateWindow(nullptr);
render_object_.reset(new render::WindowRenderObject(this));
render_object_->SetAttachedControl(this);
@@ -129,7 +132,7 @@ Window::~Window() {
[this](Control* control) { control->OnDetachToWindow(this); });
}
-std::wstring_view Window::GetControlType() const { return control_type; }
+std::string_view Window::GetControlType() const { return control_type; }
render::RenderObject* Window::GetRenderObject() const {
return render_object_.get();
@@ -194,8 +197,7 @@ Control* Window::HitTest(const Point& point) {
void Window::OnNativeDestroy(std::nullptr_t) { delete this; }
void Window::OnNativePaint(std::nullptr_t) {
- const auto painter =
- std::unique_ptr<platform::graph::Painter>(native_window_->BeginPaint());
+ auto painter = native_window_->BeginPaint();
render_object_->Draw(painter.get());
painter->EndDraw();
}
@@ -204,15 +206,16 @@ void Window::OnNativeResize(const Size& size) {
render_object_->GetRenderHost()->InvalidateLayout();
}
-void Window::OnNativeFocus(bool focus) {
- focus ? DispatchEvent(event_names::GainFocus, focus_control_,
- &Control::GainFocusEvent, nullptr, true)
- : DispatchEvent(event_names::LoseFocus, focus_control_,
- &Control::LoseFocusEvent, nullptr, true);
+void Window::OnNativeFocus(FocusChangeType focus) {
+ focus == FocusChangeType::Gain
+ ? DispatchEvent(event_names::GainFocus, focus_control_,
+ &Control::GainFocusEvent, nullptr, true)
+ : DispatchEvent(event_names::LoseFocus, focus_control_,
+ &Control::LoseFocusEvent, nullptr, true);
}
-void Window::OnNativeMouseEnterLeave(bool enter) {
- if (!enter) {
+void Window::OnNativeMouseEnterLeave(MouseEnterLeaveType type) {
+ if (type == MouseEnterLeaveType::Leave) {
DispatchEvent(event_names::MouseLeave, mouse_hover_control_,
&Control::MouseLeaveEvent, nullptr);
mouse_hover_control_ = nullptr;
diff --git a/src/win/exception.cpp b/src/win/exception.cpp
index 4cac66bb..271067fc 100644
--- a/src/win/exception.cpp
+++ b/src/win/exception.cpp
@@ -7,7 +7,7 @@ using util::Format;
inline std::string HResultMakeMessage(HRESULT h_result,
const std::string_view* message) {
- char buffer[10];
+ char buffer[20];
sprintf_s(buffer, "%#08x", h_result);
if (message)
@@ -29,7 +29,7 @@ HResultError::HResultError(HRESULT h_result,
inline std::string Win32MakeMessage(DWORD error_code,
const std::string_view* message) {
- char buffer[10];
+ char buffer[20];
sprintf_s(buffer, "%#04x", error_code);
if (message)
diff --git a/src/win/native/ui_application.cpp b/src/win/native/ui_application.cpp
index f3a7f1dc..0ae8ee81 100644
--- a/src/win/native/ui_application.cpp
+++ b/src/win/native/ui_application.cpp
@@ -24,6 +24,12 @@ WinUiApplication::WinUiApplication() {
}
instance = this;
+ IUiApplication::instance = this;
+
+ instance_handle_ = ::GetModuleHandleW(nullptr);
+ if (!instance_handle_)
+ throw Win32Error(::GetLastError(),
+ "Failed to get module(instance) handle.");
log::Logger::GetInstance()->AddSource(
std::make_unique<::cru::platform::win::WinDebugLoggerSource>());
@@ -37,7 +43,10 @@ WinUiApplication::WinUiApplication() {
cursor_manager_ = std::make_unique<WinCursorManager>();
}
-WinUiApplication::~WinUiApplication() { instance = nullptr; }
+WinUiApplication::~WinUiApplication() {
+ IUiApplication::instance = nullptr;
+ instance = nullptr;
+}
int WinUiApplication::Run() {
MSG msg;
diff --git a/src/win/native/window.cpp b/src/win/native/window.cpp
index 517426ff..6fd94838 100644
--- a/src/win/native/window.cpp
+++ b/src/win/native/window.cpp
@@ -43,6 +43,9 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application,
window_manager->RegisterWindow(hwnd_, this);
+ SetCursor(application->GetCursorManager()->GetSystemCursor(
+ cru::platform::native::SystemCursorType::Arrow));
+
window_render_target_ = std::make_unique<WindowRenderTarget>(
application->GetDirectFactory(), hwnd_);
}
diff --git a/src/win/native/window_render_target.cpp b/src/win/native/window_render_target.cpp
index f501b4dd..f15aeb6e 100644
--- a/src/win/native/window_render_target.cpp
+++ b/src/win/native/window_render_target.cpp
@@ -29,6 +29,7 @@ WindowRenderTarget::WindowRenderTarget(DirectGraphFactory* factory, HWND hwnd)
swap_chain_desc.Scaling = DXGI_SCALING_NONE;
swap_chain_desc.SwapEffect =
DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
+ swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
swap_chain_desc.Flags = 0;
// Get the final swap chain for this window from the DXGI factory.