]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/combobox.mm
Make wxEVT_CHAR_HOOK propagate upwards and send it to the window itself.
[wxWidgets.git] / src / osx / cocoa / combobox.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/combobox.mm
3 // Purpose: wxChoice
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_COMBOBOX
15
16 #include "wx/combobox.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/menu.h"
20 #include "wx/dcclient.h"
21 #endif
22
23 #include "wx/osx/cocoa/private/textimpl.h"
24
25 // work in progress
26
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
38 @interface wxNSComboBox : NSComboBox
39 {
40 }
41
42 @end
43
44 @implementation wxNSComboBox
45
46 + (void)initialize
47 {
48 static BOOL initialized = NO;
49 if (!initialized)
50 {
51 initialized = YES;
52 wxOSXCocoaClassAddWXMethods( self );
53 }
54 }
55
56 - (void)controlTextDidChange:(NSNotification *)aNotification
57 {
58 wxUnusedVar(aNotification);
59 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
60 if ( impl && impl->ShouldSendEvents() )
61 {
62 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
63 if ( wxpeer ) {
64 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
65 event.SetEventObject( wxpeer );
66 event.SetString( static_cast<wxComboBox*>(wxpeer)->GetValue() );
67 wxpeer->HandleWindowEvent( event );
68 }
69 }
70 }
71
72 - (void)comboBoxSelectionDidChange:(NSNotification *)notification
73 {
74 wxUnusedVar(notification);
75 wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
76 if ( impl && impl->ShouldSendEvents())
77 {
78 wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
79 if ( wxpeer ) {
80 wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, wxpeer->GetId());
81 event.SetEventObject( wxpeer );
82 event.SetInt( static_cast<wxComboBox*>(wxpeer)->GetSelection() );
83 // For some reason, wxComboBox::GetValue will not return the newly selected item
84 // while we're inside this callback, so use AddPendingEvent to make sure
85 // GetValue() returns the right value.
86 wxpeer->GetEventHandler()->AddPendingEvent( event );
87 }
88 }
89 }
90 @end
91
92 wxNSComboBoxControl::wxNSComboBoxControl( wxComboBox *wxPeer, WXWidget w )
93 : wxNSTextFieldControl(wxPeer, wxPeer, w)
94 {
95 m_comboBox = (NSComboBox*)w;
96 }
97
98 wxNSComboBoxControl::~wxNSComboBoxControl()
99 {
100 }
101
102 int wxNSComboBoxControl::GetSelectedItem() const
103 {
104 return [m_comboBox indexOfSelectedItem];
105 }
106
107 void wxNSComboBoxControl::SetSelectedItem(int item)
108 {
109 SendEvents(false);
110
111 if ( item != wxNOT_FOUND )
112 {
113 wxASSERT_MSG( item >= 0 && item < [m_comboBox numberOfItems],
114 "Inavlid item index." );
115 [m_comboBox selectItemAtIndex: item];
116 }
117 else // remove current selection (if we have any)
118 {
119 const int sel = GetSelectedItem();
120 if ( sel != wxNOT_FOUND )
121 [m_comboBox deselectItemAtIndex:sel];
122 }
123
124 SendEvents(true);
125 }
126
127 int wxNSComboBoxControl::GetNumberOfItems() const
128 {
129 return [m_comboBox numberOfItems];
130 }
131
132 void wxNSComboBoxControl::InsertItem(int pos, const wxString& item)
133 {
134 [m_comboBox insertItemWithObjectValue:wxCFStringRef( item , m_wxPeer->GetFont().GetEncoding() ).AsNSString() atIndex:pos];
135 }
136
137 void wxNSComboBoxControl::RemoveItem(int pos)
138 {
139 SendEvents(false);
140 [m_comboBox removeItemAtIndex:pos];
141 SendEvents(true);
142 }
143
144 void wxNSComboBoxControl::Clear()
145 {
146 SendEvents(false);
147 [m_comboBox removeAllItems];
148 SendEvents(true);
149 }
150
151 wxString wxNSComboBoxControl::GetStringAtIndex(int pos) const
152 {
153 return wxCFStringRef::AsString([m_comboBox itemObjectValueAtIndex:pos], m_wxPeer->GetFont().GetEncoding());
154 }
155
156 int wxNSComboBoxControl::FindString(const wxString& text) const
157 {
158 NSInteger nsresult = [m_comboBox indexOfItemWithObjectValue:wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
159
160 int result;
161 if (nsresult == NSNotFound)
162 result = wxNOT_FOUND;
163 else
164 result = (int) nsresult;
165 return result;
166 }
167
168 wxWidgetImplType* wxWidgetImpl::CreateComboBox( wxComboBox* wxpeer,
169 wxWindowMac* WXUNUSED(parent),
170 wxWindowID WXUNUSED(id),
171 wxMenu* WXUNUSED(menu),
172 const wxPoint& pos,
173 const wxSize& size,
174 long style,
175 long WXUNUSED(extraStyle))
176 {
177 NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
178 wxNSComboBox* v = [[wxNSComboBox alloc] initWithFrame:r];
179 if (style & wxCB_READONLY)
180 [v setEditable:NO];
181 wxNSComboBoxControl* c = new wxNSComboBoxControl( wxpeer, v );
182 return c;
183 }
184
185 wxSize wxComboBox::DoGetBestSize() const
186 {
187 int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
188 wxSize baseSize = wxWindow::DoGetBestSize();
189 int lbHeight = baseSize.y;
190 int wLine;
191
192 {
193 wxClientDC dc(const_cast<wxComboBox*>(this));
194
195 // Find the widest line
196 for(unsigned int i = 0; i < GetCount(); i++)
197 {
198 wxString str(GetString(i));
199
200 wxCoord width, height ;
201 dc.GetTextExtent( str , &width, &height);
202 wLine = width ;
203
204 lbWidth = wxMax( lbWidth, wLine ) ;
205 }
206
207 // Add room for the popup arrow
208 lbWidth += 2 * lbHeight ;
209 }
210
211 return wxSize( lbWidth, lbHeight );
212 }
213
214 #endif // wxUSE_COMBOBOX