]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/combobox.cpp
Did much work on colors. It doesn't work and I guess
[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_hasOwnStyle)
139 {
140 GtkBin *bin = GTK_BIN( list_item );
141 gtk_widget_set_style( bin->child,
142 gtk_style_ref(
143 gtk_widget_get_style( m_widget ) ) );
144 gtk_widget_set_style( GTK_WIDGET(bin),
145 gtk_style_ref(
146 gtk_widget_get_style( m_widget ) ) );
147 }
148
149 gtk_signal_connect( GTK_OBJECT(list_item), "select",
150 GTK_SIGNAL_FUNC(gtk_combo_clicked_callback), (gpointer)this );
151
152 m_clientData.Append( (wxObject*)clientData );
153
154 gtk_container_add( GTK_CONTAINER(list), list_item );
155
156 gtk_widget_show( list_item );
157 }
158
159 void wxComboBox::Delete( int n )
160 {
161 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
162
163 GtkList *listbox = GTK_LIST( GTK_COMBO(m_widget)->list );
164
165 GList *child = g_list_nth( listbox->children, n );
166
167 if (!child)
168 {
169 wxFAIL_MSG("wrong index");
170 return;
171 }
172
173 GList *list = g_list_append( NULL, child->data );
174 gtk_list_remove_items( listbox, list );
175 g_list_free( list );
176
177 wxNode *node = m_clientData.Nth( n );
178 if (!node)
179 {
180 wxFAIL_MSG( "wrong index" );
181 }
182 else
183 m_clientData.DeleteNode( node );
184 }
185
186 int wxComboBox::FindString( const wxString &item )
187 {
188 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
189
190 GtkWidget *list = GTK_COMBO(m_widget)->list;
191
192 GList *child = GTK_LIST(list)->children;
193 int count = 0;
194 while (child)
195 {
196 GtkBin *bin = GTK_BIN( child->data );
197 GtkLabel *label = GTK_LABEL( bin->child );
198 if (item == label->label) return count;
199 count++;
200 child = child->next;
201 }
202
203 wxFAIL_MSG( "wxComboBox: string not found" );
204
205 return -1;
206 }
207
208 char* wxComboBox::GetClientData( int n )
209 {
210 wxCHECK_MSG( m_widget != NULL, (char*)NULL, "invalid combobox" );
211
212 wxNode *node = m_clientData.Nth( n );
213 if (node) return (char*)node->Data();
214
215 wxFAIL_MSG( "wxComboBox: wrong index" );
216
217 return (char *) NULL;
218 }
219
220 void wxComboBox::SetClientData( int n, char * clientData )
221 {
222 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
223
224 wxNode *node = m_clientData.Nth( n );
225 if (node) node->SetData( (wxObject*) clientData );
226
227 wxFAIL_MSG( "wxComboBox: wrong index" );
228 }
229
230 int wxComboBox::GetSelection(void) const
231 {
232 wxCHECK_MSG( m_widget != NULL, -1, "invalid combobox" );
233
234 GtkWidget *list = GTK_COMBO(m_widget)->list;
235
236 GList *selection = GTK_LIST(list)->selection;
237 if (selection)
238 {
239 GList *child = GTK_LIST(list)->children;
240 int count = 0;
241 while (child)
242 {
243 if (child->data == selection->data) return count;
244 count++;
245 child = child->next;
246 }
247 }
248
249 wxFAIL_MSG( "wxComboBox: no selection" );
250
251 return -1;
252 }
253
254 wxString wxComboBox::GetString( int n ) const
255 {
256 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
257
258 GtkWidget *list = GTK_COMBO(m_widget)->list;
259
260 GList *child = g_list_nth( GTK_LIST(list)->children, n );
261 if (child)
262 {
263 GtkBin *bin = GTK_BIN( child->data );
264 GtkLabel *label = GTK_LABEL( bin->child );
265 return label->label;
266 }
267
268 wxFAIL_MSG( "wxComboBox: wrong index" );
269
270 return "";
271 }
272
273 wxString wxComboBox::GetStringSelection(void) const
274 {
275 wxCHECK_MSG( m_widget != NULL, "", "invalid combobox" );
276
277 GtkWidget *list = GTK_COMBO(m_widget)->list;
278
279 GList *selection = GTK_LIST(list)->selection;
280 if (selection)
281 {
282 GtkBin *bin = GTK_BIN( selection->data );
283 wxString tmp = GTK_LABEL( bin->child )->label;
284 return tmp;
285 }
286
287 wxFAIL_MSG( "wxComboBox: no selection" );
288
289 return "";
290 }
291
292 int wxComboBox::Number(void) const
293 {
294 wxCHECK_MSG( m_widget != NULL, 0, "invalid combobox" );
295
296 GtkWidget *list = GTK_COMBO(m_widget)->list;
297
298 GList *child = GTK_LIST(list)->children;
299 int count = 0;
300 while (child) { count++; child = child->next; }
301 return count;
302 }
303
304 void wxComboBox::SetSelection( int n )
305 {
306 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
307
308 GtkWidget *list = GTK_COMBO(m_widget)->list;
309 gtk_list_select_item( GTK_LIST(list), n );
310 }
311
312 void wxComboBox::SetStringSelection( const wxString &string )
313 {
314 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
315
316 int res = FindString( string );
317 if (res == -1) return;
318 SetSelection( res );
319 }
320
321 wxString wxComboBox::GetValue(void) const
322 {
323 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
324 wxString tmp = gtk_entry_get_text( GTK_ENTRY(entry) );
325 return tmp;
326 }
327
328 void wxComboBox::SetValue( const wxString& value )
329 {
330 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
331
332 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
333 wxString tmp = "";
334 if (!value.IsNull()) tmp = value;
335 gtk_entry_set_text( GTK_ENTRY(entry), tmp );
336 }
337
338 void wxComboBox::Copy(void)
339 {
340 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
341
342 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
343 #if (GTK_MINOR_VERSION == 1)
344 gtk_editable_copy_clipboard( GTK_EDITABLE(entry) );
345 #else
346 gtk_editable_copy_clipboard( GTK_EDITABLE(entry), 0 );
347 #endif
348 }
349
350 void wxComboBox::Cut(void)
351 {
352 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
353
354 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
355 #if (GTK_MINOR_VERSION == 1)
356 gtk_editable_cut_clipboard( GTK_EDITABLE(entry) );
357 #else
358 gtk_editable_cut_clipboard( GTK_EDITABLE(entry), 0 );
359 #endif
360 }
361
362 void wxComboBox::Paste(void)
363 {
364 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
365
366 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
367 #if (GTK_MINOR_VERSION == 1)
368 gtk_editable_paste_clipboard( GTK_EDITABLE(entry) );
369 #else
370 gtk_editable_paste_clipboard( GTK_EDITABLE(entry), 0 );
371 #endif
372 }
373
374 void wxComboBox::SetInsertionPoint( long pos )
375 {
376 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
377
378 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
379 int tmp = (int) pos;
380 gtk_entry_set_position( GTK_ENTRY(entry), tmp );
381 }
382
383 void wxComboBox::SetInsertionPointEnd(void)
384 {
385 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
386
387 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
388 int pos = GTK_ENTRY(entry)->text_length;
389 SetInsertionPoint( pos-1 );
390 }
391
392 long wxComboBox::GetInsertionPoint(void) const
393 {
394 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
395 return (long) GTK_EDITABLE(entry)->current_pos;
396 }
397
398 long wxComboBox::GetLastPosition(void) const
399 {
400 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
401 int pos = GTK_ENTRY(entry)->text_length;
402 return (long) pos-1;
403 }
404
405 void wxComboBox::Replace( long from, long to, const wxString& value )
406 {
407 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
408
409 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
410 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
411 if (value.IsNull()) return;
412 gint pos = (gint)to;
413 gtk_editable_insert_text( GTK_EDITABLE(entry), value, value.Length(), &pos );
414 }
415
416 void wxComboBox::Remove(long from, long to)
417 {
418 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
419
420 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
421 gtk_editable_delete_text( GTK_EDITABLE(entry), (gint)from, (gint)to );
422 }
423
424 void wxComboBox::SetSelection( long WXUNUSED(from), long WXUNUSED(to) )
425 {
426 wxFAIL_MSG( "wxComboBox::SetSelection not implemented" );
427 }
428
429 void wxComboBox::SetEditable( bool WXUNUSED(editable) )
430 {
431 wxFAIL_MSG( "wxComboBox::SetEditable not implemented" );
432 }
433
434 void wxComboBox::OnSize( wxSizeEvent &event )
435 {
436 wxControl::OnSize( event );
437
438 int w = 21;
439
440 gtk_widget_set_usize( GTK_COMBO(m_widget)->entry, m_width-w-1, m_height );
441
442 gtk_widget_set_uposition( GTK_COMBO(m_widget)->button, m_x+m_width-w, m_y );
443 gtk_widget_set_usize( GTK_COMBO(m_widget)->button, w, m_height );
444 }
445
446 void wxComboBox::SetFont( const wxFont &font )
447 {
448 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
449
450 wxWindow::SetFont( font );
451
452 GtkWidget *entry = GTK_COMBO(m_widget)->entry;
453
454 gtk_widget_set_style( entry,
455 gtk_style_ref(
456 gtk_widget_get_style( m_widget ) ) );
457
458 GtkWidget *list = GTK_COMBO(m_widget)->list;
459
460 GList *child = GTK_LIST(list)->children;
461 while (child)
462 {
463 GtkBin *bin = (GtkBin*) child->data;
464 gtk_widget_set_style( bin->child,
465 gtk_style_ref(
466 gtk_widget_get_style( m_widget ) ) );
467
468 child = child->next;
469 }
470 }
471
472 GtkWidget* wxComboBox::GetConnectWidget(void)
473 {
474 return GTK_COMBO(m_widget)->entry;
475 }
476
477 bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
478 {
479 return ( (window == GTK_ENTRY( GTK_COMBO(m_widget)->entry )->text_area) ||
480 (window == GTK_COMBO(m_widget)->button->window ) );
481 }
482
483 void wxComboBox::SetBackgroundColour( const wxColour &colour )
484 {
485 return;
486
487 wxCHECK_RET( m_widget != NULL, "invalid combobox" );
488
489 m_backgroundColour = colour;
490 if (!m_backgroundColour.Ok()) return;
491
492 GtkStyle *style = gtk_widget_get_style( m_widget );
493 if (!m_hasOwnStyle)
494 {
495 m_hasOwnStyle = TRUE;
496 style = gtk_style_copy( gtk_widget_get_style( m_widget ) );
497 }
498
499 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
500 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
501
502 gtk_widget_set_style( m_widget, style );
503
504 gtk_widget_set_style( GTK_COMBO(m_widget)->button, gtk_style_ref( style ) );
505 gtk_widget_set_style( GTK_COMBO(m_widget)->entry, gtk_style_ref( style ) );
506 gtk_widget_set_style( GTK_COMBO(m_widget)->list, gtk_style_ref( style ) );
507
508 GList *child = GTK_LIST( GTK_COMBO(m_widget)->list )->children;
509 while (child)
510 {
511 GtkWidget *item = GTK_WIDGET(child->data);
512 gtk_widget_set_style( item, gtk_style_ref( style ) );
513 child = child->next;
514 }
515 }
516