///////////////////////////////////////////////////////////////////////////////
// Name: wx/aui/serializer.h
// Purpose: Declaration of wxAuiSerializer and wxAuiDeserializer classes.
// Author: Vadim Zeitlin
// Created: 2024-01-20
// Copyright: (c) 2024 Vadim Zeitlin <vadim@wxwidgets.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_AUI_SERIALIZER_H_
#define _WX_AUI_SERIALIZER_H_
#include "wx/aui/framemanager.h" // Just for wxAUI_DOCK_LEFT
#if wxUSE_AUI
#include <utility>
#include <vector>
class WXDLLIMPEXP_FWD_AUI wxAuiNotebook;
class WXDLLIMPEXP_FWD_AUI wxAuiTabCtrl;
// ----------------------------------------------------------------------------
// Classes used to save/load wxAuiManager layout.
// ----------------------------------------------------------------------------
// Fields common to wxAuiPaneLayoutInfo and wxAuiTabLayoutInfo containing
// information about a docked pane or tab layout.
struct wxAuiDockLayoutInfo
{
// Identifies the dock containing the pane.
int dock_direction = wxAUI_DOCK_LEFT;
int dock_layer = 0;
int dock_row = 0;
int dock_pos = 0;
int dock_proportion = 0;
// Size of the containing dock.
//
// Note that storing the dock size is redundant as it can be calculated
// from pane sizes, but storing all pane sizes would be redundant too, so
// we prefer to keep things simple and store just this size.
int dock_size = 0;
};
// This struct contains information about the layout of a tab control in a
// wxAuiNotebook, including where it is docked and the order of pages in it.
struct wxAuiTabLayoutInfo : wxAuiDockLayoutInfo
{
// If this vector is empty, it means that the tab control contains all
// notebook pages in natural order.
std::vector<int> pages;
// Vectors contain indices of pinned pages, if any, i.e. it can be empty.
std::vector<int> pinned;
// Currently active page in this tab control.
int active = 0;
};
// This struct contains the pane name and information about its layout that can
// be manipulated by the user interactively.
struct wxAuiPaneLayoutInfo : wxAuiDockLayoutInfo
{
// Ctor sets the name, which is always required.
explicit wxAuiPaneLayoutInfo(wxString name_) : name{std::move(name_)} { }
// Unique name of the pane.
wxString name;
// Floating pane geometry, may be invalid.
wxPoint floating_pos = wxDefaultPosition;
wxSize floating_size = wxDefaultSize;
wxSize floating_client_size = wxDefaultSize;
// The remaining fields correspond to individual bits of the pane state
// flags instead of corresponding to wxAuiPaneInfo fields directly because
// we prefer not storing the entire state -- this would be less readable
// and extensible.
// True if the pane is currently maximized.
bool is_maximized = false;
// True if the pane is currently hidden.
bool is_hidden = false;
};
// wxAuiBookSerializer is used for serializing wxAuiNotebook layout.
//
// This includes the tab controls layout and the order of pages in them.
//
// It can be used standalone with wxAuiNotebook::SaveLayout() or as base class
// of wxAuiSerializer for saving and restoring the entire layout.
class wxAuiBookSerializer
{
public:
// Trivial default ctor.
wxAuiBookSerializer() = default;
// Trivial but virtual dtor for a base class.
virtual ~wxAuiBookSerializer() = default;
// Called before starting to save information about the tabs in the
// notebook in the AUI pane with the given name.
virtual void BeforeSaveNotebook(const wxString& name) = 0;
// Called to save information about a single tab control in the given
// notebook.
virtual void SaveNotebookTabControl(const wxAuiTabLayoutInfo& tab) = 0;
// Called after saving information about all the pages of the notebook in
// the AUI pane with the given name, does nothing by default.
virtual void AfterSaveNotebook() { }
};
// wxAuiSerializer is used with wxAuiManager::SaveLayout().
//
// This is an abstract base class, you need to inherit from it and override its
// pure virtual functions, including those inherited from wxAuiBookSerializer,
// in your derived class.
//
// If any of the functions of the derived class throw an exception, it is
// propagated out of wxAuiManager::SaveLayout() and it's callers responsibility
// to handle it.
class wxAuiSerializer : public wxAuiBookSerializer
{
public:
// Trivial default ctor.
wxAuiSerializer() = default;
// Called before doing anything else, does nothing by default.
virtual void BeforeSave() { }
// Called before starting to save information about the panes, does nothing
// by default.
virtual void BeforeSavePanes() { }
// Save information about the given pane.
virtual void SavePane(const wxAuiPaneLayoutInfo& pane) = 0;
// Called after the last call to SavePane(), does nothing by default.
virtual void AfterSavePanes() { }
// Called before starting to save information about the notebooks, does
// nothing by default.
virtual void BeforeSaveNotebooks() { }
// Called after the last call to SaveNotebook(), does nothing by default.
virtual void AfterSaveNotebooks() { }
// Called after saving everything, does nothing by default.
virtual void AfterSave() { }
};
// wxAuiBookDeserializer is used for deserializing wxAuiNotebook layout.
//
// Similarly to wxAuiBookSerializer, it can be used standalone with
// wxAuiNotebook::LoadLayout() or as base class of wxAuiDeserializer.
class wxAuiBookDeserializer
{
public:
// Trivial default ctor.
wxAuiBookDeserializer() = default;
// Trivial but virtual dtor for a base class.
virtual ~wxAuiBookDeserializer() = default;
// Load information about all the tab controls in the pane containing
// wxAuiNotebook with the given name.
virtual std::vector<wxAuiTabLayoutInfo>
LoadNotebookTabs(const wxString& name) = 0;
// If any pages haven't been assigned to any tab control after restoring
// the pages order, they are passed to this function to determine what to
// do with them.
//
// By default, it returns true without modifying the output arguments,
// which results in the page being appended to the main tab control. It may
// also modify tabCtrl and tabIndex arguments to modify where the page
// should appear or return false to remove the page from the notebook
// completely.
virtual bool
HandleOrphanedPage(wxAuiNotebook& WXUNUSED(book),
int WXUNUSED(page),
wxAuiTabCtrl** WXUNUSED(tabCtrl),
int* WXUNUSED(tabIndex))
{ return true; }
};
// wxAuiDeserializer is used with wxAuiManager::LoadLayout().
//
// As wxAuiSerializer, this is an abstract base class, you need to inherit from
// it and override its pure virtual functions in your derived class.
//
// Derived class function also may throw and, if any of them other than
// AfterLoad() does, the existing layout is not changed, i.e.
// wxAuiManager::LoadLayout() is exception-safe.
class wxAuiDeserializer : public wxAuiBookDeserializer
{
public:
// Ctor takes the manager for which we're restoring the layout, it must
// remain valid for the lifetime of this object.
explicit wxAuiDeserializer(wxAuiManager& manager) : m_manager(manager) { }
// Called before doing anything else, does nothing by default.
virtual void BeforeLoad() { }
// Load information about all the panes previously saved with SavePane().
virtual std::vector<wxAuiPaneLayoutInfo> LoadPanes() = 0;
// Create the window to be managed by the given pane: this is called if any
// of the panes returned by LoadPanes() doesn't exist in the existing
// layout and allows to create windows on the fly.
//
// If this function returns nullptr, the pane is not added to the manager.
//
// Note that the pane info may (and usually will, if a window is created)
// be modified, to set fields such as caption or icon and any flags other
// "maximized".
virtual wxWindow* CreatePaneWindow(wxAuiPaneInfo& WXUNUSED(pane))
{
return nullptr;
}
// Called after restoring everything, calls Update() on the manager by
// default.
virtual void AfterLoad() { m_manager.Update(); }
protected:
// The manager for which we're restoring the layout.
wxAuiManager& m_manager;
};
#endif // wxUSE_AUI
#endif // _WX_AUI_SERIALIZER_H_