///////////////////////////////////////////////////////////////////////////////
-// 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".
#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