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