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