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