]>
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 | ||
387 | if ( IsCreated() ) | |
388 | wxVListBox::SetItemCount(0); | |
389 | } | |
390 | ||
391 | void wxVListBoxComboPopup::ClearClientDatas() | |
392 | { | |
393 | if ( m_clientDataItemsType == wxClientData_Object ) | |
394 | { | |
395 | size_t i; | |
396 | for ( i=0; i<m_clientDatas.GetCount(); i++ ) | |
397 | delete (wxClientData*) m_clientDatas[i]; | |
398 | } | |
399 | ||
400 | m_clientDatas.Empty(); | |
401 | } | |
402 | ||
403 | void wxVListBoxComboPopup::SetItemClientData( unsigned int n, | |
404 | void* clientData, | |
405 | wxClientDataType clientDataItemsType ) | |
406 | { | |
407 | // It should be sufficient to update this variable only here | |
408 | m_clientDataItemsType = clientDataItemsType; | |
409 | ||
410 | m_clientDatas.SetCount(n+1,NULL); | |
411 | m_clientDatas[n] = clientData; | |
412 | } | |
413 | ||
414 | void* wxVListBoxComboPopup::GetItemClientData(unsigned int n) const | |
415 | { | |
416 | if ( m_clientDatas.GetCount() > n ) | |
417 | return m_clientDatas[n]; | |
418 | ||
419 | return NULL; | |
420 | } | |
421 | ||
422 | void wxVListBoxComboPopup::Delete( unsigned int item ) | |
423 | { | |
424 | // Remove client data, if set | |
425 | if ( m_clientDatas.GetCount() ) | |
426 | { | |
427 | if ( m_clientDataItemsType == wxClientData_Object ) | |
428 | delete (wxClientData*) m_clientDatas[item]; | |
429 | ||
430 | m_clientDatas.RemoveAt(item); | |
431 | } | |
432 | ||
433 | m_strings.RemoveAt(item); | |
434 | ||
435 | if ( IsCreated() ) | |
436 | wxVListBox::SetItemCount( wxVListBox::GetItemCount()-1 ); | |
437 | } | |
438 | ||
439 | int wxVListBoxComboPopup::FindString(const wxString& s) const | |
440 | { | |
441 | return m_strings.Index(s); | |
442 | } | |
443 | ||
444 | unsigned int wxVListBoxComboPopup::GetCount() const | |
445 | { | |
446 | return m_strings.GetCount(); | |
447 | } | |
448 | ||
449 | wxString wxVListBoxComboPopup::GetString( int item ) const | |
450 | { | |
451 | return m_strings[item]; | |
452 | } | |
453 | ||
454 | void wxVListBoxComboPopup::SetString( int item, const wxString& str ) | |
455 | { | |
456 | m_strings[item] = str; | |
457 | } | |
458 | ||
459 | wxString wxVListBoxComboPopup::GetStringValue() const | |
460 | { | |
461 | if ( m_value >= 0 ) | |
462 | return m_strings[m_value]; | |
463 | return wxEmptyString; | |
464 | } | |
465 | ||
466 | void wxVListBoxComboPopup::SetSelection( int item ) | |
467 | { | |
85fed18c WS |
468 | wxCHECK_RET( item == wxNOT_FOUND || ((unsigned int)item < GetCount()), |
469 | wxT("invalid index in wxVListBoxComboPopup::SetSelection") ); | |
a340b80d VZ |
470 | |
471 | m_value = item; | |
472 | ||
473 | if ( IsCreated() ) | |
474 | wxVListBox::SetSelection(item); | |
475 | } | |
476 | ||
6d0ce565 VZ |
477 | int wxVListBoxComboPopup::GetSelection() const |
478 | { | |
479 | return m_value; | |
480 | } | |
481 | ||
a340b80d VZ |
482 | void wxVListBoxComboPopup::SetStringValue( const wxString& value ) |
483 | { | |
484 | int index = m_strings.Index(value); | |
485 | ||
486 | m_value = index; | |
487 | ||
488 | if ( index >= -1 && index < (int)wxVListBox::GetItemCount() ) | |
489 | wxVListBox::SetSelection(index); | |
490 | } | |
491 | ||
492 | wxSize wxVListBoxComboPopup::GetAdjustedSize( int minWidth, int prefHeight, int maxHeight ) | |
493 | { | |
494 | int height = 250; | |
495 | ||
496 | if ( m_strings.GetCount() ) | |
497 | { | |
498 | if ( prefHeight > 0 ) | |
499 | height = prefHeight; | |
500 | ||
501 | if ( height > maxHeight ) | |
502 | height = maxHeight; | |
503 | ||
504 | int totalHeight = GetTotalHeight(); // + 3; | |
505 | if ( height >= totalHeight ) | |
506 | { | |
507 | height = totalHeight; | |
508 | } | |
509 | else | |
510 | { | |
511 | // Adjust height to a multiple of the height of the first item | |
512 | // NB: Calculations that take variable height into account | |
513 | // are unnecessary. | |
514 | int fih = GetLineHeight(0); | |
515 | int shown = height/fih; | |
516 | height = shown * fih; | |
517 | } | |
518 | } | |
519 | else | |
520 | height = 50; | |
521 | ||
522 | // Take scrollbar into account in width calculations | |
523 | int widestWidth = m_widestWidth + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); | |
524 | return wxSize(minWidth > widestWidth ? minWidth : widestWidth, | |
525 | height+2); | |
526 | } | |
527 | ||
6d0ce565 VZ |
528 | //void wxVListBoxComboPopup::Populate( int n, const wxString choices[] ) |
529 | void wxVListBoxComboPopup::Populate( const wxArrayString& choices ) | |
a340b80d VZ |
530 | { |
531 | int i; | |
532 | ||
6d0ce565 VZ |
533 | int n = choices.GetCount(); |
534 | ||
a340b80d VZ |
535 | for ( i=0; i<n; i++ ) |
536 | { | |
6d0ce565 | 537 | const wxString& item = choices.Item(i); |
a340b80d VZ |
538 | m_strings.Add(item); |
539 | CheckWidth(i); | |
540 | } | |
541 | ||
542 | if ( IsCreated() ) | |
543 | wxVListBox::SetItemCount(n); | |
544 | ||
545 | // Sort the initial choices | |
546 | if ( m_combo->GetWindowStyle() & wxCB_SORT ) | |
547 | m_strings.Sort(); | |
548 | ||
549 | // Find initial selection | |
550 | wxString strValue = m_combo->GetValue(); | |
551 | if ( strValue.Length() ) | |
552 | m_value = m_strings.Index(strValue); | |
553 | } | |
554 | ||
555 | // ---------------------------------------------------------------------------- | |
556 | // wxOwnerDrawnComboBox | |
557 | // ---------------------------------------------------------------------------- | |
558 | ||
559 | ||
a57d600f | 560 | BEGIN_EVENT_TABLE(wxOwnerDrawnComboBox, wxComboCtrl) |
a340b80d VZ |
561 | END_EVENT_TABLE() |
562 | ||
563 | ||
a57d600f | 564 | IMPLEMENT_DYNAMIC_CLASS2(wxOwnerDrawnComboBox, wxComboCtrl, wxControlWithItems) |
a340b80d VZ |
565 | |
566 | void wxOwnerDrawnComboBox::Init() | |
567 | { | |
6d0ce565 | 568 | m_popupInterface = NULL; |
a340b80d VZ |
569 | } |
570 | ||
571 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
572 | wxWindowID id, | |
573 | const wxString& value, | |
574 | const wxPoint& pos, | |
575 | const wxSize& size, | |
576 | long style, | |
577 | const wxValidator& validator, | |
578 | const wxString& name) | |
579 | { | |
a57d600f | 580 | return wxComboCtrl::Create(parent,id,value,pos,size,style,validator,name); |
a340b80d VZ |
581 | } |
582 | ||
583 | wxOwnerDrawnComboBox::wxOwnerDrawnComboBox(wxWindow *parent, | |
584 | wxWindowID id, | |
585 | const wxString& value, | |
586 | const wxPoint& pos, | |
587 | const wxSize& size, | |
588 | const wxArrayString& choices, | |
589 | long style, | |
590 | const wxValidator& validator, | |
591 | const wxString& name) | |
a57d600f | 592 | : wxComboCtrl() |
a340b80d VZ |
593 | { |
594 | Init(); | |
595 | ||
596 | Create(parent,id,value,pos,size,choices,style, validator, name); | |
597 | } | |
598 | ||
599 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
600 | wxWindowID id, | |
601 | const wxString& value, | |
602 | const wxPoint& pos, | |
603 | const wxSize& size, | |
604 | const wxArrayString& choices, | |
605 | long style, | |
606 | const wxValidator& validator, | |
607 | const wxString& name) | |
608 | { | |
6d0ce565 VZ |
609 | m_initChs = choices; |
610 | //wxCArrayString chs(choices); | |
a340b80d | 611 | |
6d0ce565 VZ |
612 | //return Create(parent, id, value, pos, size, chs.GetCount(), |
613 | // chs.GetStrings(), style, validator, name); | |
614 | return Create(parent, id, value, pos, size, 0, | |
615 | NULL, style, validator, name); | |
a340b80d VZ |
616 | } |
617 | ||
618 | bool wxOwnerDrawnComboBox::Create(wxWindow *parent, | |
619 | wxWindowID id, | |
620 | const wxString& value, | |
621 | const wxPoint& pos, | |
622 | const wxSize& size, | |
623 | int n, | |
624 | const wxString choices[], | |
625 | long style, | |
626 | const wxValidator& validator, | |
627 | const wxString& name) | |
628 | { | |
629 | ||
630 | if ( !Create(parent, id, value, pos, size, style, | |
631 | validator, name) ) | |
632 | { | |
633 | return false; | |
634 | } | |
635 | ||
6d0ce565 VZ |
636 | int i; |
637 | for ( i=0; i<n; i++ ) | |
638 | m_initChs.Add(choices[i]); | |
a340b80d VZ |
639 | |
640 | return true; | |
641 | } | |
642 | ||
643 | wxOwnerDrawnComboBox::~wxOwnerDrawnComboBox() | |
644 | { | |
645 | if ( m_popupInterface ) | |
646 | m_popupInterface->ClearClientDatas(); | |
647 | } | |
648 | ||
6d0ce565 VZ |
649 | void wxOwnerDrawnComboBox::SetPopupControl( wxComboPopup* popup ) |
650 | { | |
651 | if ( !popup ) | |
652 | { | |
653 | popup = new wxVListBoxComboPopup(); | |
654 | } | |
655 | ||
a57d600f | 656 | wxComboCtrl::SetPopupControl(popup); |
6d0ce565 VZ |
657 | |
658 | wxASSERT(popup); | |
659 | m_popupInterface = (wxVListBoxComboPopup*) popup; | |
660 | ||
661 | // Add initial choices to the wxVListBox | |
662 | if ( !m_popupInterface->GetCount() ) | |
663 | { | |
664 | //m_popupInterface->Populate(m_initChs.GetCount(),m_initChs.GetStrings()); | |
665 | m_popupInterface->Populate(m_initChs); | |
666 | m_initChs.Clear(); | |
667 | } | |
668 | } | |
669 | ||
a340b80d VZ |
670 | // ---------------------------------------------------------------------------- |
671 | // wxOwnerDrawnComboBox item manipulation methods | |
672 | // ---------------------------------------------------------------------------- | |
673 | ||
674 | void wxOwnerDrawnComboBox::Clear() | |
675 | { | |
6d0ce565 | 676 | EnsurePopupControl(); |
a340b80d VZ |
677 | |
678 | m_popupInterface->Clear(); | |
679 | ||
680 | GetTextCtrl()->SetValue(wxEmptyString); | |
681 | } | |
682 | ||
683 | void wxOwnerDrawnComboBox::Delete(unsigned int n) | |
684 | { | |
85fed18c | 685 | wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Delete") ); |
a340b80d VZ |
686 | |
687 | if ( GetSelection() == (int) n ) | |
688 | SetValue(wxEmptyString); | |
689 | ||
690 | m_popupInterface->Delete(n); | |
691 | } | |
692 | ||
693 | unsigned int wxOwnerDrawnComboBox::GetCount() const | |
694 | { | |
6d0ce565 | 695 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
696 | return m_popupInterface->GetCount(); |
697 | } | |
698 | ||
699 | wxString wxOwnerDrawnComboBox::GetString(unsigned int n) const | |
700 | { | |
85fed18c | 701 | wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxOwnerDrawnComboBox::GetString") ); |
a340b80d VZ |
702 | return m_popupInterface->GetString(n); |
703 | } | |
704 | ||
705 | void wxOwnerDrawnComboBox::SetString(unsigned int n, const wxString& s) | |
706 | { | |
85fed18c | 707 | wxCHECK_RET( IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::SetString") ); |
a340b80d VZ |
708 | m_popupInterface->SetString(n,s); |
709 | } | |
710 | ||
711 | int wxOwnerDrawnComboBox::FindString(const wxString& s) const | |
712 | { | |
6d0ce565 | 713 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
714 | return m_popupInterface->FindString(s); |
715 | } | |
716 | ||
717 | void wxOwnerDrawnComboBox::Select(int n) | |
718 | { | |
85fed18c | 719 | wxCHECK_RET( (n == wxNOT_FOUND) || IsValid(n), _T("invalid index in wxOwnerDrawnComboBox::Select") ); |
6d0ce565 | 720 | EnsurePopupControl(); |
a340b80d VZ |
721 | |
722 | m_popupInterface->SetSelection(n); | |
723 | ||
724 | wxString str; | |
725 | if ( n >= 0 ) | |
726 | str = m_popupInterface->GetString(n); | |
727 | ||
728 | // Refresh text portion in control | |
729 | if ( m_text ) | |
730 | m_text->SetValue( str ); | |
731 | else | |
732 | m_valueString = str; | |
733 | ||
734 | Refresh(); | |
735 | } | |
736 | ||
737 | int wxOwnerDrawnComboBox::GetSelection() const | |
738 | { | |
6d0ce565 | 739 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
740 | return m_popupInterface->GetSelection(); |
741 | } | |
742 | ||
743 | int wxOwnerDrawnComboBox::DoAppend(const wxString& item) | |
744 | { | |
6d0ce565 VZ |
745 | EnsurePopupControl(); |
746 | wxASSERT(m_popupInterface); | |
a340b80d VZ |
747 | return m_popupInterface->Append(item); |
748 | } | |
749 | ||
750 | int wxOwnerDrawnComboBox::DoInsert(const wxString& item, unsigned int pos) | |
751 | { | |
752 | wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list")); | |
85fed18c | 753 | wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index")); |
a340b80d | 754 | |
6d0ce565 | 755 | EnsurePopupControl(); |
a340b80d VZ |
756 | m_popupInterface->Insert(item,pos); |
757 | ||
758 | return pos; | |
759 | } | |
760 | ||
761 | void wxOwnerDrawnComboBox::DoSetItemClientData(unsigned int n, void* clientData) | |
762 | { | |
6d0ce565 | 763 | EnsurePopupControl(); |
a340b80d VZ |
764 | m_popupInterface->SetItemClientData(n,clientData,m_clientDataItemsType); |
765 | } | |
766 | ||
767 | void* wxOwnerDrawnComboBox::DoGetItemClientData(unsigned int n) const | |
768 | { | |
6d0ce565 | 769 | wxASSERT_MSG( m_popupInterface, wxT("no popup interface") ); |
a340b80d VZ |
770 | return m_popupInterface->GetItemClientData(n); |
771 | } | |
772 | ||
773 | void wxOwnerDrawnComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) | |
774 | { | |
775 | DoSetItemClientData(n, (void*) clientData); | |
776 | } | |
777 | ||
778 | wxClientData* wxOwnerDrawnComboBox::DoGetItemClientObject(unsigned int n) const | |
779 | { | |
780 | return (wxClientData*) DoGetItemClientData(n); | |
781 | } | |
782 | ||
a57d600f | 783 | #endif // wxUSE_ODCOMBOBOX |