/// <summary> /// Sets shortcut</summary> /// <param name="shortcut">Shortcut keys</param> /// <param name="info">CommandInfo corresponding to shortcut keys</param> /// <remarks>Keeps m_shortcuts field, the menu item, and the CommandInfo in sync with regards to shortcuts /// and ensures that each shortcut is unique</remarks> protected void SetShortcut(Keys shortcut, CommandInfo info) { shortcut = KeysUtil.NumPadToNum(shortcut); // if shortcut is reserved then do not set it. if (m_reservedKeys.ContainsKey(shortcut)) { Outputs.WriteLine(OutputMessageType.Warning, "cannot assign " + KeysUtil.KeysToString(shortcut, true) + " to " + GetCommandPath(info) + " it is reserved for " + m_reservedKeys[shortcut]); info.RemoveShortcut(shortcut); // erase shortcut if exist. EraseShortcut(shortcut); return; } info.AddShortcut(shortcut); if (shortcut != Keys.None) { // If the shortcut already exists for a different command, then erase the old commands's shortcut. if (m_shortcuts.ContainsKey(shortcut) && m_shortcuts[shortcut] != info.CommandTag) { object existingCommandTag = m_shortcuts[shortcut]; if (m_commandsById.ContainsKey(existingCommandTag)) { CommandInfo existingInfo = m_commandsById[existingCommandTag]; existingInfo.RemoveShortcut(shortcut); } } m_shortcuts[shortcut] = info.CommandTag; } }
/// <summary> /// Handles the PreviewKeyDown event on AdaptedControl, and changes the selection /// if the user navigates using the keyboard</summary> /// <param name="sender">Sender</param> /// <param name="e">Event args</param> protected virtual void PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { Keys keyData = e.KeyData; Keys modifiers = keyData & Keys.Modifiers; keyData &= ~Keys.Modifiers; if (IsNavigationKey(keyData)) { List <TNode> oldSelection; // If the user is reversing direction of a past shift+selection, and they didn't // overshoot the beginning (i.e., the stack isn't empty), then don't search for // nodes and instead restore a past selection. if (modifiers == Keys.Shift && OppositeNavigationKeys(m_lastKeyWithShift, keyData) && m_shiftKeySelectionStack.Count > 0) { oldSelection = m_shiftKeySelectionStack.Pop(); ChangeSelection(oldSelection); return; } // We need to know the current selection now. oldSelection = new List <TNode>(m_selectionContext.SelectionCount); oldSelection.AddRange(m_selectionContext.GetSelection <TNode>()); // If the user is doing a shift+selection, then push the current selection on to the // stack. But if the user chose a new direction, clear the stack first. bool pushOldSelectionIfSelectionChanges = false; if (modifiers == Keys.Shift) { if (m_lastKeyWithShift != Keys.None && m_lastKeyWithShift != keyData) { m_lastKeyWithShift = Keys.None; m_shiftKeySelectionStack.Clear(); } pushOldSelectionIfSelectionChanges = true; } else { m_lastKeyWithShift = Keys.None; m_shiftKeySelectionStack.Clear(); } // Do a search from the existing selected nodes, looking only along wires. var connectedNodes = new HashSet <TNode>(); foreach (TNode startElement in m_selectionContext.GetSelection <TNode>()) { foreach (TNode connectedNode in FindConnectedNodes(startElement, keyData, modifiers)) { connectedNodes.Add(connectedNode); } } // If no connected nodes were found, then look for the nearest nodes. if (connectedNodes.Count == 0) { foreach (TNode startElement in m_selectionContext.GetSelection <TNode>()) { TNode nearestNode = FindNearestNode(startElement, keyData, modifiers); if (nearestNode != null) { connectedNodes.Add(nearestNode); } } } // If we have new connected nodes then change the selection. if (connectedNodes.Count > 0) { // With this keyboard navigation, the Control key doesn't seem to make sense // for toggling nodes in the selection. modifiers &= ~Keys.Control; var newSelection = new HashSet <TNode>(oldSelection); KeysUtil.Select(newSelection, connectedNodes, modifiers); if (!newSelection.SetEquals(oldSelection)) { ChangeSelection(newSelection); if (pushOldSelectionIfSelectionChanges) { m_lastKeyWithShift = keyData; m_shiftKeySelectionStack.Push(new List <TNode>(oldSelection)); } // Attempt to pan, to make sure the newly selected nodes are visible if (m_transformAdapter != null) { Rectangle boundingRect = m_pickingAdapter.GetBounds(newSelection.OfType <object>()); m_transformAdapter.PanToRect(boundingRect); } } } } }