]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/gtk/listbox.cpp
Added casts to fix compile problem
[wxWidgets.git] / src / gtk / listbox.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: listbox.cpp
3// Purpose:
4// Author: Robert Roebling
5// Created: 01/02/97
6// Id:
7// Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11
12#ifdef __GNUG__
13#pragma implementation "listbox.h"
14#endif
15
16#include "wx/dynarray.h"
17#include "wx/listbox.h"
18#include "wx/utils.h"
19#include <wx/intl.h>
20
21//-----------------------------------------------------------------------------
22// data
23//-----------------------------------------------------------------------------
24
25extern bool g_blockEventsOnDrag;
26
27//-----------------------------------------------------------------------------
28// "select" and "deselect"
29//-----------------------------------------------------------------------------
30
31static void gtk_listitem_select_callback( GtkWidget *WXUNUSED(widget), wxListBox *listbox )
32{
33 if (!listbox->HasVMT()) return;
34 if (g_blockEventsOnDrag) return;
35
36 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
37
38 wxArrayInt aSelections;
39 int count = listbox->GetSelections(aSelections);
40 if ( count > 0 )
41 {
42 event.m_commandInt = aSelections[0] ;
43 event.m_clientData = listbox->GetClientData(event.m_commandInt);
44 wxString str(listbox->GetString(event.m_commandInt));
45 if (str != "")
46 event.m_commandString = copystring((char *)(const char *)str);
47 }
48 else
49 {
50 event.m_commandInt = -1 ;
51 event.m_commandString = copystring("") ;
52 }
53
54 event.SetEventObject( listbox );
55
56 listbox->GetEventHandler()->ProcessEvent( event );
57 if (event.m_commandString) delete[] event.m_commandString ;
58}
59
60//-----------------------------------------------------------------------------
61// wxListBox
62//-----------------------------------------------------------------------------
63
64IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
65
66wxListBox::wxListBox(void)
67{
68 m_list = (GtkList *) NULL;
69}
70
71bool wxListBox::Create( wxWindow *parent, wxWindowID id,
72 const wxPoint &pos, const wxSize &size,
73 int n, const wxString choices[],
74 long style, const wxValidator& validator, const wxString &name )
75{
76 m_needParent = TRUE;
77
78 PreCreation( parent, id, pos, size, style, name );
79
80 SetValidator( validator );
81
82 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
83 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
84 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
85
86 m_list = GTK_LIST( gtk_list_new() );
87
88 GtkSelectionMode mode = GTK_SELECTION_BROWSE;
89 if (style & wxLB_MULTIPLE)
90 mode = GTK_SELECTION_MULTIPLE;
91 else if (style & wxLB_EXTENDED)
92 mode = GTK_SELECTION_EXTENDED;
93
94 gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
95
96 gtk_container_add (GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
97 gtk_widget_show( GTK_WIDGET(m_list) );
98
99 wxSize newSize = size;
100 if (newSize.x == -1) newSize.x = 100;
101 if (newSize.y == -1) newSize.y = 110;
102 SetSize( newSize.x, newSize.y );
103
104 for (int i = 0; i < n; i++)
105 {
106 GtkWidget *list_item;
107 list_item = gtk_list_item_new_with_label( choices[i] );
108
109 gtk_container_add( GTK_CONTAINER(m_list), list_item );
110
111 gtk_signal_connect( GTK_OBJECT(list_item), "select",
112 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
113
114 if (style & wxLB_MULTIPLE)
115 gtk_signal_connect( GTK_OBJECT(list_item), "deselect",
116 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
117
118 m_clientData.Append( (wxObject*)NULL );
119
120 gtk_widget_show( list_item );
121 }
122
123 PostCreation();
124
125 gtk_widget_realize( GTK_WIDGET(m_list) );
126
127 Show( TRUE );
128
129 return TRUE;
130}
131
132void wxListBox::Append( const wxString &item )
133{
134 Append( item, (char*)NULL );
135}
136
137void wxListBox::Append( const wxString &item, char *clientData )
138{
139 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
140
141 GtkWidget *list_item = gtk_list_item_new_with_label( item );
142
143 if (m_hasOwnStyle)
144 {
145 GtkBin *bin = GTK_BIN( list_item );
146 gtk_widget_set_style( bin->child,
147 gtk_style_ref(
148 gtk_widget_get_style( GTK_WIDGET(m_list) ) ) );
149
150 gtk_widget_set_style( GTK_WIDGET(bin),
151 gtk_style_ref(
152 gtk_widget_get_style( GTK_WIDGET(m_list) ) ) );
153 }
154
155 gtk_signal_connect( GTK_OBJECT(list_item), "select",
156 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
157
158 if (GetWindowStyleFlag() & wxLB_MULTIPLE)
159 gtk_signal_connect( GTK_OBJECT(list_item), "deselect",
160 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
161
162 m_clientData.Append( (wxObject*)clientData );
163
164 gtk_container_add( GTK_CONTAINER(m_list), list_item );
165
166 gtk_widget_show( list_item );
167
168 ConnectWidget( list_item );
169
170 ConnectDnDWidget( list_item );
171}
172
173void wxListBox::Clear(void)
174{
175 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
176
177 gtk_list_clear_items( m_list, 0, Number() );
178
179 m_clientData.Clear();
180}
181
182void wxListBox::Delete( int n )
183{
184 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
185
186 GList *child = g_list_nth( m_list->children, n );
187
188 if (!child)
189 {
190 wxFAIL_MSG("wrong listbox index");
191 return;
192 }
193
194 GList *list = g_list_append( NULL, child->data );
195 gtk_list_remove_items( m_list, list );
196 g_list_free( list );
197
198 wxNode *node = m_clientData.Nth( n );
199 if (!node)
200 {
201 wxFAIL_MSG("wrong listbox index");
202 }
203 else
204 m_clientData.DeleteNode( node );
205}
206
207void wxListBox::Deselect( int n )
208{
209 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
210
211 gtk_list_unselect_item( m_list, n );
212}
213
214int wxListBox::FindString( const wxString &item ) const
215{
216 wxCHECK_MSG( m_list != NULL, -1, "invalid list ctrl" );
217
218 GList *child = m_list->children;
219 int count = 0;
220 while (child)
221 {
222 GtkBin *bin = GTK_BIN( child->data );
223 GtkLabel *label = GTK_LABEL( bin->child );
224 if (item == label->label) return count;
225 count++;
226 child = child->next;
227 }
228
229 // it's not an error if the string is not found - this function may be used to
230 // test for existence of the string in the listbox, so don't give any
231 // errors/assert failures.
232
233 return -1;
234}
235
236char *wxListBox::GetClientData( int n ) const
237{
238 wxCHECK_MSG( m_list != NULL, (char*) NULL, "invalid list ctrl" );
239
240 wxNode *node = m_clientData.Nth( n );
241 if (node) return ((char*)node->Data());
242
243 wxFAIL_MSG("wrong listbox index");
244 return (char *) NULL;
245}
246
247int wxListBox::GetSelection(void) const
248{
249 wxCHECK_MSG( m_list != NULL, -1, "invalid list ctrl" );
250
251 GList *child = m_list->children;
252 int count = 0;
253 while (child)
254 {
255 if (GTK_WIDGET(child->data)->state == GTK_STATE_SELECTED) return count;
256 count++;
257 child = child->next;
258 }
259 return -1;
260}
261
262int wxListBox::GetSelections(wxArrayInt& aSelections) const
263{
264 wxCHECK_MSG( m_list != NULL, -1, "invalid list ctrl" );
265
266 // get the number of selected items first
267 GList *child = m_list->children;
268 int count = 0;
269 for ( child = m_list->children; child != NULL; child = child->next )
270 {
271 if ( GTK_WIDGET(child->data)->state == GTK_STATE_SELECTED )
272 count++;
273 }
274
275 aSelections.Empty();
276
277 if ( count > 0 ) {
278 // now fill the list
279 aSelections.Alloc(count); // optimization attempt
280 int i = 0;
281 for ( child = m_list->children; child != NULL; child = child->next, i++ )
282 {
283 if ( GTK_WIDGET(child->data)->state == GTK_STATE_SELECTED )
284 aSelections.Add(i);
285 }
286 }
287
288 return count;
289}
290
291wxString wxListBox::GetString( int n ) const
292{
293 wxCHECK_MSG( m_list != NULL, "", "invalid list ctrl" );
294
295 GList *child = g_list_nth( m_list->children, n );
296 if (child)
297 {
298 GtkBin *bin = GTK_BIN( child->data );
299 GtkLabel *label = GTK_LABEL( bin->child );
300 return label->label;
301 }
302 wxFAIL_MSG("wrong listbox index");
303 return "";
304}
305
306wxString wxListBox::GetStringSelection(void) const
307{
308 wxCHECK_MSG( m_list != NULL, "", "invalid list ctrl" );
309
310 GList *selection = m_list->selection;
311 if (selection)
312 {
313 GtkBin *bin = GTK_BIN( selection->data );
314 wxString tmp = GTK_LABEL( bin->child )->label;
315 return tmp;
316 }
317 wxFAIL_MSG("no listbox selection available");
318 return "";
319}
320
321int wxListBox::Number(void)
322{
323 wxCHECK_MSG( m_list != NULL, -1, "invalid list ctrl" );
324
325 GList *child = m_list->children;
326 int count = 0;
327 while (child) { count++; child = child->next; }
328 return count;
329}
330
331bool wxListBox::Selected( int n )
332{
333 wxCHECK_MSG( m_list != NULL, FALSE, "invalid list ctrl" );
334
335 GList *target = g_list_nth( m_list->children, n );
336 if (target)
337 {
338 GList *child = m_list->selection;
339 while (child)
340 {
341 if (child->data == target->data) return TRUE;
342 child = child->next;
343 }
344 }
345 wxFAIL_MSG("wrong listbox index");
346 return FALSE;
347}
348
349void wxListBox::Set( int WXUNUSED(n), const wxString *WXUNUSED(choices) )
350{
351 wxFAIL_MSG("wxListBox::Set not implemented");
352}
353
354void wxListBox::SetClientData( int n, char *clientData )
355{
356 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
357
358 wxNode *node = m_clientData.Nth( n );
359 if (node)
360 {
361 node->SetData( (wxObject*)clientData );
362 }
363 else
364 {
365 wxFAIL_MSG("wrong listbox index");
366 }
367}
368
369void wxListBox::SetFirstItem( int WXUNUSED(n) )
370{
371 wxFAIL_MSG("wxListBox::SetFirstItem not implemented");
372}
373
374void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
375{
376 wxFAIL_MSG("wxListBox::SetFirstItem not implemented");
377}
378
379void wxListBox::SetSelection( int n, bool select )
380{
381 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
382
383 if (select)
384 gtk_list_select_item( m_list, n );
385 else
386 gtk_list_unselect_item( m_list, n );
387}
388
389void wxListBox::SetString( int n, const wxString &string )
390{
391 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
392
393 GList *child = g_list_nth( m_list->children, n );
394 if (child)
395 {
396 GtkBin *bin = GTK_BIN( child->data );
397 GtkLabel *label = GTK_LABEL( bin->child );
398 gtk_label_set( label, string );
399 }
400 else
401 {
402 wxFAIL_MSG("wrong listbox index");
403 }
404}
405
406void wxListBox::SetStringSelection( const wxString &string, bool select )
407{
408 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
409
410 SetSelection( FindString(string), select );
411}
412
413int wxListBox::GetIndex( GtkWidget *item ) const
414{
415 if (item)
416 {
417 GList *child = m_list->children;
418 int count = 0;
419 while (child)
420 {
421 if (GTK_WIDGET(child->data) == item) return count;
422 count++;
423 child = child->next;
424 }
425 }
426 return -1;
427}
428
429void wxListBox::SetDropTarget( wxDropTarget *dropTarget )
430{
431 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
432
433 GList *child = m_list->children;
434 while (child)
435 {
436 DisconnectDnDWidget( GTK_WIDGET( child->data ) );
437 child = child->next;
438 }
439
440 wxWindow::SetDropTarget( dropTarget );
441
442 child = m_list->children;
443 while (child)
444 {
445 ConnectDnDWidget( GTK_WIDGET( child->data ) );
446 child = child->next;
447 }
448}
449
450GtkWidget *wxListBox::GetConnectWidget(void)
451{
452 return GTK_WIDGET(m_list);
453}
454
455void wxListBox::SetFont( const wxFont &font )
456{
457 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
458
459 if (((wxFont*)&font)->Ok())
460 m_font = font;
461 else
462 m_font = *wxSWISS_FONT;
463
464 GtkStyle *style = (GtkStyle*) NULL;
465 if (!m_hasOwnStyle)
466 {
467 m_hasOwnStyle = TRUE;
468 style = gtk_style_copy( gtk_widget_get_style( GTK_WIDGET(m_list) ) );
469 }
470 else
471 {
472 style = gtk_widget_get_style( GTK_WIDGET(m_list) );
473 }
474
475 gdk_font_unref( style->font );
476 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
477
478 gtk_widget_set_style( GTK_WIDGET(m_list), style );
479
480
481 GList *child = m_list->children;
482 while (child)
483 {
484 GtkBin *bin = (GtkBin*) child->data;
485 gtk_widget_set_style( bin->child,
486 gtk_style_ref(
487 gtk_widget_get_style( GTK_WIDGET(m_list) ) ) );
488 child = child->next;
489 }
490}
491
492bool wxListBox::IsOwnGtkWindow( GdkWindow *window )
493{
494 if (wxWindow::IsOwnGtkWindow( window )) return TRUE;
495
496 GList *child = m_list->children;
497 while (child)
498 {
499 GtkBin *bin = GTK_BIN( child->data );
500 if (bin->child->window == window) return TRUE;
501 child = child->next;
502 }
503
504 return FALSE;
505}
506
507void wxListBox::SetBackgroundColour( const wxColour &colour )
508{
509 wxCHECK_RET( m_list != NULL, "invalid list ctrl" );
510
511 m_backgroundColour = colour;
512 if (!m_backgroundColour.Ok()) return;
513
514 SetBackgroundColourHelper( GTK_WIDGET(m_list)->window );
515
516 GtkStyle *style = (GtkStyle*) NULL;
517 if (!m_hasOwnStyle)
518 {
519 m_hasOwnStyle = TRUE;
520 style = gtk_style_copy( gtk_widget_get_style( GTK_WIDGET(m_list) ) );
521 }
522 else
523 {
524 style = gtk_widget_get_style( GTK_WIDGET(m_list) );
525 }
526
527 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
528 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
529
530 gtk_widget_set_style( GTK_WIDGET(m_list), style );
531
532 GList *child = m_list->children;
533 while (child)
534 {
535 GtkWidget *item = GTK_WIDGET(child->data);
536 gtk_widget_set_style( item,
537 gtk_style_ref(
538 gtk_widget_get_style( GTK_WIDGET(m_list) ) ) );
539 child = child->next;
540 }
541}
542