]> git.saurik.com Git - wxWidgets.git/blame - src/motif/listbox.cpp
image handlers moved to separate headers (imagbmp.h etc.) This change is backward...
[wxWidgets.git] / src / motif / listbox.cpp
CommitLineData
4bb6408c
JS
1///////////////////////////////////////////////////////////////////////////////
2// Name: listbox.cpp
3// Purpose: wxListBox
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
29006414 13 #pragma implementation "listbox.h"
4bb6408c
JS
14#endif
15
16#include "wx/listbox.h"
17#include "wx/settings.h"
18#include "wx/dynarray.h"
19#include "wx/log.h"
f97c9854
JS
20#include "wx/utils.h"
21
338dd992
JJ
22#ifdef __VMS__
23#pragma message disable nosimpint
24#endif
f97c9854 25#include <Xm/List.h>
338dd992
JJ
26#ifdef __VMS__
27#pragma message enable nosimpint
28#endif
f97c9854 29#include "wx/motif/private.h"
4bb6408c 30
29006414 31 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
4bb6408c 32
29006414
VZ
33static void wxListBoxCallback(Widget w,
34 XtPointer clientData,
35 XmListCallbackStruct * cbs);
f97c9854 36
29006414
VZ
37static void wxListBoxDefaultActionProc(Widget list_w,
38 XtPointer client_data,
39 XmListCallbackStruct * cbs);
f97c9854 40
4bb6408c
JS
41// ============================================================================
42// list box control implementation
43// ============================================================================
44
45// Listbox item
29006414 46wxListBox::wxListBox() : m_clientDataList(wxKEY_INTEGER)
4bb6408c 47{
f97c9854
JS
48 m_noItems = 0;
49 m_selected = 0;
4bb6408c
JS
50}
51
52bool wxListBox::Create(wxWindow *parent, wxWindowID id,
53 const wxPoint& pos,
54 const wxSize& size,
55 int n, const wxString choices[],
56 long style,
57 const wxValidator& validator,
58 const wxString& name)
59{
f97c9854
JS
60 m_windowStyle = style;
61 m_noItems = n;
62 m_selected = 0;
94b49b93
JS
63 // m_backgroundColour = parent->GetBackgroundColour();
64 m_backgroundColour = * wxWHITE;
0d57be45 65 m_foregroundColour = parent->GetForegroundColour();
29006414 66
f97c9854
JS
67 SetName(name);
68 SetValidator(validator);
29006414 69
f97c9854 70 if (parent) parent->AddChild(this);
29006414 71
f97c9854 72 m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
29006414 73
f97c9854 74 Widget parentWidget = (Widget) parent->GetClientWidget();
29006414 75
f97c9854
JS
76 Arg args[3];
77 int count;
78 XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
79 if (m_windowStyle & wxLB_MULTIPLE)
80 XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
81 else if (m_windowStyle & wxLB_EXTENDED)
82 XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
83 else
84 XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
85 if (m_windowStyle & wxLB_ALWAYS_SB)
86 {
87 XtSetArg (args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
88 count = 3;
89 }
90 else
91 count = 2;
29006414 92
f97c9854 93 Widget listWidget = XmCreateScrolledList (parentWidget, (char*) (const char*) name, args, count);
29006414 94
f97c9854 95 m_mainWidget = (WXWidget) listWidget;
29006414 96
a4294b78 97 Set(n, choices);
29006414 98
f97c9854 99 XtManageChild (listWidget);
29006414 100
f97c9854
JS
101 long width = size.x;
102 long height = size.y;
103 if (width == -1)
104 width = 150;
105 if (height == -1)
106 height = 80;
29006414 107
f97c9854 108 XtAddCallback (listWidget, XmNbrowseSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 109 (XtPointer) this);
f97c9854 110 XtAddCallback (listWidget, XmNextendedSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 111 (XtPointer) this);
f97c9854 112 XtAddCallback (listWidget, XmNmultipleSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 113 (XtPointer) this);
29006414 114
f97c9854 115 XtAddCallback (listWidget, XmNdefaultActionCallback, (XtCallbackProc) wxListBoxDefaultActionProc,
2d120f83 116 (XtPointer) this);
29006414 117
da175b2c 118 m_font = parent->GetFont();
4b5f3fe6 119 ChangeFont(FALSE);
29006414 120
15d5ab67 121 SetCanAddEventHandler(TRUE);
f97c9854 122 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, width, height);
29006414 123
0d57be45 124 ChangeBackgroundColour();
29006414 125
f97c9854 126 return TRUE;
4bb6408c
JS
127}
128
129wxListBox::~wxListBox()
130{
131}
132
133void wxListBox::SetFirstItem(int N)
134{
2d120f83 135 int count, length;
29006414 136
2d120f83
JS
137 if (N < 0)
138 return;
139 XtVaGetValues ((Widget) m_mainWidget,
29006414
VZ
140 XmNvisibleItemCount, &count,
141 XmNitemCount, &length,
142 NULL);
2d120f83
JS
143 if ((N + count) >= length)
144 N = length - count;
145 XmListSetPos ((Widget) m_mainWidget, N + 1);
4bb6408c
JS
146}
147
148void wxListBox::SetFirstItem(const wxString& s)
149{
2d120f83 150 int N = FindString (s);
29006414 151
2d120f83
JS
152 if (N >= 0)
153 SetFirstItem (N);
4bb6408c
JS
154}
155
156void wxListBox::Delete(int N)
157{
2d120f83
JS
158 int width1, height1;
159 int width2, height2;
160 Widget listBox = (Widget) m_mainWidget;
161 GetSize (&width1, &height1);
29006414 162
2d120f83 163 bool managed = XtIsManaged(listBox);
29006414 164
2d120f83
JS
165 if (managed)
166 XtUnmanageChild (listBox);
29006414 167
2d120f83 168 XmListDeletePos (listBox, N + 1);
29006414 169
2d120f83
JS
170 if (managed)
171 XtManageChild (listBox);
29006414 172
2d120f83
JS
173 GetSize (&width2, &height2);
174 // Correct for randomly resized listbox - bad boy, Motif!
175 if (width1 != width2 || height1 != height2)
176 SetSize (-1, -1, width1, height1);
29006414 177
2d120f83
JS
178 // (JDH) need to add code here to take care of clientDataList
179 wxNode *node = m_clientDataList.Find((long)N); // get item from list
180 if (node) m_clientDataList.DeleteNode(node); // if existed then delete from list
181 node = m_clientDataList.First(); // we now have to adjust all keys that
182 while (node) // are >=N+1
29006414
VZ
183 {
184 if (node->GetKeyInteger() >= (long)(N+1))
185 node->SetKeyInteger(node->GetKeyInteger() - 1);
186 node = node->Next();
2d120f83 187 }
29006414 188
2d120f83 189 m_noItems --;
4bb6408c
JS
190}
191
192void wxListBox::Append(const wxString& item)
193{
2d120f83
JS
194 int width1, height1;
195 int width2, height2;
29006414 196
2d120f83
JS
197 Widget listBox = (Widget) m_mainWidget;
198 GetSize (&width1, &height1);
29006414 199
2d120f83 200 bool managed = XtIsManaged(listBox);
29006414 201
2d120f83
JS
202 if (managed)
203 XtUnmanageChild (listBox);
204 int n;
205 XtVaGetValues (listBox, XmNitemCount, &n, NULL);
206 XmString text = XmStringCreateSimple ((char*) (const char*) item);
207 // XmListAddItem(listBox, text, n + 1);
208 XmListAddItemUnselected (listBox, text, 0);
209 XmStringFree (text);
29006414 210
2d120f83
JS
211 // It seems that if the list is cleared, we must re-ask for
212 // selection policy!!
213 Arg args[3];
214 XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
215 if (m_windowStyle & wxLB_MULTIPLE)
216 XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
217 else if (m_windowStyle & wxLB_EXTENDED)
218 XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
219 else
220 XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
221 XtSetValues (listBox, args, 2);
29006414 222
2d120f83
JS
223 if (managed)
224 XtManageChild (listBox);
29006414 225
2d120f83
JS
226 GetSize (&width2, &height2);
227 // Correct for randomly resized listbox - bad boy, Motif!
228 if (width1 != width2 || height1 != height2)
229 SetSize (-1, -1, width1, height1);
230 m_noItems ++;
4bb6408c
JS
231}
232
813c20a6 233void wxListBox::Append(const wxString& item, void *clientData)
4bb6408c 234{
2d120f83
JS
235 int width1, height1;
236 int width2, height2;
29006414 237
2d120f83 238 Widget listBox = (Widget) m_mainWidget;
29006414 239
2d120f83
JS
240 GetSize (&width1, &height1);
241 Bool managed = XtIsManaged(listBox);
29006414 242
2d120f83
JS
243 if (managed)
244 XtUnmanageChild (listBox);
29006414 245
2d120f83
JS
246 int n;
247 XtVaGetValues (listBox, XmNitemCount, &n, NULL);
248 XmString text = XmStringCreateSimple ((char*) (const char*) item);
249 // XmListAddItem(listBox, text, n + 1);
250 XmListAddItemUnselected (listBox, text, 0);
251 XmStringFree (text);
29006414 252
2d120f83
JS
253 // It seems that if the list is cleared, we must re-ask for
254 // selection policy!!
255 Arg args[3];
256 XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
257 if (m_windowStyle & wxLB_MULTIPLE)
258 XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
259 else if (m_windowStyle & wxLB_EXTENDED)
260 XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
261 else
262 XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
263 XtSetValues (listBox, args, 2);
29006414 264
2d120f83 265 m_clientDataList.Append ((long) n, (wxObject *) clientData);
29006414 266
2d120f83
JS
267 if (managed)
268 XtManageChild (listBox);
29006414 269
2d120f83 270 GetSize (&width2, &height2);
29006414 271
2d120f83
JS
272 // Correct for randomly resized listbox - bad boy, Motif!
273 if (width1 != width2 || height1 != height2)
274 SetSize (-1, -1, width1, height1);
29006414 275
2d120f83 276 m_noItems ++;
4bb6408c
JS
277}
278
813c20a6 279void wxListBox::Set(int n, const wxString *choices, void** clientData)
4bb6408c 280{
2d120f83
JS
281 m_clientDataList.Clear();
282 int width1, height1;
283 int width2, height2;
29006414 284
2d120f83
JS
285 Widget listBox = (Widget) m_mainWidget;
286 GetSize (&width1, &height1);
29006414 287
2d120f83 288 bool managed = XtIsManaged(listBox);
29006414 289
2d120f83
JS
290 if (managed)
291 XtUnmanageChild (listBox);
292 /***
293 for (int i=0; i<n; i++)
294 {
295 XmString text = XmStringCreateSimple(choices[i]);
296 XmListAddItemUnselected(listBox, text, 0);
297 XmStringFree(text);
298 }
299 ***/
300 XmString *text = new XmString[n];
301 int i;
f97c9854 302 for (i = 0; i < n; i++)
2d120f83 303 text[i] = XmStringCreateSimple ((char*) (const char*) choices[i]);
29006414 304
2d120f83
JS
305 if ( clientData )
306 for (i = 0; i < n; i++)
307 m_clientDataList.Append ((long) i, (wxObject *) clientData[i]);
29006414 308
2d120f83
JS
309 XmListAddItems (listBox, text, n, 0);
310 for (i = 0; i < n; i++)
311 XmStringFree (text[i]);
312 delete[]text;
29006414 313
2d120f83
JS
314 // It seems that if the list is cleared, we must re-ask for
315 // selection policy!!
316 Arg args[3];
317 XtSetArg (args[0], XmNlistSizePolicy, XmCONSTANT);
318 if (m_windowStyle & wxLB_MULTIPLE)
319 XtSetArg (args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
320 else if (m_windowStyle & wxLB_EXTENDED)
321 XtSetArg (args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
322 else
323 XtSetArg (args[1], XmNselectionPolicy, XmBROWSE_SELECT);
324 XtSetValues (listBox, args, 2);
29006414 325
2d120f83
JS
326 if (managed)
327 XtManageChild (listBox);
29006414 328
2d120f83
JS
329 GetSize (&width2, &height2);
330 // Correct for randomly resized listbox - bad boy, Motif!
331 if (width1 != width2 || height1 != height2)
332 SetSize (-1, -1, width1, height1);
29006414 333
2d120f83 334 m_noItems = n;
4bb6408c
JS
335}
336
337int wxListBox::FindString(const wxString& s) const
338{
2d120f83
JS
339 XmString str = XmStringCreateSimple ((char*) (const char*) s);
340 int *positions = NULL;
341 int no_positions = 0;
342 bool success = XmListGetMatchPos ((Widget) m_mainWidget, str, &positions, &no_positions);
343 XmStringFree (str);
344 if (success)
f97c9854 345 {
2d120f83
JS
346 int pos = positions[0];
347 if (positions)
348 XtFree ((char *) positions);
349 return pos - 1;
f97c9854 350 }
2d120f83
JS
351 else
352 return -1;
4bb6408c
JS
353}
354
355void wxListBox::Clear()
356{
2d120f83
JS
357 if (m_noItems <= 0)
358 return;
29006414 359
2d120f83
JS
360 int width1, height1;
361 int width2, height2;
29006414 362
2d120f83
JS
363 Widget listBox = (Widget) m_mainWidget;
364 GetSize (&width1, &height1);
29006414 365
2d120f83
JS
366 XmListDeleteAllItems (listBox);
367 m_clientDataList.Clear ();
368 GetSize (&width2, &height2);
29006414 369
2d120f83
JS
370 // Correct for randomly resized listbox - bad boy, Motif!
371 if (width1 != width2 || height1 != height2)
372 SetSize (-1, -1, width1, height1);
29006414 373
2d120f83 374 m_noItems = 0;
4bb6408c
JS
375}
376
377void wxListBox::SetSelection(int N, bool select)
378{
2d120f83
JS
379 m_inSetValue = TRUE;
380 if (select)
f97c9854 381 {
29006414
VZ
382#if 0
383 if (m_windowStyle & wxLB_MULTIPLE)
384 {
385 int *selections = NULL;
386 int n = GetSelections (&selections);
387
388 // This hack is supposed to work, to make it possible to select more
389 // than one item, but it DOESN'T under Motif 1.1.
390
391 XtVaSetValues ((Widget) m_mainWidget, XmNselectionPolicy, XmMULTIPLE_SELECT, NULL);
392
393 int i;
394 for (i = 0; i < n; i++)
395 XmListSelectPos ((Widget) m_mainWidget, selections[i] + 1, FALSE);
396
397 XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
398
399 XtVaSetValues ((Widget) m_mainWidget, XmNselectionPolicy, XmEXTENDED_SELECT, NULL);
400 }
401 else
402#endif // 0
2d120f83 403 XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
29006414 404
f97c9854 405 }
2d120f83
JS
406 else
407 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
29006414 408
2d120f83 409 m_inSetValue = FALSE;
4bb6408c
JS
410}
411
412bool wxListBox::Selected(int N) const
413{
2d120f83
JS
414 // In Motif, no simple way to determine if the item is selected.
415 wxArrayInt theSelections;
416 int count = GetSelections (theSelections);
417 if (count == 0)
418 return FALSE;
419 else
420 {
421 int j;
422 for (j = 0; j < count; j++)
423 if (theSelections[j] == N)
424 return TRUE;
425 }
4bb6408c
JS
426 return FALSE;
427}
428
429void wxListBox::Deselect(int N)
430{
f97c9854 431 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
4bb6408c
JS
432}
433
813c20a6 434void *wxListBox::GetClientData(int N) const
4bb6408c 435{
f97c9854
JS
436 wxNode *node = m_clientDataList.Find ((long) N);
437 if (node)
813c20a6 438 return (void *) node->Data ();
f97c9854
JS
439 else
440 return NULL;
4bb6408c
JS
441}
442
813c20a6 443void wxListBox::SetClientData(int N, void *Client_data)
4bb6408c 444{
f97c9854
JS
445 wxNode *node = m_clientDataList.Find ((long) N);
446 if (node)
447 node->SetData ((wxObject *)Client_data);
a4294b78
JS
448 else
449 node = m_clientDataList.Append((long) N, (wxObject*) Client_data);
4bb6408c
JS
450}
451
452// Return number of selections and an array of selected integers
453int wxListBox::GetSelections(wxArrayInt& aSelections) const
454{
2d120f83 455 aSelections.Empty();
29006414 456
2d120f83
JS
457 Widget listBox = (Widget) m_mainWidget;
458 int *posList = NULL;
459 int posCnt = 0;
460 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
461 if (flag)
462 {
463 if (posCnt > 0)
464 {
465 aSelections.Alloc(posCnt);
29006414 466
2d120f83
JS
467 int i;
468 for (i = 0; i < posCnt; i++)
469 aSelections.Add(posList[i] - 1);
29006414 470
2d120f83
JS
471 XtFree ((char *) posList);
472 return posCnt;
473 }
474 else
475 return 0;
4bb6408c 476 }
2d120f83
JS
477 else
478 return 0;
4bb6408c
JS
479}
480
481// Get single selection, for single choice list items
482int wxListBox::GetSelection() const
483{
f97c9854
JS
484 Widget listBox = (Widget) m_mainWidget;
485 int *posList = NULL;
486 int posCnt = 0;
487 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
488 if (flag)
489 {
490 int id = -1;
491 if (posCnt > 0)
492 id = posList[0] - 1;
493 XtFree ((char *) posList);
494 return id;
495 }
496 else
497 return -1;
4bb6408c
JS
498}
499
500// Find string for position
501wxString wxListBox::GetString(int N) const
502{
f97c9854
JS
503 Widget listBox = (Widget) m_mainWidget;
504 XmString *strlist;
505 int n;
506 XtVaGetValues (listBox, XmNitemCount, &n, XmNitems, &strlist, NULL);
507 if (N <= n && N >= 0)
508 {
509 char *txt;
510 if (XmStringGetLtoR (strlist[N], XmSTRING_DEFAULT_CHARSET, &txt))
511 {
512 wxString str(txt);
513 XtFree (txt);
514 return str;
515 }
516 else
517 return wxEmptyString;
518 }
519 else
520 return wxEmptyString;
4bb6408c
JS
521}
522
bfc6fde4 523void wxListBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
4bb6408c 524{
bfc6fde4 525 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
29006414 526
f97c9854
JS
527 // Check resulting size is correct
528 int tempW, tempH;
529 GetSize (&tempW, &tempH);
29006414 530
89c7e962
JS
531 /*
532 if (tempW != width || tempH != height)
533 {
2d120f83 534 cout << "wxListBox::SetSize sizes not set correctly.");
89c7e962
JS
535 }
536 */
4bb6408c
JS
537}
538
539void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
540{
f97c9854
JS
541 int width1, height1;
542 int width2, height2;
29006414 543
f97c9854 544 Widget listBox = (Widget) m_mainWidget;
29006414 545
f97c9854 546 GetSize(&width1, &height1);
29006414 547
f97c9854 548 bool managed = XtIsManaged(listBox);
29006414 549
f97c9854
JS
550 if (managed)
551 XtUnmanageChild(listBox);
29006414 552
f97c9854
JS
553 XmString *text = new XmString[nItems];
554 int i;
2d120f83
JS
555 // Steve Hammes: Motif 1.1 compatibility
556 // #if XmVersion > 1100
557 // Corrected by Sergey Krasnov from Steve Hammes' code
f97c9854
JS
558#if XmVersion > 1001
559 for (i = 0; i < nItems; i++)
560 text[i] = XmStringCreateSimple((char*) (const char*) items[i]);
561 XmListAddItemsUnselected(listBox, text, nItems, pos+1);
562#else
563 for (i = 0; i < nItems; i++)
564 {
565 text[i] = XmStringCreateSimple((char*) (const char*) items[i]);
2d120f83 566 // XmListAddItemUnselected(listBox, text[i], i);
f97c9854
JS
567 XmListAddItemUnselected(listBox, text[i], pos+i+1); // Another Sergey correction
568 }
569#endif
570 for (i = 0; i < nItems; i++)
571 XmStringFree(text[i]);
29006414 572
f97c9854 573 delete[] text;
29006414 574
f97c9854
JS
575 // It seems that if the list is cleared, we must re-ask for
576 // selection policy!!
577 Arg args[3];
578 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
579 if (m_windowStyle & wxLB_MULTIPLE)
580 XtSetArg(args[1], XmNselectionPolicy, XmMULTIPLE_SELECT);
581 else if (m_windowStyle & wxLB_EXTENDED)
582 XtSetArg(args[1], XmNselectionPolicy, XmEXTENDED_SELECT);
583 else XtSetArg(args[1], XmNselectionPolicy, XmBROWSE_SELECT);
584 XtSetValues(listBox,args,2) ;
29006414 585
f97c9854
JS
586 if (managed)
587 XtManageChild(listBox);
29006414 588
f97c9854
JS
589 GetSize(&width2, &height2);
590 // Correct for randomly resized listbox - bad boy, Motif!
591 if (width1 != width2 /*|| height1 != height2*/)
592 SetSize(-1, -1, width1, height1);
29006414 593
f97c9854 594 m_noItems += nItems;
4bb6408c
JS
595}
596
597void wxListBox::SetString(int N, const wxString& s)
598{
f97c9854
JS
599 int width1, height1;
600 int width2, height2;
29006414 601
f97c9854
JS
602 Widget listBox = (Widget) m_mainWidget;
603 GetSize (&width1, &height1);
29006414 604
f97c9854 605 XmString text = XmStringCreateSimple ((char*) (const char*) s);
29006414
VZ
606
607 // delete the item and add it again.
608 // FIXME isn't there a way to change it in place?
f97c9854
JS
609 XmListDeletePos (listBox, N+1);
610 XmListAddItem (listBox, text, N+1);
29006414 611
f97c9854 612 XmStringFree(text);
29006414 613
f97c9854
JS
614 GetSize (&width2, &height2);
615 // Correct for randomly resized listbox - bad boy, Motif!
616 if (width1 != width2 || height1 != height2)
617 SetSize (-1, -1, width1, height1);
4bb6408c
JS
618}
619
620int wxListBox::Number () const
621{
f97c9854 622 return m_noItems;
4bb6408c
JS
623}
624
625// For single selection items only
626wxString wxListBox::GetStringSelection () const
627{
29006414
VZ
628 wxString res;
629 int sel = GetSelection();
f97c9854 630 if (sel > -1)
29006414
VZ
631 res = GetString(sel);
632
633 return res;
4bb6408c
JS
634}
635
636bool wxListBox::SetStringSelection (const wxString& s, bool flag)
637{
f97c9854
JS
638 int sel = FindString (s);
639 if (sel > -1)
4bb6408c 640 {
f97c9854
JS
641 SetSelection (sel, flag);
642 return TRUE;
4bb6408c 643 }
f97c9854
JS
644 else
645 return FALSE;
4bb6408c
JS
646}
647
648void wxListBox::Command (wxCommandEvent & event)
649{
f97c9854
JS
650 if (event.m_extraLong)
651 SetSelection (event.m_commandInt);
652 else
653 {
654 Deselect (event.m_commandInt);
655 return;
656 }
657 ProcessCommand (event);
658}
659
af111fc3 660void wxListBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
2d120f83 661 XmListCallbackStruct * cbs)
f97c9854 662{
29006414 663 /*
f97c9854
JS
664 if (cbs->reason == XmCR_EXTENDED_SELECT)
665 cout << "*** Extend select\n";
666 else if (cbs->reason == XmCR_SINGLE_SELECT)
667 cout << "*** Single select\n";
668 else if (cbs->reason == XmCR_MULTIPLE_SELECT)
669 cout << "*** Multiple select\n";
670 else if (cbs->reason == XmCR_BROWSE_SELECT)
671 cout << "*** Browse select\n";
672
673 if (cbs->selection_type == XmMODIFICATION)
674 cout << "*** Modification\n";
675 else if (cbs->selection_type == XmINITIAL)
676 cout << "*** Initial\n";
677 else if (cbs->selection_type == XmADDITION)
678 cout << "*** Addition\n";
2d120f83 679 */
29006414 680
f97c9854 681 wxListBox *item = (wxListBox *) clientData;
29006414 682
a4294b78 683 if (item->InSetValue())
f97c9854 684 return;
29006414 685
b412f9be 686 wxCommandEvent event (wxEVT_COMMAND_LISTBOX_SELECTED, item->GetId());
f97c9854 687 switch (cbs->reason)
4bb6408c 688 {
2d120f83
JS
689 case XmCR_MULTIPLE_SELECT:
690 case XmCR_BROWSE_SELECT:
f97c9854
JS
691 {
692 event.m_clientData = item->GetClientData (cbs->item_position - 1);
f97c9854
JS
693 event.m_commandInt = cbs->item_position - 1;
694 event.m_extraLong = TRUE;
695 event.SetEventObject(item);
696 item->ProcessCommand (event);
f97c9854
JS
697 break;
698 }
2d120f83 699 case XmCR_EXTENDED_SELECT:
f97c9854
JS
700 {
701 switch (cbs->selection_type)
702 {
2d120f83
JS
703 case XmINITIAL:
704 case XmADDITION:
705 case XmMODIFICATION:
f97c9854
JS
706 {
707 event.m_clientData = item->GetClientData (cbs->item_position - 1);
708 event.m_commandInt = cbs->item_position - 1;
709 event.m_extraLong = TRUE;
710 event.SetEventObject(item);
711 item->ProcessCommand (event);
712 break;
713 }
714 }
715 break;
716 }
4bb6408c 717 }
4bb6408c
JS
718}
719
f97c9854 720/* Respond by getting the
2d120f83
JS
721* designated "default button" in the action area and activate it
722* as if the user had selected it.
723*/
af111fc3 724void wxListBoxDefaultActionProc (Widget WXUNUSED(list_w), XtPointer client_data, XmListCallbackStruct * WXUNUSED(cbs))
f97c9854
JS
725{
726 wxListBox *lbox = (wxListBox *) client_data;
29006414 727
f97c9854
JS
728 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, lbox->GetId());
729 event.SetEventObject( lbox );
730 lbox->GetEventHandler()->ProcessEvent(event) ;
731}
732
89c7e962
JS
733WXWidget wxListBox::GetTopWidget() const
734{
2d120f83 735 return (WXWidget) XtParent( (Widget) m_mainWidget );
89c7e962 736}
0d57be45 737
4b5f3fe6 738void wxListBox::ChangeFont(bool keepOriginalSize)
0d57be45 739{
4b5f3fe6 740 wxWindow::ChangeFont(keepOriginalSize);
0d57be45
JS
741}
742
743void wxListBox::ChangeBackgroundColour()
744{
321db4b6 745 wxWindow::ChangeBackgroundColour();
29006414 746
02800301
JS
747 Widget parent = XtParent ((Widget) m_mainWidget);
748 Widget hsb, vsb;
29006414 749
02800301 750 XtVaGetValues (parent,
2d120f83
JS
751 XmNhorizontalScrollBar, &hsb,
752 XmNverticalScrollBar, &vsb,
753 NULL);
29006414 754
a91b47e8
JS
755 /* TODO: should scrollbars be affected? Should probably have separate
756 * function to change them (by default, taken from wxSystemSettings)
2d120f83 757 */
94b49b93
JS
758 wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
759 DoChangeBackgroundColour((WXWidget) hsb, backgroundColour, TRUE);
760 DoChangeBackgroundColour((WXWidget) vsb, backgroundColour, TRUE);
15d5ab67
JS
761
762 XtVaSetValues (hsb,
763 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
764 NULL);
765 XtVaSetValues (vsb,
766 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
767 NULL);
29006414 768
02800301 769 DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, TRUE);
0d57be45
JS
770}
771
772void wxListBox::ChangeForegroundColour()
773{
321db4b6 774 wxWindow::ChangeForegroundColour();
29006414 775
02800301
JS
776 Widget parent = XtParent ((Widget) m_mainWidget);
777 Widget hsb, vsb;
29006414
VZ
778
779 XtVaGetValues(parent,
780 XmNhorizontalScrollBar, &hsb,
781 XmNverticalScrollBar, &vsb,
782 NULL);
783
784 /* TODO: should scrollbars be affected? Should probably have separate
785 function to change them (by default, taken from wxSystemSettings)
786
2d120f83
JS
787 DoChangeForegroundColour((WXWidget) hsb, m_foregroundColour);
788 DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour);
789 DoChangeForegroundColour((WXWidget) parent, m_foregroundColour);
02800301 790 */
0d57be45
JS
791}
792
6adaedf0
JS
793// These implement functions needed by wxControlWithItems.
794// Unfortunately, they're not all implemented yet.
02800301 795
6adaedf0
JS
796int wxListBox::GetCount() const
797{
798 return Number();
799}
800
801int wxListBox::DoAppend(const wxString& item)
802{
803 Append(item, (void*) NULL);
804 return GetCount() - 1;
805}
806
807// Just appends, doesn't yet insert
808void wxListBox::DoInsertItems(const wxArrayString& items, int WXUNUSED(pos))
809{
810 size_t nItems = items.GetCount();
811
812 for ( size_t n = 0; n < nItems; n++ )
813 {
814 Append( items[n], (void*) NULL);
815 }
816}
817
818void wxListBox::DoSetItems(const wxArrayString& items, void **clientData)
819{
820 size_t nItems = items.GetCount();
821 wxString* strings = new wxString[nItems];
822
823 for ( size_t n = 0; n < nItems; n++ )
824 {
825 strings[n] = items[n];
826 }
827 Set(nItems, strings, clientData);
828
829 delete[] strings;
830}
831
832void wxListBox::DoSetFirstItem(int WXUNUSED(n))
833{
834 wxFAIL_MSG( wxT("wxListBox::DoSetFirstItem not implemented") );
835}
836
837void wxListBox::DoSetItemClientData(int n, void* clientData)
838{
839 SetClientData(n, clientData);
840}
841
842void* wxListBox::DoGetItemClientData(int n) const
843{
844 return GetClientData(n);
845}
846
847void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
848{
849 DoSetItemClientData(n, (void*) clientData);
850}
851
852wxClientData* wxListBox::DoGetItemClientObject(int n) const
853{
854 return (wxClientData*) DoGetItemClientData(n);
855}
856
857void wxListBox::Select(int n)
858{
859 SetSelection(n, TRUE);
860}