]> git.saurik.com Git - wxWidgets.git/blame - src/motif/listbox.cpp
re-renamed DoCreate() to XmDoCreateTLW() to avoid virtual function hiding in other...
[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
65571936 9// Licence: wxWindows licence
4bb6408c
JS
10///////////////////////////////////////////////////////////////////////////////
11
1248b41f
MB
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
4dff3400
JJ
15#ifdef __VMS
16#define XtParent XTPARENT
17#define XtDisplay XTDISPLAY
18#endif
19
20# include "wx/listbox.h"
4bb6408c
JS
21#include "wx/settings.h"
22#include "wx/dynarray.h"
23#include "wx/log.h"
f97c9854 24#include "wx/utils.h"
584ad2a3 25#include "wx/arrstr.h"
f97c9854 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
99ab3e3f
MB
42// ----------------------------------------------------------------------------
43// wxSizeKeeper
44// ----------------------------------------------------------------------------
45
46// helper class to reduce code duplication
47class wxSizeKeeper
48{
49 int m_x, m_y;
50 wxWindow* m_w;
51public:
52 wxSizeKeeper( wxWindow* w )
53 : m_w( w )
54 {
55 m_w->GetSize( &m_x, &m_y );
56 }
57
58 void Restore()
59 {
60 int x, y;
61
62 m_w->GetSize( &x, &y );
63 if( x != m_x || y != m_y )
64 m_w->SetSize( -1, -1, m_x, m_y );
65 }
66};
67
4bb6408c
JS
68// ============================================================================
69// list box control implementation
70// ============================================================================
71
72// Listbox item
99ab3e3f 73wxListBox::wxListBox()
4bb6408c 74{
f97c9854 75 m_noItems = 0;
4bb6408c
JS
76}
77
78bool wxListBox::Create(wxWindow *parent, wxWindowID id,
79 const wxPoint& pos,
80 const wxSize& size,
81 int n, const wxString choices[],
82 long style,
83 const wxValidator& validator,
84 const wxString& name)
85{
99ab3e3f
MB
86 if( !wxControl::CreateControl( parent, id, pos, size, style,
87 validator, name ) )
96be256b 88 return false;
99ab3e3f 89
f97c9854 90 m_noItems = n;
94b49b93 91 m_backgroundColour = * wxWHITE;
29006414 92
f97c9854 93 Widget parentWidget = (Widget) parent->GetClientWidget();
73608949 94 Display* dpy = XtDisplay(parentWidget);
e1aae528
MB
95
96 Arg args[4];
99ab3e3f 97 int count = 0;
e1aae528
MB
98 XtSetArg( args[count], XmNlistSizePolicy, XmCONSTANT ); ++count;
99 XtSetArg( args[count], XmNselectionPolicy,
99ab3e3f
MB
100 ( m_windowStyle & wxLB_MULTIPLE ) ? XmMULTIPLE_SELECT :
101 ( m_windowStyle & wxLB_EXTENDED ) ? XmEXTENDED_SELECT :
102 XmBROWSE_SELECT );
103 ++count;
73608949 104 if( m_font.Ok() )
e1aae528 105 {
73608949
MB
106 XtSetArg( args[count],
107 (String)wxFont::GetFontTag(), m_font.GetFontTypeC(dpy) );
e1aae528
MB
108 ++count;
109 }
99ab3e3f 110 if( m_windowStyle & wxLB_ALWAYS_SB )
f97c9854 111 {
e1aae528 112 XtSetArg( args[count], XmNscrollBarDisplayPolicy, XmSTATIC );
99ab3e3f 113 ++count;
f97c9854 114 }
29006414 115
d3a80c92
MB
116 Widget listWidget =
117 XmCreateScrolledList(parentWidget,
118 wxConstCast(name.c_str(), char), args, count);
29006414 119
f97c9854 120 m_mainWidget = (WXWidget) listWidget;
29006414 121
a4294b78 122 Set(n, choices);
29006414 123
f97c9854 124 XtManageChild (listWidget);
29006414 125
e1aae528
MB
126 wxSize best = GetBestSize();
127 if( size.x != -1 ) best.x = size.x;
128 if( size.y != -1 ) best.y = size.y;
29006414 129
ef41d80c
MB
130 XtAddCallback (listWidget,
131 XmNbrowseSelectionCallback,
132 (XtCallbackProc) wxListBoxCallback,
133 (XtPointer) this);
134 XtAddCallback (listWidget,
135 XmNextendedSelectionCallback,
136 (XtCallbackProc) wxListBoxCallback,
137 (XtPointer) this);
138 XtAddCallback (listWidget,
139 XmNmultipleSelectionCallback,
140 (XtCallbackProc) wxListBoxCallback,
141 (XtPointer) this);
142 XtAddCallback (listWidget,
143 XmNdefaultActionCallback,
144 (XtCallbackProc) wxListBoxCallback,
145 (XtPointer) this);
29006414 146
ef41d80c 147 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
e1aae528 148 pos.x, pos.y, best.x, best.y);
29006414 149
0d57be45 150 ChangeBackgroundColour();
29006414 151
96be256b 152 return true;
4bb6408c
JS
153}
154
584ad2a3
MB
155bool wxListBox::Create(wxWindow *parent, wxWindowID id,
156 const wxPoint& pos,
157 const wxSize& size,
158 const wxArrayString& choices,
159 long style,
160 const wxValidator& validator,
161 const wxString& name)
162{
163 wxCArrayString chs(choices);
164 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
165 style, validator, name);
166}
167
4bb6408c
JS
168wxListBox::~wxListBox()
169{
99ab3e3f
MB
170 if( HasClientObjectData() )
171 m_clientDataDict.DestroyData();
172}
173
174void wxListBox::SetSelectionPolicy()
175{
176 Widget listBox = (Widget)m_mainWidget;
177 Arg args[3];
178
179 XtSetArg( args[0], XmNlistSizePolicy, XmCONSTANT );
180
181 XtSetArg( args[1], XmNselectionPolicy,
182 ( m_windowStyle & wxLB_MULTIPLE ) ? XmMULTIPLE_SELECT :
183 ( m_windowStyle & wxLB_EXTENDED ) ? XmEXTENDED_SELECT :
184 XmBROWSE_SELECT );
185
186 XtSetValues( listBox, args, 2 );
4bb6408c
JS
187}
188
ef41d80c 189void wxListBox::DoSetFirstItem( int N )
4bb6408c 190{
2d120f83 191 int count, length;
29006414 192
2d120f83
JS
193 if (N < 0)
194 return;
195 XtVaGetValues ((Widget) m_mainWidget,
29006414
VZ
196 XmNvisibleItemCount, &count,
197 XmNitemCount, &length,
198 NULL);
2d120f83
JS
199 if ((N + count) >= length)
200 N = length - count;
201 XmListSetPos ((Widget) m_mainWidget, N + 1);
4bb6408c
JS
202}
203
4bb6408c
JS
204void wxListBox::Delete(int N)
205{
99ab3e3f 206 wxSizeKeeper sk( this );
2d120f83 207 Widget listBox = (Widget) m_mainWidget;
29006414 208
2d120f83 209 bool managed = XtIsManaged(listBox);
29006414 210
2d120f83
JS
211 if (managed)
212 XtUnmanageChild (listBox);
29006414 213
2d120f83 214 XmListDeletePos (listBox, N + 1);
29006414 215
2d120f83
JS
216 if (managed)
217 XtManageChild (listBox);
29006414 218
99ab3e3f
MB
219 sk.Restore();
220 m_clientDataDict.Delete(N, HasClientObjectData());
2d120f83 221 m_noItems --;
4bb6408c
JS
222}
223
ef41d80c 224int wxListBox::DoAppend(const wxString& item)
4bb6408c 225{
99ab3e3f 226 wxSizeKeeper sk( this );
2d120f83 227 Widget listBox = (Widget) m_mainWidget;
29006414 228
2d120f83 229 bool managed = XtIsManaged(listBox);
29006414 230
2d120f83
JS
231 if (managed)
232 XtUnmanageChild (listBox);
233 int n;
234 XtVaGetValues (listBox, XmNitemCount, &n, NULL);
99ab3e3f 235 wxXmString text( item );
2d120f83 236 // XmListAddItem(listBox, text, n + 1);
99ab3e3f 237 XmListAddItemUnselected (listBox, text(), 0);
29006414 238
2d120f83
JS
239 // It seems that if the list is cleared, we must re-ask for
240 // selection policy!!
99ab3e3f 241 SetSelectionPolicy();
29006414 242
2d120f83
JS
243 if (managed)
244 XtManageChild (listBox);
29006414 245
99ab3e3f 246 sk.Restore();
2d120f83 247 m_noItems ++;
ef41d80c
MB
248
249 return GetCount() - 1;
4bb6408c
JS
250}
251
ef41d80c 252void wxListBox::DoSetItems(const wxArrayString& items, void** clientData)
4bb6408c 253{
99ab3e3f 254 wxSizeKeeper sk( this );
2d120f83 255 Widget listBox = (Widget) m_mainWidget;
99ab3e3f
MB
256
257 if( HasClientObjectData() )
258 m_clientDataDict.DestroyData();
ef41d80c
MB
259
260 bool managed = XtIsManaged(listBox);
29006414 261
2d120f83
JS
262 if (managed)
263 XtUnmanageChild (listBox);
ef41d80c
MB
264 XmString *text = new XmString[items.GetCount()];
265 size_t i;
266 for (i = 0; i < items.GetCount(); ++i)
d3a80c92 267 text[i] = wxStringToXmString (items[i]);
29006414 268
ef41d80c
MB
269 if ( clientData )
270 for (i = 0; i < items.GetCount(); ++i)
96be256b 271 m_clientDataDict.Set(i, (wxClientData*)clientData[i], false);
ef41d80c
MB
272
273 XmListAddItems (listBox, text, items.GetCount(), 0);
274 for (i = 0; i < items.GetCount(); i++)
275 XmStringFree (text[i]);
276 delete[] text;
29006414 277
2d120f83
JS
278 // It seems that if the list is cleared, we must re-ask for
279 // selection policy!!
99ab3e3f 280 SetSelectionPolicy();
29006414 281
2d120f83
JS
282 if (managed)
283 XtManageChild (listBox);
29006414 284
99ab3e3f 285 sk.Restore();
29006414 286
ef41d80c 287 m_noItems = items.GetCount();
4bb6408c
JS
288}
289
9b1bd0c6 290int wxDoFindStringInList(Widget w, const wxString& s)
4bb6408c 291{
99ab3e3f 292 wxXmString str( s );
2d120f83
JS
293 int *positions = NULL;
294 int no_positions = 0;
9b1bd0c6 295 bool success = XmListGetMatchPos (w, str(),
ef41d80c 296 &positions, &no_positions);
99ab3e3f 297
2d120f83 298 if (success)
f97c9854 299 {
2d120f83
JS
300 int pos = positions[0];
301 if (positions)
302 XtFree ((char *) positions);
303 return pos - 1;
f97c9854 304 }
2d120f83
JS
305 else
306 return -1;
4bb6408c
JS
307}
308
9b1bd0c6
MB
309int wxListBox::FindString(const wxString& s) const
310{
311 return wxDoFindStringInList( (Widget)m_mainWidget, s );
312}
313
4bb6408c
JS
314void wxListBox::Clear()
315{
2d120f83
JS
316 if (m_noItems <= 0)
317 return;
29006414 318
99ab3e3f 319 wxSizeKeeper sk( this );
2d120f83 320 Widget listBox = (Widget) m_mainWidget;
29006414 321
2d120f83 322 XmListDeleteAllItems (listBox);
99ab3e3f
MB
323 if( HasClientObjectData() )
324 m_clientDataDict.DestroyData();
29006414 325
99ab3e3f 326 sk.Restore();
29006414 327
2d120f83 328 m_noItems = 0;
4bb6408c
JS
329}
330
c6179a84 331void wxListBox::DoSetSelection(int N, bool select)
4bb6408c 332{
96be256b 333 m_inSetValue = true;
2d120f83 334 if (select)
f97c9854 335 {
29006414
VZ
336#if 0
337 if (m_windowStyle & wxLB_MULTIPLE)
338 {
339 int *selections = NULL;
340 int n = GetSelections (&selections);
341
ef41d80c
MB
342 // This hack is supposed to work, to make it possible
343 // to select more than one item, but it DOESN'T under Motif 1.1.
29006414 344
ef41d80c
MB
345 XtVaSetValues ((Widget) m_mainWidget,
346 XmNselectionPolicy, XmMULTIPLE_SELECT,
347 NULL);
29006414
VZ
348
349 int i;
350 for (i = 0; i < n; i++)
ef41d80c 351 XmListSelectPos ((Widget) m_mainWidget,
96be256b 352 selections[i] + 1, False);
29006414 353
96be256b 354 XmListSelectPos ((Widget) m_mainWidget, N + 1, False);
29006414 355
ef41d80c
MB
356 XtVaSetValues ((Widget) m_mainWidget,
357 XmNselectionPolicy, XmEXTENDED_SELECT,
358 NULL);
29006414
VZ
359 }
360 else
361#endif // 0
96be256b 362 XmListSelectPos ((Widget) m_mainWidget, N + 1, False);
29006414 363
f97c9854 364 }
2d120f83
JS
365 else
366 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
29006414 367
96be256b 368 m_inSetValue = false;
4bb6408c
JS
369}
370
d7d38ea4 371bool wxListBox::IsSelected(int N) const
4bb6408c 372{
2d120f83
JS
373 // In Motif, no simple way to determine if the item is selected.
374 wxArrayInt theSelections;
375 int count = GetSelections (theSelections);
376 if (count == 0)
96be256b 377 return false;
2d120f83
JS
378 else
379 {
380 int j;
381 for (j = 0; j < count; j++)
382 if (theSelections[j] == N)
96be256b 383 return true;
2d120f83 384 }
96be256b 385 return false;
4bb6408c
JS
386}
387
ef41d80c
MB
388void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
389{
96be256b 390 m_clientDataDict.Set(n, clientData, false);
ef41d80c
MB
391}
392
393wxClientData* wxListBox::DoGetItemClientObject(int n) const
4bb6408c 394{
99ab3e3f 395 return m_clientDataDict.Get(n);
4bb6408c
JS
396}
397
ef41d80c 398void *wxListBox::DoGetItemClientData(int N) const
4bb6408c 399{
99ab3e3f 400 return (void*)m_clientDataDict.Get(N);
4bb6408c
JS
401}
402
ef41d80c 403void wxListBox::DoSetItemClientData(int N, void *Client_data)
4bb6408c 404{
96be256b 405 m_clientDataDict.Set(N, (wxClientData*)Client_data, false);
4bb6408c
JS
406}
407
408// Return number of selections and an array of selected integers
409int wxListBox::GetSelections(wxArrayInt& aSelections) const
410{
2d120f83 411 aSelections.Empty();
29006414 412
2d120f83
JS
413 Widget listBox = (Widget) m_mainWidget;
414 int *posList = NULL;
415 int posCnt = 0;
416 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
417 if (flag)
418 {
419 if (posCnt > 0)
420 {
421 aSelections.Alloc(posCnt);
29006414 422
2d120f83
JS
423 int i;
424 for (i = 0; i < posCnt; i++)
425 aSelections.Add(posList[i] - 1);
29006414 426
2d120f83
JS
427 XtFree ((char *) posList);
428 return posCnt;
429 }
430 else
431 return 0;
4bb6408c 432 }
2d120f83
JS
433 else
434 return 0;
4bb6408c
JS
435}
436
437// Get single selection, for single choice list items
9b1bd0c6 438int wxDoGetSelectionInList(Widget listBox)
4bb6408c 439{
f97c9854
JS
440 int *posList = NULL;
441 int posCnt = 0;
442 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
443 if (flag)
444 {
445 int id = -1;
446 if (posCnt > 0)
447 id = posList[0] - 1;
448 XtFree ((char *) posList);
449 return id;
450 }
451 else
452 return -1;
4bb6408c
JS
453}
454
9b1bd0c6
MB
455int wxListBox::GetSelection() const
456{
457 return wxDoGetSelectionInList((Widget) m_mainWidget);
458}
459
4bb6408c 460// Find string for position
e1aae528 461wxString wxDoGetStringInList( Widget listBox, int n )
4bb6408c 462{
f97c9854 463 XmString *strlist;
e1aae528
MB
464 int count;
465 XtVaGetValues( listBox,
466 XmNitemCount, &count,
467 XmNitems, &strlist,
468 NULL );
d40708e2 469 if( n < count && n >= 0 )
e1aae528 470 return wxXmStringToString( strlist[n] );
f97c9854
JS
471 else
472 return wxEmptyString;
4bb6408c
JS
473}
474
e1aae528
MB
475wxString wxListBox::GetString( int n ) const
476{
477 return wxDoGetStringInList( (Widget)m_mainWidget, n );
478}
479
ef41d80c 480void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
4bb6408c 481{
99ab3e3f 482 wxSizeKeeper sk( this );
f97c9854 483 Widget listBox = (Widget) m_mainWidget;
29006414 484
f97c9854 485 bool managed = XtIsManaged(listBox);
29006414 486
f97c9854
JS
487 if (managed)
488 XtUnmanageChild(listBox);
29006414 489
ef41d80c
MB
490 XmString *text = new XmString[items.GetCount()];
491 size_t i;
2d120f83
JS
492 // Steve Hammes: Motif 1.1 compatibility
493 // #if XmVersion > 1100
494 // Corrected by Sergey Krasnov from Steve Hammes' code
f97c9854 495#if XmVersion > 1001
ef41d80c 496 for (i = 0; i < items.GetCount(); i++)
d3a80c92 497 text[i] = wxStringToXmString(items[i]);
ef41d80c 498 XmListAddItemsUnselected(listBox, text, items.GetCount(), pos+1);
f97c9854 499#else
ef41d80c 500 for (i = 0; i < items.GetCount(); i++)
f97c9854 501 {
d3a80c92 502 text[i] = wxStringToXmString(items[i]);
ef41d80c
MB
503 // Another Sergey correction
504 XmListAddItemUnselected(listBox, text[i], pos+i+1);
f97c9854
JS
505 }
506#endif
ef41d80c 507 for (i = 0; i < items.GetCount(); i++)
f97c9854 508 XmStringFree(text[i]);
f97c9854 509 delete[] text;
29006414 510
f97c9854
JS
511 // It seems that if the list is cleared, we must re-ask for
512 // selection policy!!
99ab3e3f 513 SetSelectionPolicy();
29006414 514
f97c9854
JS
515 if (managed)
516 XtManageChild(listBox);
29006414 517
99ab3e3f 518 sk.Restore();
29006414 519
ef41d80c 520 m_noItems += items.GetCount();
4bb6408c
JS
521}
522
523void wxListBox::SetString(int N, const wxString& s)
524{
99ab3e3f 525 wxSizeKeeper sk( this );
f97c9854 526 Widget listBox = (Widget) m_mainWidget;
29006414 527
99ab3e3f 528 wxXmString text( s );
29006414
VZ
529
530 // delete the item and add it again.
531 // FIXME isn't there a way to change it in place?
f97c9854 532 XmListDeletePos (listBox, N+1);
99ab3e3f 533 XmListAddItem (listBox, text(), N+1);
29006414 534
99ab3e3f 535 sk.Restore();
4bb6408c
JS
536}
537
4bb6408c
JS
538void wxListBox::Command (wxCommandEvent & event)
539{
687706f5
KH
540 if (event.GetExtraLong())
541 SetSelection (event.GetInt());
f97c9854
JS
542 else
543 {
687706f5 544 Deselect (event.GetInt());
f97c9854
JS
545 return;
546 }
547 ProcessCommand (event);
548}
549
af111fc3 550void wxListBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
2d120f83 551 XmListCallbackStruct * cbs)
f97c9854 552{
f97c9854 553 wxListBox *item = (wxListBox *) clientData;
29006414 554
a4294b78 555 if (item->InSetValue())
f97c9854 556 return;
29006414 557
ef41d80c
MB
558 wxEventType evtType;
559
560 if( cbs->reason == XmCR_DEFAULT_ACTION )
561 evtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
562 else
563 evtType = wxEVT_COMMAND_LISTBOX_SELECTED;
564
565 int n = cbs->item_position - 1;
566 wxCommandEvent event (evtType, item->GetId());
567 if ( item->HasClientObjectData() )
568 event.SetClientObject( item->GetClientObject(n) );
569 else if ( item->HasClientUntypedData() )
570 event.SetClientData( item->GetClientData(n) );
687706f5 571 event.SetInt(n);
96be256b 572 event.SetExtraLong(true);
ef41d80c
MB
573 event.SetEventObject(item);
574 event.SetString( item->GetString( n ) );
575
576 int x = -1;
2b5f62a0 577 if( NULL != cbs->event && cbs->event->type == ButtonRelease )
ef41d80c
MB
578 {
579 XButtonEvent* evt = (XButtonEvent*)cbs->event;
580
581 x = evt->x;
582 }
583
f97c9854 584 switch (cbs->reason)
4bb6408c 585 {
2d120f83
JS
586 case XmCR_MULTIPLE_SELECT:
587 case XmCR_BROWSE_SELECT:
ef41d80c
MB
588#if wxUSE_CHECKLISTBOX
589 item->DoToggleItem( n, x );
590#endif
591 case XmCR_DEFAULT_ACTION:
592 item->GetEventHandler()->ProcessEvent(event);
593 break;
2d120f83 594 case XmCR_EXTENDED_SELECT:
ef41d80c 595 switch (cbs->selection_type)
f97c9854 596 {
ef41d80c
MB
597 case XmINITIAL:
598 case XmADDITION:
599 case XmMODIFICATION:
600 item->DoToggleItem( n, x );
601 item->GetEventHandler()->ProcessEvent(event);
f97c9854
JS
602 break;
603 }
ef41d80c 604 break;
4bb6408c 605 }
4bb6408c
JS
606}
607
89c7e962
JS
608WXWidget wxListBox::GetTopWidget() const
609{
2d120f83 610 return (WXWidget) XtParent( (Widget) m_mainWidget );
89c7e962 611}
0d57be45 612
0d57be45
JS
613void wxListBox::ChangeBackgroundColour()
614{
321db4b6 615 wxWindow::ChangeBackgroundColour();
29006414 616
02800301
JS
617 Widget parent = XtParent ((Widget) m_mainWidget);
618 Widget hsb, vsb;
29006414 619
02800301 620 XtVaGetValues (parent,
2d120f83
JS
621 XmNhorizontalScrollBar, &hsb,
622 XmNverticalScrollBar, &vsb,
623 NULL);
29006414 624
a91b47e8
JS
625 /* TODO: should scrollbars be affected? Should probably have separate
626 * function to change them (by default, taken from wxSystemSettings)
2d120f83 627 */
a756f210 628 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
96be256b
MB
629 wxDoChangeBackgroundColour((WXWidget) hsb, backgroundColour, true);
630 wxDoChangeBackgroundColour((WXWidget) vsb, backgroundColour, true);
15d5ab67
JS
631
632 XtVaSetValues (hsb,
633 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
634 NULL);
635 XtVaSetValues (vsb,
636 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
637 NULL);
29006414 638
73d33f1a 639 // MBN: why change parent's background? It looks really ugly.
96be256b 640 // wxDoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, true);
0d57be45
JS
641}
642
643void wxListBox::ChangeForegroundColour()
644{
321db4b6 645 wxWindow::ChangeForegroundColour();
29006414 646
02800301
JS
647 Widget parent = XtParent ((Widget) m_mainWidget);
648 Widget hsb, vsb;
29006414
VZ
649
650 XtVaGetValues(parent,
651 XmNhorizontalScrollBar, &hsb,
652 XmNverticalScrollBar, &vsb,
653 NULL);
654
655 /* TODO: should scrollbars be affected? Should probably have separate
656 function to change them (by default, taken from wxSystemSettings)
657
a8680e3e
MB
658 wxDoChangeForegroundColour((WXWidget) hsb, m_foregroundColour);
659 wxDoChangeForegroundColour((WXWidget) vsb, m_foregroundColour);
660 wxDoChangeForegroundColour((WXWidget) parent, m_foregroundColour);
02800301 661 */
0d57be45
JS
662}
663
6adaedf0
JS
664int wxListBox::GetCount() const
665{
ef41d80c 666 return m_noItems;
6adaedf0 667}
e1aae528
MB
668
669#define LIST_SCROLL_SPACING 6
670
671wxSize wxDoGetListBoxBestSize( Widget listWidget, const wxWindow* window )
672{
673 int max;
674 Dimension spacing, highlight, xmargin, ymargin, shadow;
675 int width = 0;
676 int x, y;
677
678 XtVaGetValues( listWidget,
679 XmNitemCount, &max,
680 XmNlistSpacing, &spacing,
681 XmNhighlightThickness, &highlight,
682 XmNlistMarginWidth, &xmargin,
683 XmNlistMarginHeight, &ymargin,
684 XmNshadowThickness, &shadow,
685 NULL );
686
687 for( size_t i = 0; i < (size_t)max; ++i )
688 {
689 window->GetTextExtent( wxDoGetStringInList( listWidget, i ), &x, &y );
690 width = wxMax( width, x );
691 }
692
693 // use some arbitrary value if there are no strings
694 if( width == 0 )
695 width = 100;
696
697 // get my
698 window->GetTextExtent( "v", &x, &y );
699
700 // make it a little larger than widest string, plus the scrollbar
701 width += wxSystemSettings::GetMetric( wxSYS_VSCROLL_X )
702 + 2 * highlight + LIST_SCROLL_SPACING + 2 * xmargin + 2 * shadow;
703
704 // at least 3 items, at most 10
705 int height = wxMax( 3, wxMin( 10, max ) ) *
706 ( y + spacing + 2 * highlight ) + 2 * ymargin + 2 * shadow;
707
708 return wxSize( width, height );
709}
710
711wxSize wxListBox::DoGetBestSize() const
712{
713 return wxDoGetListBoxBestSize( (Widget)m_mainWidget, this );
714}
715