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