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