Refactor wxButton and wxToggleButton to derive from wxAnyButton.
Introduce wxAnyButton class, a common base class for wxButton and wxToggleButton, allowing to reuse the same implementation for them. This also allows to implement support for bitmaps in wxToggleButton for all platforms and make wxBitmapToggleButton a trivial subclass of it everywhere, similarly to wxBitmapButton and wxButton. Closes #13198. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67931 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -45,157 +45,30 @@ wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent );
|
||||
// wxBitmapToggleButton
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxControl)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton)
|
||||
|
||||
bool wxBitmapToggleButton::Create(wxWindow *parent, wxWindowID id,
|
||||
const wxBitmap &label, const wxPoint &pos,
|
||||
const wxBitmap &bitmap, const wxPoint &pos,
|
||||
const wxSize &size, long style,
|
||||
const wxValidator& validator,
|
||||
const wxString &name)
|
||||
{
|
||||
if (!PreCreation(parent, pos, size) ||
|
||||
!CreateBase(parent, id, pos, size, style, validator, name ))
|
||||
{
|
||||
wxFAIL_MSG(wxT("wxBitmapToggleButton creation failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the gtk widget.
|
||||
m_widget = gtk_toggle_button_new();
|
||||
g_object_ref(m_widget);
|
||||
|
||||
if (style & wxNO_BORDER)
|
||||
gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
|
||||
|
||||
m_bitmap = label;
|
||||
OnSetBitmap();
|
||||
|
||||
g_signal_connect (m_widget, "clicked",
|
||||
G_CALLBACK (gtk_togglebutton_clicked_callback),
|
||||
this);
|
||||
|
||||
m_parent->DoAddChild(this);
|
||||
|
||||
PostCreation(size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxBitmapToggleButton::GTKDisableEvents()
|
||||
{
|
||||
g_signal_handlers_block_by_func(m_widget,
|
||||
(gpointer) gtk_togglebutton_clicked_callback, this);
|
||||
}
|
||||
|
||||
void wxBitmapToggleButton::GTKEnableEvents()
|
||||
{
|
||||
g_signal_handlers_unblock_by_func(m_widget,
|
||||
(gpointer) gtk_togglebutton_clicked_callback, this);
|
||||
}
|
||||
|
||||
// void SetValue(bool state)
|
||||
// Set the value of the toggle button.
|
||||
void wxBitmapToggleButton::SetValue(bool state)
|
||||
{
|
||||
wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
|
||||
|
||||
if (state == GetValue())
|
||||
return;
|
||||
|
||||
GTKDisableEvents();
|
||||
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), state);
|
||||
|
||||
GTKEnableEvents();
|
||||
}
|
||||
|
||||
// bool GetValue() const
|
||||
// Get the value of the toggle button.
|
||||
bool wxBitmapToggleButton::GetValue() const
|
||||
{
|
||||
wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
|
||||
|
||||
return gtk_toggle_button_get_active((GtkToggleButton*)m_widget);
|
||||
}
|
||||
|
||||
void wxBitmapToggleButton::SetLabel(const wxBitmap& label)
|
||||
{
|
||||
wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
|
||||
|
||||
m_bitmap = label;
|
||||
InvalidateBestSize();
|
||||
|
||||
OnSetBitmap();
|
||||
}
|
||||
|
||||
void wxBitmapToggleButton::OnSetBitmap()
|
||||
{
|
||||
if (!m_bitmap.IsOk()) return;
|
||||
|
||||
GtkWidget* image = gtk_bin_get_child(GTK_BIN(m_widget));
|
||||
if (image == NULL)
|
||||
{
|
||||
image = gtk_image_new();
|
||||
gtk_widget_show(image);
|
||||
gtk_container_add((GtkContainer*)m_widget, image);
|
||||
}
|
||||
// always use pixbuf, because pixmap mask does not
|
||||
// work with disabled images in some themes
|
||||
gtk_image_set_from_pixbuf((GtkImage*)image, m_bitmap.GetPixbuf());
|
||||
}
|
||||
|
||||
bool wxBitmapToggleButton::Enable(bool enable /*=true*/)
|
||||
{
|
||||
bool isEnabled = IsEnabled();
|
||||
|
||||
if (!wxControl::Enable(enable))
|
||||
if ( !wxToggleButton::Create(parent, id, wxEmptyString, pos, size, style | wxBU_NOTEXT | wxBU_EXACTFIT,
|
||||
validator, name) )
|
||||
return false;
|
||||
|
||||
gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable);
|
||||
|
||||
if (!isEnabled && enable)
|
||||
if ( bitmap.IsOk() )
|
||||
{
|
||||
GTKFixSensitivity();
|
||||
SetBitmapLabel(bitmap);
|
||||
|
||||
// we need to adjust the size after setting the bitmap as it may be too
|
||||
// big for the default button size
|
||||
SetInitialSize(size);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxBitmapToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||
{
|
||||
gtk_widget_modify_style(m_widget, style);
|
||||
gtk_widget_modify_style(gtk_bin_get_child(GTK_BIN(m_widget)), style);
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
wxBitmapToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
|
||||
{
|
||||
return GTK_BUTTON(m_widget)->event_window;
|
||||
}
|
||||
|
||||
// Get the "best" size for this control.
|
||||
wxSize wxBitmapToggleButton::DoGetBestSize() const
|
||||
{
|
||||
wxSize best;
|
||||
|
||||
if (m_bitmap.IsOk())
|
||||
{
|
||||
int border = HasFlag(wxNO_BORDER) ? 4 : 10;
|
||||
best.x = m_bitmap.GetWidth()+border;
|
||||
best.y = m_bitmap.GetHeight()+border;
|
||||
}
|
||||
CacheBestSize(best);
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
wxVisualAttributes
|
||||
wxBitmapToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
|
||||
{
|
||||
return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// wxToggleButton
|
||||
@@ -216,11 +89,28 @@ bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the gtk widget.
|
||||
m_widget = gtk_toggle_button_new_with_mnemonic("");
|
||||
// create either a standard toggle button with text label (which may still contain
|
||||
// an image under GTK+ 2.6+) or a bitmap-only toggle button if we don't have any
|
||||
// label
|
||||
const bool
|
||||
useLabel = !(style & wxBU_NOTEXT) && !label.empty();
|
||||
if ( useLabel )
|
||||
{
|
||||
m_widget = gtk_toggle_button_new_with_mnemonic("");
|
||||
}
|
||||
else // no label, suppose we will have a bitmap
|
||||
{
|
||||
m_widget = gtk_toggle_button_new();
|
||||
|
||||
GtkWidget *image = gtk_image_new();
|
||||
gtk_widget_show(image);
|
||||
gtk_container_add(GTK_CONTAINER(m_widget), image);
|
||||
}
|
||||
|
||||
g_object_ref(m_widget);
|
||||
|
||||
SetLabel(label);
|
||||
if ( useLabel )
|
||||
SetLabel(label);
|
||||
|
||||
g_signal_connect (m_widget, "clicked",
|
||||
G_CALLBACK (gtk_togglebutton_clicked_callback),
|
||||
@@ -274,7 +164,7 @@ void wxToggleButton::SetLabel(const wxString& label)
|
||||
{
|
||||
wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
|
||||
|
||||
wxControl::SetLabel(label);
|
||||
wxAnyButton::SetLabel(label);
|
||||
|
||||
const wxString labelGTK = GTKConvertMnemonics(label);
|
||||
|
||||
@@ -283,18 +173,31 @@ void wxToggleButton::SetLabel(const wxString& label)
|
||||
GTKApplyWidgetStyle( false );
|
||||
}
|
||||
|
||||
bool wxToggleButton::Enable(bool enable /*=true*/)
|
||||
#if wxUSE_MARKUP
|
||||
bool wxToggleButton::DoSetLabelMarkup(const wxString& markup)
|
||||
{
|
||||
if (!base_type::Enable(enable))
|
||||
wxCHECK_MSG( m_widget != NULL, false, "invalid toggle button" );
|
||||
|
||||
const wxString stripped = RemoveMarkup(markup);
|
||||
if ( stripped.empty() && !markup.empty() )
|
||||
return false;
|
||||
|
||||
gtk_widget_set_sensitive(gtk_bin_get_child(GTK_BIN(m_widget)), enable);
|
||||
wxControl::SetLabel(stripped);
|
||||
|
||||
if (enable)
|
||||
GTKFixSensitivity();
|
||||
GtkLabel * const label = GTKGetLabel();
|
||||
wxCHECK_MSG( label, false, "no label in this toggle button?" );
|
||||
|
||||
GTKSetLabelWithMarkupForLabel(label, markup);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // wxUSE_MARKUP
|
||||
|
||||
GtkLabel *wxToggleButton::GTKGetLabel() const
|
||||
{
|
||||
GtkWidget* child = gtk_bin_get_child(GTK_BIN(m_widget));
|
||||
return GTK_LABEL(child);
|
||||
}
|
||||
|
||||
void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||
{
|
||||
@@ -302,16 +205,10 @@ void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
|
||||
gtk_widget_modify_style(gtk_bin_get_child(GTK_BIN(m_widget)), style);
|
||||
}
|
||||
|
||||
GdkWindow *
|
||||
wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
|
||||
{
|
||||
return GTK_BUTTON(m_widget)->event_window;
|
||||
}
|
||||
|
||||
// Get the "best" size for this control.
|
||||
wxSize wxToggleButton::DoGetBestSize() const
|
||||
{
|
||||
wxSize ret(wxControl::DoGetBestSize());
|
||||
wxSize ret(wxAnyButton::DoGetBestSize());
|
||||
|
||||
if (!HasFlag(wxBU_EXACTFIT))
|
||||
{
|
||||
|
Reference in New Issue
Block a user