see https://github.com/wxWidgets/wxWidgets/pull/698 , along the idea by commit 1776f136f7d673c8e772c9ca6e1607089a071651, implemented a little bit more defensively
242 lines
6.8 KiB
Plaintext
242 lines
6.8 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/osx/cocoa/srchctrl.mm
|
|
// Purpose: implements mac carbon wxSearchCtrl
|
|
// Author: Vince Harron
|
|
// Created: 2006-02-19
|
|
// Copyright: Vince Harron
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_SEARCHCTRL
|
|
|
|
#include "wx/srchctrl.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/menu.h"
|
|
#endif //WX_PRECOMP
|
|
|
|
#if wxUSE_NATIVE_SEARCH_CONTROL
|
|
|
|
#include "wx/osx/private.h"
|
|
#include "wx/osx/cocoa/private/textimpl.h"
|
|
|
|
|
|
@interface wxNSSearchField : NSSearchField
|
|
{
|
|
BOOL m_withinTextDidChange;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation wxNSSearchField
|
|
|
|
+ (void)initialize
|
|
{
|
|
static BOOL initialized = NO;
|
|
if (!initialized)
|
|
{
|
|
initialized = YES;
|
|
wxOSXCocoaClassAddWXMethods( self );
|
|
}
|
|
}
|
|
|
|
- (id)initWithFrame:(NSRect)frame
|
|
{
|
|
if ( self = [super initWithFrame:frame] )
|
|
{
|
|
m_withinTextDidChange = NO;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)textDidChange:(NSNotification *)aNotification
|
|
{
|
|
m_withinTextDidChange = YES;
|
|
[super textDidChange:aNotification];
|
|
m_withinTextDidChange = NO;
|
|
}
|
|
|
|
- (void)controlTextDidChange:(NSNotification *)aNotification
|
|
{
|
|
wxUnusedVar(aNotification);
|
|
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
|
|
if ( impl )
|
|
impl->controlTextDidChange();
|
|
}
|
|
|
|
- (NSArray *)control:(NSControl *)control textView:(NSTextView *)textView completions:(NSArray *)words
|
|
forPartialWordRange:(NSRange)charRange indexOfSelectedItem:(int*)index
|
|
{
|
|
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;
|
|
}
|
|
|
|
- (BOOL) isWithinTextDidChange
|
|
{
|
|
return m_withinTextDidChange;
|
|
}
|
|
|
|
@end
|
|
|
|
// ============================================================================
|
|
// wxMacSearchFieldControl
|
|
// ============================================================================
|
|
|
|
class wxNSSearchFieldControl : public wxNSTextFieldControl, public wxSearchWidgetImpl
|
|
{
|
|
public :
|
|
wxNSSearchFieldControl( wxTextCtrl *wxPeer, wxNSSearchField* w ) : wxNSTextFieldControl(wxPeer, w)
|
|
{
|
|
m_searchFieldCell = [w cell];
|
|
m_searchField = w;
|
|
}
|
|
~wxNSSearchFieldControl();
|
|
|
|
// search field options
|
|
virtual void ShowSearchButton( bool show ) wxOVERRIDE
|
|
{
|
|
if ( show )
|
|
[m_searchFieldCell resetSearchButtonCell];
|
|
else
|
|
[m_searchFieldCell setSearchButtonCell:nil];
|
|
[m_searchField setNeedsDisplay:YES];
|
|
}
|
|
|
|
virtual bool IsSearchButtonVisible() const wxOVERRIDE
|
|
{
|
|
return [m_searchFieldCell searchButtonCell] != nil;
|
|
}
|
|
|
|
virtual void ShowCancelButton( bool show ) wxOVERRIDE
|
|
{
|
|
if ( show )
|
|
[m_searchFieldCell resetCancelButtonCell];
|
|
else
|
|
[m_searchFieldCell setCancelButtonCell:nil];
|
|
[m_searchField setNeedsDisplay:YES];
|
|
}
|
|
|
|
virtual bool IsCancelButtonVisible() const wxOVERRIDE
|
|
{
|
|
return [m_searchFieldCell cancelButtonCell] != nil;
|
|
}
|
|
|
|
virtual void SetSearchMenu( wxMenu* menu ) wxOVERRIDE
|
|
{
|
|
if ( menu )
|
|
[m_searchFieldCell setSearchMenuTemplate:menu->GetHMenu()];
|
|
else
|
|
[m_searchFieldCell setSearchMenuTemplate:nil];
|
|
[m_searchField setNeedsDisplay:YES];
|
|
}
|
|
|
|
virtual void SetDescriptiveText(const wxString& text) wxOVERRIDE
|
|
{
|
|
[m_searchFieldCell setPlaceholderString:
|
|
wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
|
|
}
|
|
|
|
virtual bool SetFocus() wxOVERRIDE
|
|
{
|
|
return wxNSTextFieldControl::SetFocus();
|
|
}
|
|
|
|
void controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender)) wxOVERRIDE
|
|
{
|
|
wxSearchCtrl* wxpeer = (wxSearchCtrl*) GetWXPeer();
|
|
if ( wxpeer )
|
|
{
|
|
NSString *searchString = [m_searchField stringValue];
|
|
if ( searchString == nil || !searchString.length )
|
|
{
|
|
if ( ![m_searchField isWithinTextDidChange])
|
|
wxpeer->HandleSearchFieldCancelHit();
|
|
}
|
|
else
|
|
{
|
|
wxpeer->HandleSearchFieldSearchHit();
|
|
}
|
|
}
|
|
}
|
|
|
|
virtual void SetCentredLook( bool centre )
|
|
{
|
|
SEL sel = @selector(setCenteredLook:);
|
|
if ( [m_searchFieldCell respondsToSelector: sel] )
|
|
{
|
|
// all this avoids xcode parsing warnings when using
|
|
// [m_searchFieldCell setCenteredLook:NO];
|
|
NSMethodSignature* signature =
|
|
[NSSearchFieldCell instanceMethodSignatureForSelector:sel];
|
|
NSInvocation* invocation =
|
|
[NSInvocation invocationWithMethodSignature: signature];
|
|
[invocation setTarget: m_searchFieldCell];
|
|
[invocation setSelector:sel];
|
|
[invocation setArgument:¢re atIndex:2];
|
|
[invocation invoke];
|
|
}
|
|
}
|
|
|
|
private:
|
|
wxNSSearchField* m_searchField;
|
|
NSSearchFieldCell* m_searchFieldCell;
|
|
} ;
|
|
|
|
wxNSSearchFieldControl::~wxNSSearchFieldControl()
|
|
{
|
|
}
|
|
|
|
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))
|
|
{
|
|
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
|
|
wxNSSearchField* v = [[wxNSSearchField alloc] initWithFrame:r];
|
|
|
|
// Make it behave consistently with the single line wxTextCtrl
|
|
[[v cell] setScrollable:YES];
|
|
|
|
[[v cell] setSendsWholeSearchString:YES];
|
|
// per wx default cancel is not shown
|
|
[[v cell] setCancelButtonCell:nil];
|
|
|
|
wxNSSearchFieldControl* c = new wxNSSearchFieldControl( wxpeer, v );
|
|
c->SetNeedsFrame( false );
|
|
c->SetCentredLook( false );
|
|
c->SetStringValue( str );
|
|
return c;
|
|
}
|
|
|
|
#endif // wxUSE_NATIVE_SEARCH_CONTROL
|
|
|
|
#endif // wxUSE_SEARCHCTRL
|