aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/window.cpp48
-rw-r--r--src/ui/window.hpp28
2 files changed, 69 insertions, 7 deletions
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
index f7506f18..2737b70b 100644
--- a/src/ui/window.cpp
+++ b/src/ui/window.cpp
@@ -113,20 +113,44 @@ namespace cru::ui
}
}
- Window::Window() : Window(nullptr)
+ Window* Window::CreateOverlapped()
{
+ return new Window(tag_overlapped_constructor{});
+ }
+ Window* Window::CreatePopup(Window* parent, const bool caption)
+ {
+ return new Window(tag_popup_constructor{}, parent, caption);
}
- Window::Window(Window* parent) : Control(WindowConstructorTag{}, this), control_list_({ this }) {
+ Window::Window(tag_overlapped_constructor) : Control(WindowConstructorTag{}, this), control_list_({ this }) {
+ const auto window_manager = WindowManager::GetInstance();
+
+ hwnd_ = CreateWindowEx(0,
+ window_manager->GetGeneralWindowClass()->GetName(),
+ L"", WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ nullptr, nullptr, Application::GetInstance()->GetInstanceHandle(), nullptr
+ );
+
+ if (hwnd_ == nullptr)
+ throw std::runtime_error("Failed to create window.");
+
+ AfterCreateHwnd(window_manager);
+ }
+ Window::Window(tag_popup_constructor, Window* parent, const bool caption) : Control(WindowConstructorTag{}, this), control_list_({ this })
+ {
if (parent != nullptr && !parent->IsWindowValid())
throw std::runtime_error("Parent window is not valid.");
+ parent_window_ = parent;
+
const auto window_manager = WindowManager::GetInstance();
+
hwnd_ = CreateWindowEx(0,
window_manager->GetGeneralWindowClass()->GetName(),
- L"", WS_OVERLAPPEDWINDOW,
+ L"", caption ? (WS_POPUPWINDOW | WS_CAPTION) : WS_POPUP,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
parent == nullptr ? nullptr : parent->GetWindowHandle(),
nullptr, Application::GetInstance()->GetInstanceHandle(), nullptr
@@ -135,6 +159,11 @@ namespace cru::ui
if (hwnd_ == nullptr)
throw std::runtime_error("Failed to create window.");
+ AfterCreateHwnd(window_manager);
+ }
+
+ void Window::AfterCreateHwnd(WindowManager* window_manager)
+ {
window_manager->RegisterWindow(hwnd_, this);
render_target_ = graph::GraphManager::GetInstance()->CreateWindowRenderTarget(hwnd_);
@@ -143,7 +172,11 @@ namespace cru::ui
}
Window::~Window() {
- Close();
+ if (IsWindowValid())
+ {
+ SetDeleteThisOnDestroy(false); // avoid double delete.
+ Close();
+ }
TraverseDescendants([this](Control* control) {
control->OnDetachToWindow(this);
});
@@ -154,6 +187,11 @@ namespace cru::ui
return control_type;
}
+ void Window::SetDeleteThisOnDestroy(bool value)
+ {
+ delete_this_on_destroy_ = value;
+ }
+
void Window::Close() {
if (IsWindowValid())
DestroyWindow(hwnd_);
@@ -531,6 +569,8 @@ namespace cru::ui
void Window::OnDestroyInternal() {
WindowManager::GetInstance()->UnregisterWindow(hwnd_);
hwnd_ = nullptr;
+ if (delete_this_on_destroy_)
+ delete this;
}
void Window::OnPaintInternal() {
diff --git a/src/ui/window.hpp b/src/ui/window.hpp
index 82cbfc4f..963bff78 100644
--- a/src/ui/window.hpp
+++ b/src/ui/window.hpp
@@ -83,14 +83,26 @@ namespace cru::ui
- class Window : public Control
+ class Window final : public Control
{
friend class WindowManager;
public:
static constexpr auto control_type = L"Window";
- Window();
- explicit Window(Window* parent);
+ public:
+ static Window* CreateOverlapped();
+ static Window* CreatePopup(Window* parent, bool caption = false);
+
+ private:
+ struct tag_overlapped_constructor {};
+ struct tag_popup_constructor {};
+
+ explicit Window(tag_overlapped_constructor);
+ Window(tag_popup_constructor, Window* parent, bool caption);
+
+ void AfterCreateHwnd(WindowManager* window_manager);
+
+ public:
Window(const Window& other) = delete;
Window(Window&& other) = delete;
Window& operator=(const Window& other) = delete;
@@ -100,6 +112,8 @@ namespace cru::ui
public:
StringView GetControlType() const override final;
+ void SetDeleteThisOnDestroy(bool value);
+
//*************** region: handle ***************
//Get the handle of the window. Return null if window is invalid.
@@ -117,6 +131,11 @@ namespace cru::ui
//*************** region: window operations ***************
+ Window* GetParentWindow() const
+ {
+ return parent_window_;
+ }
+
//Close and destroy the window if the window is valid.
void Close();
@@ -286,7 +305,10 @@ namespace cru::ui
void DispatchMouseHoverControlChangeEvent(Control* old_control, Control * new_control, const Point& point);
private:
+ bool delete_this_on_destroy_ = true;
+
HWND hwnd_ = nullptr;
+ Window* parent_window_ = nullptr;
std::shared_ptr<graph::WindowRenderTarget> render_target_{};
std::list<Control*> control_list_{};