Improved selection mode handling in wxGrid::SelectBlock
[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 #ifdef __VMS__
23 #pragma message disable nosimpint
24 #endif
25 #include <Xm/List.h>
26 #ifdef __VMS__
27 #pragma message enable nosimpint
28 #endif
29 #include "wx/motif/private.h"
30
31 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
32
33 static void wxListBoxCallback(Widget w,
34 XtPointer clientData,
35 XmListCallbackStruct * cbs);
36
37 static void wxListBoxDefaultActionProc(Widget list_w,
38 XtPointer client_data,
39 XmListCallbackStruct * cbs);
40
41 // ============================================================================
42 // list box control implementation
43 // ============================================================================
44
45 // Listbox item
46 wxListBox::wxListBox() : m_clientDataList(wxKEY_INTEGER)
47 {
48 m_noItems = 0;
49 m_selected = 0;
50 }
51
52 bool 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 {
60 m_windowStyle = style;
61 m_noItems = n;
62 m_selected = 0;
63 // m_backgroundColour = parent->GetBackgroundColour();
64 m_backgroundColour = * wxWHITE;
65 m_foregroundColour = parent->GetForegroundColour();
66
67 SetName(name);
68 SetValidator(validator);
69
70 if (parent) parent->AddChild(this);
71
72 m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
73
74 Widget parentWidget = (Widget) parent->GetClientWidget();
75
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;
92
93 Widget listWidget = XmCreateScrolledList (parentWidget, (char*) (const char*) name, args, count);
94
95 m_mainWidget = (WXWidget) listWidget;
96
97 Set(n, choices);
98
99 XtManageChild (listWidget);
100
101 long width = size.x;
102 long height = size.y;
103 if (width == -1)
104 width = 150;
105 if (height == -1)
106 height = 80;
107
108 XtAddCallback (listWidget, XmNbrowseSelectionCallback, (XtCallbackProc) wxListBoxCallback,
109 (XtPointer) this);
110 XtAddCallback (listWidget, XmNextendedSelectionCallback, (XtCallbackProc) wxListBoxCallback,
111 (XtPointer) this);
112 XtAddCallback (listWidget, XmNmultipleSelectionCallback, (XtCallbackProc) wxListBoxCallback,
113 (XtPointer) this);
114
115 XtAddCallback (listWidget, XmNdefaultActionCallback, (XtCallbackProc) wxListBoxDefaultActionProc,
116 (XtPointer) this);
117
118 m_font = parent->GetFont();
119 ChangeFont(FALSE);
120
121 SetCanAddEventHandler(TRUE);
122 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, width, height);
123
124 ChangeBackgroundColour();
125
126 return TRUE;
127 }
128
129 wxListBox::~wxListBox()
130 {
131 }
132
133 void wxListBox::SetFirstItem(int N)
134 {
135 int count, length;
136
137 if (N < 0)
138 return;
139 XtVaGetValues ((Widget) m_mainWidget,
140 XmNvisibleItemCount, &count,
141 XmNitemCount, &length,
142 NULL);
143 if ((N + count) >= length)
144 N = length - count;
145 XmListSetPos ((Widget) m_mainWidget, N + 1);
146 }
147
148 void wxListBox::SetFirstItem(const wxString& s)
149 {
150 int N = FindString (s);
151
152 if (N >= 0)
153 SetFirstItem (N);
154 }
155
156 void wxListBox::Delete(int N)
157 {
158 int width1, height1;
159 int width2, height2;
160 Widget listBox = (Widget) m_mainWidget;
161 GetSize (&width1, &height1);
162
163 bool managed = XtIsManaged(listBox);
164
165 if (managed)
166 XtUnmanageChild (listBox);
167
168 XmListDeletePos (listBox, N + 1);
169
170 if (managed)
171 XtManageChild (listBox);
172
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);
177
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
183 {
184 if (node->GetKeyInteger() >= (long)(N+1))
185 node->SetKeyInteger(node->GetKeyInteger() - 1);
186 node = node->Next();
187 }
188
189 m_noItems --;
190 }
191
192 void wxListBox::Append(const wxString& item)
193 {
194 int width1, height1;
195 int width2, height2;
196
197 Widget listBox = (Widget) m_mainWidget;
198 GetSize (&width1, &height1);
199
200 bool managed = XtIsManaged(listBox);
201
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);
210
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);
222
223 if (managed)
224 XtManageChild (listBox);
225
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 ++;
231 }
232
233 void wxListBox::Append(const wxString& item, void *clientData)
234 {
235 int width1, height1;
236 int width2, height2;
237
238 Widget listBox = (Widget) m_mainWidget;
239
240 GetSize (&width1, &height1);
241 Bool managed = XtIsManaged(listBox);
242
243 if (managed)
244 XtUnmanageChild (listBox);
245
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);
252
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);
264
265 m_clientDataList.Append ((long) n, (wxObject *) clientData);
266
267 if (managed)
268 XtManageChild (listBox);
269
270 GetSize (&width2, &height2);
271
272 // Correct for randomly resized listbox - bad boy, Motif!
273 if (width1 != width2 || height1 != height2)
274 SetSize (-1, -1, width1, height1);
275
276 m_noItems ++;
277 }
278
279 void wxListBox::Set(int n, const wxString *choices, void** clientData)
280 {
281 m_clientDataList.Clear();
282 int width1, height1;
283 int width2, height2;
284
285 Widget listBox = (Widget) m_mainWidget;
286 GetSize (&width1, &height1);
287
288 bool managed = XtIsManaged(listBox);
289
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;
302 for (i = 0; i < n; i++)
303 text[i] = XmStringCreateSimple ((char*) (const char*) choices[i]);
304
305 if ( clientData )
306 for (i = 0; i < n; i++)
307 m_clientDataList.Append ((long) i, (wxObject *) clientData[i]);
308
309 XmListAddItems (listBox, text, n, 0);
310 for (i = 0; i < n; i++)
311 XmStringFree (text[i]);
312 delete[]text;
313
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);
325
326 if (managed)
327 XtManageChild (listBox);
328
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);
333
334 m_noItems = n;
335 }
336
337 int wxListBox::FindString(const wxString& s) const
338 {
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)
345 {
346 int pos = positions[0];
347 if (positions)
348 XtFree ((char *) positions);
349 return pos - 1;
350 }
351 else
352 return -1;
353 }
354
355 void wxListBox::Clear()
356 {
357 if (m_noItems <= 0)
358 return;
359
360 int width1, height1;
361 int width2, height2;
362
363 Widget listBox = (Widget) m_mainWidget;
364 GetSize (&width1, &height1);
365
366 XmListDeleteAllItems (listBox);
367 m_clientDataList.Clear ();
368 GetSize (&width2, &height2);
369
370 // Correct for randomly resized listbox - bad boy, Motif!
371 if (width1 != width2 || height1 != height2)
372 SetSize (-1, -1, width1, height1);
373
374 m_noItems = 0;
375 }
376
377 void wxListBox::SetSelection(int N, bool select)
378 {
379 m_inSetValue = TRUE;
380 if (select)
381 {
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
403 XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
404
405 }
406 else
407 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
408
409 m_inSetValue = FALSE;
410 }
411
412 bool wxListBox::Selected(int N) const
413 {
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 }
426 return FALSE;
427 }
428
429 void wxListBox::Deselect(int N)
430 {
431 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
432 }
433
434 void *wxListBox::GetClientData(int N) const
435 {
436 wxNode *node = m_clientDataList.Find ((long) N);
437 if (node)
438 return (void *) node->Data ();
439 else
440 return NULL;
441 }
442
443 void wxListBox::SetClientData(int N, void *Client_data)
444 {
445 wxNode *node = m_clientDataList.Find ((long) N);
446 if (node)
447 node->SetData ((wxObject *)Client_data);
448 else
449 node = m_clientDataList.Append((long) N, (wxObject*) Client_data);
450 }
451
452 // Return number of selections and an array of selected integers
453 int wxListBox::GetSelections(wxArrayInt& aSelections) const
454 {
455 aSelections.Empty();
456
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);
466
467 int i;
468 for (i = 0; i < posCnt; i++)
469 aSelections.Add(posList[i] - 1);
470
471 XtFree ((char *) posList);
472 return posCnt;
473 }
474 else
475 return 0;
476 }
477 else
478 return 0;
479 }
480
481 // Get single selection, for single choice list items
482 int wxListBox::GetSelection() const
483 {
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;
498 }
499
500 // Find string for position
501 wxString wxListBox::GetString(int N) const
502 {
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;
521 }
522
523 void wxListBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
524 {
525 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
526
527 // Check resulting size is correct
528 int tempW, tempH;
529 GetSize (&tempW, &tempH);
530
531 /*
532 if (tempW != width || tempH != height)
533 {
534 cout << "wxListBox::SetSize sizes not set correctly.");
535 }
536 */
537 }
538
539 void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
540 {
541 int width1, height1;
542 int width2, height2;
543
544 Widget listBox = (Widget) m_mainWidget;
545
546 GetSize(&width1, &height1);
547
548 bool managed = XtIsManaged(listBox);
549
550 if (managed)
551 XtUnmanageChild(listBox);
552
553 XmString *text = new XmString[nItems];
554 int i;
555 // Steve Hammes: Motif 1.1 compatibility
556 // #if XmVersion > 1100
557 // Corrected by Sergey Krasnov from Steve Hammes' code
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]);
566 // XmListAddItemUnselected(listBox, text[i], i);
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]);
572
573 delete[] text;
574
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) ;
585
586 if (managed)
587 XtManageChild(listBox);
588
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);
593
594 m_noItems += nItems;
595 }
596
597 void wxListBox::SetString(int N, const wxString& s)
598 {
599 int width1, height1;
600 int width2, height2;
601
602 Widget listBox = (Widget) m_mainWidget;
603 GetSize (&width1, &height1);
604
605 XmString text = XmStringCreateSimple ((char*) (const char*) s);
606
607 // delete the item and add it again.
608 // FIXME isn't there a way to change it in place?
609 XmListDeletePos (listBox, N+1);
610 XmListAddItem (listBox, text, N+1);
611
612 XmStringFree(text);
613
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);
618 }
619
620 int wxListBox::Number () const
621 {
622 return m_noItems;
623 }
624
625 // For single selection items only
626 wxString wxListBox::GetStringSelection () const
627 {
628 wxString res;
629 int sel = GetSelection();
630 if (sel > -1)
631 res = GetString(sel);
632
633 return res;
634 }
635
636 bool wxListBox::SetStringSelection (const wxString& s, bool flag)
637 {
638 int sel = FindString (s);
639 if (sel > -1)
640 {
641 SetSelection (sel, flag);
642 return TRUE;
643 }
644 else
645 return FALSE;
646 }
647
648 void wxListBox::Command (wxCommandEvent & event)
649 {
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
660 void wxListBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
661 XmListCallbackStruct * cbs)
662 {
663 /*
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";
679 */
680
681 wxListBox *item = (wxListBox *) clientData;
682
683 if (item->InSetValue())
684 return;
685
686 wxCommandEvent event (wxEVT_COMMAND_LISTBOX_SELECTED, item->GetId());
687 switch (cbs->reason)
688 {
689 case XmCR_MULTIPLE_SELECT:
690 case XmCR_BROWSE_SELECT:
691 {
692 event.m_clientData = item->GetClientData (cbs->item_position - 1);
693 event.m_commandInt = cbs->item_position - 1;
694 event.m_extraLong = TRUE;
695 event.SetEventObject(item);
696 item->ProcessCommand (event);
697 break;
698 }
699 case XmCR_EXTENDED_SELECT:
700 {
701 switch (cbs->selection_type)
702 {
703 case XmINITIAL:
704 case XmADDITION:
705 case XmMODIFICATION:
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 }
717 }
718 }
719
720 /* Respond by getting the
721 * designated "default button" in the action area and activate it
722 * as if the user had selected it.
723 */
724 void wxListBoxDefaultActionProc (Widget WXUNUSED(list_w), XtPointer client_data, XmListCallbackStruct * WXUNUSED(cbs))
725 {
726 wxListBox *lbox = (wxListBox *) client_data;
727
728 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, lbox->GetId());
729 event.SetEventObject( lbox );
730 lbox->GetEventHandler()->ProcessEvent(event) ;
731 }
732
733 WXWidget wxListBox::GetTopWidget() const
734 {
735 return (WXWidget) XtParent( (Widget) m_mainWidget );
736 }
737
738 void wxListBox::ChangeFont(bool keepOriginalSize)
739 {
740 wxWindow::ChangeFont(keepOriginalSize);
741 }
742
743 void wxListBox::ChangeBackgroundColour()
744 {
745 wxWindow::ChangeBackgroundColour();
746
747 Widget parent = XtParent ((Widget) m_mainWidget);
748 Widget hsb, vsb;
749
750 XtVaGetValues (parent,
751 XmNhorizontalScrollBar, &hsb,
752 XmNverticalScrollBar, &vsb,
753 NULL);
754
755 /* TODO: should scrollbars be affected? Should probably have separate
756 * function to change them (by default, taken from wxSystemSettings)
757 */
758 wxColour backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE);
759 DoChangeBackgroundColour((WXWidget) hsb, backgroundColour, TRUE);
760 DoChangeBackgroundColour((WXWidget) vsb, backgroundColour, TRUE);
761
762 XtVaSetValues (hsb,
763 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
764 NULL);
765 XtVaSetValues (vsb,
766 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
767 NULL);
768
769 DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, TRUE);
770 }
771
772 void wxListBox::ChangeForegroundColour()
773 {
774 wxWindow::ChangeForegroundColour();
775
776 Widget parent = XtParent ((Widget) m_mainWidget);
777 Widget hsb, vsb;
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
787 DoChangeForegroundColour((WXWidget) hsb, m_foregroundColour);
788 DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour);
789 DoChangeForegroundColour((WXWidget) parent, m_foregroundColour);
790 */
791 }
792
793 // These implement functions needed by wxControlWithItems.
794 // Unfortunately, they're not all implemented yet.
795
796 int wxListBox::GetCount() const
797 {
798 return Number();
799 }
800
801 int wxListBox::DoAppend(const wxString& item)
802 {
803 Append(item, (void*) NULL);
804 return GetCount() - 1;
805 }
806
807 // Just appends, doesn't yet insert
808 void 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
818 void 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
832 void wxListBox::DoSetFirstItem(int WXUNUSED(n))
833 {
834 wxFAIL_MSG( wxT("wxListBox::DoSetFirstItem not implemented") );
835 }
836
837 void wxListBox::DoSetItemClientData(int n, void* clientData)
838 {
839 SetClientData(n, clientData);
840 }
841
842 void* wxListBox::DoGetItemClientData(int n) const
843 {
844 return GetClientData(n);
845 }
846
847 void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
848 {
849 DoSetItemClientData(n, (void*) clientData);
850 }
851
852 wxClientData* wxListBox::DoGetItemClientObject(int n) const
853 {
854 return (wxClientData*) DoGetItemClientData(n);
855 }
856
857 void wxListBox::Select(int n)
858 {
859 SetSelection(n, TRUE);
860 }