From 9110574bb51e9e2959842a7641f598d34c3cd847 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 13 Dec 2019 01:02:47 +0800 Subject: ... --- src/CMakeLists.txt | 2 +- src/main.cpp | 14 ++++----- src/platform/native/CMakeLists.txt | 8 +++-- src/platform/native/ui_application.cpp | 5 +++ src/ui/CMakeLists.txt | 8 +++-- src/ui/control.cpp | 19 ++++++------ src/ui/controls/button.cpp | 22 +++++++------ src/ui/controls/container.cpp | 4 +-- src/ui/controls/text_block.cpp | 14 +++++---- src/ui/helper.cpp | 15 +++++++++ src/ui/helper.hpp | 17 ++++++++++ src/ui/render/border_render_object.cpp | 41 ++++++++++++------------ src/ui/render/flex_layout_render_object.cpp | 4 +-- src/ui/render/render_object.cpp | 16 +++++----- src/ui/render/text_render_object.cpp | 29 +++++++++-------- src/ui/render/window_render_object.cpp | 32 +++++++++---------- src/ui/routed_event_dispatch.hpp | 26 ++++++++-------- src/ui/ui_manager.cpp | 48 +++++++++++++++++------------ src/ui/window.cpp | 33 +++++++++++--------- src/win/exception.cpp | 4 +-- src/win/native/ui_application.cpp | 11 ++++++- src/win/native/window.cpp | 3 ++ src/win/native/window_render_target.cpp | 1 + 23 files changed, 224 insertions(+), 152 deletions(-) create mode 100644 src/platform/native/ui_application.cpp create mode 100644 src/ui/helper.cpp create mode 100644 src/ui/helper.hpp (limited to 'src') 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 application(UiApplication::CreateInstance()); + std::unique_ptr application = + std::make_unique(); 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 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 Control::GetCursor() { return cursor_; } +std::shared_ptr Control::GetCursor() { return cursor_; } -std::shared_ptr Control::GetInheritedCursor() { +std::shared_ptr 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) { +void Control::SetCursor(std::shared_ptr 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 +#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 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_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_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( + 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 #include @@ -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 builder{ + const auto graph_factory = GetGraphFactory(); + std::unique_ptr 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 #include @@ -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 #include +//TODO: Null Check!!! + namespace cru::ui::render { TextRenderObject::TextRenderObject( - std::shared_ptr brush, - std::shared_ptr font, - std::shared_ptr selection_brush) { + std::shared_ptr brush, + std::shared_ptr font, + std::shared_ptr 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 TextRenderObject::GetFont() const { +std::shared_ptr TextRenderObject::GetFont() const { return text_layout_->GetFont(); } -void TextRenderObject::SetFont(std::shared_ptr font) { +void TextRenderObject::SetFont(std::shared_ptr 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 @@ -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* 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 -void DispatchEvent(const std::wstring_view& event_name, +void DispatchEvent(const std::string_view& event_name, Control* const original_sender, event::RoutedEvent* (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 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(graph_factory->CreateSolidColorBrush(colors::black))); - text_block_selection_brush.reset(static_cast( - graph_factory->CreateSolidColorBrush(colors::skyblue))); - text_block_text_brush.reset( - static_cast(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( - factory->CreateSolidColorBrush(Color::FromHex(0x00bfff))); - theme_resource_.button_style.hover.border_brush = std::shared_ptr( - factory->CreateSolidColorBrush(Color::FromHex(0x47d1ff))); - theme_resource_.button_style.press.border_brush = std::shared_ptr( - factory->CreateSolidColorBrush(Color::FromHex(0x91e4ff))); - theme_resource_.button_style.press_cancel.border_brush = std::shared_ptr( - 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 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(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(); } -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( 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. -- cgit v1.2.3