simplify native textcontrol creations, adding search control for cocoa
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -25,368 +25,165 @@
|
||||
|
||||
#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)
|
||||
@interface wxNSSearchField : NSSearchField
|
||||
{
|
||||
wxWidgetImpl* impl;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation wxNSSearchField
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
[super initWithFrame:frame];
|
||||
impl = NULL;
|
||||
[self setTarget: self];
|
||||
[self setAction: @selector(searchAction:)];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setImplementation: (wxWidgetImpl *) theImplementation
|
||||
{
|
||||
impl = theImplementation;
|
||||
}
|
||||
|
||||
- (wxWidgetImpl*) implementation
|
||||
{
|
||||
return impl;
|
||||
}
|
||||
|
||||
- (BOOL) isFlipped
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// use our common calls
|
||||
- (void) setTitle:(NSString *) title
|
||||
{
|
||||
[self setStringValue: title];
|
||||
}
|
||||
|
||||
- (void) searchAction: (id) sender
|
||||
{
|
||||
if ( impl )
|
||||
{
|
||||
wxSearchCtrl* wxpeer = dynamic_cast<wxSearchCtrl*>( impl->GetWXPeer() );
|
||||
if ( wxpeer )
|
||||
{
|
||||
NSString *searchString = [self stringValue];
|
||||
if ( searchString == nil )
|
||||
{
|
||||
wxpeer->HandleSearchFieldCancelHit();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxpeer->HandleSearchFieldSearchHit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// ============================================================================
|
||||
// wxMacSearchFieldControl
|
||||
// ============================================================================
|
||||
|
||||
static const EventTypeSpec eventList[] =
|
||||
{
|
||||
{ kEventClassSearchField, kEventSearchFieldCancelClicked } ,
|
||||
{ kEventClassSearchField, kEventSearchFieldSearchClicked } ,
|
||||
};
|
||||
|
||||
class wxMacSearchFieldControl : public wxMacUnicodeTextControl
|
||||
class wxNSSearchFieldControl : public wxNSTextFieldControl, public wxSearchWidgetImpl
|
||||
{
|
||||
public :
|
||||
wxMacSearchFieldControl( wxTextCtrl *wxPeer,
|
||||
const wxString& str,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size, long style ) : wxMacUnicodeTextControl( wxPeer )
|
||||
wxNSSearchFieldControl( wxTextCtrl *wxPeer, wxNSSearchField* w ) : wxNSTextFieldControl(wxPeer, w)
|
||||
{
|
||||
Create( wxPeer, str, pos, size, style );
|
||||
m_searchFieldCell = [w cell];
|
||||
m_searchField = w;
|
||||
}
|
||||
~wxNSSearchFieldControl();
|
||||
|
||||
// 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 void ShowSearchButton( bool show )
|
||||
{
|
||||
if ( show )
|
||||
[m_searchFieldCell resetSearchButtonCell];
|
||||
else
|
||||
[m_searchFieldCell setSearchButtonCell:nil];
|
||||
[m_searchField setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
virtual bool SetFocus();
|
||||
virtual bool IsSearchButtonVisible() const
|
||||
{
|
||||
return [m_searchFieldCell searchButtonCell] != nil;
|
||||
}
|
||||
|
||||
protected :
|
||||
virtual void CreateControl( wxTextCtrl* peer, const Rect* bounds, CFStringRef crf );
|
||||
virtual void ShowCancelButton( bool show )
|
||||
{
|
||||
if ( show )
|
||||
[m_searchFieldCell resetCancelButtonCell];
|
||||
else
|
||||
[m_searchFieldCell setCancelButtonCell:nil];
|
||||
[m_searchField setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
virtual bool IsCancelButtonVisible() const
|
||||
{
|
||||
return [m_searchFieldCell cancelButtonCell] != nil;
|
||||
}
|
||||
|
||||
virtual void SetSearchMenu( wxMenu* menu )
|
||||
{
|
||||
if ( menu )
|
||||
[m_searchFieldCell setSearchMenuTemplate:menu->GetHMenu()];
|
||||
else
|
||||
[m_searchFieldCell setSearchMenuTemplate:nil];
|
||||
[m_searchField setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
virtual void SetDescriptiveText(const wxString& text)
|
||||
{
|
||||
[m_searchFieldCell setPlaceholderString:
|
||||
wxCFStringRef( text , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
|
||||
}
|
||||
|
||||
virtual bool SetFocus()
|
||||
{
|
||||
return wxNSTextFieldControl::SetFocus();
|
||||
}
|
||||
|
||||
private:
|
||||
wxMenu* m_menu;
|
||||
wxNSSearchField* m_searchField;
|
||||
NSSearchFieldCell* m_searchFieldCell;
|
||||
} ;
|
||||
|
||||
void wxMacSearchFieldControl::CreateControl(wxTextCtrl* WXUNUSED(peer),
|
||||
const Rect* bounds,
|
||||
CFStringRef WXUNUSED(crf))
|
||||
wxNSSearchFieldControl::~wxNSSearchFieldControl()
|
||||
{
|
||||
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 )
|
||||
wxWidgetImplType* wxWidgetImpl::CreateSearchControl( wxTextCtrl* wxpeer,
|
||||
wxWindowMac* parent,
|
||||
wxWindowID id,
|
||||
const wxString& str,
|
||||
const wxPoint& pos,
|
||||
const wxSize& size,
|
||||
long style,
|
||||
long extraStyle)
|
||||
{
|
||||
OptionBits set = 0;
|
||||
OptionBits clear = 0;
|
||||
if ( show )
|
||||
{
|
||||
set |= kHISearchFieldAttributesSearchIcon;
|
||||
}
|
||||
else
|
||||
{
|
||||
clear |= kHISearchFieldAttributesSearchIcon;
|
||||
}
|
||||
HISearchFieldChangeAttributes( m_controlRef, set, clear );
|
||||
}
|
||||
NSView* sv = (wxpeer->GetParent()->GetHandle() );
|
||||
|
||||
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
|
||||
wxNSSearchField* v = [[wxNSSearchField alloc] initWithFrame:r];
|
||||
[sv addSubview:v];
|
||||
[[v cell] setSendsWholeSearchString:YES];
|
||||
// per wx default cancel is not shown
|
||||
[[v cell] setCancelButtonCell:nil];
|
||||
|
||||
bool wxMacSearchFieldControl::IsSearchButtonVisible() const
|
||||
{
|
||||
OptionBits attributes = 0;
|
||||
verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) );
|
||||
return ( attributes & kHISearchFieldAttributesSearchIcon ) != 0;
|
||||
}
|
||||
|
||||
void wxMacSearchFieldControl::ShowCancelButton( bool show )
|
||||
{
|
||||
OptionBits set = 0;
|
||||
OptionBits clear = 0;
|
||||
if ( show )
|
||||
{
|
||||
set |= kHISearchFieldAttributesCancel;
|
||||
}
|
||||
else
|
||||
{
|
||||
clear |= kHISearchFieldAttributesCancel;
|
||||
}
|
||||
HISearchFieldChangeAttributes( m_controlRef, set, clear );
|
||||
}
|
||||
|
||||
bool wxMacSearchFieldControl::IsCancelButtonVisible() const
|
||||
{
|
||||
OptionBits attributes = 0;
|
||||
verify_noerr( HISearchFieldGetAttributes( m_controlRef, &attributes ) );
|
||||
return ( attributes & kHISearchFieldAttributesCancel ) != 0;
|
||||
}
|
||||
|
||||
void wxMacSearchFieldControl::SetSearchMenu( wxMenu* menu )
|
||||
{
|
||||
m_menu = menu;
|
||||
if ( m_menu )
|
||||
{
|
||||
verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, MAC_WXHMENU(m_menu->GetHMenu()) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
verify_noerr( HISearchFieldSetSearchMenu( m_controlRef, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
wxMenu* wxMacSearchFieldControl::GetSearchMenu() const
|
||||
{
|
||||
return m_menu;
|
||||
}
|
||||
|
||||
|
||||
void wxMacSearchFieldControl::SetDescriptiveText(const wxString& text)
|
||||
{
|
||||
verify_noerr( HISearchFieldSetDescriptiveText(
|
||||
m_controlRef,
|
||||
wxCFStringRef( text, wxFont::GetDefaultEncoding() )));
|
||||
}
|
||||
|
||||
wxString wxMacSearchFieldControl::GetDescriptiveText() const
|
||||
{
|
||||
CFStringRef cfStr;
|
||||
verify_noerr( HISearchFieldCopyDescriptiveText( m_controlRef, &cfStr ));
|
||||
if ( cfStr )
|
||||
{
|
||||
return wxCFStringRef(cfStr).AsString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return wxEmptyString;
|
||||
}
|
||||
}
|
||||
|
||||
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 ) )
|
||||
{
|
||||
case kEventSearchFieldCancelClicked :
|
||||
thisWindow->MacSearchFieldCancelHit( handler , event ) ;
|
||||
break ;
|
||||
case kEventSearchFieldSearchClicked :
|
||||
thisWindow->MacSearchFieldSearchHit( handler , event ) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
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) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_menu )
|
||||
{
|
||||
m_menu->SetInvokingWindow( 0 );
|
||||
}
|
||||
|
||||
delete m_menu;
|
||||
m_menu = menu;
|
||||
|
||||
if ( m_menu )
|
||||
{
|
||||
m_menu->SetInvokingWindow( this );
|
||||
}
|
||||
|
||||
GetPeer()->SetSearchMenu( m_menu );
|
||||
}
|
||||
|
||||
wxMenu* wxSearchCtrl::GetMenu()
|
||||
{
|
||||
return m_menu;
|
||||
}
|
||||
|
||||
void wxSearchCtrl::ShowSearchButton( bool show )
|
||||
{
|
||||
if ( IsSearchButtonVisible() == show )
|
||||
{
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
GetPeer()->ShowSearchButton( show );
|
||||
}
|
||||
|
||||
bool wxSearchCtrl::IsSearchButtonVisible() const
|
||||
{
|
||||
return GetPeer()->IsSearchButtonVisible();
|
||||
}
|
||||
|
||||
|
||||
void wxSearchCtrl::ShowCancelButton( bool show )
|
||||
{
|
||||
if ( IsCancelButtonVisible() == show )
|
||||
{
|
||||
// no change
|
||||
return;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
wxInt32 wxSearchCtrl::MacSearchFieldSearchHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) )
|
||||
{
|
||||
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) )
|
||||
{
|
||||
wxCommandEvent event(wxEVT_COMMAND_SEARCHCTRL_CANCEL_BTN, m_windowId );
|
||||
event.SetEventObject(this);
|
||||
ProcessCommand(event);
|
||||
return eventNotHandledErr ;
|
||||
}
|
||||
|
||||
|
||||
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->SetStringValue( str );
|
||||
[v setImplementation:c];
|
||||
return c;
|
||||
}
|
||||
|
||||
#endif // wxUSE_NATIVE_SEARCH_CONTROL
|
||||
|
||||
Reference in New Issue
Block a user