]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/combobox.cpp
Added background colour again
[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, const wxString& name )
62 {
63 m_alreadySent = FALSE;
64 m_needParent = TRUE;
65
66 PreCreation( parent, id, pos, size, style, name );
67
68 SetValidator( validator );
69
70 m_widget = gtk_combo_new();
71
72 wxSize newSize = size;
73 if (newSize.x == -1) newSize.x = 100;
74 if (newSize.y == -1) newSize.y = 26;
75 SetSize( newSize.x, newSize.y );
76
77 GtkWidget *list = GTK_COMBO(m_widget)->list;
78
79 for (int i = 0; i < n; i++)
80 {
81 GtkWidget *list_item = gtk_list_item_new_with_label( choices[i] );
82
83 m_clientData.Append( (wxObject*)NULL );
84
85 gtk_container_add( GTK_CONTAINER(list), list_item );
86
87 gtk_widget_realize( list_item );
88 gtk_widget_realize( GTK_BIN(list_item)->child );
89
90 gtk_widget_show( list_item );
91
92 gtk_signal_connect( GTK_OBJECT(list_item), "select",
93 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
94 }
95
96 PostCreation();
97
98 ConnectWidget( GTK_COMBO(m_widget)->button );
99
100 if (!value.IsNull()) SetValue( value );
101
102 gtk_widget_realize( GTK_COMBO(m_widget)->list );
103 gtk_widget_realize( GTK_COMBO(m_widget)->entry );
104 gtk_widget_realize( GTK_COMBO(m_widget)->button );
105
106 SetBackgroundColour( parent->GetBackgroundColour() );
107
108 Show( TRUE );
109
110 return TRUE;
111 }
112
113 void wxComboBox::Clear(void)
114 {
115 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
116
117 GtkWidget *list = GTK_COMBO(m_widget)->list;
118 gtk_list_clear_items( GTK_LIST(list), 0, Number() );
119
120 m_clientData.Clear();
121 }
122
123 void wxComboBox::Append( const wxString &item )
124 {
125 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
126
127 Append( item, (char*)NULL );
128 }
129
130 void wxComboBox::Append( const wxString &item, char *clientData )
131 {
132 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
133
134 GtkWidget *list = GTK_COMBO(m_widget)->list;
135
136 GtkWidget *list_item = gtk_list_item_new_with_label( item );
137
138 if (m_widgetStyle)
139 {
140 gtk_widget_set_style( list_item, m_widgetStyle );
141 gtk_widget_set_style( GTK_BIN( list_item )->child, m_widgetStyle );
142 }
143
144 gtk_signal_connect( GTK_OBJECT(list_item), "select",
145 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
146
147 m_clientData.Append( (wxObject*)clientData );
148
149 gtk_container_add( GTK_CONTAINER(list), list_item );
150
151 gtk_widget_show( list_item );
152 }
153
154 void wxComboBox::Delete( int n )
155 {
156 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
157
158 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
159
160 GList *child = g_list_nth( listbox->children, n );
161
162 if (!child)
163 {
164 wxFAIL_MSG("wrong index");
165 return;
166 }
167
168 GList *list = g_list_append( NULL, child->data );
169 gtk_list_remove_items( listbox, list );
170 g_list_free( list );
171
172 wxNode *node = m_clientData.Nth( n );
173 if (!node)
174 {
175 wxFAIL_MSG( "wrong index" );
176 }
177 else
178 m_clientData.DeleteNode( node );
179 }
180
181 int wxComboBox::FindString( const wxString &item )
182 {
183 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
184
185 GtkWidget *list = GTK_COMBO(m_widget)->list;
186
187 GList *child = GTK_LIST(list)->children;
188 int count = 0;
189 while (child)
190 {
191 GtkBin *bin = GTK_BIN( child->data );
192 GtkLabel *label = GTK_LABEL( bin->child );
193 if (item == label->label) return count;
194 count++;
195 child = child->next;
196 }
197
198 wxFAIL_MSG( "wxComboBox: string not found" );
199
200 return -1;
201 }
202
203 char* wxComboBox::GetClientData( int n )
204 {
205 wxCHECK_MSG( m_widget != NULL, (char*)NULL, "invalid combobox" );
206
207 wxNode *node = m_clientData.Nth( n );
208 if (node) return (char*)node->Data();
209
210 wxFAIL_MSG( "wxComboBox: wrong index" );
211
212 return (char *) NULL;
213 }
214
215 void wxComboBox::SetClientData( int n, char * clientData )
216 {
217 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
218
219 wxNode *node = m_clientData.Nth( n );
220 if (node) node->SetData( (wxObject*) clientData );
221
222 wxFAIL_MSG( "wxComboBox: wrong index" );
223 }
224
225 int wxComboBox::GetSelection(void) const
226 {
227 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
228
229 GtkWidget *list = GTK_COMBO(m_widget)->list;
230
231 GList *selection = GTK_LIST(list)->selection;
232 if (selection)
233 {
234 GList *child = GTK_LIST(list)->children;
235 int count = 0;
236 while (child)
237 {
238 if (child->data == selection->data) return count;
239 count++;
240 child = child->next;
241 }
242 }
243
244 wxFAIL_MSG( "wxComboBox: no selection" );
245
246 return -1;
247 }
248
249 wxString wxComboBox::GetString( int n ) const
250 {
251 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
252
253 GtkWidget *list = GTK_COMBO(m_widget)->list;
254
255 GList *child = g_list_nth( GTK_LIST(list)->children, n );
256 if (child)
257 {
258 GtkBin *bin = GTK_BIN( child->data );
259 GtkLabel *label = GTK_LABEL( bin->child );
260 return label->label;
261 }
262
263 wxFAIL_MSG( "wxComboBox: wrong index" );
264
265 return "";
266 }
267
268 wxString wxComboBox::GetStringSelection(void) const
269 {
270 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
271
272 GtkWidget *list = GTK_COMBO(m_widget)->list;
273
274 GList *selection = GTK_LIST(list)->selection;
275 if (selection)
276 {
277 GtkBin *bin = GTK_BIN( selection->data );
278 wxString tmp = GTK_LABEL( bin->child )->label;
279 return tmp;
280 }
281
282 wxFAIL_MSG( "wxComboBox: no selection" );
283
284 return "";
285 }
286
287 int wxComboBox::Number(void) const
288 {
289 wxCHECK_MSG( m_widget != NULL, 0, "invalid combobox" );
290
291 GtkWidget *list = GTK_COMBO(m_widget)->list;
292
293 GList *child = GTK_LIST(list)->children;
294 int count = 0;
295 while (child) { count++; child = child->next; }
296 return count;
297 }
298
299 void wxComboBox::SetSelection( int n )
300 {
301 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
302
303 GtkWidget *list = GTK_COMBO(m_widget)->list;
304 gtk_list_select_item( GTK_LIST(list), n );
305 }
306
307 void wxComboBox::SetStringSelection( const wxString &string )
308 {
309 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
310
311 int res = FindString( string );
312 if (res == -1) return;
313 SetSelection( res );
314 }
315
316 wxString wxComboBox::GetValue(void) const
317 {
318 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
319 wxString tmp = gtk_entry_get_text( GTK_ENTRY(entry) );
320 return tmp;
321 }
322
323 void wxComboBox::SetValue( const wxString& value )
324 {
325 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
326
327 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
328 wxString tmp = "";
329 if (!value.IsNull()) tmp = value;
330 gtk_entry_set_text( GTK_ENTRY(entry), tmp );
331 }
332
333 void wxComboBox::Copy(void)
334 {
335 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
336
337 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
338 #if (GTK_MINOR_VERSION == 1)
339 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
340 #else
341 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
342 #endif
343 }
344
345 void wxComboBox::Cut(void)
346 {
347 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
348
349 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
350 #if (GTK_MINOR_VERSION == 1)
351 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
352 #else
353 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
354 #endif
355 }
356
357 void wxComboBox::Paste(void)
358 {
359 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
360
361 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
362 #if (GTK_MINOR_VERSION == 1)
363 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
364 #else
365 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
366 #endif
367 }
368
369 void wxComboBox::SetInsertionPoint( long pos )
370 {
371 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
372
373 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
374 int tmp = (int) pos;
375 gtk_entry_set_position( GTK_ENTRY(entry), tmp );
376 }
377
378 void wxComboBox::SetInsertionPointEnd(void)
379 {
380 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
381
382 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
383 int pos = GTK_ENTRY(entry)->text_length;
384 SetInsertionPoint( pos-1 );
385 }
386
387 long wxComboBox::GetInsertionPoint(void) const
388 {
389 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
390 return (long) GTK_EDITABLE(entry)->current_pos;
391 }
392
393 long wxComboBox::GetLastPosition(void) const
394 {
395 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
396 int pos = GTK_ENTRY(entry)->text_length;
397 return (long) pos-1;
398 }
399
400 void wxComboBox::Replace( long from, long to, const wxString& value )
401 {
402 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
403
404 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
405 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
406 if (value.IsNull()) return;
407 gint pos = (gint)to;
408 gtk_editable_insert_text( GTK_EDITABLE(entry), value, value.Length(), &pos );
409 }
410
411 void wxComboBox::Remove(long from, long to)
412 {
413 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
414
415 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
416 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
417 }
418
419 void wxComboBox::SetSelection( long WXUNUSED(from), long WXUNUSED(to) )
420 {
421 wxFAIL_MSG( "wxComboBox::SetSelection not implemented" );
422 }
423
424 void wxComboBox::SetEditable( bool WXUNUSED(editable) )
425 {
426 wxFAIL_MSG( "wxComboBox::SetEditable not implemented" );
427 }
428
429 void wxComboBox::OnSize( wxSizeEvent &event )
430 {
431 wxControl::OnSize( event );
432
433 int w = 21;
434
435 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
436
437 gtk_widget_set_uposition( GTK_COMBO(m_widget)->button, m_x+m_width-w, m_y );
438 gtk_widget_set_usize( GTK_COMBO(m_widget)->button, w, m_height );
439 }
440
441 void wxComboBox::SetFont( const wxFont &font )
442 {
443 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
444
445 wxWindow::SetFont( font );
446
447 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, m_widgetStyle );
448
449 GtkList *list = GTK_LIST( GTK_COMBO(m_widget)->list );
450
451 GList *child = list->children;
452 while (child)
453 {
454 GtkBin *bin = (GtkBin*) child->data;
455
456 gtk_widget_set_style( bin->child, m_widgetStyle );
457
458 child = child->next;
459 }
460 }
461
462 GtkWidget* wxComboBox::GetConnectWidget(void)
463 {
464 return GTK_COMBO(m_widget)->entry;
465 }
466
467 bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
468 {
469 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
470 (window == GTK_COMBO(m_widget)->button->window ) );
471 }
472
473 void wxComboBox::SetBackgroundColour( const wxColour &colour )
474 {
475 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
476
477 wxControl::SetBackgroundColour( colour );
478
479 if (!m_backgroundColour.Ok()) return;
480
481 // gtk_widget_set_style( m_widget, m_widgetStyle );
482
483 gtk_widget_set_style( GTK_COMBO(m_widget)->button, m_widgetStyle );
484 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, m_widgetStyle );
485 gtk_widget_set_style( GTK_COMBO(m_widget)->list, m_widgetStyle );
486
487 GList *child = GTK_LIST( GTK_COMBO(m_widget)->list )->children;
488 while (child)
489 {
490 gtk_widget_set_style( GTK_WIDGET(child->data), m_widgetStyle );
491
492 child = child->next;
493 }
494 }
495