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