1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/combobox_osx.cpp
3 // Purpose: wxComboBox class using HIView ComboBox
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: combobox_osx.cpp 58318 2009-01-23 08:36:16Z RR $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/combobox.h"
23 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
)
25 wxComboBox::~wxComboBox()
29 bool wxComboBox::Create(wxWindow
*parent
, wxWindowID id
,
30 const wxString
& value
,
33 const wxArrayString
& choices
,
35 const wxValidator
& validator
,
38 wxCArrayString
chs( choices
);
40 return Create( parent
, id
, value
, pos
, size
, chs
.GetCount(),
41 chs
.GetStrings(), style
, validator
, name
);
44 bool wxComboBox::Create(wxWindow
*parent
, wxWindowID id
,
45 const wxString
& value
,
48 int n
, const wxString choices
[],
50 const wxValidator
& validator
,
56 m_macIsUserPane
= false;
58 if ( !wxControl::Create( parent
, id
, pos
, size
, style
, validator
, name
) )
61 m_peer
= wxWidgetImpl::CreateComboBox( this, parent
, id
, m_popUpMenu
, pos
, size
, style
, GetExtraStyle() );
63 MacPostControlCreate( pos
, size
);
66 if ( style
& wxCB_SORT
)
68 m_strings
= wxArrayString( 1 );
73 // Set the first item as being selected
77 // Needed because it is a wxControlWithItems
78 SetInitialSize( size
);
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 wxSize
wxComboBox::DoGetBestSize() const
90 return wxControl::DoGetBestSize();
92 wxSize size
= m_choice
->GetBestSize();
96 wxSize sizeText
= m_text
->GetBestSize();
98 size
.x
= POPUPWIDTH
+ sizeText
.x
+ MARGIN
;
105 void wxComboBox::DoMoveWindow(int x
, int y
, int width
, int height
) {
107 wxControl::DoMoveWindow(x
, y
, width
, height
);
109 height
= POPUPHEIGHT
;
111 wxControl::DoMoveWindow(x
, y
, width
, height
);
113 if ( m_text
== NULL
)
115 // we might not be fully constructed yet, therefore watch out...
117 m_choice
->SetSize(0, 0 , width
, wxDefaultCoord
);
121 wxCoord wText
= width
- POPUPWIDTH
- MARGIN
;
122 m_text
->SetSize(0, 0, wText
, height
);
123 m_choice
->SetSize(0 + wText
+ MARGIN
, 0, POPUPWIDTH
, wxDefaultCoord
);
130 // ----------------------------------------------------------------------------
131 // operations forwarded to the subcontrols
132 // ----------------------------------------------------------------------------
134 bool wxComboBox::Enable(bool enable
)
136 if ( !wxControl::Enable(enable
) )
142 bool wxComboBox::Show(bool show
)
144 if ( !wxControl::Show(show
) )
150 void wxComboBox::SetFocus()
153 wxControl::SetFocus();
155 if ( m_text
!= NULL
) {
162 void wxComboBox::DelegateTextChanged( const wxString
& value
)
164 SetStringSelection( value
);
168 void wxComboBox::DelegateChoice( const wxString
& value
)
170 SetStringSelection( value
);
173 bool wxComboBox::Create(wxWindow
*parent
, wxWindowID id
,
174 const wxString
& value
,
177 int n
, const wxString choices
[],
179 const wxValidator
& validator
,
180 const wxString
& name
)
185 m_macIsUserPane
= false;
187 if ( !wxControl::Create(parent
, id
, wxDefaultPosition
, wxDefaultSize
, style
,
188 wxDefaultValidator
, name
) )
193 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
);
196 hiRect
.origin
.x
= 20; //bounds.left;
197 hiRect
.origin
.y
= 25; //bounds.top;
198 hiRect
.size
.width
= 120;// bounds.right - bounds.left;
199 hiRect
.size
.height
= 24;
201 //For some reason, this code causes the combo box not to be displayed at all.
202 //hiRect.origin.x = bounds.left;
203 //hiRect.origin.y = bounds.top;
204 //hiRect.size.width = bounds.right - bounds.left;
205 //hiRect.size.height = bounds.bottom - bounds.top;
206 //printf("left = %d, right = %d, top = %d, bottom = %d\n", bounds.left, bounds.right, bounds.top, bounds.bottom);
207 //printf("x = %d, y = %d, width = %d, height = %d\n", hibounds.origin.x, hibounds.origin.y, hibounds.size.width, hibounds.size.height);
208 m_peer
= new wxMacControl(this);
209 verify_noerr( HIComboBoxCreate( &hiRect
, CFSTR(""), NULL
, NULL
, kHIComboBoxStandardAttributes
, m_peer
->GetControlRefAddr() ) );
212 m_peer
->SetMinimum( 0 );
213 m_peer
->SetMaximum( 100);
215 m_peer
->SetValue( 1 );
217 MacPostControlCreate(pos
,size
);
219 Append( choices
[ i
] );
221 HIViewSetVisible( m_peer
->GetControlRef(), true );
223 EventHandlerRef comboEventHandler
;
224 InstallControlEventHandler( m_peer
->GetControlRef(), GetwxMacComboBoxEventHandlerUPP(),
225 GetEventTypeCount(eventList
), eventList
, this,
226 (EventHandlerRef
*)&comboEventHandler
);
228 m_choice
= new wxComboBoxChoice(this, style
);
229 m_choice
->SetMinSize( wxSize( POPUPWIDTH
, POPUPHEIGHT
) );
232 if ( style
& wxCB_READONLY
)
238 m_text
= new wxComboBoxText(this);
239 if ( size
.y
== wxDefaultCoord
) {
240 csize
.y
= m_text
->GetSize().y
;
244 DoSetSize(pos
.x
, pos
.y
, csize
.x
, csize
.y
);
246 m_choice
->Append( n
, choices
);
247 SetInitialSize(csize
); // Needed because it is a wxControlWithItems
253 wxString
wxComboBox::GetValue() const
256 CFStringRef myString
;
257 HIComboBoxCopyTextItemAtIndex( m_peer
->GetControlRef(), (CFIndex
)GetSelection(), &myString
);
258 return wxMacCFStringHolder( myString
, GetFont().GetEncoding() ).AsString();
262 if ( m_text
== NULL
)
264 result
= m_choice
->GetString( m_choice
->GetSelection() );
268 result
= m_text
->GetValue();
275 void wxComboBox::SetValue(const wxString
& value
)
280 int s
= FindString (value
);
281 if (s
== wxNOT_FOUND
&& !HasFlag(wxCB_READONLY
) )
283 m_choice
->Append(value
);
285 SetStringSelection( value
);
289 // Clipboard operations
290 void wxComboBox::Copy()
292 if ( m_text
!= NULL
)
298 void wxComboBox::Cut()
300 if ( m_text
!= NULL
)
306 void wxComboBox::Paste()
308 if ( m_text
!= NULL
)
314 void wxComboBox::SetEditable(bool editable
)
316 if ( ( m_text
== NULL
) && editable
)
318 m_text
= new wxComboBoxText( this );
320 else if ( ( m_text
!= NULL
) && !editable
)
326 int currentX
, currentY
;
327 GetPosition( ¤tX
, ¤tY
);
329 int currentW
, currentH
;
330 GetSize( ¤tW
, ¤tH
);
332 DoMoveWindow( currentX
, currentY
, currentW
, currentH
);
335 void wxComboBox::SetInsertionPoint(long pos
)
340 void wxComboBox::SetInsertionPointEnd()
345 long wxComboBox::GetInsertionPoint() const
351 wxTextPos
wxComboBox::GetLastPosition() const
357 void wxComboBox::Replace(long from
, long to
, const wxString
& value
)
362 void wxComboBox::Remove(long from
, long to
)
367 void wxComboBox::SetSelection(long from
, long to
)
372 int wxComboBox::DoInsertItems(const wxArrayStringsAdapter
& items
,
374 void **clientData
, wxClientDataType type
)
377 const unsigned int count
= items
.GetCount();
378 for ( unsigned int i
= 0; i
< count
; ++i
, ++pos
)
380 HIComboBoxInsertTextItemAtIndex(m_peer
->GetControlRef(),
382 wxMacCFStringHolder(items
[i
],
383 GetFont().GetEncoding()));
384 AssignNewItemClientData(pos
, clientData
, i
, type
);
387 //SetControl32BitMaximum( m_peer->GetControlRef(), GetCount() );
391 return m_choice
->DoInsertItems( items
, pos
, clientData
, type
);
395 void wxComboBox::DoSetItemClientData(unsigned int n
, void* clientData
)
400 return m_choice
->DoSetItemClientData( n
, clientData
);
404 void* wxComboBox::DoGetItemClientData(unsigned int n
) const
409 return m_choice
->DoGetItemClientData( n
);
413 unsigned int wxComboBox::GetCount() const {
415 return (unsigned int) HIComboBoxGetItemCount( m_peer
->GetControlRef() );
417 return m_choice
->GetCount();
421 void wxComboBox::DoDeleteOneItem(unsigned int n
)
424 HIComboBoxRemoveItemAtIndex( m_peer
->GetControlRef(), (CFIndex
)n
);
426 m_choice
->Delete( n
);
430 void wxComboBox::DoClear()
433 for ( CFIndex i
= GetCount() - 1; i
>= 0; ++ i
)
434 verify_noerr( HIComboBoxRemoveItemAtIndex( m_peer
->GetControlRef(), i
) );
435 m_peer
->SetData
<CFStringRef
>(kHIComboBoxEditTextPart
,kControlEditTextCFStringTag
,CFSTR(""));
441 int wxComboBox::GetSelection() const
444 return FindString( GetStringSelection() );
446 return m_choice
->GetSelection();
450 void wxComboBox::SetSelection(int n
)
453 SetControl32BitValue( m_peer
->GetControlRef() , n
+ 1 );
455 m_choice
->SetSelection( n
);
457 if ( m_text
!= NULL
)
459 m_text
->SetValue(GetString(n
));
464 int wxComboBox::FindString(const wxString
& s
, bool bCase
) const
467 for( unsigned int i
= 0 ; i
< GetCount() ; i
++ )
469 if (GetString(i
).IsSameAs(s
, bCase
) )
474 return m_choice
->FindString( s
, bCase
);
478 wxString
wxComboBox::GetString(unsigned int n
) const
481 CFStringRef itemText
;
482 HIComboBoxCopyTextItemAtIndex( m_peer
->GetControlRef(), (CFIndex
)n
, &itemText
);
483 return wxMacCFStringHolder(itemText
).AsString();
485 return m_choice
->GetString( n
);
489 wxString
wxComboBox::GetStringSelection() const
492 return wxMacCFStringHolder(m_peer
->GetData
<CFStringRef
>(kHIComboBoxEditTextPart
,kControlEditTextCFStringTag
)).AsString();
494 int sel
= GetSelection ();
495 if (sel
!= wxNOT_FOUND
)
496 return wxString(this->GetString((unsigned int)sel
));
498 return wxEmptyString
;
502 void wxComboBox::SetString(unsigned int n
, const wxString
& s
)
505 verify_noerr ( HIComboBoxInsertTextItemAtIndex( m_peer
->GetControlRef(), (CFIndex
) n
,
506 wxMacCFStringHolder(s
, GetFont().GetEncoding()) ) );
507 verify_noerr ( HIComboBoxRemoveItemAtIndex( m_peer
->GetControlRef(), (CFIndex
) n
+ 1 ) );
509 m_choice
->SetString( n
, s
);
513 bool wxComboBox::IsEditable() const
517 return !HasFlag(wxCB_READONLY
);
519 return m_text
!= NULL
&& !HasFlag(wxCB_READONLY
);
523 void wxComboBox::Undo()
533 void wxComboBox::Redo()
543 void wxComboBox::SelectAll()
553 bool wxComboBox::CanCopy() const
560 return m_text
->CanCopy();
566 bool wxComboBox::CanCut() const
573 return m_text
->CanCut();
579 bool wxComboBox::CanPaste() const
586 return m_text
->CanPaste();
592 bool wxComboBox::CanUndo() const
599 return m_text
->CanUndo();
605 bool wxComboBox::CanRedo() const
612 return m_text
->CanRedo();
618 bool wxComboBox::OSXHandleClicked( double timestampsec
)
620 wxCommandEvent
event(wxEVT_COMMAND_COMBOBOX_SELECTED
, m_windowId
);
621 event
.SetInt(GetSelection());
622 event
.SetEventObject(this);
623 event
.SetString(GetStringSelection());
624 ProcessCommand(event
);