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