From 06d1d0442276a05b6caad6e3468f4afb1e8ee5df Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 28 Jun 2020 00:03:11 +0800 Subject: ... --- src/ui/Control.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++ src/ui/Helper.cpp | 15 +++++ src/ui/Helper.hpp | 17 ++++++ src/ui/Window.cpp | 28 +++++++++ src/ui/control.cpp | 130 ------------------------------------------ src/ui/controls/Button.cpp | 73 ++++++++++++++++++++++++ src/ui/controls/Container.cpp | 18 ++++++ src/ui/controls/button.cpp | 73 ------------------------ src/ui/controls/container.cpp | 18 ------ src/ui/helper.cpp | 15 ----- src/ui/helper.hpp | 17 ------ src/ui/window.cpp | 28 --------- 12 files changed, 281 insertions(+), 281 deletions(-) create mode 100644 src/ui/Control.cpp create mode 100644 src/ui/Helper.cpp create mode 100644 src/ui/Helper.hpp create mode 100644 src/ui/Window.cpp delete mode 100644 src/ui/control.cpp create mode 100644 src/ui/controls/Button.cpp create mode 100644 src/ui/controls/Container.cpp delete mode 100644 src/ui/controls/button.cpp delete mode 100644 src/ui/controls/container.cpp delete mode 100644 src/ui/helper.cpp delete mode 100644 src/ui/helper.hpp delete mode 100644 src/ui/window.cpp (limited to 'src/ui') diff --git a/src/ui/Control.cpp b/src/ui/Control.cpp new file mode 100644 index 00000000..cd1367fe --- /dev/null +++ b/src/ui/Control.cpp @@ -0,0 +1,130 @@ +#include "cru/ui/Control.hpp" + +#include "cru/platform/native/Cursor.hpp" +#include "cru/platform/native/UiApplication.hpp" +#include "cru/ui/Base.hpp" +#include "cru/ui/UiHost.hpp" +#include "RoutedEventDispatch.hpp" + +#include + +namespace cru::ui { +using platform::native::ICursor; +using platform::native::IUiApplication; +using platform::native::SystemCursorType; + +Control::Control() { + MouseEnterEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { + this->is_mouse_over_ = true; + this->OnMouseHoverChange(true); + }); + + MouseLeaveEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { + this->is_mouse_over_ = false; + this->OnMouseHoverChange(true); + }); +} + +void Control::_SetParent(Control* parent) { + const auto old_parent = GetParent(); + parent_ = parent; + const auto new_parent = GetParent(); + if (old_parent != new_parent) OnParentChanged(old_parent, new_parent); +} + +void Control::_SetDescendantUiHost(UiHost* host) { + if (host == nullptr && ui_host_ == nullptr) return; + + // You can only attach or detach window. + Expects((host != nullptr && ui_host_ == nullptr) || + (host == nullptr && ui_host_ != nullptr)); + + if (host == nullptr) { + const auto old = ui_host_; + TraverseDescendants([old](Control* control) { + control->ui_host_ = nullptr; + control->OnDetachFromHost(old); + }); + } else + TraverseDescendants([host](Control* control) { + control->ui_host_ = host; + control->OnAttachToHost(host); + }); +} + +void Control::TraverseDescendants( + const std::function& predicate) { + _TraverseDescendants(this, predicate); +} + +void Control::_TraverseDescendants( + Control* control, const std::function& predicate) { + predicate(control); + for (auto c : control->GetChildren()) _TraverseDescendants(c, predicate); +} + +bool Control::RequestFocus() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->RequestFocusFor(this); +} + +bool Control::HasFocus() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->GetFocusControl() == this; +} + +bool Control::CaptureMouse() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->CaptureMouseFor(this); +} + +bool Control::ReleaseMouse() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->CaptureMouseFor(nullptr); +} + +bool Control::IsMouseCaptured() { + auto host = GetUiHost(); + if (host == nullptr) return false; + + return host->GetMouseCaptureControl() == this; +} + +std::shared_ptr Control::GetCursor() { return cursor_; } + +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 IUiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( + SystemCursorType::Arrow); +} + +void Control::SetCursor(std::shared_ptr cursor) { + cursor_ = std::move(cursor); + const auto host = GetUiHost(); + if (host != nullptr) { + host->UpdateCursor(); + } +} + +void Control::OnParentChanged(Control* old_parent, Control* new_parent) { + CRU_UNUSED(old_parent) + CRU_UNUSED(new_parent) +} + +void Control::OnAttachToHost(UiHost* host) { CRU_UNUSED(host) } + +void Control::OnDetachFromHost(UiHost* host) { CRU_UNUSED(host) } +} // namespace cru::ui diff --git a/src/ui/Helper.cpp b/src/ui/Helper.cpp new file mode 100644 index 00000000..6f67e701 --- /dev/null +++ b/src/ui/Helper.cpp @@ -0,0 +1,15 @@ +#include "Helper.hpp" + +#include "cru/platform/graph/Factory.hpp" +#include "cru/platform/native/UiApplication.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..6923852f --- /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/Window.cpp b/src/ui/Window.cpp new file mode 100644 index 00000000..de7044dd --- /dev/null +++ b/src/ui/Window.cpp @@ -0,0 +1,28 @@ +#include "cru/ui/Window.hpp" + +#include "cru/ui/render/WindowRenderObject.hpp" +#include "cru/ui/UiHost.hpp" + +namespace cru::ui { +Window* Window::CreateOverlapped() { + return new Window(tag_overlapped_constructor{}); +} + +Window::Window(tag_overlapped_constructor) { + managed_ui_host_ = std::make_unique(this); +} + +Window::~Window() { + // explicit destroy ui host first. + managed_ui_host_.reset(); +} + +std::string_view Window::GetControlType() const { return control_type; } + +render::RenderObject* Window::GetRenderObject() const { return render_object_; } + +void Window::OnChildChanged(Control* old_child, Control* new_child) { + if (old_child) render_object_->RemoveChild(0); + if (new_child) render_object_->AddChild(new_child->GetRenderObject(), 0); +} +} // namespace cru::ui diff --git a/src/ui/control.cpp b/src/ui/control.cpp deleted file mode 100644 index cd1367fe..00000000 --- a/src/ui/control.cpp +++ /dev/null @@ -1,130 +0,0 @@ -#include "cru/ui/Control.hpp" - -#include "cru/platform/native/Cursor.hpp" -#include "cru/platform/native/UiApplication.hpp" -#include "cru/ui/Base.hpp" -#include "cru/ui/UiHost.hpp" -#include "RoutedEventDispatch.hpp" - -#include - -namespace cru::ui { -using platform::native::ICursor; -using platform::native::IUiApplication; -using platform::native::SystemCursorType; - -Control::Control() { - MouseEnterEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { - this->is_mouse_over_ = true; - this->OnMouseHoverChange(true); - }); - - MouseLeaveEvent()->Direct()->AddHandler([this](event::MouseEventArgs&) { - this->is_mouse_over_ = false; - this->OnMouseHoverChange(true); - }); -} - -void Control::_SetParent(Control* parent) { - const auto old_parent = GetParent(); - parent_ = parent; - const auto new_parent = GetParent(); - if (old_parent != new_parent) OnParentChanged(old_parent, new_parent); -} - -void Control::_SetDescendantUiHost(UiHost* host) { - if (host == nullptr && ui_host_ == nullptr) return; - - // You can only attach or detach window. - Expects((host != nullptr && ui_host_ == nullptr) || - (host == nullptr && ui_host_ != nullptr)); - - if (host == nullptr) { - const auto old = ui_host_; - TraverseDescendants([old](Control* control) { - control->ui_host_ = nullptr; - control->OnDetachFromHost(old); - }); - } else - TraverseDescendants([host](Control* control) { - control->ui_host_ = host; - control->OnAttachToHost(host); - }); -} - -void Control::TraverseDescendants( - const std::function& predicate) { - _TraverseDescendants(this, predicate); -} - -void Control::_TraverseDescendants( - Control* control, const std::function& predicate) { - predicate(control); - for (auto c : control->GetChildren()) _TraverseDescendants(c, predicate); -} - -bool Control::RequestFocus() { - auto host = GetUiHost(); - if (host == nullptr) return false; - - return host->RequestFocusFor(this); -} - -bool Control::HasFocus() { - auto host = GetUiHost(); - if (host == nullptr) return false; - - return host->GetFocusControl() == this; -} - -bool Control::CaptureMouse() { - auto host = GetUiHost(); - if (host == nullptr) return false; - - return host->CaptureMouseFor(this); -} - -bool Control::ReleaseMouse() { - auto host = GetUiHost(); - if (host == nullptr) return false; - - return host->CaptureMouseFor(nullptr); -} - -bool Control::IsMouseCaptured() { - auto host = GetUiHost(); - if (host == nullptr) return false; - - return host->GetMouseCaptureControl() == this; -} - -std::shared_ptr Control::GetCursor() { return cursor_; } - -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 IUiApplication::GetInstance()->GetCursorManager()->GetSystemCursor( - SystemCursorType::Arrow); -} - -void Control::SetCursor(std::shared_ptr cursor) { - cursor_ = std::move(cursor); - const auto host = GetUiHost(); - if (host != nullptr) { - host->UpdateCursor(); - } -} - -void Control::OnParentChanged(Control* old_parent, Control* new_parent) { - CRU_UNUSED(old_parent) - CRU_UNUSED(new_parent) -} - -void Control::OnAttachToHost(UiHost* host) { CRU_UNUSED(host) } - -void Control::OnDetachFromHost(UiHost* host) { CRU_UNUSED(host) } -} // namespace cru::ui diff --git a/src/ui/controls/Button.cpp b/src/ui/controls/Button.cpp new file mode 100644 index 00000000..6f6af878 --- /dev/null +++ b/src/ui/controls/Button.cpp @@ -0,0 +1,73 @@ +#include "cru/ui/controls/Button.hpp" +#include + +#include "../Helper.hpp" +#include "cru/platform/graph/Brush.hpp" +#include "cru/platform/native/Cursor.hpp" +#include "cru/platform/native/UiApplication.hpp" +#include "cru/ui/render/BorderRenderObject.hpp" +#include "cru/ui/UiManager.hpp" +#include "cru/ui/Window.hpp" + +namespace cru::ui::controls { +using cru::platform::native::SystemCursorType; + +namespace { +void Set(render::BorderRenderObject* o, const ButtonStateStyle& s) { + o->SetBorderBrush(s.border_brush); + o->SetBorderThickness(s.border_thickness); + o->SetBorderRadius(s.border_radius); + 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_ = std::make_unique(); + render_object_->SetAttachedControl(this); + Set(render_object_.get(), style_.normal); + render_object_->SetBorderEnabled(true); + + click_detector_.StateChangeEvent()->AddHandler( + [this](const ClickState& state) { + switch (state) { + case ClickState::None: + Set(render_object_.get(), style_.normal); + SetCursor(GetSystemCursor(SystemCursorType::Arrow)); + break; + case ClickState::Hover: + Set(render_object_.get(), style_.hover); + SetCursor(GetSystemCursor(SystemCursorType::Hand)); + break; + case ClickState::Press: + Set(render_object_.get(), style_.press); + SetCursor(GetSystemCursor(SystemCursorType::Hand)); + break; + case ClickState::PressInactive: + Set(render_object_.get(), style_.press_cancel); + SetCursor(GetSystemCursor(SystemCursorType::Arrow)); + break; + } + }); +} + +Button::~Button() = default; + +render::RenderObject* Button::GetRenderObject() const { + return render_object_.get(); +} + +void Button::OnChildChanged(Control* old_child, Control* new_child) { + if (old_child != nullptr) render_object_->RemoveChild(0); + if (new_child != nullptr) + render_object_->AddChild(new_child->GetRenderObject(), 0); +} + +} // namespace cru::ui::controls diff --git a/src/ui/controls/Container.cpp b/src/ui/controls/Container.cpp new file mode 100644 index 00000000..de58ee64 --- /dev/null +++ b/src/ui/controls/Container.cpp @@ -0,0 +1,18 @@ +#include "cru/ui/controls/Container.hpp" + +#include "cru/platform/graph/Factory.hpp" +#include "cru/ui/render/BorderRenderObject.hpp" + +namespace cru::ui::controls { +Container::Container() { + render_object_ = std::make_unique(); + render_object_->SetBorderEnabled(false); +} + +Container::~Container() = default; + +void Container::OnChildChanged(Control*, Control* new_child) { + render_object_->RemoveChild(0); + render_object_->AddChild(new_child->GetRenderObject(), 0); +} +} // namespace cru::ui::controls diff --git a/src/ui/controls/button.cpp b/src/ui/controls/button.cpp deleted file mode 100644 index 6f6af878..00000000 --- a/src/ui/controls/button.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "cru/ui/controls/Button.hpp" -#include - -#include "../Helper.hpp" -#include "cru/platform/graph/Brush.hpp" -#include "cru/platform/native/Cursor.hpp" -#include "cru/platform/native/UiApplication.hpp" -#include "cru/ui/render/BorderRenderObject.hpp" -#include "cru/ui/UiManager.hpp" -#include "cru/ui/Window.hpp" - -namespace cru::ui::controls { -using cru::platform::native::SystemCursorType; - -namespace { -void Set(render::BorderRenderObject* o, const ButtonStateStyle& s) { - o->SetBorderBrush(s.border_brush); - o->SetBorderThickness(s.border_thickness); - o->SetBorderRadius(s.border_radius); - 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_ = std::make_unique(); - render_object_->SetAttachedControl(this); - Set(render_object_.get(), style_.normal); - render_object_->SetBorderEnabled(true); - - click_detector_.StateChangeEvent()->AddHandler( - [this](const ClickState& state) { - switch (state) { - case ClickState::None: - Set(render_object_.get(), style_.normal); - SetCursor(GetSystemCursor(SystemCursorType::Arrow)); - break; - case ClickState::Hover: - Set(render_object_.get(), style_.hover); - SetCursor(GetSystemCursor(SystemCursorType::Hand)); - break; - case ClickState::Press: - Set(render_object_.get(), style_.press); - SetCursor(GetSystemCursor(SystemCursorType::Hand)); - break; - case ClickState::PressInactive: - Set(render_object_.get(), style_.press_cancel); - SetCursor(GetSystemCursor(SystemCursorType::Arrow)); - break; - } - }); -} - -Button::~Button() = default; - -render::RenderObject* Button::GetRenderObject() const { - return render_object_.get(); -} - -void Button::OnChildChanged(Control* old_child, Control* new_child) { - if (old_child != nullptr) render_object_->RemoveChild(0); - if (new_child != nullptr) - render_object_->AddChild(new_child->GetRenderObject(), 0); -} - -} // namespace cru::ui::controls diff --git a/src/ui/controls/container.cpp b/src/ui/controls/container.cpp deleted file mode 100644 index de58ee64..00000000 --- a/src/ui/controls/container.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "cru/ui/controls/Container.hpp" - -#include "cru/platform/graph/Factory.hpp" -#include "cru/ui/render/BorderRenderObject.hpp" - -namespace cru::ui::controls { -Container::Container() { - render_object_ = std::make_unique(); - render_object_->SetBorderEnabled(false); -} - -Container::~Container() = default; - -void Container::OnChildChanged(Control*, Control* new_child) { - render_object_->RemoveChild(0); - render_object_->AddChild(new_child->GetRenderObject(), 0); -} -} // namespace cru::ui::controls diff --git a/src/ui/helper.cpp b/src/ui/helper.cpp deleted file mode 100644 index 6f67e701..00000000 --- a/src/ui/helper.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "Helper.hpp" - -#include "cru/platform/graph/Factory.hpp" -#include "cru/platform/native/UiApplication.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 deleted file mode 100644 index 6923852f..00000000 --- a/src/ui/helper.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#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/window.cpp b/src/ui/window.cpp deleted file mode 100644 index de7044dd..00000000 --- a/src/ui/window.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "cru/ui/Window.hpp" - -#include "cru/ui/render/WindowRenderObject.hpp" -#include "cru/ui/UiHost.hpp" - -namespace cru::ui { -Window* Window::CreateOverlapped() { - return new Window(tag_overlapped_constructor{}); -} - -Window::Window(tag_overlapped_constructor) { - managed_ui_host_ = std::make_unique(this); -} - -Window::~Window() { - // explicit destroy ui host first. - managed_ui_host_.reset(); -} - -std::string_view Window::GetControlType() const { return control_type; } - -render::RenderObject* Window::GetRenderObject() const { return render_object_; } - -void Window::OnChildChanged(Control* old_child, Control* new_child) { - if (old_child) render_object_->RemoveChild(0); - if (new_child) render_object_->AddChild(new_child->GetRenderObject(), 0); -} -} // namespace cru::ui -- cgit v1.2.3