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