From 40f2cf0a78c725ff69c7ca142f069ee0cdb0816f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 2 Jun 2014 01:15:11 +0000 Subject: [PATCH] Allow access to the currently shown wxInfoBar buttons. Add wxInfoBar::GetButtonCount(), GetButtonId() and HasButtonId() methods. Closes #15110. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76651 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + include/wx/generic/infobar.h | 4 ++ include/wx/gtk/infobar.h | 4 ++ include/wx/infobar.h | 5 ++ interface/wx/infobar.h | 39 +++++++++++++ src/generic/infobar.cpp | 104 +++++++++++++++++++++++++++++++++++ src/gtk/infobar.cpp | 37 +++++++++++++ 7 files changed, 194 insertions(+) diff --git a/docs/changes.txt b/docs/changes.txt index b797aaeef3..fcddfdfa09 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -57,6 +57,7 @@ All (GUI): - Improve auto sizing of wrapped cells in wxGrid (iwbnwif). - Fix handling of rectangular selections in wxStyledTextCtrl (roberto). - Fix characters outside of the BMP in wxStyledTextCtrl (Thomas Goyne). +- Allow access to the currently shown wxInfoBar buttons (Hanmac). wxGTK: diff --git a/include/wx/generic/infobar.h b/include/wx/generic/infobar.h index e3cd14f2b5..6da98bfa8c 100644 --- a/include/wx/generic/infobar.h +++ b/include/wx/generic/infobar.h @@ -46,6 +46,10 @@ public: virtual void RemoveButton(wxWindowID btnid) wxOVERRIDE; + virtual size_t GetButtonCount() const wxOVERRIDE; + virtual wxWindowID GetButtonId(size_t idx) const wxOVERRIDE; + virtual bool HasButtonId(wxWindowID btnid) const wxOVERRIDE; + // methods specific to this version // -------------------------------- diff --git a/include/wx/gtk/infobar.h b/include/wx/gtk/infobar.h index b8f24043a7..26653df2f5 100644 --- a/include/wx/gtk/infobar.h +++ b/include/wx/gtk/infobar.h @@ -47,6 +47,10 @@ public: virtual void RemoveButton(wxWindowID btnid) wxOVERRIDE; + virtual size_t GetButtonCount() const wxOVERRIDE; + virtual wxWindowID GetButtonId(size_t idx) const wxOVERRIDE; + virtual bool HasButtonId(wxWindowID btnid) const wxOVERRIDE; + // implementation only // ------------------- diff --git a/include/wx/infobar.h b/include/wx/infobar.h index be390a856e..ebda4f695a 100644 --- a/include/wx/infobar.h +++ b/include/wx/infobar.h @@ -46,6 +46,11 @@ public: // remove a button previously added by AddButton() virtual void RemoveButton(wxWindowID btnid) = 0; + // get information about the currently shown buttons + virtual size_t GetButtonCount() const = 0; + virtual wxWindowID GetButtonId(size_t idx) const = 0; + virtual bool HasButtonId(wxWindowID btnid) const = 0; + private: wxDECLARE_NO_COPY_CLASS(wxInfoBarBase); }; diff --git a/interface/wx/infobar.h b/interface/wx/infobar.h index 24903d882d..bcb4a90872 100644 --- a/interface/wx/infobar.h +++ b/interface/wx/infobar.h @@ -181,6 +181,45 @@ public: */ void ShowMessage(const wxString& msg, int flags = wxICON_NONE); + /** + Returns the number of currently shown buttons. + + This is simply the number of calls to AddButton() minus the number + of calls to RemoveButton() so far. + + @return The number of currently shown buttons, possibly 0. + + @since 3.1.0 + */ + virtual size_t GetButtonCount() const; + + /** + Returns the ID of the button at the given position. + + The positions of the buttons are counted in order of their addition. + + @param idx + The position of the button in 0 to GetButtonCount() range. + @return + The ID of the button at the given position or wxID_NONE if it + is out of range (this also results in an assertion failure). + + @since 3.1.0 + */ + virtual wxWindowID GetButtonId(size_t idx) const; + + /** + Returns whether a button with the given ID is currently shown. + + @param btnid + ID of the button to check for. + @return + \true if the button with this ID is currently shown. + + @since 3.1.0 + */ + virtual bool HasButtonId(wxWindowID btnid) const; + /** @name Generic version customization methods. diff --git a/src/generic/infobar.cpp b/src/generic/infobar.cpp index fdafa24fcd..0d49b8d218 100644 --- a/src/generic/infobar.cpp +++ b/src/generic/infobar.cpp @@ -277,6 +277,110 @@ void wxInfoBarGeneric::AddButton(wxWindowID btnid, const wxString& label) sizer->Add(button, wxSizerFlags().Centre().DoubleBorder()); } +size_t wxInfoBarGeneric::GetButtonCount() const +{ + size_t count = 0; + wxSizer * const sizer = GetSizer(); + if ( !sizer ) + return 0; + + // iterate over the sizer items in reverse order + const wxSizerItemList& items = sizer->GetChildren(); + for ( wxSizerItemList::compatibility_iterator node = items.GetLast(); + node != items.GetFirst(); + node = node->GetPrevious() ) + { + const wxSizerItem * const item = node->GetData(); + + // if we reached the spacer separating the buttons from the text + // break the for-loop. + if ( item->IsSpacer() ) + break; + + // if the standard button is shown, there must be no other ones + if ( item->GetWindow() == m_button ) + return 0; + + ++count; + } + + return count; +} + +wxWindowID wxInfoBarGeneric::GetButtonId(size_t idx) const +{ + wxCHECK_MSG( idx < GetButtonCount(), wxID_NONE, + "Invalid infobar button position" ); + + wxSizer * const sizer = GetSizer(); + if ( !sizer ) + return wxID_NONE; + + bool foundSpacer = false; + + size_t count = 0; + const wxSizerItemList& items = sizer->GetChildren(); + for ( wxSizerItemList::compatibility_iterator node = items.GetLast(); + node != items.GetFirst() || node != items.GetLast(); + ) + { + const wxSizerItem * const item = node->GetData(); + + if ( item->IsSpacer() ) + foundSpacer = true; + + if ( foundSpacer ) + { + if ( !item->IsSpacer() ) + { + if ( count == idx ) + { + if ( item->GetWindow() != m_button ) + return item->GetWindow()->GetId(); + } + + ++count; + } + + node = node->GetNext(); + } + else + { + node = node->GetPrevious(); + } + } + + return wxID_NONE; +} + +bool wxInfoBarGeneric::HasButtonId(wxWindowID btnid) const +{ + wxSizer * const sizer = GetSizer(); + if ( !sizer ) + return false; + + // iterate over the sizer items in reverse order to find the last added + // button with this id + const wxSizerItemList& items = sizer->GetChildren(); + for ( wxSizerItemList::compatibility_iterator node = items.GetLast(); + node != items.GetFirst(); + node = node->GetPrevious() ) + { + const wxSizerItem * const item = node->GetData(); + + // if we reached the spacer separating the buttons from the text + // then the wanted ID is not inside. + if ( item->IsSpacer() ) + return false; + + // check if we found our button + if ( item->GetWindow()->GetId() == btnid ) + return true; + } + + return false; +} + void wxInfoBarGeneric::RemoveButton(wxWindowID btnid) { wxSizer * const sizer = GetSizer(); diff --git a/src/gtk/infobar.cpp b/src/gtk/infobar.cpp index fb55f9b3a3..2f7ea108b2 100644 --- a/src/gtk/infobar.cpp +++ b/src/gtk/infobar.cpp @@ -223,6 +223,25 @@ GtkWidget *wxInfoBar::GTKAddButton(wxWindowID btnid, const wxString& label) return button; } +size_t wxInfoBar::GetButtonCount() const +{ + if ( !UseNative() ) + return wxInfoBarGeneric::GetButtonCount(); + + return m_impl->m_buttons.size(); +} + +wxWindowID wxInfoBar::GetButtonId(size_t idx) const +{ + if ( !UseNative() ) + return wxInfoBarGeneric::GetButtonId(idx); + + wxCHECK_MSG( idx < m_impl->m_buttons.size(), wxID_NONE, + "Invalid infobar button position" ); + + return m_impl->m_buttons[idx].id; +} + void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label) { if ( !UseNative() ) @@ -244,6 +263,24 @@ void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label) m_impl->m_buttons.push_back(wxInfoBarGTKImpl::Button(button, btnid)); } +bool wxInfoBar::HasButtonId(wxWindowID btnid) const +{ + if ( !UseNative() ) + return wxInfoBarGeneric::HasButtonId(btnid); + + // as in the generic version, look for the button starting from the end + const wxInfoBarGTKImpl::Buttons& buttons = m_impl->m_buttons; + for ( wxInfoBarGTKImpl::Buttons::const_reverse_iterator i = buttons.rbegin(); + i != buttons.rend(); + ++i ) + { + if ( i->id == btnid ) + return true; + } + + return false; +} + void wxInfoBar::RemoveButton(wxWindowID btnid) { if ( !UseNative() )