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