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:
@@ -43,6 +43,7 @@ public:
|
|||||||
|
|
||||||
virtual void AddButton(wxWindowID btnid, const wxString& label = wxString());
|
virtual void AddButton(wxWindowID btnid, const wxString& label = wxString());
|
||||||
|
|
||||||
|
virtual void RemoveButton(wxWindowID btnid);
|
||||||
|
|
||||||
// methods specific to this version
|
// methods specific to this version
|
||||||
// --------------------------------
|
// --------------------------------
|
||||||
|
@@ -44,6 +44,8 @@ public:
|
|||||||
virtual void AddButton(wxWindowID btnid,
|
virtual void AddButton(wxWindowID btnid,
|
||||||
const wxString& label = wxString());
|
const wxString& label = wxString());
|
||||||
|
|
||||||
|
virtual void RemoveButton(wxWindowID btnid);
|
||||||
|
|
||||||
// implementation only
|
// implementation only
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
@@ -53,9 +55,11 @@ protected:
|
|||||||
virtual bool GTKShouldConnectSizeRequest() const { return false; }
|
virtual bool GTKShouldConnectSizeRequest() const { return false; }
|
||||||
|
|
||||||
private:
|
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);
|
wxDECLARE_NO_COPY_CLASS(wxInfoBar);
|
||||||
};
|
};
|
||||||
|
@@ -40,6 +40,9 @@ public:
|
|||||||
virtual void AddButton(wxWindowID btnid,
|
virtual void AddButton(wxWindowID btnid,
|
||||||
const wxString& label = wxString()) = 0;
|
const wxString& label = wxString()) = 0;
|
||||||
|
|
||||||
|
// remove a button previously added by AddButton()
|
||||||
|
virtual void RemoveButton(wxWindowID btnid) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxDECLARE_NO_COPY_CLASS(wxInfoBarBase);
|
wxDECLARE_NO_COPY_CLASS(wxInfoBarBase);
|
||||||
};
|
};
|
||||||
|
@@ -131,6 +131,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
void AddButton(wxWindowID btnid, const wxString& label = wxString());
|
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.
|
Show a message in the bar.
|
||||||
|
|
||||||
|
@@ -531,6 +531,12 @@ MyFrame::MyFrame(const wxString& title)
|
|||||||
// or it can also be customized
|
// or it can also be customized
|
||||||
m_infoBarAdvanced = new wxInfoBar(this);
|
m_infoBarAdvanced = new wxInfoBar(this);
|
||||||
m_infoBarAdvanced->AddButton(wxID_UNDO);
|
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->SetOwnBackgroundColour(0xc8ffff);
|
||||||
m_infoBarAdvanced->SetShowHideEffects(wxSHOW_EFFECT_EXPAND,
|
m_infoBarAdvanced->SetShowHideEffects(wxSHOW_EFFECT_EXPAND,
|
||||||
|
@@ -249,11 +249,45 @@ void wxInfoBarGeneric::AddButton(wxWindowID btnid, const wxString& label)
|
|||||||
wxSizer * const sizer = GetSizer();
|
wxSizer * const sizer = GetSizer();
|
||||||
wxCHECK_RET( sizer, "must be created first" );
|
wxCHECK_RET( sizer, "must be created first" );
|
||||||
|
|
||||||
sizer->Insert(sizer->GetItemCount() - 2,
|
sizer->Insert(sizer->GetItemCount() - 1,
|
||||||
new wxButton(this, btnid, label),
|
new wxButton(this, btnid, label),
|
||||||
wxSizerFlags().Centre().DoubleBorder());
|
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))
|
void wxInfoBarGeneric::OnButton(wxCommandEvent& WXUNUSED(event))
|
||||||
{
|
{
|
||||||
DoHide();
|
DoHide();
|
||||||
|
@@ -30,9 +30,41 @@
|
|||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#endif // WX_PRECOMP
|
#endif // WX_PRECOMP
|
||||||
|
|
||||||
|
#include "wx/vector.h"
|
||||||
|
|
||||||
#include "wx/gtk/private.h"
|
#include "wx/gtk/private.h"
|
||||||
#include "wx/gtk/private/messagetype.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
|
// local functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -75,6 +107,8 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
|
|||||||
if ( !UseNative() )
|
if ( !UseNative() )
|
||||||
return wxInfoBarGeneric::Create(parent, winid);
|
return wxInfoBarGeneric::Create(parent, winid);
|
||||||
|
|
||||||
|
m_impl = new wxInfoBarGTKImpl;
|
||||||
|
|
||||||
// this control is created initially hidden
|
// this control is created initially hidden
|
||||||
Hide();
|
Hide();
|
||||||
if ( !CreateBase(parent, winid) )
|
if ( !CreateBase(parent, winid) )
|
||||||
@@ -86,13 +120,13 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
|
|||||||
g_object_ref(m_widget);
|
g_object_ref(m_widget);
|
||||||
|
|
||||||
// also create a label which will be used to show our message
|
// also create a label which will be used to show our message
|
||||||
m_label = gtk_label_new("");
|
m_impl->m_label = gtk_label_new("");
|
||||||
gtk_widget_show(m_label);
|
gtk_widget_show(m_impl->m_label);
|
||||||
|
|
||||||
GtkWidget * const
|
GtkWidget * const
|
||||||
contentArea = gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget));
|
contentArea = gtk_info_bar_get_content_area(GTK_INFO_BAR(m_widget));
|
||||||
wxCHECK_MSG( contentArea, false, "failed to get GtkInfoBar content area" );
|
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
|
// finish creation and connect to all the signals we're interested in
|
||||||
m_parent->DoAddChild(this);
|
m_parent->DoAddChild(this);
|
||||||
@@ -105,6 +139,11 @@ bool wxInfoBar::Create(wxWindow *parent, wxWindowID winid)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxInfoBar::~wxInfoBar()
|
||||||
|
{
|
||||||
|
delete m_impl;
|
||||||
|
}
|
||||||
|
|
||||||
void wxInfoBar::ShowMessage(const wxString& msg, int flags)
|
void wxInfoBar::ShowMessage(const wxString& msg, int flags)
|
||||||
{
|
{
|
||||||
if ( !UseNative() )
|
if ( !UseNative() )
|
||||||
@@ -116,7 +155,7 @@ void wxInfoBar::ShowMessage(const wxString& msg, int flags)
|
|||||||
GtkMessageType type;
|
GtkMessageType type;
|
||||||
if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
|
if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
|
||||||
gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget), 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() )
|
if ( !IsShown() )
|
||||||
Show();
|
Show();
|
||||||
@@ -139,12 +178,42 @@ void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_info_bar_add_button
|
GtkWidget *button = gtk_info_bar_add_button
|
||||||
(
|
(
|
||||||
GTK_INFO_BAR(m_widget),
|
GTK_INFO_BAR(m_widget),
|
||||||
label.empty() ? GTKConvertMnemonics(wxGetStockGtkID(btnid)) : label,
|
label.empty()
|
||||||
btnid
|
? 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
|
#endif // wxUSE_INFOBAR
|
||||||
|
Reference in New Issue
Block a user