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