]> git.saurik.com Git - wxWidgets.git/blame - src/univ/combobox.cpp
revert removal of gtk1 code from common file
[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
7// RCS-ID: $Id$
442b35b5 8// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
65571936 9// Licence: wxWindows licence
1e6feb95
VZ
10/////////////////////////////////////////////////////////////////////////////
11
1e6feb95
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
1e6feb95
VZ
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"
8cb172b4 35 #include "wx/bmpbuttn.h"
1e6feb95
VZ
36
37 #include "wx/validate.h"
38#endif
39
d4e5272b 40#include "wx/tooltip.h"
a340b80d 41#include "wx/combo.h"
1e6feb95
VZ
42
43#include "wx/univ/renderer.h"
44#include "wx/univ/inphand.h"
45#include "wx/univ/theme.h"
46
1e6feb95
VZ
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
e051d008 57 wxComboListBox();
1e6feb95
VZ
58 virtual ~wxComboListBox();
59
60 // implement wxComboPopup methods
a340b80d
VZ
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);
1e6feb95 67
d2fde247
VZ
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
6f02a879
VZ
72 // used to process wxUniv actions
73 bool PerformAction(const wxControlAction& action,
74 long numArg,
75 const wxString& strArg);
76
1e6feb95 77protected:
55f095d4
VZ
78 // set m_clicked value from here
79 void OnLeftUp(wxMouseEvent& event);
80
1e6feb95 81private:
1e6feb95
VZ
82 DECLARE_EVENT_TABLE()
83};
84
85// ----------------------------------------------------------------------------
86// event tables and such
87// ----------------------------------------------------------------------------
88
1e6feb95 89BEGIN_EVENT_TABLE(wxComboListBox, wxListBox)
55f095d4 90 EVT_LEFT_UP(wxComboListBox::OnLeftUp)
1e6feb95
VZ
91END_EVENT_TABLE()
92
a57d600f 93IMPLEMENT_DYNAMIC_CLASS2(wxComboBox, wxControl, wxComboCtrl)
1e6feb95
VZ
94
95// ============================================================================
96// implementation
97// ============================================================================
98
99// ----------------------------------------------------------------------------
a340b80d 100// wxComboListBox
1e6feb95
VZ
101// ----------------------------------------------------------------------------
102
e051d008 103wxComboListBox::wxComboListBox() : wxListBox(), wxComboPopup()
1e6feb95 104{
1e6feb95
VZ
105}
106
a340b80d 107bool wxComboListBox::Create(wxWindow* parent)
1e6feb95 108{
a340b80d
VZ
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) )
a290fa5a 114 return false;
1e6feb95 115
a340b80d
VZ
116 // we don't react to the mouse events outside the window at all
117 StopAutoScrolling();
1e6feb95 118
a290fa5a 119 return true;
1e6feb95
VZ
120}
121
a340b80d 122wxComboListBox::~wxComboListBox()
1e6feb95 123{
1e6feb95
VZ
124}
125
a340b80d 126wxString wxComboListBox::GetStringValue() const
1e6feb95 127{
a340b80d 128 return wxListBox::GetStringSelection();
1e6feb95
VZ
129}
130
a340b80d 131void wxComboListBox::SetStringValue(const wxString& value)
1e6feb95 132{
615a96e3
JS
133 if ( !value.empty() )
134 {
135 if (FindString(value) != wxNOT_FOUND)
136 wxListBox::SetStringSelection(value);
137 }
a340b80d
VZ
138 else
139 wxListBox::SetSelection(-1);
1e6feb95
VZ
140}
141
a340b80d 142void wxComboListBox::OnPopup()
1e6feb95
VZ
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
a57d600f 155 // and this is done by wxComboCtrl itself
a290fa5a 156 return true;
1e6feb95
VZ
157 }
158
159 return wxListBox::PerformAction(action, numArg, strArg);
160}
161
55f095d4
VZ
162void wxComboListBox::OnLeftUp(wxMouseEvent& event)
163{
164 // we should dismiss the combo now
a340b80d
VZ
165 // first update the combo and close the listbox
166 Dismiss();
167 m_combo->SetValue(wxListBox::GetStringSelection());
55f095d4 168
a340b80d
VZ
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);
55f095d4 174
a340b80d 175 event.Skip();
e2ca829e
JS
176}
177
a340b80d
VZ
178wxSize wxComboListBox::GetAdjustedSize(int minWidth,
179 int WXUNUSED(prefHeight),
180 int maxHeight)
1e6feb95 181{
a340b80d
VZ
182 wxSize bestSize = wxListBox::GetBestSize();
183 return wxSize(wxMax(bestSize.x,minWidth),
184 wxMin(bestSize.y,maxHeight));
1e6feb95
VZ
185}
186
187// ----------------------------------------------------------------------------
188// wxComboBox
189// ----------------------------------------------------------------------------
190
191void wxComboBox::Init()
192{
193 m_lbox = (wxListBox *)NULL;
194}
195
584ad2a3
MB
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
1e6feb95
VZ
227bool wxComboBox::Create(wxWindow *parent,
228 wxWindowID id,
229 const wxString& value,
230 const wxPoint& pos,
231 const wxSize& size,
232 int n,
ba1e9d6c 233 const wxString choices[],
1e6feb95
VZ
234 long style,
235 const wxValidator& validator,
236 const wxString& name)
237{
a57d600f 238 if ( !wxComboCtrl::Create(parent, id, value, pos, size, style,
1e6feb95
VZ
239 validator, name) )
240 {
a290fa5a 241 return false;
1e6feb95
VZ
242 }
243
e051d008 244 wxComboListBox *combolbox = new wxComboListBox();
a340b80d
VZ
245 SetPopupControl(combolbox);
246
1e6feb95
VZ
247 m_lbox = combolbox;
248 m_lbox->Set(n, choices);
249
a290fa5a 250 return true;
1e6feb95
VZ
251}
252
253wxComboBox::~wxComboBox()
254{
255}
256
257// ----------------------------------------------------------------------------
258// wxComboBox methods forwarded to wxTextCtrl
259// ----------------------------------------------------------------------------
260
261wxString wxComboBox::GetValue() const
262{
a57d600f 263 return wxComboCtrl::GetValue();
1e6feb95
VZ
264}
265
266void wxComboBox::SetValue(const wxString& value)
267{
a57d600f 268 wxComboCtrl::SetValue(value);
1e6feb95
VZ
269}
270
271void wxComboBox::Copy()
272{
a340b80d 273 if ( GetTextCtrl() ) GetTextCtrl()->Copy();
1e6feb95
VZ
274}
275
276void wxComboBox::Cut()
277{
a340b80d 278 if ( GetTextCtrl() ) GetTextCtrl()->Cut();
1e6feb95
VZ
279}
280
281void wxComboBox::Paste()
282{
a340b80d 283 if ( GetTextCtrl() ) GetTextCtrl()->Paste();
1e6feb95
VZ
284}
285
286void wxComboBox::SetInsertionPoint(long pos)
287{
a340b80d 288 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPoint(pos);
1e6feb95
VZ
289}
290
291void wxComboBox::SetInsertionPointEnd()
292{
a340b80d 293 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPointEnd();
1e6feb95
VZ
294}
295
296long wxComboBox::GetInsertionPoint() const
297{
a340b80d
VZ
298 if ( GetTextCtrl() )
299 return GetTextCtrl()->GetInsertionPoint();
300 return -1;
1e6feb95
VZ
301}
302
7d8268a1 303wxTextPos wxComboBox::GetLastPosition() const
1e6feb95 304{
a340b80d
VZ
305 if ( GetTextCtrl() )
306 return GetTextCtrl()->GetLastPosition();
307 return -1;
1e6feb95
VZ
308}
309
310void wxComboBox::Replace(long from, long to, const wxString& value)
311{
a340b80d 312 if ( GetTextCtrl() ) GetTextCtrl()->Replace(from, to, value);
1e6feb95
VZ
313}
314
315void wxComboBox::Remove(long from, long to)
316{
a340b80d 317 if ( GetTextCtrl() ) GetTextCtrl()->Remove(from, to);
1e6feb95
VZ
318}
319
320void wxComboBox::SetSelection(long from, long to)
321{
a340b80d 322 if ( GetTextCtrl() ) GetTextCtrl()->SetSelection(from, to);
1e6feb95
VZ
323}
324
325void wxComboBox::SetEditable(bool editable)
326{
a340b80d 327 if ( GetTextCtrl() ) GetTextCtrl()->SetEditable(editable);
1e6feb95
VZ
328}
329
330// ----------------------------------------------------------------------------
331// wxComboBox methods forwarded to wxListBox
332// ----------------------------------------------------------------------------
333
334void wxComboBox::Clear()
335{
336 GetLBox()->Clear();
a340b80d 337 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(wxEmptyString);
1e6feb95
VZ
338}
339
aa61d352 340void wxComboBox::Delete(unsigned int n)
1e6feb95 341{
8228b893 342 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::Delete") );
48aa18c0 343
aa61d352 344 if (GetSelection() == (int)n)
a340b80d 345 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(wxEmptyString);
48aa18c0 346
1e6feb95
VZ
347 GetLBox()->Delete(n);
348}
349
aa61d352 350unsigned int wxComboBox::GetCount() const
1e6feb95
VZ
351{
352 return GetLBox()->GetCount();
353}
354
aa61d352 355wxString wxComboBox::GetString(unsigned int n) const
1e6feb95 356{
8228b893 357 wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxComboBox::GetString") );
48aa18c0 358
1e6feb95
VZ
359 return GetLBox()->GetString(n);
360}
361
aa61d352 362void wxComboBox::SetString(unsigned int n, const wxString& s)
1e6feb95 363{
8228b893 364 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::SetString") );
48aa18c0 365
1e6feb95
VZ
366 GetLBox()->SetString(n, s);
367}
368
11e62fe6 369int wxComboBox::FindString(const wxString& s, bool bCase) const
1e6feb95 370{
11e62fe6 371 return GetLBox()->FindString(s, bCase);
1e6feb95
VZ
372}
373
c6179a84 374void wxComboBox::SetSelection(int n)
1e6feb95 375{
8228b893 376 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::Select") );
1e6feb95
VZ
377
378 GetLBox()->SetSelection(n);
a340b80d 379 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(GetLBox()->GetString(n));
1e6feb95
VZ
380}
381
382int wxComboBox::GetSelection() const
383{
48aa18c0 384#if 1 // FIXME:: What is the correct behavior?
1e6feb95 385 // if the current value isn't one of the listbox strings, return -1
48aa18c0 386 return GetLBox()->GetSelection();
150e31d2
JS
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
48aa18c0 390 // in the list that it is the item that is selected!
a340b80d 391 return FindString(if ( GetTextCtrl() ) GetTextCtrl()->GetValue());
48aa18c0 392#endif
1e6feb95
VZ
393}
394
395int wxComboBox::DoAppend(const wxString& item)
396{
397 return GetLBox()->Append(item);
398}
399
aa61d352 400int wxComboBox::DoInsert(const wxString& item, unsigned int pos)
243dbf1a
VZ
401{
402 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
8228b893 403 wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index"));
243dbf1a 404
aa61d352 405 if (pos == GetCount())
243dbf1a
VZ
406 return DoAppend(item);
407
3f85391e 408 GetLBox()->Insert(item, pos);
243dbf1a
VZ
409 return pos;
410}
411
aa61d352 412void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData)
1e6feb95
VZ
413{
414 GetLBox()->SetClientData(n, clientData);
415}
416
aa61d352 417void *wxComboBox::DoGetItemClientData(unsigned int n) const
1e6feb95
VZ
418{
419 return GetLBox()->GetClientData(n);
420}
421
aa61d352 422void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData)
1e6feb95
VZ
423{
424 GetLBox()->SetClientObject(n, clientData);
425}
426
aa61d352 427wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const
1e6feb95
VZ
428{
429 return GetLBox()->GetClientObject(n);
430}
431
150e31d2
JS
432bool wxComboBox::IsEditable() const
433{
a340b80d 434 return GetTextCtrl() != NULL && (!HasFlag(wxCB_READONLY) || GetTextCtrl()->IsEditable() );
150e31d2
JS
435}
436
437void wxComboBox::Undo()
438{
439 if (IsEditable())
a340b80d 440 if ( GetTextCtrl() ) GetTextCtrl()->Undo();
150e31d2
JS
441}
442
443void wxComboBox::Redo()
444{
445 if (IsEditable())
a340b80d 446 if ( GetTextCtrl() ) GetTextCtrl()->Redo();
150e31d2
JS
447}
448
449void wxComboBox::SelectAll()
450{
a340b80d 451 if ( GetTextCtrl() ) GetTextCtrl()->SelectAll();
150e31d2
JS
452}
453
454bool wxComboBox::CanCopy() const
455{
a340b80d
VZ
456 if (GetTextCtrl() != NULL)
457 return GetTextCtrl()->CanCopy();
150e31d2
JS
458 else
459 return false;
460}
461
462bool wxComboBox::CanCut() const
463{
a340b80d
VZ
464 if (GetTextCtrl() != NULL)
465 return GetTextCtrl()->CanCut();
150e31d2
JS
466 else
467 return false;
468}
469
470bool wxComboBox::CanPaste() const
471{
472 if (IsEditable())
a340b80d 473 return GetTextCtrl()->CanPaste();
150e31d2
JS
474 else
475 return false;
476}
477
478bool wxComboBox::CanUndo() const
479{
480 if (IsEditable())
a340b80d 481 return GetTextCtrl()->CanUndo();
150e31d2
JS
482 else
483 return false;
484}
485
486bool wxComboBox::CanRedo() const
487{
488 if (IsEditable())
a340b80d 489 return GetTextCtrl()->CanRedo();
150e31d2
JS
490 else
491 return false;
492}
493
494
1e6feb95
VZ
495// ----------------------------------------------------------------------------
496// wxStdComboBoxInputHandler
497// ----------------------------------------------------------------------------
498
499wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
500 : wxStdInputHandler(inphand)
501{
502}
503
23645bfa 504bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer,
1e6feb95
VZ
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
a290fa5a 522 if ( !action.IsEmpty() )
1e6feb95 523 {
23645bfa 524 consumer->PerformAction(action);
1e6feb95 525
a290fa5a 526 return true;
1e6feb95
VZ
527 }
528 }
529
23645bfa 530 return wxStdInputHandler::HandleKey(consumer, event, pressed);
1e6feb95
VZ
531}
532
a340b80d 533
1e6feb95 534#endif // wxUSE_COMBOBOX