Ejemplo n.º 1
0
        /// <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);
                        }
                    }
                }
            }
        }