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