Monday, January 24, 2011

wxGrid, TAB and the trapped focus

An accounting program is likely to be used for intensive data entry, so it is important to make typing easy for the end user.
Experienced users like to be able to work as much as possible without using the mouse: the mouse is useful for less experienced users but it slows down data entry.

An example is a dialog that contains a wxGrid and other controls: the user can move among controls using the TAB key (SHIFT-TAB to move backwards), but as soon as the focus goes to the wxGrid control is is trapped. It is possible to move from column to column using TAB but is is not possible to leave the grid any more: the user has to use the mouse to click another control.

This problem can be solved in a rather simple way, handling the wxEVT_KEY_DOWN event. Here is an example:

void fsGridBase::OnKeyDown( wxKeyEvent& event )
{
    bool keyHandled = false;

    if( event.GetKeyCode() == WXK_TAB ) {
        if( event.ShiftDown() ) {
            // shift-TAB: if we are in the first column move to the previous control
            if( GetGridCursorCol() == 0 ) {
                Navigate( wxNavigationKeyEvent::IsBackward );
                keyHandled = true;
            }
        }
        else {
            // TAB: if we are in the last column move to the next control
            if( GetGridCursorCol() == GetNumberCols() - 1 ) {
                Navigate( wxNavigationKeyEvent::IsForward );
                keyHandled = true;
            }
        }
    }

    if( !keyHandled )
        event.Skip();
}


Using this code the TAB key moves from column to column, but when the cursor goes to the first or last column pressing TAB moves the focus to the previous or last control.
This code works with wxWidgets 2.9: I don't know if it works for 2.8 too.

No comments:

Post a Comment