fixed centering of top level windows on secondary displays (replaces patch 1267173)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37436 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -82,6 +82,7 @@ All (GUI):
|
|||||||
- Added SetSheetStyle to wxPropertySheetDialog and allowed it to
|
- Added SetSheetStyle to wxPropertySheetDialog and allowed it to
|
||||||
behave like a Mac OS X settings dialog.
|
behave like a Mac OS X settings dialog.
|
||||||
- Added <disabled> XRC tag for wxToolBar elements and <bg> for wxToolBar itself
|
- Added <disabled> XRC tag for wxToolBar elements and <bg> for wxToolBar itself
|
||||||
|
- Fixed centering of top level windows on secondary displays
|
||||||
|
|
||||||
wxMSW:
|
wxMSW:
|
||||||
|
|
||||||
|
@@ -177,6 +177,11 @@ public:
|
|||||||
virtual void SetRightMenu(int id = wxID_ANY, const wxString& label = wxEmptyString, wxMenu *subMenu = NULL) = 0;
|
virtual void SetRightMenu(int id = wxID_ANY, const wxString& label = wxEmptyString, wxMenu *subMenu = NULL) = 0;
|
||||||
#endif // __SMARTPHONE__
|
#endif // __SMARTPHONE__
|
||||||
|
|
||||||
|
// centre the window on screen: this is just a shortcut
|
||||||
|
void CentreOnScreen(int dir = wxBOTH) { DoCentre(dir | wxCENTRE_ON_SCREEN); }
|
||||||
|
void CenterOnScreen(int dir = wxBOTH) { CentreOnScreen(dir); }
|
||||||
|
|
||||||
|
|
||||||
// implementation only from now on
|
// implementation only from now on
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
@@ -216,6 +221,10 @@ protected:
|
|||||||
virtual void DoClientToScreen(int *x, int *y) const;
|
virtual void DoClientToScreen(int *x, int *y) const;
|
||||||
virtual void DoScreenToClient(int *x, int *y) const;
|
virtual void DoScreenToClient(int *x, int *y) const;
|
||||||
|
|
||||||
|
// add support for wxCENTRE_ON_SCREEN
|
||||||
|
virtual void DoCentre(int dir);
|
||||||
|
|
||||||
|
|
||||||
// test whether this window makes part of the frame
|
// test whether this window makes part of the frame
|
||||||
// (menubar, toolbar and statusbar are excluded from automatic layout)
|
// (menubar, toolbar and statusbar are excluded from automatic layout)
|
||||||
virtual bool IsOneOfBars(const wxWindow *WXUNUSED(win)) const
|
virtual bool IsOneOfBars(const wxWindow *WXUNUSED(win)) const
|
||||||
|
@@ -332,15 +332,11 @@ public:
|
|||||||
// the generic centre function - centers the window on parent by`
|
// the generic centre function - centers the window on parent by`
|
||||||
// default or on screen if it doesn't have parent or
|
// default or on screen if it doesn't have parent or
|
||||||
// wxCENTER_ON_SCREEN flag is given
|
// wxCENTER_ON_SCREEN flag is given
|
||||||
void Centre( int direction = wxBOTH );
|
void Centre(int dir = wxBOTH) { DoCentre(dir); }
|
||||||
void Center( int direction = wxBOTH ) { Centre(direction); }
|
void Center(int dir = wxBOTH) { DoCentre(dir); }
|
||||||
|
|
||||||
// centre on screen (only works for top level windows)
|
|
||||||
void CentreOnScreen(int dir = wxBOTH) { Centre(dir | wxCENTER_ON_SCREEN); }
|
|
||||||
void CenterOnScreen(int dir = wxBOTH) { CentreOnScreen(dir); }
|
|
||||||
|
|
||||||
// centre with respect to the the parent window
|
// centre with respect to the the parent window
|
||||||
void CentreOnParent(int dir = wxBOTH) { Centre(dir | wxCENTER_FRAME); }
|
void CentreOnParent(int dir = wxBOTH) { DoCentre(dir); }
|
||||||
void CenterOnParent(int dir = wxBOTH) { CentreOnParent(dir); }
|
void CenterOnParent(int dir = wxBOTH) { CentreOnParent(dir); }
|
||||||
|
|
||||||
// set window size to wrap around its children
|
// set window size to wrap around its children
|
||||||
@@ -1295,6 +1291,11 @@ protected:
|
|||||||
// arrange themselves inside the given rectangle
|
// arrange themselves inside the given rectangle
|
||||||
virtual void DoMoveWindow(int x, int y, int width, int height) = 0;
|
virtual void DoMoveWindow(int x, int y, int width, int height) = 0;
|
||||||
|
|
||||||
|
// centre the window in the specified direction on parent, note that
|
||||||
|
// wxCENTRE_ON_SCREEN shouldn't be specified here, it only makes sense for
|
||||||
|
// TLWs
|
||||||
|
virtual void DoCentre(int dir);
|
||||||
|
|
||||||
#if wxUSE_TOOLTIPS
|
#if wxUSE_TOOLTIPS
|
||||||
virtual void DoSetToolTip( wxToolTip *tip );
|
virtual void DoSetToolTip( wxToolTip *tip );
|
||||||
#endif // wxUSE_TOOLTIPS
|
#endif // wxUSE_TOOLTIPS
|
||||||
|
@@ -29,6 +29,8 @@
|
|||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
#endif // WX_PRECOMP
|
#endif // WX_PRECOMP
|
||||||
|
|
||||||
|
#include "wx/display.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// event table
|
// event table
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -151,6 +153,35 @@ wxSize wxTopLevelWindowBase::GetDefaultSize()
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxTopLevelWindowBase::DoCentre(int dir)
|
||||||
|
{
|
||||||
|
wxRect rectCentre;
|
||||||
|
if ( !(dir & wxCENTRE_ON_SCREEN) && GetParent() )
|
||||||
|
{
|
||||||
|
// centre on parent window
|
||||||
|
rectCentre = GetParent()->GetRect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we were explicitely asked to centre this window on the entire screen
|
||||||
|
// or if we have no parent anyhow and so can't centre on it
|
||||||
|
#if wxUSE_DISPLAY
|
||||||
|
const int nDisplay = wxDisplay::GetFromWindow(this);
|
||||||
|
if ( nDisplay != wxNOT_FOUND )
|
||||||
|
{
|
||||||
|
rectCentre = wxDisplay(nDisplay).GetGeometry();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif // wxUSE_DISPLAY
|
||||||
|
{
|
||||||
|
wxDisplaySize(&rectCentre.width, &rectCentre.height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// window may be at -1 if it's centered on a secondary display, for example
|
||||||
|
SetSize(GetRect().CentreIn(rectCentre, dir), wxSIZE_ALLOW_MINUS_ONE);
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTopLevelWindow size management: we exclude the areas taken by
|
// wxTopLevelWindow size management: we exclude the areas taken by
|
||||||
// menu/status/toolbars from the client area, so the client area is what's
|
// menu/status/toolbars from the client area, so the client area is what's
|
||||||
|
@@ -74,10 +74,6 @@
|
|||||||
#include "wx/caret.h"
|
#include "wx/caret.h"
|
||||||
#endif // wxUSE_CARET
|
#endif // wxUSE_CARET
|
||||||
|
|
||||||
#if wxUSE_DISPLAY
|
|
||||||
#include "wx/display.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if wxUSE_SYSTEM_OPTIONS
|
#if wxUSE_SYSTEM_OPTIONS
|
||||||
#include "wx/sysopt.h"
|
#include "wx/sysopt.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -400,142 +396,12 @@ bool wxWindowBase::DestroyChildren()
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// centre the window with respect to its parent in either (or both) directions
|
// centre the window with respect to its parent in either (or both) directions
|
||||||
void wxWindowBase::Centre(int direction)
|
void wxWindowBase::DoCentre(int dir)
|
||||||
{
|
{
|
||||||
// the position/size of the parent window or of the entire screen
|
wxCHECK_RET( !(dir & wxCENTRE_ON_SCREEN) && GetParent(),
|
||||||
wxPoint posParent;
|
_T("this method only implements centering child windows") );
|
||||||
int widthParent, heightParent;
|
|
||||||
|
|
||||||
wxWindow *parent = NULL;
|
SetSize(GetRect().CentreIn(GetParent()->GetClientSize(), dir));
|
||||||
wxTopLevelWindow *winTop = NULL;
|
|
||||||
|
|
||||||
if ( !(direction & wxCENTRE_ON_SCREEN) )
|
|
||||||
{
|
|
||||||
// find the parent to centre this window on: it should be the
|
|
||||||
// immediate parent for the controls but the top level parent for the
|
|
||||||
// top level windows (like dialogs)
|
|
||||||
parent = GetParent();
|
|
||||||
if ( IsTopLevel() )
|
|
||||||
{
|
|
||||||
while ( parent && !parent->IsTopLevel() )
|
|
||||||
{
|
|
||||||
parent = parent->GetParent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// there is no wxTopLevelWindow under wxMotif yet
|
|
||||||
#ifndef __WXMOTIF__
|
|
||||||
// we shouldn't center the dialog on the iconized window: under
|
|
||||||
// Windows, for example, this places it completely off the screen
|
|
||||||
if ( parent )
|
|
||||||
{
|
|
||||||
winTop = wxDynamicCast(parent, wxTopLevelWindow);
|
|
||||||
if ( winTop && winTop->IsIconized() )
|
|
||||||
{
|
|
||||||
winTop = NULL;
|
|
||||||
parent = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // __WXMOTIF__
|
|
||||||
|
|
||||||
// did we find the parent?
|
|
||||||
if ( !parent )
|
|
||||||
{
|
|
||||||
// no other choice
|
|
||||||
direction |= wxCENTRE_ON_SCREEN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( direction & wxCENTRE_ON_SCREEN )
|
|
||||||
{
|
|
||||||
//RN: If we are using wxDisplay we get
|
|
||||||
//the dimensions of the monitor the window is on,
|
|
||||||
//otherwise we get the dimensions of the primary monitor
|
|
||||||
//FIXME: wxDisplay::GetFromWindow only implemented on MSW
|
|
||||||
#if wxUSE_DISPLAY && defined(__WXMSW__)
|
|
||||||
int nDisplay = wxDisplay::GetFromWindow((wxWindow*)this);
|
|
||||||
if(nDisplay != wxNOT_FOUND)
|
|
||||||
{
|
|
||||||
wxDisplay windowDisplay(nDisplay);
|
|
||||||
wxRect displayRect = windowDisplay.GetGeometry();
|
|
||||||
widthParent = displayRect.width;
|
|
||||||
heightParent = displayRect.height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
// centre with respect to the whole screen
|
|
||||||
wxDisplaySize(&widthParent, &heightParent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( IsTopLevel() )
|
|
||||||
{
|
|
||||||
if(winTop)
|
|
||||||
winTop->GetRectForTopLevelChildren(&posParent.x, &posParent.y, &widthParent, &heightParent);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// centre on the parent
|
|
||||||
parent->GetSize(&widthParent, &heightParent);
|
|
||||||
|
|
||||||
// adjust to the parents position
|
|
||||||
posParent = parent->GetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// centre inside the parents client rectangle
|
|
||||||
parent->GetClientSize(&widthParent, &heightParent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int width, height;
|
|
||||||
GetSize(&width, &height);
|
|
||||||
|
|
||||||
int xNew = wxDefaultCoord,
|
|
||||||
yNew = wxDefaultCoord;
|
|
||||||
|
|
||||||
if ( direction & wxHORIZONTAL )
|
|
||||||
xNew = (widthParent - width)/2;
|
|
||||||
|
|
||||||
if ( direction & wxVERTICAL )
|
|
||||||
yNew = (heightParent - height)/2;
|
|
||||||
|
|
||||||
xNew += posParent.x;
|
|
||||||
yNew += posParent.y;
|
|
||||||
|
|
||||||
// FIXME: This needs to get the client display rect of the display
|
|
||||||
// the window is (via wxDisplay::GetFromWindow).
|
|
||||||
|
|
||||||
// Base size of the visible dimensions of the display
|
|
||||||
// to take into account the taskbar. And the Mac menu bar at top.
|
|
||||||
wxRect clientrect = wxGetClientDisplayRect();
|
|
||||||
|
|
||||||
// NB: in wxMSW, negative position may not necessarily mean "out of screen",
|
|
||||||
// but it may mean that the window is placed on other than the main
|
|
||||||
// display. Therefore we only make sure centered window is on the main display
|
|
||||||
// if the parent is at least partially present here.
|
|
||||||
if (posParent.x + widthParent >= 0) // if parent is (partially) on the main display
|
|
||||||
{
|
|
||||||
if (xNew < clientrect.GetLeft())
|
|
||||||
xNew = clientrect.GetLeft();
|
|
||||||
else if (xNew + width > clientrect.GetRight())
|
|
||||||
xNew = clientrect.GetRight() - width;
|
|
||||||
}
|
|
||||||
if (posParent.y + heightParent >= 0) // if parent is (partially) on the main display
|
|
||||||
{
|
|
||||||
if (yNew + height > clientrect.GetBottom())
|
|
||||||
yNew = clientrect.GetBottom() - height;
|
|
||||||
|
|
||||||
// Make certain that the title bar is initially visible
|
|
||||||
// always, even if this would push the bottom of the
|
|
||||||
// dialog off the visible area of the display
|
|
||||||
if (yNew < clientrect.GetTop())
|
|
||||||
yNew = clientrect.GetTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// move the window to this position (keeping the old size but using
|
|
||||||
// SetSize() and not Move() to allow xNew and/or yNew to be wxDefaultCoord)
|
|
||||||
SetSize(xNew, yNew, width, height, wxSIZE_ALLOW_MINUS_ONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fits the window around the children
|
// fits the window around the children
|
||||||
|
Reference in New Issue
Block a user