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
230 lines
6.3 KiB
C++
230 lines
6.3 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/gtk/tglbtn.cpp
|
|
// Purpose: Definition of the wxToggleButton class, which implements a
|
|
// toggle button under wxGTK.
|
|
// Author: John Norris, minor changes by Axel Schlueter
|
|
// Modified by:
|
|
// Created: 08.02.01
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 2000 Johnny C. Norris II
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#if wxUSE_TOGGLEBTN
|
|
|
|
#include "wx/tglbtn.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/button.h"
|
|
#endif
|
|
|
|
#include "wx/gtk/private.h"
|
|
|
|
extern bool g_blockEventsOnDrag;
|
|
|
|
extern "C" {
|
|
static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
|
|
{
|
|
if (!cb->m_hasVMT || g_blockEventsOnDrag)
|
|
return;
|
|
|
|
// Generate a wx event.
|
|
wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, cb->GetId());
|
|
event.SetInt(cb->GetValue());
|
|
event.SetEventObject(cb);
|
|
cb->HandleWindowEvent(event);
|
|
}
|
|
}
|
|
|
|
wxDEFINE_EVENT( wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEvent );
|
|
|
|
// ------------------------------------------------------------------------
|
|
// wxBitmapToggleButton
|
|
// ------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton)
|
|
|
|
bool wxBitmapToggleButton::Create(wxWindow *parent, wxWindowID id,
|
|
const wxBitmap &bitmap, const wxPoint &pos,
|
|
const wxSize &size, long style,
|
|
const wxValidator& validator,
|
|
const wxString &name)
|
|
{
|
|
if ( !wxToggleButton::Create(parent, id, wxEmptyString, pos, size, style | wxBU_NOTEXT | wxBU_EXACTFIT,
|
|
validator, name) )
|
|
return false;
|
|
|
|
if ( bitmap.IsOk() )
|
|
{
|
|
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;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------
|
|
// wxToggleButton
|
|
// ------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
|
|
|
|
bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
|
|
const wxString &label, 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("wxToggleButton creation failed"));
|
|
return false;
|
|
}
|
|
|
|
// 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);
|
|
|
|
if ( useLabel )
|
|
SetLabel(label);
|
|
|
|
g_signal_connect (m_widget, "clicked",
|
|
G_CALLBACK (gtk_togglebutton_clicked_callback),
|
|
this);
|
|
|
|
m_parent->DoAddChild(this);
|
|
|
|
PostCreation(size);
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxToggleButton::GTKDisableEvents()
|
|
{
|
|
g_signal_handlers_block_by_func(m_widget,
|
|
(gpointer) gtk_togglebutton_clicked_callback, this);
|
|
}
|
|
|
|
void wxToggleButton::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 wxToggleButton::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 wxToggleButton::GetValue() const
|
|
{
|
|
wxCHECK_MSG(m_widget != NULL, false, wxT("invalid toggle button"));
|
|
|
|
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)) != 0;
|
|
}
|
|
|
|
void wxToggleButton::SetLabel(const wxString& label)
|
|
{
|
|
wxCHECK_RET(m_widget != NULL, wxT("invalid toggle button"));
|
|
|
|
wxAnyButton::SetLabel(label);
|
|
|
|
const wxString labelGTK = GTKConvertMnemonics(label);
|
|
|
|
gtk_button_set_label(GTK_BUTTON(m_widget), wxGTK_CONV(labelGTK));
|
|
|
|
GTKApplyWidgetStyle( false );
|
|
}
|
|
|
|
#if wxUSE_MARKUP
|
|
bool wxToggleButton::DoSetLabelMarkup(const wxString& markup)
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, "invalid toggle button" );
|
|
|
|
const wxString stripped = RemoveMarkup(markup);
|
|
if ( stripped.empty() && !markup.empty() )
|
|
return false;
|
|
|
|
wxControl::SetLabel(stripped);
|
|
|
|
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)
|
|
{
|
|
gtk_widget_modify_style(m_widget, style);
|
|
gtk_widget_modify_style(gtk_bin_get_child(GTK_BIN(m_widget)), style);
|
|
}
|
|
|
|
// Get the "best" size for this control.
|
|
wxSize wxToggleButton::DoGetBestSize() const
|
|
{
|
|
wxSize ret(wxAnyButton::DoGetBestSize());
|
|
|
|
if (!HasFlag(wxBU_EXACTFIT))
|
|
{
|
|
if (ret.x < 80) ret.x = 80;
|
|
}
|
|
|
|
CacheBestSize(ret);
|
|
return ret;
|
|
}
|
|
|
|
// static
|
|
wxVisualAttributes
|
|
wxToggleButton::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
|
|
{
|
|
return GetDefaultAttributesFromGTKWidget(gtk_toggle_button_new);
|
|
}
|
|
|
|
#endif // wxUSE_TOGGLEBTN
|