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