aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/main/main.cpp2
-rw-r--r--include/cru/ui/controls/Window.hpp8
-rw-r--r--include/cru/ui/host/WindowHost.hpp13
-rw-r--r--src/ui/controls/Popup.cpp5
-rw-r--r--src/ui/controls/Window.cpp15
-rw-r--r--src/ui/host/WindowHost.cpp31
6 files changed, 48 insertions, 26 deletions
diff --git a/demos/main/main.cpp b/demos/main/main.cpp
index dd3e31e9..2d5939f1 100644
--- a/demos/main/main.cpp
+++ b/demos/main/main.cpp
@@ -45,7 +45,7 @@ int main() {
const auto text_box = TextBox::Create();
flex_layout->AddChild(text_box, 2);
- window->GetWindowHost()->GetNativeWindow()->SetVisible(true);
+ window->Show();
return application->Run();
}
diff --git a/include/cru/ui/controls/Window.hpp b/include/cru/ui/controls/Window.hpp
index 616e2ee7..996bc75e 100644
--- a/include/cru/ui/controls/Window.hpp
+++ b/include/cru/ui/controls/Window.hpp
@@ -24,13 +24,13 @@ class Window final : public LayoutControl {
render::RenderObject* GetRenderObject() const override;
- protected:
- void OnAddChild(Control* child, Index position) override;
- void OnRemoveChild(Control* child, Index position) override;
+ // If create is false and native window is not create, it will not be created
+ // and shown.
+ void Show(bool create = true);
private:
std::unique_ptr<host::WindowHost> window_host_;
std::unique_ptr<render::StackLayoutRenderObject> render_object_;
};
-} // namespace cru::ui
+} // namespace cru::ui::controls
diff --git a/include/cru/ui/host/WindowHost.hpp b/include/cru/ui/host/WindowHost.hpp
index 6d338df1..9fc24eb2 100644
--- a/include/cru/ui/host/WindowHost.hpp
+++ b/include/cru/ui/host/WindowHost.hpp
@@ -28,8 +28,7 @@ class WindowHost : public Object {
CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::host::WindowHost")
public:
- WindowHost(controls::Control* root_control,
- CreateWindowParams create_window_params = {});
+ WindowHost(controls::Control* root_control);
CRU_DELETE_COPY(WindowHost)
CRU_DELETE_MOVE(WindowHost)
@@ -39,6 +38,10 @@ class WindowHost : public Object {
public:
platform::gui::INativeWindow* GetNativeWindow() { return native_window_; }
+ // Do nothing if native window is already created.
+ gsl::not_null<platform::gui::INativeWindow*> CreateNativeWindow(
+ CreateWindowParams create_window_params = {});
+
// Mark the layout as invalid, and arrange a re-layout later.
// This method could be called more than one times in a message cycle. But
// layout only takes place once.
@@ -102,6 +105,10 @@ class WindowHost : public Object {
void UpdateCursor();
+ IEvent<platform::gui::INativeWindow*>* NativeWindowChangeEvent() {
+ return &native_window_change_event_;
+ }
+
private:
//*************** region: native messages ***************
void OnNativeDestroy(platform::gui::INativeWindow* window, std::nullptr_t);
@@ -152,5 +159,7 @@ class WindowHost : public Object {
controls::Control* mouse_captured_control_ = nullptr;
bool layout_prefer_to_fill_window_ = true;
+
+ Event<platform::gui::INativeWindow*> native_window_change_event_;
};
} // namespace cru::ui::host
diff --git a/src/ui/controls/Popup.cpp b/src/ui/controls/Popup.cpp
index f51f2b3b..982aee38 100644
--- a/src/ui/controls/Popup.cpp
+++ b/src/ui/controls/Popup.cpp
@@ -9,11 +9,10 @@
namespace cru::ui::controls {
Popup::Popup(Control* attached_control) : attached_control_(attached_control) {
render_object_ = std::make_unique<render::StackLayoutRenderObject>();
+ render_object_->SetAttachedControl(this);
SetContainerRenderObject(render_object_.get());
- window_host_ = std::make_unique<host::WindowHost>(
- this, host::CreateWindowParams(
- nullptr, platform::gui::CreateWindowFlags::NoCaptionAndBorder));
+ window_host_ = std::make_unique<host::WindowHost>(this);
}
Popup::~Popup() = default;
diff --git a/src/ui/controls/Window.cpp b/src/ui/controls/Window.cpp
index 7ce40dfe..b302cb62 100644
--- a/src/ui/controls/Window.cpp
+++ b/src/ui/controls/Window.cpp
@@ -1,6 +1,7 @@
#include "cru/ui/controls/Window.hpp"
#include "cru/common/Base.hpp"
+#include "cru/platform/gui/Base.hpp"
#include "cru/ui/host/WindowHost.hpp"
#include "cru/ui/render/Base.hpp"
#include "cru/ui/render/StackLayoutRenderObject.hpp"
@@ -10,6 +11,7 @@ Window* Window::CreateOverlapped() { return new Window(); }
Window::Window() : render_object_(new render::StackLayoutRenderObject()) {
render_object_->SetAttachedControl(this);
+ SetContainerRenderObject(render_object_.get());
window_host_ = std::make_unique<host::WindowHost>(this);
}
@@ -21,12 +23,11 @@ render::RenderObject* Window::GetRenderObject() const {
return render_object_.get();
}
-void Window::OnAddChild(Control* child, Index position) {
- render_object_->AddChild(child->GetRenderObject(), position);
-}
-
-void Window::OnRemoveChild(Control* child, Index position) {
- CRU_UNUSED(child);
- render_object_->RemoveChild(position);
+void Window::Show(bool create) {
+ platform::gui::INativeWindow* native_window =
+ create ? window_host_->CreateNativeWindow().get()
+ : window_host_->GetNativeWindow();
+ if (!native_window) return;
+ native_window->SetVisible(true);
}
} // namespace cru::ui::controls
diff --git a/src/ui/host/WindowHost.cpp b/src/ui/host/WindowHost.cpp
index 95de51c2..4bd981c2 100644
--- a/src/ui/host/WindowHost.cpp
+++ b/src/ui/host/WindowHost.cpp
@@ -103,14 +103,8 @@ inline void BindNativeEvent(
}
} // namespace
-WindowHost::WindowHost(controls::Control* root_control,
- CreateWindowParams create_window_params)
+WindowHost::WindowHost(controls::Control* root_control)
: root_control_(root_control), focus_control_(root_control) {
- const auto ui_application = IUiApplication::GetInstance();
- auto native_window = ui_application->CreateWindow(create_window_params.parent,
- create_window_params.flag);
- native_window_ = native_window;
-
root_control_->TraverseDescendants([this](controls::Control* control) {
control->window_host_ = this;
control->OnAttachToHost(this);
@@ -120,6 +114,20 @@ WindowHost::WindowHost(controls::Control* root_control,
root_render_object_->SetWindowHostRecursive(this);
this->layout_paint_cycler_ = std::make_unique<LayoutPaintCycler>(this);
+}
+
+WindowHost::~WindowHost() {}
+
+gsl::not_null<platform::gui::INativeWindow*> WindowHost::CreateNativeWindow(
+ CreateWindowParams create_window_params) {
+ if (native_window_ != nullptr) return native_window_;
+
+ const auto ui_application = IUiApplication::GetInstance();
+
+ auto native_window = ui_application->CreateWindow(create_window_params.parent,
+ create_window_params.flag);
+
+ native_window_ = native_window;
BindNativeEvent(this, native_window, native_window->DestroyEvent(),
&WindowHost::OnNativeDestroy, event_revoker_guards_);
@@ -141,9 +149,11 @@ WindowHost::WindowHost(controls::Control* root_control,
&WindowHost::OnNativeKeyDown, event_revoker_guards_);
BindNativeEvent(this, native_window, native_window->KeyUpEvent(),
&WindowHost::OnNativeKeyUp, event_revoker_guards_);
-}
-WindowHost::~WindowHost() {}
+ native_window_change_event_.Raise(native_window);
+
+ return native_window_;
+}
void WindowHost::InvalidatePaint() { layout_paint_cycler_->InvalidatePaint(); }
@@ -254,6 +264,9 @@ void WindowHost::RunAfterLayoutStable(std::function<void()> action) {
void WindowHost::OnNativeDestroy(INativeWindow* window, std::nullptr_t) {
CRU_UNUSED(window)
this->native_window_ = nullptr;
+ event_revoker_guards_.clear();
+
+ native_window_change_event_.Raise(nullptr);
}
void WindowHost::OnNativePaint(INativeWindow* window, std::nullptr_t) {