Ejemplo n.º 1
0
        private void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            Keys keyData   = e.KeyData;
            Keys modifiers = keyData & Keys.Modifiers;

            keyData &= ~Keys.Modifiers;

            if (keyData == Keys.Up ||
                keyData == Keys.Right ||
                keyData == Keys.Down ||
                keyData == Keys.Left)
            {
                TNode startElement = Adapters.As <TNode>(m_selectionContext.LastSelected);
                if (startElement != null)
                {
                    Rectangle nearestRect;
                    TNode     nearest = FindNearestElement(startElement, keyData, out nearestRect);
                    if (nearest != null)
                    {
                        var selection = new List <TNode>(m_selectionContext.SelectionCount);
                        selection.AddRange(m_selectionContext.GetSelection <TNode>());
                        KeysUtil.Select <TNode>(selection, nearest, modifiers);
                        m_selectionContext.Selection = selection.Cast <object>();
                        var transformAdapter = AdaptedControl.As <ITransformAdapter>();
                        if (transformAdapter != null)
                        {
                            transformAdapter.PanToRect(nearestRect);
                        }
                    }
                }
            }
        }
        /// <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);
                        }
                    }
                }
            }
        }