]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/srchctrl.cpp
Forward port of my recent changes in the 2.8 branch:
[wxWidgets.git] / src / mac / carbon / srchctrl.cpp
CommitLineData
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
3f7f284d
RD
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
3f7f284d
RD
18#if wxUSE_SEARCHCTRL
19
20#include "wx/srchctrl.h"
21
1c62bcbe
PC
22#ifndef WX_PRECOMP
23 #include "wx/menu.h"
24#endif //WX_PRECOMP
25
5b43c75c 26#if wxUSE_NATIVE_SEARCH_CONTROL
3f7f284d
RD
27
28#include "wx/mac/uma.h"
29#include "wx/mac/carbon/private/mactext.h"
30
31BEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase)
32END_EVENT_TABLE()
33
34IMPLEMENT_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
43static const EventTypeSpec eventList[] =
44{
45 { kEventClassSearchField, kEventSearchFieldCancelClicked } ,
68fc5c80 46#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
3f7f284d 47 { kEventClassSearchField, kEventSearchFieldSearchClicked } ,
68fc5c80 48#endif
3f7f284d
RD
49};
50
51class wxMacSearchFieldControl : public wxMacUnicodeTextControl
52{
53public :
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
ec184e32
VZ
63 virtual void ShowSearchButton( bool show );
64 virtual bool IsSearchButtonVisible() const;
3f7f284d 65
ec184e32
VZ
66 virtual void ShowCancelButton( bool show );
67 virtual bool IsCancelButtonVisible() const;
3f7f284d
RD
68
69 virtual void SetSearchMenu( wxMenu* menu );
70 virtual wxMenu* GetSearchMenu() const;
6646ca90
RD
71
72 virtual void SetDescriptiveText(const wxString& text);
73 virtual wxString GetDescriptiveText() const;
74
3f7f284d
RD
75protected :
76 virtual void CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef crf );
77
78private:
79 wxMenu* m_menu;
80} ;
81
82void wxMacSearchFieldControl::CreateControl( wxTextCtrl* /*peer*/, const Rect* bounds, CFStringRef crf )
83{
84 OptionBits attributes = 0;
68fc5c80 85#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
3f7f284d
RD
86 if ( UMAGetSystemVersion() >= 0x1040 )
87 {
ec184e32
VZ
88 attributes = kHISearchFieldAttributesSearchIcon;
89 }
68fc5c80 90#endif
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 103void wxMacSearchFieldControl::ShowSearchButton( bool show )
3f7f284d 104{
68fc5c80 105#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
3f7f284d
RD
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 }
68fc5c80 120#endif
3f7f284d
RD
121}
122
ef0abde6 123bool wxMacSearchFieldControl::IsSearchButtonVisible() const
8bc333d7 124{
68fc5c80 125#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
3f7f284d
RD
126 OptionBits attributes = 0;
127 verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) );
128 return ( attributes & kHISearchFieldAttributesSearchIcon ) != 0;
68fc5c80
RD
129#else
130 return false;
131#endif
3f7f284d
RD
132}
133
ef0abde6 134void wxMacSearchFieldControl::ShowCancelButton( bool show )
3f7f284d
RD
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
ef0abde6 149bool wxMacSearchFieldControl::IsCancelButtonVisible() const
8bc333d7 150{
3f7f284d
RD
151 OptionBits attributes = 0;
152 verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) );
153 return ( attributes & kHISearchFieldAttributesCancel ) != 0;
154}
155
156void 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
169wxMenu* wxMacSearchFieldControl::GetSearchMenu() const
170{
171 return m_menu;
172}
173
6646ca90
RD
174
175void wxMacSearchFieldControl::SetDescriptiveText(const wxString& text)
176{
177 verify_noerr( HISearchFieldSetDescriptiveText(
178 m_controlRef,
179 wxMacCFStringHolder( text, wxFont::GetDefaultEncoding() )));
180}
181
182wxString 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
3f7f284d
RD
196#endif
197
198// ============================================================================
199// implementation
200// ============================================================================
201
202static 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 ;
3f7f284d
RD
210 cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ;
211
212 switch( GetEventKind( event ) )
213 {
214 case kEventSearchFieldCancelClicked :
215 thisWindow->MacSearchFieldCancelHit( handler , event ) ;
216 break ;
68fc5c80 217#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
3f7f284d
RD
218 case kEventSearchFieldSearchClicked :
219 thisWindow->MacSearchFieldSearchHit( handler , event ) ;
220 break ;
68fc5c80 221#endif
3f7f284d
RD
222 }
223
224 return result ;
225}
226
227DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacSearchControlEventHandler )
228
229
230// ----------------------------------------------------------------------------
231// wxSearchCtrl creation
232// ----------------------------------------------------------------------------
233
234// creation
235// --------
236
237wxSearchCtrl::wxSearchCtrl()
8bc333d7 238{
3f7f284d
RD
239 Init();
240}
241
242wxSearchCtrl::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
255void wxSearchCtrl::Init()
256{
257 m_menu = 0;
258}
259
260bool 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
281wxSearchCtrl::~wxSearchCtrl()
282{
283 delete m_menu;
284}
285
286wxSize wxSearchCtrl::DoGetBestSize() const
287{
698db322
KO
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);
8bc333d7 292
698db322
KO
293 return size;
294}
295
296void 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() );
3f7f284d
RD
316}
317
318// search control specific interfaces
319// wxSearchCtrl owns menu after this call
320void 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
344wxMenu* wxSearchCtrl::GetMenu()
345{
346 return m_menu;
347}
348
ef0abde6 349void wxSearchCtrl::ShowSearchButton( bool show )
3f7f284d 350{
ef0abde6 351 if ( IsSearchButtonVisible() == show )
3f7f284d
RD
352 {
353 // no change
354 return;
355 }
ef0abde6 356 GetPeer()->ShowSearchButton( show );
3f7f284d
RD
357}
358
ef0abde6 359bool wxSearchCtrl::IsSearchButtonVisible() const
3f7f284d 360{
ef0abde6 361 return GetPeer()->IsSearchButtonVisible();
3f7f284d
RD
362}
363
364
ef0abde6 365void wxSearchCtrl::ShowCancelButton( bool show )
3f7f284d 366{
ef0abde6 367 if ( IsCancelButtonVisible() == show )
3f7f284d
RD
368 {
369 // no change
370 return;
371 }
ef0abde6 372 GetPeer()->ShowCancelButton( show );
3f7f284d
RD
373}
374
ef0abde6 375bool wxSearchCtrl::IsCancelButtonVisible() const
3f7f284d 376{
ef0abde6 377 return GetPeer()->IsCancelButtonVisible();
3f7f284d
RD
378}
379
6646ca90
RD
380void wxSearchCtrl::SetDescriptiveText(const wxString& text)
381{
382 GetPeer()->SetDescriptiveText(text);
383}
384
385wxString wxSearchCtrl::GetDescriptiveText() const
386{
387 return GetPeer()->GetDescriptiveText();
388}
389
3f7f284d
RD
390wxInt32 wxSearchCtrl::MacSearchFieldSearchHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
391{
c60122bf 392 wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, m_windowId );
3f7f284d
RD
393 event.SetEventObject(this);
394 ProcessCommand(event);
395 return eventNotHandledErr ;
396}
397
398wxInt32 wxSearchCtrl::MacSearchFieldCancelHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
399{
c60122bf 400 wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, m_windowId );
3f7f284d
RD
401 event.SetEventObject(this);
402 ProcessCommand(event);
403 return eventNotHandledErr ;
404}
405
406
407void 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
5b43c75c 426#endif // wxUSE_NATIVE_SEARCH_CONTROL
3f7f284d
RD
427
428#endif // wxUSE_SEARCHCTRL