]>
Commit | Line | Data |
---|---|---|
3f7f284d RD |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/mac/carbon/srchctrl.cpp | |
3 | // Purpose: implements mac carbon wxSearchCtrl | |
4 | // Author: Vince Harron | |
3f7f284d | 5 | // Created: 2006-02-19 |
8bc333d7 | 6 | // RCS-ID: $Id$ |
3f7f284d RD |
7 | // Copyright: Vince Harron |
8 | // License: wxWindows licence | |
9 | /////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | // ============================================================================ | |
12 | // declarations | |
13 | // ============================================================================ | |
14 | ||
15 | // ---------------------------------------------------------------------------- | |
16 | // headers | |
17 | // ---------------------------------------------------------------------------- | |
18 | ||
3f7f284d RD |
19 | // For compilers that support precompilation, includes "wx.h". |
20 | #include "wx/wxprec.h" | |
21 | ||
22 | #ifdef __BORLANDC__ | |
23 | #pragma hdrstop | |
24 | #endif | |
25 | ||
26 | #ifndef WX_PRECOMP | |
27 | #include "wx/menu.h" | |
28 | #endif //WX_PRECOMP | |
29 | ||
30 | #if wxUSE_SEARCHCTRL | |
31 | ||
32 | #include "wx/srchctrl.h" | |
33 | ||
5b43c75c | 34 | #if wxUSE_NATIVE_SEARCH_CONTROL |
3f7f284d RD |
35 | |
36 | #include "wx/mac/uma.h" | |
37 | #include "wx/mac/carbon/private/mactext.h" | |
38 | ||
39 | BEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase) | |
40 | END_EVENT_TABLE() | |
41 | ||
42 | IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase) | |
43 | ||
44 | // ============================================================================ | |
45 | // wxMacSearchFieldControl | |
46 | // ============================================================================ | |
47 | ||
48 | #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 | |
49 | ||
50 | ||
51 | static const EventTypeSpec eventList[] = | |
52 | { | |
53 | { kEventClassSearchField, kEventSearchFieldCancelClicked } , | |
54 | { kEventClassSearchField, kEventSearchFieldSearchClicked } , | |
55 | }; | |
56 | ||
57 | class wxMacSearchFieldControl : public wxMacUnicodeTextControl | |
58 | { | |
59 | public : | |
60 | wxMacSearchFieldControl( wxTextCtrl *wxPeer, | |
61 | const wxString& str, | |
62 | const wxPoint& pos, | |
63 | const wxSize& size, long style ) : wxMacUnicodeTextControl( wxPeer ) | |
64 | { | |
65 | Create( wxPeer, str, pos, size, style ); | |
66 | } | |
67 | ||
68 | // search field options | |
ec184e32 VZ |
69 | virtual void ShowSearchButton( bool show ); |
70 | virtual bool IsSearchButtonVisible() const; | |
3f7f284d | 71 | |
ec184e32 VZ |
72 | virtual void ShowCancelButton( bool show ); |
73 | virtual bool IsCancelButtonVisible() const; | |
3f7f284d RD |
74 | |
75 | virtual void SetSearchMenu( wxMenu* menu ); | |
76 | virtual wxMenu* GetSearchMenu() const; | |
77 | protected : | |
78 | virtual void CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef crf ); | |
79 | ||
80 | private: | |
81 | wxMenu* m_menu; | |
82 | } ; | |
83 | ||
84 | void wxMacSearchFieldControl::CreateControl( wxTextCtrl* /*peer*/, const Rect* bounds, CFStringRef crf ) | |
85 | { | |
86 | OptionBits attributes = 0; | |
87 | if ( UMAGetSystemVersion() >= 0x1040 ) | |
88 | { | |
ec184e32 VZ |
89 | attributes = kHISearchFieldAttributesSearchIcon; |
90 | } | |
3f7f284d | 91 | HIRect hibounds = { { bounds->left, bounds->top }, { bounds->right-bounds->left, bounds->bottom-bounds->top } }; |
8bc333d7 | 92 | verify_noerr( HISearchFieldCreate( |
3f7f284d RD |
93 | &hibounds, |
94 | attributes, | |
95 | 0, // MenuRef | |
96 | CFSTR("Search"), | |
97 | &m_controlRef | |
98 | ) ); | |
8bc333d7 | 99 | HIViewSetVisible (m_controlRef, true); |
3f7f284d RD |
100 | } |
101 | ||
102 | // search field options | |
ef0abde6 | 103 | void wxMacSearchFieldControl::ShowSearchButton( bool show ) |
3f7f284d RD |
104 | { |
105 | if ( UMAGetSystemVersion() >= 0x1040 ) | |
106 | { | |
107 | OptionBits set = 0; | |
108 | OptionBits clear = 0; | |
109 | if ( show ) | |
110 | { | |
111 | set |= kHISearchFieldAttributesSearchIcon; | |
112 | } | |
113 | else | |
114 | { | |
115 | clear |= kHISearchFieldAttributesSearchIcon; | |
116 | } | |
117 | HISearchFieldChangeAttributes( m_controlRef, set, clear ); | |
118 | } | |
119 | } | |
120 | ||
ef0abde6 | 121 | bool wxMacSearchFieldControl::IsSearchButtonVisible() const |
8bc333d7 | 122 | { |
3f7f284d RD |
123 | OptionBits attributes = 0; |
124 | verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) ); | |
125 | return ( attributes & kHISearchFieldAttributesSearchIcon ) != 0; | |
126 | } | |
127 | ||
ef0abde6 | 128 | void wxMacSearchFieldControl::ShowCancelButton( bool show ) |
3f7f284d RD |
129 | { |
130 | OptionBits set = 0; | |
131 | OptionBits clear = 0; | |
132 | if ( show ) | |
133 | { | |
134 | set |= kHISearchFieldAttributesCancel; | |
135 | } | |
136 | else | |
137 | { | |
138 | clear |= kHISearchFieldAttributesCancel; | |
139 | } | |
140 | HISearchFieldChangeAttributes( m_controlRef, set, clear ); | |
141 | } | |
142 | ||
ef0abde6 | 143 | bool wxMacSearchFieldControl::IsCancelButtonVisible() const |
8bc333d7 | 144 | { |
3f7f284d RD |
145 | OptionBits attributes = 0; |
146 | verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) ); | |
147 | return ( attributes & kHISearchFieldAttributesCancel ) != 0; | |
148 | } | |
149 | ||
150 | void wxMacSearchFieldControl::SetSearchMenu( wxMenu* menu ) | |
151 | { | |
152 | m_menu = menu; | |
153 | if ( m_menu ) | |
154 | { | |
155 | verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, MAC_WXHMENU(m_menu->GetHMenu()) ) ); | |
156 | } | |
157 | else | |
158 | { | |
159 | verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, 0 ) ); | |
160 | } | |
161 | } | |
162 | ||
163 | wxMenu* wxMacSearchFieldControl::GetSearchMenu() const | |
164 | { | |
165 | return m_menu; | |
166 | } | |
167 | ||
168 | #endif | |
169 | ||
170 | // ============================================================================ | |
171 | // implementation | |
172 | // ============================================================================ | |
173 | ||
174 | static pascal OSStatus wxMacSearchControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) | |
175 | { | |
176 | OSStatus result = eventNotHandledErr ; | |
177 | ||
178 | wxMacCarbonEvent cEvent( event ) ; | |
179 | ||
180 | ControlRef controlRef ; | |
181 | wxSearchCtrl* thisWindow = (wxSearchCtrl*) data ; | |
182 | wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ; | |
183 | cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; | |
184 | ||
185 | switch( GetEventKind( event ) ) | |
186 | { | |
187 | case kEventSearchFieldCancelClicked : | |
188 | thisWindow->MacSearchFieldCancelHit( handler , event ) ; | |
189 | break ; | |
190 | case kEventSearchFieldSearchClicked : | |
191 | thisWindow->MacSearchFieldSearchHit( handler , event ) ; | |
192 | break ; | |
193 | } | |
194 | ||
195 | return result ; | |
196 | } | |
197 | ||
198 | DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacSearchControlEventHandler ) | |
199 | ||
200 | ||
201 | // ---------------------------------------------------------------------------- | |
202 | // wxSearchCtrl creation | |
203 | // ---------------------------------------------------------------------------- | |
204 | ||
205 | // creation | |
206 | // -------- | |
207 | ||
208 | wxSearchCtrl::wxSearchCtrl() | |
8bc333d7 | 209 | { |
3f7f284d RD |
210 | Init(); |
211 | } | |
212 | ||
213 | wxSearchCtrl::wxSearchCtrl(wxWindow *parent, wxWindowID id, | |
214 | const wxString& value, | |
215 | const wxPoint& pos, | |
216 | const wxSize& size, | |
217 | long style, | |
218 | const wxValidator& validator, | |
219 | const wxString& name) | |
220 | { | |
221 | Init(); | |
222 | ||
223 | Create(parent, id, value, pos, size, style, validator, name); | |
224 | } | |
225 | ||
226 | void wxSearchCtrl::Init() | |
227 | { | |
228 | m_menu = 0; | |
229 | } | |
230 | ||
231 | bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id, | |
232 | const wxString& value, | |
233 | const wxPoint& pos, | |
234 | const wxSize& size, | |
235 | long style, | |
236 | const wxValidator& validator, | |
237 | const wxString& name) | |
238 | { | |
239 | if ( !wxTextCtrl::Create(parent, id, wxEmptyString, pos, size, wxBORDER_NONE | style, validator, name) ) | |
240 | { | |
241 | return false; | |
242 | } | |
243 | ||
244 | EventHandlerRef searchEventHandler; | |
245 | InstallControlEventHandler( m_peer->GetControlRef(), GetwxMacSearchControlEventHandlerUPP(), | |
246 | GetEventTypeCount(eventList), eventList, this, | |
247 | (EventHandlerRef *)&searchEventHandler); | |
248 | ||
249 | return true; | |
250 | } | |
251 | ||
252 | wxSearchCtrl::~wxSearchCtrl() | |
253 | { | |
254 | delete m_menu; | |
255 | } | |
256 | ||
257 | wxSize wxSearchCtrl::DoGetBestSize() const | |
258 | { | |
698db322 KO |
259 | wxSize size = wxWindow::DoGetBestSize(); |
260 | // it seems to return a default width of about 16, which is way too small here. | |
261 | if (size.GetWidth() < 100) | |
262 | size.SetWidth(100); | |
8bc333d7 | 263 | |
698db322 KO |
264 | return size; |
265 | } | |
266 | ||
267 | void wxSearchCtrl::SetFocus() | |
268 | { | |
269 | // NB: We have to implement SetFocus a little differently because kControlFocusNextPart | |
270 | // leads to setting the focus on the search icon rather than the text area. | |
271 | // We get around this by explicitly telling the control to set focus to the | |
272 | // text area. | |
273 | if ( !AcceptsFocus() ) | |
274 | return ; | |
275 | ||
276 | wxWindow* former = FindFocus() ; | |
277 | if ( former == this ) | |
278 | return ; | |
279 | ||
280 | // as we cannot rely on the control features to find out whether we are in full keyboard mode, | |
281 | // we can only leave in case of an error | |
282 | OSStatus err = m_peer->SetFocus( kControlEditTextPart ) ; | |
283 | if ( err == errCouldntSetFocus ) | |
284 | return ; | |
285 | ||
286 | SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); | |
3f7f284d RD |
287 | } |
288 | ||
289 | // search control specific interfaces | |
290 | // wxSearchCtrl owns menu after this call | |
291 | void wxSearchCtrl::SetMenu( wxMenu* menu ) | |
292 | { | |
293 | if ( menu == m_menu ) | |
294 | { | |
295 | // no change | |
296 | return; | |
297 | } | |
298 | ||
299 | if ( m_menu ) | |
300 | { | |
301 | m_menu->SetInvokingWindow( 0 ); | |
302 | } | |
303 | ||
304 | delete m_menu; | |
305 | m_menu = menu; | |
306 | ||
307 | if ( m_menu ) | |
308 | { | |
309 | m_menu->SetInvokingWindow( this ); | |
310 | } | |
311 | ||
312 | GetPeer()->SetSearchMenu( m_menu ); | |
313 | } | |
314 | ||
315 | wxMenu* wxSearchCtrl::GetMenu() | |
316 | { | |
317 | return m_menu; | |
318 | } | |
319 | ||
ef0abde6 | 320 | void wxSearchCtrl::ShowSearchButton( bool show ) |
3f7f284d | 321 | { |
ef0abde6 | 322 | if ( IsSearchButtonVisible() == show ) |
3f7f284d RD |
323 | { |
324 | // no change | |
325 | return; | |
326 | } | |
ef0abde6 | 327 | GetPeer()->ShowSearchButton( show ); |
3f7f284d RD |
328 | } |
329 | ||
ef0abde6 | 330 | bool wxSearchCtrl::IsSearchButtonVisible() const |
3f7f284d | 331 | { |
ef0abde6 | 332 | return GetPeer()->IsSearchButtonVisible(); |
3f7f284d RD |
333 | } |
334 | ||
335 | ||
ef0abde6 | 336 | void wxSearchCtrl::ShowCancelButton( bool show ) |
3f7f284d | 337 | { |
ef0abde6 | 338 | if ( IsCancelButtonVisible() == show ) |
3f7f284d RD |
339 | { |
340 | // no change | |
341 | return; | |
342 | } | |
ef0abde6 | 343 | GetPeer()->ShowCancelButton( show ); |
3f7f284d RD |
344 | } |
345 | ||
ef0abde6 | 346 | bool wxSearchCtrl::IsCancelButtonVisible() const |
3f7f284d | 347 | { |
ef0abde6 | 348 | return GetPeer()->IsCancelButtonVisible(); |
3f7f284d RD |
349 | } |
350 | ||
351 | wxInt32 wxSearchCtrl::MacSearchFieldSearchHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) | |
352 | { | |
353 | wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_SEARCH, m_windowId ); | |
354 | event.SetEventObject(this); | |
355 | ProcessCommand(event); | |
356 | return eventNotHandledErr ; | |
357 | } | |
358 | ||
359 | wxInt32 wxSearchCtrl::MacSearchFieldCancelHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) | |
360 | { | |
361 | wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_CANCEL, m_windowId ); | |
362 | event.SetEventObject(this); | |
363 | ProcessCommand(event); | |
364 | return eventNotHandledErr ; | |
365 | } | |
366 | ||
367 | ||
368 | void wxSearchCtrl::CreatePeer( | |
369 | const wxString& str, | |
370 | const wxPoint& pos, | |
371 | const wxSize& size, long style ) | |
372 | { | |
373 | #ifdef __WXMAC_OSX__ | |
374 | #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 | |
375 | if ( UMAGetSystemVersion() >= 0x1030 ) | |
376 | { | |
377 | m_peer = new wxMacSearchFieldControl( this , str , pos , size , style ); | |
378 | } | |
379 | #endif | |
380 | #endif | |
381 | if ( !m_peer ) | |
382 | { | |
383 | wxTextCtrl::CreatePeer( str, pos, size, style ); | |
384 | } | |
385 | } | |
386 | ||
5b43c75c | 387 | #endif // wxUSE_NATIVE_SEARCH_CONTROL |
3f7f284d RD |
388 | |
389 | #endif // wxUSE_SEARCHCTRL |