]> git.saurik.com Git - wxWidgets.git/blame - src/motif/listbox.cpp
added wxCURSOR_RIGHT_ARROW to wxMGL
[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
4dff3400
JJ
16#ifdef __VMS
17#define XtParent XTPARENT
18#define XtDisplay XTDISPLAY
19#endif
20
21# include "wx/listbox.h"
4bb6408c
JS
22#include "wx/settings.h"
23#include "wx/dynarray.h"
24#include "wx/log.h"
f97c9854
JS
25#include "wx/utils.h"
26
338dd992
JJ
27#ifdef __VMS__
28#pragma message disable nosimpint
29#endif
f97c9854 30#include <Xm/List.h>
338dd992
JJ
31#ifdef __VMS__
32#pragma message enable nosimpint
33#endif
f97c9854 34#include "wx/motif/private.h"
4bb6408c 35
29006414 36 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
4bb6408c 37
29006414
VZ
38static void wxListBoxCallback(Widget w,
39 XtPointer clientData,
40 XmListCallbackStruct * cbs);
f97c9854 41
29006414
VZ
42static void wxListBoxDefaultActionProc(Widget list_w,
43 XtPointer client_data,
44 XmListCallbackStruct * cbs);
f97c9854 45
4bb6408c
JS
46// ============================================================================
47// list box control implementation
48// ============================================================================
49
50// Listbox item
29006414 51wxListBox::wxListBox() : m_clientDataList(wxKEY_INTEGER)
4bb6408c 52{
f97c9854
JS
53 m_noItems = 0;
54 m_selected = 0;
4bb6408c
JS
55}
56
57bool 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{
f97c9854
JS
65 m_windowStyle = style;
66 m_noItems = n;
67 m_selected = 0;
94b49b93
JS
68 // m_backgroundColour = parent->GetBackgroundColour();
69 m_backgroundColour = * wxWHITE;
0d57be45 70 m_foregroundColour = parent->GetForegroundColour();
29006414 71
f97c9854
JS
72 SetName(name);
73 SetValidator(validator);
29006414 74
f97c9854 75 if (parent) parent->AddChild(this);
29006414 76
f97c9854 77 m_windowId = ( id == -1 ) ? (int)NewControlId() : id;
29006414 78
f97c9854 79 Widget parentWidget = (Widget) parent->GetClientWidget();
29006414 80
f97c9854
JS
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;
29006414 97
f97c9854 98 Widget listWidget = XmCreateScrolledList (parentWidget, (char*) (const char*) name, args, count);
29006414 99
f97c9854 100 m_mainWidget = (WXWidget) listWidget;
29006414 101
a4294b78 102 Set(n, choices);
29006414 103
f97c9854 104 XtManageChild (listWidget);
29006414 105
f97c9854
JS
106 long width = size.x;
107 long height = size.y;
108 if (width == -1)
109 width = 150;
110 if (height == -1)
111 height = 80;
29006414 112
f97c9854 113 XtAddCallback (listWidget, XmNbrowseSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 114 (XtPointer) this);
f97c9854 115 XtAddCallback (listWidget, XmNextendedSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 116 (XtPointer) this);
f97c9854 117 XtAddCallback (listWidget, XmNmultipleSelectionCallback, (XtCallbackProc) wxListBoxCallback,
2d120f83 118 (XtPointer) this);
29006414 119
f97c9854 120 XtAddCallback (listWidget, XmNdefaultActionCallback, (XtCallbackProc) wxListBoxDefaultActionProc,
2d120f83 121 (XtPointer) this);
29006414 122
da175b2c 123 m_font = parent->GetFont();
4b5f3fe6 124 ChangeFont(FALSE);
29006414 125
15d5ab67 126 SetCanAddEventHandler(TRUE);
f97c9854 127 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, width, height);
29006414 128
0d57be45 129 ChangeBackgroundColour();
29006414 130
f97c9854 131 return TRUE;
4bb6408c
JS
132}
133
134wxListBox::~wxListBox()
135{
136}
137
138void wxListBox::SetFirstItem(int N)
139{
2d120f83 140 int count, length;
29006414 141
2d120f83
JS
142 if (N < 0)
143 return;
144 XtVaGetValues ((Widget) m_mainWidget,
29006414
VZ
145 XmNvisibleItemCount, &count,
146 XmNitemCount, &length,
147 NULL);
2d120f83
JS
148 if ((N + count) >= length)
149 N = length - count;
150 XmListSetPos ((Widget) m_mainWidget, N + 1);
4bb6408c
JS
151}
152
153void wxListBox::SetFirstItem(const wxString& s)
154{
2d120f83 155 int N = FindString (s);
29006414 156
2d120f83
JS
157 if (N >= 0)
158 SetFirstItem (N);
4bb6408c
JS
159}
160
161void wxListBox::Delete(int N)
162{
2d120f83
JS
163 int width1, height1;
164 int width2, height2;
165 Widget listBox = (Widget) m_mainWidget;
166 GetSize (&width1, &height1);
29006414 167
2d120f83 168 bool managed = XtIsManaged(listBox);
29006414 169
2d120f83
JS
170 if (managed)
171 XtUnmanageChild (listBox);
29006414 172
2d120f83 173 XmListDeletePos (listBox, N + 1);
29006414 174
2d120f83
JS
175 if (managed)
176 XtManageChild (listBox);
29006414 177
2d120f83
JS
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);
29006414 182
2d120f83
JS
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
29006414
VZ
188 {
189 if (node->GetKeyInteger() >= (long)(N+1))
190 node->SetKeyInteger(node->GetKeyInteger() - 1);
191 node = node->Next();
2d120f83 192 }
29006414 193
2d120f83 194 m_noItems --;
4bb6408c
JS
195}
196
197void wxListBox::Append(const wxString& item)
198{
2d120f83
JS
199 int width1, height1;
200 int width2, height2;
29006414 201
2d120f83
JS
202 Widget listBox = (Widget) m_mainWidget;
203 GetSize (&width1, &height1);
29006414 204
2d120f83 205 bool managed = XtIsManaged(listBox);
29006414 206
2d120f83
JS
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);
29006414 215
2d120f83
JS
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);
29006414 227
2d120f83
JS
228 if (managed)
229 XtManageChild (listBox);
29006414 230
2d120f83
JS
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 ++;
4bb6408c
JS
236}
237
813c20a6 238void wxListBox::Append(const wxString& item, void *clientData)
4bb6408c 239{
2d120f83
JS
240 int width1, height1;
241 int width2, height2;
29006414 242
2d120f83 243 Widget listBox = (Widget) m_mainWidget;
29006414 244
2d120f83
JS
245 GetSize (&width1, &height1);
246 Bool managed = XtIsManaged(listBox);
29006414 247
2d120f83
JS
248 if (managed)
249 XtUnmanageChild (listBox);
29006414 250
2d120f83
JS
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);
29006414 257
2d120f83
JS
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);
29006414 269
2d120f83 270 m_clientDataList.Append ((long) n, (wxObject *) clientData);
29006414 271
2d120f83
JS
272 if (managed)
273 XtManageChild (listBox);
29006414 274
2d120f83 275 GetSize (&width2, &height2);
29006414 276
2d120f83
JS
277 // Correct for randomly resized listbox - bad boy, Motif!
278 if (width1 != width2 || height1 != height2)
279 SetSize (-1, -1, width1, height1);
29006414 280
2d120f83 281 m_noItems ++;
4bb6408c
JS
282}
283
813c20a6 284void wxListBox::Set(int n, const wxString *choices, void** clientData)
4bb6408c 285{
2d120f83
JS
286 m_clientDataList.Clear();
287 int width1, height1;
288 int width2, height2;
29006414 289
2d120f83
JS
290 Widget listBox = (Widget) m_mainWidget;
291 GetSize (&width1, &height1);
29006414 292
2d120f83 293 bool managed = XtIsManaged(listBox);
29006414 294
2d120f83
JS
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;
f97c9854 307 for (i = 0; i < n; i++)
2d120f83 308 text[i] = XmStringCreateSimple ((char*) (const char*) choices[i]);
29006414 309
2d120f83
JS
310 if ( clientData )
311 for (i = 0; i < n; i++)
312 m_clientDataList.Append ((long) i, (wxObject *) clientData[i]);
29006414 313
2d120f83
JS
314 XmListAddItems (listBox, text, n, 0);
315 for (i = 0; i < n; i++)
316 XmStringFree (text[i]);
317 delete[]text;
29006414 318
2d120f83
JS
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);
29006414 330
2d120f83
JS
331 if (managed)
332 XtManageChild (listBox);
29006414 333
2d120f83
JS
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);
29006414 338
2d120f83 339 m_noItems = n;
4bb6408c
JS
340}
341
342int wxListBox::FindString(const wxString& s) const
343{
2d120f83
JS
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)
f97c9854 350 {
2d120f83
JS
351 int pos = positions[0];
352 if (positions)
353 XtFree ((char *) positions);
354 return pos - 1;
f97c9854 355 }
2d120f83
JS
356 else
357 return -1;
4bb6408c
JS
358}
359
360void wxListBox::Clear()
361{
2d120f83
JS
362 if (m_noItems <= 0)
363 return;
29006414 364
2d120f83
JS
365 int width1, height1;
366 int width2, height2;
29006414 367
2d120f83
JS
368 Widget listBox = (Widget) m_mainWidget;
369 GetSize (&width1, &height1);
29006414 370
2d120f83
JS
371 XmListDeleteAllItems (listBox);
372 m_clientDataList.Clear ();
373 GetSize (&width2, &height2);
29006414 374
2d120f83
JS
375 // Correct for randomly resized listbox - bad boy, Motif!
376 if (width1 != width2 || height1 != height2)
377 SetSize (-1, -1, width1, height1);
29006414 378
2d120f83 379 m_noItems = 0;
4bb6408c
JS
380}
381
382void wxListBox::SetSelection(int N, bool select)
383{
2d120f83
JS
384 m_inSetValue = TRUE;
385 if (select)
f97c9854 386 {
29006414
VZ
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
2d120f83 408 XmListSelectPos ((Widget) m_mainWidget, N + 1, FALSE);
29006414 409
f97c9854 410 }
2d120f83
JS
411 else
412 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
29006414 413
2d120f83 414 m_inSetValue = FALSE;
4bb6408c
JS
415}
416
d7d38ea4 417bool wxListBox::IsSelected(int N) const
4bb6408c 418{
2d120f83
JS
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 }
4bb6408c
JS
431 return FALSE;
432}
433
434void wxListBox::Deselect(int N)
435{
f97c9854 436 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
4bb6408c
JS
437}
438
813c20a6 439void *wxListBox::GetClientData(int N) const
4bb6408c 440{
f97c9854
JS
441 wxNode *node = m_clientDataList.Find ((long) N);
442 if (node)
813c20a6 443 return (void *) node->Data ();
f97c9854
JS
444 else
445 return NULL;
4bb6408c
JS
446}
447
813c20a6 448void wxListBox::SetClientData(int N, void *Client_data)
4bb6408c 449{
f97c9854
JS
450 wxNode *node = m_clientDataList.Find ((long) N);
451 if (node)
452 node->SetData ((wxObject *)Client_data);
a4294b78
JS
453 else
454 node = m_clientDataList.Append((long) N, (wxObject*) Client_data);
4bb6408c
JS
455}
456
457// Return number of selections and an array of selected integers
458int wxListBox::GetSelections(wxArrayInt& aSelections) const
459{
2d120f83 460 aSelections.Empty();
29006414 461
2d120f83
JS
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);
29006414 471
2d120f83
JS
472 int i;
473 for (i = 0; i < posCnt; i++)
474 aSelections.Add(posList[i] - 1);
29006414 475
2d120f83
JS
476 XtFree ((char *) posList);
477 return posCnt;
478 }
479 else
480 return 0;
4bb6408c 481 }
2d120f83
JS
482 else
483 return 0;
4bb6408c
JS
484}
485
486// Get single selection, for single choice list items
487int wxListBox::GetSelection() const
488{
f97c9854
JS
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;
4bb6408c
JS
503}
504
505// Find string for position
506wxString wxListBox::GetString(int N) const
507{
f97c9854
JS
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;
4bb6408c
JS
526}
527
bfc6fde4 528void wxListBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
4bb6408c 529{
bfc6fde4 530 wxWindow::DoSetSize(x, y, width, height, sizeFlags);
29006414 531
f97c9854
JS
532 // Check resulting size is correct
533 int tempW, tempH;
534 GetSize (&tempW, &tempH);
29006414 535
89c7e962
JS
536 /*
537 if (tempW != width || tempH != height)
538 {
2d120f83 539 cout << "wxListBox::SetSize sizes not set correctly.");
89c7e962
JS
540 }
541 */
4bb6408c
JS
542}
543
544void wxListBox::InsertItems(int nItems, const wxString items[], int pos)
545{
f97c9854
JS
546 int width1, height1;
547 int width2, height2;
29006414 548
f97c9854 549 Widget listBox = (Widget) m_mainWidget;
29006414 550
f97c9854 551 GetSize(&width1, &height1);
29006414 552
f97c9854 553 bool managed = XtIsManaged(listBox);
29006414 554
f97c9854
JS
555 if (managed)
556 XtUnmanageChild(listBox);
29006414 557
f97c9854
JS
558 XmString *text = new XmString[nItems];
559 int i;
2d120f83
JS
560 // Steve Hammes: Motif 1.1 compatibility
561 // #if XmVersion > 1100
562 // Corrected by Sergey Krasnov from Steve Hammes' code
f97c9854
JS
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]);
2d120f83 571 // XmListAddItemUnselected(listBox, text[i], i);
f97c9854
JS
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]);
29006414 577
f97c9854 578 delete[] text;
29006414 579
f97c9854
JS
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) ;
29006414 590
f97c9854
JS
591 if (managed)
592 XtManageChild(listBox);
29006414 593
f97c9854
JS
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);
29006414 598
f97c9854 599 m_noItems += nItems;
4bb6408c
JS
600}
601
602void wxListBox::SetString(int N, const wxString& s)
603{
f97c9854
JS
604 int width1, height1;
605 int width2, height2;
29006414 606
f97c9854
JS
607 Widget listBox = (Widget) m_mainWidget;
608 GetSize (&width1, &height1);
29006414 609
f97c9854 610 XmString text = XmStringCreateSimple ((char*) (const char*) s);
29006414
VZ
611
612 // delete the item and add it again.
613 // FIXME isn't there a way to change it in place?
f97c9854
JS
614 XmListDeletePos (listBox, N+1);
615 XmListAddItem (listBox, text, N+1);
29006414 616
f97c9854 617 XmStringFree(text);
29006414 618
f97c9854
JS
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);
4bb6408c
JS
623}
624
625int wxListBox::Number () const
626{
f97c9854 627 return m_noItems;
4bb6408c
JS
628}
629
630// For single selection items only
631wxString wxListBox::GetStringSelection () const
632{
29006414
VZ
633 wxString res;
634 int sel = GetSelection();
f97c9854 635 if (sel > -1)
29006414
VZ
636 res = GetString(sel);
637
638 return res;
4bb6408c
JS
639}
640
641bool wxListBox::SetStringSelection (const wxString& s, bool flag)
642{
f97c9854
JS
643 int sel = FindString (s);
644 if (sel > -1)
4bb6408c 645 {
f97c9854
JS
646 SetSelection (sel, flag);
647 return TRUE;
4bb6408c 648 }
f97c9854
JS
649 else
650 return FALSE;
4bb6408c
JS
651}
652
653void wxListBox::Command (wxCommandEvent & event)
654{
f97c9854
JS
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
af111fc3 665void wxListBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
2d120f83 666 XmListCallbackStruct * cbs)
f97c9854 667{
29006414 668 /*
f97c9854
JS
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";
2d120f83 684 */
29006414 685
f97c9854 686 wxListBox *item = (wxListBox *) clientData;
29006414 687
a4294b78 688 if (item->InSetValue())
f97c9854 689 return;
29006414 690
b412f9be 691 wxCommandEvent event (wxEVT_COMMAND_LISTBOX_SELECTED, item->GetId());
f97c9854 692 switch (cbs->reason)
4bb6408c 693 {
2d120f83
JS
694 case XmCR_MULTIPLE_SELECT:
695 case XmCR_BROWSE_SELECT:
f97c9854
JS
696 {
697 event.m_clientData = item->GetClientData (cbs->item_position - 1);
f97c9854
JS
698 event.m_commandInt = cbs->item_position - 1;
699 event.m_extraLong = TRUE;
700 event.SetEventObject(item);
701 item->ProcessCommand (event);
f97c9854
JS
702 break;
703 }
2d120f83 704 case XmCR_EXTENDED_SELECT:
f97c9854
JS
705 {
706 switch (cbs->selection_type)
707 {
2d120f83
JS
708 case XmINITIAL:
709 case XmADDITION:
710 case XmMODIFICATION:
f97c9854
JS
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 }
4bb6408c 722 }
4bb6408c
JS
723}
724
f97c9854 725/* Respond by getting the
2d120f83
JS
726* designated "default button" in the action area and activate it
727* as if the user had selected it.
728*/
af111fc3 729void wxListBoxDefaultActionProc (Widget WXUNUSED(list_w), XtPointer client_data, XmListCallbackStruct * WXUNUSED(cbs))
f97c9854
JS
730{
731 wxListBox *lbox = (wxListBox *) client_data;
29006414 732
f97c9854
JS
733 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, lbox->GetId());
734 event.SetEventObject( lbox );
735 lbox->GetEventHandler()->ProcessEvent(event) ;
736}
737
89c7e962
JS
738WXWidget wxListBox::GetTopWidget() const
739{
2d120f83 740 return (WXWidget) XtParent( (Widget) m_mainWidget );
89c7e962 741}
0d57be45 742
4b5f3fe6 743void wxListBox::ChangeFont(bool keepOriginalSize)
0d57be45 744{
4b5f3fe6 745 wxWindow::ChangeFont(keepOriginalSize);
0d57be45
JS
746}
747
748void wxListBox::ChangeBackgroundColour()
749{
321db4b6 750 wxWindow::ChangeBackgroundColour();
29006414 751
02800301
JS
752 Widget parent = XtParent ((Widget) m_mainWidget);
753 Widget hsb, vsb;
29006414 754
02800301 755 XtVaGetValues (parent,
2d120f83
JS
756 XmNhorizontalScrollBar, &hsb,
757 XmNverticalScrollBar, &vsb,
758 NULL);
29006414 759
a91b47e8
JS
760 /* TODO: should scrollbars be affected? Should probably have separate
761 * function to change them (by default, taken from wxSystemSettings)
2d120f83 762 */
a756f210 763 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
94b49b93
JS
764 DoChangeBackgroundColour((WXWidget) hsb, backgroundColour, TRUE);
765 DoChangeBackgroundColour((WXWidget) vsb, backgroundColour, TRUE);
15d5ab67
JS
766
767 XtVaSetValues (hsb,
768 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
769 NULL);
770 XtVaSetValues (vsb,
771 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
772 NULL);
29006414 773
02800301 774 DoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, TRUE);
0d57be45
JS
775}
776
777void wxListBox::ChangeForegroundColour()
778{
321db4b6 779 wxWindow::ChangeForegroundColour();
29006414 780
02800301
JS
781 Widget parent = XtParent ((Widget) m_mainWidget);
782 Widget hsb, vsb;
29006414
VZ
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
2d120f83
JS
792 DoChangeForegroundColour((WXWidget) hsb, m_foregroundColour);
793 DoChangeForegroundColour((WXWidget) vsb, m_foregroundColour);
794 DoChangeForegroundColour((WXWidget) parent, m_foregroundColour);
02800301 795 */
0d57be45
JS
796}
797
6adaedf0
JS
798// These implement functions needed by wxControlWithItems.
799// Unfortunately, they're not all implemented yet.
02800301 800
6adaedf0
JS
801int wxListBox::GetCount() const
802{
803 return Number();
804}
805
806int wxListBox::DoAppend(const wxString& item)
807{
808 Append(item, (void*) NULL);
809 return GetCount() - 1;
810}
811
812// Just appends, doesn't yet insert
813void 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
823void 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
837void wxListBox::DoSetFirstItem(int WXUNUSED(n))
838{
839 wxFAIL_MSG( wxT("wxListBox::DoSetFirstItem not implemented") );
840}
841
842void wxListBox::DoSetItemClientData(int n, void* clientData)
843{
844 SetClientData(n, clientData);
845}
846
847void* wxListBox::DoGetItemClientData(int n) const
848{
849 return GetClientData(n);
850}
851
852void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
853{
854 DoSetItemClientData(n, (void*) clientData);
855}
856
857wxClientData* wxListBox::DoGetItemClientObject(int n) const
858{
859 return (wxClientData*) DoGetItemClientData(n);
860}
861
862void wxListBox::Select(int n)
863{
864 SetSelection(n, TRUE);
865}