]>
Commit | Line | Data |
---|---|---|
a340b80d | 1 | ///////////////////////////////////////////////////////////////////////////// |
85fed18c | 2 | // Name: src/generic/odcombo.cpp |
a340b80d VZ |
3 | // Purpose: wxOwnerDrawnComboBox, wxVListBoxComboPopup |
4 | // Author: Jaakko Salli | |
5 | // Modified by: | |
6 | // Created: Apr-30-2006 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2005 Jaakko Salli | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
20 | #include "wx/wxprec.h" | |
21 | ||
22 | #ifdef __BORLANDC__ | |
23 | #pragma hdrstop | |
24 | #endif | |
25 | ||
a57d600f | 26 | #if wxUSE_ODCOMBOBOX |
a340b80d | 27 | |
85fed18c WS |
28 | #include "wx/odcombo.h" |
29 | ||
a340b80d VZ |
30 | #ifndef WX_PRECOMP |
31 | #include "wx/log.h" | |
32 | #include "wx/combobox.h" | |
33 | #include "wx/dcclient.h" | |
34 | #include "wx/settings.h" | |
35 | #include "wx/dialog.h" | |
36 | #endif | |
37 | ||
38 | #include "wx/combo.h" | |
a340b80d VZ |
39 | |
40 | // ============================================================================ | |
41 | // implementation | |
42 | // ============================================================================ | |
43 | ||
44 | ||
45 | // ---------------------------------------------------------------------------- | |
46 | // wxVListBoxComboPopup is a wxVListBox customized to act as a popup control | |
47 | // | |
48 | // ---------------------------------------------------------------------------- | |
49 | ||
50 | ||
51 | BEGIN_EVENT_TABLE(wxVListBoxComboPopup, wxVListBox) | |
52 | EVT_MOTION(wxVListBoxComboPopup::OnMouseMove) | |
53 | EVT_KEY_DOWN(wxVListBoxComboPopup::OnKey) | |
54 | EVT_LEFT_UP(wxVListBoxComboPopup::OnLeftClick) | |
55 | END_EVENT_TABLE() | |
56 | ||
57 | ||
6d0ce565 | 58 | void wxVListBoxComboPopup::Init() |
a340b80d VZ |
59 | { |
60 | m_widestWidth = 0; | |
61 | m_avgCharWidth = 0; | |
62 | m_baseImageWidth = 0; | |
63 | m_itemHeight = 0; | |
64 | m_value = -1; | |
65 | m_itemHover = -1; | |
66 | m_clientDataItemsType = wxClientData_None; | |
67 | } | |
68 | ||
69 | bool wxVListBoxComboPopup::Create(wxWindow* parent) | |
70 | { | |
71 | if ( !wxVListBox::Create(parent, | |
72 | wxID_ANY, | |
73 | wxDefaultPosition, | |
74 | wxDefaultSize, | |
75 | wxBORDER_SIMPLE | wxLB_INT_HEIGHT | wxWANTS_CHARS) ) | |
76 | return false; | |
77 | ||
6d0ce565 | 78 | m_useFont = m_combo->GetFont(); |
a340b80d VZ |
79 | |
80 | wxVListBox::SetItemCount(m_strings.GetCount()); | |
81 | ||
82 | // TODO: Move this to SetFont | |
83 | m_itemHeight = GetCharHeight() + 0; | |
84 | ||
85 | return true; | |
86 | } | |
87 | ||
88 | wxVListBoxComboPopup::~wxVListBoxComboPopup() | |
89 | { | |
90 | Clear(); | |
91 | } | |
92 | ||
93 | bool wxVListBoxComboPopup::LazyCreate() | |
94 | { | |
95 | // NB: There is a bug with wxVListBox that can be avoided by creating | |
96 | // it later (bug causes empty space to be shown if initial selection | |
97 | // is at the end of a list longer than the control can show at once). | |
98 | return true; | |
99 | } | |
100 | ||
101 | // paint the control itself | |
102 | void wxVListBoxComboPopup::PaintComboControl( wxDC& dc, const wxRect& rect ) | |
103 | { | |
104 | if ( !(m_combo->GetWindowStyle() & wxODCB_STD_CONTROL_PAINT) ) | |
105 | { | |
106 | m_combo->DrawFocusBackground(dc,rect,0); | |
107 | if ( m_value >= 0 ) | |
108 | { | |
6d0ce565 VZ |
109 | OnDrawItem(dc,rect,m_value,wxCP_PAINTING_CONTROL); |
110 | return; | |
a340b80d VZ |
111 | } |
112 | } | |
113 | ||
114 | wxComboPopup::PaintComboControl(dc,rect); | |
115 | } | |
116 | ||
117 | void wxVListBoxComboPopup::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const | |
118 | { | |
6d0ce565 VZ |
119 | // TODO: Maybe this code could be moved to wxVListBox::OnPaint? |
120 | dc.SetFont(m_useFont); | |
a340b80d VZ |
121 | |
122 | // Set correct text colour for selected items | |
6d0ce565 | 123 | if ( wxVListBox::GetSelection() == (int) n ) |
a340b80d VZ |
124 | dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) ); |
125 | else | |
126 | dc.SetTextForeground( wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT) ); | |
127 | ||
6d0ce565 | 128 | OnDrawItem(dc,rect,(int)n,0); |
a340b80d VZ |
129 | } |
130 | ||
6d0ce565 | 131 | wxCoord wxVListBoxComboPopup::OnMeasureItem(size_t WXUNUSED(n)) const |
a340b80d | 132 | { |
6d0ce565 VZ |
133 | return m_itemHeight; |
134 | } | |
a340b80d | 135 | |
6d0ce565 VZ |
136 | wxCoord wxVListBoxComboPopup::OnMeasureItemWidth(size_t WXUNUSED(n)) const |
137 | { | |
138 | //return OnMeasureListItemWidth(n); | |
139 | return -1; | |
a340b80d VZ |
140 | } |
141 | ||
142 | void wxVListBoxComboPopup::OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const | |
143 | { | |
144 | // we need to render selected and current items differently | |
145 | if ( IsCurrent(n) ) | |
146 | { | |
147 | m_combo->DrawFocusBackground( dc, rect, wxCONTROL_ISSUBMENU|wxCONTROL_SELECTED ); | |
148 | } | |
149 | //else: do nothing for the normal items | |
150 | } | |
151 | ||
6d0ce565 VZ |
152 | // This is called from wxVListBoxComboPopup::OnDrawItem, with text colour and font prepared |
153 | void wxVListBoxComboPopup::OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const | |
154 | { | |
155 | if ( flags & wxCP_PAINTING_CONTROL ) | |
156 | { | |
157 | dc.DrawText( m_combo->GetValue(), | |
158 | rect.x + m_combo->GetTextIndent(), | |
159 | (rect.height-dc.GetCharHeight())/2 + rect.y ); | |
160 | } | |
161 | else | |
162 | { | |
163 | dc.DrawText( GetString(item), rect.x + 2, rect.y ); | |
164 | } | |
165 | } | |
166 | ||
167 | void wxVListBoxComboPopup::DismissWithEvent() | |
168 | { | |
169 | int selection = wxVListBox::GetSelection(); | |
170 | ||
171 | Dismiss(); | |
172 | ||
173 | wxString valStr; | |
174 | if ( selection != wxNOT_FOUND ) | |
175 | valStr = m_strings[selection]; | |
176 | else | |
177 | valStr = wxEmptyString; | |
178 | ||
179 | m_value = selection; | |
180 | ||
181 | if ( valStr != m_combo->GetValue() ) | |
182 | m_combo->SetValue(valStr); | |
183 | ||
184 | SendComboBoxEvent(selection); | |
185 | } | |
186 | ||
187 | void wxVListBoxComboPopup::SendComboBoxEvent( int selection ) | |
a340b80d VZ |
188 | { |
189 | wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED,m_combo->GetId()); | |
a340b80d VZ |
190 | |
191 | evt.SetEventObject(m_combo); | |
6d0ce565 | 192 | |
a340b80d VZ |
193 | evt.SetInt(selection); |
194 | ||
195 | // Set client data, if any | |
196 | if ( selection >= 0 && (int)m_clientDatas.GetCount() > selection ) | |
197 | { | |
198 | void* clientData = m_clientDatas[selection]; | |
199 | if ( m_clientDataItemsType == wxClientData_Object ) | |
200 | evt.SetClientObject((wxClientData*)clientData); | |
201 | else | |
202 | evt.SetClientData(clientData); | |
203 | } | |
204 | ||
205 | m_combo->GetEventHandler()->AddPendingEvent(evt); | |
206 | } | |
207 | ||
208 | // returns true if key was consumed | |
209 | bool wxVListBoxComboPopup::HandleKey( int keycode, bool saturate ) | |
210 | { | |
211 | int value = m_value; | |
212 | int itemCount = GetCount(); | |
213 | ||
214 | if ( keycode == WXK_DOWN || keycode == WXK_RIGHT ) | |
215 | { | |
216 | value++; | |
217 | } | |
218 | else if ( keycode == WXK_UP || keycode == WXK_LEFT ) | |
219 | { | |
220 | value--; | |
221 | } | |
222 | else if ( keycode == WXK_PAGEDOWN ) | |
223 | { | |
224 | value+=10; | |
225 | } | |
226 | else if ( keycode == WXK_PAGEUP ) | |
227 | { | |
228 | value-=10; | |
229 | } | |
a340b80d VZ |
230 | else |
231 | return false; | |
232 | ||
233 | if ( saturate ) | |
234 | { | |
235 | if ( value >= itemCount ) | |
236 | value = itemCount - 1; | |
237 | else if ( value < 0 ) | |
238 | value = 0; | |
239 | } | |
240 | else | |
241 | { | |
242 | if ( value >= itemCount ) | |
243 | value -= itemCount; | |
244 | else if ( value < 0 ) | |
245 | value += itemCount; | |
246 | } | |
247 | ||
248 | if ( value == m_value ) | |
249 | // Even if value was same, don't skip the event | |
250 | // (good for consistency) | |
251 | return true; | |
252 | ||
253 | m_value = value; | |
254 | ||
a340b80d VZ |
255 | if ( value >= 0 ) |
256 | m_combo->SetValue(m_strings[value]); | |
257 | ||
6d0ce565 | 258 | SendComboBoxEvent(m_value); |
a340b80d VZ |
259 | |
260 | return true; | |
261 | } | |
262 | ||
263 | void wxVListBoxComboPopup::OnComboDoubleClick() | |
264 | { | |
265 | // Cycle on dclick (disable saturation to allow true cycling). | |
266 | if ( !::wxGetKeyState(WXK_SHIFT) ) | |
267 | HandleKey(WXK_DOWN,false); | |
268 | else | |
269 | HandleKey(WXK_UP,false); | |
270 | } | |
271 | ||
272 | void wxVListBoxComboPopup::OnComboKeyEvent( wxKeyEvent& event ) | |
273 | { | |
274 | // Saturated key movement on | |
275 | if ( !HandleKey(event.GetKeyCode(),true) ) | |
276 | event.Skip(); | |
277 | } | |
278 | ||
279 | void wxVListBoxComboPopup::OnPopup() | |
280 | { | |
281 | // *must* set value after size is set (this is because of a vlbox bug) | |
282 | wxVListBox::SetSelection(m_value); | |
283 | } | |
284 | ||
285 | void wxVListBoxComboPopup::OnMouseMove(wxMouseEvent& event) | |
286 | { | |
287 | // Move selection to cursor if it is inside the popup | |
288 | int itemHere = GetItemAtPosition(event.GetPosition()); | |
289 | if ( itemHere >= 0 ) | |
290 | wxVListBox::SetSelection(itemHere); | |
291 | ||
292 | event.Skip(); | |
293 | } | |
294 | ||
295 | void wxVListBoxComboPopup::OnLeftClick(wxMouseEvent& WXUNUSED(event)) | |
296 | { | |
6d0ce565 | 297 | DismissWithEvent(); |
a340b80d VZ |
298 | } |
299 | ||
300 | void wxVListBoxComboPopup::OnKey(wxKeyEvent& event) | |
301 | { | |
302 | // Select item if ENTER is pressed | |
303 | if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER ) | |
304 | { | |
6d0ce565 | 305 | DismissWithEvent(); |
a340b80d VZ |
306 | } |
307 | // Hide popup if ESC is pressed | |
308 | else if ( event.GetKeyCode() == WXK_ESCAPE ) | |
309 | Dismiss(); | |
310 | else | |
311 | event.Skip(); | |
312 | } | |
313 | ||
314 | void wxVListBoxComboPopup::CheckWidth( int pos ) | |
315 | { | |
6d0ce565 | 316 | wxCoord x = OnMeasureItemWidth(pos); |
a340b80d VZ |
317 | |
318 | if ( x < 0 ) | |
319 | { | |
6d0ce565 VZ |
320 | if ( !m_useFont.Ok() ) |
321 | m_useFont = m_combo->GetFont(); | |
a340b80d VZ |
322 | |
323 | wxCoord y; | |
6d0ce565 | 324 | m_combo->GetTextExtent(m_strings[pos], &x, &y, 0, 0, &m_useFont); |
a340b80d VZ |
325 | x += 4; |
326 | } | |
327 | ||
328 | if ( m_widestWidth < x ) | |
329 | { | |
330 | m_widestWidth = x; | |
331 | } | |
332 | } | |
333 | ||
334 | void wxVListBoxComboPopup::Insert( const wxString& item, int pos ) | |
335 | { | |
336 | // Need to change selection? | |
337 | wxString strValue; | |
338 | if ( !(m_combo->GetWindowStyle() & wxCB_READONLY) && | |
339 | m_combo->GetValue() == item ) | |
6d0ce565 | 340 | { |
a340b80d | 341 | m_value = pos; |
6d0ce565 | 342 | } |
a340b80d VZ |
343 | |
344 | m_strings.Insert(item,pos); | |
345 | ||
346 | if ( IsCreated() ) | |
347 | wxVListBox::SetItemCount( wxVListBox::GetItemCount()+1 ); | |
348 | ||
349 | // Calculate width | |
350 | CheckWidth(pos); | |
351 | } | |
352 | ||
353 | int wxVListBoxComboPopup::Append(const wxString& item) | |
354 | { | |
355 | int pos = (int)m_strings.GetCount(); | |
356 | ||
357 | if ( m_combo->GetWindowStyle() & wxCB_SORT ) | |
358 | { | |
359 | // Find position | |
360 | // TODO: Could be optimized with binary search | |
361 | wxArrayString strings = m_strings; | |
362 | unsigned int i; | |
363 | ||
364 | for ( i=0; i<strings.GetCount(); i++ ) | |
365 | { | |
366 | if ( item.Cmp(strings.Item(i)) < 0 ) | |
367 | { | |
368 | pos = (int)i; | |
369 | break; | |
370 | } | |
371 | } | |
372 | } | |
373 | ||
374 | Insert(item,pos); | |
375 | ||
376 | return pos; | |
377 | } | |
378 | ||
379 | void wxVListBoxComboPopup::Clear() | |
380 | { | |
381 | wxASSERT(m_combo); | |
382 | ||
383 | m_strings.Empty(); | |
384 | ||
385 | ClearClientDatas(); | |
386 | ||
cdc99ddd WS |
387 | m_value = wxNOT_FOUND; |
388 | ||
a340b80d VZ |
389 | if ( IsCreated() ) |
390 | wxVListBox::SetItemCount(0); | |
391 | } | |
392 | ||
393 | void wxVListBoxComboPopup::ClearClientDatas() | |
394 | { | |
395 | if ( m_clientDataItemsType == wxClientData_Object ) | |
396 | { | |
397 | size_t i; | |
398 | for ( i=0; i<m_clientDatas.GetCount(); i++ ) | |
399 | delete (wxClientData*) m_clientDatas[i]; | |
400 | } | |
401 | ||
402 | m_clientDatas.Empty(); | |
403 | } | |
404 | ||
405 | void wxVListBoxComboPopup::SetItemClientData( unsigned int n, | |
406 | void* clientData, | |
407 | wxClientDataType clientDataItemsType ) | |
408 | { | |
409 | // It should be sufficient to update this variable only here | |
410 | m_clientDataItemsType = clientDataItemsType; | |
411 | ||
412 | m_clientDatas.SetCount(n+1,NULL); | |
413 | m_clientDatas[n] = clientData; | |
414 | } | |
415 | ||
416 | void* wxVListBoxComboPopup::GetItemClientData(unsigned int n) const | |
417 | { | |
418 | if ( m_clientDatas.GetCount() > n ) | |
419 | return m_clientDatas[n]; | |
420 | ||
421 | return NULL; | |
422 | } | |
423 | ||
424 | void wxVListBoxComboPopup::Delete( unsigned int item ) | |
425 | { | |
426 | // Remove client data, if set | |
427 | if ( m_clientDatas.GetCount() ) | |
428 | { | |
429 | if ( m_clientDataItemsType == wxClientData_Object ) | |
430 | delete (wxClientData*) m_clientDatas[item]; | |
431 | ||
432 | m_clientDatas.RemoveAt(item); | |
433 | } | |
434 | ||
435 | m_strings.RemoveAt(item); | |
436 | ||
437 | if ( IsCreated() ) | |
438 | wxVListBox::SetItemCount( wxVListBox::GetItemCount()-1 ); | |
439 | } | |
440 | ||
441 | int wxVListBoxComboPopup::FindString(const wxString& s) const | |
442 | { | |
443 | return m_strings.Index(s); | |
444 | } | |
445 | ||
446 | unsigned int wxVListBoxComboPopup::GetCount() const | |
447 | { | |
448 | return m_strings.GetCount(); | |
449 | } | |
450 | ||
451 | wxString wxVListBoxComboPopup::GetString( int item ) const | |
452 | { | |
453 | return m_strings[item]; | |
454 | } | |
455 | ||
456 | void wxVListBoxComboPopup::SetString( int item, const wxString& str ) | |
457 | { | |
458 | m_strings[item] = str; | |
459 | } | |
460 | ||
461 | wxString wxVListBoxComboPopup::GetStringValue() const | |
462 | { | |
463 | if ( m_value >= 0 ) | |
464 | return m_strings[m_value]; | |
465 | return wxEmptyString; | |
466 | } | |
467 | ||
468 | void wxVListBoxComboPopup::SetSelection( int item ) | |
469 | { | |
85fed18c WS |
470 | wxCHECK_RET( item == wxNOT_FOUND || ((unsigned int)item < GetCount()), |
471 | wxT("invalid index in wxVListBoxComboPopup::SetSelection") ); | |
a340b80d VZ |
472 | |
473 | m_value = item; | |
474 | ||
475 | if ( IsCreated() ) | |
476 | wxVListBox::SetSelection(item); | |
477 | } | |
478 | ||
6d0ce565 VZ |
479 | int wxVListBoxComboPopup::GetSelection() const |
480 | { | |
481 | return m_value; | |
482 | } | |
483 | ||
a340b80d VZ |
484 | void wxVListBoxComboPopup::SetStringValue( const wxString& value ) |
485 | { | |
486 | int index = m_strings.Index(value); | |
487 | ||
488 | m_value = index; | |
489 | ||
490 | if ( index >= -1 && index < (int)wxVListBox::GetItemCount() ) | |
491 | wxVListBox::SetSelection(index); | |
492 | } | |
493 | ||
494 | wxSize wxVListBoxComboPopup::GetAdjustedSize( int minWidth, int prefHeight, int maxHeight ) | |
495 | { | |
496 | int height = 250; | |
497 | ||
498 | if ( m_strings.GetCount() ) | |
499 | { | |
500 | if ( prefHeight > 0 ) | |
501 | height = prefHeight; | |
502 | ||
503 | if ( height > maxHeight ) | |
504 | height = maxHeight; | |
505 | ||
506 | int totalHeight = GetTotalHeight(); // + 3; | |
507 | if ( height >= totalHeight ) | |
508 | { | |
509 | height = totalHeight; | |
510 | } | |
511 | else | |
512 | { | |
513 | // Adjust height to a multiple of the height of the first item | |
514 | // NB: Calculations that take variable height into account | |
515 | // are unnecessary. | |
516 | int fih = GetLineHeight(0); | |
517 | int shown = height/fih; | |
518 | height = shown * fih; | |
519 | } | |
520 | } | |
521 | else | |
522 | height = 50; | |
523 | ||
524 | // Take scrollbar into account in width calculations | |
525 | int widestWidth = m_widestWidth + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); | |
526 | return wxSize(minWidth > widestWidth ? minWidth : widestWidth, | |
527 | height+2); | |
528 | } | |
529 | ||
6d0ce565 VZ |
530 | //void wxVListBoxComboPopup::Populate( int n, const wxString choices[] ) |
531 | void wxVListBoxComboPopup::Populate( const wxArrayString& choices ) | |
a340b80d VZ |
532 | { |
533 | int i; | |
534 | ||
6d0ce565 VZ |
535 | int n = choices.GetCount(); |
536 | ||
a340b80d VZ |
537 | for ( i=0; i<n; i++ ) |
538 | { | |
6d0ce565 | 539 | const wxString& item = choices.Item(i); |
a340b80d VZ |
540 | m_strings.Add(item); |
541 | CheckWidth(i); | |
542 | } | |
543 | ||
544 | if ( IsCreated() ) | |
545 | wxVListBox::SetItemCount(n); | |
546 | ||
547 | // Sort the initial choices | |
548 | if ( m_combo->GetWindowStyle() & wxCB_SORT ) | |
549 | m_strings.Sort(); | |
550 | ||
551 | // Find initial selection | |
552 | wxString strValue = m_combo->GetValue(); | |
553 | if ( strValue.Length() ) | |
554 | m_value = m_strings.Index(strValue); | |
555 | } | |
556 | ||
557 | // ---------------------------------------------------------------------------- | |
558 | // wxOwnerDrawnComboBox | |
559 | // ---------------------------------------------------------------------------- | |
560 | ||
561 | ||
a57d600f | 562 | BEGIN_EVENT_TABLE(wxOwnerDrawnComboBox, wxComboCtrl) |
a340b80d VZ |
563 | END_EVENT_TABLE() |
564 | ||
565 | ||
a57d600f | 566 | IMPLEMENT_DYNAMIC_CLASS2(wxOwnerDrawnComboBox, wxComboCtrl, wxControlWithItems) |
a340b80d VZ |
567 | |
568 | void wxOwnerDrawnComboBox::Init() | |
569 | { | |
6d0ce565 | 570 | m_popupInterface = NULL; |
a340b80d VZ |
571 | } |
572 | ||
573 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
574 | wxWindowID id, | |
575 | const wxString& value, | |
576 | const wxPoint& pos, | |
577 | const wxSize& size, | |
578 | long style, | |
579 | const wxValidator& validator, | |
580 | const wxString& name) | |
581 | { | |
a57d600f | 582 | return wxComboCtrl::Create(parent,id,value,pos,size,style,validator,name); |
a340b80d VZ |
583 | } |
584 | ||
585 | wxOwnerDrawnComboBox::wxOwnerDrawnComboBox(wxWindow *parent, | |
586 | wxWindowID id, | |
587 | const wxString& value, | |
588 | const wxPoint& pos, | |
589 | const wxSize& size, | |
590 | const wxArrayString& choices, | |
591 | long style, | |
592 | const wxValidator& validator, | |
593 | const wxString& name) | |
a57d600f | 594 | : wxComboCtrl() |
a340b80d VZ |
595 | { |
596 | Init(); | |
597 | ||
598 | Create(parent,id,value,pos,size,choices,style, validator, name); | |
599 | } | |
600 | ||
601 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
602 | wxWindowID id, | |
603 | const wxString& value, | |
604 | const wxPoint& pos, | |
605 | const wxSize& size, | |
606 | const wxArrayString& choices, | |
607 | long style, | |
608 | const wxValidator& validator, | |
609 | const wxString& name) | |
610 | { | |
6d0ce565 VZ |
611 | m_initChs = choices; |
612 | //wxCArrayString chs(choices); | |
a340b80d | 613 | |
6d0ce565 VZ |
614 | //return Create(parent, id, value, pos, size, chs.GetCount(), |
615 | // chs.GetStrings(), style, validator, name); | |
616 | return Create(parent, id, value, pos, size, 0, | |
617 | NULL, style, validator, name); | |
a340b80d VZ |
618 | } |
619 | ||
620 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
621 | wxWindowID id, | |
622 | const wxString& value, | |
623 | const wxPoint& pos, | |
624 | const wxSize& size, | |
625 | int n, | |
626 | const wxString choices[], | |
627 | long style, | |
628 | const wxValidator& validator, | |
629 | const wxString& name) | |
630 | { | |
631 | ||
632 | if ( !Create(parent, id, value, pos, size, style, | |
633 | validator, name) ) | |
634 | { | |
635 | return false; | |
636 | } | |
637 | ||
6d0ce565 VZ |
638 | int i; |
639 | for ( i=0; i<n; i++ ) | |
640 | m_initChs.Add(choices[i]); | |
a340b80d VZ |
641 | |
642 | return true; | |
643 | } | |
644 | ||
645 | wxOwnerDrawnComboBox::~wxOwnerDrawnComboBox() | |
646 | { | |
647 | if ( m_popupInterface ) | |
648 | m_popupInterface->ClearClientDatas(); | |
649 | } | |
650 | ||
6d0ce565 VZ |
651 | void wxOwnerDrawnComboBox::SetPopupControl( wxComboPopup* popup ) |
652 | { | |
653 | if ( !popup ) | |
654 | { | |
655 | popup = new wxVListBoxComboPopup(); | |
656 | } | |
657 | ||
a57d600f | 658 | wxComboCtrl::SetPopupControl(popup); |
6d0ce565 VZ |
659 | |
660 | wxASSERT(popup); | |
661 | m_popupInterface = (wxVListBoxComboPopup*) popup; | |
662 | ||
663 | // Add initial choices to the wxVListBox | |
664 | if ( !m_popupInterface->GetCount() ) | |
665 | { | |
666 | //m_popupInterface->Populate(m_initChs.GetCount(),m_initChs.GetStrings()); | |
667 | m_popupInterface->Populate(m_initChs); | |
668 | m_initChs.Clear(); | |
669 | } | |
670 | } | |
671 | ||
a340b80d VZ |
672 | // ---------------------------------------------------------------------------- |
673 | // wxOwnerDrawnComboBox item manipulation methods | |
674 | // ---------------------------------------------------------------------------- | |
675 | ||
676 | void wxOwnerDrawnComboBox::Clear() | |
677 | { | |
6d0ce565 | 678 | EnsurePopupControl(); |
a340b80d VZ |
679 | |
680 | m_popupInterface->Clear(); | |
681 | ||
cdc99ddd | 682 | SetValue(wxEmptyString); |
a340b80d VZ |
683 | } |
684 | ||
685 | void wxOwnerDrawnComboBox::Delete(unsigned int n) | |
686 | { | |
85fed18c | 687 | wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Delete") ); |
a340b80d VZ |
688 | |
689 | if ( GetSelection() == (int) n ) | |
690 | SetValue(wxEmptyString); | |
691 | ||
692 | m_popupInterface->Delete(n); | |
693 | } | |
694 | ||
695 | unsigned int wxOwnerDrawnComboBox::GetCount() const | |
696 | { | |
6d0ce565 | 697 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
698 | return m_popupInterface->GetCount(); |
699 | } | |
700 | ||
701 | wxString wxOwnerDrawnComboBox::GetString(unsigned int n) const | |
702 | { | |
85fed18c | 703 | wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxOwnerDrawnComboBox::GetString") ); |
a340b80d VZ |
704 | return m_popupInterface->GetString(n); |
705 | } | |
706 | ||
707 | void wxOwnerDrawnComboBox::SetString(unsigned int n, const wxString& s) | |
708 | { | |
85fed18c | 709 | wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::SetString") ); |
a340b80d VZ |
710 | m_popupInterface->SetString(n,s); |
711 | } | |
712 | ||
713 | int wxOwnerDrawnComboBox::FindString(const wxString& s) const | |
714 | { | |
6d0ce565 | 715 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
716 | return m_popupInterface->FindString(s); |
717 | } | |
718 | ||
719 | void wxOwnerDrawnComboBox::Select(int n) | |
720 | { | |
85fed18c | 721 | wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") ); |
6d0ce565 | 722 | EnsurePopupControl(); |
a340b80d VZ |
723 | |
724 | m_popupInterface->SetSelection(n); | |
725 | ||
726 | wxString str; | |
727 | if ( n >= 0 ) | |
728 | str = m_popupInterface->GetString(n); | |
729 | ||
730 | // Refresh text portion in control | |
731 | if ( m_text ) | |
732 | m_text->SetValue( str ); | |
733 | else | |
734 | m_valueString = str; | |
735 | ||
736 | Refresh(); | |
737 | } | |
738 | ||
739 | int wxOwnerDrawnComboBox::GetSelection() const | |
740 | { | |
6d0ce565 | 741 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
742 | return m_popupInterface->GetSelection(); |
743 | } | |
744 | ||
745 | int wxOwnerDrawnComboBox::DoAppend(const wxString& item) | |
746 | { | |
6d0ce565 VZ |
747 | EnsurePopupControl(); |
748 | wxASSERT(m_popupInterface); | |
a340b80d VZ |
749 | return m_popupInterface->Append(item); |
750 | } | |
751 | ||
752 | int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos) | |
753 | { | |
754 | wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); | |
85fed18c | 755 | wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); |
a340b80d | 756 | |
6d0ce565 | 757 | EnsurePopupControl(); |
a340b80d VZ |
758 | m_popupInterface->Insert(item,pos); |
759 | ||
760 | return pos; | |
761 | } | |
762 | ||
763 | void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData) | |
764 | { | |
6d0ce565 | 765 | EnsurePopupControl(); |
a340b80d VZ |
766 | m_popupInterface->SetItemClientData(n,clientData,m_clientDataItemsType); |
767 | } | |
768 | ||
769 | void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const | |
770 | { | |
6d0ce565 | 771 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
772 | return m_popupInterface->GetItemClientData(n); |
773 | } | |
774 | ||
775 | void wxOwnerDrawnComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) | |
776 | { | |
777 | DoSetItemClientData(n, (void*) clientData); | |
778 | } | |
779 | ||
780 | wxClientData* wxOwnerDrawnComboBox::DoGetItemClientObject(unsigned int n) const | |
781 | { | |
782 | return (wxClientData*) DoGetItemClientData(n); | |
783 | } | |
784 | ||
a57d600f | 785 | #endif // wxUSE_ODCOMBOBOX |