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