X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/524c47aa3adf2af11a3069fd5da035a604f08f66..b0ae60498d2a1cab6cff09d425d235a0847135e8:/src/osx/cocoa/srchctrl.mm diff --git a/src/osx/cocoa/srchctrl.mm b/src/osx/cocoa/srchctrl.mm index cc744f8c72..567789a2e9 100644 --- a/src/osx/cocoa/srchctrl.mm +++ b/src/osx/cocoa/srchctrl.mm @@ -1,11 +1,11 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/srchctrl.cpp +// Name: src/osx/cocoa/srchctrl.mm // Purpose: implements mac carbon wxSearchCtrl // Author: Vince Harron // Created: 2006-02-19 -// RCS-ID: $Id: srchctrl.cpp 54820 2008-07-29 20:04:11Z SC $ +// RCS-ID: $Id$ // Copyright: Vince Harron -// License: wxWindows licence +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". @@ -25,368 +25,176 @@ #if wxUSE_NATIVE_SEARCH_CONTROL -#include "wx/osx/uma.h" -#include "wx/osx/carbon/private/mactext.h" +#include "wx/osx/private.h" +#include "wx/osx/cocoa/private/textimpl.h" -BEGIN_EVENT_TABLE(wxSearchCtrl, wxSearchCtrlBase) -END_EVENT_TABLE() -IMPLEMENT_DYNAMIC_CLASS(wxSearchCtrl, wxSearchCtrlBase) - -// ============================================================================ -// wxMacSearchFieldControl -// ============================================================================ - -static const EventTypeSpec eventList[] = -{ - { kEventClassSearchField, kEventSearchFieldCancelClicked } , - { kEventClassSearchField, kEventSearchFieldSearchClicked } , -}; - -class wxMacSearchFieldControl : public wxMacUnicodeTextControl -{ -public : - wxMacSearchFieldControl( wxTextCtrl *wxPeer, - const wxString& str, - const wxPoint& pos, - const wxSize& size, long style ) : wxMacUnicodeTextControl( wxPeer ) - { - Create( wxPeer, str, pos, size, style ); - } - - // search field options - virtual void ShowSearchButton( bool show ); - virtual bool IsSearchButtonVisible() const; - - virtual void ShowCancelButton( bool show ); - virtual bool IsCancelButtonVisible() const; - - virtual void SetSearchMenu( wxMenu* menu ); - virtual wxMenu* GetSearchMenu() const; - - virtual void SetDescriptiveText(const wxString& text); - virtual wxString GetDescriptiveText() const; - - virtual bool SetFocus(); - -protected : - virtual void CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef crf ); - -private: - wxMenu* m_menu; -} ; - -void wxMacSearchFieldControl::CreateControl(wxTextCtrl* WXUNUSED(peer), - const Rect* bounds, - CFStringRef WXUNUSED(crf)) +@interface wxNSSearchField : NSSearchField { - OptionBits attributes = kHISearchFieldAttributesSearchIcon; - - HIRect hibounds = { { bounds->left, bounds->top }, { bounds->right-bounds->left, bounds->bottom-bounds->top } }; - verify_noerr( HISearchFieldCreate( - &hibounds, - attributes, - 0, // MenuRef - CFSTR("Search"), - &m_controlRef - ) ); - HIViewSetVisible (m_controlRef, true); } -// search field options -void wxMacSearchFieldControl::ShowSearchButton( bool show ) -{ - OptionBits set = 0; - OptionBits clear = 0; - if ( show ) - { - set |= kHISearchFieldAttributesSearchIcon; - } - else - { - clear |= kHISearchFieldAttributesSearchIcon; - } - HISearchFieldChangeAttributes( m_controlRef, set, clear ); -} +@end -bool wxMacSearchFieldControl::IsSearchButtonVisible() const -{ - OptionBits attributes = 0; - verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) ); - return ( attributes & kHISearchFieldAttributesSearchIcon ) != 0; -} +@implementation wxNSSearchField -void wxMacSearchFieldControl::ShowCancelButton( bool show ) ++ (void)initialize { - OptionBits set = 0; - OptionBits clear = 0; - if ( show ) + static BOOL initialized = NO; + if (!initialized) { - set |= kHISearchFieldAttributesCancel; + initialized = YES; + wxOSXCocoaClassAddWXMethods( self ); } - else - { - clear |= kHISearchFieldAttributesCancel; - } - HISearchFieldChangeAttributes( m_controlRef, set, clear ); } -bool wxMacSearchFieldControl::IsCancelButtonVisible() const +- (id)initWithFrame:(NSRect)frame { - OptionBits attributes = 0; - verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) ); - return ( attributes & kHISearchFieldAttributesCancel ) != 0; + self = [super initWithFrame:frame]; + return self; } - -void wxMacSearchFieldControl::SetSearchMenu( wxMenu* menu ) + +- (void)controlTextDidChange:(NSNotification *)aNotification { - m_menu = menu; - if ( m_menu ) - { - verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, MAC_WXHMENU(m_menu->GetHMenu()) ) ); - } - else - { - verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, 0 ) ); - } + wxUnusedVar(aNotification); + wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); + if ( impl ) + impl->controlTextDidChange(); } -wxMenu* wxMacSearchFieldControl::GetSearchMenu() const +- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words + forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index { - return m_menu; + NSMutableArray* matches = NULL; + NSString* partialString; + + partialString = [[textView string] substringWithRange:charRange]; + matches = [NSMutableArray array]; + + // wxTextWidgetImpl* impl = (wxTextWidgetImpl* ) wxWidgetImpl::FindFromWXWidget( self ); + wxArrayString completions; + + // adapt to whatever strategy we have for getting the strings + // impl->GetTextEntry()->GetCompletions(wxCFStringRef::AsString(partialString), completions); + + for (size_t i = 0; i < completions.GetCount(); ++i ) + [matches addObject: wxCFStringRef(completions[i]).AsNSString()]; + + // [matches sortUsingSelector:@selector(compare:)]; + + + return matches; } +@end -void wxMacSearchFieldControl::SetDescriptiveText(const wxString& text) -{ - verify_noerr( HISearchFieldSetDescriptiveText( - m_controlRef, - wxCFStringRef( text, wxFont::GetDefaultEncoding() ))); -} +// ============================================================================ +// wxMacSearchFieldControl +// ============================================================================ -wxString wxMacSearchFieldControl::GetDescriptiveText() const +class wxNSSearchFieldControl : public wxNSTextFieldControl, public wxSearchWidgetImpl { - CFStringRef cfStr; - verify_noerr( HISearchFieldCopyDescriptiveText( m_controlRef, &cfStr )); - if ( cfStr ) +public : + wxNSSearchFieldControl( wxTextCtrl *wxPeer, wxNSSearchField* w ) : wxNSTextFieldControl(wxPeer, w) { - return wxCFStringRef(cfStr).AsString(); + m_searchFieldCell = [w cell]; + m_searchField = w; } - else + ~wxNSSearchFieldControl(); + + // search field options + virtual void ShowSearchButton( bool show ) { - return wxEmptyString; + if ( show ) + [m_searchFieldCell resetSearchButtonCell]; + else + [m_searchFieldCell setSearchButtonCell:nil]; + [m_searchField setNeedsDisplay:YES]; } -} - -bool wxMacSearchFieldControl::SetFocus() -{ - // NB: We have to implement SetFocus a little differently because kControlFocusNextPart - // leads to setting the focus on the search icon rather than the text area. - // We get around this by explicitly telling the control to set focus to the - // text area. - OSStatus err = SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, kControlEditTextPart ); - if ( err == errCouldntSetFocus ) - return false ; - SetUserFocusWindow(GetControlOwner( m_controlRef ) ); - return true; -} - - -// ============================================================================ -// implementation -// ============================================================================ - -static pascal OSStatus wxMacSearchControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) -{ - OSStatus result = eventNotHandledErr ; - - wxMacCarbonEvent cEvent( event ) ; - - ControlRef controlRef ; - wxSearchCtrl* thisWindow = (wxSearchCtrl*) data ; - cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; - - switch( GetEventKind( event ) ) + virtual bool IsSearchButtonVisible() const { - case kEventSearchFieldCancelClicked : - thisWindow->MacSearchFieldCancelHit( handler , event ) ; - break ; - case kEventSearchFieldSearchClicked : - thisWindow->MacSearchFieldSearchHit( handler , event ) ; - break ; + return [m_searchFieldCell searchButtonCell] != nil; } - return result ; -} - -DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacSearchControlEventHandler ) - - -// ---------------------------------------------------------------------------- -// wxSearchCtrl creation -// ---------------------------------------------------------------------------- - -// creation -// -------- - -wxSearchCtrl::wxSearchCtrl() -{ - Init(); -} - -wxSearchCtrl::wxSearchCtrl(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) -{ - Init(); - - Create(parent, id, value, pos, size, style, validator, name); -} - -void wxSearchCtrl::Init() -{ - m_menu = 0; -} - -bool wxSearchCtrl::Create(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - long style, - const wxValidator& validator, - const wxString& name) -{ - if ( !wxTextCtrl::Create(parent, id, wxEmptyString, pos, size, wxBORDER_NONE | style, validator, name) ) + virtual void ShowCancelButton( bool show ) { - return false; + if ( show ) + [m_searchFieldCell resetCancelButtonCell]; + else + [m_searchFieldCell setCancelButtonCell:nil]; + [m_searchField setNeedsDisplay:YES]; } - EventHandlerRef searchEventHandler; - InstallControlEventHandler( m_peer->GetControlRef(), GetwxMacSearchControlEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, this, - (EventHandlerRef *)&searchEventHandler); - - SetValue(value); - - return true; -} - -wxSearchCtrl::~wxSearchCtrl() -{ - delete m_menu; -} - -wxSize wxSearchCtrl::DoGetBestSize() const -{ - wxSize size = wxWindow::DoGetBestSize(); - // it seems to return a default width of about 16, which is way too small here. - if (size.GetWidth() < 100) - size.SetWidth(100); - - return size; -} - - -// search control specific interfaces -// wxSearchCtrl owns menu after this call -void wxSearchCtrl::SetMenu( wxMenu* menu ) -{ - if ( menu == m_menu ) + virtual bool IsCancelButtonVisible() const { - // no change - return; + return [m_searchFieldCell cancelButtonCell] != nil; } - if ( m_menu ) + virtual void SetSearchMenu( wxMenu* menu ) { - m_menu->SetInvokingWindow( 0 ); + if ( menu ) + [m_searchFieldCell setSearchMenuTemplate:menu->GetHMenu()]; + else + [m_searchFieldCell setSearchMenuTemplate:nil]; + [m_searchField setNeedsDisplay:YES]; } - delete m_menu; - m_menu = menu; - - if ( m_menu ) + virtual void SetDescriptiveText(const wxString& text) { - m_menu->SetInvokingWindow( this ); + [m_searchFieldCell setPlaceholderString: + wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()]; } - GetPeer()->SetSearchMenu( m_menu ); -} - -wxMenu* wxSearchCtrl::GetMenu() -{ - return m_menu; -} - -void wxSearchCtrl::ShowSearchButton( bool show ) -{ - if ( IsSearchButtonVisible() == show ) + virtual bool SetFocus() { - // no change - return; + return wxNSTextFieldControl::SetFocus(); } - GetPeer()->ShowSearchButton( show ); -} - -bool wxSearchCtrl::IsSearchButtonVisible() const -{ - return GetPeer()->IsSearchButtonVisible(); -} - -void wxSearchCtrl::ShowCancelButton( bool show ) -{ - if ( IsCancelButtonVisible() == show ) + void controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender)) { - // no change - return; + wxSearchCtrl* wxpeer = (wxSearchCtrl*) GetWXPeer(); + if ( wxpeer ) + { + NSString *searchString = [m_searchField stringValue]; + if ( searchString == nil ) + { + wxpeer->HandleSearchFieldCancelHit(); + } + else + { + wxpeer->HandleSearchFieldSearchHit(); + } + } } - GetPeer()->ShowCancelButton( show ); -} - -bool wxSearchCtrl::IsCancelButtonVisible() const -{ - return GetPeer()->IsCancelButtonVisible(); -} - -void wxSearchCtrl::SetDescriptiveText(const wxString& text) -{ - GetPeer()->SetDescriptiveText(text); -} - -wxString wxSearchCtrl::GetDescriptiveText() const -{ - return GetPeer()->GetDescriptiveText(); -} + +private: + wxNSSearchField* m_searchField; + NSSearchFieldCell* m_searchFieldCell; +} ; -wxInt32 wxSearchCtrl::MacSearchFieldSearchHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +wxNSSearchFieldControl::~wxNSSearchFieldControl() { - wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_SEARCH_BTN, m_windowId ); - event.SetEventObject(this); - ProcessCommand(event); - return eventNotHandledErr ; } -wxInt32 wxSearchCtrl::MacSearchFieldCancelHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +wxWidgetImplType* wxWidgetImpl::CreateSearchControl( wxSearchCtrl* wxpeer, + wxWindowMac* WXUNUSED(parent), + wxWindowID WXUNUSED(id), + const wxString& str, + const wxPoint& pos, + const wxSize& size, + long WXUNUSED(style), + long WXUNUSED(extraStyle)) { - wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, m_windowId ); - event.SetEventObject(this); - ProcessCommand(event); - return eventNotHandledErr ; -} - + NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ; + wxNSSearchField* v = [[wxNSSearchField alloc] initWithFrame:r]; + [[v cell] setSendsWholeSearchString:YES]; + // per wx default cancel is not shown + [[v cell] setCancelButtonCell:nil]; -void wxSearchCtrl::CreatePeer( - const wxString& str, - const wxPoint& pos, - const wxSize& size, long style ) -{ - m_peer = new wxMacSearchFieldControl( this , str , pos , size , style ); + wxNSSearchFieldControl* c = new wxNSSearchFieldControl( wxpeer, v ); + c->SetNeedsFrame( false ); + c->SetStringValue( str ); + return c; } #endif // wxUSE_NATIVE_SEARCH_CONTROL