Introduce platform-dependent wxTLWGeometry class
Previously, TLW geometry was implicitly defined as just its position, size and the maximized/iconized state by wxPersistentTLW code. This already wasn't enough for wxGTK which added the decoration sizes to the geometry being saved/restored, but this had to be done using conditional compilation, which was not ideal. And it didn't allow using an entirely different geometry representation as will be done for wxMSW soon. Change the code to use wxTLWGeometry class defining the geometry, as used by the current port, explicitly and move wxPersistentTLW logic into it, as wxPersistentXXX classes are supposed to be very simple, which wasn't really the case. Also provide public SaveGeometry() and RestoreToGeometry() methods in wxTopLevelWindow, which can be useful even to people not using wxPersistentTLW for whatever reason. There should be no changes in behaviour so far.
This commit is contained in:
77
include/wx/gtk/private/tlwgeom.h
Normal file
77
include/wx/gtk/private/tlwgeom.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/gtk/private/tlwgeom.h
|
||||||
|
// Purpose: wxGTK-specific wxTLWGeometry class.
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2018-04-29
|
||||||
|
// Copyright: (c) 2018 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_GTK_PRIVATE_TLWGEOM_H_
|
||||||
|
#define _WX_GTK_PRIVATE_TLWGEOM_H_
|
||||||
|
|
||||||
|
class wxTLWGeometry : public wxTLWGeometryGeneric
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool Save(const Serializer& ser) const wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( !wxTLWGeometryGeneric::Save(ser) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't save the decoration sizes if we don't really have any values
|
||||||
|
// for them.
|
||||||
|
if ( m_decorSize.left || m_decorSize.right ||
|
||||||
|
m_decorSize.top || m_decorSize.bottom )
|
||||||
|
{
|
||||||
|
ser.SaveField("decor_l", m_decorSize.left);
|
||||||
|
ser.SaveField("decor_r", m_decorSize.right);
|
||||||
|
ser.SaveField("decor_t", m_decorSize.top);
|
||||||
|
ser.SaveField("decor_b", m_decorSize.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Restore(Serializer& ser) wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( !wxTLWGeometryGeneric::Restore(ser) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ser.RestoreField("decor_l", &m_decorSize.left);
|
||||||
|
ser.RestoreField("decor_r", &m_decorSize.right);
|
||||||
|
ser.RestoreField("decor_t", &m_decorSize.top);
|
||||||
|
ser.RestoreField("decor_b", &m_decorSize.bottom);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetFrom(const wxTopLevelWindow* tlw) wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( !wxTLWGeometryGeneric::GetFrom(tlw) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_decorSize = tlw->m_decorSize;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool ApplyTo(wxTopLevelWindow* tlw) wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( !wxTLWGeometryGeneric::ApplyTo(tlw) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Don't overwrite the current decoration size if we already have it.
|
||||||
|
if ( !tlw->m_decorSize.left && !tlw->m_decorSize.right &&
|
||||||
|
!tlw->m_decorSize.top && !tlw->m_decorSize.bottom )
|
||||||
|
{
|
||||||
|
tlw->m_decorSize = m_decorSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxTopLevelWindow::DecorSize m_decorSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _WX_GTK_PRIVATE_TLWGEOM_H_
|
@@ -13,7 +13,6 @@
|
|||||||
#include "wx/persist/window.h"
|
#include "wx/persist/window.h"
|
||||||
|
|
||||||
#include "wx/toplevel.h"
|
#include "wx/toplevel.h"
|
||||||
#include "wx/display.h"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// string constants used by wxPersistentTLW
|
// string constants used by wxPersistentTLW
|
||||||
@@ -24,21 +23,13 @@
|
|||||||
// windows, just persistent controls which have their own specific kind strings
|
// windows, just persistent controls which have their own specific kind strings
|
||||||
#define wxPERSIST_TLW_KIND "Window"
|
#define wxPERSIST_TLW_KIND "Window"
|
||||||
|
|
||||||
// names for various persistent options
|
|
||||||
#define wxPERSIST_TLW_X "x"
|
|
||||||
#define wxPERSIST_TLW_Y "y"
|
|
||||||
#define wxPERSIST_TLW_W "w"
|
|
||||||
#define wxPERSIST_TLW_H "h"
|
|
||||||
|
|
||||||
#define wxPERSIST_TLW_MAXIMIZED "Maximized"
|
|
||||||
#define wxPERSIST_TLW_ICONIZED "Iconized"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxPersistentTLW: supports saving/restoring window position and size as well
|
// wxPersistentTLW: supports saving/restoring window position and size as well
|
||||||
// as maximized/iconized/restore state
|
// as maximized/iconized/restore state
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class wxPersistentTLW : public wxPersistentWindow<wxTopLevelWindow>
|
class wxPersistentTLW : public wxPersistentWindow<wxTopLevelWindow>,
|
||||||
|
private wxTopLevelWindow::GeometrySerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
wxPersistentTLW(wxTopLevelWindow *tlw)
|
wxPersistentTLW(wxTopLevelWindow *tlw)
|
||||||
@@ -50,96 +41,28 @@ public:
|
|||||||
{
|
{
|
||||||
const wxTopLevelWindow * const tlw = Get();
|
const wxTopLevelWindow * const tlw = Get();
|
||||||
|
|
||||||
const wxPoint pos = tlw->GetScreenPosition();
|
tlw->SaveGeometry(*this);
|
||||||
SaveValue(wxPERSIST_TLW_X, pos.x);
|
|
||||||
SaveValue(wxPERSIST_TLW_Y, pos.y);
|
|
||||||
|
|
||||||
// notice that we use GetSize() here and not GetClientSize() because
|
|
||||||
// the latter doesn't return correct results for the minimized windows
|
|
||||||
// (at least not under Windows)
|
|
||||||
//
|
|
||||||
// of course, it shouldn't matter anyhow usually, the client size
|
|
||||||
// should be preserved as well unless the size of the decorations
|
|
||||||
// changed between the runs
|
|
||||||
const wxSize size = tlw->GetSize();
|
|
||||||
SaveValue(wxPERSIST_TLW_W, size.x);
|
|
||||||
SaveValue(wxPERSIST_TLW_H, size.y);
|
|
||||||
|
|
||||||
SaveValue(wxPERSIST_TLW_MAXIMIZED, tlw->IsMaximized());
|
|
||||||
SaveValue(wxPERSIST_TLW_ICONIZED, tlw->IsIconized());
|
|
||||||
#ifdef __WXGTK20__
|
|
||||||
SaveValue("decor_l", tlw->m_decorSize.left);
|
|
||||||
SaveValue("decor_r", tlw->m_decorSize.right);
|
|
||||||
SaveValue("decor_t", tlw->m_decorSize.top);
|
|
||||||
SaveValue("decor_b", tlw->m_decorSize.bottom);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool Restore() wxOVERRIDE
|
virtual bool Restore() wxOVERRIDE
|
||||||
{
|
{
|
||||||
wxTopLevelWindow * const tlw = Get();
|
wxTopLevelWindow * const tlw = Get();
|
||||||
|
|
||||||
wxPoint pos;
|
return tlw->RestoreToGeometry(*this);
|
||||||
wxSize size;
|
|
||||||
|
|
||||||
const bool hasPos = RestoreValue(wxPERSIST_TLW_X, &pos.x) &&
|
|
||||||
RestoreValue(wxPERSIST_TLW_Y, &pos.y);
|
|
||||||
const bool hasSize = RestoreValue(wxPERSIST_TLW_W, &size.x) &&
|
|
||||||
RestoreValue(wxPERSIST_TLW_H, &size.y);
|
|
||||||
#ifdef __WXGTK20__
|
|
||||||
wxTopLevelWindowGTK::DecorSize decorSize;
|
|
||||||
if (tlw->m_decorSize.top == 0 &&
|
|
||||||
RestoreValue("decor_l", &decorSize.left) &&
|
|
||||||
RestoreValue("decor_r", &decorSize.right) &&
|
|
||||||
RestoreValue("decor_t", &decorSize.top) &&
|
|
||||||
RestoreValue("decor_b", &decorSize.bottom))
|
|
||||||
{
|
|
||||||
tlw->m_decorSize = decorSize;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ( hasPos )
|
|
||||||
{
|
|
||||||
// to avoid making the window completely invisible if it had been
|
|
||||||
// shown on a monitor which was disconnected since the last run
|
|
||||||
// (this is pretty common for notebook with external displays)
|
|
||||||
//
|
|
||||||
// NB: we should allow window position to be (slightly) off screen,
|
|
||||||
// it's not uncommon to position the window so that its upper
|
|
||||||
// left corner has slightly negative coordinate
|
|
||||||
if ( wxDisplay::GetFromPoint(pos) != wxNOT_FOUND ||
|
|
||||||
(hasSize && wxDisplay::GetFromPoint(pos + size) != wxNOT_FOUND) )
|
|
||||||
{
|
|
||||||
tlw->Move(pos, wxSIZE_ALLOW_MINUS_ONE);
|
|
||||||
}
|
|
||||||
//else: should we try to adjust position/size somehow?
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( hasSize )
|
|
||||||
{
|
|
||||||
// a previous version of the program could have saved the window
|
|
||||||
// size which used to be big enough, but which is not big enough
|
|
||||||
// any more for the new version, so check that the size we restore
|
|
||||||
// doesn't cut off parts of the window
|
|
||||||
size.IncTo(tlw->GetBestSize());
|
|
||||||
tlw->SetSize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// note that the window can be both maximized and iconized
|
|
||||||
bool maximized;
|
|
||||||
if ( RestoreValue(wxPERSIST_TLW_MAXIMIZED, &maximized) && maximized )
|
|
||||||
tlw->Maximize();
|
|
||||||
|
|
||||||
bool iconized;
|
|
||||||
if ( RestoreValue(wxPERSIST_TLW_ICONIZED, &iconized) && iconized )
|
|
||||||
tlw->Iconize();
|
|
||||||
|
|
||||||
// the most important property of the window that we restore is its
|
|
||||||
// size, so disregard the value of hasPos here
|
|
||||||
return hasSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual wxString GetKind() const wxOVERRIDE { return wxPERSIST_TLW_KIND; }
|
virtual wxString GetKind() const wxOVERRIDE { return wxPERSIST_TLW_KIND; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool SaveField(const wxString& name, int value) const wxOVERRIDE
|
||||||
|
{
|
||||||
|
return SaveValue(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool RestoreField(const wxString& name, int* value) wxOVERRIDE
|
||||||
|
{
|
||||||
|
return RestoreValue(name, value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *tlw)
|
inline wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *tlw)
|
||||||
|
177
include/wx/private/tlwgeom.h
Normal file
177
include/wx/private/tlwgeom.h
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: wx/private/tlwgeom.h
|
||||||
|
// Purpose: Declaration of platform-specific and private wxTLWGeometry.
|
||||||
|
// Author: Vadim Zeitlin
|
||||||
|
// Created: 2018-04-29
|
||||||
|
// Copyright: (c) 2018 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_PRIVATE_TLWGEOM_H_
|
||||||
|
#define _WX_PRIVATE_TLWGEOM_H_
|
||||||
|
|
||||||
|
#include "wx/display.h"
|
||||||
|
#include "wx/toplevel.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTLWGeometryBase: abstract base class for platform-specific classes
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// wxTLWGeometry contains full information about the window geometry, which may
|
||||||
|
// include things other than the obvious ones like its current position and
|
||||||
|
// size (e.g. under MSW it also stores the position of the maximized window,
|
||||||
|
// under GTK the size of non-client decorations etc). It is private to wx and
|
||||||
|
// is only used indirectly, via wxTopLevelWindow::SaveGeometry() and
|
||||||
|
// RestoreToGeometry() methods, in the public API.
|
||||||
|
|
||||||
|
class wxTLWGeometryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef wxTopLevelWindow::GeometrySerializer Serializer;
|
||||||
|
|
||||||
|
wxTLWGeometryBase() {}
|
||||||
|
virtual ~wxTLWGeometryBase() {}
|
||||||
|
|
||||||
|
// Initialize from the given window.
|
||||||
|
virtual bool GetFrom(const wxTopLevelWindow* tlw) = 0;
|
||||||
|
|
||||||
|
// Resize the window to use this geometry.
|
||||||
|
virtual bool ApplyTo(wxTopLevelWindow* tlw) = 0;
|
||||||
|
|
||||||
|
// Serialize or deserialize the object by using the provided object for
|
||||||
|
// writing/reading the values of the different fields of this object.
|
||||||
|
virtual bool Save(const Serializer& ser) const = 0;
|
||||||
|
virtual bool Restore(Serializer& ser) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// wxTLWGeometryGeneric: simplest possible generic implementation
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// names for various persistent options
|
||||||
|
#define wxPERSIST_TLW_X "x"
|
||||||
|
#define wxPERSIST_TLW_Y "y"
|
||||||
|
#define wxPERSIST_TLW_W "w"
|
||||||
|
#define wxPERSIST_TLW_H "h"
|
||||||
|
|
||||||
|
#define wxPERSIST_TLW_MAXIMIZED "Maximized"
|
||||||
|
#define wxPERSIST_TLW_ICONIZED "Iconized"
|
||||||
|
|
||||||
|
class wxTLWGeometryGeneric : public wxTLWGeometryBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxTLWGeometryGeneric()
|
||||||
|
{
|
||||||
|
m_hasPos =
|
||||||
|
m_hasSize =
|
||||||
|
m_iconized =
|
||||||
|
m_maximized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Save(const Serializer& ser) const wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( !ser.SaveField(wxPERSIST_TLW_X, m_rectScreen.x) ||
|
||||||
|
!ser.SaveField(wxPERSIST_TLW_Y, m_rectScreen.y) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !ser.SaveField(wxPERSIST_TLW_W, m_rectScreen.width) ||
|
||||||
|
!ser.SaveField(wxPERSIST_TLW_H, m_rectScreen.height) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !ser.SaveField(wxPERSIST_TLW_MAXIMIZED, m_maximized) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !ser.SaveField(wxPERSIST_TLW_ICONIZED, m_iconized) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool Restore(Serializer& ser) wxOVERRIDE
|
||||||
|
{
|
||||||
|
m_hasPos = ser.RestoreField(wxPERSIST_TLW_X, &m_rectScreen.x) &&
|
||||||
|
ser.RestoreField(wxPERSIST_TLW_Y, &m_rectScreen.y);
|
||||||
|
|
||||||
|
m_hasSize = ser.RestoreField(wxPERSIST_TLW_W, &m_rectScreen.width) &&
|
||||||
|
ser.RestoreField(wxPERSIST_TLW_H, &m_rectScreen.height);
|
||||||
|
|
||||||
|
int tmp;
|
||||||
|
if ( ser.RestoreField(wxPERSIST_TLW_MAXIMIZED, &tmp) )
|
||||||
|
m_maximized = tmp != 0;
|
||||||
|
|
||||||
|
if ( ser.RestoreField(wxPERSIST_TLW_ICONIZED, &tmp) )
|
||||||
|
m_iconized = tmp != 0;
|
||||||
|
|
||||||
|
// If we restored at least something, return true.
|
||||||
|
return m_hasPos || m_hasSize || m_maximized || m_iconized;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool GetFrom(const wxTopLevelWindow* tlw) wxOVERRIDE
|
||||||
|
{
|
||||||
|
m_rectScreen = tlw->GetScreenRect();
|
||||||
|
m_hasPos =
|
||||||
|
m_hasSize = true;
|
||||||
|
m_iconized = tlw->IsIconized();
|
||||||
|
m_maximized = tlw->IsMaximized();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool ApplyTo(wxTopLevelWindow* tlw) wxOVERRIDE
|
||||||
|
{
|
||||||
|
if ( m_hasPos )
|
||||||
|
{
|
||||||
|
// to avoid making the window completely invisible if it had been
|
||||||
|
// shown on a monitor which was disconnected since the last run
|
||||||
|
// (this is pretty common for notebook with external displays)
|
||||||
|
//
|
||||||
|
// NB: we should allow window position to be (slightly) off screen,
|
||||||
|
// it's not uncommon to position the window so that its upper
|
||||||
|
// left corner has slightly negative coordinate
|
||||||
|
if ( wxDisplay::GetFromPoint(m_rectScreen.GetTopLeft()) != wxNOT_FOUND ||
|
||||||
|
(m_hasSize &&
|
||||||
|
wxDisplay::GetFromPoint(m_rectScreen.GetBottomRight()) != wxNOT_FOUND) )
|
||||||
|
{
|
||||||
|
tlw->Move(m_rectScreen.GetTopLeft(), wxSIZE_ALLOW_MINUS_ONE);
|
||||||
|
}
|
||||||
|
//else: should we try to adjust position/size somehow?
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_hasSize )
|
||||||
|
{
|
||||||
|
// a previous version of the program could have saved the window
|
||||||
|
// size which used to be big enough, but which is not big enough
|
||||||
|
// any more for the new version, so check that the size we restore
|
||||||
|
// doesn't cut off parts of the window
|
||||||
|
wxSize size = m_rectScreen.GetSize();
|
||||||
|
size.IncTo(tlw->GetBestSize());
|
||||||
|
tlw->SetSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// note that the window can be both maximized and iconized
|
||||||
|
if ( m_maximized )
|
||||||
|
tlw->Maximize();
|
||||||
|
|
||||||
|
if ( m_iconized )
|
||||||
|
tlw->Iconize();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxRect m_rectScreen;
|
||||||
|
bool m_hasPos;
|
||||||
|
bool m_hasSize;
|
||||||
|
bool m_iconized;
|
||||||
|
bool m_maximized;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __WXGTK20__
|
||||||
|
#include "wx/gtk/private/tlwgeom.h"
|
||||||
|
#else
|
||||||
|
class wxTLWGeometry : public wxTLWGeometryGeneric
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _WX_PRIVATE_TLWGEOM_H_
|
@@ -238,6 +238,35 @@ public:
|
|||||||
wxWindow *SetTmpDefaultItem(wxWindow *win)
|
wxWindow *SetTmpDefaultItem(wxWindow *win)
|
||||||
{ wxWindow *old = GetDefaultItem(); m_winTmpDefault = win; return old; }
|
{ wxWindow *old = GetDefaultItem(); m_winTmpDefault = win; return old; }
|
||||||
|
|
||||||
|
|
||||||
|
// Class for saving/restoring fields describing the window geometry.
|
||||||
|
//
|
||||||
|
// This class is used by the functions below to allow saving the geometry
|
||||||
|
// of the window and restoring it later. The components describing geometry
|
||||||
|
// are platform-dependent, so there is no struct containing them and
|
||||||
|
// instead the methods of this class are used to save or [try to] restore
|
||||||
|
// whichever components are used under the current platform.
|
||||||
|
class GeometrySerializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~GeometrySerializer() {}
|
||||||
|
|
||||||
|
// If saving a field returns false, it's fatal error and SaveGeometry()
|
||||||
|
// will return false.
|
||||||
|
virtual bool SaveField(const wxString& name, int value) const = 0;
|
||||||
|
|
||||||
|
// If restoring a field returns false, it just means that the field is
|
||||||
|
// not present and RestoreToGeometry() still continues with restoring
|
||||||
|
// the other values.
|
||||||
|
virtual bool RestoreField(const wxString& name, int* value) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save the current window geometry using the provided serializer and
|
||||||
|
// restore the window to the previously saved geometry.
|
||||||
|
bool SaveGeometry(const GeometrySerializer& ser) const;
|
||||||
|
bool RestoreToGeometry(GeometrySerializer& ser);
|
||||||
|
|
||||||
|
|
||||||
// implementation only from now on
|
// implementation only from now on
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
|
@@ -350,6 +350,94 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Restore();
|
void Restore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Class used with SaveGeometry() and RestoreToGeometry().
|
||||||
|
|
||||||
|
This is an abstract base class, i.e. to use it you must define a
|
||||||
|
derived class implementing the pure virtual SaveField() and
|
||||||
|
RestoreField() methods.
|
||||||
|
|
||||||
|
For example, if you wished to store the window geometry in a database,
|
||||||
|
you could derive a class saving fields such as "width" or "height" in a
|
||||||
|
table in this database and restoring them from it later.
|
||||||
|
|
||||||
|
@since 3.1.2
|
||||||
|
*/
|
||||||
|
class GeometrySerializer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
Save a single field with the given value.
|
||||||
|
|
||||||
|
Note that if this function returns @false, SaveGeometry() supposes
|
||||||
|
that saving the geometry failed and returns @false itself, without
|
||||||
|
even trying to save anything else.
|
||||||
|
|
||||||
|
@param name uniquely identifies the field but is otherwise
|
||||||
|
arbitrary.
|
||||||
|
@param value value of the field (can be positive or negative, i.e.
|
||||||
|
it can't be assumed that a value like -1 is invalid).
|
||||||
|
|
||||||
|
@return @true if the field was saved or @false if saving it failed,
|
||||||
|
resulting in wxTopLevelWindow::SaveGeometry() failure.
|
||||||
|
*/
|
||||||
|
virtual bool SaveField(const wxString& name, int value) const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Try to restore a single field.
|
||||||
|
|
||||||
|
Unlike for SaveField(), returning @false from this function may
|
||||||
|
indicate that the value simply wasn't present and doesn't prevent
|
||||||
|
RestoreToGeometry() from continuing with trying to restore the
|
||||||
|
other values.
|
||||||
|
|
||||||
|
@param name uniquely identifies the field
|
||||||
|
@param value non-@NULL pointer to the value to be filled by this
|
||||||
|
function
|
||||||
|
|
||||||
|
@return @true if the value was retrieved or @false if it wasn't
|
||||||
|
found or an error occurred.
|
||||||
|
*/
|
||||||
|
virtual bool RestoreField(const wxString& name, int* value) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Restores the window to the previously saved geometry.
|
||||||
|
|
||||||
|
This is a companion function to SaveGeometry() and can be called later
|
||||||
|
to restore the window to the geometry it had when it was saved.
|
||||||
|
|
||||||
|
@param ser An object implementing GeometrySerializer virtual methods.
|
||||||
|
|
||||||
|
@return @true if any (and, usually, but not necessarily, all) of the
|
||||||
|
window geometry attributes were restored or @false if there was no
|
||||||
|
saved geometry information at all or restoring it failed.
|
||||||
|
|
||||||
|
@since 3.1.2
|
||||||
|
*/
|
||||||
|
bool RestoreToGeometry(GeometrySerializer& ser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save the current window geometry to allow restoring it later.
|
||||||
|
|
||||||
|
After calling this function, window geometry is saved in the provided
|
||||||
|
serializer and calling RestoreToGeometry() with the same serializer
|
||||||
|
later (i.e. usually during a subsequent program execution) would
|
||||||
|
restore the window to the same position, size, maximized/minimized
|
||||||
|
state etc.
|
||||||
|
|
||||||
|
This function is used by wxPersistentTLW, so it is not necessary to use
|
||||||
|
it if the goal is to just save and restore window geometry in the
|
||||||
|
simplest possible way. However is more flexibility is required, it can
|
||||||
|
be also used directly with a custom serializer object.
|
||||||
|
|
||||||
|
@param ser An object implementing GeometrySerializer virtual methods.
|
||||||
|
|
||||||
|
@return @true if the geometry was saved, @false if doing it failed
|
||||||
|
|
||||||
|
@since 3.1.2
|
||||||
|
*/
|
||||||
|
bool SaveGeometry(const GeometrySerializer& ser) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Changes the default item for the panel, usually @a win is a button.
|
Changes the default item for the panel, usually @a win is a button.
|
||||||
|
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
|
|
||||||
#include "wx/display.h"
|
#include "wx/display.h"
|
||||||
|
|
||||||
|
#include "wx/private/tlwgeom.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// event table
|
// event table
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -310,6 +312,28 @@ void wxTopLevelWindowBase::DoCentre(int dir)
|
|||||||
SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
|
SetSize(rect, wxSIZE_ALLOW_MINUS_ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Saving/restoring geometry
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool wxTopLevelWindowBase::SaveGeometry(const GeometrySerializer& ser) const
|
||||||
|
{
|
||||||
|
wxTLWGeometry geom;
|
||||||
|
if ( !geom.GetFrom(static_cast<const wxTopLevelWindow*>(this)) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return geom.Save(ser);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxTopLevelWindowBase::RestoreToGeometry(GeometrySerializer& ser)
|
||||||
|
{
|
||||||
|
wxTLWGeometry geom;
|
||||||
|
if ( !geom.Restore(ser) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return geom.ApplyTo(static_cast<wxTopLevelWindow*>(this));
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// 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
|
||||||
|
Reference in New Issue
Block a user