1///////////////////////////////////////////////////////////////////////////////
2// Name:        src/osx/cocoa/srchctrl.mm
3// Purpose:     implements mac carbon wxSearchCtrl
4// Author:      Vince Harron
5// Created:     2006-02-19
6// Copyright:   Vince Harron
7// Licence:     wxWindows licence
8///////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14    #pragma hdrstop
15#endif
16
17#if wxUSE_SEARCHCTRL
18
19#include "wx/srchctrl.h"
20
21#ifndef WX_PRECOMP
22    #include "wx/menu.h"
23#endif //WX_PRECOMP
24
25#if wxUSE_NATIVE_SEARCH_CONTROL
26
27#include "wx/osx/private.h"
28#include "wx/osx/cocoa/private/textimpl.h"
29
30
31@interface wxNSSearchField : NSSearchField
32{
33}
34
35@end
36
37@implementation wxNSSearchField
38
39+ (void)initialize
40{
41    static BOOL initialized = NO;
42    if (!initialized)
43    {
44        initialized = YES;
45        wxOSXCocoaClassAddWXMethods( self );
46    }
47}
48
49- (id)initWithFrame:(NSRect)frame
50{
51    self = [super initWithFrame:frame];
52    return self;
53}
54
55- (void)controlTextDidChange:(NSNotification *)aNotification
56{
57    wxUnusedVar(aNotification);
58    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
59    if ( impl )
60        impl->controlTextDidChange();
61}
62
63- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words
64 forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
65{
66    NSMutableArray* matches = NULL;
67    NSString*       partialString;
68
69    partialString = [[textView string] substringWithRange:charRange];
70    matches       = [NSMutableArray array];
71
72    // wxTextWidgetImpl* impl = (wxTextWidgetImpl* ) wxWidgetImpl::FindFromWXWidget( self );
73    wxArrayString completions;
74
75    // adapt to whatever strategy we have for getting the strings
76    // impl->GetTextEntry()->GetCompletions(wxCFStringRef::AsString(partialString), completions);
77
78    for (size_t i = 0; i < completions.GetCount(); ++i )
79        [matches addObject: wxCFStringRef(completions[i]).AsNSString()];
80
81    // [matches sortUsingSelector:@selector(compare:)];
82
83
84    return matches;
85}
86
87@end
88
89// ============================================================================
90// wxMacSearchFieldControl
91// ============================================================================
92
93class wxNSSearchFieldControl : public wxNSTextFieldControl, public wxSearchWidgetImpl
94{
95public :
96    wxNSSearchFieldControl( wxTextCtrl *wxPeer, wxNSSearchField* w  ) : wxNSTextFieldControl(wxPeer, w)
97    {
98        m_searchFieldCell = [w cell];
99        m_searchField = w;
100    }
101    ~wxNSSearchFieldControl();
102
103    // search field options
104    virtual void ShowSearchButton( bool show )
105    {
106        if ( show )
107            [m_searchFieldCell resetSearchButtonCell];
108        else
109            [m_searchFieldCell setSearchButtonCell:nil];
110        [m_searchField setNeedsDisplay:YES];
111    }
112
113    virtual bool IsSearchButtonVisible() const
114    {
115        return [m_searchFieldCell searchButtonCell] != nil;
116    }
117
118    virtual void ShowCancelButton( bool show )
119    {
120        if ( show )
121            [m_searchFieldCell resetCancelButtonCell];
122        else
123            [m_searchFieldCell setCancelButtonCell:nil];
124        [m_searchField setNeedsDisplay:YES];
125    }
126
127    virtual bool IsCancelButtonVisible() const
128    {
129        return [m_searchFieldCell cancelButtonCell] != nil;
130    }
131
132    virtual void SetSearchMenu( wxMenu* menu )
133    {
134        if ( menu )
135            [m_searchFieldCell setSearchMenuTemplate:menu->GetHMenu()];
136        else
137            [m_searchFieldCell setSearchMenuTemplate:nil];
138        [m_searchField setNeedsDisplay:YES];
139    }
140
141    virtual void SetDescriptiveText(const wxString& text)
142    {
143        [m_searchFieldCell setPlaceholderString:
144            wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
145    }
146
147    virtual bool SetFocus()
148    {
149       return  wxNSTextFieldControl::SetFocus();
150    }
151
152    void controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
153    {
154        wxSearchCtrl* wxpeer = (wxSearchCtrl*) GetWXPeer();
155        if ( wxpeer )
156        {
157            NSString *searchString = [m_searchField stringValue];
158            if ( searchString == nil || !searchString.length )
159            {
160                wxpeer->HandleSearchFieldCancelHit();
161            }
162            else
163            {
164                wxpeer->HandleSearchFieldSearchHit();
165            }
166        }
167    }
168
169    virtual void SetCentredLook( bool centre )
170    {
171        SEL sel = @selector(setCenteredLook:);
172        if ( [m_searchFieldCell respondsToSelector: sel] )
173        {
174            // all this avoids xcode parsing warnings when using
175            // [m_searchFieldCell setCenteredLook:NO];
176            NSMethodSignature* signature =
177            [NSSearchFieldCell instanceMethodSignatureForSelector:sel];
178            NSInvocation* invocation =
179            [NSInvocation invocationWithMethodSignature: signature];
180            [invocation setTarget: m_searchFieldCell];
181            [invocation setSelector:sel];
182            [invocation setArgument:&centre atIndex:2];
183            [invocation invoke];
184        }
185    }
186
187private:
188    wxNSSearchField* m_searchField;
189    NSSearchFieldCell* m_searchFieldCell;
190} ;
191
192wxNSSearchFieldControl::~wxNSSearchFieldControl()
193{
194}
195
196wxWidgetImplType* wxWidgetImpl::CreateSearchControl( wxSearchCtrl* wxpeer,
197                                    wxWindowMac* WXUNUSED(parent),
198                                    wxWindowID WXUNUSED(id),
199                                    const wxString& str,
200                                    const wxPoint& pos,
201                                    const wxSize& size,
202                                    long WXUNUSED(style),
203                                    long WXUNUSED(extraStyle))
204{
205    NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
206    wxNSSearchField* v = [[wxNSSearchField alloc] initWithFrame:r];
207
208    // Make it behave consistently with the single line wxTextCtrl
209    [[v cell] setScrollable:YES];
210
211    [[v cell] setSendsWholeSearchString:YES];
212    // per wx default cancel is not shown
213    [[v cell] setCancelButtonCell:nil];
214
215    wxNSSearchFieldControl* c = new wxNSSearchFieldControl( wxpeer, v );
216    c->SetNeedsFrame( false );
217    c->SetCentredLook( false );
218    c->SetStringValue( str );
219    return c;
220}
221
222#endif // wxUSE_NATIVE_SEARCH_CONTROL
223
224#endif // wxUSE_SEARCHCTRL
225