private void Edit_Keys_Load( object sender, EventArgs e ) { WavesToolbar = ( Token_Toolbar )this.Owner; // Make sure nothing gets edited when the DataViewGrid gets populated lockKeys = true; // Create a second copy of our list of KeyCommand. Since when the DataListGrid is edited, it also actually // edits the "DataSource" (which will be KeyCommand), we need this second copy in case the user makes a // mistake in selecting a shortcut key for a menu. If this validation fails, the backup will be a fallback. for ( int i = 0; i < Token_Toolbar.KeyCommand.Count(); i++ ) { keyCommandsBackup[ i ] = new KeyCombo(); keyCommandsBackup[ i ]._alt = Token_Toolbar.KeyCommand[ i ]._alt; keyCommandsBackup[ i ]._ctrl = Token_Toolbar.KeyCommand[ i ]._ctrl; keyCommandsBackup[ i ]._mainKey = Token_Toolbar.KeyCommand[ i ]._mainKey; } // Initialize the DataGridView control. DATAGRID_Keys.DataSource = Token_Toolbar.KeyCommand; DATAGRID_Keys.RowHeadersWidth = 225; SetHeaders(); DATAGRID_Keys.AutoResizeColumns(); DATAGRID_Keys.Columns[ 2 ].Width = 75; // This makes the 4th column invisible DATAGRID_Keys.Columns[ 3 ].Visible = false; // Set the form's color scheme appropriately SetFormColors(); // Set whether this window will be on top of all other windows this.TopMost = WavesToolbar.MENU_View_AlwaysOnTop.Checked; // Everything is alright to go! lockKeys = false; }
/// <summary> /// This function tests the currently edited shortcut key to make sure it is a valid shortcut combination /// </summary> /// <param name="dgv">A handle to the Key Combination DataGridView</param> private void TestShortcutKey( DataGridView dgv ) { // First, get the keycode for the currently edited row int row = dgv.CurrentCellAddress.Y; KeyCombo com = new KeyCombo( ( bool )dgv[ 0, row ].EditedFormattedValue, ( bool )dgv[ 1, row ].EditedFormattedValue, ( string )dgv[ 2, row ].EditedFormattedValue ); // If this combo is the same as the backup version... it never changed if ( ( com._mainKey == keyCommandsBackup[ row ]._mainKey ) && ( com._alt == keyCommandsBackup[ row ]._alt ) && ( com._ctrl == keyCommandsBackup[ row ]._ctrl ) ) return; // The function "IsValidShortcut" does the heavy lifting for this operation if ( com.IsValidShortcut() ) { // These assignments are automatic and are not explicitly needed! // KeyCommand[row].Ctrl = (bool)dgv[0, row].Value; // KeyCommand[row].Alt = (bool)dgv[1, row].Value; // KeyCommand[row].mainKey = (string)dgv[2, row].Value; anyChangesMade = true; } else { // The user entered invalid data. Restore the originally backed up combo (although this might be Keys.None)! dgv[ 0, row ].Value = keyCommandsBackup[ row ]._ctrl; dgv[ 1, row ].Value = keyCommandsBackup[ row ]._alt; dgv[ 2, row ].Value = keyCommandsBackup[ row ]._mainKey; } }
// ******************************************************************************************************************* // The following functions provide the user with speech prompting when a control is entered. // Most controls may be entered by [TAB] or by arrow key, or by entering it's location via mouse. // ******************************************************************************************************************* /// <summary> /// Bind to both "Enter" and "MouseEnter" events for dynamic token/element buttons to allow voice prompting. /// </summary> /// <param name="sender">The object (castable to "Button") that raised the event</param> /// <param name="e">Event data pertinent to Enter and MouseEnter events</param> private void Button_Dynamic_Enter( object sender, EventArgs e ) { // This event is bound to both "Enter" and "MouseEnter" events. // Its purpose is to provide a speech prompt and visible prompt for what the dynamic button represents Button button = sender as Button; string saySpeech = ""; // This will be the speech to be spoken string showSymbol = ""; //string typeSymbol = "token"; KeyCombo showShortcut = new KeyCombo( true, false, "" ); if( button != null ) { // Check master token list for this button's speech text // First, check <mo> tags foreach( Token tok in MasterToken._mo ) { if( tok != null ) if( tok._symbol == ( string )button.Text ) { saySpeech = tok._speech; showSymbol = tok._symbol; showShortcut.GetWavesTokenShortcut( this, button, false ); } } // Then, check <mi> tags if not yet found if( saySpeech == "" ) { foreach( Token tok in MasterToken._mi ) { if( tok != null ) if( tok._symbol == ( string )button.Text ) { saySpeech = tok._speech; showSymbol = tok._symbol; showShortcut.GetWavesTokenShortcut( this, button, false ); } } } // Then, check element tags if not yet found if( saySpeech == "" ) { foreach( Token tok in MasterToken._mathMLelement ) { if( tok._symbol == ( string )button.Name ) { saySpeech = tok._speech; showSymbol = tok._symbol; //typeSymbol = "element"; showShortcut.GetWavesTokenShortcut( this, button, true ); } } } // And so, we should now have speech to say... flush the Speaker buffer and initialize the current sound byte if( MENU_Options_VoicePrompting.Checked ) { Speaker.SpeakAsyncCancelAll(); Speaker.SpeakAsync( saySpeech ); } string tooltipMessage = "Add \"" + showSymbol + "\" to formula (" + showShortcut.GetKeyCombo() + ")"; TOOLTIP_Display.SetToolTip( button, tooltipMessage ); } // Log the control on the form that has been entered //for( int i = 0; i < Controls.Count; i++ ) { // if( Controls[ i ] == button ) // DynamicSelected = i; //} }
private void Token_Toolbar_KeyUp( object sender, KeyEventArgs e ) { // This event determines what to do when a key has been released. Because of the argument difference between // the KeyPress event and this KeyUp event, the KeyUp event is actually the more versatile of the two events. // This function used to deal with key-combos and keycodes that are important to the overall working of the // toolbar. // It is now a shadow of what it once was. It only drives the selection of excerpts, via up/down arrow presses. // The Down key selects the next excerpt in the List if( e.KeyData == Keys.Down ) { if( LISTBOX_ShowExcerpts.SelectedIndex < ( LISTBOX_ShowExcerpts.Items.Count - 1 ) ) LISTBOX_ShowExcerpts.SelectedIndex += 1; } // The Up Arrow key selects the last excerpt in the List, and activates the List if( e.KeyData == Keys.Up ) { if( LISTBOX_ShowExcerpts.SelectedIndex > 0 ) LISTBOX_ShowExcerpts.SelectedIndex -= 1; } // Test the particular keyboard shortcut that fired this event, and // test the keyboard state against the shortcuts that fire dynamic button clicks KeyCombo keysPressed = new KeyCombo( e.Control, e.Alt, GetLeastSignificantBits( ( int )e.KeyData ).ToString() ); Button button = GetButtonFromShortcut( keysPressed ); if( button != null ) { if( !TEXTBOX_MathExpression.Focused ) TEXTBOX_MathExpression.SelectionStart = TEXTBOX_MathExpression.Text.Length; button.PerformClick(); } //showShortcut.GetWavesTokenShortcut( this, button, false ); }
/// <summary> /// Assigns a keystoke combination to an existing ToolStripMenuItem, if possible. /// </summary> /// <param name="key">Keystroke combination to assign</param> /// <param name="menu">Menu item to which to assign the keystroke combination</param> public void AssignKeyToMenu( KeyCombo key, ToolStripMenuItem menu ) { Keys newCombo = new Keys(); KeysConverter kc = new KeysConverter(); //menu.ShortcutKeys = Keys.None; try { // This command can throw an exception if mainKey is not set. // This, however, is fine; it just means there is no keyboard shortcut for this item. newCombo = ( Keys )kc.ConvertFromString( key._mainKey ); if( key._ctrl ) newCombo = newCombo | Keys.Control; if( key._alt ) newCombo = newCombo | Keys.Alt; menu.ShortcutKeys = ( Keys )newCombo; } catch //(Exception ex) { menu.ShortcutKeys = Keys.None; //MessageBox.Show(ex.ToString()); } }
/// <summary> /// Loads all Keystroke combinations for various editor commands from an external XML file. /// </summary> /// <param name="filename">The XML document to parse</param> /// <returns>0 if successful, -1 if failed</returns> private int ParseKeyMappingDOM( string filename ) { // First of all, we test to see if the XML file we are going to be parsing exists... if( System.IO.File.Exists( filename ) ) { // Load the XML document XmlDocument keyXML = new XmlDocument(); keyXML.Load( filename ); int id = 0; // Parse the document, looking for only direct children of the "/all" node. // Note: This will work so long as the direct children aren't called "control", "alt", or "key"! //foreach (XmlNode node in keyXML.SelectNodes("/all/*")) foreach( XmlNode node in keyXML.DocumentElement.ChildNodes ) { // if (node.Name.ToLower() != "control" && node.Name.ToLower() != "alt" && node.Name.ToLower() != "key") // { // This is a shortcut key. Add it into our data structure. // id is used, and then increment after the execution of the next statement KeyCommand[ id++ ] = new KeyCombo( node.Name, node.ChildNodes[ 0 ].InnerText, node.ChildNodes[ 1 ].InnerText, node.ChildNodes[ 2 ].InnerText ); //id++; // } } // Assign the shortcut keys to the menus AssignKeyToMenu( KeyCommand[ 0 ], MENU_Formula_New ); AssignKeyToMenu( KeyCommand[ 1 ], MENU_Formula_ImportMathML ); AssignKeyToMenu( KeyCommand[ 2 ], MENU_Formula_Undo ); AssignKeyToMenu( KeyCommand[ 3 ], MENU_Formula_ClearExcerpt ); AssignKeyToMenu( KeyCommand[ 4 ], MENU_Formula_Read ); AssignKeyToMenu( KeyCommand[ 5 ], MENU_Formula_CopyClipboard ); AssignKeyToMenu( KeyCommand[ 6 ], MENU_Formula_ExportMathML ); AssignKeyToMenu( KeyCommand[ 7 ], MENU_Formula_ExportGraphic ); AssignKeyToMenu( KeyCommand[ 8 ], MENU_Formula_Close ); AssignKeyToMenu( KeyCommand[ 9 ], MENU_View_AlwaysOnTop ); AssignKeyToMenu( KeyCommand[ 10 ], MENU_View_HideMenu ); AssignKeyToMenu( KeyCommand[ 11 ], MENU_View_MathJax ); AssignKeyToMenu( KeyCommand[ 12 ], MENU_View_Level2 ); AssignKeyToMenu( KeyCommand[ 13 ], MENU_View_Repository ); AssignKeyToMenu( KeyCommand[ 14 ], MENU_View_Autotune ); AssignKeyToMenu( KeyCommand[ 15 ], MENU_Options_EnglishExcerpts ); AssignKeyToMenu( KeyCommand[ 16 ], MENU_Options_HighContrast ); AssignKeyToMenu( KeyCommand[ 17 ], MENU_Options_ReadAsPower ); AssignKeyToMenu( KeyCommand[ 18 ], MENU_Options_VoicePrompting ); AssignKeyToMenu( KeyCommand[ 19 ], MENU_Options_EditKeyboard ); AssignKeyToMenu( KeyCommand[ 20 ], MENU_Options_EditMasterTokenList ); AssignKeyToMenu( KeyCommand[ 21 ], MENU_Help_Index ); AssignKeyToMenu( KeyCommand[ 22 ], MENU_Help_About ); // AssignKeyToMenu(KeyCommand[20], MENU_Help_Shortcuts); // AssignKeyToMenu(KeyCommand[21], MENU_Help_About); // Alert calling function of success return 0; } else { // Show error and alert calling function of FAILURE Token_Toolbar.ShowError( 4 ); return -1; } }
/// <summary> /// This returns the Button to activate, if necessary, from a Shortcut. /// </summary> /// <param name="keys">The keystroke combination being tried</param> /// <returns>The Button to click, or null if the shortcut didn't click any button</returns> private Button GetButtonFromShortcut( KeyCombo keys ) { // As written, there are twenty possible shortcuts to fire dynamic buttons: // Ctrl + [ 1 through 5 ] → Add MathML Element 1-5 // Ctrl + [ 6 through 0 ] → Add Level 1 Token 1-5 // Ctrl + Alt + [ 1 through 0] → And Level 2 Token 1-10 int butIndex = 0; int buttonNum = Convert.ToInt32( keys._mainKey ); if ( ( buttonNum < 48 ) | ( buttonNum > 57 ) ) return null; buttonNum -= 48; if( buttonNum == 0 ) buttonNum = 10; buttonNum--; if ( keys._ctrl == true ) { if( keys._alt == true ) { // This will be a level 2 token butIndex = NUM_CONTROLS + ( NumElements + NumLevel1 ) + buttonNum; } else { if( buttonNum < 5 ) { // This is an element butIndex = NUM_CONTROLS + buttonNum; if( butIndex >= ( NUM_CONTROLS + NumElements ) ) butIndex = 0; } else { // This is a level 1 token butIndex = NUM_CONTROLS + buttonNum + NumElements - 5; if( butIndex >= ( NUM_CONTROLS + NumElements + NumLevel1 ) ) butIndex = 0; } } } if( butIndex == 0 ) return null; if( butIndex < Controls.Count ) return ( Button )Controls[ butIndex ]; else return null; }