This is slightly simpler, as it doesn't require checking whether the
control state really changes or not (it always does if DoEnable() is
called) and allows disabling the controls before creating them, e.g.
code like
wxButton* const b = new wxButton();
b->Disable();
b->Create(this, wxID_OK);
works as expected now instead of spewing GTK+ errors.
712 lines
21 KiB
C++
712 lines
21 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/gtk/radiobox.cpp
|
|
// Purpose:
|
|
// Author: Robert Roebling
|
|
// Copyright: (c) 1998 Robert Roebling
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#if wxUSE_RADIOBOX
|
|
|
|
#include "wx/radiobox.h"
|
|
|
|
#if wxUSE_TOOLTIPS
|
|
#include "wx/tooltip.h"
|
|
#endif
|
|
|
|
#include "wx/gtk/private.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxGTKRadioButtonInfo
|
|
//-----------------------------------------------------------------------------
|
|
// structure internally used by wxRadioBox to store its child buttons
|
|
|
|
class wxGTKRadioButtonInfo : public wxObject
|
|
{
|
|
public:
|
|
wxGTKRadioButtonInfo( GtkRadioButton * abutton, const wxRect & arect )
|
|
: button( abutton ), rect( arect ) {}
|
|
|
|
GtkRadioButton * button;
|
|
wxRect rect;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// data
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "wx/listimpl.cpp"
|
|
WX_DEFINE_LIST( wxRadioBoxButtonsInfoList )
|
|
|
|
extern bool g_blockEventsOnDrag;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// "clicked"
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern "C" {
|
|
static void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioBox *rb )
|
|
{
|
|
if (g_blockEventsOnDrag) return;
|
|
|
|
if (!gtk_toggle_button_get_active(button)) return;
|
|
|
|
wxCommandEvent event( wxEVT_RADIOBOX, rb->GetId() );
|
|
event.SetInt( rb->GetSelection() );
|
|
event.SetString( rb->GetStringSelection() );
|
|
event.SetEventObject( rb );
|
|
rb->HandleWindowEvent(event);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// "key_press_event"
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern "C" {
|
|
static gint gtk_radiobox_keypress_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxRadioBox *rb )
|
|
{
|
|
if (g_blockEventsOnDrag) return FALSE;
|
|
|
|
if ( ((gdk_event->keyval == GDK_KEY_Tab) ||
|
|
(gdk_event->keyval == GDK_KEY_ISO_Left_Tab)) &&
|
|
rb->GetParent() && (rb->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
|
|
{
|
|
wxNavigationKeyEvent new_event;
|
|
new_event.SetEventObject( rb->GetParent() );
|
|
// GDK reports GDK_ISO_Left_Tab for SHIFT-TAB
|
|
new_event.SetDirection( (gdk_event->keyval == GDK_KEY_Tab) );
|
|
// CTRL-TAB changes the (parent) window, i.e. switch notebook page
|
|
new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) != 0 );
|
|
new_event.SetCurrentFocus( rb );
|
|
return rb->GetParent()->HandleWindowEvent(new_event);
|
|
}
|
|
|
|
if ((gdk_event->keyval != GDK_KEY_Up) &&
|
|
(gdk_event->keyval != GDK_KEY_Down) &&
|
|
(gdk_event->keyval != GDK_KEY_Left) &&
|
|
(gdk_event->keyval != GDK_KEY_Right))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = rb->m_buttonsInfo.GetFirst();
|
|
while( node && GTK_WIDGET( node->GetData()->button ) != widget )
|
|
{
|
|
node = node->GetNext();
|
|
}
|
|
if (!node)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ((gdk_event->keyval == GDK_KEY_Up) ||
|
|
(gdk_event->keyval == GDK_KEY_Left))
|
|
{
|
|
if (node == rb->m_buttonsInfo.GetFirst())
|
|
node = rb->m_buttonsInfo.GetLast();
|
|
else
|
|
node = node->GetPrevious();
|
|
}
|
|
else
|
|
{
|
|
if (node == rb->m_buttonsInfo.GetLast())
|
|
node = rb->m_buttonsInfo.GetFirst();
|
|
else
|
|
node = node->GetNext();
|
|
}
|
|
|
|
GtkWidget *button = (GtkWidget*) node->GetData()->button;
|
|
|
|
gtk_widget_grab_focus( button );
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
static gint gtk_radiobutton_focus_out( GtkWidget * WXUNUSED(widget),
|
|
GdkEventFocus *WXUNUSED(event),
|
|
wxRadioBox *win )
|
|
{
|
|
// NB: This control is composed of several GtkRadioButton widgets and
|
|
// when focus changes from one of them to another in the same
|
|
// wxRadioBox, we get a focus-out event followed by focus-in for
|
|
// another GtkRadioButton owned by the same control. We don't want
|
|
// to generate two spurious wxEVT_SET_FOCUS events in this case,
|
|
// so we defer sending wx events until idle time.
|
|
win->GTKHandleFocusOut();
|
|
|
|
// never stop the signal emission, it seems to break the kbd handling
|
|
// inside the radiobox
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
static gint gtk_radiobutton_focus_in( GtkWidget * WXUNUSED(widget),
|
|
GdkEventFocus *WXUNUSED(event),
|
|
wxRadioBox *win )
|
|
{
|
|
win->GTKHandleFocusIn();
|
|
|
|
// never stop the signal emission, it seems to break the kbd handling
|
|
// inside the radiobox
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
extern "C" {
|
|
static void gtk_radiobutton_size_allocate( GtkWidget *widget,
|
|
GtkAllocation * alloc,
|
|
wxRadioBox *win )
|
|
{
|
|
for ( wxRadioBoxButtonsInfoList::compatibility_iterator node = win->m_buttonsInfo.GetFirst();
|
|
node;
|
|
node = node->GetNext())
|
|
{
|
|
if (widget == GTK_WIDGET(node->GetData()->button))
|
|
{
|
|
const wxPoint origin = win->GetPosition();
|
|
wxRect rect = wxRect( alloc->x - origin.x, alloc->y - origin.y,
|
|
alloc->width, alloc->height );
|
|
node->GetData()->rect = rect;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef __WXGTK3__
|
|
extern "C" {
|
|
static gboolean expose_event(GtkWidget* widget, GdkEventExpose*, wxWindow*)
|
|
{
|
|
const GtkAllocation& a = widget->allocation;
|
|
gtk_paint_flat_box(gtk_widget_get_style(widget), gtk_widget_get_window(widget),
|
|
GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, "", a.x, a.y, a.width, a.height);
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// wxRadioBox
|
|
//-----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl);
|
|
|
|
bool wxRadioBox::Create( wxWindow *parent, wxWindowID id,
|
|
const wxString& title,
|
|
const wxPoint &pos, const wxSize &size,
|
|
const wxArrayString& choices, int majorDim,
|
|
long style, const wxValidator& validator,
|
|
const wxString &name )
|
|
{
|
|
wxCArrayString chs(choices);
|
|
|
|
return Create( parent, id, title, pos, size, chs.GetCount(),
|
|
chs.GetStrings(), majorDim, style, validator, name );
|
|
}
|
|
|
|
bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
|
|
const wxPoint &pos, const wxSize &size,
|
|
int n, const wxString choices[], int majorDim,
|
|
long style, const wxValidator& validator,
|
|
const wxString &name )
|
|
{
|
|
if (!PreCreation( parent, pos, size ) ||
|
|
!CreateBase( parent, id, pos, size, style, validator, name ))
|
|
{
|
|
wxFAIL_MSG( wxT("wxRadioBox creation failed") );
|
|
return false;
|
|
}
|
|
|
|
m_widget = GTKCreateFrame(title);
|
|
g_object_ref(m_widget);
|
|
wxControl::SetLabel(title);
|
|
if ( HasFlag(wxNO_BORDER) )
|
|
{
|
|
// If we don't do this here, the wxNO_BORDER style is ignored in Show()
|
|
gtk_frame_set_shadow_type(GTK_FRAME(m_widget), GTK_SHADOW_NONE);
|
|
}
|
|
|
|
|
|
// majorDim may be 0 if all trailing parameters were omitted, so don't
|
|
// assert here but just use the correct value for it
|
|
SetMajorDim(majorDim == 0 ? n : majorDim, style);
|
|
|
|
|
|
unsigned int num_of_cols = GetColumnCount();
|
|
unsigned int num_of_rows = GetRowCount();
|
|
|
|
GtkRadioButton *rbtn = NULL;
|
|
|
|
#ifdef __WXGTK3__
|
|
GtkWidget* grid = gtk_grid_new();
|
|
gtk_widget_show(grid);
|
|
gtk_container_add(GTK_CONTAINER(m_widget), grid);
|
|
#else
|
|
GtkWidget *table = gtk_table_new( num_of_rows, num_of_cols, FALSE );
|
|
gtk_table_set_col_spacings( GTK_TABLE(table), 1 );
|
|
gtk_table_set_row_spacings( GTK_TABLE(table), 1 );
|
|
gtk_widget_show( table );
|
|
gtk_container_add( GTK_CONTAINER(m_widget), table );
|
|
#endif
|
|
|
|
GSList *radio_button_group = NULL;
|
|
for (unsigned int i = 0; i < (unsigned int)n; i++)
|
|
{
|
|
if ( i != 0 )
|
|
radio_button_group = gtk_radio_button_get_group( GTK_RADIO_BUTTON(rbtn) );
|
|
|
|
// Process mnemonic in the label
|
|
wxString label;
|
|
bool hasMnemonic = false;
|
|
for ( wxString::const_iterator pc = choices[i].begin();
|
|
pc != choices[i].end(); ++pc )
|
|
{
|
|
if ( *pc == wxS('_') )
|
|
{
|
|
// If we have a literal underscore character in the label
|
|
// containing mnemonic, two underscores should be used.
|
|
if ( hasMnemonic )
|
|
label += wxS('_');
|
|
}
|
|
else if ( *pc == wxS('&') )
|
|
{
|
|
++pc; // skip it
|
|
if ( pc == choices[i].end() )
|
|
{
|
|
break;
|
|
}
|
|
else if ( *pc != wxS('&') )
|
|
{
|
|
if ( !hasMnemonic )
|
|
{
|
|
hasMnemonic = true;
|
|
// So far we assumed that label doesn't contain mnemonic
|
|
// and therefore single underscore characters were not
|
|
// replaced by two underscores. Now we have to double
|
|
// all existing underscore characters.
|
|
label.Replace(wxS("_"), wxS("__"));
|
|
label += wxS('_');
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG(wxT("duplicate mnemonic char in radio button label"));
|
|
}
|
|
}
|
|
}
|
|
|
|
label += *pc;
|
|
}
|
|
if ( hasMnemonic )
|
|
rbtn = GTK_RADIO_BUTTON( gtk_radio_button_new_with_mnemonic( radio_button_group, wxGTK_CONV( label ) ) );
|
|
else
|
|
rbtn = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label( radio_button_group, wxGTK_CONV( label ) ) );
|
|
|
|
gtk_widget_show( GTK_WIDGET(rbtn) );
|
|
|
|
g_signal_connect (rbtn, "key_press_event",
|
|
G_CALLBACK (gtk_radiobox_keypress_callback), this);
|
|
|
|
m_buttonsInfo.Append( new wxGTKRadioButtonInfo( rbtn, wxRect() ) );
|
|
|
|
#ifdef __WXGTK3__
|
|
int left, top;
|
|
if (HasFlag(wxRA_SPECIFY_COLS))
|
|
{
|
|
left = i % num_of_cols;
|
|
top = i / num_of_cols;
|
|
}
|
|
else
|
|
{
|
|
left = i / num_of_rows;
|
|
top = i % num_of_rows;
|
|
}
|
|
gtk_grid_attach(GTK_GRID(grid), GTK_WIDGET(rbtn), left, top, 1, 1);
|
|
#else
|
|
if (HasFlag(wxRA_SPECIFY_COLS))
|
|
{
|
|
int left = i%num_of_cols;
|
|
int right = (i%num_of_cols) + 1;
|
|
int top = i/num_of_cols;
|
|
int bottom = (i/num_of_cols)+1;
|
|
gtk_table_attach( GTK_TABLE(table), GTK_WIDGET(rbtn), left, right, top, bottom,
|
|
GTK_FILL, GTK_FILL, 1, 1 );
|
|
}
|
|
else
|
|
{
|
|
int left = i/num_of_rows;
|
|
int right = (i/num_of_rows) + 1;
|
|
int top = i%num_of_rows;
|
|
int bottom = (i%num_of_rows)+1;
|
|
gtk_table_attach( GTK_TABLE(table), GTK_WIDGET(rbtn), left, right, top, bottom,
|
|
GTK_FILL, GTK_FILL, 1, 1 );
|
|
}
|
|
#endif
|
|
|
|
ConnectWidget( GTK_WIDGET(rbtn) );
|
|
|
|
if (!i)
|
|
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(rbtn), TRUE );
|
|
|
|
g_signal_connect (rbtn, "clicked",
|
|
G_CALLBACK (gtk_radiobutton_clicked_callback), this);
|
|
g_signal_connect (rbtn, "focus_in_event",
|
|
G_CALLBACK (gtk_radiobutton_focus_in), this);
|
|
g_signal_connect (rbtn, "focus_out_event",
|
|
G_CALLBACK (gtk_radiobutton_focus_out), this);
|
|
g_signal_connect (rbtn, "size_allocate",
|
|
G_CALLBACK (gtk_radiobutton_size_allocate), this);
|
|
}
|
|
|
|
m_parent->DoAddChild( this );
|
|
|
|
PostCreation(size);
|
|
|
|
return true;
|
|
}
|
|
|
|
wxRadioBox::~wxRadioBox()
|
|
{
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkWidget *button = GTK_WIDGET( node->GetData()->button );
|
|
GTKDisconnect(button);
|
|
gtk_widget_destroy( button );
|
|
node = node->GetNext();
|
|
}
|
|
WX_CLEAR_LIST( wxRadioBoxButtonsInfoList, m_buttonsInfo );
|
|
}
|
|
|
|
bool wxRadioBox::Show( bool show )
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
|
|
|
|
if (!wxControl::Show(show))
|
|
{
|
|
// nothing to do
|
|
return false;
|
|
}
|
|
|
|
if ( HasFlag(wxNO_BORDER) )
|
|
gtk_widget_hide( m_widget );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkWidget *button = GTK_WIDGET( node->GetData()->button );
|
|
|
|
if (show)
|
|
gtk_widget_show( button );
|
|
else
|
|
gtk_widget_hide( button );
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxRadioBox::SetSelection( int n )
|
|
{
|
|
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( n );
|
|
|
|
wxCHECK_RET( node, wxT("radiobox wrong index") );
|
|
|
|
GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->GetData()->button );
|
|
|
|
GtkDisableEvents();
|
|
|
|
gtk_toggle_button_set_active( button, 1 );
|
|
|
|
GtkEnableEvents();
|
|
}
|
|
|
|
int wxRadioBox::GetSelection(void) const
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid radiobox") );
|
|
|
|
int count = 0;
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->GetData()->button );
|
|
if (gtk_toggle_button_get_active(button)) return count;
|
|
count++;
|
|
node = node->GetNext();
|
|
}
|
|
|
|
wxFAIL_MSG( wxT("wxRadioBox none selected") );
|
|
|
|
return wxNOT_FOUND;
|
|
}
|
|
|
|
wxString wxRadioBox::GetString(unsigned int n) const
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, wxEmptyString, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( n );
|
|
|
|
wxCHECK_MSG( node, wxEmptyString, wxT("radiobox wrong index") );
|
|
|
|
GtkLabel* label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(node->GetData()->button)));
|
|
|
|
wxString str( wxGTK_CONV_BACK( gtk_label_get_text(label) ) );
|
|
|
|
return str;
|
|
}
|
|
|
|
void wxRadioBox::SetLabel( const wxString& label )
|
|
{
|
|
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
|
|
|
|
GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
|
|
}
|
|
|
|
void wxRadioBox::SetString(unsigned int item, const wxString& label)
|
|
{
|
|
wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
|
|
|
|
wxCHECK_RET( node, wxT("radiobox wrong index") );
|
|
|
|
GtkLabel* g_label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(node->GetData()->button)));
|
|
|
|
gtk_label_set_text( g_label, wxGTK_CONV( label ) );
|
|
}
|
|
|
|
bool wxRadioBox::Enable( bool enable )
|
|
{
|
|
// Explicitly forward to the base class just because we need to override
|
|
// this function to prevent it from being hidden by Enable(int, bool)
|
|
// overload.
|
|
return wxControl::Enable(enable);
|
|
}
|
|
|
|
void wxRadioBox::DoEnable(bool enable)
|
|
{
|
|
if ( !m_widget )
|
|
return;
|
|
|
|
wxControl::DoEnable(enable);
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkButton *button = GTK_BUTTON( node->GetData()->button );
|
|
GtkLabel *label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(button)));
|
|
|
|
gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
|
|
gtk_widget_set_sensitive( GTK_WIDGET(label), enable );
|
|
node = node->GetNext();
|
|
}
|
|
|
|
if (enable)
|
|
GTKFixSensitivity();
|
|
}
|
|
|
|
bool wxRadioBox::Enable(unsigned int item, bool enable)
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
|
|
|
|
wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
|
|
|
|
GtkButton *button = GTK_BUTTON( node->GetData()->button );
|
|
GtkLabel *label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(button)));
|
|
|
|
gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
|
|
gtk_widget_set_sensitive( GTK_WIDGET(label), enable );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxRadioBox::IsItemEnabled(unsigned int item) const
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
|
|
|
|
wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
|
|
|
|
GtkButton *button = GTK_BUTTON( node->GetData()->button );
|
|
|
|
// don't use GTK_WIDGET_IS_SENSITIVE() here, we want to return true even if
|
|
// the parent radiobox is disabled
|
|
return gtk_widget_get_sensitive(GTK_WIDGET(button)) != 0;
|
|
}
|
|
|
|
bool wxRadioBox::Show(unsigned int item, bool show)
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
|
|
|
|
wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
|
|
|
|
GtkWidget *button = GTK_WIDGET( node->GetData()->button );
|
|
|
|
if (show)
|
|
gtk_widget_show( button );
|
|
else
|
|
gtk_widget_hide( button );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxRadioBox::IsItemShown(unsigned int item) const
|
|
{
|
|
wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
|
|
|
|
wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
|
|
|
|
GtkButton *button = GTK_BUTTON( node->GetData()->button );
|
|
|
|
return gtk_widget_get_visible(GTK_WIDGET(button)) != 0;
|
|
}
|
|
|
|
unsigned int wxRadioBox::GetCount() const
|
|
{
|
|
return m_buttonsInfo.GetCount();
|
|
}
|
|
|
|
void wxRadioBox::GtkDisableEvents()
|
|
{
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
g_signal_handlers_block_by_func(node->GetData()->button,
|
|
(gpointer)gtk_radiobutton_clicked_callback, this);
|
|
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
void wxRadioBox::GtkEnableEvents()
|
|
{
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
g_signal_handlers_unblock_by_func(node->GetData()->button,
|
|
(gpointer)gtk_radiobutton_clicked_callback, this);
|
|
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
void wxRadioBox::DoApplyWidgetStyle(GtkRcStyle *style)
|
|
{
|
|
GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkWidget *widget = GTK_WIDGET( node->GetData()->button );
|
|
|
|
GTKApplyStyle(widget, style);
|
|
GTKApplyStyle(gtk_bin_get_child(GTK_BIN(widget)), style);
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
#ifndef __WXGTK3__
|
|
g_signal_handlers_disconnect_by_func(m_widget, (void*)expose_event, this);
|
|
if (m_backgroundColour.IsOk())
|
|
g_signal_connect(m_widget, "expose-event", G_CALLBACK(expose_event), this);
|
|
#endif
|
|
}
|
|
|
|
bool wxRadioBox::GTKWidgetNeedsMnemonic() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void wxRadioBox::GTKWidgetDoSetMnemonic(GtkWidget* w)
|
|
{
|
|
GTKFrameSetMnemonicWidget(GTK_FRAME(m_widget), w);
|
|
}
|
|
|
|
#if wxUSE_TOOLTIPS
|
|
void wxRadioBox::GTKApplyToolTip(const char* tip)
|
|
{
|
|
// set this tooltip for all radiobuttons which don't have their own tips
|
|
unsigned n = 0;
|
|
for ( wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
node;
|
|
node = node->GetNext(), n++ )
|
|
{
|
|
if ( !GetItemToolTip(n) )
|
|
{
|
|
wxToolTip::GTKApply(GTK_WIDGET(node->GetData()->button), tip);
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxRadioBox::DoSetItemToolTip(unsigned int n, wxToolTip *tooltip)
|
|
{
|
|
wxCharBuffer buf;
|
|
if ( !tooltip )
|
|
tooltip = GetToolTip();
|
|
if ( tooltip )
|
|
buf = wxGTK_CONV(tooltip->GetTip());
|
|
|
|
wxToolTip::GTKApply(GTK_WIDGET(m_buttonsInfo[n]->button), buf);
|
|
}
|
|
|
|
#endif // wxUSE_TOOLTIPS
|
|
|
|
GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const
|
|
{
|
|
windows.push_back(gtk_widget_get_window(m_widget));
|
|
|
|
wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
|
|
while (node)
|
|
{
|
|
GtkWidget *button = GTK_WIDGET( node->GetData()->button );
|
|
|
|
// don't put NULL pointers in the 'windows' array!
|
|
if (gtk_widget_get_window(button))
|
|
windows.push_back(gtk_widget_get_window(button));
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// static
|
|
wxVisualAttributes
|
|
wxRadioBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
|
|
{
|
|
return GetDefaultAttributesFromGTKWidget(gtk_radio_button_new_with_label(NULL, ""));
|
|
}
|
|
|
|
int wxRadioBox::GetItemFromPoint(const wxPoint& point) const
|
|
{
|
|
const wxPoint pt = ScreenToClient(point);
|
|
unsigned n = 0;
|
|
for ( wxRadioBoxButtonsInfoList::compatibility_iterator
|
|
node = m_buttonsInfo.GetFirst(); node; node = node->GetNext(), n++ )
|
|
{
|
|
if ( m_buttonsInfo[n]->rect.Contains(pt) )
|
|
return n;
|
|
}
|
|
|
|
return wxNOT_FOUND;
|
|
}
|
|
|
|
#endif // wxUSE_RADIOBOX
|