Support keyboard navigation with Tab in generic wxDataViewCtrl.

Move keyboard focus between columns with Tab and Shift-Tab. Works
similarly to left and right arrows, but wraps around to go to the next
or previous line and doesn't collapse tree nodes.

If focus reaches the last or first cell, the key event is skipped,
allowing normal Tab handling for moving to another control.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75386 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík 2013-12-16 16:36:05 +00:00
parent 132a0aaacd
commit 15fe4acb3e

View File

@ -702,9 +702,9 @@ public:
void OnPaint( wxPaintEvent &event );
void OnCharHook( wxKeyEvent &event );
void OnChar( wxKeyEvent &event );
void OnVerticalNavigation(int delta, const wxKeyEvent& event);
void OnLeftKey();
void OnRightKey();
void OnVerticalNavigation(const wxKeyEvent& event, int delta);
void OnLeftKey(wxKeyEvent& event);
void OnRightKey(wxKeyEvent& event);
void OnMouse( wxMouseEvent &event );
void OnSetFocus( wxFocusEvent &event );
void OnKillFocus( wxFocusEvent &event );
@ -721,7 +721,7 @@ public:
unsigned GetCurrentRow() const { return m_currentRow; }
bool HasCurrentRow() { return m_currentRow != (unsigned int)-1; }
void ChangeCurrentRow( unsigned int row );
bool TryAdvanceCurrentColumn(wxDataViewTreeNode *node, bool forward);
bool TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxKeyEvent& event, bool forward);
wxDataViewColumn *GetCurrentColumn() const { return m_currentCol; }
void ClearCurrentColumn() { m_currentCol = NULL; }
@ -3673,10 +3673,22 @@ void wxDataViewMainWindow::OnCharHook(wxKeyEvent& event)
return;
case WXK_RETURN:
case WXK_TAB:
m_editorRenderer->FinishEditing();
return;
}
}
else if ( m_useCellFocus )
{
if ( event.GetKeyCode() == WXK_TAB )
{
if ( event.ShiftDown() )
OnLeftKey(event);
else
OnRightKey(event);
return;
}
}
event.Skip();
}
@ -3801,35 +3813,35 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
break;
case WXK_UP:
OnVerticalNavigation( -1, event );
OnVerticalNavigation(event, -1);
break;
case WXK_DOWN:
OnVerticalNavigation( +1, event );
OnVerticalNavigation(event, +1);
break;
// Add the process for tree expanding/collapsing
case WXK_LEFT:
OnLeftKey();
OnLeftKey(event);
break;
case WXK_RIGHT:
OnRightKey();
OnRightKey(event);
break;
case WXK_END:
OnVerticalNavigation( +(int)GetRowCount(), event );
OnVerticalNavigation(event, +(int)GetRowCount());
break;
case WXK_HOME:
OnVerticalNavigation( -(int)GetRowCount(), event );
OnVerticalNavigation(event, -(int)GetRowCount());
break;
case WXK_PAGEUP:
OnVerticalNavigation( -(pageSize - 1), event );
OnVerticalNavigation(event, -(pageSize - 1));
break;
case WXK_PAGEDOWN:
OnVerticalNavigation( +(pageSize - 1), event );
OnVerticalNavigation(event, +(pageSize - 1));
break;
default:
@ -3837,7 +3849,7 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
}
}
void wxDataViewMainWindow::OnVerticalNavigation(int delta, const wxKeyEvent& event)
void wxDataViewMainWindow::OnVerticalNavigation(const wxKeyEvent& event, int delta)
{
// if there is no selection, we cannot move it anywhere
if (!HasCurrentRow() || IsEmpty())
@ -3897,11 +3909,11 @@ void wxDataViewMainWindow::OnVerticalNavigation(int delta, const wxKeyEvent& eve
GetOwner()->EnsureVisible( m_currentRow, -1 );
}
void wxDataViewMainWindow::OnLeftKey()
void wxDataViewMainWindow::OnLeftKey(wxKeyEvent& event)
{
if ( IsList() )
{
TryAdvanceCurrentColumn(NULL, /*forward=*/false);
TryAdvanceCurrentColumn(NULL, event, /*forward=*/false);
}
else
{
@ -3909,9 +3921,18 @@ void wxDataViewMainWindow::OnLeftKey()
if ( !node )
return;
if ( TryAdvanceCurrentColumn(node, /*forward=*/false) )
if ( TryAdvanceCurrentColumn(node, event, /*forward=*/false) )
return;
const bool dontCollapseNodes = event.GetKeyCode() == WXK_TAB;
if ( dontCollapseNodes )
{
m_currentCol = NULL;
// allow focus change
event.Skip();
return;
}
// Because TryAdvanceCurrentColumn() return false, we are at the first
// column or using whole-row selection. In this situation, we can use
// the standard TreeView handling of the left key.
@ -3941,11 +3962,11 @@ void wxDataViewMainWindow::OnLeftKey()
}
}
void wxDataViewMainWindow::OnRightKey()
void wxDataViewMainWindow::OnRightKey(wxKeyEvent& event)
{
if ( IsList() )
{
TryAdvanceCurrentColumn(NULL, /*forward=*/true);
TryAdvanceCurrentColumn(NULL, event, /*forward=*/true);
}
else
{
@ -3972,12 +3993,12 @@ void wxDataViewMainWindow::OnRightKey()
}
else
{
TryAdvanceCurrentColumn(node, /*forward=*/true);
TryAdvanceCurrentColumn(node, event, /*forward=*/true);
}
}
}
bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, bool forward)
bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, wxKeyEvent& event, bool forward)
{
if ( GetOwner()->GetColumnCount() == 0 )
return false;
@ -3985,6 +4006,8 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, boo
if ( !m_useCellFocus )
return false;
const bool wrapAround = event.GetKeyCode() == WXK_TAB;
if ( node )
{
// navigation shouldn't work in branch nodes without other columns:
@ -4002,13 +4025,48 @@ bool wxDataViewMainWindow::TryAdvanceCurrentColumn(wxDataViewTreeNode *node, boo
return true;
}
else
return false;
{
if ( !wrapAround )
return false;
}
}
int idx = GetOwner()->GetColumnIndex(m_currentCol) + (forward ? +1 : -1);
if ( idx >= (int)GetOwner()->GetColumnCount() )
return false;
{
if ( !wrapAround )
return false;
if ( GetCurrentRow() < GetRowCount() - 1 )
{
// go to the first column of the next row:
idx = 0;
OnVerticalNavigation(wxKeyEvent()/*dummy*/, +1);
}
else
{
// allow focus change
event.Skip();
return false;
}
}
if ( idx < 0 && wrapAround )
{
if ( GetCurrentRow() > 0 )
{
// go to the last column of the previous row:
idx = (int)GetOwner()->GetColumnCount() - 1;
OnVerticalNavigation(wxKeyEvent()/*dummy*/, -1);
}
else
{
// allow focus change
event.Skip();
return false;
}
}
GetOwner()->EnsureVisible(m_currentRow, idx);