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