]> git.saurik.com Git - wxWidgets.git/blame - src/motif/listbox.cpp
avoid trying to link QA if not required
[wxWidgets.git] / src / motif / listbox.cpp
CommitLineData
4bb6408c 1///////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/motif/listbox.cpp
4bb6408c
JS
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
11e62fe6 309int wxListBox::FindString(const wxString& s, bool bCase) const
9b1bd0c6 310{
11e62fe6
WS
311 // FIXME: back to base class for not supported value of bCase
312
9b1bd0c6
MB
313 return wxDoFindStringInList( (Widget)m_mainWidget, s );
314}
315
4bb6408c
JS
316void wxListBox::Clear()
317{
2d120f83
JS
318 if (m_noItems <= 0)
319 return;
29006414 320
99ab3e3f 321 wxSizeKeeper sk( this );
2d120f83 322 Widget listBox = (Widget) m_mainWidget;
29006414 323
2d120f83 324 XmListDeleteAllItems (listBox);
99ab3e3f
MB
325 if( HasClientObjectData() )
326 m_clientDataDict.DestroyData();
29006414 327
99ab3e3f 328 sk.Restore();
29006414 329
2d120f83 330 m_noItems = 0;
4bb6408c
JS
331}
332
c6179a84 333void wxListBox::DoSetSelection(int N, bool select)
4bb6408c 334{
96be256b 335 m_inSetValue = true;
2d120f83 336 if (select)
f97c9854 337 {
29006414
VZ
338#if 0
339 if (m_windowStyle & wxLB_MULTIPLE)
340 {
341 int *selections = NULL;
342 int n = GetSelections (&selections);
343
ef41d80c
MB
344 // This hack is supposed to work, to make it possible
345 // to select more than one item, but it DOESN'T under Motif 1.1.
29006414 346
ef41d80c
MB
347 XtVaSetValues ((Widget) m_mainWidget,
348 XmNselectionPolicy, XmMULTIPLE_SELECT,
349 NULL);
29006414
VZ
350
351 int i;
352 for (i = 0; i < n; i++)
ef41d80c 353 XmListSelectPos ((Widget) m_mainWidget,
96be256b 354 selections[i] + 1, False);
29006414 355
96be256b 356 XmListSelectPos ((Widget) m_mainWidget, N + 1, False);
29006414 357
ef41d80c
MB
358 XtVaSetValues ((Widget) m_mainWidget,
359 XmNselectionPolicy, XmEXTENDED_SELECT,
360 NULL);
29006414
VZ
361 }
362 else
363#endif // 0
96be256b 364 XmListSelectPos ((Widget) m_mainWidget, N + 1, False);
29006414 365
f97c9854 366 }
2d120f83
JS
367 else
368 XmListDeselectPos ((Widget) m_mainWidget, N + 1);
29006414 369
96be256b 370 m_inSetValue = false;
4bb6408c
JS
371}
372
d7d38ea4 373bool wxListBox::IsSelected(int N) const
4bb6408c 374{
2d120f83
JS
375 // In Motif, no simple way to determine if the item is selected.
376 wxArrayInt theSelections;
377 int count = GetSelections (theSelections);
378 if (count == 0)
96be256b 379 return false;
2d120f83
JS
380 else
381 {
382 int j;
383 for (j = 0; j < count; j++)
384 if (theSelections[j] == N)
96be256b 385 return true;
2d120f83 386 }
96be256b 387 return false;
4bb6408c
JS
388}
389
ef41d80c
MB
390void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
391{
96be256b 392 m_clientDataDict.Set(n, clientData, false);
ef41d80c
MB
393}
394
395wxClientData* wxListBox::DoGetItemClientObject(int n) const
4bb6408c 396{
99ab3e3f 397 return m_clientDataDict.Get(n);
4bb6408c
JS
398}
399
ef41d80c 400void *wxListBox::DoGetItemClientData(int N) const
4bb6408c 401{
99ab3e3f 402 return (void*)m_clientDataDict.Get(N);
4bb6408c
JS
403}
404
ef41d80c 405void wxListBox::DoSetItemClientData(int N, void *Client_data)
4bb6408c 406{
96be256b 407 m_clientDataDict.Set(N, (wxClientData*)Client_data, false);
4bb6408c
JS
408}
409
410// Return number of selections and an array of selected integers
411int wxListBox::GetSelections(wxArrayInt& aSelections) const
412{
2d120f83 413 aSelections.Empty();
29006414 414
2d120f83
JS
415 Widget listBox = (Widget) m_mainWidget;
416 int *posList = NULL;
417 int posCnt = 0;
418 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
419 if (flag)
420 {
421 if (posCnt > 0)
422 {
423 aSelections.Alloc(posCnt);
29006414 424
2d120f83
JS
425 int i;
426 for (i = 0; i < posCnt; i++)
427 aSelections.Add(posList[i] - 1);
29006414 428
2d120f83
JS
429 XtFree ((char *) posList);
430 return posCnt;
431 }
432 else
433 return 0;
4bb6408c 434 }
2d120f83
JS
435 else
436 return 0;
4bb6408c
JS
437}
438
439// Get single selection, for single choice list items
9b1bd0c6 440int wxDoGetSelectionInList(Widget listBox)
4bb6408c 441{
f97c9854
JS
442 int *posList = NULL;
443 int posCnt = 0;
444 bool flag = XmListGetSelectedPos (listBox, &posList, &posCnt);
445 if (flag)
446 {
447 int id = -1;
448 if (posCnt > 0)
449 id = posList[0] - 1;
450 XtFree ((char *) posList);
451 return id;
452 }
453 else
454 return -1;
4bb6408c
JS
455}
456
9b1bd0c6
MB
457int wxListBox::GetSelection() const
458{
459 return wxDoGetSelectionInList((Widget) m_mainWidget);
460}
461
4bb6408c 462// Find string for position
e1aae528 463wxString wxDoGetStringInList( Widget listBox, int n )
4bb6408c 464{
f97c9854 465 XmString *strlist;
e1aae528
MB
466 int count;
467 XtVaGetValues( listBox,
468 XmNitemCount, &count,
469 XmNitems, &strlist,
470 NULL );
d40708e2 471 if( n < count && n >= 0 )
e1aae528 472 return wxXmStringToString( strlist[n] );
f97c9854
JS
473 else
474 return wxEmptyString;
4bb6408c
JS
475}
476
e1aae528
MB
477wxString wxListBox::GetString( int n ) const
478{
479 return wxDoGetStringInList( (Widget)m_mainWidget, n );
480}
481
ef41d80c 482void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
4bb6408c 483{
99ab3e3f 484 wxSizeKeeper sk( this );
f97c9854 485 Widget listBox = (Widget) m_mainWidget;
29006414 486
f97c9854 487 bool managed = XtIsManaged(listBox);
29006414 488
f97c9854
JS
489 if (managed)
490 XtUnmanageChild(listBox);
29006414 491
ef41d80c
MB
492 XmString *text = new XmString[items.GetCount()];
493 size_t i;
2d120f83
JS
494 // Steve Hammes: Motif 1.1 compatibility
495 // #if XmVersion > 1100
496 // Corrected by Sergey Krasnov from Steve Hammes' code
f97c9854 497#if XmVersion > 1001
ef41d80c 498 for (i = 0; i < items.GetCount(); i++)
d3a80c92 499 text[i] = wxStringToXmString(items[i]);
ef41d80c 500 XmListAddItemsUnselected(listBox, text, items.GetCount(), pos+1);
f97c9854 501#else
ef41d80c 502 for (i = 0; i < items.GetCount(); i++)
f97c9854 503 {
d3a80c92 504 text[i] = wxStringToXmString(items[i]);
ef41d80c
MB
505 // Another Sergey correction
506 XmListAddItemUnselected(listBox, text[i], pos+i+1);
f97c9854
JS
507 }
508#endif
ef41d80c 509 for (i = 0; i < items.GetCount(); i++)
f97c9854 510 XmStringFree(text[i]);
f97c9854 511 delete[] text;
29006414 512
f97c9854
JS
513 // It seems that if the list is cleared, we must re-ask for
514 // selection policy!!
99ab3e3f 515 SetSelectionPolicy();
29006414 516
f97c9854
JS
517 if (managed)
518 XtManageChild(listBox);
29006414 519
99ab3e3f 520 sk.Restore();
29006414 521
ef41d80c 522 m_noItems += items.GetCount();
4bb6408c
JS
523}
524
525void wxListBox::SetString(int N, const wxString& s)
526{
99ab3e3f 527 wxSizeKeeper sk( this );
f97c9854 528 Widget listBox = (Widget) m_mainWidget;
29006414 529
99ab3e3f 530 wxXmString text( s );
29006414
VZ
531
532 // delete the item and add it again.
533 // FIXME isn't there a way to change it in place?
f97c9854 534 XmListDeletePos (listBox, N+1);
99ab3e3f 535 XmListAddItem (listBox, text(), N+1);
29006414 536
99ab3e3f 537 sk.Restore();
4bb6408c
JS
538}
539
4bb6408c
JS
540void wxListBox::Command (wxCommandEvent & event)
541{
687706f5
KH
542 if (event.GetExtraLong())
543 SetSelection (event.GetInt());
f97c9854
JS
544 else
545 {
687706f5 546 Deselect (event.GetInt());
f97c9854
JS
547 return;
548 }
549 ProcessCommand (event);
550}
551
af111fc3 552void wxListBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
2d120f83 553 XmListCallbackStruct * cbs)
f97c9854 554{
f97c9854 555 wxListBox *item = (wxListBox *) clientData;
29006414 556
a4294b78 557 if (item->InSetValue())
f97c9854 558 return;
29006414 559
ef41d80c
MB
560 wxEventType evtType;
561
562 if( cbs->reason == XmCR_DEFAULT_ACTION )
563 evtType = wxEVT_COMMAND_LISTBOX_DOUBLECLICKED;
564 else
565 evtType = wxEVT_COMMAND_LISTBOX_SELECTED;
566
567 int n = cbs->item_position - 1;
568 wxCommandEvent event (evtType, item->GetId());
569 if ( item->HasClientObjectData() )
570 event.SetClientObject( item->GetClientObject(n) );
571 else if ( item->HasClientUntypedData() )
572 event.SetClientData( item->GetClientData(n) );
687706f5 573 event.SetInt(n);
96be256b 574 event.SetExtraLong(true);
ef41d80c
MB
575 event.SetEventObject(item);
576 event.SetString( item->GetString( n ) );
577
578 int x = -1;
2b5f62a0 579 if( NULL != cbs->event && cbs->event->type == ButtonRelease )
ef41d80c
MB
580 {
581 XButtonEvent* evt = (XButtonEvent*)cbs->event;
582
583 x = evt->x;
584 }
585
f97c9854 586 switch (cbs->reason)
4bb6408c 587 {
2d120f83
JS
588 case XmCR_MULTIPLE_SELECT:
589 case XmCR_BROWSE_SELECT:
ef41d80c
MB
590#if wxUSE_CHECKLISTBOX
591 item->DoToggleItem( n, x );
592#endif
593 case XmCR_DEFAULT_ACTION:
594 item->GetEventHandler()->ProcessEvent(event);
595 break;
2d120f83 596 case XmCR_EXTENDED_SELECT:
ef41d80c 597 switch (cbs->selection_type)
f97c9854 598 {
ef41d80c
MB
599 case XmINITIAL:
600 case XmADDITION:
601 case XmMODIFICATION:
602 item->DoToggleItem( n, x );
603 item->GetEventHandler()->ProcessEvent(event);
f97c9854
JS
604 break;
605 }
ef41d80c 606 break;
4bb6408c 607 }
4bb6408c
JS
608}
609
89c7e962
JS
610WXWidget wxListBox::GetTopWidget() const
611{
2d120f83 612 return (WXWidget) XtParent( (Widget) m_mainWidget );
89c7e962 613}
0d57be45 614
0d57be45
JS
615void wxListBox::ChangeBackgroundColour()
616{
321db4b6 617 wxWindow::ChangeBackgroundColour();
29006414 618
02800301
JS
619 Widget parent = XtParent ((Widget) m_mainWidget);
620 Widget hsb, vsb;
29006414 621
02800301 622 XtVaGetValues (parent,
2d120f83
JS
623 XmNhorizontalScrollBar, &hsb,
624 XmNverticalScrollBar, &vsb,
625 NULL);
29006414 626
a91b47e8
JS
627 /* TODO: should scrollbars be affected? Should probably have separate
628 * function to change them (by default, taken from wxSystemSettings)
2d120f83 629 */
a756f210 630 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
96be256b
MB
631 wxDoChangeBackgroundColour((WXWidget) hsb, backgroundColour, true);
632 wxDoChangeBackgroundColour((WXWidget) vsb, backgroundColour, true);
15d5ab67
JS
633
634 XtVaSetValues (hsb,
635 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(hsb)),
636 NULL);
637 XtVaSetValues (vsb,
638 XmNtroughColor, backgroundColour.AllocColour(XtDisplay(vsb)),
639 NULL);
29006414 640
73d33f1a 641 // MBN: why change parent's background? It looks really ugly.
96be256b 642 // wxDoChangeBackgroundColour((WXWidget) parent, m_backgroundColour, true);
0d57be45
JS
643}
644
645void wxListBox::ChangeForegroundColour()
646{
321db4b6 647 wxWindow::ChangeForegroundColour();
29006414 648
02800301
JS
649 Widget parent = XtParent ((Widget) m_mainWidget);
650 Widget hsb, vsb;
29006414
VZ
651
652 XtVaGetValues(parent,
653 XmNhorizontalScrollBar, &hsb,
654 XmNverticalScrollBar, &vsb,
655 NULL);
656
657 /* TODO: should scrollbars be affected? Should probably have separate
658 function to change them (by default, taken from wxSystemSettings)
659
a8680e3e
MB
660 wxDoChangeForegroundColour((WXWidget) hsb, m_foregroundColour);
661 wxDoChangeForegroundColour((WXWidget) vsb, m_foregroundColour);
662 wxDoChangeForegroundColour((WXWidget) parent, m_foregroundColour);
02800301 663 */
0d57be45
JS
664}
665
6adaedf0
JS
666int wxListBox::GetCount() const
667{
ef41d80c 668 return m_noItems;
6adaedf0 669}
e1aae528
MB
670
671#define LIST_SCROLL_SPACING 6
672
673wxSize wxDoGetListBoxBestSize( Widget listWidget, const wxWindow* window )
674{
675 int max;
676 Dimension spacing, highlight, xmargin, ymargin, shadow;
677 int width = 0;
678 int x, y;
679
680 XtVaGetValues( listWidget,
681 XmNitemCount, &max,
682 XmNlistSpacing, &spacing,
683 XmNhighlightThickness, &highlight,
684 XmNlistMarginWidth, &xmargin,
685 XmNlistMarginHeight, &ymargin,
686 XmNshadowThickness, &shadow,
687 NULL );
688
689 for( size_t i = 0; i < (size_t)max; ++i )
690 {
691 window->GetTextExtent( wxDoGetStringInList( listWidget, i ), &x, &y );
692 width = wxMax( width, x );
693 }
694
695 // use some arbitrary value if there are no strings
696 if( width == 0 )
697 width = 100;
698
699 // get my
700 window->GetTextExtent( "v", &x, &y );
701
702 // make it a little larger than widest string, plus the scrollbar
703 width += wxSystemSettings::GetMetric( wxSYS_VSCROLL_X )
704 + 2 * highlight + LIST_SCROLL_SPACING + 2 * xmargin + 2 * shadow;
705
706 // at least 3 items, at most 10
707 int height = wxMax( 3, wxMin( 10, max ) ) *
708 ( y + spacing + 2 * highlight ) + 2 * ymargin + 2 * shadow;
709
710 return wxSize( width, height );
711}
712
713wxSize wxListBox::DoGetBestSize() const
714{
715 return wxDoGetListBoxBestSize( (Widget)m_mainWidget, this );
716}