]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/combobox.mm
Fix install_name_tool calls in OS X "make install".
[wxWidgets.git] / src / osx / cocoa / combobox.mm
CommitLineData
4ddfa282
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/cocoa/combobox.mm
3// Purpose: wxChoice
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
4ddfa282
SC
7// Copyright: (c) Stefan Csomor
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
c84030e0 13#if wxUSE_COMBOBOX
4ddfa282
SC
14
15#include "wx/combobox.h"
18a7376a 16#include "wx/evtloop.h"
4ddfa282
SC
17
18#ifndef WX_PRECOMP
19 #include "wx/menu.h"
20 #include "wx/dcclient.h"
21#endif
22
c84030e0 23#include "wx/osx/cocoa/private/textimpl.h"
4ddfa282
SC
24
25// work in progress
26
28953245
SC
27@interface wxNSTableDataSource : NSObject wxOSX_10_6_AND_LATER(<NSComboBoxDataSource>)
28{
29 wxNSComboBoxControl* impl;
30}
31
32- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;
33- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;
34
35@end
36
37
4ddfa282
SC
38@implementation wxNSComboBox
39
40+ (void)initialize
41{
42 static BOOL initialized = NO;
43 if (!initialized)
44 {
45 initialized = YES;
46 wxOSXCocoaClassAddWXMethods( self );
47 }
48}
49
d9307d00
SC
50- (void) dealloc
51{
52 [fieldEditor release];
53 [super dealloc];
54}
55
56// Over-riding NSComboBox onKeyDown method doesn't work for key events.
57// Ensure that we can use our own wxNSTextFieldEditor to catch key events.
58// See windowWillReturnFieldEditor in nonownedwnd.mm.
59// Key events will be caught and handled via wxNSTextFieldEditor onkey...
60// methods in textctrl.mm.
61
62- (void) setFieldEditor:(wxNSTextFieldEditor*) editor
63{
64 if ( editor != fieldEditor )
65 {
66 [editor retain];
67 [fieldEditor release];
68 fieldEditor = editor;
69 }
70}
71
72- (wxNSTextFieldEditor*) fieldEditor
73{
74 return fieldEditor;
75}
76
c84030e0 77- (void)controlTextDidChange:(NSNotification *)aNotification
4ddfa282 78{
c84030e0
KO
79 wxUnusedVar(aNotification);
80 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
809020fc 81 if ( impl && impl->ShouldSendEvents() )
c84030e0
KO
82 {
83 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
84 if ( wxpeer ) {
ce7fe42e 85 wxCommandEvent event(wxEVT_TEXT, wxpeer->GetId());
c84030e0
KO
86 event.SetEventObject( wxpeer );
87 event.SetString( static_cast<wxComboBox*>(wxpeer)->GetValue() );
88 wxpeer->HandleWindowEvent( event );
89 }
90 }
4ddfa282
SC
91}
92
c84030e0 93- (void)comboBoxSelectionDidChange:(NSNotification *)notification
4ddfa282 94{
c84030e0
KO
95 wxUnusedVar(notification);
96 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
809020fc 97 if ( impl && impl->ShouldSendEvents())
c84030e0 98 {
2de58153 99 wxComboBox* wxpeer = static_cast<wxComboBox*>(impl->GetWXPeer());
c84030e0 100 if ( wxpeer ) {
2de58153
VZ
101 const int sel = wxpeer->GetSelection();
102
ce7fe42e 103 wxCommandEvent event(wxEVT_COMBOBOX, wxpeer->GetId());
c84030e0 104 event.SetEventObject( wxpeer );
2de58153
VZ
105 event.SetInt( sel );
106 event.SetString( wxpeer->GetString(sel) );
c84030e0
KO
107 // For some reason, wxComboBox::GetValue will not return the newly selected item
108 // while we're inside this callback, so use AddPendingEvent to make sure
109 // GetValue() returns the right value.
18a7376a 110
c84030e0 111 wxpeer->GetEventHandler()->AddPendingEvent( event );
18a7376a 112
c84030e0
KO
113 }
114 }
4ddfa282 115}
4ddfa282
SC
116@end
117
c072b9ec
VZ
118wxNSComboBoxControl::wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w )
119 : wxNSTextFieldControl(wxPeer, wxPeer, w)
c84030e0
KO
120{
121 m_comboBox = (NSComboBox*)w;
122}
123
124wxNSComboBoxControl::~wxNSComboBoxControl()
125{
126}
127
06e56e62
SC
128void wxNSComboBoxControl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
129{
130 // NSComboBox has its own event loop, which reacts very badly to our synthetic
131 // events used to signal when a wxEvent is posted, so during that time we switch
132 // the wxEventLoop::WakeUp implementation to a lower-level version
133
134 bool reset = false;
135 wxEventLoop* const loop = (wxEventLoop*) wxEventLoopBase::GetActive();
136
137 if ( loop != NULL && [event type] == NSLeftMouseDown )
138 {
139 reset = true;
140 loop->OSXUseLowLevelWakeup(true);
141 }
142
143 wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
144 superimpl(slf, (SEL)_cmd, event);
145
146 if ( reset )
147 {
5928f660 148 loop->OSXUseLowLevelWakeup(false);
06e56e62
SC
149 }
150}
151
c84030e0
KO
152int wxNSComboBoxControl::GetSelectedItem() const
153{
154 return [m_comboBox indexOfSelectedItem];
155}
156
157void wxNSComboBoxControl::SetSelectedItem(int item)
158{
809020fc 159 SendEvents(false);
6f07c007
VZ
160
161 if ( item != wxNOT_FOUND )
162 {
163 wxASSERT_MSG( item >= 0 && item < [m_comboBox numberOfItems],
164 "Inavlid item index." );
165 [m_comboBox selectItemAtIndex: item];
166 }
167 else // remove current selection (if we have any)
168 {
169 const int sel = GetSelectedItem();
170 if ( sel != wxNOT_FOUND )
171 [m_comboBox deselectItemAtIndex:sel];
172 }
173
809020fc 174 SendEvents(true);
c84030e0
KO
175}
176
177int wxNSComboBoxControl::GetNumberOfItems() const
178{
179 return [m_comboBox numberOfItems];
180}
181
182void wxNSComboBoxControl::InsertItem(int pos, const wxString& item)
183{
184 [m_comboBox insertItemWithObjectValue:wxCFStringRef( item , m_wxPeer->GetFont().GetEncoding() ).AsNSString() atIndex:pos];
185}
186
187void wxNSComboBoxControl::RemoveItem(int pos)
188{
809020fc 189 SendEvents(false);
c84030e0 190 [m_comboBox removeItemAtIndex:pos];
809020fc 191 SendEvents(true);
c84030e0
KO
192}
193
194void wxNSComboBoxControl::Clear()
195{
809020fc 196 SendEvents(false);
c84030e0 197 [m_comboBox removeAllItems];
1d90958b 198 [m_comboBox setStringValue:@""];
809020fc 199 SendEvents(true);
c84030e0
KO
200}
201
202wxString wxNSComboBoxControl::GetStringAtIndex(int pos) const
203{
204 return wxCFStringRef::AsString([m_comboBox itemObjectValueAtIndex:pos], m_wxPeer->GetFont().GetEncoding());
205}
206
207int wxNSComboBoxControl::FindString(const wxString& text) const
208{
79323592
SC
209 NSInteger nsresult = [m_comboBox indexOfItemWithObjectValue:wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
210
211 int result;
212 if (nsresult == NSNotFound)
2c755d9b 213 result = wxNOT_FOUND;
79323592
SC
214 else
215 result = (int) nsresult;
2c755d9b 216 return result;
c84030e0
KO
217}
218
ff8cb900
VZ
219void wxNSComboBoxControl::Popup()
220{
221 id ax = NSAccessibilityUnignoredDescendant(m_comboBox);
222 [ax accessibilitySetValue: [NSNumber numberWithBool: YES] forAttribute: NSAccessibilityExpandedAttribute];
223}
224
225void wxNSComboBoxControl::Dismiss()
226{
227 id ax = NSAccessibilityUnignoredDescendant(m_comboBox);
228 [ax accessibilitySetValue: [NSNumber numberWithBool: NO] forAttribute: NSAccessibilityExpandedAttribute];
229}
230
d4e5c5b9
SC
231void wxNSComboBoxControl::SetEditable(bool editable)
232{
233 // TODO: unfortunately this does not work, setEditable just means the same as CB_READONLY
234 // I don't see a way to access the text field directly
06e56e62
SC
235
236 // Behavior NONE <- SELECTECTABLE
237 [m_comboBox setEditable:editable];
d4e5c5b9
SC
238}
239
c072b9ec 240wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxComboBox* wxpeer,
4ddfa282
SC
241 wxWindowMac* WXUNUSED(parent),
242 wxWindowID WXUNUSED(id),
e7794cf2 243 wxMenu* WXUNUSED(menu),
4ddfa282
SC
244 const wxPoint& pos,
245 const wxSize& size,
ec073e73 246 long style,
4ddfa282
SC
247 long WXUNUSED(extraStyle))
248{
249 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
f941a30b 250 wxNSComboBox* v = [[wxNSComboBox alloc] initWithFrame:r];
ec073e73
KO
251 if (style & wxCB_READONLY)
252 [v setEditable:NO];
c84030e0 253 wxNSComboBoxControl* c = new wxNSComboBoxControl( wxpeer, v );
4ddfa282
SC
254 return c;
255}
256
5bd77105
SC
257wxSize wxComboBox::DoGetBestSize() const
258{
259 int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
260 wxSize baseSize = wxWindow::DoGetBestSize();
261 int lbHeight = baseSize.y;
262 int wLine;
263
264 {
265 wxClientDC dc(const_cast<wxComboBox*>(this));
266
267 // Find the widest line
268 for(unsigned int i = 0; i < GetCount(); i++)
269 {
270 wxString str(GetString(i));
271
272 wxCoord width, height ;
273 dc.GetTextExtent( str , &width, &height);
274 wLine = width ;
275
276 lbWidth = wxMax( lbWidth, wLine ) ;
277 }
278
279 // Add room for the popup arrow
280 lbWidth += 2 * lbHeight ;
281 }
282
283 return wxSize( lbWidth, lbHeight );
284}
285
c072b9ec 286#endif // wxUSE_COMBOBOX