From 70e32ff3e555fc528b963e445513e2c689235fba Mon Sep 17 00:00:00 2001 From: codereader Date: Sun, 6 Nov 2022 16:42:16 +0100 Subject: [PATCH] #4764: Better popup sizing and placement --- libs/wxutil/TransientPopupWindow.h | 53 ++++++++++++++++++++++++ radiant/ui/mediabrowser/MediaBrowser.cpp | 31 ++++---------- tools/msvc/wxutillib.vcxproj | 1 + tools/msvc/wxutillib.vcxproj.filters | 1 + 4 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 libs/wxutil/TransientPopupWindow.h diff --git a/libs/wxutil/TransientPopupWindow.h b/libs/wxutil/TransientPopupWindow.h new file mode 100644 index 0000000000..a675e5e16e --- /dev/null +++ b/libs/wxutil/TransientPopupWindow.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include "MultiMonitor.h" + +namespace wxutil +{ + +class TransientPopupWindow : + public wxPopupTransientWindow +{ +public: + TransientPopupWindow(wxWindow* parent) : + wxPopupTransientWindow(parent, wxBORDER_DEFAULT) + { + SetSizer(new wxBoxSizer(wxVERTICAL)); + } + + // Attempts to position the popup to the right or left of the given window + // The vertical offset is added to the screen position of the given window + void PositionNextTo(wxWindow* win, int verticalOffset, const wxSize& size) + { + auto rectScreen = MultiMonitor::getMonitorForWindow(win); + + SetSize(size); + + // Try right first + auto rightTop = win->GetScreenRect().GetRightTop(); + rightTop.y += verticalOffset; + + if (rightTop.x + size.GetWidth() < rectScreen.GetX() + rectScreen.GetWidth()) + { + SetPosition(rightTop); + return; + } + + // Failed, place to the left + auto leftTop = win->GetScreenRect().GetLeftTop(); + leftTop.y += verticalOffset; + + if (leftTop.x - size.GetWidth() > rectScreen.GetX()) + { + SetPosition(wxPoint(leftTop.x - size.GetWidth(), leftTop.y)); + return; + } + + // Fall back to the wxwidgets default algorithm + Position(win->GetScreenPosition(), size); + } +}; + +} diff --git a/radiant/ui/mediabrowser/MediaBrowser.cpp b/radiant/ui/mediabrowser/MediaBrowser.cpp index e56860de38..512fb9ae15 100644 --- a/radiant/ui/mediabrowser/MediaBrowser.cpp +++ b/radiant/ui/mediabrowser/MediaBrowser.cpp @@ -19,6 +19,8 @@ #include "FocusMaterialRequest.h" #include "ui/UserInterfaceModule.h" #include "ui/texturebrowser/TextureDirectoryBrowser.h" +#include "wxutil/MultiMonitor.h" +#include "wxutil/TransientPopupWindow.h" namespace ui { @@ -196,32 +198,17 @@ void MediaBrowser::_onTreeViewSelectionChanged(wxDataViewEvent& ev) _preview->ClearPreview(); // When a directory is selected, open the popup - auto popup = new wxPopupTransientWindow(this); - - popup->SetSizer(new wxBoxSizer(wxVERTICAL)); - + auto popup = new wxutil::TransientPopupWindow(this); auto browser = new TextureDirectoryBrowser(popup, _treeView->GetSelectedFullname()); - //browser->SetMinSize(size); - - wxPoint posScreen; - wxSize sizeScreen; - - const int displayNum = wxDisplay::GetFromPoint(GetScreenPosition()); - if ( displayNum != wxNOT_FOUND ) - { - wxRect rectScreen = wxDisplay(displayNum).GetGeometry(); - posScreen = rectScreen.GetPosition(); - sizeScreen = rectScreen.GetSize(); - } + popup->GetSizer()->Add(browser, 1, wxEXPAND | wxALL, 3); - // From the upper edge of the mediabrowser to the bottom of the screen (minus a few pixels) - wxSize size(600, (posScreen.y + sizeScreen.y) - GetScreenPosition().y - 40); + // Size reaching from the upper edge of the mediabrowser to the bottom of the screen (minus a few pixels) + auto rectScreen = wxutil::MultiMonitor::getMonitorForWindow(this); + int verticalOffset = -(GetScreenPosition().y - rectScreen.GetY()) / 2; + wxSize size(630, rectScreen.GetY() + rectScreen.GetHeight() - GetScreenPosition().y - verticalOffset - 40); - popup->GetSizer()->Add(browser, 1, wxEXPAND); - popup->SetPosition(this->GetScreenRect().GetRightTop()); - popup->SetSize(size); + popup->PositionNextTo(this, verticalOffset, size); popup->Layout(); - //popup->Position(this->GetScreenRect().GetRightTop(), size); popup->Popup(); } diff --git a/tools/msvc/wxutillib.vcxproj b/tools/msvc/wxutillib.vcxproj index 42822cf131..f3edbf1f23 100644 --- a/tools/msvc/wxutillib.vcxproj +++ b/tools/msvc/wxutillib.vcxproj @@ -203,6 +203,7 @@ + diff --git a/tools/msvc/wxutillib.vcxproj.filters b/tools/msvc/wxutillib.vcxproj.filters index ecbce1c322..f823ac457b 100644 --- a/tools/msvc/wxutillib.vcxproj.filters +++ b/tools/msvc/wxutillib.vcxproj.filters @@ -186,6 +186,7 @@ dataview +