]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/choice.cpp
switching to safe yields, because we got into loops when handling print document...
[wxWidgets.git] / src / mac / carbon / choice.cpp
CommitLineData
2ac013b1 1/////////////////////////////////////////////////////////////////////////////
e9576ca5
SC
2// Name: choice.cpp
3// Purpose: wxChoice
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
e9576ca5
SC
11#ifdef __GNUG__
12#pragma implementation "choice.h"
13#endif
d8c736e5 14#include "wx/defs.h"
e9576ca5 15#include "wx/choice.h"
03e11df5 16#include "wx/menu.h"
519cb848 17#include "wx/mac/uma.h"
2f1ae414 18#if !USE_SHARED_LIBRARY
e9576ca5 19IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
2f1ae414 20#endif
892e461e 21extern MenuHandle NewUniqueMenu() ;
5b781a67
SC
22wxChoice::~wxChoice()
23{
24 // DeleteMenu( m_macPopUpMenuId ) ;
e7b596fb 25 // DisposeMenu( m_macPopUpMenuHandle ) ;
5b781a67 26}
e9576ca5
SC
27bool wxChoice::Create(wxWindow *parent, wxWindowID id,
28 const wxPoint& pos,
29 const wxSize& size,
03e11df5
GD
30 int n, const wxString choices[],
31 long style,
e9576ca5
SC
32 const wxValidator& validator,
33 const wxString& name)
34{
519cb848
SC
35 Rect bounds ;
36 Str255 title ;
37
38 MacPreControlCreate( parent , id , "" , pos , size ,style, validator , name , &bounds , title ) ;
76a5e5d2 39 m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , -12345 , 0 ,
8208e181 40 kControlPopupButtonProc + kControlPopupFixedWidthVariant , (long) this ) ;
519cb848 41
892e461e 42 m_macPopUpMenuHandle = NewUniqueMenu() ;
76a5e5d2 43 SetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlPopupButtonMenuHandleTag , sizeof( MenuHandle ) , (char*) &m_macPopUpMenuHandle) ;
467e3168
SC
44 SetControl32BitMinimum( (ControlHandle) m_macControl , 0 ) ;
45 SetControl32BitMaximum( (ControlHandle) m_macControl , 0) ;
2f1ae414 46 if ( n > 0 )
467e3168 47 SetControl32BitValue( (ControlHandle) m_macControl , 1 ) ;
519cb848 48 MacPostControlCreate() ;
b668a735
SC
49 for ( int i = 0; i < n; i++ )
50 {
51 Append(choices[i]);
52 }
519cb848 53 return TRUE;
e9576ca5 54}
b668a735
SC
55// ----------------------------------------------------------------------------
56// adding/deleting items to/from the list
57// ----------------------------------------------------------------------------
2597135a 58int wxChoice::DoAppend(const wxString& item)
e9576ca5 59{
2f1ae414
SC
60 Str255 label;
61 wxMenuItem::MacBuildMenuString( label , NULL , NULL , item ,false);
f2d990ad
SC
62 MacAppendMenu(MAC_WXHMENU( m_macPopUpMenuHandle ) , "\pA");
63 SetMenuItemText(MAC_WXHMENU( m_macPopUpMenuHandle ) ,
64 (SInt16) ::CountMenuItems(MAC_WXHMENU( m_macPopUpMenuHandle ) ), label);
65 // was AppendMenu( MAC_WXHMENU( m_macPopUpMenuHandle ) , label ) ;
2f1ae414 66 m_strings.Add( item ) ;
b668a735
SC
67 m_datas.Add( NULL ) ;
68 int index = m_strings.GetCount() - 1 ;
69 DoSetItemClientData( index , NULL ) ;
467e3168 70 SetControl32BitMaximum( (ControlHandle) m_macControl , GetCount()) ;
b668a735 71 return index ;
2597135a 72}
b668a735 73void wxChoice::Delete(int n)
2597135a 74{
b668a735 75 wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
b668a735 76 if ( HasClientObjectData() )
2597135a 77 {
b668a735 78 delete GetClientObject(n);
2597135a 79 }
76a5e5d2 80 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1) ;
2f1ae414 81 m_strings.Remove( n ) ;
3ef585df 82 m_datas.RemoveAt( n ) ;
467e3168 83 SetControl32BitMaximum( (ControlHandle) m_macControl , GetCount()) ;
e9576ca5 84}
e9576ca5
SC
85void wxChoice::Clear()
86{
4b651a46 87 FreeData();
b668a735 88 for ( int i = 0 ; i < GetCount() ; i++ )
519cb848 89 {
76a5e5d2 90 ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
4b651a46 91 }
b668a735
SC
92 m_strings.Empty() ;
93 m_datas.Empty() ;
467e3168 94 SetControl32BitMaximum( (ControlHandle) m_macControl , 0 ) ;
e9576ca5 95}
4b651a46 96void wxChoice::FreeData()
b668a735
SC
97{
98 if ( HasClientObjectData() )
99 {
100 size_t count = GetCount();
101 for ( size_t n = 0; n < count; n++ )
102 {
103 delete GetClientObject(n);
104 }
105 }
106}
b668a735
SC
107// ----------------------------------------------------------------------------
108// selection
109// ----------------------------------------------------------------------------
e9576ca5
SC
110int wxChoice::GetSelection() const
111{
467e3168 112 return GetControl32BitValue( (ControlHandle) m_macControl ) -1 ;
e9576ca5 113}
b668a735 114void wxChoice::SetSelection(int n)
519cb848 115{
467e3168 116 SetControl32BitValue( (ControlHandle) m_macControl , n + 1 ) ;
519cb848 117}
b668a735
SC
118// ----------------------------------------------------------------------------
119// string list functions
120// ----------------------------------------------------------------------------
b668a735 121int wxChoice::GetCount() const
e9576ca5 122{
b668a735 123 return m_strings.GetCount() ;
e9576ca5 124}
e9576ca5
SC
125int wxChoice::FindString(const wxString& s) const
126{
b668a735 127 for( int i = 0 ; i < GetCount() ; i++ )
519cb848 128 {
b668a735 129 if ( GetString( i ).IsSameAs(s, FALSE) )
519cb848
SC
130 return i ;
131 }
b668a735
SC
132 return wxNOT_FOUND ;
133}
b668a735
SC
134void wxChoice::SetString(int n, const wxString& s)
135{
4b651a46 136 wxFAIL_MSG(wxT("wxChoice::SetString() not yet implemented"));
b668a735
SC
137#if 0 // should do this, but no Insert() so far
138 Delete(n);
139 Insert(n + 1, s);
140#endif
e9576ca5
SC
141}
142
143wxString wxChoice::GetString(int n) const
144{
2f1ae414 145 return m_strings[n] ;
e9576ca5 146}
b668a735
SC
147// ----------------------------------------------------------------------------
148// client data
149// ----------------------------------------------------------------------------
b668a735
SC
150void wxChoice::DoSetItemClientData( int n, void* clientData )
151{
d81cc883 152 wxCHECK_RET( n >= 0 && (size_t)n < m_datas.GetCount(),
b668a735 153 "invalid index in wxChoice::SetClientData" );
b668a735 154
d81cc883 155 m_datas[n] = (char*) clientData ;
b668a735 156}
d81cc883 157void *wxChoice::DoGetItemClientData(int n) const
b668a735 158{
d81cc883 159 wxCHECK_MSG( n >= 0 && (size_t)n < m_datas.GetCount(), NULL,
b668a735 160 "invalid index in wxChoice::GetClientData" );
d81cc883 161 return (void *)m_datas[n];
b668a735 162}
b668a735
SC
163void wxChoice::DoSetItemClientObject( int n, wxClientData* clientData )
164{
165 DoSetItemClientData(n, clientData);
166}
b668a735 167wxClientData* wxChoice::DoGetItemClientObject( int n ) const
e9576ca5 168{
b668a735 169 return (wxClientData *)DoGetItemClientData(n);
e9576ca5 170}
76a5e5d2 171void wxChoice::MacHandleControlClick( WXWidget control , wxInt16 controlpart )
b668a735
SC
172{
173 wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, m_windowId );
f2d990ad
SC
174 int n = GetSelection();
175 // actually n should be made sure by the os to be a valid selection, but ...
176 if ( n > -1 )
177 {
178 event.SetInt( n );
179 event.SetString(GetStringSelection());
180 event.SetEventObject(this);
f2d990ad
SC
181 if ( HasClientObjectData() )
182 event.SetClientObject( GetClientObject(n) );
183 else if ( HasClientUntypedData() )
184 event.SetClientData( GetClientData(n) );
f2d990ad
SC
185 ProcessCommand(event);
186 }
9453cf2b 187}
f2d990ad 188wxSize wxChoice::DoGetBestSize() const
b668a735 189{
f2d990ad
SC
190 int lbWidth = 100; // some defaults
191 int lbHeight = 20;
192 int wLine;
193#if TARGET_CARBON
194 long metric ;
195 GetThemeMetric(kThemeMetricPopupButtonHeight , &metric );
196 lbHeight = metric ;
197#endif
198 {
199 wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetRootWindow() ) ) ;
200 Rect drawRect ;
f2d990ad 201 wxFontRefData * font = (wxFontRefData*) m_font.GetRefData() ;
f2d990ad
SC
202 if ( font )
203 {
204 ::TextFont( font->m_macFontNum ) ;
205 ::TextSize( short(font->m_macFontSize) ) ;
206 ::TextFace( font->m_macFontStyle ) ;
207 }
208 else
209 {
210 ::TextFont( kFontIDMonaco ) ;
211 ::TextSize( 9 );
212 ::TextFace( 0 ) ;
213 }
f2d990ad
SC
214 // Find the widest line
215 for(int i = 0; i < GetCount(); i++) {
216 wxString str(GetString(i));
217 wLine = ::TextWidth( str.c_str() , 0 , str.Length() ) ;
218 lbWidth = wxMax(lbWidth, wLine);
219 }
f2d990ad
SC
220 // Add room for the popup arrow
221 lbWidth += 2 * lbHeight ;
f2d990ad
SC
222 // And just a bit more
223 int cy = 12 ;
224 int cx = ::TextWidth( "X" , 0 , 1 ) ;
225 lbWidth += cx ;
226
227 }
228 return wxSize(lbWidth, lbHeight);
2ac013b1 229}