aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-10-29 00:01:26 +0800
committercrupest <crupest@outlook.com>2020-10-29 00:01:26 +0800
commit52594324b302f6e9da10ac01fe803196371bb2d9 (patch)
tree38dd36e0bf934b283dd80f808531a2ee862b174b /src
parentdf4df679e157f974773dad7776b204e9d4f3009e (diff)
downloadcru-52594324b302f6e9da10ac01fe803196371bb2d9.tar.gz
cru-52594324b302f6e9da10ac01fe803196371bb2d9.tar.bz2
cru-52594324b302f6e9da10ac01fe803196371bb2d9.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/ContentControl.cpp24
-rw-r--r--src/ui/Control.cpp106
-rw-r--r--src/ui/LayoutControl.cpp47
-rw-r--r--src/ui/NoChildControl.cpp4
-rw-r--r--src/ui/Window.cpp31
-rw-r--r--src/ui/WindowHost.cpp98
-rw-r--r--src/ui/controls/TextControlService.hpp77
-rw-r--r--src/ui/render/RenderObject.cpp25
-rw-r--r--src/ui/render/WindowRenderObject.cpp44
-rw-r--r--src/win/native/UiApplication.cpp5
-rw-r--r--src/win/native/Window.cpp1
12 files changed, 193 insertions, 271 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index d59fd7da..045fea24 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -30,7 +30,6 @@ add_library(cru_ui STATIC
render/ScrollRenderObject.cpp
render/StackLayoutRenderObject.cpp
render/TextRenderObject.cpp
- render/WindowRenderObject.cpp
)
target_sources(cru_ui PUBLIC
${CRU_UI_INCLUDE_DIR}/Base.hpp
@@ -63,6 +62,5 @@ target_sources(cru_ui PUBLIC
${CRU_UI_INCLUDE_DIR}/render/ScrollRenderObject.hpp
${CRU_UI_INCLUDE_DIR}/render/StackLayoutRenderObject.hpp
${CRU_UI_INCLUDE_DIR}/render/TextRenderObject.hpp
- ${CRU_UI_INCLUDE_DIR}/render/WindowRenderObject.hpp
)
target_link_libraries(cru_ui PUBLIC cru_platform_native)
diff --git a/src/ui/ContentControl.cpp b/src/ui/ContentControl.cpp
index 60d944d6..19b1b06f 100644
--- a/src/ui/ContentControl.cpp
+++ b/src/ui/ContentControl.cpp
@@ -3,25 +3,19 @@
#include "cru/ui/Window.hpp"
namespace cru::ui {
-ContentControl::ContentControl()
- : child_vector_{nullptr}, child_(child_vector_[0]) {}
-
-ContentControl::~ContentControl() { delete child_; }
+Control* ContentControl::GetChild() const {
+ if (GetChildren().empty()) return nullptr;
+ return GetChildren()[0];
+}
void ContentControl::SetChild(Control* child) {
- Expects(!dynamic_cast<Window*>(child)); // Can't add a window as child.
- if (child == child_) return;
-
- const auto host = GetWindowHost();
- const auto old_child = child_;
- child_ = child;
- if (old_child) {
- old_child->_SetParent(nullptr);
- old_child->_SetDescendantWindowHost(nullptr);
+ Control* old_child = nullptr;
+ if (!GetChildren().empty()) {
+ old_child = GetChildren()[0];
+ this->RemoveChild(0);
}
if (child) {
- child->_SetParent(this);
- child->_SetDescendantWindowHost(host);
+ this->AddChild(child, 0);
}
OnChildChanged(old_child, child);
}
diff --git a/src/ui/Control.cpp b/src/ui/Control.cpp
index cd7ed0dc..13b1c780 100644
--- a/src/ui/Control.cpp
+++ b/src/ui/Control.cpp
@@ -1,10 +1,12 @@
#include "cru/ui/Control.hpp"
+#include "RoutedEventDispatch.hpp"
+#include "cru/common/Base.hpp"
#include "cru/platform/native/Cursor.hpp"
#include "cru/platform/native/UiApplication.hpp"
#include "cru/ui/Base.hpp"
#include "cru/ui/WindowHost.hpp"
-#include "RoutedEventDispatch.hpp"
+#include "cru/ui/render/RenderObject.hpp"
#include <memory>
@@ -25,49 +27,16 @@ Control::Control() {
});
}
-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);
+Control::~Control() {
+ for (const auto child : children_) delete child;
}
-void Control::_SetDescendantWindowHost(WindowHost* 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);
- });
-}
+WindowHost* Control::GetWindowHost() const { return window_host_; }
void Control::TraverseDescendants(
const std::function<void(Control*)>& predicate) {
- _TraverseDescendants(this, predicate);
-}
-
-void Control::_TraverseDescendants(
- Control* control, const std::function<void(Control*)>& predicate) {
- predicate(control);
- for (auto c : control->GetChildren()) _TraverseDescendants(c, predicate);
-}
-
-bool Control::RequestFocus() {
- auto host = GetWindowHost();
- if (host == nullptr) return false;
-
- return host->RequestFocusFor(this);
+ predicate(this);
+ for (auto c : GetChildren()) c->TraverseDescendants(predicate);
}
bool Control::HasFocus() {
@@ -84,6 +53,13 @@ bool Control::CaptureMouse() {
return host->CaptureMouseFor(this);
}
+void Control::SetFocus() {
+ auto host = GetWindowHost();
+ if (host == nullptr) return;
+
+ host->SetFocusControl(this);
+}
+
bool Control::ReleaseMouse() {
auto host = GetWindowHost();
if (host == nullptr) return false;
@@ -119,6 +95,58 @@ void Control::SetCursor(std::shared_ptr<ICursor> cursor) {
}
}
+void Control::AddChild(Control* control, const Index position) {
+ Expects(control->GetParent() ==
+ nullptr); // The control already has a parent.
+ Expects(position >= 0);
+ Expects(position <= static_cast<Index>(
+ children_.size())); // The position is out of range.
+
+ children_.insert(children_.cbegin() + position, control);
+
+ const auto old_parent = control->parent_;
+ control->parent_ = this;
+
+ OnAddChild(control, position);
+ control->OnParentChanged(old_parent, this);
+
+ if (window_host_)
+ control->TraverseDescendants([this](Control* control) {
+ control->window_host_ = window_host_;
+ control->OnAttachToHost(window_host_);
+ });
+}
+
+void Control::RemoveChild(const Index position) {
+ Expects(position >= 0);
+ Expects(position < static_cast<Index>(
+ children_.size())); // The position is out of range.
+
+ const auto i = children_.cbegin() + position;
+ const auto control = *i;
+
+ children_.erase(i);
+ control->parent_ = nullptr;
+
+ OnRemoveChild(control, position);
+ control->OnParentChanged(this, nullptr);
+
+ if (window_host_)
+ control->TraverseDescendants([this](Control* control) {
+ control->window_host_ = nullptr;
+ control->OnDetachFromHost(window_host_);
+ });
+}
+
+void Control::OnAddChild(Control* child, Index position) {
+ CRU_UNUSED(child)
+ CRU_UNUSED(position)
+}
+void Control::OnRemoveChild(Control* child, Index position) {
+ CRU_UNUSED(child)
+ CRU_UNUSED(position)
+}
+
void Control::OnParentChanged(Control* old_parent, Control* new_parent) {
CRU_UNUSED(old_parent)
CRU_UNUSED(new_parent)
diff --git a/src/ui/LayoutControl.cpp b/src/ui/LayoutControl.cpp
index 05fcdc4a..351026f9 100644
--- a/src/ui/LayoutControl.cpp
+++ b/src/ui/LayoutControl.cpp
@@ -3,51 +3,4 @@
#include "cru/ui/Window.hpp"
namespace cru::ui {
-LayoutControl::~LayoutControl() {
- for (const auto child : children_) delete child;
-}
-
-void LayoutControl::AddChild(Control* control, const Index position) {
- Expects(control->GetParent() ==
- nullptr); // The control already has a parent.
- Expects(!dynamic_cast<Window*>(control)); // Can't add a window as child.
- Expects(position >= 0);
- Expects(position <=
- static_cast<Index>(
- this->children_.size())); // The position is out of range.
-
- children_.insert(this->children_.cbegin() + position, control);
-
- control->_SetParent(this);
- control->_SetDescendantWindowHost(GetWindowHost());
-
- OnAddChild(control, position);
-}
-
-void LayoutControl::RemoveChild(const Index position) {
- Expects(position >= 0);
- Expects(position <
- static_cast<Index>(
- this->children_.size())); // The position is out of range.
-
- const auto i = children_.cbegin() + position;
- const auto child = *i;
-
- children_.erase(i);
-
- child->_SetParent(nullptr);
- child->_SetDescendantWindowHost(nullptr);
-
- OnRemoveChild(child, position);
-}
-
-void LayoutControl::OnAddChild(Control* child, const Index position) {
- CRU_UNUSED(child)
- CRU_UNUSED(position)
-}
-
-void LayoutControl::OnRemoveChild(Control* child, const Index position) {
- CRU_UNUSED(child)
- CRU_UNUSED(position)
-}
} // namespace cru::ui
diff --git a/src/ui/NoChildControl.cpp b/src/ui/NoChildControl.cpp
index 86861049..8adbe3bc 100644
--- a/src/ui/NoChildControl.cpp
+++ b/src/ui/NoChildControl.cpp
@@ -1,5 +1,3 @@
#include "cru/ui/NoChildControl.hpp"
-namespace cru::ui {
-const std::vector<Control*> NoChildControl::empty_control_vector{};
-}
+namespace cru::ui {}
diff --git a/src/ui/Window.cpp b/src/ui/Window.cpp
index a8cb315b..6d507858 100644
--- a/src/ui/Window.cpp
+++ b/src/ui/Window.cpp
@@ -1,28 +1,31 @@
#include "cru/ui/Window.hpp"
-#include "cru/ui/render/WindowRenderObject.hpp"
+#include "cru/common/Base.hpp"
#include "cru/ui/WindowHost.hpp"
+#include "cru/ui/render/Base.hpp"
+#include "cru/ui/render/StackLayoutRenderObject.hpp"
namespace cru::ui {
-Window* Window::CreateOverlapped() {
- return new Window(tag_overlapped_constructor{});
-}
+Window* Window::CreateOverlapped() { return new Window(); }
-Window::Window(tag_overlapped_constructor) {
- managed_ui_host_ = std::make_unique<WindowHost>(this);
+Window::Window() : render_object_(new render::StackLayoutRenderObject()) {
+ window_host_ = std::make_unique<WindowHost>(this);
}
-Window::~Window() {
- // explicit destroy ui host first.
- managed_ui_host_.reset();
-}
+Window::~Window() {}
std::u16string_view Window::GetControlType() const { return control_type; }
-render::RenderObject* Window::GetRenderObject() const { return render_object_; }
+render::RenderObject* Window::GetRenderObject() const {
+ return render_object_.get();
+}
+
+void Window::OnAddChild(Control* child, Index position) {
+ render_object_->AddChild(child->GetRenderObject(), position);
+}
-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);
+void Window::OnRemoveChild(Control* child, Index position) {
+ CRU_UNUSED(child);
+ render_object_->RemoveChild(position);
}
} // namespace cru::ui
diff --git a/src/ui/WindowHost.cpp b/src/ui/WindowHost.cpp
index d3dec422..1dba4404 100644
--- a/src/ui/WindowHost.cpp
+++ b/src/ui/WindowHost.cpp
@@ -9,7 +9,9 @@
#include "cru/ui/DebugFlags.hpp"
#include "cru/ui/Window.hpp"
#include "cru/ui/render/MeasureRequirement.hpp"
-#include "cru/ui/render/WindowRenderObject.hpp"
+#include "cru/ui/render/RenderObject.hpp"
+
+#include <cstddef>
namespace cru::ui {
using platform::native::INativeWindow;
@@ -97,25 +99,18 @@ inline void BindNativeEvent(
}
} // namespace
-WindowHost::WindowHost(Window* window)
- : window_control_(window),
- mouse_hover_control_(nullptr),
- focus_control_(window),
- mouse_captured_control_(nullptr) {
+WindowHost::WindowHost(Control* root_control) : root_control_(root_control) {
const auto ui_application = IUiApplication::GetInstance();
- native_window_resolver_ = ui_application->CreateWindow(nullptr);
-
- const auto native_window = native_window_resolver_->Resolve();
-
- auto input_method_context =
- ui_application->GetInputMethodManager()->GetContext(native_window);
- input_method_context->DisableIME();
+ auto native_window = ui_application->CreateWindow(nullptr);
+ native_window_ = native_window;
- window->ui_host_ = this;
+ root_control_->TraverseDescendants([this](Control* control) {
+ control->window_host_ = this;
+ control->OnAttachToHost(this);
+ });
- root_render_object_ = std::make_unique<render::WindowRenderObject>(this);
- root_render_object_->SetAttachedControl(window);
- window->render_object_ = root_render_object_.get();
+ root_render_object_ = root_control->GetRenderObject();
+ root_render_object_->SetWindowHostRecursive(this);
BindNativeEvent(this, native_window, native_window->DestroyEvent(),
&WindowHost::OnNativeDestroy, event_revoker_guards_);
@@ -140,34 +135,24 @@ WindowHost::WindowHost(Window* window)
}
WindowHost::~WindowHost() {
- deleting_ = true;
- window_control_->TraverseDescendants(
- [this](Control* control) { control->OnDetachFromHost(this); });
- if (!native_window_destroyed_) {
- const auto native_window = native_window_resolver_->Resolve();
- if (native_window) {
- native_window->Close();
- }
+ if (native_window_) {
+ native_window_->Close();
}
}
void WindowHost::InvalidatePaint() {
- if (const auto native_window = native_window_resolver_->Resolve())
- native_window->RequestRepaint();
+ if (native_window_) native_window_->RequestRepaint();
}
void WindowHost::InvalidateLayout() {
if constexpr (debug_flags::layout)
log::TagDebug(log_tag, u"A relayout is requested.");
if (!need_layout_) {
- platform::native::IUiApplication::GetInstance()->SetImmediate(
- [resolver = this->CreateResolver()] {
- if (const auto host = resolver.Resolve()) {
- host->Relayout();
- host->need_layout_ = false;
- host->InvalidatePaint();
- }
- });
+ platform::native::IUiApplication::GetInstance()->SetImmediate([this] {
+ Relayout();
+ need_layout_ = false;
+ InvalidatePaint();
+ });
need_layout_ = true;
}
}
@@ -183,15 +168,17 @@ void WindowHost::SetLayoutPreferToFillWindow(bool value) {
}
void WindowHost::Relayout() {
- const auto native_window = native_window_resolver_->Resolve();
- const auto client_size = native_window
- ? native_window->GetClientSize()
- : Size{100, 100}; // a reasonable assumed size
+ const auto available_size =
+ native_window_ ? native_window_->GetClientSize()
+ : Size{100, 100}; // a reasonable assumed size
+ Relayout(available_size);
+}
+void WindowHost::Relayout(const Size& available_size) {
root_render_object_->Measure(
- render::MeasureRequirement{client_size,
+ render::MeasureRequirement{available_size,
IsLayoutPreferToFillWindow()
- ? render::MeasureSize(client_size)
+ ? render::MeasureSize(available_size)
: render::MeasureSize::NotSpecified()},
render::MeasureSize::NotSpecified());
root_render_object_->Layout(Point{});
@@ -202,11 +189,11 @@ void WindowHost::Relayout() {
log::TagDebug(log_tag, u"A relayout is finished.");
}
-bool WindowHost::RequestFocusFor(Control* control) {
- Expects(control != nullptr); // The control to request focus can't be null.
- // You can set it as the window.
+Control* WindowHost::GetFocusControl() { return focus_control_; }
- if (focus_control_ == control) return true;
+void WindowHost::SetFocusControl(Control* control) {
+ if (focus_control_ == control) return;
+ if (control == nullptr) control = root_control_;
const auto old_focus_control = focus_control_;
@@ -217,15 +204,10 @@ bool WindowHost::RequestFocusFor(Control* control) {
DispatchEvent(event_names::GainFocus, control, &Control::GainFocusEvent,
nullptr, false);
-
- return true;
}
-Control* WindowHost::GetFocusControl() { return focus_control_; }
-
bool WindowHost::CaptureMouseFor(Control* control) {
- const auto native_window = native_window_resolver_->Resolve();
- if (!native_window) return false;
+ if (!native_window_) return false;
if (control == mouse_captured_control_) return true;
@@ -236,7 +218,7 @@ bool WindowHost::CaptureMouseFor(Control* control) {
if (old_capture_control != mouse_hover_control_) {
DispatchMouseHoverControlChangeEvent(
old_capture_control, mouse_hover_control_,
- native_window->GetMousePosition(), true, false);
+ native_window_->GetMousePosition(), true, false);
}
UpdateCursor();
return true;
@@ -247,7 +229,7 @@ bool WindowHost::CaptureMouseFor(Control* control) {
mouse_captured_control_ = control;
DispatchMouseHoverControlChangeEvent(
mouse_hover_control_, mouse_captured_control_,
- native_window->GetMousePosition(), false, true);
+ native_window_->GetMousePosition(), false, true);
UpdateCursor();
return true;
}
@@ -266,8 +248,8 @@ void WindowHost::RunAfterLayoutStable(std::function<void()> action) {
void WindowHost::OnNativeDestroy(INativeWindow* window, std::nullptr_t) {
CRU_UNUSED(window)
- native_window_destroyed_ = true;
- if (!deleting_ && !retain_after_destroy_) delete window_control_;
+ this->relayout_timer_canceler_.Reset();
+ this->native_window_ = nullptr;
}
void WindowHost::OnNativePaint(INativeWindow* window, std::nullptr_t) {
@@ -399,9 +381,9 @@ void WindowHost::DispatchMouseHoverControlChangeEvent(Control* old_control,
}
void WindowHost::UpdateCursor() {
- if (const auto native_window = native_window_resolver_->Resolve()) {
+ if (native_window_) {
const auto capture = GetMouseCaptureControl();
- native_window->SetCursor(
+ native_window_->SetCursor(
(capture ? capture : GetMouseHoverControl())->GetInheritedCursor());
}
}
@@ -413,6 +395,6 @@ Control* WindowHost::HitTest(const Point& point) {
Ensures(control);
return control;
}
- return window_control_;
+ return root_control_;
}
} // namespace cru::ui
diff --git a/src/ui/controls/TextControlService.hpp b/src/ui/controls/TextControlService.hpp
index 8c1bd32f..33a6bc36 100644
--- a/src/ui/controls/TextControlService.hpp
+++ b/src/ui/controls/TextControlService.hpp
@@ -61,7 +61,7 @@ class TextControlService : public Object {
void SetEditable(bool editable) {
this->editable_ = editable;
- this->input_method_context_.reset();
+ if (!editable) CancelComposition();
}
std::u16string GetText() { return this->text_; }
@@ -69,8 +69,8 @@ class TextControlService : public Object {
void SetText(std::u16string text, bool stop_composition = false) {
this->text_ = std::move(text);
CoerceSelection();
- if (stop_composition && this->input_method_context_) {
- this->input_method_context_->CancelComposition();
+ if (stop_composition) {
+ CancelComposition();
}
SyncTextRenderObject();
}
@@ -83,8 +83,8 @@ class TextControlService : public Object {
}
this->text_.insert(this->text_.cbegin() + position, text.begin(),
text.end());
- if (stop_composition && this->input_method_context_) {
- this->input_method_context_->CancelComposition();
+ if (stop_composition) {
+ CancelComposition();
}
SyncTextRenderObject();
}
@@ -129,15 +129,30 @@ class TextControlService : public Object {
this->text_.erase(this->text_.cbegin() + range.GetStart(),
this->text_.cbegin() + range.GetEnd());
this->CoerceSelection();
- if (stop_composition && this->input_method_context_) {
- this->input_method_context_->CancelComposition();
+ if (stop_composition) {
+ CancelComposition();
}
this->SyncTextRenderObject();
}
+ platform::native::IInputMethodContext* GetInputMethodContext() {
+ WindowHost* host = this->control_->GetWindowHost();
+ if (!host) return nullptr;
+ platform::native::INativeWindow* native_window = host->GetNativeWindow();
+ if (!native_window) return nullptr;
+ return native_window->GetInputMethodContext();
+ }
+
+ void CancelComposition() {
+ auto input_method_context = GetInputMethodContext();
+ if (input_method_context == nullptr) return;
+ input_method_context->CancelComposition();
+ }
+
std::optional<platform::native::CompositionText> GetCompositionInfo() {
- if (this->input_method_context_ == nullptr) return std::nullopt;
- auto composition_info = this->input_method_context_->GetCompositionText();
+ auto input_method_context = GetInputMethodContext();
+ if (input_method_context == nullptr) return std::nullopt;
+ auto composition_info = input_method_context->GetCompositionText();
if (composition_info.text.empty()) return std::nullopt;
return composition_info;
}
@@ -319,12 +334,11 @@ class TextControlService : public Object {
}
void MouseDownHandler(event::MouseButtonEventArgs& args) {
- this->control_->RequestFocus();
if (this->select_down_button_.has_value()) {
return;
} else {
+ this->control_->SetFocus();
if (!this->control_->CaptureMouse()) return;
- if (!this->control_->RequestFocus()) return;
const auto text_render_object = this->GetTextRenderObject();
this->select_down_button_ = args.GetButton();
const auto result = text_render_object->TextHitTest(
@@ -408,33 +422,35 @@ class TextControlService : public Object {
void GainFocusHandler(event::FocusChangeEventArgs& args) {
CRU_UNUSED(args);
if (editable_) {
- WindowHost* ui_host = this->control_->GetWindowHost();
- auto window = ui_host->GetNativeWindowResolver()->Resolve();
- if (window == nullptr) return;
- input_method_context_ =
- GetUiApplication()->GetInputMethodManager()->GetContext(window);
- input_method_context_->EnableIME();
+ auto input_method_context = GetInputMethodContext();
+ if (input_method_context == nullptr) return;
+ input_method_context->EnableIME();
auto sync = [this](std::nullptr_t) {
this->SyncTextRenderObject();
ScrollToCaret();
};
- input_method_context_->CompositionStartEvent()->AddHandler(
- [this](std::nullptr_t) { this->DeleteSelectedText(); });
- input_method_context_->CompositionEvent()->AddHandler(sync);
- input_method_context_->CompositionEndEvent()->AddHandler(sync);
- input_method_context_->TextEvent()->AddHandler(
- [this](const std::u16string_view& text) {
- if (text == u"\b") return;
- this->ReplaceSelectedText(text);
- });
+ input_method_context_event_guard_ +=
+ input_method_context->CompositionStartEvent()->AddHandler(
+ [this](std::nullptr_t) { this->DeleteSelectedText(); });
+ input_method_context_event_guard_ +=
+ input_method_context->CompositionEvent()->AddHandler(sync);
+ input_method_context_event_guard_ +=
+ input_method_context->CompositionEndEvent()->AddHandler(sync);
+ input_method_context_event_guard_ +=
+ input_method_context->TextEvent()->AddHandler(
+ [this](const std::u16string_view& text) {
+ if (text == u"\b") return;
+ this->ReplaceSelectedText(text);
+ });
}
}
void LoseFocusHandler(event::FocusChangeEventArgs& args) {
if (!args.IsWindow()) this->AbortSelection();
- if (input_method_context_) {
- input_method_context_->DisableIME();
- input_method_context_.reset();
+ input_method_context_event_guard_.Clear();
+ auto input_method_context = GetInputMethodContext();
+ if (input_method_context) {
+ input_method_context->DisableIME();
}
SyncTextRenderObject();
}
@@ -442,6 +458,7 @@ class TextControlService : public Object {
private:
gsl::not_null<TControl*> control_;
EventRevokerListGuard event_guard_;
+ EventRevokerListGuard input_method_context_event_guard_;
std::u16string text_;
TextRange selection_;
@@ -457,7 +474,5 @@ class TextControlService : public Object {
// nullopt means not selecting
std::optional<MouseButton> select_down_button_;
-
- std::unique_ptr<platform::native::IInputMethodContext> input_method_context_;
}; // namespace cru::ui::controls
} // namespace cru::ui::controls
diff --git a/src/ui/render/RenderObject.cpp b/src/ui/render/RenderObject.cpp
index 5266daaf..fd0c7712 100644
--- a/src/ui/render/RenderObject.cpp
+++ b/src/ui/render/RenderObject.cpp
@@ -24,7 +24,7 @@ void RenderObject::AddChild(RenderObject* render_object, const Index position) {
children_.insert(children_.cbegin() + position, render_object);
render_object->SetParent(this);
- render_object->SetRenderHostRecursive(GetWindowHost());
+ render_object->SetWindowHostRecursive(GetWindowHost());
OnAddChild(render_object, position);
}
@@ -37,7 +37,7 @@ void RenderObject::RemoveChild(const Index position) {
const auto removed_child = *i;
children_.erase(i);
removed_child->SetParent(nullptr);
- removed_child->SetRenderHostRecursive(nullptr);
+ removed_child->SetWindowHostRecursive(nullptr);
OnRemoveChild(removed_child, position);
}
@@ -269,11 +269,11 @@ void RenderObject::SetParent(RenderObject* new_parent) {
}
void RenderObject::InvalidateLayout() {
- if (ui_host_ != nullptr) ui_host_->InvalidateLayout();
+ if (window_host_ != nullptr) window_host_->InvalidateLayout();
}
void RenderObject::InvalidatePaint() {
- if (ui_host_ != nullptr) ui_host_->InvalidatePaint();
+ if (window_host_ != nullptr) window_host_->InvalidatePaint();
}
constexpr std::u16string_view kUnamedName(u"UNNAMED");
@@ -297,17 +297,16 @@ std::u16string RenderObject::GetDebugPathInTree() const {
return result;
}
-void RenderObject::NotifyAfterLayoutRecursive(RenderObject* render_object) {
- render_object->OnAfterLayout();
- for (const auto o : render_object->GetChildren()) {
- NotifyAfterLayoutRecursive(o);
+void RenderObject::SetWindowHostRecursive(WindowHost* host) {
+ if (window_host_ != nullptr) {
+ detach_from_host_event_.Raise(nullptr);
+ }
+ window_host_ = host;
+ if (host != nullptr) {
+ attach_to_host_event_.Raise(nullptr);
}
-}
-
-void RenderObject::SetRenderHostRecursive(WindowHost* host) {
- ui_host_ = host;
for (const auto child : GetChildren()) {
- child->SetRenderHostRecursive(host);
+ child->SetWindowHostRecursive(host);
}
}
} // namespace cru::ui::render
diff --git a/src/ui/render/WindowRenderObject.cpp b/src/ui/render/WindowRenderObject.cpp
deleted file mode 100644
index 23cca12e..00000000
--- a/src/ui/render/WindowRenderObject.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "cru/ui/render/WindowRenderObject.hpp"
-
-#include "../Helper.hpp"
-#include "cru/platform/graph/util/Painter.hpp"
-#include "cru/ui/WindowHost.hpp"
-
-namespace cru::ui::render {
-WindowRenderObject::WindowRenderObject(WindowHost* host) {
- SetChildMode(ChildMode::Single);
- ui_host_ = host;
- after_layout_event_guard_.Reset(host->AfterLayoutEvent()->AddHandler(
- [this](auto) { NotifyAfterLayoutRecursive(this); }));
-}
-
-RenderObject* WindowRenderObject::HitTest(const Point& point) {
- if (const auto child = GetChild()) {
- auto offset = child->GetOffset();
- Point p{point.x - offset.x, point.y - offset.y};
- const auto result = child->HitTest(p);
- if (result != nullptr) {
- return result;
- }
- }
- return Rect{Point{}, GetSize()}.IsPointInside(point) ? this : nullptr;
-}
-
-std::u16string_view WindowRenderObject::GetName() const {
- return u"WindowRenderObject";
-}
-
-Size WindowRenderObject::OnMeasureContent(const MeasureRequirement& requirement,
- const MeasureSize& preferred_size) {
- if (const auto child = GetChild()) {
- child->Measure(requirement, preferred_size);
- return child->GetSize();
- } else {
- return Size{};
- }
-}
-
-void WindowRenderObject::OnLayoutContent(const Rect& content_rect) {
- if (const auto child = GetChild()) child->Layout(content_rect.GetLeftTop());
-}
-} // namespace cru::ui::render
diff --git a/src/win/native/UiApplication.cpp b/src/win/native/UiApplication.cpp
index 60ff8e8c..87ef0b81 100644
--- a/src/win/native/UiApplication.cpp
+++ b/src/win/native/UiApplication.cpp
@@ -43,7 +43,6 @@ WinUiApplication::WinUiApplication() {
timer_manager_ = std::make_unique<TimerManager>(god_window_.get());
window_manager_ = std::make_unique<WindowManager>(this);
cursor_manager_ = std::make_unique<WinCursorManager>();
- input_method_manager_ = std::make_unique<WinInputMethodManager>(this);
}
WinUiApplication::~WinUiApplication() { instance = nullptr; }
@@ -116,8 +115,4 @@ cru::platform::graph::IGraphFactory* WinUiApplication::GetGraphFactory() {
ICursorManager* WinUiApplication::GetCursorManager() {
return cursor_manager_.get();
}
-
-IInputMethodManager* WinUiApplication::GetInputMethodManager() {
- return input_method_manager_.get();
-}
} // namespace cru::platform::native::win
diff --git a/src/win/native/Window.cpp b/src/win/native/Window.cpp
index d9237c4f..1a6fcb07 100644
--- a/src/win/native/Window.cpp
+++ b/src/win/native/Window.cpp
@@ -55,6 +55,7 @@ WinNativeWindow::WinNativeWindow(WinUiApplication* application,
window_render_target_->SetDpi(dpi_, dpi_);
input_method_context_ = std::make_unique<WinInputMethodContext>(this);
+ input_method_context_->DisableIME();
}
WinNativeWindow::~WinNativeWindow() {