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