diff options
author | crupest <crupest@outlook.com> | 2021-11-20 22:43:30 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2021-11-20 22:43:30 +0800 |
commit | a60910cb3db6f47fd8f3b7f31648a9d0514d4f2c (patch) | |
tree | 32c01c22e21742ae0c9febb2cbc26339f99eec1d | |
parent | 1a53ed0791d9793ed8030d3a44e833e5e7c4542b (diff) | |
download | cru-a60910cb3db6f47fd8f3b7f31648a9d0514d4f2c.tar.gz cru-a60910cb3db6f47fd8f3b7f31648a9d0514d4f2c.tar.bz2 cru-a60910cb3db6f47fd8f3b7f31648a9d0514d4f2c.zip |
...
-rw-r--r-- | demos/main/main.cpp | 7 | ||||
-rw-r--r-- | demos/scroll_view/main.cpp | 2 | ||||
-rw-r--r-- | include/cru/osx/gui/InputMethod.hpp | 4 | ||||
-rw-r--r-- | include/cru/osx/gui/Window.hpp | 7 | ||||
-rw-r--r-- | include/cru/platform/gui/Window.hpp | 4 | ||||
-rw-r--r-- | include/cru/ui/controls/Popup.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/controls/RootControl.hpp | 17 | ||||
-rw-r--r-- | include/cru/ui/controls/Window.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/host/WindowHost.hpp | 19 | ||||
-rw-r--r-- | src/osx/gui/Window.mm | 143 | ||||
-rw-r--r-- | src/osx/gui/WindowPrivate.h | 10 | ||||
-rw-r--r-- | src/ui/components/Menu.cpp | 5 | ||||
-rw-r--r-- | src/ui/controls/Popup.cpp | 16 | ||||
-rw-r--r-- | src/ui/controls/RootControl.cpp | 60 | ||||
-rw-r--r-- | src/ui/controls/Window.cpp | 9 | ||||
-rw-r--r-- | src/ui/host/WindowHost.cpp | 35 |
16 files changed, 152 insertions, 196 deletions
diff --git a/demos/main/main.cpp b/demos/main/main.cpp index 1a92e5ff..5c51a05a 100644 --- a/demos/main/main.cpp +++ b/demos/main/main.cpp @@ -49,11 +49,14 @@ int main() { window->MouseDownEvent()->Bubble()->AddHandler( [window, &popup_menu](cru::ui::event::MouseButtonEventArgs& e) { - popup_menu->SetPosition(e.GetPoint()); + popup_menu->SetPosition(e.GetPoint() + window->GetWindowHost() + ->GetNativeWindow() + ->GetClientRect() + .GetLeftTop()); popup_menu->Show(); }); - window->Show(); + window->GetWindowHost()->GetNativeWindow()->SetVisible(true); return application->Run(); } diff --git a/demos/scroll_view/main.cpp b/demos/scroll_view/main.cpp index be8bd228..c3593986 100644 --- a/demos/scroll_view/main.cpp +++ b/demos/scroll_view/main.cpp @@ -81,7 +81,7 @@ The cold never bothered me anyway)"); scroll_view->SetChild(text_block); - window->Show(); + window->GetWindowHost()->GetNativeWindow()->SetVisible(true); return application->Run(); } diff --git a/include/cru/osx/gui/InputMethod.hpp b/include/cru/osx/gui/InputMethod.hpp index aa013338..d184a722 100644 --- a/include/cru/osx/gui/InputMethod.hpp +++ b/include/cru/osx/gui/InputMethod.hpp @@ -7,12 +7,14 @@ namespace cru::platform::gui::osx { class OsxWindow; namespace details { +class OsxWindowPrivate; class OsxInputMethodContextPrivate; -} +} // namespace details class OsxInputMethodContext : public OsxGuiResource, public virtual IInputMethodContext { friend OsxWindow; + friend details::OsxWindowPrivate; friend details::OsxInputMethodContextPrivate; public: diff --git a/include/cru/osx/gui/Window.hpp b/include/cru/osx/gui/Window.hpp index 406c133f..7ea21926 100644 --- a/include/cru/osx/gui/Window.hpp +++ b/include/cru/osx/gui/Window.hpp @@ -39,6 +39,9 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { Size GetClientSize() override; void SetClientSize(const Size& size) override; + Rect GetClientRect() override; + void SetClientRect(const Rect& rect) override; + Rect GetWindowRect() override; void SetWindowRect(const Rect& rect) override; @@ -55,6 +58,7 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { std::unique_ptr<graphics::IPainter> BeginPaint() override; + IEvent<std::nullptr_t>* CreateEvent() override; IEvent<std::nullptr_t>* DestroyEvent() override; IEvent<std::nullptr_t>* PaintEvent() override; IEvent<Size>* ResizeEvent() override; @@ -70,9 +74,6 @@ class OsxWindow : public OsxGuiResource, public INativeWindow { IInputMethodContext* GetInputMethodContext() override; private: - void CreateWindow(); - - private: std::unique_ptr<details::OsxWindowPrivate> p_; }; } // namespace cru::platform::gui::osx diff --git a/include/cru/platform/gui/Window.hpp b/include/cru/platform/gui/Window.hpp index 49cbe1a0..a1816e4a 100644 --- a/include/cru/platform/gui/Window.hpp +++ b/include/cru/platform/gui/Window.hpp @@ -43,6 +43,9 @@ struct INativeWindow : virtual IPlatformResource { virtual Size GetClientSize() = 0; virtual void SetClientSize(const Size& size) = 0; + virtual Rect GetClientRect() = 0; + virtual void SetClientRect(const Rect& rect) = 0; + // Get the rect of the window containing frame. // The lefttop of the rect is relative to screen lefttop. virtual Rect GetWindowRect() = 0; @@ -67,6 +70,7 @@ struct INativeWindow : virtual IPlatformResource { virtual std::unique_ptr<graphics::IPainter> BeginPaint() = 0; // Don't use this instance after receive this event. + virtual IEvent<std::nullptr_t>* CreateEvent() = 0; virtual IEvent<std::nullptr_t>* DestroyEvent() = 0; virtual IEvent<std::nullptr_t>* PaintEvent() = 0; virtual IEvent<Size>* ResizeEvent() = 0; diff --git a/include/cru/ui/controls/Popup.hpp b/include/cru/ui/controls/Popup.hpp index cd5e1813..2e40bb5b 100644 --- a/include/cru/ui/controls/Popup.hpp +++ b/include/cru/ui/controls/Popup.hpp @@ -22,10 +22,5 @@ class Popup : public RootControl { ~Popup() override; String GetControlType() const override { return kControlType.ToString(); } - - protected: - gsl::not_null<platform::gui::INativeWindow*> CreateNativeWindow( - gsl::not_null<host::WindowHost*> host, - platform::gui::INativeWindow* parent) override; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/controls/RootControl.hpp b/include/cru/ui/controls/RootControl.hpp index a795f322..44722cef 100644 --- a/include/cru/ui/controls/RootControl.hpp +++ b/include/cru/ui/controls/RootControl.hpp @@ -4,11 +4,13 @@ #include "cru/common/Base.hpp" #include "cru/platform/gui/Base.hpp" #include "cru/ui/Base.hpp" +#include "cru/ui/host/WindowHost.hpp" namespace cru::ui::controls { class RootControl : public LayoutControl { protected: - explicit RootControl(Control* attached_control); + explicit RootControl(Control* attached_control, + host::CreateWindowParams params); public: CRU_DELETE_COPY(RootControl) @@ -18,20 +20,7 @@ class RootControl : public LayoutControl { public: render::RenderObject* GetRenderObject() const override; - void EnsureWindowCreated(); - - // If create is false and native window is not create, it will not be created - // and shown. - void Show(bool create = true); - - Rect GetRect(); - void SetRect(const Rect& rect); - protected: - virtual gsl::not_null<platform::gui::INativeWindow*> CreateNativeWindow( - gsl::not_null<host::WindowHost*> host, - platform::gui::INativeWindow* parent) = 0; - void SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value); private: diff --git a/include/cru/ui/controls/Window.hpp b/include/cru/ui/controls/Window.hpp index 63b4d1e3..b0828f70 100644 --- a/include/cru/ui/controls/Window.hpp +++ b/include/cru/ui/controls/Window.hpp @@ -23,10 +23,5 @@ class Window final : public RootControl { public: String GetControlType() const final { return control_type.ToString(); } - - protected: - gsl::not_null<platform::gui::INativeWindow*> CreateNativeWindow( - gsl::not_null<host::WindowHost*> host, - platform::gui::INativeWindow* parent) override; }; } // namespace cru::ui::controls diff --git a/include/cru/ui/host/WindowHost.hpp b/include/cru/ui/host/WindowHost.hpp index f3caeeef..6fb853b6 100644 --- a/include/cru/ui/host/WindowHost.hpp +++ b/include/cru/ui/host/WindowHost.hpp @@ -30,7 +30,7 @@ class WindowHost : public Object { CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::host::WindowHost") public: - WindowHost(controls::Control* root_control); + WindowHost(controls::Control* root_control, CreateWindowParams params); CRU_DELETE_COPY(WindowHost) CRU_DELETE_MOVE(WindowHost) @@ -40,10 +40,6 @@ 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. @@ -112,18 +108,13 @@ class WindowHost : public Object { return &native_window_change_event_; } - // If window exist, return window actual size. Otherwise if saved rect exists, - // return it. Otherwise return 0. - Rect GetWindowRect(); - - void SetSavedWindowRect(std::optional<Rect> rect); - - void SetWindowRect(const Rect& rect); - std::shared_ptr<platform::gui::ICursor> GetOverrideCursor(); void SetOverrideCursor(std::shared_ptr<platform::gui::ICursor> cursor); private: + gsl::not_null<platform::gui::INativeWindow*> CreateNativeWindow( + CreateWindowParams params); + //*************** region: native messages *************** void OnNativeDestroy(platform::gui::INativeWindow* window, std::nullptr_t); void OnNativePaint(platform::gui::INativeWindow* window, std::nullptr_t); @@ -178,8 +169,6 @@ class WindowHost : public Object { Event<platform::gui::INativeWindow*> native_window_change_event_; - std::optional<Rect> saved_rect_; - std::shared_ptr<platform::gui::ICursor> override_cursor_; }; } // namespace cru::ui::host diff --git a/src/osx/gui/Window.mm b/src/osx/gui/Window.mm index 9f0d9742..b838165f 100644 --- a/src/osx/gui/Window.mm +++ b/src/osx/gui/Window.mm @@ -56,10 +56,10 @@ void OsxWindowPrivate::OnWindowWillClose() { void OsxWindowPrivate::OnWindowDidExpose() { osx_window_->RequestRepaint(); } void OsxWindowPrivate::OnWindowDidUpdate() {} +void OsxWindowPrivate::OnWindowDidMove() { content_rect_ = RetrieveContentRect(); } + void OsxWindowPrivate::OnWindowDidResize() { - NSRect rect = [NSWindow contentRectForFrameRect:[window_ frame] - styleMask:CalcWindowStyleMask(frame_)]; - content_rect_ = cru::platform::graphics::osx::quartz::Convert(rect); + content_rect_ = RetrieveContentRect(); auto view = [window_ contentView]; [view removeTrackingArea:[view trackingAreas][0]]; @@ -72,13 +72,7 @@ void OsxWindowPrivate::OnWindowDidResize() { CGLayerRelease(draw_layer_); - // If size is 0 then create layer will fail. - auto s = rect.size; - if (s.width == 0) s.width = 1; - if (s.height == 0) s.height = 1; - - draw_layer_ = CGLayerCreateWithContext(nullptr, s, nullptr); - Ensures(draw_layer_); + draw_layer_ = CreateLayer(Convert(content_rect_.GetSize())); resize_event_.Raise(osx_window_->GetClientSize()); @@ -121,6 +115,17 @@ void OsxWindowPrivate::OnKeyUp(KeyCode key, KeyModifier key_modifier) { key_up_event_.Raise({key, key_modifier}); } +CGLayerRef OsxWindowPrivate::CreateLayer(const CGSize& size) { + auto s = size; + if (s.width == 0) s.width = 1; + if (s.height == 0) s.height = 1; + + auto draw_layer = CGLayerCreateWithContext(nullptr, s, nullptr); + Ensures(draw_layer); + + return draw_layer; +} + void OsxWindowPrivate::UpdateCursor() { auto cursor = cursor_ == nullptr ? std::dynamic_pointer_cast<OsxCursor>( @@ -137,6 +142,48 @@ Point OsxWindowPrivate::TransformMousePoint(const Point& point) { return r; } +void OsxWindowPrivate::CreateWindow() { + NSRect content_rect = Convert(content_rect_); + NSWindowStyleMask style_mask = CalcWindowStyleMask(frame_); + + auto cr = content_rect; + cr.origin.y = GetScreenSize().height - content_rect.origin.y - content_rect.size.height; + window_ = [[CruWindow alloc] init:this contentRect:content_rect style:style_mask]; + Ensures(window_); + + [window_ setDelegate:window_delegate_]; + + if (parent_) { + auto parent = CheckPlatform<OsxWindow>(parent_, this->osx_window_->GetPlatformId()); + [window_ setParentWindow:parent->p_->window_]; + } + + NSView* content_view = [[CruView alloc] init:this + input_context_p:input_method_context_->p_.get() + frame:Rect(Point{}, content_rect_.GetSize())]; + + [window_ setContentView:content_view]; + + draw_layer_ = CreateLayer(content_rect.size); + + create_event_.Raise(nullptr); + + osx_window_->RequestRepaint(); +} + +Size OsxWindowPrivate::GetScreenSize() { + auto screen = window_ ? [window_ screen] : [NSScreen mainScreen]; + auto size = [screen frame].size; + return Convert(size); +} + +Rect OsxWindowPrivate::RetrieveContentRect() { + NSRect rect = [NSWindow contentRectForFrameRect:[window_ frame] + styleMask:CalcWindowStyleMask(frame_)]; + rect.origin.y = GetScreenSize().height - rect.origin.y - rect.size.height; + return cru::platform::graphics::osx::quartz::Convert(rect); +} + } OsxWindow::OsxWindow(OsxUiApplication* ui_application, INativeWindow* parent, bool frame) @@ -178,7 +225,7 @@ void OsxWindow::SetVisible(bool is_visible) { } } else { if (is_visible) { - CreateWindow(); + p_->CreateWindow(); [p_->window_ orderFront:nil]; } } @@ -194,26 +241,33 @@ void OsxWindow::SetClientSize(const Size& size) { } } -Rect OsxWindow::GetWindowRect() { +Rect OsxWindow::GetClientRect() { return p_->content_rect_; } + +void OsxWindow::SetClientRect(const Rect& rect) { if (p_->window_) { - auto r = [p_->window_ frame]; - return Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); + auto r = Convert(rect); + r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height; + r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->frame_)]; + [p_->window_ setFrame:r display:false]; } else { - NSRect rr{p_->content_rect_.left, p_->content_rect_.top, p_->content_rect_.width, - p_->content_rect_.height}; - auto r = [NSWindow frameRectForContentRect:rr styleMask:CalcWindowStyleMask(p_->frame_)]; - return Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); + p_->content_rect_ = rect; } } +Rect OsxWindow::GetWindowRect() { + auto r = Convert(p_->content_rect_); + r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height; + r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->frame_)]; + r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height; + return Convert(r); +} + void OsxWindow::SetWindowRect(const Rect& rect) { - auto rr = NSRect{rect.left, rect.top, rect.width, rect.height}; - if (p_->window_) { - [p_->window_ setFrame:rr display:false]; - } else { - auto r = [NSWindow contentRectForFrameRect:rr styleMask:CalcWindowStyleMask(p_->frame_)]; - p_->content_rect_ = Rect(r.origin.x, r.origin.y, r.size.width, r.size.height); - } + auto r = Convert(rect); + r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height; + r = [NSWindow frameRectForContentRect:r styleMask:CalcWindowStyleMask(p_->frame_)]; + r.origin.y = p_->GetScreenSize().height - r.origin.y - r.size.height; + SetClientRect(Convert(r)); } void OsxWindow::RequestRepaint() { @@ -236,40 +290,6 @@ std::unique_ptr<graphics::IPainter> OsxWindow::BeginPaint() { }); } -void OsxWindow::CreateWindow() { - NSRect content_rect = CGRectMake(p_->content_rect_.left, p_->content_rect_.top, - p_->content_rect_.width, p_->content_rect_.height); - - NSWindowStyleMask style_mask = CalcWindowStyleMask(p_->frame_); - - p_->window_ = [[CruWindow alloc] init:p_.get() contentRect:content_rect style:style_mask]; - Ensures(p_->window_); - - [p_->window_ setDelegate:p_->window_delegate_]; - - if (p_->parent_) { - auto parent = CheckPlatform<OsxWindow>(p_->parent_, GetPlatformId()); - [p_->window_ setParentWindow:parent->p_->window_]; - } - - NSView* content_view = [[CruView alloc] init:p_.get() - input_context_p:p_->input_method_context_->p_.get() - frame:Rect(Point{}, p_->content_rect_.GetSize())]; - - [p_->window_ setContentView:content_view]; - - // If size is 0 then create layer will fail. - auto s = p_->content_rect_.GetSize(); - if (s.width == 0) s.width = 1; - if (s.height == 0) s.height = 1; - - p_->draw_layer_ = - CGLayerCreateWithContext(nullptr, cru::platform::graphics::osx::quartz::Convert(s), nullptr); - Ensures(p_->draw_layer_); - - RequestRepaint(); -} - bool OsxWindow::RequestFocus() { if (!p_->window_) return false; [p_->window_ makeKeyWindow]; @@ -292,6 +312,7 @@ void OsxWindow::SetCursor(std::shared_ptr<ICursor> cursor) { } } +IEvent<std::nullptr_t>* OsxWindow::CreateEvent() { return &p_->create_event_; } IEvent<std::nullptr_t>* OsxWindow::DestroyEvent() { return &p_->destroy_event_; } IEvent<std::nullptr_t>* OsxWindow::PaintEvent() { return &p_->paint_event_; } IEvent<Size>* OsxWindow::ResizeEvent() { return &p_->resize_event_; } @@ -660,6 +681,10 @@ const std::unordered_set<KeyCode> input_context_handle_codes_when_has_text{ _p->OnWindowDidUpdate(); } +- (void)windowDidMove:(NSNotification*)notification { + _p->OnWindowDidMove(); +} + - (void)windowDidResize:(NSNotification*)notification { _p->OnWindowDidResize(); } diff --git a/src/osx/gui/WindowPrivate.h b/src/osx/gui/WindowPrivate.h index 0778195a..88760673 100644 --- a/src/osx/gui/WindowPrivate.h +++ b/src/osx/gui/WindowPrivate.h @@ -53,6 +53,7 @@ class OsxWindowPrivate { void OnWindowWillClose(); void OnWindowDidExpose(); void OnWindowDidUpdate(); + void OnWindowDidMove(); void OnWindowDidResize(); void OnBecomeKeyWindow(); void OnResignKeyWindow(); @@ -63,10 +64,18 @@ class OsxWindowPrivate { NSWindow* GetNSWindow() { return window_; } private: + Size GetScreenSize(); + + void CreateWindow(); + void UpdateCursor(); Point TransformMousePoint(const Point& point); + CGLayerRef CreateLayer(const CGSize& size); + + Rect RetrieveContentRect(); + private: OsxWindow* osx_window_; @@ -88,6 +97,7 @@ class OsxWindowPrivate { TimerAutoCanceler draw_timer_; + Event<std::nullptr_t> create_event_; Event<std::nullptr_t> destroy_event_; Event<std::nullptr_t> paint_event_; Event<Size> resize_event_; diff --git a/src/ui/components/Menu.cpp b/src/ui/components/Menu.cpp index af54c46c..964eead9 100644 --- a/src/ui/components/Menu.cpp +++ b/src/ui/components/Menu.cpp @@ -1,4 +1,5 @@ #include "cru/ui/components/Menu.hpp" +#include "cru/platform/gui/Window.hpp" #include "cru/ui/UiManager.hpp" #include "cru/ui/controls/Button.hpp" #include "cru/ui/controls/Control.hpp" @@ -82,11 +83,11 @@ PopupMenu::~PopupMenu() { controls::Control* PopupMenu::GetRootControl() { return popup_; } void PopupMenu::SetPosition(const Point& position) { - popup_->SetRect(Rect{position, {}}); + popup_->GetWindowHost()->GetNativeWindow()->SetClientRect(Rect{position, {}}); } void PopupMenu::Show() { popup_->GetWindowHost()->RelayoutWithSize(Size::Infinate(), true); - popup_->Show(); + popup_->GetWindowHost()->GetNativeWindow()->SetVisible(true); } } // namespace cru::ui::components diff --git a/src/ui/controls/Popup.cpp b/src/ui/controls/Popup.cpp index 515c7b31..ae6ac1d2 100644 --- a/src/ui/controls/Popup.cpp +++ b/src/ui/controls/Popup.cpp @@ -8,19 +8,13 @@ #include <memory> namespace cru::ui::controls { -Popup::Popup(Control* attached_control) : RootControl(attached_control) { +Popup::Popup(Control* attached_control) + : RootControl( + attached_control, + host::CreateWindowParams{ + nullptr, platform::gui::CreateWindowFlags::NoCaptionAndBorder}) { SetGainFocusOnCreateAndDestroyWhenLoseFocus(true); } Popup::~Popup() = default; - -gsl::not_null<platform::gui::INativeWindow*> Popup::CreateNativeWindow( - gsl::not_null<host::WindowHost*> host, - platform::gui::INativeWindow* parent) { - auto window = host->CreateNativeWindow( - {parent, platform::gui::CreateWindowFlags::NoCaptionAndBorder}); - - return window; -} - } // namespace cru::ui::controls diff --git a/src/ui/controls/RootControl.cpp b/src/ui/controls/RootControl.cpp index 007a0ac1..4ae41c80 100644 --- a/src/ui/controls/RootControl.cpp +++ b/src/ui/controls/RootControl.cpp @@ -11,57 +11,35 @@ #include <memory> namespace cru::ui::controls { -RootControl::RootControl(Control* attached_control) +RootControl::RootControl(Control* attached_control, + host::CreateWindowParams params) : 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); -} - -RootControl::~RootControl() {} - -render::RenderObject* RootControl::GetRenderObject() const { - return render_object_.get(); -} - -void RootControl::EnsureWindowCreated() { this->GetNativeWindow(true); } + window_host_ = std::make_unique<host::WindowHost>(this, params); -Rect RootControl::GetRect() { return window_host_->GetWindowRect(); } - -void RootControl::SetRect(const Rect& rect) { - window_host_->SetWindowRect(rect); -} - -void RootControl::Show(bool create) { - platform::gui::INativeWindow* native_window = GetNativeWindow(create); - if (!native_window) return; - native_window->SetVisible(true); if (gain_focus_on_create_and_destroy_when_lose_focus_) { - native_window->RequestFocus(); + auto native_window = window_host_->GetNativeWindow(); + native_window->CreateEvent()->AddHandler( + [](platform::gui::INativeWindow* window) { + window->CreateEvent()->AddHandler( + [window](std::nullptr_t) { window->RequestFocus(); }); + }); + + native_window->FocusEvent()->AddHandler( + [native_window](platform::gui::FocusChangeType type) { + if (type == platform::gui::FocusChangeType::Lost) { + native_window->Close(); + } + }); } } -platform::gui::INativeWindow* RootControl::GetNativeWindow(bool create) { - const auto host = GetWindowHost(); - platform::gui::INativeWindow* native_window = host->GetNativeWindow(); - if (!create) return native_window; - if (!native_window) { - native_window = this->CreateNativeWindow( - host, attached_control_ - ? attached_control_->GetWindowHost()->GetNativeWindow() - : nullptr); +RootControl::~RootControl() {} - if (gain_focus_on_create_and_destroy_when_lose_focus_) { - native_window->FocusEvent()->AddHandler( - [native_window](platform::gui::FocusChangeType type) { - if (type == platform::gui::FocusChangeType::Lost) { - native_window->Close(); - } - }); - } - } - return native_window; +render::RenderObject* RootControl::GetRenderObject() const { + return render_object_.get(); } void RootControl::SetGainFocusOnCreateAndDestroyWhenLoseFocus(bool value) { diff --git a/src/ui/controls/Window.cpp b/src/ui/controls/Window.cpp index ba66f42e..00fab8e9 100644 --- a/src/ui/controls/Window.cpp +++ b/src/ui/controls/Window.cpp @@ -12,13 +12,8 @@ Window* Window::Create(Control* attached_control) { return new Window(attached_control); } -Window::Window(Control* attached_control) : RootControl(attached_control) {} +Window::Window(Control* attached_control) + : RootControl(attached_control, host::CreateWindowParams{}) {} Window::~Window() {} - -gsl::not_null<platform::gui::INativeWindow*> Window::CreateNativeWindow( - gsl::not_null<host::WindowHost*> host, - platform::gui::INativeWindow* parent) { - return host->CreateNativeWindow({parent}); -} } // namespace cru::ui::controls diff --git a/src/ui/host/WindowHost.cpp b/src/ui/host/WindowHost.cpp index d26b43ab..3f3976b4 100644 --- a/src/ui/host/WindowHost.cpp +++ b/src/ui/host/WindowHost.cpp @@ -104,7 +104,8 @@ inline void BindNativeEvent( } } // namespace -WindowHost::WindowHost(controls::Control* root_control) +WindowHost::WindowHost(controls::Control* root_control, + CreateWindowParams params) : root_control_(root_control), focus_control_(root_control) { root_control_->TraverseDescendants([this](controls::Control* control) { control->window_host_ = this; @@ -115,14 +116,14 @@ WindowHost::WindowHost(controls::Control* root_control) root_render_object_->SetWindowHostRecursive(this); this->layout_paint_cycler_ = std::make_unique<LayoutPaintCycler>(this); + + CreateNativeWindow(params); } 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, @@ -153,10 +154,6 @@ gsl::not_null<platform::gui::INativeWindow*> WindowHost::CreateNativeWindow( BindNativeEvent(this, native_window, native_window->KeyUpEvent(), &WindowHost::OnNativeKeyUp, event_revoker_guards_); - if (saved_rect_) { - native_window->SetWindowRect(saved_rect_.value()); - } - native_window_change_event_.Raise(native_window); return native_window_; @@ -194,8 +191,7 @@ void WindowHost::RelayoutWithSize(const Size& available_size, render::MeasureSize::NotSpecified()); if (set_window_size_to_fit_content) { - auto rect = GetWindowRect(); - SetWindowRect({rect.GetLeftTop(), root_render_object_->GetSize()}); + native_window_->SetClientSize(root_render_object_->GetSize()); } root_render_object_->Layout(Point{}); @@ -277,29 +273,8 @@ void WindowHost::RunAfterLayoutStable(std::function<void()> action) { } } -Rect WindowHost::GetWindowRect() { - if (native_window_) return native_window_->GetWindowRect(); - return saved_rect_.value_or(Rect{}); -} - -void WindowHost::SetSavedWindowRect(std::optional<Rect> rect) { - saved_rect_ = std::move(rect); -} - -void WindowHost::SetWindowRect(const Rect& rect) { - SetSavedWindowRect(rect); - if (native_window_) native_window_->SetWindowRect(rect); -} - void WindowHost::OnNativeDestroy(INativeWindow* window, std::nullptr_t) { CRU_UNUSED(window) - - saved_rect_ = this->native_window_->GetWindowRect(); - - this->native_window_ = nullptr; - event_revoker_guards_.clear(); - - native_window_change_event_.Raise(nullptr); } void WindowHost::OnNativePaint(INativeWindow* window, std::nullptr_t) { |