1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/radiobox.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Copyright: (c) 1998 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
8
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
11
12 #if wxUSE_RADIOBOX
13
14 #include "wx/radiobox.h"
15
16 #if wxUSE_TOOLTIPS
17 #include "wx/tooltip.h"
18 #endif
19
20 #include <gtk/gtk.h>
21 #include "wx/gtk/private.h"
22 #include "wx/gtk/private/gtk2-compat.h"
23
24 #include <gdk/gdkkeysyms.h>
25 #if GTK_CHECK_VERSION(3,0,0)
26 #include <gdk/gdkkeysyms-compat.h>
27 #endif
28
29 //-----------------------------------------------------------------------------
30 // wxGTKRadioButtonInfo
31 //-----------------------------------------------------------------------------
32 // structure internally used by wxRadioBox to store its child buttons
33
34 class wxGTKRadioButtonInfo : public wxObject
35 {
36 public:
wxGTKRadioButtonInfo(GtkRadioButton * abutton,const wxRect & arect)37 wxGTKRadioButtonInfo( GtkRadioButton * abutton, const wxRect & arect )
38 : button( abutton ), rect( arect ) {}
39
40 GtkRadioButton * button;
41 wxRect rect;
42 };
43
44 //-----------------------------------------------------------------------------
45 // data
46 //-----------------------------------------------------------------------------
47
48 #include "wx/listimpl.cpp"
49 WX_DEFINE_LIST( wxRadioBoxButtonsInfoList )
50
51 extern bool g_blockEventsOnDrag;
52
53 //-----------------------------------------------------------------------------
54 // "clicked"
55 //-----------------------------------------------------------------------------
56
57 extern "C" {
gtk_radiobutton_clicked_callback(GtkToggleButton * button,wxRadioBox * rb)58 static void gtk_radiobutton_clicked_callback( GtkToggleButton *button, wxRadioBox *rb )
59 {
60 if (g_blockEventsOnDrag) return;
61
62 if (!gtk_toggle_button_get_active(button)) return;
63
64 wxCommandEvent event( wxEVT_RADIOBOX, rb->GetId() );
65 event.SetInt( rb->GetSelection() );
66 event.SetString( rb->GetStringSelection() );
67 event.SetEventObject( rb );
68 rb->HandleWindowEvent(event);
69 }
70 }
71
72 //-----------------------------------------------------------------------------
73 // "key_press_event"
74 //-----------------------------------------------------------------------------
75
76 extern "C" {
gtk_radiobox_keypress_callback(GtkWidget * widget,GdkEventKey * gdk_event,wxRadioBox * rb)77 static gint gtk_radiobox_keypress_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxRadioBox *rb )
78 {
79 if (g_blockEventsOnDrag) return FALSE;
80
81 if ( ((gdk_event->keyval == GDK_Tab) ||
82 (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
83 rb->GetParent() && (rb->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
84 {
85 wxNavigationKeyEvent new_event;
86 new_event.SetEventObject( rb->GetParent() );
87 // GDK reports GDK_ISO_Left_Tab for SHIFT-TAB
88 new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
89 // CTRL-TAB changes the (parent) window, i.e. switch notebook page
90 new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) != 0 );
91 new_event.SetCurrentFocus( rb );
92 return rb->GetParent()->HandleWindowEvent(new_event);
93 }
94
95 if ((gdk_event->keyval != GDK_Up) &&
96 (gdk_event->keyval != GDK_Down) &&
97 (gdk_event->keyval != GDK_Left) &&
98 (gdk_event->keyval != GDK_Right))
99 {
100 return FALSE;
101 }
102
103 wxRadioBoxButtonsInfoList::compatibility_iterator node = rb->m_buttonsInfo.GetFirst();
104 while( node && GTK_WIDGET( node->GetData()->button ) != widget )
105 {
106 node = node->GetNext();
107 }
108 if (!node)
109 {
110 return FALSE;
111 }
112
113 if ((gdk_event->keyval == GDK_Up) ||
114 (gdk_event->keyval == GDK_Left))
115 {
116 if (node == rb->m_buttonsInfo.GetFirst())
117 node = rb->m_buttonsInfo.GetLast();
118 else
119 node = node->GetPrevious();
120 }
121 else
122 {
123 if (node == rb->m_buttonsInfo.GetLast())
124 node = rb->m_buttonsInfo.GetFirst();
125 else
126 node = node->GetNext();
127 }
128
129 GtkWidget *button = (GtkWidget*) node->GetData()->button;
130
131 gtk_widget_grab_focus( button );
132
133 return TRUE;
134 }
135 }
136
137 extern "C" {
gtk_radiobutton_focus_out(GtkWidget * WXUNUSED (widget),GdkEventFocus * WXUNUSED (event),wxRadioBox * win)138 static gint gtk_radiobutton_focus_out( GtkWidget * WXUNUSED(widget),
139 GdkEventFocus *WXUNUSED(event),
140 wxRadioBox *win )
141 {
142 // NB: This control is composed of several GtkRadioButton widgets and
143 // when focus changes from one of them to another in the same
144 // wxRadioBox, we get a focus-out event followed by focus-in for
145 // another GtkRadioButton owned by the same control. We don't want
146 // to generate two spurious wxEVT_SET_FOCUS events in this case,
147 // so we defer sending wx events until idle time.
148 win->GTKHandleFocusOut();
149
150 // never stop the signal emission, it seems to break the kbd handling
151 // inside the radiobox
152 return FALSE;
153 }
154 }
155
156 extern "C" {
gtk_radiobutton_focus_in(GtkWidget * WXUNUSED (widget),GdkEventFocus * WXUNUSED (event),wxRadioBox * win)157 static gint gtk_radiobutton_focus_in( GtkWidget * WXUNUSED(widget),
158 GdkEventFocus *WXUNUSED(event),
159 wxRadioBox *win )
160 {
161 win->GTKHandleFocusIn();
162
163 // never stop the signal emission, it seems to break the kbd handling
164 // inside the radiobox
165 return FALSE;
166 }
167 }
168
169 extern "C" {
gtk_radiobutton_size_allocate(GtkWidget * widget,GtkAllocation * alloc,wxRadioBox * win)170 static void gtk_radiobutton_size_allocate( GtkWidget *widget,
171 GtkAllocation * alloc,
172 wxRadioBox *win )
173 {
174 for ( wxRadioBoxButtonsInfoList::compatibility_iterator node = win->m_buttonsInfo.GetFirst();
175 node;
176 node = node->GetNext())
177 {
178 if (widget == GTK_WIDGET(node->GetData()->button))
179 {
180 const wxPoint origin = win->GetPosition();
181 wxRect rect = wxRect( alloc->x - origin.x, alloc->y - origin.y,
182 alloc->width, alloc->height );
183 node->GetData()->rect = rect;
184 break;
185 }
186 }
187 }
188 }
189
190 #ifndef __WXGTK3__
191 extern "C" {
expose_event(GtkWidget * widget,GdkEventExpose *,wxWindow *)192 static gboolean expose_event(GtkWidget* widget, GdkEventExpose*, wxWindow*)
193 {
194 const GtkAllocation& a = widget->allocation;
195 gtk_paint_flat_box(gtk_widget_get_style(widget), gtk_widget_get_window(widget),
196 GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, widget, "", a.x, a.y, a.width, a.height);
197 return false;
198 }
199 }
200 #endif
201
202 //-----------------------------------------------------------------------------
203 // wxRadioBox
204 //-----------------------------------------------------------------------------
205
IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)206 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)
207
208 bool wxRadioBox::Create( wxWindow *parent, wxWindowID id,
209 const wxString& title,
210 const wxPoint &pos, const wxSize &size,
211 const wxArrayString& choices, int majorDim,
212 long style, const wxValidator& validator,
213 const wxString &name )
214 {
215 wxCArrayString chs(choices);
216
217 return Create( parent, id, title, pos, size, chs.GetCount(),
218 chs.GetStrings(), majorDim, style, validator, name );
219 }
220
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)221 bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
222 const wxPoint &pos, const wxSize &size,
223 int n, const wxString choices[], int majorDim,
224 long style, const wxValidator& validator,
225 const wxString &name )
226 {
227 if (!PreCreation( parent, pos, size ) ||
228 !CreateBase( parent, id, pos, size, style, validator, name ))
229 {
230 wxFAIL_MSG( wxT("wxRadioBox creation failed") );
231 return false;
232 }
233
234 m_widget = GTKCreateFrame(title);
235 g_object_ref(m_widget);
236 wxControl::SetLabel(title);
237 if ( HasFlag(wxNO_BORDER) )
238 {
239 // If we don't do this here, the wxNO_BORDER style is ignored in Show()
240 gtk_frame_set_shadow_type(GTK_FRAME(m_widget), GTK_SHADOW_NONE);
241 }
242
243
244 // majorDim may be 0 if all trailing parameters were omitted, so don't
245 // assert here but just use the correct value for it
246 SetMajorDim(majorDim == 0 ? n : majorDim, style);
247
248
249 unsigned int num_of_cols = GetColumnCount();
250 unsigned int num_of_rows = GetRowCount();
251
252 GtkRadioButton *rbtn = NULL;
253
254 GtkWidget *table = gtk_table_new( num_of_rows, num_of_cols, FALSE );
255 gtk_table_set_col_spacings( GTK_TABLE(table), 1 );
256 gtk_table_set_row_spacings( GTK_TABLE(table), 1 );
257 gtk_widget_show( table );
258 gtk_container_add( GTK_CONTAINER(m_widget), table );
259
260 GSList *radio_button_group = NULL;
261 for (unsigned int i = 0; i < (unsigned int)n; i++)
262 {
263 if ( i != 0 )
264 radio_button_group = gtk_radio_button_get_group( GTK_RADIO_BUTTON(rbtn) );
265
266 // Process mnemonic in the label
267 wxString label;
268 bool hasMnemonic = false;
269 for ( wxString::const_iterator pc = choices[i].begin();
270 pc != choices[i].end(); ++pc )
271 {
272 if ( *pc == wxS('_') )
273 {
274 // If we have a literal underscore character in the label
275 // containing mnemonic, two underscores should be used.
276 if ( hasMnemonic )
277 label += wxS('_');
278 }
279 else if ( *pc == wxS('&') )
280 {
281 ++pc; // skip it
282 if ( pc == choices[i].end() )
283 {
284 break;
285 }
286 else if ( *pc != wxS('&') )
287 {
288 if ( !hasMnemonic )
289 {
290 hasMnemonic = true;
291 // So far we assumed that label doesn't contain mnemonic
292 // and therefore single underscore characters were not
293 // replaced by two underscores. Now we have to double
294 // all exisiting underscore characters.
295 label.Replace(wxS("_"), wxS("__"));
296 label += wxS('_');
297 }
298 else
299 {
300 wxFAIL_MSG(wxT("duplicate mnemonic char in radio button label"));
301 }
302 }
303 }
304
305 label += *pc;
306 }
307 if ( hasMnemonic )
308 rbtn = GTK_RADIO_BUTTON( gtk_radio_button_new_with_mnemonic( radio_button_group, wxGTK_CONV( label ) ) );
309 else
310 rbtn = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label( radio_button_group, wxGTK_CONV( label ) ) );
311
312 gtk_widget_show( GTK_WIDGET(rbtn) );
313
314 g_signal_connect (rbtn, "key_press_event",
315 G_CALLBACK (gtk_radiobox_keypress_callback), this);
316
317 m_buttonsInfo.Append( new wxGTKRadioButtonInfo( rbtn, wxRect() ) );
318
319 if (HasFlag(wxRA_SPECIFY_COLS))
320 {
321 int left = i%num_of_cols;
322 int right = (i%num_of_cols) + 1;
323 int top = i/num_of_cols;
324 int bottom = (i/num_of_cols)+1;
325 gtk_table_attach( GTK_TABLE(table), GTK_WIDGET(rbtn), left, right, top, bottom,
326 GTK_FILL, GTK_FILL, 1, 1 );
327 }
328 else
329 {
330 int left = i/num_of_rows;
331 int right = (i/num_of_rows) + 1;
332 int top = i%num_of_rows;
333 int bottom = (i%num_of_rows)+1;
334 gtk_table_attach( GTK_TABLE(table), GTK_WIDGET(rbtn), left, right, top, bottom,
335 GTK_FILL, GTK_FILL, 1, 1 );
336 }
337
338 ConnectWidget( GTK_WIDGET(rbtn) );
339
340 if (!i)
341 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(rbtn), TRUE );
342
343 g_signal_connect (rbtn, "clicked",
344 G_CALLBACK (gtk_radiobutton_clicked_callback), this);
345 g_signal_connect (rbtn, "focus_in_event",
346 G_CALLBACK (gtk_radiobutton_focus_in), this);
347 g_signal_connect (rbtn, "focus_out_event",
348 G_CALLBACK (gtk_radiobutton_focus_out), this);
349 g_signal_connect (rbtn, "size_allocate",
350 G_CALLBACK (gtk_radiobutton_size_allocate), this);
351 }
352
353 m_parent->DoAddChild( this );
354
355 PostCreation(size);
356
357 return true;
358 }
359
~wxRadioBox()360 wxRadioBox::~wxRadioBox()
361 {
362 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
363 while (node)
364 {
365 GtkWidget *button = GTK_WIDGET( node->GetData()->button );
366 GTKDisconnect(button);
367 gtk_widget_destroy( button );
368 node = node->GetNext();
369 }
370 WX_CLEAR_LIST( wxRadioBoxButtonsInfoList, m_buttonsInfo );
371 }
372
Show(bool show)373 bool wxRadioBox::Show( bool show )
374 {
375 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
376
377 if (!wxControl::Show(show))
378 {
379 // nothing to do
380 return false;
381 }
382
383 if ( HasFlag(wxNO_BORDER) )
384 gtk_widget_hide( m_widget );
385
386 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
387 while (node)
388 {
389 GtkWidget *button = GTK_WIDGET( node->GetData()->button );
390
391 if (show)
392 gtk_widget_show( button );
393 else
394 gtk_widget_hide( button );
395
396 node = node->GetNext();
397 }
398
399 return true;
400 }
401
SetSelection(int n)402 void wxRadioBox::SetSelection( int n )
403 {
404 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
405
406 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( n );
407
408 wxCHECK_RET( node, wxT("radiobox wrong index") );
409
410 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->GetData()->button );
411
412 GtkDisableEvents();
413
414 gtk_toggle_button_set_active( button, 1 );
415
416 GtkEnableEvents();
417 }
418
GetSelection(void) const419 int wxRadioBox::GetSelection(void) const
420 {
421 wxCHECK_MSG( m_widget != NULL, wxNOT_FOUND, wxT("invalid radiobox") );
422
423 int count = 0;
424
425 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
426 while (node)
427 {
428 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->GetData()->button );
429 if (gtk_toggle_button_get_active(button)) return count;
430 count++;
431 node = node->GetNext();
432 }
433
434 wxFAIL_MSG( wxT("wxRadioBox none selected") );
435
436 return wxNOT_FOUND;
437 }
438
GetString(unsigned int n) const439 wxString wxRadioBox::GetString(unsigned int n) const
440 {
441 wxCHECK_MSG( m_widget != NULL, wxEmptyString, wxT("invalid radiobox") );
442
443 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( n );
444
445 wxCHECK_MSG( node, wxEmptyString, wxT("radiobox wrong index") );
446
447 GtkLabel* label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(node->GetData()->button)));
448
449 wxString str( wxGTK_CONV_BACK( gtk_label_get_text(label) ) );
450
451 return str;
452 }
453
SetLabel(const wxString & label)454 void wxRadioBox::SetLabel( const wxString& label )
455 {
456 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
457
458 GTKSetLabelForFrame(GTK_FRAME(m_widget), label);
459 }
460
SetString(unsigned int item,const wxString & label)461 void wxRadioBox::SetString(unsigned int item, const wxString& label)
462 {
463 wxCHECK_RET( m_widget != NULL, wxT("invalid radiobox") );
464
465 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
466
467 wxCHECK_RET( node, wxT("radiobox wrong index") );
468
469 GtkLabel* g_label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(node->GetData()->button)));
470
471 gtk_label_set_text( g_label, wxGTK_CONV( label ) );
472 }
473
Enable(bool enable)474 bool wxRadioBox::Enable( bool enable )
475 {
476 if ( !wxControl::Enable( enable ) )
477 return false;
478
479 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
480 while (node)
481 {
482 GtkButton *button = GTK_BUTTON( node->GetData()->button );
483 GtkLabel *label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(button)));
484
485 gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
486 gtk_widget_set_sensitive( GTK_WIDGET(label), enable );
487 node = node->GetNext();
488 }
489
490 if (enable)
491 GTKFixSensitivity();
492
493 return true;
494 }
495
Enable(unsigned int item,bool enable)496 bool wxRadioBox::Enable(unsigned int item, bool enable)
497 {
498 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
499
500 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
501
502 wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
503
504 GtkButton *button = GTK_BUTTON( node->GetData()->button );
505 GtkLabel *label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(button)));
506
507 gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
508 gtk_widget_set_sensitive( GTK_WIDGET(label), enable );
509
510 return true;
511 }
512
IsItemEnabled(unsigned int item) const513 bool wxRadioBox::IsItemEnabled(unsigned int item) const
514 {
515 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
516
517 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
518
519 wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
520
521 GtkButton *button = GTK_BUTTON( node->GetData()->button );
522
523 // don't use GTK_WIDGET_IS_SENSITIVE() here, we want to return true even if
524 // the parent radiobox is disabled
525 return gtk_widget_get_sensitive(GTK_WIDGET(button)) != 0;
526 }
527
Show(unsigned int item,bool show)528 bool wxRadioBox::Show(unsigned int item, bool show)
529 {
530 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
531
532 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
533
534 wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
535
536 GtkWidget *button = GTK_WIDGET( node->GetData()->button );
537
538 if (show)
539 gtk_widget_show( button );
540 else
541 gtk_widget_hide( button );
542
543 return true;
544 }
545
IsItemShown(unsigned int item) const546 bool wxRadioBox::IsItemShown(unsigned int item) const
547 {
548 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid radiobox") );
549
550 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.Item( item );
551
552 wxCHECK_MSG( node, false, wxT("radiobox wrong index") );
553
554 GtkButton *button = GTK_BUTTON( node->GetData()->button );
555
556 return gtk_widget_get_visible(GTK_WIDGET(button)) != 0;
557 }
558
GetCount() const559 unsigned int wxRadioBox::GetCount() const
560 {
561 return m_buttonsInfo.GetCount();
562 }
563
GtkDisableEvents()564 void wxRadioBox::GtkDisableEvents()
565 {
566 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
567 while (node)
568 {
569 g_signal_handlers_block_by_func(node->GetData()->button,
570 (gpointer)gtk_radiobutton_clicked_callback, this);
571
572 node = node->GetNext();
573 }
574 }
575
GtkEnableEvents()576 void wxRadioBox::GtkEnableEvents()
577 {
578 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
579 while (node)
580 {
581 g_signal_handlers_unblock_by_func(node->GetData()->button,
582 (gpointer)gtk_radiobutton_clicked_callback, this);
583
584 node = node->GetNext();
585 }
586 }
587
DoApplyWidgetStyle(GtkRcStyle * style)588 void wxRadioBox::DoApplyWidgetStyle(GtkRcStyle *style)
589 {
590 GTKFrameApplyWidgetStyle(GTK_FRAME(m_widget), style);
591
592 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
593 while (node)
594 {
595 GtkWidget *widget = GTK_WIDGET( node->GetData()->button );
596
597 GTKApplyStyle(widget, style);
598 GTKApplyStyle(gtk_bin_get_child(GTK_BIN(widget)), style);
599
600 node = node->GetNext();
601 }
602
603 #ifndef __WXGTK3__
604 g_signal_handlers_disconnect_by_func(m_widget, (void*)expose_event, this);
605 if (m_backgroundColour.IsOk())
606 g_signal_connect(m_widget, "expose-event", G_CALLBACK(expose_event), this);
607 #endif
608 }
609
GTKWidgetNeedsMnemonic() const610 bool wxRadioBox::GTKWidgetNeedsMnemonic() const
611 {
612 return true;
613 }
614
GTKWidgetDoSetMnemonic(GtkWidget * w)615 void wxRadioBox::GTKWidgetDoSetMnemonic(GtkWidget* w)
616 {
617 GTKFrameSetMnemonicWidget(GTK_FRAME(m_widget), w);
618 }
619
620 #if wxUSE_TOOLTIPS
GTKApplyToolTip(const char * tip)621 void wxRadioBox::GTKApplyToolTip(const char* tip)
622 {
623 // set this tooltip for all radiobuttons which don't have their own tips
624 unsigned n = 0;
625 for ( wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
626 node;
627 node = node->GetNext(), n++ )
628 {
629 if ( !GetItemToolTip(n) )
630 {
631 wxToolTip::GTKApply(GTK_WIDGET(node->GetData()->button), tip);
632 }
633 }
634 }
635
DoSetItemToolTip(unsigned int n,wxToolTip * tooltip)636 void wxRadioBox::DoSetItemToolTip(unsigned int n, wxToolTip *tooltip)
637 {
638 wxCharBuffer buf;
639 if ( !tooltip )
640 tooltip = GetToolTip();
641 if ( tooltip )
642 buf = wxGTK_CONV(tooltip->GetTip());
643
644 wxToolTip::GTKApply(GTK_WIDGET(m_buttonsInfo[n]->button), buf);
645 }
646
647 #endif // wxUSE_TOOLTIPS
648
GTKGetWindow(wxArrayGdkWindows & windows) const649 GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const
650 {
651 windows.push_back(gtk_widget_get_window(m_widget));
652
653 wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
654 while (node)
655 {
656 GtkWidget *button = GTK_WIDGET( node->GetData()->button );
657
658 // don't put NULL pointers in the 'windows' array!
659 if (gtk_widget_get_window(button))
660 windows.push_back(gtk_widget_get_window(button));
661
662 node = node->GetNext();
663 }
664
665 return NULL;
666 }
667
668 // static
669 wxVisualAttributes
GetClassDefaultAttributes(wxWindowVariant WXUNUSED (variant))670 wxRadioBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
671 {
672 return GetDefaultAttributesFromGTKWidget(gtk_radio_button_new_with_label(NULL, ""));
673 }
674
GetItemFromPoint(const wxPoint & point) const675 int wxRadioBox::GetItemFromPoint(const wxPoint& point) const
676 {
677 const wxPoint pt = ScreenToClient(point);
678 unsigned n = 0;
679 for ( wxRadioBoxButtonsInfoList::compatibility_iterator
680 node = m_buttonsInfo.GetFirst(); node; node = node->GetNext(), n++ )
681 {
682 if ( m_buttonsInfo[n]->rect.Contains(pt) )
683 return n;
684 }
685
686 return wxNOT_FOUND;
687 }
688
689 #endif // wxUSE_RADIOBOX
690