1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 #pragma implementation "choice.h"
16 #include "wx/wxprec.h"
20 #include "wx/choice.h"
22 #include "wx/mac/uma.h"
24 #if !USE_SHARED_LIBRARY
25 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControl
)
28 extern MenuHandle
NewUniqueMenu() ;
32 if ( HasClientObjectData() )
34 size_t i
, max
= GetCount();
36 for ( i
= 0; i
< max
; ++i
)
37 delete GetClientObject(i
);
40 // DeleteMenu( m_macPopUpMenuId ) ;
41 // DisposeMenu( m_macPopUpMenuHandle ) ;
44 bool wxChoice::Create(wxWindow
*parent
, wxWindowID id
,
47 const wxArrayString
& choices
,
49 const wxValidator
& validator
,
52 wxCArrayString
chs(choices
);
54 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
55 style
, validator
, name
);
58 bool wxChoice::Create(wxWindow
*parent
, wxWindowID id
,
61 int n
, const wxString choices
[],
63 const wxValidator
& validator
,
66 m_macIsUserPane
= false ;
68 if ( !wxChoiceBase::Create(parent
, id
, pos
, size
, style
, validator
, name
) )
71 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
73 m_peer
= new wxMacControl(this) ;
74 verify_noerr ( CreatePopupButtonControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()) , &bounds
, CFSTR("") ,
75 -12345 , false /* no variable width */ , 0 , 0 , 0 , m_peer
->GetControlRefAddr() ) );
78 m_macPopUpMenuHandle
= NewUniqueMenu() ;
79 m_peer
->SetData
<MenuHandle
>( kControlNoPart
, kControlPopupButtonMenuHandleTag
, (MenuHandle
) m_macPopUpMenuHandle
) ;
80 m_peer
->SetValueAndRange( n
> 0 ? 1 : 0 , 0 , 0 ) ;
81 MacPostControlCreate(pos
,size
) ;
83 for ( int i
= 0; i
< n
; i
++ )
87 SetBestSize(size
); // Needed because it is a wxControlWithItems
91 // ----------------------------------------------------------------------------
92 // adding/deleting items to/from the list
93 // ----------------------------------------------------------------------------
94 int wxChoice::DoAppend(const wxString
& item
)
96 UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle
) , item
, m_font
.GetEncoding() );
97 m_strings
.Add( item
) ;
99 int index
= m_strings
.GetCount() - 1 ;
100 DoSetItemClientData( index
, NULL
) ;
101 m_peer
->SetMaximum( GetCount() ) ;
105 int wxChoice::DoInsert(const wxString
& item
, int pos
)
107 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT
), -1, wxT("can't insert into sorted list"));
108 wxCHECK_MSG((pos
>=0) && (pos
<=GetCount()), -1, wxT("invalid index"));
110 if (pos
== GetCount())
111 return DoAppend(item
);
113 UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle
) , item
, m_font
.GetEncoding() );
114 m_strings
.Insert( item
, pos
) ;
115 m_datas
.Insert( NULL
, pos
) ;
116 DoSetItemClientData( pos
, NULL
) ;
117 m_peer
->SetMaximum( GetCount() ) ;
121 void wxChoice::Delete(int n
)
123 wxCHECK_RET( n
< GetCount(), wxT("invalid item index in wxChoice::Delete") );
124 if ( HasClientObjectData() )
126 delete GetClientObject(n
);
128 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , n
+ 1) ;
129 m_strings
.RemoveAt( n
) ;
130 m_datas
.RemoveAt( n
) ;
131 m_peer
->SetMaximum( GetCount() ) ;
134 void wxChoice::Clear()
137 for ( int i
= 0 ; i
< GetCount() ; i
++ )
139 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle
) , 1 ) ;
143 m_peer
->SetMaximum( 0 ) ;
146 void wxChoice::FreeData()
148 if ( HasClientObjectData() )
150 size_t count
= GetCount();
151 for ( size_t n
= 0; n
< count
; n
++ )
153 delete GetClientObject(n
);
158 // ----------------------------------------------------------------------------
160 // ----------------------------------------------------------------------------
161 int wxChoice::GetSelection() const
163 return m_peer
->GetValue() -1 ;
166 void wxChoice::SetSelection(int n
)
168 m_peer
->SetValue( n
+ 1 ) ;
171 // ----------------------------------------------------------------------------
172 // string list functions
173 // ----------------------------------------------------------------------------
175 int wxChoice::GetCount() const
177 return m_strings
.GetCount() ;
180 int wxChoice::FindString(const wxString
& s
) const
182 for( int i
= 0 ; i
< GetCount() ; i
++ )
184 if ( GetString( i
).IsSameAs(s
, false) )
190 void wxChoice::SetString(int n
, const wxString
& s
)
192 wxFAIL_MSG(wxT("wxChoice::SetString() not yet implemented"));
193 #if 0 // should do this, but no Insert() so far
199 wxString
wxChoice::GetString(int n
) const
201 wxCHECK_MSG( n
>= 0 && (size_t)n
< m_strings
.GetCount(), _T(""),
202 _T("wxChoice::GetString(): invalid index") );
204 return m_strings
[n
] ;
207 // ----------------------------------------------------------------------------
209 // ----------------------------------------------------------------------------
210 void wxChoice::DoSetItemClientData( int n
, void* clientData
)
212 wxCHECK_RET( n
>= 0 && (size_t)n
< m_datas
.GetCount(),
213 wxT("invalid index in wxChoice::SetClientData") );
215 m_datas
[n
] = (char*) clientData
;
218 void *wxChoice::DoGetItemClientData(int n
) const
220 wxCHECK_MSG( n
>= 0 && (size_t)n
< m_datas
.GetCount(), NULL
,
221 wxT("invalid index in wxChoice::GetClientData") );
222 return (void *)m_datas
[n
];
225 void wxChoice::DoSetItemClientObject( int n
, wxClientData
* clientData
)
227 DoSetItemClientData(n
, clientData
);
230 wxClientData
* wxChoice::DoGetItemClientObject( int n
) const
232 return (wxClientData
*)DoGetItemClientData(n
);
235 wxInt32
wxChoice::MacControlHit(WXEVENTHANDLERREF
WXUNUSED(handler
) , WXEVENTREF
WXUNUSED(event
) )
237 wxCommandEvent
event(wxEVT_COMMAND_CHOICE_SELECTED
, m_windowId
);
238 int n
= GetSelection();
239 // actually n should be made sure by the os to be a valid selection, but ...
243 event
.SetString(GetStringSelection());
244 event
.SetEventObject(this);
245 if ( HasClientObjectData() )
246 event
.SetClientObject( GetClientObject(n
) );
247 else if ( HasClientUntypedData() )
248 event
.SetClientData( GetClientData(n
) );
249 ProcessCommand(event
);
254 wxSize
wxChoice::DoGetBestSize() const
256 int lbWidth
= GetCount() > 0 ? 20 : 100; // some defaults
261 GetThemeMetric(kThemeMetricPopupButtonHeight
, &metric
);
265 wxMacPortStateHelper
st( UMAGetWindowPort( (WindowRef
) MacGetTopLevelWindowRef() ) ) ;
268 ::TextFont( m_font
.MacGetFontNum() ) ;
269 ::TextSize( m_font
.MacGetFontSize() ) ;
270 ::TextFace( m_font
.MacGetFontStyle() ) ;
274 ::TextFont( kFontIDMonaco
) ;
278 // Find the widest line
279 for(int i
= 0; i
< GetCount(); i
++) {
280 wxString
str(GetString(i
));
284 ::GetThemeTextDimensions( wxMacCFStringHolder( str
, m_font
.GetEncoding() ) ,
285 kThemeCurrentPortFont
,
292 wLine
= ::TextWidth( str
.c_str() , 0 , str
.Length() ) ;
294 lbWidth
= wxMax(lbWidth
, wLine
);
296 // Add room for the popup arrow
297 lbWidth
+= 2 * lbHeight
;
298 // And just a bit more
299 int cx
= ::TextWidth( "X" , 0 , 1 ) ;
303 return wxSize(lbWidth
, lbHeight
);
306 #endif // wxUSE_CHOICE