From 50c06297bd2a5b496a899198a5957755655ab43d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 17 Mar 2005 21:17:38 +0000 Subject: [PATCH] added wxSizerSpacer and modified wxSizerItem to contain a pointer to either wxWindow, wxSizer or wxSizerSpacer (instead of containing either a pointer or just wxSize for spacers) and implement IsShown() and Show() by forwarding it to the appropriate pointer: this means that now you can directly hide/show windows/sizers/spacers instead of having to pass by containing sizers Show(child) method git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@32865 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/sizer.h | 155 +++++++++++++-------- src/common/sizer.cpp | 317 +++++++++++++++++++++++++++++-------------- 2 files changed, 313 insertions(+), 159 deletions(-) diff --git a/include/wx/sizer.h b/include/wx/sizer.h index 78581ba30c..9b84741354 100644 --- a/include/wx/sizer.h +++ b/include/wx/sizer.h @@ -102,29 +102,36 @@ private: }; -//--------------------------------------------------------------------------- -// wxSizerItem -//--------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- +// wxSizerSpacer: used by wxSizerItem to represent a spacer +// ---------------------------------------------------------------------------- -class WXDLLEXPORT wxSizerItem: public wxObject +class WXDLLEXPORT wxSizerSpacer { public: - // window with flags - wxSizerItem(wxWindow *window, const wxSizerFlags& flags) - { - Init(flags); + wxSizerSpacer(const wxSize& size) : m_size(size), m_isShown(true) { } - m_window = window; - } + void SetSize(const wxSize& size) { m_size = size; } + const wxSize& GetSize() const { return m_size; } - // sizer with flags - wxSizerItem(wxSizer *sizer, const wxSizerFlags& flags) - { - Init(flags); + void Show(bool show) { m_isShown = show; } + bool IsShown() const { return m_isShown; } - m_sizer = sizer; - } +private: + // the size, in pixel + wxSize m_size; + // is the spacer currently shown? + bool m_isShown; +}; + +// ---------------------------------------------------------------------------- +// wxSizerItem +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxSizerItem : public wxObject +{ +public: // window wxSizerItem( wxWindow *window, int proportion, @@ -132,6 +139,14 @@ public: int border, wxObject* userData ); + // window with flags + wxSizerItem(wxWindow *window, const wxSizerFlags& flags) + { + Init(flags); + + SetWindow(window); + } + // subsizer wxSizerItem( wxSizer *sizer, int proportion, @@ -139,6 +154,14 @@ public: int border, wxObject* userData ); + // sizer with flags + wxSizerItem(wxSizer *sizer, const wxSizerFlags& flags) + { + Init(flags); + + SetSizer(sizer); + } + // spacer wxSizerItem( int width, int height, @@ -147,14 +170,21 @@ public: int border, wxObject* userData); + // spacer with flags + wxSizerItem(int width, int height, const wxSizerFlags& flags) + { + Init(flags); + + SetSpacer(width, height); + } + wxSizerItem(); virtual ~wxSizerItem(); virtual void DeleteWindows(); // Enable deleting the SizerItem without destroying the contained sizer. - void DetachSizer() - { m_sizer = 0; } + void DetachSizer() { m_sizer = NULL; } virtual wxSize GetSize() const; virtual wxSize CalcMin(); @@ -165,31 +195,32 @@ public: wxSize GetMinSizeWithBorder() const; void SetMinSize(const wxSize& size) - { - if (IsWindow()) m_window->SetMinSize(size); - m_minSize = size; - } + { + if ( IsWindow() ) + m_window->SetMinSize(size); + m_minSize = size; + } void SetMinSize( int x, int y ) { SetMinSize(wxSize(x, y)); } void SetInitSize( int x, int y ) { SetMinSize(wxSize(x, y)); } - void SetRatio( int width, int height ) - // if either of dimensions is zero, ratio is assumed to be 1 - // to avoid "divide by zero" errors + // if either of dimensions is zero, ratio is assumed to be 1 + // to avoid "divide by zero" errors + void SetRatio(int width, int height) { m_ratio = (width && height) ? ((float) width / (float) height) : 1; } - void SetRatio( wxSize size ) - { m_ratio = (size.x && size.y) ? ((float) size.x / (float) size.y) : 1; } - void SetRatio( float ratio ) + void SetRatio(const wxSize& size) + { SetRatio(size.x, size.y); } + void SetRatio(float ratio) { m_ratio = ratio; } float GetRatio() const { return m_ratio; } - virtual wxRect GetRect() { return m_zoneRect; } + virtual wxRect GetRect() { return m_rect; } - bool IsWindow() const; - bool IsSizer() const; - bool IsSpacer() const; + bool IsWindow() const { return m_kind == Item_Window; } + bool IsSizer() const { return m_kind == Item_Sizer; } + bool IsSpacer() const { return m_kind == Item_Spacer; } // Deprecated in 2.6, use {G,S}etProportion instead. wxDEPRECATED( void SetOption( int option ) ); @@ -209,48 +240,56 @@ public: { return m_border; } wxWindow *GetWindow() const - { return m_window; } - void SetWindow( wxWindow *window ) - { m_window = window; m_minSize = window->GetSize(); } + { return m_kind == Item_Window ? m_window : NULL; } wxSizer *GetSizer() const - { return m_sizer; } - void SetSizer( wxSizer *sizer ) - { m_sizer = sizer; } - const wxSize &GetSpacer() const - { return m_size; } - void SetSpacer( const wxSize &size ) - { m_size = size; m_minSize = size; } + { return m_kind == Item_Sizer ? m_sizer : NULL; } + wxSize GetSpacer() const; - void Show ( bool show ); - bool IsShown() const - { return m_show; } + void Show(bool show); + bool IsShown() const; wxObject* GetUserData() const { return m_userData; } wxPoint GetPosition() const { return m_pos; } + + // these functions do not free old sizer/spacer + void SetWindow(wxWindow *window); + void SetSizer(wxSizer *sizer); + void SetSpacer(const wxSize& size); + void SetSpacer(int width, int height) { SetSpacer(wxSize(width, height)); } + protected: // common part of several ctors - void Init(); + void Init() { m_userData = NULL; } // common part of ctors taking wxSizerFlags void Init(const wxSizerFlags& flags); + enum + { + Item_None, + Item_Window, + Item_Sizer, + Item_Spacer, + Item_Max + } m_kind; + union + { + wxWindow *m_window; + wxSizer *m_sizer; + wxSizerSpacer *m_spacer; + }; - wxWindow *m_window; - wxSizer *m_sizer; - wxSize m_size; wxPoint m_pos; wxSize m_minSize; int m_proportion; int m_border; int m_flag; - wxRect m_zoneRect; // Rectangle for window or item (not including borders) - // If true, then this item is considered in the layout - // calculation. Otherwise, it is skipped over. - bool m_show; + // on screen rectangle of this item (not including borders) + wxRect m_rect; // Aspect ratio can always be calculated from m_size, // but this would cause precision loss when the window @@ -374,13 +413,13 @@ public: void SetMinSize( wxSize size ) { DoSetMinSize( size.x, size.y ); } - /* Searches recursively */ + // Searches recursively bool SetItemMinSize( wxWindow *window, int width, int height ) { return DoSetItemMinSize( window, width, height ); } bool SetItemMinSize( wxWindow *window, wxSize size ) { return DoSetItemMinSize( window, size.x, size.y ); } - /* Searches recursively */ + // Searches recursively bool SetItemMinSize( wxSizer *sizer, int width, int height ) { return DoSetItemMinSize( sizer, width, height ); } bool SetItemMinSize( wxSizer *sizer, wxSize size ) @@ -396,7 +435,7 @@ public: wxPoint GetPosition() const { return m_position; } - /* Calculate the minimal size or return m_minSize if bigger. */ + // Calculate the minimal size or return m_minSize if bigger. wxSize GetMinSize(); virtual void RecalcSizes() = 0; @@ -438,11 +477,15 @@ public: // Recursively call wxWindow::Show () on all sizer items. virtual void ShowItems (bool show); + void Show(bool show) { m_isShown = show; } + bool IsShown() const { return m_isShown; } + protected: wxSize m_size; wxSize m_minSize; wxPoint m_position; wxSizerItemList m_children; + bool m_isShown; wxSize GetMaxWindowSize( wxWindow *window ) const; wxSize GetMinWindowSize( wxWindow *window ); diff --git a/src/common/sizer.cpp b/src/common/sizer.cpp index f6ef4e0cbc..f959eb34b2 100644 --- a/src/common/sizer.cpp +++ b/src/common/sizer.cpp @@ -85,18 +85,9 @@ WX_DEFINE_EXPORTED_LIST( wxSizerItemList ); minsize */ -//--------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxSizerItem -//--------------------------------------------------------------------------- - -void wxSizerItem::Init() -{ - m_window = NULL; - m_sizer = NULL; - m_show = true; - m_userData = NULL; - m_zoneRect = wxRect(0,0,0,0); -} +// ---------------------------------------------------------------------------- void wxSizerItem::Init(const wxSizerFlags& flags) { @@ -107,89 +98,156 @@ void wxSizerItem::Init(const wxSizerFlags& flags) m_border = flags.GetBorderInPixels(); } -wxSizerItem::wxSizerItem( int width, int height, int proportion, int flag, int border, wxObject* userData ) - : m_window( NULL ) - , m_sizer( NULL ) - , m_size( wxSize( width, height ) ) // size is set directly - , m_minSize( m_size ) // minimal size is the initial size - , m_proportion( proportion ) - , m_border( border ) - , m_flag( flag ) - , m_zoneRect() - , m_show( true ) - , m_userData( userData ) -{ - SetRatio( m_size ); -} - -wxSizerItem::wxSizerItem( wxWindow *window, int proportion, int flag, int border, wxObject* userData ) - : m_window( window ) - , m_sizer( NULL ) - , m_proportion( proportion ) - , m_border( border ) - , m_flag( flag ) - , m_zoneRect() - , m_show( true ) - , m_userData( userData ) -{ - if (flag & wxFIXED_MINSIZE) - window->SetMinSize(window->GetSize()); +wxSizerItem::wxSizerItem() +{ + Init(); + + m_proportion = 0; + m_border = 0; + m_flag = 0; + + m_kind = Item_None; +} + +// window item +void wxSizerItem::SetWindow(wxWindow *window) +{ + wxCHECK_RET( window, _T("NULL window in wxSizerItem::SetWindow()") ); + + m_kind = Item_Window; + m_window = window; + + // window doesn't become smaller than its initial size, whatever happens m_minSize = window->GetSize(); + if ( m_flag & wxFIXED_MINSIZE ) + window->SetMinSize(m_minSize); + // aspect ratio calculated from initial size - SetRatio( m_minSize ); + SetRatio(m_minSize); +} - // m_size is calculated later +wxSizerItem::wxSizerItem(wxWindow *window, + int proportion, + int flag, + int border, + wxObject* userData) + : m_proportion(proportion), + m_border(border), + m_flag(flag), + m_userData(userData) +{ + SetWindow(window); } -wxSizerItem::wxSizerItem( wxSizer *sizer, int proportion, int flag, int border, wxObject* userData ) - : m_window( NULL ) - , m_sizer( sizer ) - , m_proportion( proportion ) - , m_border( border ) - , m_flag( flag ) - , m_zoneRect() - , m_show( true ) - , m_ratio( 0.0 ) - , m_userData( userData ) +// sizer item +void wxSizerItem::SetSizer(wxSizer *sizer) { - // m_minSize is calculated later - // m_size is calculated later + m_kind = Item_Sizer; + m_sizer = sizer; } -wxSizerItem::wxSizerItem() +wxSizerItem::wxSizerItem(wxSizer *sizer, + int proportion, + int flag, + int border, + wxObject* userData) + : m_proportion(proportion), + m_border(border), + m_flag(flag), + m_ratio(0.0), + m_userData(userData) { - Init(); + SetSizer(sizer); - m_proportion = 0; - m_border = 0; - m_flag = 0; + // m_minSize is set later +} + +// spacer item +void wxSizerItem::SetSpacer(const wxSize& size) +{ + m_kind = Item_Spacer; + m_spacer = new wxSizerSpacer(size); + m_minSize = size; + SetRatio(size); +} + +wxSizerItem::wxSizerItem(int width, + int height, + int proportion, + int flag, + int border, + wxObject* userData) + : m_minSize(width, height), // minimal size is the initial size + m_proportion(proportion), + m_border(border), + m_flag(flag), + m_userData(userData) +{ + SetSpacer(width, height); } wxSizerItem::~wxSizerItem() { delete m_userData; - if ( m_window ) + switch ( m_kind ) { - m_window->SetContainingSizer(NULL); - } - else // we must be a sizer - { - delete m_sizer; + case Item_None: + break; + + case Item_Window: + m_window->SetContainingSizer(NULL); + break; + + case Item_Sizer: + delete m_sizer; + break; + + case Item_Spacer: + delete m_spacer; + break; + + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); } } +wxSize wxSizerItem::GetSpacer() const +{ + wxSize size; + if ( m_kind == Item_Spacer ) + size = m_spacer->GetSize(); + + return size; +} + wxSize wxSizerItem::GetSize() const { wxSize ret; - if (IsSizer()) - ret = m_sizer->GetSize(); - else - if (IsWindow()) - ret = m_window->GetSize(); - else ret = m_size; + switch ( m_kind ) + { + case Item_None: + break; + + case Item_Window: + ret = m_window->GetSize(); + break; + + case Item_Sizer: + ret = m_sizer->GetSize(); + break; + + case Item_Spacer: + ret = m_spacer->GetSize(); + break; + + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); + } if (m_flag & wxWEST) ret.x += m_border; @@ -294,53 +352,106 @@ void wxSizerItem::SetDimension( wxPoint pos, wxSize size ) size.y -= m_border; } - if (IsSizer()) - m_sizer->SetDimension( pos.x, pos.y, size.x, size.y ); + m_rect = wxRect(pos, size); + + switch ( m_kind ) + { + case Item_None: + wxFAIL_MSG( _T("can't set size of uninitialized sizer item") ); + break; + + case Item_Window: + m_window->SetSize(pos.x, pos.y, size.x, size.y, + wxSIZE_ALLOW_MINUS_ONE); + break; - m_zoneRect = wxRect(pos, size); - if (IsWindow()) - m_window->SetSize( pos.x, pos.y, size.x, size.y, wxSIZE_ALLOW_MINUS_ONE ); + case Item_Sizer: + m_sizer->SetDimension(pos.x, pos.y, size.x, size.y); + break; + + case Item_Spacer: + m_spacer->SetSize(size); + break; - m_size = size; + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); + } } void wxSizerItem::DeleteWindows() { - if (m_window) + switch ( m_kind ) { - m_window->Destroy(); - m_window = NULL; + case Item_None: + case Item_Spacer: + break; + + case Item_Window: + m_window->Destroy(); + break; + + case Item_Sizer: + m_sizer->DeleteWindows(); + break; + + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); } - if (m_sizer) - m_sizer->DeleteWindows(); + m_kind = Item_None; } -bool wxSizerItem::IsWindow() const +void wxSizerItem::Show( bool show ) { - return (m_window != NULL); -} + switch ( m_kind ) + { + case Item_None: + wxFAIL_MSG( _T("can't show uninitialized sizer item") ); + break; -bool wxSizerItem::IsSizer() const -{ - return (m_sizer != NULL); -} + case Item_Window: + m_window->Show(show); + break; -bool wxSizerItem::IsSpacer() const -{ - return (m_window == NULL) && (m_sizer == NULL); + case Item_Sizer: + m_sizer->ShowItems(show); + break; + + case Item_Spacer: + m_spacer->Show(show); + break; + + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); + } } -void wxSizerItem::Show( bool show ) +bool wxSizerItem::IsShown() const { - m_show = show; + switch ( m_kind ) + { + case Item_None: + wxFAIL_MSG( _T("uninitialized sizer item") ); + break; - if( IsWindow() ) - m_window->Show( show ); - else if( IsSizer() ) - m_sizer->ShowItems( show ); + case Item_Window: + return m_window->IsShown(); - // ... nothing else to do to hide/show spacers + case Item_Sizer: + return m_sizer->IsShown(); + + case Item_Spacer: + return m_spacer->IsShown(); + + case Item_Max: + default: + wxFAIL_MSG( _T("unexpected wxSizerItem::m_kind") ); + } + + return false; } void wxSizerItem::SetOption( int option ) @@ -359,8 +470,8 @@ int wxSizerItem::GetOption() const //--------------------------------------------------------------------------- wxSizer::wxSizer() - :m_minSize() { + m_isShown = true; } wxSizer::~wxSizer() @@ -372,7 +483,7 @@ wxSizerItem* wxSizer::Insert( size_t index, wxSizerItem *item ) { m_children.Insert( index, item ); - if( item->GetWindow() ) + if ( item->GetWindow() ) item->GetWindow()->SetContainingSizer( this ); return item; @@ -417,7 +528,7 @@ bool wxSizer::Remove( int index ) wxSizerItem *item = node->GetData(); - if( item->IsWindow() ) + if ( item->IsWindow() ) item->GetWindow()->SetContainingSizer( NULL ); delete item; @@ -481,9 +592,9 @@ bool wxSizer::Detach( int index ) wxSizerItem *item = node->GetData(); - if( item->IsSizer() ) + if ( item->IsSizer() ) item->DetachSizer(); - else if( item->IsWindow() ) + else if ( item->IsWindow() ) item->GetWindow()->SetContainingSizer( NULL ); delete item; @@ -620,7 +731,7 @@ wxSize wxSizer::GetMaxClientSize( wxWindow *window ) const { wxSize maxSize( window->GetMaxSize() ); - if( maxSize != wxDefaultSize ) + if ( maxSize != wxDefaultSize ) { wxSize size( window->GetSize() ); wxSize client_size( window->GetClientSize() ); -- 2.45.2