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