aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-11-19 02:59:30 +0800
committerYuqian Yang <crupest@crupest.life>2025-11-19 02:59:30 +0800
commit2eb34dfc3dd3ca718da6ebf049886b4ae140b332 (patch)
treec43dbca6e6898fd474ca9b976b4bf21b3419e512
parentdf2dadbd0f0ace6e02281c84218537ec2ce5c47f (diff)
downloadcru-2eb34dfc3dd3ca718da6ebf049886b4ae140b332.tar.gz
cru-2eb34dfc3dd3ca718da6ebf049886b4ae140b332.tar.bz2
cru-2eb34dfc3dd3ca718da6ebf049886b4ae140b332.zip
Remove all children when control destroyed.
-rw-r--r--include/cru/ui/components/Menu.h4
-rw-r--r--include/cru/ui/controls/ControlHost.h4
-rw-r--r--include/cru/ui/controls/Window.h5
-rw-r--r--src/platform/gui/win/Window.cpp10
-rw-r--r--src/ui/components/Menu.cpp6
-rw-r--r--src/ui/controls/Control.cpp10
-rw-r--r--src/ui/controls/ControlHost.cpp15
7 files changed, 26 insertions, 28 deletions
diff --git a/include/cru/ui/components/Menu.h b/include/cru/ui/components/Menu.h
index 92731f2e..a8a90ed7 100644
--- a/include/cru/ui/components/Menu.h
+++ b/include/cru/ui/components/Menu.h
@@ -70,7 +70,7 @@ class CRU_UI_API PopupMenu : public Component {
public:
controls::Control* GetRootControl() override;
- controls::Window* GetPopup() { return popup_; }
+ controls::Window* GetPopup() { return popup_.get(); }
Menu* GetMenu() { return &menu_; }
// position relative to screen left top.
@@ -86,7 +86,7 @@ class CRU_UI_API PopupMenu : public Component {
private:
controls::Control* attached_control_;
- controls::Window* popup_;
+ std::unique_ptr<controls::Window> popup_;
Menu menu_;
};
} // namespace cru::ui::components
diff --git a/include/cru/ui/controls/ControlHost.h b/include/cru/ui/controls/ControlHost.h
index c67e8a72..a27be835 100644
--- a/include/cru/ui/controls/ControlHost.h
+++ b/include/cru/ui/controls/ControlHost.h
@@ -169,7 +169,8 @@ class CRU_UI_API ControlHost : public Object {
}
void UpdateCursor();
- void NotifyControlParentChange(Control* control, Control* old_parent, Control* new_parent);
+ void NotifyControlParentChange(Control* control, Control* old_parent,
+ Control* new_parent);
private:
int event_handling_count_;
@@ -185,7 +186,6 @@ class CRU_UI_API ControlHost : public Object {
bool layout_prefer_to_fill_window_;
- platform::gui::TimerAutoCanceler repaint_schedule_canceler_;
platform::gui::TimerAutoCanceler relayout_schedule_canceler_;
};
} // namespace cru::ui::controls
diff --git a/include/cru/ui/controls/Window.h b/include/cru/ui/controls/Window.h
index a2ae01f9..3d3ff0b0 100644
--- a/include/cru/ui/controls/Window.h
+++ b/include/cru/ui/controls/Window.h
@@ -1,5 +1,6 @@
#pragma once
#include "../render/StackLayoutRenderObject.h"
+#include "ControlHost.h"
#include "LayoutControl.h"
#include <cru/base/Base.h>
@@ -9,6 +10,8 @@
#include <cru/platform/gui/UiApplication.h>
#include <cru/platform/gui/Window.h>
+#include <memory>
+
namespace cru::ui::controls {
class CRU_UI_API Window
: public LayoutControl<render::StackLayoutRenderObject> {
@@ -31,7 +34,7 @@ class CRU_UI_API Window
void SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value);
private:
- std::shared_ptr<ControlHost> control_host_;
+ std::unique_ptr<ControlHost> control_host_;
Control* attached_control_;
diff --git a/src/platform/gui/win/Window.cpp b/src/platform/gui/win/Window.cpp
index 02357336..eb5112f5 100644
--- a/src/platform/gui/win/Window.cpp
+++ b/src/platform/gui/win/Window.cpp
@@ -4,7 +4,6 @@
#include "cru/base/log/Logger.h"
#include "cru/platform/graphics/NullPainter.h"
#include "cru/platform/graphics/direct2d/WindowPainter.h"
-#include "cru/platform/gui/DebugFlags.h"
#include "cru/platform/gui/Input.h"
#include "cru/platform/gui/Window.h"
#include "cru/platform/gui/win/Cursor.h"
@@ -224,9 +223,8 @@ bool WinNativeWindow::ReleaseMouse() {
}
void WinNativeWindow::RequestRepaint() {
- if constexpr (DebugFlags::paint) {
- CRU_LOG_TAG_DEBUG("A repaint is requested.");
- }
+ CRU_LOG_TAG_DEBUG("A repaint is requested.");
+ if (!hwnd_) return;
if (!::InvalidateRect(hwnd_, nullptr, FALSE))
throw Win32Error(::GetLastError(), "Failed to invalidate window.");
if (!::UpdateWindow(hwnd_))
@@ -533,9 +531,7 @@ void WinNativeWindow::OnDestroyInternal() {
void WinNativeWindow::OnPaintInternal() {
paint_event_.Raise(nullptr);
ValidateRect(hwnd_, nullptr);
- if constexpr (DebugFlags::paint) {
- CRU_LOG_TAG_DEBUG("A repaint is finished.");
- }
+ CRU_LOG_TAG_DEBUG("A repaint is finished.");
}
void WinNativeWindow::OnMoveInternal(const int new_left, const int new_top) {
diff --git a/src/ui/components/Menu.cpp b/src/ui/components/Menu.cpp
index 380da911..c6be942a 100644
--- a/src/ui/components/Menu.cpp
+++ b/src/ui/components/Menu.cpp
@@ -78,14 +78,14 @@ void Menu::AddTextItemAt(std::string text, Index index,
PopupMenu::PopupMenu(controls::Control* attached_control)
: attached_control_(attached_control) {
menu_.SetOnItemClick([this](Index) { popup_->GetNativeWindow()->Close(); });
- popup_ = controls::Window::CreatePopup();
+ popup_.reset(controls::Window::CreatePopup());
popup_->SetAttachedControl(attached_control);
popup_->InsertChildAt(menu_.GetRootControl(), 0);
}
-PopupMenu::~PopupMenu() { delete popup_; }
+PopupMenu::~PopupMenu() {}
-controls::Control* PopupMenu::GetRootControl() { return popup_; }
+controls::Control* PopupMenu::GetRootControl() { return popup_.get(); }
void PopupMenu::SetPosition(const Point& position) {
auto window = popup_->GetNativeWindow();
diff --git a/src/ui/controls/Control.cpp b/src/ui/controls/Control.cpp
index 02148b72..70a3b1f3 100644
--- a/src/ui/controls/Control.cpp
+++ b/src/ui/controls/Control.cpp
@@ -27,6 +27,7 @@ Control::~Control() {
}
RemoveFromParent();
+ RemoveAllChild();
}
std::string Control::GetDebugId() const {
@@ -89,9 +90,8 @@ void Control::InsertChildAt(Control* control, Index index) {
children_.insert(children_.cbegin() + index, control);
control->parent_ = this;
-
- TraverseDescendents([this](Control* control) { control->host_ = host_; },
- false);
+ control->TraverseDescendents(
+ [this](Control* control) { control->host_ = host_; }, true);
if (host_) {
host_->NotifyControlParentChange(control, nullptr, this);
}
@@ -111,8 +111,8 @@ void Control::RemoveChildAt(Index index) {
auto control = children_[index];
children_.erase(children_.cbegin() + index);
control->parent_ = nullptr;
- TraverseDescendents([this](Control* control) { control->host_ = nullptr; },
- false);
+ control->TraverseDescendents(
+ [this](Control* control) { control->host_ = nullptr; }, true);
if (host_) {
host_->NotifyControlParentChange(control, this, nullptr);
}
diff --git a/src/ui/controls/ControlHost.cpp b/src/ui/controls/ControlHost.cpp
index 09639465..f83aa1a2 100644
--- a/src/ui/controls/ControlHost.cpp
+++ b/src/ui/controls/ControlHost.cpp
@@ -15,11 +15,14 @@ ControlHost::ControlHost(Control* root_control)
mouse_hover_control_(nullptr),
mouse_captured_control_(nullptr),
layout_prefer_to_fill_window_(true) {
- root_control->TraverseDescendents(
+ root_control_->TraverseDescendents(
[this](Control* control) { control->host_ = this; }, true);
}
-ControlHost::~ControlHost() {}
+ControlHost::~ControlHost() {
+ root_control_->TraverseDescendents(
+ [this](Control* control) { control->host_ = nullptr; }, true);
+}
platform::gui::INativeWindow* ControlHost::GetNativeWindow() {
return native_window_.get();
@@ -121,11 +124,7 @@ ControlHost::CreateNativeWindow() {
return std::unique_ptr<platform::gui::INativeWindow>(native_window);
}
-void ControlHost::InvalidatePaint() {
- repaint_schedule_canceler_.Reset(
- platform::gui::IUiApplication::GetInstance()->SetImmediate(
- [this] { Repaint(); }));
-}
+void ControlHost::InvalidatePaint() { native_window_->RequestRepaint(); }
void ControlHost::InvalidateLayout() {
relayout_schedule_canceler_.Reset(
@@ -244,7 +243,7 @@ void ControlHost::OnNativeDestroy(platform::gui::INativeWindow* window,
void ControlHost::OnNativePaint(platform::gui::INativeWindow* window,
std::nullptr_t) {
CRU_UNUSED(window)
- InvalidatePaint();
+ Repaint();
}
void ControlHost::OnNativeResize(platform::gui::INativeWindow* window,