]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/listbox.cpp
couple of minor bug fixes/enhancements (interface unchanged)
[wxWidgets.git] / src / gtk1 / listbox.cpp
CommitLineData
c801d85f
KB
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
a3622daa 8// Licence: wxWindows licence
c801d85f
KB
9/////////////////////////////////////////////////////////////////////////////
10
11
12#ifdef __GNUG__
13#pragma implementation "listbox.h"
14#endif
15
6a6d4eed 16#include "wx/dynarray.h"
c801d85f 17#include "wx/listbox.h"
09cf7c58 18#include "wx/utils.h"
c801d85f 19
66bd6b93
RR
20//-----------------------------------------------------------------------------
21// data
22//-----------------------------------------------------------------------------
23
24extern bool g_blockEventsOnDrag;
25
c801d85f
KB
26//-----------------------------------------------------------------------------
27// wxListBox
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;
34
c801d85f
KB
35 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() );
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 ;
c801d85f
KB
57};
58
59//-----------------------------------------------------------------------------
60
61IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl)
62
63wxListBox::wxListBox(void)
64{
65 m_list = NULL;
66};
67
68wxListBox::wxListBox( wxWindow *parent, wxWindowID id,
69 const wxPoint &pos, const wxSize &size,
debe6624
JS
70 int n, const wxString choices[],
71 long style, const wxString &name )
c801d85f
KB
72{
73 Create( parent, id, pos, size, n, choices, style, name );
74};
75
76bool wxListBox::Create( wxWindow *parent, wxWindowID id,
77 const wxPoint &pos, const wxSize &size,
debe6624
JS
78 int n, const wxString choices[],
79 long style, const wxString &name )
c801d85f
KB
80{
81 m_needParent = TRUE;
82
83 PreCreation( parent, id, pos, size, style, name );
84
85 m_widget = gtk_scrolled_window_new( NULL, NULL );
86 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
87 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
88
89 m_list = GTK_LIST( gtk_list_new() );
6a6d4eed
VZ
90
91 // @@ what's the difference between BROWSE and SINGLE?
92 GtkSelectionMode mode = GTK_SELECTION_BROWSE;
93 if ( style & wxLB_MULTIPLE )
94 mode = GTK_SELECTION_MULTIPLE;
95 else if ( style & wxLB_EXTENDED )
96 mode = GTK_SELECTION_EXTENDED;
97
98 gtk_list_set_selection_mode( GTK_LIST(m_list), mode );
c801d85f
KB
99
100 gtk_container_add (GTK_CONTAINER(m_widget), GTK_WIDGET(m_list) );
101 gtk_widget_show( GTK_WIDGET(m_list) );
102
103 for (int i = 0; i < n; i++)
104 {
105 GtkWidget *list_item;
106 list_item = gtk_list_item_new_with_label( choices[i] );
107
66bd6b93
RR
108 gtk_container_add( GTK_CONTAINER(m_list), list_item );
109
c801d85f
KB
110 gtk_signal_connect( GTK_OBJECT(list_item), "select",
111 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
112
09cf7c58
RR
113 if ( style & wxLB_MULTIPLE )
114 gtk_signal_connect( GTK_OBJECT(list_item), "deselect",
115 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
116
e2414cbe
RR
117 m_clientData.Append( (wxObject*)NULL );
118
c801d85f
KB
119 gtk_widget_show( list_item );
120 };
121
122 PostCreation();
123
e3e65dac
RR
124 gtk_widget_realize( GTK_WIDGET(m_list) );
125
c801d85f
KB
126 Show( TRUE );
127
128 return TRUE;
129};
130
131void wxListBox::Append( const wxString &item )
132{
09cf7c58 133 Append( item, (char*)NULL );
c801d85f
KB
134};
135
e2414cbe 136void wxListBox::Append( const wxString &item, char *clientData )
c801d85f 137{
e2414cbe
RR
138 GtkWidget *list_item;
139 list_item = gtk_list_item_new_with_label( item );
140
09cf7c58 141 gtk_signal_connect( GTK_OBJECT(list_item), "select",
e2414cbe
RR
142 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
143
09cf7c58
RR
144 if ( GetWindowStyleFlag() & wxLB_MULTIPLE )
145 gtk_signal_connect( GTK_OBJECT(list_item), "deselect",
146 GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this );
147
e2414cbe
RR
148 gtk_container_add( GTK_CONTAINER(m_list), list_item );
149
150 m_clientData.Append( (wxObject*)clientData );
151
152 gtk_widget_show( list_item );
c801d85f
KB
153};
154
155void wxListBox::Clear(void)
156{
157 gtk_list_clear_items( m_list, 0, Number() );
e2414cbe
RR
158
159 m_clientData.Clear();
c801d85f
KB
160};
161
162void wxListBox::Delete( int n )
163{
164 gtk_list_clear_items( m_list, n, n );
e2414cbe
RR
165
166 wxNode *node = m_clientData.Nth( n );
167 if (!node)
168 {
169 wxFAIL_MSG("wxListBox::Delete wrong index");
170 }
171 else
172 m_clientData.DeleteNode( node );
c801d85f
KB
173};
174
175void wxListBox::Deselect( int n )
176{
177 gtk_list_unselect_item( m_list, n );
178};
179
180int wxListBox::FindString( const wxString &item ) const
181{
182 GList *child = m_list->children;
183 int count = 0;
184 while (child)
185 {
186 GtkBin *bin = GTK_BIN( child->data );
187 GtkLabel *label = GTK_LABEL( bin->child );
188 if (item == label->label) return count;
189 count++;
190 child = child->next;
191 };
192 return -1;
193};
194
e2414cbe 195char *wxListBox::GetClientData( int n ) const
c801d85f 196{
e2414cbe
RR
197 wxNode *node = m_clientData.Nth( n );
198 if (node) return ((char*)node->Data());
c801d85f
KB
199 return NULL;
200};
201
202int wxListBox::GetSelection(void) const
203{
204 GList *selection = m_list->selection;
205 if (selection)
206 {
207 GList *child = m_list->children;
208 int count = 0;
209 while (child)
210 {
211 if (child->data == selection->data) return count;
212 count++;
213 child = child->next;
214 };
215 };
216 return -1;
217};
218
6a6d4eed 219int wxListBox::GetSelections(wxArrayInt& aSelections) const
c801d85f 220{
6a6d4eed
VZ
221 // get the number of selected items first
222 GList *child = m_list->children;
223 int count = 0;
224 for ( child = m_list->children; child != NULL; child = child->next ) {
225 if ( GTK_WIDGET(child->data)->state == GTK_STATE_SELECTED )
226 count++;
227 }
228
229 aSelections.Empty();
230
231 if ( count > 0 ) {
232 // now fill the list
233 aSelections.Alloc(count); // optimization attempt
234 int i = 0;
235 for ( child = m_list->children; child != NULL; child = child->next, i++ ) {
236 if ( GTK_WIDGET(child->data)->state == GTK_STATE_SELECTED )
237 aSelections.Add(i);
238 }
239 }
240
241 return count;
c801d85f
KB
242};
243
244wxString wxListBox::GetString( int n ) const
245{
246 GList *child = g_list_nth( m_list->children, n );
247 if (child)
248 {
249 GtkBin *bin = GTK_BIN( child->data );
250 GtkLabel *label = GTK_LABEL( bin->child );
251 return label->label;
252 };
253 return "";
254};
255
256wxString wxListBox::GetStringSelection(void) const
257{
258 GList *selection = m_list->selection;
259 if (selection)
260 {
261 GtkBin *bin = GTK_BIN( selection->data );
262 wxString tmp = GTK_LABEL( bin->child )->label;
263 return tmp;
264 };
265 return "";
266};
267
268int wxListBox::Number(void)
269{
270 GList *child = m_list->children;
271 int count = 0;
272 while (child) { count++; child = child->next; };
273 return count;
274};
275
debe6624 276bool wxListBox::Selected( int n )
c801d85f
KB
277{
278 GList *target = g_list_nth( m_list->children, n );
279 if (target)
280 {
281 GList *child = m_list->selection;
282 while (child)
283 {
284 if (child->data == target->data) return TRUE;
285 child = child->next;
286 };
287 };
288 return FALSE;
289};
290
debe6624 291void wxListBox::Set( int WXUNUSED(n), const wxString *WXUNUSED(choices) )
c801d85f
KB
292{
293};
294
e2414cbe 295void wxListBox::SetClientData( int n, char *clientData )
c801d85f 296{
e2414cbe
RR
297 wxNode *node = m_clientData.Nth( n );
298 if (node) node->SetData( (wxObject*)clientData );
c801d85f
KB
299};
300
301void wxListBox::SetFirstItem( int WXUNUSED(n) )
302{
303};
304
305void wxListBox::SetFirstItem( const wxString &WXUNUSED(item) )
306{
307};
308
debe6624 309void wxListBox::SetSelection( int n, bool select )
c801d85f
KB
310{
311 if (select)
312 gtk_list_select_item( m_list, n );
313 else
314 gtk_list_unselect_item( m_list, n );
315};
316
09cf7c58 317void wxListBox::SetString( int n, const wxString &string )
c801d85f 318{
09cf7c58
RR
319 GList *child = g_list_nth( m_list->children, n );
320 if (child)
321 {
322 GtkBin *bin = GTK_BIN( child->data );
323 GtkLabel *label = GTK_LABEL( bin->child );
324 gtk_label_set( label, string );
325 };
c801d85f
KB
326};
327
debe6624 328void wxListBox::SetStringSelection( const wxString &string, bool select )
c801d85f
KB
329{
330 SetSelection( FindString(string), select );
331};
332
333int wxListBox::GetIndex( GtkWidget *item ) const
334{
335 if (item)
336 {
337 GList *child = m_list->children;
338 int count = 0;
339 while (child)
340 {
341 if (GTK_WIDGET(child->data) == item) return count;
342 count++;
343 child = child->next;
344 };
345 };
346 return -1;
347};
348
e3e65dac
RR
349GtkWidget *wxListBox::GetDropTargetWidget(void)
350{
351 return GTK_WIDGET(m_list);
352};
353
354
c801d85f 355