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