Implement EVT_CHAR generation for wxDataViewCtrl under Mac

This requires manually sending the original key event back to the native
control because NSOutlineView doesn't implement the NSTextInputClient
protocol and so doesn't allow handling the keys in the usual way.
This commit is contained in:
Stefan Csomor
2021-04-13 17:35:20 +02:00
committed by Vadim Zeitlin
parent 18c45321f4
commit 26d6f82a81
4 changed files with 61 additions and 13 deletions

View File

@@ -573,6 +573,9 @@ public:
virtual void SetFont(const wxFont& font);
virtual void keyEvent(WX_NSEvent event, WXWidget slf, void* _cmd) wxOVERRIDE;
virtual bool doCommandBySelector(void* sel, WXWidget slf, void* _cmd) wxOVERRIDE;
private:
void InitOutlineView(long style);
int GetDefaultRowHeight() const;

View File

@@ -285,6 +285,7 @@ protected:
// event handling
void OnSize(wxSizeEvent &event);
void OnMouse(wxMouseEvent &event);
void OnChar(wxKeyEvent &event);
private:
// initializing of local variables:

View File

@@ -1632,6 +1632,16 @@ outlineView:(NSOutlineView*)outlineView
// ============================================================================
@implementation wxCocoaOutlineView
+ (void)initialize
{
static BOOL initialized = NO;
if (!initialized)
{
initialized = YES;
wxOSXCocoaClassAddWXMethods( self );
}
}
//
// initializers / destructor
//
@@ -1723,20 +1733,15 @@ outlineView:(NSOutlineView*)outlineView
// Default enter key behaviour is to begin cell editing. Subclass keyDown to
// provide a keyboard wxEVT_DATAVIEW_ITEM_ACTIVATED event and allow the NSEvent
// to pass if the wxEvent is not processed.
- (void)keyDown:(NSEvent *)event
// catch events routed here and feed them back before things get routed up the responder chain
// otherwise we lose functionality like arrow keys etc.
- (void)doCommandBySelector:(SEL)aSelector
{
if( [[event charactersIgnoringModifiers]
characterAtIndex: 0] == NSCarriageReturnCharacter )
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
if (impl)
{
wxDataViewCtrl* const dvc = implementation->GetDataViewCtrl();
const wxDataViewItem item = wxDataViewItem( [[self itemAtRow:[self selectedRow]] pointer]);
wxDataViewEvent eventDV(wxEVT_DATAVIEW_ITEM_ACTIVATED, dvc, item);
if ( !dvc->GetEventHandler()->ProcessEvent(eventDV) )
[super keyDown:event];
}
else
{
[super keyDown:event]; // all other keys
impl->doCommandBySelector(aSelector, self, _cmd);
}
}
@@ -2082,7 +2087,8 @@ wxCocoaDataViewControl::wxCocoaDataViewControl(wxWindow* peer,
: wxWidgetCocoaImpl
(
peer,
[[NSScrollView alloc] initWithFrame:wxOSXGetFrameForControl(peer,pos,size)]
[[NSScrollView alloc] initWithFrame:wxOSXGetFrameForControl(peer,pos,size)],
wxWidgetImpl::Widget_UserKeyEvents
),
m_DataSource(NULL),
m_OutlineView([[wxCocoaOutlineView alloc] init]),
@@ -2130,6 +2136,37 @@ wxCocoaDataViewControl::~wxCocoaDataViewControl()
[m_OutlineView release];
}
void wxCocoaDataViewControl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
{
if( [event type] == NSKeyDown && [[event charactersIgnoringModifiers]
characterAtIndex: 0] == NSCarriageReturnCharacter )
{
wxDataViewCtrl* const dvc = GetDataViewCtrl();
const wxDataViewItem item = wxDataViewItem( [[m_OutlineView itemAtRow:[m_OutlineView selectedRow]] pointer]);
wxDataViewEvent eventDV(wxEVT_DATAVIEW_ITEM_ACTIVATED, dvc, item);
if ( !dvc->GetEventHandler()->ProcessEvent(eventDV) )
wxWidgetCocoaImpl::keyEvent(event, slf, _cmd);
}
else
{
wxWidgetCocoaImpl::keyEvent(event, slf, _cmd); // all other keys
}
}
bool wxCocoaDataViewControl::doCommandBySelector(void* sel, WXWidget slf, void* _cmd)
{
bool handled = wxWidgetCocoaImpl::doCommandBySelector(sel, slf, _cmd);
// if this special key has not been handled
if ( !handled && IsInNativeKeyDown() )
{
// send the original key event back to the native implementation to get proper default handling like eg for arrow keys
wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:@selector(keyDown:)];
superimpl(slf, @selector(keyDown:), GetLastNativeKeyDownEvent());
}
return handled;
}
//
// column related methods (inherited from wxDataViewWidgetImpl)
//

View File

@@ -770,11 +770,18 @@ void wxDataViewCtrl::OnMouse(wxMouseEvent& event)
event.Skip();
}
void wxDataViewCtrl::OnChar(wxKeyEvent& event)
{
// generic key handling can moved here
event.Skip();
}
wxIMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxDataViewCtrlBase);
wxBEGIN_EVENT_TABLE(wxDataViewCtrl,wxDataViewCtrlBase)
EVT_SIZE(wxDataViewCtrl::OnSize)
EVT_MOTION(wxDataViewCtrl::OnMouse)
EVT_CHAR(wxDataViewCtrl::OnChar)
wxEND_EVENT_TABLE()
#endif // !wxHAS_GENERIC_DATAVIEWCTRL