diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 3 | ||||
-rw-r--r-- | src/ui/window.cpp | 57 | ||||
-rw-r--r-- | src/ui/window.hpp | 12 |
3 files changed, 55 insertions, 17 deletions
diff --git a/src/main.cpp b/src/main.cpp index f5eb655a..19e821a8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -118,7 +118,7 @@ int APIENTRY wWinMain( const auto button = Button::Create(); button->GetLayoutParams()->padding = Thickness(20, 5); button->AddChild(TextBlock::Create(L"Show popup window parenting this.")); - button->mouse_click_event.AddHandler([window](auto) + button->mouse_click_event.AddHandler([window, button](auto) { const auto popup = Window::CreatePopup(window); @@ -140,6 +140,7 @@ int APIENTRY wWinMain( popup->AddChild(menu); popup->SetSizeFitContent(); + popup->SetWindowPosition(window->PointToScreen(button->GetPositionAbsolute())); popup->Show(); }); diff --git a/src/ui/window.cpp b/src/ui/window.cpp index 41104924..f8e6d4f3 100644 --- a/src/ui/window.cpp +++ b/src/ui/window.cpp @@ -98,6 +98,15 @@ namespace cru::ui ); } + inline POINT DipToPi(const Point& dip_point) + { + POINT result; + result.x = graph::DipToPixelX(dip_point.x); + result.y = graph::DipToPixelY(dip_point.y); + return result; + } + + namespace { Cursor::Ptr GetCursorInherit(Control* control) @@ -275,6 +284,41 @@ namespace cru::ui } } + void Window::SetWindowPosition(const Point& position) + { + if (IsWindowValid()) { + SetWindowPos( + hwnd_, nullptr, + graph::DipToPixelX(position.x), + graph::DipToPixelY(position.y), + 0, 0, + SWP_NOZORDER | SWP_NOSIZE + ); + } + } + + Point Window::PointToScreen(const Point& point) + { + if (!IsWindowValid()) + return Point::Zero(); + + auto p = DipToPi(point); + if (::ClientToScreen(GetWindowHandle(), &p) == 0) + throw Win32Error(::GetLastError(), "Failed transform point from window to screen."); + return PiToDip(p); + } + + Point Window::PointFromScreen(const Point& point) + { + if (!IsWindowValid()) + return Point::Zero(); + + auto p = DipToPi(point); + if (::ScreenToClient(GetWindowHandle(), &p) == 0) + throw Win32Error(::GetLastError(), "Failed transform point from screen to window."); + return PiToDip(p); + } + bool Window::HandleWindowMessage(HWND hwnd, int msg, WPARAM w_param, LPARAM l_param, LRESULT & result) { if (!native_message_event.IsNoHandler()) @@ -444,14 +488,14 @@ namespace cru::ui void Window::Relayout() { - OnMeasureCore(GetSize()); + Measure(GetSize()); OnLayoutCore(Rect(Point::Zero(), GetSize())); is_layout_invalid_ = false; } void Window::SetSizeFitContent(const Size& max_size) { - OnMeasureCore(max_size); + Measure(max_size); SetClientSize(GetDesiredSize()); OnLayoutCore(Rect(Point::Zero(), GetSize())); is_layout_invalid_ = false; @@ -579,15 +623,6 @@ namespace cru::ui } } - Size Window::OnMeasureContent(const Size& available_size) - { - for (auto control: GetChildren()) - { - control->Measure(available_size); - } - return available_size; - } - void Window::OnDestroyInternal() { WindowManager::GetInstance()->UnregisterWindow(hwnd_); hwnd_ = nullptr; diff --git a/src/ui/window.hpp b/src/ui/window.hpp index 05b1a259..b2b8cde0 100644 --- a/src/ui/window.hpp +++ b/src/ui/window.hpp @@ -162,6 +162,13 @@ namespace cru::ui //The lefttop of the rect is relative to screen lefttop. void SetWindowRect(const Rect& rect); + //Set the lefttop of the window relative to screen. + void SetWindowPosition(const Point& position); + + Point PointToScreen(const Point& point); + + Point PointFromScreen(const Point& point); + //Handle the raw window message. //Return true if the message is handled and get the result through "result" argument. //Return false if the message is not handled. @@ -254,11 +261,6 @@ namespace cru::ui void SetCursorInternal(HCURSOR cursor); - //*************** region: layout *************** - - Size OnMeasureContent(const Size& available_size) override; - - //*************** region: native messages *************** void OnDestroyInternal(); |