From 42bf26730f871bb3887dbda64821413ad3b9f1a0 Mon Sep 17 00:00:00 2001 From: "Zane U. Ji" Date: Sun, 19 Jul 2020 17:48:51 +0200 Subject: [PATCH] Implement keyboard navigation in rich text editor symbols dialog Enable and fix keys processing in wxSymbolListCtrl::OnKeyDown(). Also set focus to this control initially as it's more useful and it's expected that cursor arrows can be used to move the selection in it rather than changing selection in the font comboboxes. Note that "Enter" key still doesn't work correctly, i.e. doesn't close the dialog when it's pressed in the symbols list control. Closes #16033. Co-authored-by: Igor Korot Co-authored-by: Vadim Zeitlin --- src/richtext/richtextsymboldlg.cpp | 97 +++++++++++++++++------------- 1 file changed, 55 insertions(+), 42 deletions(-) diff --git a/src/richtext/richtextsymboldlg.cpp b/src/richtext/richtextsymboldlg.cpp index d500929d31..236b8c838b 100644 --- a/src/richtext/richtextsymboldlg.cpp +++ b/src/richtext/richtextsymboldlg.cpp @@ -489,6 +489,8 @@ void wxSymbolPickerDialog::CreateControls() if (button) m_stdButtonSizer->Show(button, false); } + + m_symbolsCtrl->SetFocus(); } /// Data transfer @@ -1048,64 +1050,77 @@ void wxSymbolListCtrl::DoHandleItemClick(int item, int WXUNUSED(flags)) void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event) { - // No keyboard interface for now - event.Skip(); -#if 0 // flags for DoHandleItemClick() int flags = ItemClick_Kbd; + int current = m_current; + // m_current might not be wxNOT_FOUND if a Unicode symbol is selected + // before the mode is changed to ANSI + if( current < m_minSymbolValue || current > m_maxSymbolValue ) + current = m_minSymbolValue; - int currentLineNow = SymbolValueToLineNumber(m_current); + // Original first visible row + int firstVisibleRow = GetVisibleRowsBegin(); + // Current row + int currentRow = SymbolValueToLineNumber( current ); + // Number of visible rows + int visibleRows = GetClientSize().y / OnGetRowHeight( 0 ); + + // Which row to scroll to + int scrollToRow = firstVisibleRow; + // Check if the current symbol is visible + if( currentRow < firstVisibleRow ) + scrollToRow = firstVisibleRow = currentRow; + else if( currentRow >= firstVisibleRow + visibleRows ) + scrollToRow = firstVisibleRow = currentRow - visibleRows + 1; - int currentLine; switch ( event.GetKeyCode() ) { case WXK_HOME: - currentLine = 0; + current = m_minSymbolValue; + scrollToRow = 0; break; case WXK_END: - currentLine = GetLineCount() - 1; + current = m_maxSymbolValue; + scrollToRow = GetRowCount(); break; case WXK_DOWN: - if ( currentLineNow == (int)GetLineCount() - 1 ) - return; - - currentLine = currentLineNow + 1; + current += m_symbolsPerLine; + if( currentRow >= firstVisibleRow + visibleRows - 1 ) + scrollToRow++; break; case WXK_UP: - if ( m_current == wxNOT_FOUND ) - currentLine = GetLineCount() - 1; - else if ( currentLineNow != 0 ) - currentLine = currentLineNow - 1; - else // currentLineNow == 0 - return; + current -= m_symbolsPerLine; + if( currentRow == firstVisibleRow ) + scrollToRow--; + break; + + case WXK_LEFT: + current--; + // Scroll up at leftmost position + if( current < scrollToRow * m_symbolsPerLine ) + scrollToRow--; + break; + + case WXK_RIGHT: + current++; + // Scroll down at rightmost position + if( current >= ( scrollToRow + visibleRows ) * m_symbolsPerLine ) + scrollToRow++; break; case WXK_PAGEDOWN: - PageDown(); - currentLine = GetFirstVisibleLine(); + current += visibleRows * m_symbolsPerLine; + scrollToRow += visibleRows; break; case WXK_PAGEUP: - if ( currentLineNow == (int)GetFirstVisibleLine() ) - { - PageUp(); - } - - currentLine = GetFirstVisibleLine(); + current -= visibleRows * m_symbolsPerLine; + scrollToRow -= visibleRows; break; - case WXK_SPACE: - // hack: pressing space should work like a mouse click rather than - // like a keyboard arrow press, so trick DoHandleItemClick() in - // thinking we were clicked - flags &= ~ItemClick_Kbd; - currentLine = currentLineNow; - break; - -#ifdef __WXMSW__ case WXK_TAB: // Since we are using wxWANTS_CHARS we need to send navigation // events for the tabs on MSW @@ -1116,24 +1131,22 @@ void wxSymbolListCtrl::OnKeyDown(wxKeyEvent& event) ne.SetEventObject(this); GetParent()->GetEventHandler()->ProcessEvent(ne); } - // fall through to default -#endif + wxFALLTHROUGH; + default: event.Skip(); - currentLine = 0; // just to silent the stupid compiler warnings - wxUnusedVar(currentNow); return; } -#if 0 + if( current < m_minSymbolValue || current > m_maxSymbolValue ) + return; if ( event.ShiftDown() ) flags |= ItemClick_Shift; if ( event.ControlDown() ) flags |= ItemClick_Ctrl; DoHandleItemClick(current, flags); -#endif -#endif + ScrollToRow( scrollToRow ); } // ---------------------------------------------------------------------------- @@ -1233,7 +1246,7 @@ int wxSymbolListCtrl::HitTest(const wxPoint& pt) if (symbol >= m_minSymbolValue && symbol <= m_maxSymbolValue) return symbol; - return -1; + return wxNOT_FOUND; } // Respond to size change