]> git.saurik.com Git - wxWidgets.git/blame - src/univ/combobox.cpp
Remove DoSetSizeHints() call from Create()
[wxWidgets.git] / src / univ / combobox.cpp
CommitLineData
1e6feb95 1/////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/univ/combobox.cpp
6d0ce565 3// Purpose: wxComboBox implementation
1e6feb95
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 15.12.00
442b35b5 7// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
65571936 8// Licence: wxWindows licence
1e6feb95
VZ
9/////////////////////////////////////////////////////////////////////////////
10
1e6feb95
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
1e6feb95
VZ
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
22 #pragma hdrstop
23#endif
24
25#if wxUSE_COMBOBOX
26
27#ifndef WX_PRECOMP
28 #include "wx/log.h"
29
30 #include "wx/button.h"
31 #include "wx/combobox.h"
32 #include "wx/listbox.h"
33 #include "wx/textctrl.h"
8cb172b4 34 #include "wx/bmpbuttn.h"
1e6feb95
VZ
35
36 #include "wx/validate.h"
37#endif
38
d4e5272b 39#include "wx/tooltip.h"
a340b80d 40#include "wx/combo.h"
1e6feb95
VZ
41
42#include "wx/univ/renderer.h"
43#include "wx/univ/inphand.h"
44#include "wx/univ/theme.h"
45
9467bdb7
VZ
46// ----------------------------------------------------------------------------
47// wxStdComboBoxInputHandler: allows the user to open/close the combo from kbd
48// ----------------------------------------------------------------------------
49
50class WXDLLEXPORT wxStdComboBoxInputHandler : public wxStdInputHandler
51{
52public:
53 wxStdComboBoxInputHandler(wxInputHandler *inphand);
54
55 virtual bool HandleKey(wxInputConsumer *consumer,
56 const wxKeyEvent& event,
57 bool pressed);
58};
1e6feb95
VZ
59
60// ----------------------------------------------------------------------------
61// wxComboListBox is a listbox modified to be used as a popup window in a
62// combobox
63// ----------------------------------------------------------------------------
64
65class wxComboListBox : public wxListBox, public wxComboPopup
66{
67public:
68 // ctor and dtor
e051d008 69 wxComboListBox();
1e6feb95
VZ
70 virtual ~wxComboListBox();
71
72 // implement wxComboPopup methods
a340b80d
VZ
73 virtual bool Create(wxWindow* parent);
74 virtual void SetStringValue(const wxString& s);
75 virtual wxString GetStringValue() const;
76 virtual wxWindow *GetControl() { return this; }
77 virtual void OnPopup();
78 virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
1e6feb95 79
d2fde247
VZ
80 // fix virtual function hiding
81 virtual void SetSelection(int n) { DoSetSelection(n, true); }
82 void SetSelection(int n, bool select) { DoSetSelection(n, select); }
83
6f02a879
VZ
84 // used to process wxUniv actions
85 bool PerformAction(const wxControlAction& action,
86 long numArg,
87 const wxString& strArg);
88
1e6feb95 89protected:
55f095d4
VZ
90 // set m_clicked value from here
91 void OnLeftUp(wxMouseEvent& event);
92
1e6feb95 93private:
131b1fba
VZ
94 friend class wxComboBox; // it accesses our DoGetItemClientData()
95
1e6feb95
VZ
96 DECLARE_EVENT_TABLE()
97};
98
99// ----------------------------------------------------------------------------
100// event tables and such
101// ----------------------------------------------------------------------------
102
1e6feb95 103BEGIN_EVENT_TABLE(wxComboListBox, wxListBox)
55f095d4 104 EVT_LEFT_UP(wxComboListBox::OnLeftUp)
1e6feb95
VZ
105END_EVENT_TABLE()
106
1e6feb95
VZ
107// ============================================================================
108// implementation
109// ============================================================================
110
111// ----------------------------------------------------------------------------
a340b80d 112// wxComboListBox
1e6feb95
VZ
113// ----------------------------------------------------------------------------
114
e051d008 115wxComboListBox::wxComboListBox() : wxListBox(), wxComboPopup()
1e6feb95 116{
1e6feb95
VZ
117}
118
a340b80d 119bool wxComboListBox::Create(wxWindow* parent)
1e6feb95 120{
a340b80d
VZ
121 if ( !wxListBox::Create(parent, wxID_ANY,
122 wxDefaultPosition, wxDefaultSize,
123 0, NULL,
750040fa
WS
124 wxBORDER_SIMPLE |
125 ( m_combo->GetWindowStyle() & wxCB_SORT ? wxLB_SORT : 0 ) ) )
a290fa5a 126 return false;
1e6feb95 127
a340b80d
VZ
128 // we don't react to the mouse events outside the window at all
129 StopAutoScrolling();
1e6feb95 130
a290fa5a 131 return true;
1e6feb95
VZ
132}
133
a340b80d 134wxComboListBox::~wxComboListBox()
1e6feb95 135{
1e6feb95
VZ
136}
137
a340b80d 138wxString wxComboListBox::GetStringValue() const
1e6feb95 139{
a340b80d 140 return wxListBox::GetStringSelection();
1e6feb95
VZ
141}
142
a340b80d 143void wxComboListBox::SetStringValue(const wxString& value)
1e6feb95 144{
615a96e3
JS
145 if ( !value.empty() )
146 {
f6fc052a
JS
147 if (FindString(value) != wxNOT_FOUND)
148 wxListBox::SetStringSelection(value);
149 }
a340b80d
VZ
150 else
151 wxListBox::SetSelection(-1);
1e6feb95
VZ
152}
153
a340b80d 154void wxComboListBox::OnPopup()
1e6feb95
VZ
155{
156}
157
158bool wxComboListBox::PerformAction(const wxControlAction& action,
159 long numArg,
160 const wxString& strArg)
161
162{
163 if ( action == wxACTION_LISTBOX_FIND )
164 {
165 // we don't let the listbox handle this as instead of just using the
166 // single key presses, as usual, we use the text ctrl value as prefix
a57d600f 167 // and this is done by wxComboCtrl itself
a290fa5a 168 return true;
1e6feb95
VZ
169 }
170
171 return wxListBox::PerformAction(action, numArg, strArg);
172}
173
55f095d4
VZ
174void wxComboListBox::OnLeftUp(wxMouseEvent& event)
175{
176 // we should dismiss the combo now
a340b80d
VZ
177 // first update the combo and close the listbox
178 Dismiss();
179 m_combo->SetValue(wxListBox::GetStringSelection());
55f095d4 180
a340b80d 181 // next let the user code have the event
ce7fe42e 182 wxCommandEvent evt(wxEVT_COMBOBOX,m_combo->GetId());
a340b80d
VZ
183 evt.SetInt(wxListBox::GetSelection());
184 evt.SetEventObject(m_combo);
3b7fa206 185 m_combo->ProcessWindowEvent(evt);
55f095d4 186
a340b80d 187 event.Skip();
e2ca829e
JS
188}
189
a340b80d
VZ
190wxSize wxComboListBox::GetAdjustedSize(int minWidth,
191 int WXUNUSED(prefHeight),
192 int maxHeight)
1e6feb95 193{
a340b80d
VZ
194 wxSize bestSize = wxListBox::GetBestSize();
195 return wxSize(wxMax(bestSize.x,minWidth),
196 wxMin(bestSize.y,maxHeight));
1e6feb95
VZ
197}
198
199// ----------------------------------------------------------------------------
200// wxComboBox
201// ----------------------------------------------------------------------------
202
203void wxComboBox::Init()
204{
d3b9f782 205 m_lbox = NULL;
1e6feb95
VZ
206}
207
584ad2a3
MB
208wxComboBox::wxComboBox(wxWindow *parent,
209 wxWindowID id,
210 const wxString& value,
211 const wxPoint& pos,
212 const wxSize& size,
213 const wxArrayString& choices,
214 long style,
215 const wxValidator& validator,
216 const wxString& name)
217{
218 Init();
219
220 Create(parent, id, value, pos, size, choices, style, validator, name);
221}
222
223bool wxComboBox::Create(wxWindow *parent,
224 wxWindowID id,
225 const wxString& value,
226 const wxPoint& pos,
227 const wxSize& size,
228 const wxArrayString& choices,
229 long style,
230 const wxValidator& validator,
231 const wxString& name)
232{
233 wxCArrayString chs(choices);
234
235 return Create(parent, id, value, pos, size, chs.GetCount(),
236 chs.GetStrings(), style, validator, name);
237}
238
1e6feb95
VZ
239bool wxComboBox::Create(wxWindow *parent,
240 wxWindowID id,
241 const wxString& value,
242 const wxPoint& pos,
243 const wxSize& size,
244 int n,
ba1e9d6c 245 const wxString choices[],
1e6feb95
VZ
246 long style,
247 const wxValidator& validator,
248 const wxString& name)
249{
a57d600f 250 if ( !wxComboCtrl::Create(parent, id, value, pos, size, style,
1e6feb95
VZ
251 validator, name) )
252 {
a290fa5a 253 return false;
1e6feb95
VZ
254 }
255
e051d008 256 wxComboListBox *combolbox = new wxComboListBox();
a340b80d
VZ
257 SetPopupControl(combolbox);
258
1e6feb95
VZ
259 m_lbox = combolbox;
260 m_lbox->Set(n, choices);
261
a290fa5a 262 return true;
1e6feb95
VZ
263}
264
265wxComboBox::~wxComboBox()
266{
267}
268
269// ----------------------------------------------------------------------------
270// wxComboBox methods forwarded to wxTextCtrl
271// ----------------------------------------------------------------------------
272
3373e900 273wxString wxComboBox::DoGetValue() const
1e6feb95 274{
59060c07 275 return GetTextCtrl() ? GetTextCtrl()->GetValue() : m_valueString;
1e6feb95
VZ
276}
277
278void wxComboBox::SetValue(const wxString& value)
279{
0aae39ef
VZ
280 if ( GetTextCtrl() )
281 GetTextCtrl()->SetValue(value);
59060c07
VZ
282 else
283 m_valueString = value;
1e6feb95
VZ
284}
285
0ec1179b
VZ
286void wxComboBox::WriteText(const wxString& value)
287{
288 if ( GetTextCtrl() ) GetTextCtrl()->WriteText(value);
289}
290
1e6feb95
VZ
291void wxComboBox::Copy()
292{
a340b80d 293 if ( GetTextCtrl() ) GetTextCtrl()->Copy();
1e6feb95
VZ
294}
295
296void wxComboBox::Cut()
297{
a340b80d 298 if ( GetTextCtrl() ) GetTextCtrl()->Cut();
1e6feb95
VZ
299}
300
301void wxComboBox::Paste()
302{
a340b80d 303 if ( GetTextCtrl() ) GetTextCtrl()->Paste();
1e6feb95
VZ
304}
305
306void wxComboBox::SetInsertionPoint(long pos)
307{
a340b80d 308 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPoint(pos);
1e6feb95
VZ
309}
310
311void wxComboBox::SetInsertionPointEnd()
312{
a340b80d 313 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPointEnd();
1e6feb95
VZ
314}
315
316long wxComboBox::GetInsertionPoint() const
317{
a340b80d
VZ
318 if ( GetTextCtrl() )
319 return GetTextCtrl()->GetInsertionPoint();
320 return -1;
1e6feb95
VZ
321}
322
7d8268a1 323wxTextPos wxComboBox::GetLastPosition() const
1e6feb95 324{
a340b80d
VZ
325 if ( GetTextCtrl() )
326 return GetTextCtrl()->GetLastPosition();
327 return -1;
1e6feb95
VZ
328}
329
330void wxComboBox::Replace(long from, long to, const wxString& value)
331{
a340b80d 332 if ( GetTextCtrl() ) GetTextCtrl()->Replace(from, to, value);
1e6feb95
VZ
333}
334
335void wxComboBox::Remove(long from, long to)
336{
a340b80d 337 if ( GetTextCtrl() ) GetTextCtrl()->Remove(from, to);
1e6feb95
VZ
338}
339
340void wxComboBox::SetSelection(long from, long to)
341{
a340b80d 342 if ( GetTextCtrl() ) GetTextCtrl()->SetSelection(from, to);
1e6feb95
VZ
343}
344
0ec1179b
VZ
345void wxComboBox::GetSelection(long *from, long *to) const
346{
347 if ( GetTextCtrl() ) GetTextCtrl()->GetSelection(from, to);
348}
349
1e6feb95
VZ
350void wxComboBox::SetEditable(bool editable)
351{
a340b80d 352 if ( GetTextCtrl() ) GetTextCtrl()->SetEditable(editable);
1e6feb95
VZ
353}
354
355// ----------------------------------------------------------------------------
356// wxComboBox methods forwarded to wxListBox
357// ----------------------------------------------------------------------------
358
a236aa20 359void wxComboBox::DoClear()
1e6feb95
VZ
360{
361 GetLBox()->Clear();
59060c07 362 SetValue(wxEmptyString);
1e6feb95
VZ
363}
364
a236aa20 365void wxComboBox::DoDeleteOneItem(unsigned int n)
1e6feb95 366{
9a83f860 367 wxCHECK_RET( IsValid(n), wxT("invalid index in wxComboBox::Delete") );
48aa18c0 368
aa61d352 369 if (GetSelection() == (int)n)
59060c07 370 SetValue(wxEmptyString);
48aa18c0 371
1e6feb95
VZ
372 GetLBox()->Delete(n);
373}
374
aa61d352 375unsigned int wxComboBox::GetCount() const
1e6feb95
VZ
376{
377 return GetLBox()->GetCount();
378}
379
aa61d352 380wxString wxComboBox::GetString(unsigned int n) const
1e6feb95 381{
9a83f860 382 wxCHECK_MSG( IsValid(n), wxEmptyString, wxT("invalid index in wxComboBox::GetString") );
48aa18c0 383
1e6feb95
VZ
384 return GetLBox()->GetString(n);
385}
386
aa61d352 387void wxComboBox::SetString(unsigned int n, const wxString& s)
1e6feb95 388{
9a83f860 389 wxCHECK_RET( IsValid(n), wxT("invalid index in wxComboBox::SetString") );
48aa18c0 390
1e6feb95
VZ
391 GetLBox()->SetString(n, s);
392}
393
11e62fe6 394int wxComboBox::FindString(const wxString& s, bool bCase) const
1e6feb95 395{
11e62fe6 396 return GetLBox()->FindString(s, bCase);
1e6feb95
VZ
397}
398
c6179a84 399void wxComboBox::SetSelection(int n)
1e6feb95 400{
9a83f860 401 wxCHECK_RET( (n == wxNOT_FOUND || IsValid(n)), wxT("invalid index in wxComboBox::Select") );
1e6feb95
VZ
402
403 GetLBox()->SetSelection(n);
365271b5 404
75a788ee
VZ
405 wxString str;
406 if ( n != wxNOT_FOUND )
407 str = GetLBox()->GetString(n);
408
409 SetText(str);
1e6feb95
VZ
410}
411
412int wxComboBox::GetSelection() const
413{
4c51a665 414#if 1 // FIXME:: What is the correct behaviour?
1e6feb95 415 // if the current value isn't one of the listbox strings, return -1
48aa18c0 416 return GetLBox()->GetSelection();
150e31d2
JS
417#else
418 // Why oh why is this done this way?
419 // It is not because the value displayed in the text can be found
48aa18c0 420 // in the list that it is the item that is selected!
a340b80d 421 return FindString(if ( GetTextCtrl() ) GetTextCtrl()->GetValue());
48aa18c0 422#endif
1e6feb95
VZ
423}
424
0ec1179b
VZ
425wxString wxComboBox::GetStringSelection() const
426{
427 return GetLBox()->GetStringSelection();
428}
429
b152d8c5
VZ
430wxClientDataType wxComboBox::GetClientDataType() const
431{
432 return GetLBox()->GetClientDataType();
433}
434
131b1fba
VZ
435void wxComboBox::SetClientDataType(wxClientDataType clientDataItemsType)
436{
437 GetLBox()->SetClientDataType(clientDataItemsType);
438}
439
a236aa20
VZ
440int wxComboBox::DoInsertItems(const wxArrayStringsAdapter & items,
441 unsigned int pos,
442 void **clientData, wxClientDataType type)
1e6feb95 443{
a236aa20 444 return GetLBox()->DoInsertItems(items, pos, clientData, type);
243dbf1a
VZ
445}
446
aa61d352 447void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData)
1e6feb95 448{
131b1fba 449 GetLBox()->DoSetItemClientData(n, clientData);
1e6feb95
VZ
450}
451
aa61d352 452void *wxComboBox::DoGetItemClientData(unsigned int n) const
1e6feb95 453{
131b1fba 454 return GetLBox()->DoGetItemClientData(n);
1e6feb95
VZ
455}
456
150e31d2
JS
457bool wxComboBox::IsEditable() const
458{
a340b80d 459 return GetTextCtrl() != NULL && (!HasFlag(wxCB_READONLY) || GetTextCtrl()->IsEditable() );
150e31d2
JS
460}
461
462void wxComboBox::Undo()
463{
464 if (IsEditable())
a340b80d 465 if ( GetTextCtrl() ) GetTextCtrl()->Undo();
150e31d2
JS
466}
467
468void wxComboBox::Redo()
469{
470 if (IsEditable())
a340b80d 471 if ( GetTextCtrl() ) GetTextCtrl()->Redo();
150e31d2
JS
472}
473
474void wxComboBox::SelectAll()
475{
a340b80d 476 if ( GetTextCtrl() ) GetTextCtrl()->SelectAll();
150e31d2
JS
477}
478
479bool wxComboBox::CanCopy() const
480{
a340b80d
VZ
481 if (GetTextCtrl() != NULL)
482 return GetTextCtrl()->CanCopy();
150e31d2
JS
483 else
484 return false;
485}
486
487bool wxComboBox::CanCut() const
488{
a340b80d
VZ
489 if (GetTextCtrl() != NULL)
490 return GetTextCtrl()->CanCut();
150e31d2
JS
491 else
492 return false;
493}
494
495bool wxComboBox::CanPaste() const
496{
497 if (IsEditable())
a340b80d 498 return GetTextCtrl()->CanPaste();
150e31d2
JS
499 else
500 return false;
501}
502
503bool wxComboBox::CanUndo() const
504{
505 if (IsEditable())
a340b80d 506 return GetTextCtrl()->CanUndo();
150e31d2
JS
507 else
508 return false;
509}
510
511bool wxComboBox::CanRedo() const
512{
513 if (IsEditable())
a340b80d 514 return GetTextCtrl()->CanRedo();
150e31d2
JS
515 else
516 return false;
517}
518
519
1e6feb95
VZ
520// ----------------------------------------------------------------------------
521// wxStdComboBoxInputHandler
522// ----------------------------------------------------------------------------
523
524wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
525 : wxStdInputHandler(inphand)
526{
527}
528
23645bfa 529bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer,
1e6feb95
VZ
530 const wxKeyEvent& event,
531 bool pressed)
532{
533 if ( pressed )
534 {
535 wxControlAction action;
536 switch ( event.GetKeyCode() )
537 {
538 case WXK_DOWN:
539 action = wxACTION_COMBOBOX_POPUP;
540 break;
541
542 case WXK_ESCAPE:
543 action = wxACTION_COMBOBOX_DISMISS;
544 break;
545 }
546
a290fa5a 547 if ( !action.IsEmpty() )
1e6feb95 548 {
23645bfa 549 consumer->PerformAction(action);
1e6feb95 550
a290fa5a 551 return true;
1e6feb95
VZ
552 }
553 }
554
23645bfa 555 return wxStdInputHandler::HandleKey(consumer, event, pressed);
1e6feb95
VZ
556}
557
9467bdb7
VZ
558/* static */
559wxInputHandler *wxComboBox::GetStdInputHandler(wxInputHandler *handlerDef)
560{
561 static wxStdComboBoxInputHandler s_handler(handlerDef);
562
563 return &s_handler;
564}
a340b80d 565
1e6feb95 566#endif // wxUSE_COMBOBOX