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:
parent
ed8efd46d9
commit
e6b2aae1b8
@ -43,6 +43,7 @@ public:
|
||||
|
||||
virtual void AddButton(wxWindowID btnid, const wxString& label = wxString());
|
||||
|
||||
virtual void RemoveButton(wxWindowID btnid);
|
||||
|
||||
// methods specific to this version
|
||||
// --------------------------------
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user