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
This commit is contained in:
Vadim Zeitlin 2009-10-05 22:55:17 +00:00
parent ed8efd46d9
commit e6b2aae1b8
7 changed files with 140 additions and 13 deletions

View 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
// --------------------------------

View 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);
};

View 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);
};

View 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.

View 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,

View 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();

View File

@ -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<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