]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/radiobox.cpp
Corrected bug in DoSetSize() (wxALLOW_MINUS_ONE)
[wxWidgets.git] / src / gtk / radiobox.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: radiobox.cpp
3// Purpose:
4// Author: Robert Roebling
f96aa4d9
RR
5// Id: $Id$
6// Copyright: (c) 1998 Robert Roebling
29006414 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
c801d85f
KB
10#ifdef __GNUG__
11#pragma implementation "radiobox.h"
12#endif
13
14#include "wx/radiobox.h"
15#include "wx/dialog.h"
16#include "wx/frame.h"
83624f79
RR
17
18#include "gdk/gdk.h"
19#include "gtk/gtk.h"
c801d85f
KB
20#include "wx/gtk/win_gtk.h"
21
acfd422a
RR
22//-----------------------------------------------------------------------------
23// idle system
24//-----------------------------------------------------------------------------
25
26extern void wxapp_install_idle_handler();
27extern bool g_isIdle;
28
66bd6b93
RR
29//-----------------------------------------------------------------------------
30// data
31//-----------------------------------------------------------------------------
32
33extern bool g_blockEventsOnDrag;
34
c801d85f 35//-----------------------------------------------------------------------------
b4071e91 36// "clicked"
c801d85f
KB
37//-----------------------------------------------------------------------------
38
66bd6b93 39static void gtk_radiobutton_clicked_callback( GtkWidget *WXUNUSED(widget), wxRadioBox *rb )
c801d85f 40{
acfd422a
RR
41 if (g_isIdle) wxapp_install_idle_handler();
42
a2053b27 43 if (!rb->m_hasVMT) return;
907789a0 44 if (g_blockEventsOnDrag) return;
29006414 45
907789a0
RR
46 if (rb->m_alreadySent)
47 {
48 rb->m_alreadySent = FALSE;
49 return;
50 }
47908e25 51
907789a0 52 rb->m_alreadySent = TRUE;
29006414 53
907789a0
RR
54 wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, rb->GetId() );
55 event.SetInt( rb->GetSelection() );
29006414 56 event.SetString( rb->GetStringSelection() );
907789a0
RR
57 event.SetEventObject( rb );
58 rb->GetEventHandler()->ProcessEvent(event);
6de97a3b 59}
c801d85f 60
b4071e91
RR
61//-----------------------------------------------------------------------------
62// wxRadioBox
c801d85f
KB
63//-----------------------------------------------------------------------------
64
65IMPLEMENT_DYNAMIC_CLASS(wxRadioBox,wxControl)
66
3f659fd6 67BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
907789a0 68 EVT_SIZE(wxRadioBox::OnSize)
3f659fd6
RR
69END_EVENT_TABLE()
70
f03fc89f 71wxRadioBox::wxRadioBox()
c801d85f 72{
6de97a3b 73}
c801d85f 74
debe6624 75bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
907789a0 76 const wxPoint &pos, const wxSize &size,
29006414
VZ
77 int n, const wxString choices[], int majorDim,
78 long style, const wxValidator& validator,
79 const wxString &name )
c801d85f 80{
907789a0
RR
81 m_alreadySent = FALSE;
82 m_needParent = TRUE;
b292e2f5 83 m_acceptsFocus = TRUE;
29006414 84
907789a0 85 PreCreation( parent, id, pos, size, style, name );
c801d85f 86
907789a0 87 SetValidator( validator );
6de97a3b 88
b019151f 89 m_widget = gtk_frame_new( title.mbc_str() );
29006414 90
d3b4d113 91 m_majorDim = majorDim;
29006414 92
907789a0 93 GtkRadioButton *m_radio = (GtkRadioButton*) NULL;
29006414 94
d3b4d113
RR
95 GSList *radio_button_group = (GSList *) NULL;
96 for (int i = 0; i < n; i++)
c801d85f 97 {
d3b4d113 98 if (i) radio_button_group = gtk_radio_button_group( GTK_RADIO_BUTTON(m_radio) );
29006414 99
b019151f 100 m_radio = GTK_RADIO_BUTTON( gtk_radio_button_new_with_label( radio_button_group, choices[i].mbc_str() ) );
29006414 101
d3b4d113 102 m_boxes.Append( (wxObject*) m_radio );
29006414 103
d3b4d113 104 ConnectWidget( GTK_WIDGET(m_radio) );
29006414 105
d3b4d113 106 if (!i) gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(m_radio), TRUE );
29006414
VZ
107
108 gtk_signal_connect( GTK_OBJECT(m_radio), "clicked",
d3b4d113 109 GTK_SIGNAL_FUNC(gtk_radiobutton_clicked_callback), (gpointer*)this );
29006414 110
a2053b27 111 gtk_myfixed_put( GTK_MYFIXED(m_parent->m_wxwindow),
f03fc89f
VZ
112 GTK_WIDGET(m_radio),
113 m_x+10, m_y+10+(i*24), 10, 10 );
6de97a3b 114 }
29006414 115
d3b4d113 116 wxSize ls = LayoutItems();
29006414 117
907789a0 118 wxSize newSize = size;
d3b4d113
RR
119 if (newSize.x == -1) newSize.x = ls.x;
120 if (newSize.y == -1) newSize.y = ls.y;
907789a0 121 SetSize( newSize.x, newSize.y );
29006414 122
f03fc89f 123 m_parent->DoAddChild( this );
29006414 124
907789a0 125 PostCreation();
29006414 126
907789a0 127 SetLabel( title );
29006414 128
907789a0
RR
129 SetBackgroundColour( parent->GetBackgroundColour() );
130 SetForegroundColour( parent->GetForegroundColour() );
a7ac4461 131 SetFont( parent->GetFont() );
f96aa4d9 132
907789a0 133 Show( TRUE );
29006414 134
907789a0 135 return TRUE;
6de97a3b 136}
c801d85f 137
f03fc89f 138wxRadioBox::~wxRadioBox()
d6d1892b 139{
907789a0
RR
140 wxNode *node = m_boxes.First();
141 while (node)
142 {
143 GtkWidget *button = GTK_WIDGET( node->Data() );
144 gtk_widget_destroy( button );
145 node = node->Next();
146 }
d6d1892b
RR
147}
148
b4071e91 149void wxRadioBox::OnSize( wxSizeEvent &event )
3f659fd6 150{
d3b4d113 151 LayoutItems();
f03fc89f
VZ
152
153 event.Skip();
d3b4d113
RR
154}
155
156wxSize wxRadioBox::LayoutItems()
157{
bbe0af5b
RR
158 int x = 7;
159 int y = 15;
29006414 160
d3b4d113 161 int num_per_major = (m_boxes.GetCount() - 1) / m_majorDim +1;
29006414 162
d3b4d113 163 wxSize res( 0, 0 );
29006414 164
d3b4d113
RR
165 if (m_windowStyle & wxRA_HORIZONTAL)
166 {
29006414 167
d3b4d113 168 for (int j = 0; j < m_majorDim; j++)
29006414 169 {
bbe0af5b 170 y = 15;
29006414 171
d3b4d113
RR
172 int max_len = 0;
173 wxNode *node = m_boxes.Nth( j*num_per_major );
29006414
VZ
174 for (int i1 = 0; i1< num_per_major; i1++)
175 {
d3b4d113
RR
176 GtkWidget *button = GTK_WIDGET( node->Data() );
177 GtkLabel *label = GTK_LABEL( GTK_BUTTON(button)->child );
178 GdkFont *font = m_widget->style->font;
bbe0af5b 179 int len = 22+gdk_string_measure( font, label->label );
d3b4d113 180 if (len > max_len) max_len = len;
29006414 181
a2053b27 182 gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), button, m_x+x, m_y+y );
c46554be 183 y += 20;
29006414
VZ
184
185 node = node->Next();
186 if (!node) break;
187 }
188
189 // we don't know the max_len before
190
d3b4d113 191 node = m_boxes.Nth( j*num_per_major );
29006414
VZ
192 for (int i2 = 0; i2< num_per_major; i2++)
193 {
d3b4d113 194 GtkWidget *button = GTK_WIDGET( node->Data() );
29006414 195
a2053b27 196 gtk_myfixed_resize( GTK_MYFIXED(m_parent->m_wxwindow), button, max_len, 20 );
29006414
VZ
197
198 node = node->Next();
199 if (!node) break;
200 }
201
202 if (y > res.y) res.y = y;
203
204 x += max_len + 2;
d3b4d113 205 }
29006414
VZ
206
207 res.x = x+4;
208 res.y += 9;
e5403d7c 209 }
d3b4d113 210 else
e5403d7c 211 {
d3b4d113
RR
212 int max = 0;
213
214 wxNode *node = m_boxes.First();
215 while (node)
216 {
217 GtkButton *button = GTK_BUTTON( node->Data() );
218 GtkLabel *label = GTK_LABEL( button->child );
29006414 219
d3b4d113 220 GdkFont *font = m_widget->style->font;
bbe0af5b 221 int len = 22+gdk_string_measure( font, label->label );
d3b4d113 222 if (len > max) max = len;
29006414 223
d3b4d113
RR
224 node = node->Next();
225 }
29006414 226
d3b4d113
RR
227 node = m_boxes.First();
228 while (node)
229 {
230 GtkWidget *button = GTK_WIDGET( node->Data() );
29006414 231
a2053b27 232 gtk_myfixed_set_size( GTK_MYFIXED(m_parent->m_wxwindow), button, m_x+x, m_y+y, max, 20 );
d3b4d113 233 x += max;
29006414 234
d3b4d113
RR
235 node = node->Next();
236 }
29006414
VZ
237 res.x = x+4;
238 res.y = 42;
e5403d7c 239 }
29006414 240
d3b4d113 241 return res;
3f659fd6
RR
242}
243
debe6624 244bool wxRadioBox::Show( bool show )
c801d85f 245{
b019151f 246 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid radiobox") );
29006414 247
907789a0 248 wxWindow::Show( show );
c801d85f 249
ba2a0103 250 if ((m_windowStyle & wxNO_BORDER) != 0)
b0351fc9
RR
251 gtk_widget_hide( m_widget );
252
907789a0
RR
253 wxNode *node = m_boxes.First();
254 while (node)
255 {
256 GtkWidget *button = GTK_WIDGET( node->Data() );
29006414 257
907789a0 258 if (show) gtk_widget_show( button ); else gtk_widget_hide( button );
29006414 259
907789a0
RR
260 node = node->Next();
261 }
c801d85f 262
907789a0 263 return TRUE;
6de97a3b 264}
c801d85f 265
47908e25 266int wxRadioBox::FindString( const wxString &s ) const
c801d85f 267{
b019151f 268 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid radiobox") );
29006414 269
907789a0 270 int count = 0;
29006414 271
907789a0
RR
272 wxNode *node = m_boxes.First();
273 while (node)
274 {
275 GtkButton *button = GTK_BUTTON( node->Data() );
29006414 276
907789a0
RR
277 GtkLabel *label = GTK_LABEL( button->child );
278 if (s == label->label) return count;
279 count++;
29006414 280
907789a0
RR
281 node = node->Next();
282 }
29006414 283
907789a0 284 return -1;
6de97a3b 285}
c801d85f 286
b292e2f5
RR
287void wxRadioBox::SetFocus()
288{
b019151f 289 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 290
b292e2f5 291 if (m_boxes.GetCount() == 0) return;
29006414 292
b292e2f5
RR
293 wxNode *node = m_boxes.First();
294 while (node)
295 {
296 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() );
297 if (button->active)
29006414 298 {
b292e2f5 299 gtk_widget_grab_focus( GTK_WIDGET(button) );
29006414
VZ
300
301 return;
302 }
b292e2f5
RR
303 node = node->Next();
304 }
29006414 305
b292e2f5
RR
306}
307
47908e25 308void wxRadioBox::SetSelection( int n )
c801d85f 309{
b019151f 310 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 311
907789a0 312 wxNode *node = m_boxes.Nth( n );
29006414 313
b019151f 314 wxCHECK_RET( node, _T("radiobox wrong index") );
29006414 315
907789a0 316 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() );
29006414 317
907789a0 318 gtk_toggle_button_set_state( button, 1 );
6de97a3b 319}
c801d85f
KB
320
321int wxRadioBox::GetSelection(void) const
322{
b019151f 323 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid radiobox") );
29006414 324
907789a0 325 int count = 0;
29006414 326
907789a0
RR
327 wxNode *node = m_boxes.First();
328 while (node)
329 {
330 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() );
331 if (button->active) return count;
332 count++;
333 node = node->Next();
334 }
29006414 335
b019151f 336 wxFAIL_MSG( _T("wxRadioBox none selected") );
29006414 337
907789a0 338 return -1;
6de97a3b 339}
c801d85f 340
47908e25 341wxString wxRadioBox::GetString( int n ) const
c801d85f 342{
b019151f 343 wxCHECK_MSG( m_widget != NULL, _T(""), _T("invalid radiobox") );
29006414 344
907789a0 345 wxNode *node = m_boxes.Nth( n );
29006414 346
b019151f 347 wxCHECK_MSG( node, _T(""), _T("radiobox wrong index") );
29006414 348
907789a0
RR
349 GtkButton *button = GTK_BUTTON( node->Data() );
350 GtkLabel *label = GTK_LABEL( button->child );
29006414 351
907789a0 352 return wxString( label->label );
6de97a3b 353}
c801d85f 354
d3904ceb 355wxString wxRadioBox::GetLabel( int item ) const
c801d85f 356{
b019151f 357 wxCHECK_MSG( m_widget != NULL, _T(""), _T("invalid radiobox") );
29006414 358
907789a0 359 return GetString( item );
6de97a3b 360}
c801d85f 361
d3904ceb 362void wxRadioBox::SetLabel( const wxString& label )
c801d85f 363{
b019151f 364 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 365
907789a0 366 wxControl::SetLabel( label );
29006414 367
b019151f 368 gtk_frame_set_label( GTK_FRAME(m_widget), wxControl::GetLabel().mbc_str() );
6de97a3b 369}
c801d85f 370
d3904ceb 371void wxRadioBox::SetLabel( int item, const wxString& label )
c801d85f 372{
b019151f 373 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 374
907789a0 375 wxNode *node = m_boxes.Nth( item );
29006414 376
b019151f 377 wxCHECK_RET( node, _T("radiobox wrong index") );
29006414 378
907789a0
RR
379 GtkButton *button = GTK_BUTTON( node->Data() );
380 GtkLabel *g_label = GTK_LABEL( button->child );
29006414 381
b019151f 382 gtk_label_set( g_label, label.mbc_str() );
6de97a3b 383}
c801d85f 384
debe6624 385void wxRadioBox::SetLabel( int WXUNUSED(item), wxBitmap *WXUNUSED(bitmap) )
c801d85f 386{
b019151f 387 wxFAIL_MSG(_T("wxRadioBox::SetLabel not implemented."));
6de97a3b 388}
c801d85f 389
f03fc89f 390bool wxRadioBox::Enable( bool enable )
c801d85f 391{
f03fc89f
VZ
392 if ( !wxControl::Enable( enable ) )
393 return FALSE;
29006414 394
907789a0
RR
395 wxNode *node = m_boxes.First();
396 while (node)
397 {
398 GtkButton *button = GTK_BUTTON( node->Data() );
399 GtkWidget *label = button->child;
400 gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
401 gtk_widget_set_sensitive( label, enable );
402 node = node->Next();
403 }
f03fc89f
VZ
404
405 return TRUE;
6de97a3b 406}
c801d85f 407
d3904ceb 408void wxRadioBox::Enable( int item, bool enable )
c801d85f 409{
b019151f 410 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 411
907789a0 412 wxNode *node = m_boxes.Nth( item );
29006414 413
b019151f 414 wxCHECK_RET( node, _T("radiobox wrong index") );
29006414 415
907789a0
RR
416 GtkButton *button = GTK_BUTTON( node->Data() );
417 GtkWidget *label = button->child;
418 gtk_widget_set_sensitive( GTK_WIDGET(button), enable );
419 gtk_widget_set_sensitive( label, enable );
6de97a3b 420}
c801d85f 421
d3904ceb 422void wxRadioBox::Show( int item, bool show )
c801d85f 423{
b019151f 424 wxCHECK_RET( m_widget != NULL, _T("invalid radiobox") );
29006414 425
907789a0 426 wxNode *node = m_boxes.Nth( item );
29006414 427
b019151f 428 wxCHECK_RET( node, _T("radiobox wrong index") );
29006414 429
907789a0 430 GtkWidget *button = GTK_WIDGET( node->Data() );
c801d85f 431
907789a0
RR
432 if (show)
433 gtk_widget_show( button );
434 else
435 gtk_widget_hide( button );
6de97a3b 436}
c801d85f
KB
437
438wxString wxRadioBox::GetStringSelection(void) const
439{
b019151f 440 wxCHECK_MSG( m_widget != NULL, _T(""), _T("invalid radiobox") );
29006414 441
907789a0
RR
442 wxNode *node = m_boxes.First();
443 while (node)
c801d85f 444 {
907789a0
RR
445 GtkToggleButton *button = GTK_TOGGLE_BUTTON( node->Data() );
446 if (button->active)
447 {
448 GtkLabel *label = GTK_LABEL( GTK_BUTTON(button)->child );
449 return label->label;
450 }
451 node = node->Next();
6de97a3b 452 }
29006414 453
b019151f
OK
454 wxFAIL_MSG( _T("wxRadioBox none selected") );
455 return _T("");
6de97a3b 456}
c801d85f 457
907789a0 458bool wxRadioBox::SetStringSelection( const wxString &s )
c801d85f 459{
b019151f 460 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid radiobox") );
29006414 461
907789a0
RR
462 int res = FindString( s );
463 if (res == -1) return FALSE;
464 SetSelection( res );
29006414 465
907789a0 466 return TRUE;
6de97a3b 467}
c801d85f
KB
468
469int wxRadioBox::Number(void) const
470{
907789a0 471 return m_boxes.Number();
6de97a3b 472}
c801d85f
KB
473
474int wxRadioBox::GetNumberOfRowsOrCols(void) const
475{
907789a0 476 return 1;
6de97a3b 477}
c801d85f 478
debe6624 479void wxRadioBox::SetNumberOfRowsOrCols( int WXUNUSED(n) )
c801d85f 480{
b019151f 481 wxFAIL_MSG(_T("wxRadioBox::SetNumberOfRowsOrCols not implemented."));
6de97a3b 482}
c801d85f 483
58614078 484void wxRadioBox::ApplyWidgetStyle()
868a2826 485{
907789a0 486 SetWidgetStyle();
29006414 487
907789a0 488 gtk_widget_set_style( m_widget, m_widgetStyle );
29006414 489
907789a0
RR
490 wxNode *node = m_boxes.First();
491 while (node)
492 {
493 GtkWidget *widget = GTK_WIDGET( node->Data() );
494 gtk_widget_set_style( widget, m_widgetStyle );
29006414 495
907789a0
RR
496 GtkButton *button = GTK_BUTTON( node->Data() );
497 gtk_widget_set_style( button->child, m_widgetStyle );
29006414 498
907789a0
RR
499 node = node->Next();
500 }
868a2826 501}
b4071e91
RR
502
503bool wxRadioBox::IsOwnGtkWindow( GdkWindow *window )
504{
907789a0 505 if (window == m_widget->window) return TRUE;
29006414 506
907789a0
RR
507 wxNode *node = m_boxes.First();
508 while (node)
509 {
510 GtkWidget *button = GTK_WIDGET( node->Data() );
29006414 511
907789a0 512 if (window == button->window) return TRUE;
29006414 513
907789a0
RR
514 node = node->Next();
515 }
29006414 516
907789a0 517 return FALSE;
b4071e91 518}