]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/srchctrl.mm
guarding open combo box against AppDefined NSEvents issued by wxEventLoop::WakeUp...
[wxWidgets.git] / src / osx / cocoa / srchctrl.mm
index cc744f8c7264df0cdca7faf5bc2d2379da1fc951..567789a2e988fc4a4483d50691e8c05987826d3b 100644 (file)
@@ -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
 // 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
 // Copyright:   Vince Harron
-// License:     wxWindows licence
+// Licence:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
 // For compilers that support precompilation, includes "wx.h".
 ///////////////////////////////////////////////////////////////////////////////
 
 // For compilers that support precompilation, includes "wx.h".
 
 #if wxUSE_NATIVE_SEARCH_CONTROL
 
 
 #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
 }
 
 #endif // wxUSE_NATIVE_SEARCH_CONTROL