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