]> git.saurik.com Git - wxWidgets.git/blame - src/mac/classic/combobox.cpp
fixing visibility checks for native toolbars
[wxWidgets.git] / src / mac / classic / combobox.cpp
CommitLineData
2646f485
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: combobox.cpp
3// Purpose: wxComboBox class
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
2646f485
SC
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "combobox.h"
14#endif
15
16#include "wx/combobox.h"
17#include "wx/button.h"
18#include "wx/menu.h"
19#include "wx/mac/uma.h"
20
2646f485 21IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
2646f485
SC
22
23// composite combobox implementation by Dan "Bud" Keith bud@otsys.com
24
25
26static int nextPopUpMenuId = 1000 ;
150e31d2 27MenuHandle NewUniqueMenu()
2646f485
SC
28{
29 MenuHandle handle = NewMenu( nextPopUpMenuId , "\pMenu" ) ;
30 nextPopUpMenuId++ ;
31 return handle ;
32}
33
34
35// ----------------------------------------------------------------------------
36// constants
37// ----------------------------------------------------------------------------
38
39// the margin between the text control and the choice
40static const wxCoord MARGIN = 2;
41static const int POPUPWIDTH = 18;
42static const int POPUPHEIGHT = 23;
43
44
45// ----------------------------------------------------------------------------
46// wxComboBoxText: text control forwards events to combobox
47// ----------------------------------------------------------------------------
48
49class wxComboBoxText : public wxTextCtrl
50{
51public:
52 wxComboBoxText( wxComboBox * cb )
53 : wxTextCtrl( cb , 1 )
54 {
55 m_cb = cb;
56 }
57
58protected:
59 void OnChar( wxKeyEvent& event )
60 {
61 if ( event.GetKeyCode() == WXK_RETURN )
62 {
63 wxString value = GetValue();
64
65 if ( m_cb->GetCount() == 0 )
66 {
67 // make Enter generate "selected" event if there is only one item
68 // in the combobox - without it, it's impossible to select it at
69 // all!
70 wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
71 event.SetInt( 0 );
72 event.SetString( value );
73 event.SetEventObject( m_cb );
74 m_cb->GetEventHandler()->ProcessEvent( event );
75 }
76 else
77 {
78 // add the item to the list if it's not there yet
79 if ( m_cb->FindString(value) == wxNOT_FOUND )
80 {
81 m_cb->Append(value);
82 m_cb->SetStringSelection(value);
83
84 // and generate the selected event for it
85 wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
86 event.SetInt( m_cb->GetCount() - 1 );
87 event.SetString( value );
88 event.SetEventObject( m_cb );
89 m_cb->GetEventHandler()->ProcessEvent( event );
90 }
91
92 // This will invoke the dialog default action, such
93 // as the clicking the default button.
94
95 wxWindow *parent = GetParent();
96 while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
97 parent = parent->GetParent() ;
98 }
99 if ( parent && parent->GetDefaultItem() )
100 {
101 wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
102 wxButton);
103 if ( def && def->IsEnabled() )
104 {
105 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
106 event.SetEventObject(def);
107 def->Command(event);
108 return ;
109 }
110 }
111
112 return;
113 }
114 }
150e31d2 115
2646f485
SC
116 event.Skip();
117 }
118
119private:
120 wxComboBox *m_cb;
121
122 DECLARE_EVENT_TABLE()
123};
124
125BEGIN_EVENT_TABLE(wxComboBoxText, wxTextCtrl)
126 EVT_CHAR( wxComboBoxText::OnChar)
127END_EVENT_TABLE()
128
129class wxComboBoxChoice : public wxChoice
130{
131public:
132 wxComboBoxChoice(wxComboBox *cb, int style)
133 : wxChoice( cb , 1 )
134 {
135 m_cb = cb;
136 }
137
138protected:
139 void OnChoice( wxCommandEvent& e )
140 {
141 wxString s = e.GetString();
142
143 m_cb->DelegateChoice( s );
144 wxCommandEvent event2(wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
145 event2.SetInt(m_cb->GetSelection());
146 event2.SetEventObject(m_cb);
147 event2.SetString(m_cb->GetStringSelection());
148 m_cb->ProcessCommand(event2);
149 }
150
151private:
152 wxComboBox *m_cb;
153
154 DECLARE_EVENT_TABLE()
155};
156
157BEGIN_EVENT_TABLE(wxComboBoxChoice, wxChoice)
158 EVT_CHOICE(-1, wxComboBoxChoice::OnChoice)
159END_EVENT_TABLE()
160
161wxComboBox::~wxComboBox()
162{
163 // delete client objects
164 FreeData();
165
166 // delete the controls now, don't leave them alive even though they would
167 // still be eventually deleted by our parent - but it will be too late, the
168 // user code expects them to be gone now
169 if (m_text != NULL) {
170 delete m_text;
171 m_text = NULL;
172 }
173 if (m_choice != NULL) {
174 delete m_choice;
175 m_choice = NULL;
176 }
177}
178
179
180// ----------------------------------------------------------------------------
181// geometry
182// ----------------------------------------------------------------------------
183
184wxSize wxComboBox::DoGetBestSize() const
185{
186 wxSize size = m_choice->GetBestSize();
150e31d2 187
2646f485
SC
188 if ( m_text != NULL )
189 {
190 wxSize sizeText = m_text->GetBestSize();
150e31d2 191
2646f485
SC
192 size.x = POPUPWIDTH + sizeText.x + MARGIN;
193 }
194
195 return size;
196}
197
198void wxComboBox::DoMoveWindow(int x, int y, int width, int height) {
199 height = POPUPHEIGHT;
150e31d2 200
2646f485
SC
201 wxControl::DoMoveWindow(x, y, width, height);
202
203 if ( m_text == NULL )
204 {
205 m_choice->SetSize(0, 0 , width, -1);
206 }
207 else
208 {
209 wxCoord wText = width - POPUPWIDTH - MARGIN;
210 m_text->SetSize(0, 0, wText, height);
211 m_choice->SetSize(0 + wText + MARGIN, 0, POPUPWIDTH, -1);
150e31d2 212 }
2646f485
SC
213}
214
215
216
217// ----------------------------------------------------------------------------
218// operations forwarded to the subcontrols
219// ----------------------------------------------------------------------------
220
221bool wxComboBox::Enable(bool enable)
222{
223 if ( !wxControl::Enable(enable) )
7d8268a1 224 return false;
2646f485 225
7d8268a1 226 return true;
2646f485
SC
227}
228
229bool wxComboBox::Show(bool show)
230{
231 if ( !wxControl::Show(show) )
7d8268a1 232 return false;
2646f485 233
7d8268a1 234 return true;
2646f485
SC
235}
236
237void wxComboBox::SetFocus()
238{
239 if ( m_text != NULL) {
240 m_text->SetFocus();
241 }
242}
243
244
245void wxComboBox::DelegateTextChanged( const wxString& value )
246{
247 SetStringSelection( value );
248}
249
250
251void wxComboBox::DelegateChoice( const wxString& value )
252{
253 SetStringSelection( value );
254}
255
256
257bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
258 const wxString& value,
259 const wxPoint& pos,
260 const wxSize& size,
261 const wxArrayString& choices,
262 long style,
263 const wxValidator& validator,
264 const wxString& name)
265{
266 wxCArrayString chs( choices );
267
268 return Create( parent, id, value, pos, size, chs.GetCount(),
269 chs.GetStrings(), style, validator, name );
270}
271
272
273bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
274 const wxString& value,
275 const wxPoint& pos,
276 const wxSize& size,
277 int n, const wxString choices[],
278 long style,
279 const wxValidator& validator,
280 const wxString& name)
281{
282 if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style ,
283 wxDefaultValidator, name) )
284 {
7d8268a1 285 return false;
2646f485
SC
286 }
287
288 m_choice = new wxComboBoxChoice(this, style );
289
290 wxSize csize = size;
291 if ( style & wxCB_READONLY )
292 {
293 m_text = NULL;
294 }
295 else
296 {
297 m_text = new wxComboBoxText(this);
298 if ( size.y == -1 ) {
299 csize.y = m_text->GetSize().y ;
300 }
301 }
150e31d2 302
2646f485 303 DoSetSize(pos.x, pos.y, csize.x, csize.y);
150e31d2 304
2646f485
SC
305 for ( int i = 0 ; i < n ; i++ )
306 {
307 m_choice->DoAppend( choices[ i ] );
308 }
309
7d8268a1 310 return true;
2646f485
SC
311}
312
313wxString wxComboBox::GetValue() const
314{
315 wxString result;
150e31d2 316
2646f485
SC
317 if ( m_text == NULL )
318 {
319 result = m_choice->GetString( m_choice->GetSelection() );
320 }
321 else
322 {
323 result = m_text->GetValue();
324 }
325
326 return result;
327}
328
329void wxComboBox::SetValue(const wxString& value)
330{
331 int s = FindString (value);
332 if (s == wxNOT_FOUND && !HasFlag(wxCB_READONLY) )
333 {
334 m_choice->Append(value) ;
335 }
336 SetStringSelection( value ) ;
337}
338
339// Clipboard operations
340void wxComboBox::Copy()
341{
342 if ( m_text != NULL )
343 {
344 m_text->Copy();
345 }
346}
347
348void wxComboBox::Cut()
349{
350 if ( m_text != NULL )
351 {
352 m_text->Cut();
353 }
354}
355
356void wxComboBox::Paste()
357{
358 if ( m_text != NULL )
359 {
360 m_text->Paste();
361 }
362}
363
364void wxComboBox::SetEditable(bool editable)
365{
366 if ( ( m_text == NULL ) && editable )
367 {
368 m_text = new wxComboBoxText( this );
369 }
370 else if ( ( m_text != NULL ) && !editable )
371 {
372 delete m_text;
373 m_text = NULL;
374 }
375
376 int currentX, currentY;
377 GetPosition( &currentX, &currentY );
150e31d2 378
2646f485
SC
379 int currentW, currentH;
380 GetSize( &currentW, &currentH );
381
382 DoMoveWindow( currentX, currentY, currentW, currentH );
383}
384
385void wxComboBox::SetInsertionPoint(long pos)
386{
387 // TODO
388}
389
390void wxComboBox::SetInsertionPointEnd()
391{
392 // TODO
393}
394
395long wxComboBox::GetInsertionPoint() const
396{
397 // TODO
398 return 0;
399}
400
7d8268a1 401wxTextPos wxComboBox::GetLastPosition() const
2646f485
SC
402{
403 // TODO
404 return 0;
405}
406
407void wxComboBox::Replace(long from, long to, const wxString& value)
408{
409 // TODO
410}
411
412void wxComboBox::Remove(long from, long to)
413{
414 // TODO
415}
416
417void wxComboBox::SetSelection(long from, long to)
418{
419 // TODO
420}
421
150e31d2 422int wxComboBox::DoAppend(const wxString& item)
2646f485
SC
423{
424 return m_choice->DoAppend( item ) ;
425}
426
150e31d2 427int wxComboBox::DoInsert(const wxString& item, int pos)
2646f485
SC
428{
429 return m_choice->DoInsert( item , pos ) ;
430}
431
150e31d2 432void wxComboBox::DoSetItemClientData(int n, void* clientData)
2646f485
SC
433{
434 return m_choice->DoSetItemClientData( n , clientData ) ;
435}
436
437void* wxComboBox::DoGetItemClientData(int n) const
438{
439 return m_choice->DoGetItemClientData( n ) ;
440}
441
442void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData)
443{
444 return m_choice->DoSetItemClientObject( n , clientData ) ;
445}
446
150e31d2 447wxClientData* wxComboBox::DoGetItemClientObject(int n) const
2646f485
SC
448{
449 return m_choice->DoGetItemClientObject( n ) ;
450}
451
452void wxComboBox::FreeData()
453{
454 if ( HasClientObjectData() )
455 {
456 size_t count = GetCount();
457 for ( size_t n = 0; n < count; n++ )
458 {
459 SetClientObject( n, NULL );
460 }
461 }
462}
463
464void wxComboBox::Delete(int n)
465{
466 // force client object deletion
467 if( HasClientObjectData() )
468 SetClientObject( n, NULL );
469 m_choice->Delete( n );
470}
471
472void wxComboBox::Clear()
473{
474 FreeData();
475 m_choice->Clear();
476}
477
478int wxComboBox::GetSelection() const
479{
480 return m_choice->GetSelection();
481}
482
483void wxComboBox::SetSelection(int n)
484{
485 m_choice->SetSelection( n );
150e31d2 486
2646f485
SC
487 if ( m_text != NULL )
488 {
489 m_text->SetValue( GetString( n ) );
490 }
491}
492
493int wxComboBox::FindString(const wxString& s) const
494{
495 return m_choice->FindString( s );
496}
497
498wxString wxComboBox::GetString(int n) const
499{
500 return m_choice->GetString( n );
501}
502
503wxString wxComboBox::GetStringSelection() const
504{
505 int sel = GetSelection ();
506 if (sel > -1)
507 return wxString(this->GetString (sel));
508 else
509 return wxEmptyString;
510}
511
150e31d2 512void wxComboBox::SetString(int n, const wxString& s)
2646f485
SC
513{
514 m_choice->SetString( n , s ) ;
515}
516
150e31d2
JS
517bool wxComboBox::IsEditable() const
518{
7d8268a1 519 return m_text != NULL && !HasFlag(wxCB_READONLY);
150e31d2
JS
520}
521
522void wxComboBox::Undo()
523{
524 if (m_text != NULL)
525 m_text->Undo();
526}
527
528void wxComboBox::Redo()
529{
530 if (m_text != NULL)
531 m_text->Redo();
532}
533
534void wxComboBox::SelectAll()
535{
536 if (m_text != NULL)
537 m_text->SelectAll();
538}
539
540bool wxComboBox::CanCopy() const
541{
542 if (m_text != NULL)
543 return m_text->CanCopy();
544 else
545 return false;
546}
547
548bool wxComboBox::CanCut() const
549{
550 if (m_text != NULL)
551 return m_text->CanCut();
552 else
553 return false;
554}
555
556bool wxComboBox::CanPaste() const
557{
558 if (m_text != NULL)
559 return m_text->CanPaste();
560 else
561 return false;
562}
563
564bool wxComboBox::CanUndo() const
565{
566 if (m_text != NULL)
567 return m_text->CanUndo();
568 else
569 return false;
570}
571
572bool wxComboBox::CanRedo() const
573{
574 if (m_text != NULL)
575 return m_text->CanRedo();
576 else
577 return false;
578}
2646f485 579
150e31d2 580void wxComboBox::MacHandleControlClick( WXWidget WXUNUSED(control) , wxInt16 WXUNUSED(controlpart) , bool WXUNUSED(mouseStillDown))
2646f485
SC
581{
582 wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId );
583 event.SetInt(GetSelection());
584 event.SetEventObject(this);
585 event.SetString(GetStringSelection());
586 ProcessCommand(event);
587}
588