]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/combobox.cpp
SetEventData for a few widgets
[wxWidgets.git] / src / gtk / combobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: combobox.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 #ifdef __GNUG__
11 #pragma implementation "combobox.h"
12 #endif
13
14 #include "wx/combobox.h"
15 #include <wx/intl.h>
16
17 //-----------------------------------------------------------------------------
18 // data
19 //-----------------------------------------------------------------------------
20
21 extern bool g_blockEventsOnDrag;
22
23 //-----------------------------------------------------------------------------
24 // "select"
25 //-----------------------------------------------------------------------------
26
27 static void gtk_combo_clicked_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
28 {
29 if (!combo->HasVMT()) return;
30 if (g_blockEventsOnDrag) return;
31
32 if (combo->m_alreadySent)
33 {
34 combo->m_alreadySent = FALSE;
35 return;
36 }
37
38 combo->m_alreadySent = TRUE;
39
40 wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, combo->GetId());
41 event.SetInt( combo->GetSelection() );
42 wxString tmp( combo->GetStringSelection() );
43 event.SetString( WXSTRINGCAST(tmp) );
44 event.SetEventObject(combo);
45 combo->GetEventHandler()->ProcessEvent(event);
46 }
47
48 //-----------------------------------------------------------------------------
49 // wxComboBox
50 //-----------------------------------------------------------------------------
51
52 IMPLEMENT_DYNAMIC_CLASS(wxComboBox,wxControl)
53
54 BEGIN_EVENT_TABLE(wxComboBox, wxControl)
55 EVT_SIZE(wxComboBox::OnSize)
56 END_EVENT_TABLE()
57
58 bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
59 const wxPoint& pos, const wxSize& size,
60 int n, const wxString choices[],
61 long style, const wxValidator& validator,
62 const wxString& name )
63 {
64 m_alreadySent = FALSE;
65 m_needParent = TRUE;
66
67 PreCreation( parent, id, pos, size, style, name );
68
69 SetValidator( validator );
70
71 m_widget = gtk_combo_new();
72
73 wxSize newSize = size;
74 if (newSize.x == -1) newSize.x = 100;
75 if (newSize.y == -1) newSize.y = 26;
76 SetSize( newSize.x, newSize.y );
77
78 GtkWidget *list = GTK_COMBO(m_widget)->list;
79
80 for (int i = 0; i < n; i++)
81 {
82 GtkWidget *list_item = gtk_list_item_new_with_label( choices[i] );
83
84 m_clientDataList.Append( (wxObject*)NULL );
85
86 gtk_container_add( GTK_CONTAINER(list), list_item );
87
88 gtk_widget_realize( list_item );
89 gtk_widget_realize( GTK_BIN(list_item)->child );
90
91 gtk_widget_show( list_item );
92
93 gtk_signal_connect( GTK_OBJECT(list_item), "select",
94 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
95 }
96
97 m_parent->AddChild( this );
98
99 (m_parent->m_insertCallback)( m_parent, this );
100
101 PostCreation();
102
103 ConnectWidget( GTK_COMBO(m_widget)->button );
104
105 if (!value.IsNull()) SetValue( value );
106
107 gtk_widget_realize( GTK_COMBO(m_widget)->list );
108 gtk_widget_realize( GTK_COMBO(m_widget)->entry );
109 gtk_widget_realize( GTK_COMBO(m_widget)->button );
110
111 SetBackgroundColour( parent->GetBackgroundColour() );
112 SetForegroundColour( parent->GetForegroundColour() );
113
114 Show( TRUE );
115
116 return TRUE;
117 }
118
119 wxComboBox::~wxComboBox()
120 {
121 wxNode *node = m_clientDataList.First();
122 while (node)
123 {
124 wxClientData *cd = (wxClientData*)node->Data();
125 if (cd) delete cd;
126 node = node->Next();
127 }
128 m_clientDataList.Clear();
129 }
130
131 void wxComboBox::AppendCommon( const wxString &item )
132 {
133 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
134
135 GtkWidget *list = GTK_COMBO(m_widget)->list;
136
137 GtkWidget *list_item = gtk_list_item_new_with_label( item );
138
139 gtk_signal_connect( GTK_OBJECT(list_item), "select",
140 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
141
142 gtk_container_add( GTK_CONTAINER(list), list_item );
143
144 if (m_widgetStyle) ApplyWidgetStyle();
145
146 gtk_widget_show( list_item );
147 }
148
149 void wxComboBox::Append( const wxString &item )
150 {
151 m_clientDataList.Append( (wxObject*)NULL );
152
153 AppendCommon( item );
154 }
155
156 void wxComboBox::Append( const wxString &item, void *clientData )
157 {
158 if (clientData)
159 m_clientDataList.Append( (wxObject*) new wxVoidClientData( clientData ) );
160 else
161 m_clientDataList.Append( (wxObject*)NULL );
162
163 AppendCommon( item );
164 }
165
166 void wxComboBox::Append( const wxString &item, wxClientData *clientData )
167 {
168 m_clientDataList.Append( (wxObject*) clientData );
169
170 AppendCommon( item );
171 }
172
173 void wxComboBox::SetClientData( int n, void* clientData )
174 {
175 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
176
177 wxNode *node = m_clientDataList.Nth( n );
178 if (!node) return;
179
180 wxClientData *cd = (wxClientData*) node->Data();
181 if (cd) delete cd;
182
183 if (clientData)
184 node->SetData( (wxObject*) new wxVoidClientData(clientData) );
185 else
186 node->SetData( (wxObject*) NULL );
187 }
188
189 void* wxComboBox::GetClientData( int n )
190 {
191 wxCHECK_MSG( m_widget != NULL, NULL, "invalid combobox" );
192
193 wxNode *node = m_clientDataList.Nth( n );
194 if (!node) return NULL;
195
196 wxVoidClientData *cd = (wxVoidClientData*) node->Data();
197 if (cd)
198 return cd->GetData();
199 else
200 return (void*) NULL;
201 }
202
203 void wxComboBox::SetClientObject( int n, wxClientData* clientData )
204 {
205 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
206
207 wxNode *node = m_clientDataList.Nth( n );
208 if (!node) return;
209
210 wxClientData *cd = (wxClientData*) node->Data();
211 if (cd) delete cd;
212
213 node->SetData( (wxObject*) clientData );
214 }
215
216 wxClientData* wxComboBox::GetClientObject( int n )
217 {
218 wxCHECK_MSG( m_widget != NULL, (wxClientData*)NULL, "invalid combobox" );
219
220 wxNode *node = m_clientDataList.Nth( n );
221 if (!node) return (wxClientData*) NULL;
222
223 return (wxClientData*) node->Data();
224 }
225
226 void wxComboBox::Clear()
227 {
228 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
229
230 GtkWidget *list = GTK_COMBO(m_widget)->list;
231 gtk_list_clear_items( GTK_LIST(list), 0, Number() );
232
233 wxNode *node = m_clientDataList.First();
234 while (node)
235 {
236 wxClientData *cd = (wxClientData*)node->Data();
237 if (cd) delete cd;
238 node = node->Next();
239 }
240 m_clientDataList.Clear();
241 }
242
243 void wxComboBox::Delete( int n )
244 {
245 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
246
247 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
248
249 GList *child = g_list_nth( listbox->children, n );
250
251 if (!child)
252 {
253 wxFAIL_MSG("wrong index");
254 return;
255 }
256
257 GList *list = g_list_append( NULL, child->data );
258 gtk_list_remove_items( listbox, list );
259 g_list_free( list );
260
261 wxNode *node = m_clientDataList.Nth( n );
262 if (!node)
263 {
264 wxFAIL_MSG( "wrong index" );
265 }
266 else
267 {
268 wxClientData *cd = (wxClientData*)node->Data();
269 if (cd) delete cd;
270 m_clientDataList.DeleteNode( node );
271 }
272 }
273
274 int wxComboBox::FindString( const wxString &item )
275 {
276 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
277
278 GtkWidget *list = GTK_COMBO(m_widget)->list;
279
280 GList *child = GTK_LIST(list)->children;
281 int count = 0;
282 while (child)
283 {
284 GtkBin *bin = GTK_BIN( child->data );
285 GtkLabel *label = GTK_LABEL( bin->child );
286 if (item == label->label) return count;
287 count++;
288 child = child->next;
289 }
290
291 wxFAIL_MSG( "wxComboBox: string not found" );
292
293 return -1;
294 }
295
296 int wxComboBox::GetSelection() const
297 {
298 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
299
300 GtkWidget *list = GTK_COMBO(m_widget)->list;
301
302 GList *selection = GTK_LIST(list)->selection;
303 if (selection)
304 {
305 GList *child = GTK_LIST(list)->children;
306 int count = 0;
307 while (child)
308 {
309 if (child->data == selection->data) return count;
310 count++;
311 child = child->next;
312 }
313 }
314
315 wxFAIL_MSG( "wxComboBox: no selection" );
316
317 return -1;
318 }
319
320 wxString wxComboBox::GetString( int n ) const
321 {
322 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
323
324 GtkWidget *list = GTK_COMBO(m_widget)->list;
325
326 GList *child = g_list_nth( GTK_LIST(list)->children, n );
327 if (child)
328 {
329 GtkBin *bin = GTK_BIN( child->data );
330 GtkLabel *label = GTK_LABEL( bin->child );
331 return label->label;
332 }
333
334 wxFAIL_MSG( "wxComboBox: wrong index" );
335
336 return "";
337 }
338
339 wxString wxComboBox::GetStringSelection() const
340 {
341 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
342
343 GtkWidget *list = GTK_COMBO(m_widget)->list;
344
345 GList *selection = GTK_LIST(list)->selection;
346 if (selection)
347 {
348 GtkBin *bin = GTK_BIN( selection->data );
349 wxString tmp = GTK_LABEL( bin->child )->label;
350 return tmp;
351 }
352
353 wxFAIL_MSG( "wxComboBox: no selection" );
354
355 return "";
356 }
357
358 int wxComboBox::Number() const
359 {
360 wxCHECK_MSG( m_widget != NULL, 0, "invalid combobox" );
361
362 GtkWidget *list = GTK_COMBO(m_widget)->list;
363
364 GList *child = GTK_LIST(list)->children;
365 int count = 0;
366 while (child) { count++; child = child->next; }
367 return count;
368 }
369
370 void wxComboBox::SetSelection( int n )
371 {
372 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
373
374 GtkWidget *list = GTK_COMBO(m_widget)->list;
375 gtk_list_select_item( GTK_LIST(list), n );
376 }
377
378 void wxComboBox::SetStringSelection( const wxString &string )
379 {
380 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
381
382 int res = FindString( string );
383 if (res == -1) return;
384 SetSelection( res );
385 }
386
387 wxString wxComboBox::GetValue() const
388 {
389 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
390 wxString tmp = gtk_entry_get_text( GTK_ENTRY(entry) );
391 return tmp;
392 }
393
394 void wxComboBox::SetValue( const wxString& value )
395 {
396 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
397
398 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
399 wxString tmp = "";
400 if (!value.IsNull()) tmp = value;
401 gtk_entry_set_text( GTK_ENTRY(entry), tmp );
402 }
403
404 void wxComboBox::Copy()
405 {
406 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
407
408 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
409 #if (GTK_MINOR_VERSION == 1)
410 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
411 #else
412 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
413 #endif
414 }
415
416 void wxComboBox::Cut()
417 {
418 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
419
420 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
421 #if (GTK_MINOR_VERSION == 1)
422 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
423 #else
424 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
425 #endif
426 }
427
428 void wxComboBox::Paste()
429 {
430 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
431
432 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
433 #if (GTK_MINOR_VERSION == 1)
434 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
435 #else
436 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
437 #endif
438 }
439
440 void wxComboBox::SetInsertionPoint( long pos )
441 {
442 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
443
444 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
445 int tmp = (int) pos;
446 gtk_entry_set_position( GTK_ENTRY(entry), tmp );
447 }
448
449 void wxComboBox::SetInsertionPointEnd()
450 {
451 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
452
453 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
454 int pos = GTK_ENTRY(entry)->text_length;
455 SetInsertionPoint( pos-1 );
456 }
457
458 long wxComboBox::GetInsertionPoint() const
459 {
460 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
461 return (long) GTK_EDITABLE(entry)->current_pos;
462 }
463
464 long wxComboBox::GetLastPosition() const
465 {
466 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
467 int pos = GTK_ENTRY(entry)->text_length;
468 return (long) pos-1;
469 }
470
471 void wxComboBox::Replace( long from, long to, const wxString& value )
472 {
473 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
474
475 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
476 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
477 if (value.IsNull()) return;
478 gint pos = (gint)to;
479 gtk_editable_insert_text( GTK_EDITABLE(entry), value, value.Length(), &pos );
480 }
481
482 void wxComboBox::Remove(long from, long to)
483 {
484 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
485
486 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
487 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
488 }
489
490 void wxComboBox::SetSelection( long WXUNUSED(from), long WXUNUSED(to) )
491 {
492 wxFAIL_MSG( "wxComboBox::SetSelection not implemented" );
493 }
494
495 void wxComboBox::SetEditable( bool WXUNUSED(editable) )
496 {
497 wxFAIL_MSG( "wxComboBox::SetEditable not implemented" );
498 }
499
500 void wxComboBox::OnSize( wxSizeEvent &event )
501 {
502 wxControl::OnSize( event );
503
504 int w = 21;
505 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
506
507 gtk_widget_set_uposition( GTK_COMBO(m_widget)->button, m_x+m_width-w, m_y );
508 gtk_widget_set_usize( GTK_COMBO(m_widget)->button, w, m_height );
509 }
510
511 void wxComboBox::ApplyWidgetStyle()
512 {
513 SetWidgetStyle();
514
515 gtk_widget_set_style( GTK_COMBO(m_widget)->button, m_widgetStyle );
516 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, m_widgetStyle );
517 gtk_widget_set_style( GTK_COMBO(m_widget)->list, m_widgetStyle );
518
519 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
520 GList *child = list->children;
521 while (child)
522 {
523 gtk_widget_set_style( GTK_WIDGET(child->data), m_widgetStyle );
524
525 GtkBin *bin = GTK_BIN(child->data);
526 gtk_widget_set_style( bin->child, m_widgetStyle );
527
528 child = child->next;
529 }
530 }
531
532 GtkWidget* wxComboBox::GetConnectWidget()
533 {
534 return GTK_COMBO(m_widget)->entry;
535 }
536
537 bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
538 {
539 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
540 (window == GTK_COMBO(m_widget)->button->window ) );
541 }