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