Merge branch 'mac-native-focus-ring' of https://github.com/vslavik/wxWidgets

Draw wxTextCtrl focus ring natively on Mac.

Add wxWindow::EnableVisibleFocus() to explicitly control the focus ring
visibility if necessary.

See https://github.com/wxWidgets/wxWidgets/pull/2037
This commit is contained in:
Vadim Zeitlin
2020-09-01 14:59:42 +02:00
10 changed files with 33 additions and 38 deletions

View File

@@ -111,6 +111,8 @@ public :
virtual void SetNeedsDisplay( const wxRect* where = NULL ) wxOVERRIDE; virtual void SetNeedsDisplay( const wxRect* where = NULL ) wxOVERRIDE;
virtual bool GetNeedsDisplay() const wxOVERRIDE; virtual bool GetNeedsDisplay() const wxOVERRIDE;
virtual void EnableFocusRing(bool enabled) wxOVERRIDE;
virtual void SetDrawingEnabled(bool enabled) wxOVERRIDE; virtual void SetDrawingEnabled(bool enabled) wxOVERRIDE;
virtual bool CanFocus() const wxOVERRIDE; virtual bool CanFocus() const wxOVERRIDE;

View File

@@ -301,8 +301,7 @@ public :
virtual void SetNeedsDisplay( const wxRect* where = NULL ) = 0; virtual void SetNeedsDisplay( const wxRect* where = NULL ) = 0;
virtual bool GetNeedsDisplay() const = 0; virtual bool GetNeedsDisplay() const = 0;
virtual bool NeedsFocusRect() const; virtual void EnableFocusRing(bool WXUNUSED(enabled)) {}
virtual void SetNeedsFocusRect( bool needs );
virtual bool NeedsFrame() const; virtual bool NeedsFrame() const;
virtual void SetNeedsFrame( bool needs ); virtual void SetNeedsFrame( bool needs );
@@ -598,7 +597,6 @@ protected :
bool m_wantsUserKey; bool m_wantsUserKey;
bool m_wantsUserMouse; bool m_wantsUserMouse;
wxWindowMac* m_wxPeer; wxWindowMac* m_wxPeer;
bool m_needsFocusRect;
bool m_needsFrame; bool m_needsFrame;
bool m_shouldSendEvents; bool m_shouldSendEvents;

View File

@@ -157,6 +157,7 @@ public:
void MacOnScroll( wxScrollEvent&event ); void MacOnScroll( wxScrollEvent&event );
virtual bool AcceptsFocus() const wxOVERRIDE; virtual bool AcceptsFocus() const wxOVERRIDE;
virtual void EnableVisibleFocus(bool enabled) wxOVERRIDE;
virtual bool IsDoubleBuffered() const wxOVERRIDE { return true; } virtual bool IsDoubleBuffered() const wxOVERRIDE { return true; }

View File

@@ -767,6 +767,9 @@ public:
// call this when the return value of AcceptsFocus() changes // call this when the return value of AcceptsFocus() changes
virtual void SetCanFocus(bool WXUNUSED(canFocus)) { } virtual void SetCanFocus(bool WXUNUSED(canFocus)) { }
// call to customize visible focus indicator if possible in the port
virtual void EnableVisibleFocus(bool WXUNUSED(enabled)) { }
// navigates inside this window // navigates inside this window
bool NavigateIn(int flags = wxNavigationKeyEvent::IsForward) bool NavigateIn(int flags = wxNavigationKeyEvent::IsForward)
{ return DoNavigateIn(flags); } { return DoNavigateIn(flags); }

View File

@@ -540,6 +540,22 @@ public:
*/ */
virtual void SetCanFocus(bool canFocus); virtual void SetCanFocus(bool canFocus);
/**
Enables or disables visible indication of keyboard focus.
By default, controls behave in platform-appropriate way and show focus
in the same way native applications do. In some very rare circumstances
it may be desirable to change the default (notably multiline text
controls don't normally have a focus indicator on Mac), which this
method allows. It should only be used if you have a good understanding
of the native platform's guidelines and user expectations.
This method is only implemented on Mac.
@since 3.1.5
*/
virtual void EnableVisibleFocus(bool enable);
/** /**
This sets the window to receive keyboard input. This sets the window to receive keyboard input.

View File

@@ -460,10 +460,6 @@ void wxGridCellTextEditor::DoCreate(wxWindow* parent,
text->SetMargins(0, 0); text->SetMargins(0, 0);
m_control = text; m_control = text;
#ifdef __WXOSX__
wxWidgetImpl* impl = m_control->GetPeer();
impl->SetNeedsFocusRect(false);
#endif
// set max length allowed in the textctrl, if the parameter was set // set max length allowed in the textctrl, if the parameter was set
if ( m_maxChars != 0 ) if ( m_maxChars != 0 )
{ {

View File

@@ -1590,7 +1590,6 @@ wxWidgetImplType* wxWidgetImpl::CreateTextControl( wxTextCtrl* wxpeer,
v = [[wxNSTextScrollView alloc] initWithFrame:r]; v = [[wxNSTextScrollView alloc] initWithFrame:r];
wxNSTextViewControl* t = new wxNSTextViewControl( wxpeer, v, style ); wxNSTextViewControl* t = new wxNSTextViewControl( wxpeer, v, style );
c = t; c = t;
c->SetNeedsFocusRect( true );
t->SetStringValue(str); t->SetStringValue(str);
} }

View File

@@ -3849,10 +3849,6 @@ void wxWidgetCocoaImpl::DoNotifyFocusLost()
void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow) void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
{ {
wxWindow* thisWindow = GetWXPeer(); wxWindow* thisWindow = GetWXPeer();
if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
{
thisWindow->MacInvalidateBorders();
}
if ( receivedFocus ) if ( receivedFocus )
{ {
@@ -3925,6 +3921,11 @@ void wxWidgetCocoaImpl::SetFlipped(bool flipped)
#endif #endif
void wxWidgetCocoaImpl::EnableFocusRing(bool enabled)
{
[m_osxView setFocusRingType:enabled ? NSFocusRingTypeExterior : NSFocusRingTypeNone];
}
void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled) void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled)
{ {
if ( [m_osxView window] == nil ) if ( [m_osxView window] == nil )

View File

@@ -642,10 +642,6 @@ void wxWidgetIPhoneImpl::InstallEventHandler( WXWidget control )
void wxWidgetIPhoneImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow) void wxWidgetIPhoneImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
{ {
wxWindow* thisWindow = GetWXPeer(); wxWindow* thisWindow = GetWXPeer();
if ( thisWindow->MacGetTopLevelWindow() && NeedsFocusRect() )
{
thisWindow->MacInvalidateBorders();
}
if ( receivedFocus ) if ( receivedFocus )
{ {

View File

@@ -938,9 +938,6 @@ void wxWindowMac::MacInvalidateBorders()
int outerBorder = MacGetLeftBorderSize() ; int outerBorder = MacGetLeftBorderSize() ;
if ( GetPeer()->NeedsFocusRect() )
outerBorder += 4 ;
if ( outerBorder == 0 ) if ( outerBorder == 0 )
return ; return ;
@@ -1578,8 +1575,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
#if wxOSX_USE_COCOA_OR_CARBON #if wxOSX_USE_COCOA_OR_CARBON
{ {
const bool hasFocus = GetPeer()->NeedsFocusRect() && HasFocus();
CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 , CGRect cgrect = CGRectMake( tx-1 , ty-1 , tw+2 ,
th+2 ) ; th+2 ) ;
@@ -1594,7 +1589,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
info.version = 0 ; info.version = 0 ;
info.kind = 0 ; info.kind = 0 ;
info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ;
info.isFocused = hasFocus ;
if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
{ {
@@ -1607,11 +1601,6 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right
HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ;
} }
} }
if ( hasFocus )
{
HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ;
}
} }
#endif // wxOSX_USE_COCOA_OR_CARBON #endif // wxOSX_USE_COCOA_OR_CARBON
} }
@@ -2182,6 +2171,11 @@ bool wxWindowMac::AcceptsFocus() const
return GetPeer()->CanFocus(); return GetPeer()->CanFocus();
} }
void wxWindowMac::EnableVisibleFocus(bool enabled)
{
GetPeer()->EnableFocusRing(enabled);
}
void wxWindowMac::MacSuperChangedPosition() void wxWindowMac::MacSuperChangedPosition()
{ {
// only window-absolute structures have to be moved i.e. controls // only window-absolute structures have to be moved i.e. controls
@@ -2746,20 +2740,9 @@ void wxWidgetImpl::Init()
m_wantsUserKey = false; m_wantsUserKey = false;
m_wantsUserMouse = false; m_wantsUserMouse = false;
m_wxPeer = NULL; m_wxPeer = NULL;
m_needsFocusRect = false;
m_needsFrame = true; m_needsFrame = true;
} }
void wxWidgetImpl::SetNeedsFocusRect( bool needs )
{
m_needsFocusRect = needs;
}
bool wxWidgetImpl::NeedsFocusRect() const
{
return m_needsFocusRect;
}
void wxWidgetImpl::SetNeedsFrame( bool needs ) void wxWidgetImpl::SetNeedsFrame( bool needs )
{ {
m_needsFrame = needs; m_needsFrame = needs;