]> git.saurik.com Git - wxWidgets.git/commitdiff
Add wxInfoBar::RemoveButton() method.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 5 Oct 2009 22:55:17 +0000 (22:55 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 5 Oct 2009 22:55:17 +0000 (22:55 +0000)
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
include/wx/gtk/infobar.h
include/wx/infobar.h
interface/wx/infobar.h
samples/dialogs/dialogs.cpp
src/generic/infobar.cpp
src/gtk/infobar.cpp

index 13c20ff2a6d23ad512dbf4264b2fe20bca11546b..79e1c683fe045bef0019bfecd8e367037dc627d6 100644 (file)
@@ -43,6 +43,7 @@ public:
 
     virtual void AddButton(wxWindowID btnid, const wxString& label = wxString());
 
+    virtual void RemoveButton(wxWindowID btnid);
 
     // methods specific to this version
     // --------------------------------
index 8178db03432915bad2b56d064f93b9031d39e504..1789ea17694487b25d9063e75a03cafcfa93424e 100644 (file)
@@ -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);
 };
index 00046d1e4c2ae6b47d1cdd7db164ea0ab17d03c1..ec02fb33e84231a4b47fac56581bd76bd2dec792 100644 (file)
@@ -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);
 };
index 0eb6e6f0febd318666ee0311a5c2c7b96c6e3c2a..9f57867d3cf5450a89017251080af68dcffaa9d9 100644 (file)
@@ -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.
 
index d5e61a62c32bb383a75b813fe15bccaded314574..1558b54a25ca999318a00981b66162a3d5ef7d1a 100644 (file)
@@ -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,
index d6cbe2e054aa57bc34a03d889d06beb35a29a23b..42f1daf56e3ce353ba5ff77a145242ddfa827db7 100644 (file)
@@ -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();
index 604838abfc2e89f86e9818bdb9dd2f3b3a60b992..53d075d04b2b07502092450661f158978c866aca 100644 (file)
 #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<Button> Buttons;
+
+    Buttons m_buttons;
+};
+
 // ----------------------------------------------------------------------------
 // local functions
 // ----------------------------------------------------------------------------
@@ -75,6 +107,8 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
     if ( !UseNative() )
         return wxInfoBarGeneric::Create(parent, winid);
 
+    m_impl = new wxInfoBarGTKImpl;
+
     // this control is created initially hidden
     Hide();
     if ( !CreateBase(parent, winid) )
@@ -86,13 +120,13 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
     g_object_ref(m_widget);
 
     // also create a label which will be used to show our message
-    m_label = gtk_label_new("");
-    gtk_widget_show(m_label);
+    m_impl->m_label = gtk_label_new("");
+    gtk_widget_show(m_impl->m_label);
 
     GtkWidget * const
         contentArea = gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget));
     wxCHECK_MSG( contentArea, false, "failed to get GtkInfoBar content area" );
-    gtk_container_add(GTK_CONTAINER(contentArea), m_label);
+    gtk_container_add(GTK_CONTAINER(contentArea), m_impl->m_label);
 
     // finish creation and connect to all the signals we're interested in
     m_parent->DoAddChild(this);
@@ -105,6 +139,11 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
     return false;
 }
 
+wxInfoBar::~wxInfoBar()
+{
+    delete m_impl;
+}
+
 void wxInfoBar::ShowMessage(const wxString& msg, int flags)
 {
     if ( !UseNative() )
@@ -116,7 +155,7 @@ void wxInfoBar::ShowMessage(const wxString& msg, int flags)
     GtkMessageType type;
     if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
         gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget), type);
-    gtk_label_set_text(GTK_LABEL(m_label), wxGTK_CONV(msg));
+    gtk_label_set_text(GTK_LABEL(m_impl->m_label), wxGTK_CONV(msg));
 
     if ( !IsShown() )
         Show();
@@ -139,12 +178,42 @@ void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
         return;
     }
 
-    gtk_info_bar_add_button
-    (
-        GTK_INFO_BAR(m_widget),
-        label.empty() ? GTKConvertMnemonics(wxGetStockGtkID(btnid)) : label,
-        btnid
-    );
+    GtkWidget *button = gtk_info_bar_add_button
+                        (
+                            GTK_INFO_BAR(m_widget),
+                            label.empty()
+                                ? GTKConvertMnemonics(wxGetStockGtkID(btnid))
+                                : label,
+                            btnid
+                        );
+    wxCHECK_RET( button, "unexpectedly failed to add button to info bar" );
+
+    g_object_ref(button);
+    m_impl->m_buttons.push_back(wxInfoBarGTKImpl::Button(button, btnid));
+}
+
+void wxInfoBar::RemoveButton(wxWindowID btnid)
+{
+    if ( !UseNative() )
+    {
+        wxInfoBarGeneric::RemoveButton(btnid);
+        return;
+    }
+
+    // as in the generic version, look for the button starting from the end
+    wxInfoBarGTKImpl::Buttons& buttons = m_impl->m_buttons;
+    for ( wxInfoBarGTKImpl::Buttons::reverse_iterator i = buttons.rbegin();
+          i != buttons.rend();
+          ++i )
+    {
+        GtkWidget * const button = i->button;
+        buttons.erase(i.base());
+        gtk_widget_destroy(button);
+        g_object_unref(button);
+        return;
+    }
+
+    wxFAIL_MSG( wxString::Format("button with id %d not found", btnid) );
 }
 
 #endif // wxUSE_INFOBAR