From 554166194478a2b5e6bdf4e53dc3ee79614d5f98 Mon Sep 17 00:00:00 2001 From: Taka Date: Wed, 17 Jul 2019 06:16:43 +0000 Subject: [PATCH] Reworked how we handle keyboard input. --- src/MainForm.cs | 1 + src/MainForm.ui.cs | 135 +++++++++++++++++++++++++-------------------- 2 files changed, 75 insertions(+), 61 deletions(-) diff --git a/src/MainForm.cs b/src/MainForm.cs index c4d0a89..894f525 100644 --- a/src/MainForm.cs +++ b/src/MainForm.cs @@ -31,6 +31,7 @@ public partial class MainForm : Form private Tuple mScrollDragAnchor ; private double mCurrZoom, mMinZoom, mMaxZoom ; private DateTime mLastKeyPressTimeStamp = DateTime.Now ; + private bool mDisableProcessCmdKey = false ; public MainForm() { diff --git a/src/MainForm.ui.cs b/src/MainForm.ui.cs index 9842263..9a6c70b 100644 --- a/src/MainForm.ui.cs +++ b/src/MainForm.ui.cs @@ -88,9 +88,6 @@ public partial class MainForm : Form this.FormClosing += new FormClosingEventHandler( this.MainForm_FormClosing ) ; this.Resize += new EventHandler( this.MainForm_Resize ) ; this.mSearchQuery.TextChanged += new EventHandler( this.SearchQuery_TextChanged ) ; - this.mSearchQuery.KeyPress += new KeyPressEventHandler( this.SearchQuery_KeyPress ) ; - this.mSearchQuery.KeyDown += new KeyEventHandler( this.SearchQuery_KeyDown ) ; - this.mSearchResults.KeyPress += new KeyPressEventHandler( this.SearchResults_KeyPress ) ; this.mSearchResults.SelectionChanged += new EventHandler( this.SearchResults_SelectionChanged ) ; mChartImagePictureBox.MouseDown += new MouseEventHandler( this.ChartImagePictureBox_MouseDown ) ; @@ -121,6 +118,80 @@ public partial class MainForm : Form return false ; } + protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) + { + // prevent recursive calls + if ( mDisableProcessCmdKey ) + return false ; + + // initialize + Keys modifierKeys = Control.ModifierKeys & (Keys.Control | Keys.Shift | Keys.Alt) ; + Keys keyCode = keyData & ~(Keys.Control | Keys.Shift | Keys.Alt) ; + + // check for special keypresses + if ( keyCode == Keys.Left || keyCode == Keys.Right ) { + // send the keypress to the search results + mSearchResults.Focus() ; + mDisableProcessCmdKey = true ; + SendKeys.SendWait( "{" + keyCode.ToString() + "}" ) ; + mDisableProcessCmdKey = false ; + return true ; + } + if ( keyCode == Keys.Escape ) { + // clear the search query + mSearchQuery.Text = "" ; + loadSearchResults( mChartImages.Values, "SHOW-ALL" ) ; + return true ; + } + if ( keyCode == Keys.Return ) + return true ; // nb: stop Windows from beeping :-/ + + // check for ChartImage shortcuts + List chartImages = ChartImage.checkShortcut( modifierKeys, keyCode ) ; + if ( chartImages != null ) { + // yup - show them as search results + ILog logger = LogManager.GetLogger( "shortcuts" ) ; + logger.Info( $"Found ChartImage's for shortcut: {ChartImage.shortcutString(modifierKeys,keyCode)}" ) ; + foreach ( ChartImage chartImage in chartImages ) + logger.Info( $"- {chartImage.caption()}" ) ; + mSearchQuery.Text = "" ; + loadSearchResults( chartImages, "HOTKEY:"+modifierKeys+":"+keyCode ) ; + return true ; + } + + // check if we should update the search query + // FUDGE! This is incredibly annoying :-/ We get a *key code*, which is not the same as an ASCII character, + // so we only recognize a very limited set of characters here. Other characters will still be recognized + // and added to the search query *if* the textbox has focus (since the code here won't fire, we end up + // flagging the message as "not processed", and the textbox will receive the message normally), so it's + // only an issue when the user is typing a search query and something else has focus. We could perhaps + // translate things like Keys.OemXXX key codes here, but it's not worth the effort, since search queries + // will almost always consist of only letters and/or numbers. + int ch = (int) keyCode ; + string sendKey = "" ; + if ( (ch >= 65 && ch <= 90) || ch == 32 ) + sendKey = ((char)ch).ToString().ToLower() ; + else if ( ch >= 48 && ch <= 57 ) + sendKey = keyCode.ToString().Substring( 1 ) ; + else if ( keyCode == Keys.Back ) + sendKey = "{BKSP}" ; + if ( sendKey != "" ) { + // check if it's time to start a new search query + int ttl = Program.appConfig.getIntVal( new string[]{"SearchQueryTTL"}, 5 ) ; + if ( (DateTime.Now - mLastKeyPressTimeStamp).TotalSeconds > ttl ) + mSearchQuery.Text = "" ; + mLastKeyPressTimeStamp = DateTime.Now ; + // send the keypress to the search query textbox + mSearchQuery.Focus() ; + mDisableProcessCmdKey = true ; + SendKeys.SendWait( sendKey ) ; + mDisableProcessCmdKey = false ; + return true ; + } + + return false ; + } + private int ChartImagePanel_MaxScrollX() { return mChartImagePanel.HorizontalScroll.Maximum - mChartImagePanel.Width + 17 ; } private int ChartImagePanel_MaxScrollY() { return mChartImagePanel.VerticalScroll.Maximum - mChartImagePanel.Height + 17 ; } @@ -359,62 +430,4 @@ public partial class MainForm : Form updateSearchResults( mSearchQuery.Text.Trim() ) ; } - private void SearchQuery_KeyPress( object sender, KeyPressEventArgs e ) - { - // check how much time has passed since the last keypress - int ch = (int) e.KeyChar ; - if ( ch >= 32 && ch < 127 ) { - int ttl = Program.appConfig.getIntVal( new string[]{"SearchQueryTTL"}, 5 ) ; - if ( (DateTime.Now - mLastKeyPressTimeStamp).TotalSeconds > ttl ) { - // it's been a while - start a new search query - mSearchQuery.Text = "" ; - } - mLastKeyPressTimeStamp = DateTime.Now ; - } - } - - private void SearchQuery_KeyDown( object sender, KeyEventArgs e ) - { - // check if there are any ChartImage's associated with the keypress - List chartImages = ChartImage.checkShortcut( e.Modifiers, e.KeyCode ) ; - if ( chartImages != null ) { - // yup - show them as search results - ILog logger = LogManager.GetLogger( "shortcuts" ) ; - logger.Info( $"Found ChartImage's for shortcut: {ChartImage.shortcutString(e.Modifiers,e.KeyCode)}" ) ; - foreach ( ChartImage chartImage in chartImages ) - logger.Info( $"- {chartImage.caption()}" ) ; - mSearchQuery.Text = "" ; - loadSearchResults( chartImages, "HOTKEY:"+e.Modifiers+":"+e.KeyCode ) ; - e.Handled = true ; - return ; - } - - // check if we should apply the keypress to the search results - if ( e.KeyCode == Keys.Escape ) { - mSearchQuery.Text = "" ; - loadSearchResults( mChartImages.Values, "SHOW-ALL" ) ; - e.SuppressKeyPress = true ; - e.Handled = true ; - } else if ( e.KeyCode == Keys.Return ) { - e.SuppressKeyPress = true ; - e.Handled = true ; - } else if ( e.KeyCode == Keys.Left || e.KeyCode == Keys.Right ) { - mSearchResults.Focus() ; - SendKeys.SendWait( "{" + e.KeyCode.ToString() + "}" ) ; - mSearchQuery.Focus() ; - e.Handled = true ; - } - } - - private void SearchResults_KeyPress( object sender, KeyPressEventArgs e ) - { - // check if we should apply the keypress to the search query - int ch = (int) e.KeyChar ; - if ( ch == 27 ) - mSearchQuery.Text = "" ; - else if ( ch >= 32 && ch < 127 ) { - mSearchQuery.Focus() ; - SendKeys.Send( e.KeyChar.ToString() ) ; - } - } }