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:
parent
1bfb73b877
commit
1f464296de
@ -82,6 +82,7 @@ All (GUI):
|
||||
- Added SetSheetStyle to wxPropertySheetDialog and allowed it to
|
||||
behave like a Mac OS X settings dialog.
|
||||
- Added <disabled> XRC tag for wxToolBar elements and <bg> for wxToolBar itself
|
||||
- Fixed centering of top level windows on secondary displays
|
||||
|
||||
wxMSW:
|
||||
|
||||
|
@ -177,6 +177,11 @@ public:
|
||||
virtual void SetRightMenu(int id = wxID_ANY, const wxString& label = wxEmptyString, wxMenu *subMenu = NULL) = 0;
|
||||
#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
|
||||
// -------------------------------
|
||||
|
||||
@ -216,6 +221,10 @@ protected:
|
||||
virtual void DoClientToScreen(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
|
||||
// (menubar, toolbar and statusbar are excluded from automatic layout)
|
||||
virtual bool IsOneOfBars(const wxWindow *WXUNUSED(win)) const
|
||||
|
@ -332,15 +332,11 @@ public:
|
||||
// the generic centre function - centers the window on parent by`
|
||||
// default or on screen if it doesn't have parent or
|
||||
// wxCENTER_ON_SCREEN flag is given
|
||||
void Centre( int direction = wxBOTH );
|
||||
void Center( int direction = wxBOTH ) { Centre(direction); }
|
||||
|
||||
// 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); }
|
||||
void Centre(int dir = wxBOTH) { DoCentre(dir); }
|
||||
void Center(int dir = wxBOTH) { DoCentre(dir); }
|
||||
|
||||
// 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); }
|
||||
|
||||
// set window size to wrap around its children
|
||||
@ -1295,6 +1291,11 @@ protected:
|
||||
// arrange themselves inside the given rectangle
|
||||
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
|
||||
virtual void DoSetToolTip( wxToolTip *tip );
|
||||
#endif // wxUSE_TOOLTIPS
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "wx/app.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#include "wx/display.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// event table
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -151,6 +153,35 @@ wxSize wxTopLevelWindowBase::GetDefaultSize()
|
||||
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
|
||||
// menu/status/toolbars from the client area, so the client area is what's
|
||||
|
@ -74,10 +74,6 @@
|
||||
#include "wx/caret.h"
|
||||
#endif // wxUSE_CARET
|
||||
|
||||
#if wxUSE_DISPLAY
|
||||
#include "wx/display.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_SYSTEM_OPTIONS
|
||||
#include "wx/sysopt.h"
|
||||
#endif
|
||||
@ -400,142 +396,12 @@ bool wxWindowBase::DestroyChildren()
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// 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
|
||||
wxPoint posParent;
|
||||
int widthParent, heightParent;
|
||||
wxCHECK_RET( !(dir & wxCENTRE_ON_SCREEN) && GetParent(),
|
||||
_T("this method only implements centering child windows") );
|
||||
|
||||
wxWindow *parent = NULL;
|
||||
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);
|
||||
SetSize(GetRect().CentreIn(GetParent()->GetClientSize(), dir));
|
||||
}
|
||||
|
||||
// fits the window around the children
|
||||
|
Loading…
Reference in New Issue
Block a user