private:
void Init() { m_impl = NULL; }
+ // add a button with the given id/label and return its widget
+ GtkWidget *GTKAddButton(wxWindowID btnid,
+ const wxString& label = wxString());
+
// only used when the native implementation is really being used
class wxInfoBarGTKImpl *m_impl;
virtual void ShowMessage(const wxString& msg,
int flags = wxICON_INFORMATION) = 0;
- // add an extra button to the bar, near the message
+ // add an extra button to the bar, near the message (replacing the default
+ // close button which is only shown if no extra buttons are used)
virtual void AddButton(wxWindowID btnid,
const wxString& label = wxString()) = 0;
The button added by this method will be shown to the right of the text
(in LTR layout), with each successive button being added to the right
- of the previous one.
+ of the previous one. If any buttons are added to the info bar using
+ this method, the default "Close" button is not shown as it is assumed
+ that the extra buttons already allow the user to close it.
Clicking the button will generate a normal EVT_COMMAND_BUTTON_CLICKED
event which can be handled as usual. The default handler in wxInfoBar
wxSizer * const sizer = GetSizer();
wxCHECK_RET( sizer, "must be created first" );
- sizer->Insert(sizer->GetItemCount() - 1,
- new wxButton(this, btnid, label),
- wxSizerFlags().Centre().DoubleBorder());
+ // user-added buttons replace the standard close button so remove it if we
+ // hadn't done it yet
+ if ( sizer->Detach(m_button) )
+ {
+ m_button->Hide();
+ }
+
+ sizer->Add(new wxButton(this, btnid, label),
+ wxSizerFlags().Centre().DoubleBorder());
}
void wxInfoBarGeneric::RemoveButton(wxWindowID btnid)
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
break;
}
}
+
+ // check if there are any custom buttons left
+ if ( sizer->GetChildren().GetLast()->GetData()->IsSpacer() )
+ {
+ // if the last item is the spacer, none are left so restore the
+ // standard close button
+ sizer->Add(m_button, wxSizerFlags().Centre().DoubleBorder());
+ m_button->Show();
+ }
}
void wxInfoBarGeneric::OnButton(wxCommandEvent& WXUNUSED(event))
wxInfoBarGTKImpl()
{
m_label = NULL;
+ m_close = NULL;
}
+ // label for the text shown in the bar
GtkWidget *m_label;
+ // the default close button, NULL if not needed (m_buttons is not empty) or
+ // not created yet
+ GtkWidget *m_close;
+
+ // information about the buttons added using AddButton()
struct Button
{
Button(GtkWidget *button_, int id_)
return;
}
+ // if we don't have any buttons, create a standard close one to give the
+ // user at least some way to close the bar
+ if ( m_impl->m_buttons.empty() && !m_impl->m_close )
+ {
+ m_impl->m_close = GTKAddButton(wxID_CLOSE);
+ }
+
GtkMessageType type;
if ( wxGTKImpl::ConvertMessageTypeFromWX(flags, &type) )
gtk_info_bar_set_message_type(GTK_INFO_BAR(m_widget), type);
}
}
-void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
+GtkWidget *wxInfoBar::GTKAddButton(wxWindowID btnid, const wxString& label)
{
- if ( !UseNative() )
- {
- wxInfoBarGeneric::AddButton(btnid, label);
- return;
- }
+ // as GTK+ lays out the buttons vertically, adding another button changes
+ // our best size (at least in vertical direction)
+ InvalidateBestSize();
GtkWidget *button = gtk_info_bar_add_button
(
: 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));
+ wxASSERT_MSG( button, "unexpectedly failed to add button to info bar" );
+
+ return button;
+}
+
+void wxInfoBar::AddButton(wxWindowID btnid, const wxString& label)
+{
+ if ( !UseNative() )
+ {
+ wxInfoBarGeneric::AddButton(btnid, label);
+ return;
+ }
+
+ // if we had created the default close button before, remove it now that we
+ // have some user-defined button
+ if ( m_impl->m_close )
+ {
+ gtk_widget_destroy(m_impl->m_close);
+ m_impl->m_close = NULL;
+ }
+
+ GtkWidget * const button = GTKAddButton(btnid, label);
+ if ( button )
+ m_impl->m_buttons.push_back(wxInfoBarGTKImpl::Button(button, btnid));
}
void wxInfoBar::RemoveButton(wxWindowID btnid)
i != buttons.rend();
++i )
{
- GtkWidget * const button = i->button;
+ gtk_widget_destroy(i->button);
buttons.erase(i.base());
- gtk_widget_destroy(button);
- g_object_unref(button);
+
+ // see comment in GTKAddButton()
+ InvalidateBestSize();
+
return;
}