From e6b2aae1b84f4818f1b2b30f5d15bdde0fa67408 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 5 Oct 2009 22:55:17 +0000 Subject: [PATCH] Add wxInfoBar::RemoveButton() method. Also change the GTK implementation to use a separate wxInfoBarGTKImpl to store its data, this object won't be even allocated if a generic implementation is used under GTK. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62277 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/infobar.h | 1 + include/wx/gtk/infobar.h | 8 +++- include/wx/infobar.h | 3 ++ interface/wx/infobar.h | 10 ++++ samples/dialogs/dialogs.cpp | 6 +++ src/generic/infobar.cpp | 36 ++++++++++++++- src/gtk/infobar.cpp | 89 ++++++++++++++++++++++++++++++++---- 7 files changed, 140 insertions(+), 13 deletions(-) diff --git a/include/wx/generic/infobar.h b/include/wx/generic/infobar.h index 13c20ff2a6..79e1c683fe 100644 --- a/include/wx/generic/infobar.h +++ b/include/wx/generic/infobar.h @@ -43,6 +43,7 @@ public: virtual void AddButton(wxWindowID btnid, const wxString& label = wxString()); + virtual void RemoveButton(wxWindowID btnid); // methods specific to this version // -------------------------------- diff --git a/include/wx/gtk/infobar.h b/include/wx/gtk/infobar.h index 8178db0343..1789ea1769 100644 --- a/include/wx/gtk/infobar.h +++ b/include/wx/gtk/infobar.h @@ -44,6 +44,8 @@ public: virtual void AddButton(wxWindowID btnid, const wxString& label = wxString()); + virtual void RemoveButton(wxWindowID btnid); + // implementation only // ------------------- @@ -53,9 +55,11 @@ protected: virtual bool GTKShouldConnectSizeRequest() const { return false; } private: - void Init() { m_label = NULL; } + void Init() { m_impl = NULL; } - GtkWidget *m_label; + + // only used when the native implementation is really being used + class wxInfoBarGTKImpl *m_impl; wxDECLARE_NO_COPY_CLASS(wxInfoBar); }; diff --git a/include/wx/infobar.h b/include/wx/infobar.h index 00046d1e4c..ec02fb33e8 100644 --- a/include/wx/infobar.h +++ b/include/wx/infobar.h @@ -40,6 +40,9 @@ public: virtual void AddButton(wxWindowID btnid, const wxString& label = wxString()) = 0; + // remove a button previously added by AddButton() + virtual void RemoveButton(wxWindowID btnid) = 0; + private: wxDECLARE_NO_COPY_CLASS(wxInfoBarBase); }; diff --git a/interface/wx/infobar.h b/interface/wx/infobar.h index 0eb6e6f0fe..9f57867d3c 100644 --- a/interface/wx/infobar.h +++ b/interface/wx/infobar.h @@ -131,6 +131,16 @@ public: */ void AddButton(wxWindowID btnid, const wxString& label = wxString()); + /** + Remove a button previously added by AddButton(). + + @param btnid + Id of the button to remove. If more than one button with the same + id is used in the info bar (which is in any case not recommended), + the last, i.e. most recently added, button with this id is removed. + */ + void RemoveButton(wxWindowID btnid); + /** Show a message in the bar. diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index d5e61a62c3..1558b54a25 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -531,6 +531,12 @@ MyFrame::MyFrame(const wxString& title) // or it can also be customized m_infoBarAdvanced = new wxInfoBar(this); m_infoBarAdvanced->AddButton(wxID_UNDO); + m_infoBarAdvanced->AddButton(wxID_REDO); + + // adding and removing a button immediately doesn't make sense here, of + // course, it's done just to show that it is possible + m_infoBarAdvanced->AddButton(wxID_EXIT); + m_infoBarAdvanced->RemoveButton(wxID_EXIT); m_infoBarAdvanced->SetOwnBackgroundColour(0xc8ffff); m_infoBarAdvanced->SetShowHideEffects(wxSHOW_EFFECT_EXPAND, diff --git a/src/generic/infobar.cpp b/src/generic/infobar.cpp index d6cbe2e054..42f1daf56e 100644 --- a/src/generic/infobar.cpp +++ b/src/generic/infobar.cpp @@ -249,11 +249,45 @@ void wxInfoBarGeneric::AddButton(wxWindowID btnid, const wxString& label) wxSizer * const sizer = GetSizer(); wxCHECK_RET( sizer, "must be created first" ); - sizer->Insert(sizer->GetItemCount() - 2, + sizer->Insert(sizer->GetItemCount() - 1, new wxButton(this, btnid, label), wxSizerFlags().Centre().DoubleBorder()); } +void wxInfoBarGeneric::RemoveButton(wxWindowID btnid) +{ + wxSizer * const sizer = GetSizer(); + wxCHECK_RET( sizer, "must be created first" ); + + // iterate over the sizer items in reverse order to find the last added + // button with this id (ids of all buttons should be unique anyhow but if + // they are repeated removing the last added one probably makes more sense) + const wxSizerItemList& items = sizer->GetChildren(); + for ( wxSizerItemList::compatibility_iterator node = items.GetLast(); + node != items.GetFirst(); + node = node->GetPrevious() ) + { + node = node->GetPrevious(); + const wxSizerItem * const item = node->GetData(); + + // if we reached the spacer separating the buttons from the text + // preceding them without finding our button, it must mean it's not + // there at all + if ( item->IsSpacer() ) + { + wxFAIL_MSG( wxString::Format("button with id %d not found", btnid) ); + return; + } + + // check if we found our button + if ( item->GetWindow()->GetId() == btnid ) + { + delete item->GetWindow(); + break; + } + } +} + void wxInfoBarGeneric::OnButton(wxCommandEvent& WXUNUSED(event)) { DoHide(); diff --git a/src/gtk/infobar.cpp b/src/gtk/infobar.cpp index 604838abfc..53d075d04b 100644 --- a/src/gtk/infobar.cpp +++ b/src/gtk/infobar.cpp @@ -30,9 +30,41 @@ #ifndef WX_PRECOMP #endif // WX_PRECOMP +#include "wx/vector.h" + #include "wx/gtk/private.h" #include "wx/gtk/private/messagetype.h" +// ---------------------------------------------------------------------------- +// local classes +// ---------------------------------------------------------------------------- + +class wxInfoBarGTKImpl +{ +public: + wxInfoBarGTKImpl() + { + m_label = NULL; + } + + GtkWidget *m_label; + + struct Button + { + Button(GtkWidget *button_, int id_) + : button(button_), + id(id_) + { + } + + GtkWidget *button; + int id; + }; + typedef wxVector