]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/combobox.cpp
corrected scrolling problems for controls, switched to wxSpinCtrl
[wxWidgets.git] / src / mac / carbon / combobox.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: combobox.cpp
3// Purpose: wxComboBox class
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
465605e0 9// Licence: wxWindows licence
e9576ca5
SC
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "combobox.h"
14#endif
15
16#include "wx/combobox.h"
03e11df5 17#include "wx/menu.h"
519cb848 18#include "wx/mac/uma.h"
e9576ca5 19
2f1ae414 20#if !USE_SHARED_LIBRARY
e9576ca5 21IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
2f1ae414 22#endif
e9576ca5 23
12f31626
SC
24// composite combobox implementation by Dan "Bud" Keith bud@otsys.com
25
519cb848 26
0e03d1fa 27static int nextPopUpMenuId = 1000 ;
892e461e
SC
28MenuHandle NewUniqueMenu()
29{
30 MenuHandle handle = NewMenu( nextPopUpMenuId , "\pMenu" ) ;
31 nextPopUpMenuId++ ;
32 return handle ;
33}
519cb848 34
12f31626
SC
35
36// ----------------------------------------------------------------------------
37// constants
38// ----------------------------------------------------------------------------
39
40// the margin between the text control and the choice
41static const wxCoord MARGIN = 2;
42static const int POPUPWIDTH = 18;
43static const int POPUPHEIGHT = 23;
44
45
46// ----------------------------------------------------------------------------
47// wxComboBoxText: text control forwards events to combobox
48// ----------------------------------------------------------------------------
49
50class wxComboBoxText : public wxTextCtrl
51{
52public:
53 wxComboBoxText( wxComboBox * cb )
54 : wxTextCtrl( cb->GetParent(), 1 )
55 {
56 m_cb = cb;
57 }
58
59protected:
60 void OnTextChange( wxCommandEvent& event )
61 {
62 wxString s = GetValue();
22a70443
RR
63
64 if (!s.IsEmpty())
65 m_cb->DelegateTextChanged( s );
12f31626
SC
66
67 event.Skip();
68 }
69
70private:
71 wxComboBox *m_cb;
72
73 DECLARE_EVENT_TABLE()
74};
75
76BEGIN_EVENT_TABLE(wxComboBoxText, wxTextCtrl)
77 EVT_TEXT(-1, wxComboBoxText::OnTextChange)
78END_EVENT_TABLE()
79
80class wxComboBoxChoice : public wxChoice
81{
82public:
83 wxComboBoxChoice(wxComboBox *cb, int style)
84 : wxChoice( cb->GetParent(), 1 )
85 {
86 m_cb = cb;
87 }
88
89protected:
90 void OnChoice( wxCommandEvent& e )
91 {
92 wxString s = e.GetString();
93
94 m_cb->DelegateChoice( s );
95 }
96
97private:
98 wxComboBox *m_cb;
99
100 DECLARE_EVENT_TABLE()
101};
102
103BEGIN_EVENT_TABLE(wxComboBoxChoice, wxChoice)
104 EVT_CHOICE(-1, wxComboBoxChoice::OnChoice)
105END_EVENT_TABLE()
106
12f31626
SC
107wxComboBox::~wxComboBox()
108{
f5bb2251 109 // delete the controls now, don't leave them alive even though they would
12f31626
SC
110 // still be eventually deleted by our parent - but it will be too late, the
111 // user code expects them to be gone now
f5bb2251
GD
112 if (m_text != NULL) {
113 delete m_text;
114 m_text = NULL;
115 }
116 if (m_choice != NULL) {
117 delete m_choice;
118 m_choice = NULL;
119 }
12f31626
SC
120}
121
122
123// ----------------------------------------------------------------------------
124// geometry
125// ----------------------------------------------------------------------------
126
127wxSize wxComboBox::DoGetBestSize() const
128{
129 wxSize size = m_choice->GetBestSize();
130
131 if ( m_text != 0 )
132 {
133 wxSize sizeText = m_text->GetBestSize();
134
135 size.x = POPUPWIDTH + sizeText.x + MARGIN;
136 }
137
138 return size;
139}
140
141void wxComboBox::DoMoveWindow(int x, int y, int width, int height) {
142 height = POPUPHEIGHT;
143
144 wxControl::DoMoveWindow(x, y, width, height);
145
146 if ( m_text == 0 )
147 {
148 m_choice->SetSize(x, y, width, -1);
149 }
150 else
151 {
152 wxCoord wText = width - POPUPWIDTH;
153 m_text->SetSize(x, y, wText, height);
154 m_choice->SetSize(x + wText + MARGIN, y, POPUPWIDTH, -1);
155 }
156}
157
158
159
160// ----------------------------------------------------------------------------
161// operations forwarded to the subcontrols
162// ----------------------------------------------------------------------------
163
164bool wxComboBox::Enable(bool enable)
165{
166 if ( !wxControl::Enable(enable) )
167 return FALSE;
168
169 m_choice->Enable(enable);
170
171 if ( m_text != 0 )
172 {
173 m_text->Enable(enable);
174 }
175
176 return TRUE;
177}
178
179bool wxComboBox::Show(bool show)
180{
181 if ( !wxControl::Show(show) )
182 return FALSE;
183
184 // under GTK Show() is called the first time before we are fully
185 // constructed
186 if ( m_choice )
187 {
188 m_choice->Show(show);
189 if ( m_text != 0 )
190 {
191 m_text->Show(show);
192 }
193 }
194
195 return TRUE;
196}
197
465605e0
RR
198 void wxComboBox::SetFocus()
199 {
200 m_text->SetFocus();
201 }
202
12f31626
SC
203
204void wxComboBox::DelegateTextChanged( const wxString& value ) {
205}
206
207
208void wxComboBox::DelegateChoice( const wxString& value )
209{
210 SetStringSelection( value );
211}
212
213
e9576ca5
SC
214bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
215 const wxString& value,
216 const wxPoint& pos,
217 const wxSize& size,
465605e0
RR
218 int n, const wxString choices[],
219 long style,
e9576ca5
SC
220 const wxValidator& validator,
221 const wxString& name)
222{
12f31626
SC
223
224 Rect bounds ;
225 Str255 title ;
226
227 if ( !wxControl::Create(parent, id, pos, size, style,
228 wxDefaultValidator, name) )
229 {
230 return FALSE;
231 }
232
233 m_choice = new wxComboBoxChoice(this, style);
234
235 wxSize csize = size;
236 if ( style & wxCB_READONLY )
237 {
238 m_text = 0;
239 }
240 else
241 {
242 m_text = new wxComboBoxText(this);
243 if ( size.y == -1 ) {
244 csize.y = m_text->GetSize().y ;
245 }
246 }
247
248 DoSetSize(pos.x, pos.y, csize.x, csize.y);
249 for ( int i = 0 ; i < n ; i++ )
250 {
465605e0 251 m_choice->DoAppend( choices[ i ] );
12f31626
SC
252 }
253
254 // have to disable this window to avoid interfering it with message
255 // processing to the text and the button... but pretend it is enabled to
256 // make IsEnabled() return TRUE
257 wxControl::Enable(FALSE); // don't use non virtual Disable() here!
258 m_isEnabled = TRUE;
259
260 // we don't even need to show this window itself - and not doing it avoids
261 // that it overwrites the text control
262 wxControl::Show(FALSE);
263
264 return TRUE;
e9576ca5
SC
265}
266
267wxString wxComboBox::GetValue() const
268{
12f31626
SC
269 wxString result;
270
271 if ( m_text == 0 )
272 {
273 result = m_choice->GetString( m_choice->GetSelection() );
274 }
275 else
276 {
277 result = m_text->GetValue();
278 }
279
280 return result;
e9576ca5
SC
281}
282
283void wxComboBox::SetValue(const wxString& value)
284{
519cb848 285 SetStringSelection( value ) ;
e9576ca5
SC
286}
287
288// Clipboard operations
289void wxComboBox::Copy()
290{
12f31626
SC
291 if ( m_text != 0 )
292 {
293 m_text->Copy();
294 }
e9576ca5
SC
295}
296
297void wxComboBox::Cut()
298{
12f31626
SC
299 if ( m_text != 0 )
300 {
301 m_text->Cut();
302 }
e9576ca5
SC
303}
304
305void wxComboBox::Paste()
306{
12f31626
SC
307 if ( m_text != 0 )
308 {
309 m_text->Paste();
310 }
e9576ca5
SC
311}
312
313void wxComboBox::SetEditable(bool editable)
314{
12f31626
SC
315 if ( ( m_text == 0 ) && editable )
316 {
317 m_text = new wxComboBoxText( this );
318 }
319 else if ( ( m_text != 0 ) && !editable )
320 {
321 delete m_text;
322 m_text = 0;
323 }
324
325 int currentX, currentY;
326 GetPosition( &currentX, &currentY );
327
328 int currentW, currentH;
329 GetSize( &currentW, &currentH );
330
331 DoMoveWindow( currentX, currentY, currentW, currentH );
e9576ca5
SC
332}
333
334void wxComboBox::SetInsertionPoint(long pos)
335{
336 // TODO
337}
338
339void wxComboBox::SetInsertionPointEnd()
340{
341 // TODO
342}
343
344long wxComboBox::GetInsertionPoint() const
345{
346 // TODO
347 return 0;
348}
349
350long wxComboBox::GetLastPosition() const
351{
352 // TODO
353 return 0;
354}
355
356void wxComboBox::Replace(long from, long to, const wxString& value)
357{
358 // TODO
359}
360
361void wxComboBox::Remove(long from, long to)
362{
363 // TODO
364}
365
366void wxComboBox::SetSelection(long from, long to)
367{
368 // TODO
369}
370
371void wxComboBox::Append(const wxString& item)
372{
22a70443
RR
373 // I am not sure what other ports do,
374 // but wxMac chokes on empty entries.
375
376 if (!item.IsEmpty())
377 m_choice->DoAppend( item );
e9576ca5
SC
378}
379
380void wxComboBox::Delete(int n)
381{
12f31626 382 m_choice->Delete( n );
e9576ca5
SC
383}
384
385void wxComboBox::Clear()
386{
12f31626 387 m_choice->Clear();
e9576ca5
SC
388}
389
390int wxComboBox::GetSelection() const
391{
12f31626 392 return m_choice->GetSelection();
e9576ca5
SC
393}
394
395void wxComboBox::SetSelection(int n)
396{
12f31626
SC
397 m_choice->SetSelection( n );
398
399 if ( m_text != 0 )
400 {
401 m_text->SetValue( GetString( n ) );
402 }
e9576ca5
SC
403}
404
405int wxComboBox::FindString(const wxString& s) const
406{
12f31626 407 return m_choice->FindString( s );
e9576ca5
SC
408}
409
410wxString wxComboBox::GetString(int n) const
411{
12f31626 412 return m_choice->GetString( n );
e9576ca5
SC
413}
414
415wxString wxComboBox::GetStringSelection() const
416{
519cb848
SC
417 int sel = GetSelection ();
418 if (sel > -1)
419 return wxString(this->GetString (sel));
420 else
421 return wxString("");
e9576ca5
SC
422}
423
424bool wxComboBox::SetStringSelection(const wxString& sel)
425{
519cb848
SC
426 int s = FindString (sel);
427 if (s > -1)
428 {
429 SetSelection (s);
430 return TRUE;
431 }
432 else
433 return FALSE;
434}
435
76a5e5d2 436void wxComboBox::MacHandleControlClick( WXWidget control , wxInt16 controlpart )
519cb848
SC
437{
438 wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId );
465605e0 439 event.SetInt(GetSelection());
519cb848 440 event.SetEventObject(this);
0a67a93b 441 event.SetString(GetStringSelection());
519cb848 442 ProcessCommand(event);
e9576ca5 443}
519cb848 444