Exemple #1
0
        private bool handleNewPressed(InputState state, InputKey newKey)
        {
            var pressedCombination = KeyCombination.FromInputState(state);

            bool handled = false;

            var newlyPressed = KeyBindings.Except(pressedBindings).Where(m =>
                                                                         m.KeyCombination.Keys.Contains(newKey) && // only handle bindings matching current key (not required for correct logic)
                                                                         m.KeyCombination.IsPressed(pressedCombination));

            if (isModifier(newKey))
            {
                // if the current key pressed was a modifier, only handle modifier-only bindings.
                newlyPressed = newlyPressed.Where(b => b.KeyCombination.Keys.All(isModifier));
            }

            // we want to always handle bindings with more keys before bindings with less.
            newlyPressed = newlyPressed.OrderByDescending(b => b.KeyCombination.Keys.Count()).ToList();

            pressedBindings.AddRange(newlyPressed);

            foreach (var newBinding in newlyPressed)
            {
                handled |= PropagatePressed(KeyBindingInputQueue, newBinding.GetAction <T>());

                // we only want to handle the first valid binding (the one with the most keys) in non-simultaneous mode.
                if (simultaneousMode == SimultaneousBindingMode.None && handled)
                {
                    break;
                }
            }

            return(handled);
        }
        private bool handleNewPressed(InputState state, InputKey newKey, bool repeat, Vector2?scrollDelta = null, bool isPrecise = false)
        {
            float scrollAmount = 0;

            if (newKey == InputKey.MouseWheelUp)
            {
                scrollAmount = scrollDelta?.Y ?? 0;
            }
            else if (newKey == InputKey.MouseWheelDown)
            {
                scrollAmount = -(scrollDelta?.Y ?? 0);
            }
            var pressedCombination = KeyCombination.FromInputState(state, scrollDelta);

            bool handled      = false;
            var  bindings     = (repeat ? KeyBindings : KeyBindings?.Except(pressedBindings)) ?? Enumerable.Empty <KeyBinding>();
            var  newlyPressed = bindings.Where(m =>
                                               m.KeyCombination.Keys.Contains(newKey) && // only handle bindings matching current key (not required for correct logic)
                                               m.KeyCombination.IsPressed(pressedCombination, matchingMode));

            if (KeyCombination.IsModifierKey(newKey))
            {
                // if the current key pressed was a modifier, only handle modifier-only bindings.
                newlyPressed = newlyPressed.Where(b => b.KeyCombination.Keys.All(KeyCombination.IsModifierKey));
            }

            // we want to always handle bindings with more keys before bindings with less.
            newlyPressed = newlyPressed.OrderByDescending(b => b.KeyCombination.Keys.Count()).ToList();

            if (!repeat)
            {
                pressedBindings.AddRange(newlyPressed);
            }

            // exact matching may result in no pressed (new or old) bindings, in which case we want to trigger releases for existing actions
            if (simultaneousMode == SimultaneousBindingMode.None && (matchingMode == KeyCombinationMatchingMode.Exact || matchingMode == KeyCombinationMatchingMode.Modifiers))
            {
                // only want to release pressed actions if no existing bindings would still remain pressed
                if (pressedBindings.Count > 0 && !pressedBindings.Any(m => m.KeyCombination.IsPressed(pressedCombination, matchingMode)))
                {
                    releasePressedActions();
                }
            }

            foreach (var newBinding in newlyPressed)
            {
                handled |= PropagatePressed(KeyBindingInputQueue, newBinding.GetAction <T>(), scrollAmount, isPrecise);

                // we only want to handle the first valid binding (the one with the most keys) in non-simultaneous mode.
                if (simultaneousMode == SimultaneousBindingMode.None && handled)
                {
                    break;
                }
            }

            return(handled);
        }
Exemple #3
0
        private bool handleNewPressed(InputState state, InputKey newKey, bool repeat)
        {
            var pressedCombination = KeyCombination.FromInputState(state);

            // MouseWheelUp/Down cannot be obtained from KeyCombination.FromInputState so we manually add that here.
            if (!pressedCombination.Keys.Contains(newKey))
            {
                pressedCombination = new KeyCombination(pressedCombination.Keys.Concat(new[] { newKey }));
            }

            bool handled      = false;
            var  bindings     = repeat ? KeyBindings : KeyBindings.Except(pressedBindings);
            var  newlyPressed = bindings.Where(m =>
                                               m.KeyCombination.Keys.Contains(newKey) && // only handle bindings matching current key (not required for correct logic)
                                               m.KeyCombination.IsPressed(pressedCombination, simultaneousMode == SimultaneousBindingMode.NoneExact));

            if (isModifier(newKey))
            {
                // if the current key pressed was a modifier, only handle modifier-only bindings.
                newlyPressed = newlyPressed.Where(b => b.KeyCombination.Keys.All(isModifier));
            }

            // we want to always handle bindings with more keys before bindings with less.
            newlyPressed = newlyPressed.OrderByDescending(b => b.KeyCombination.Keys.Count()).ToList();

            if (!repeat)
            {
                pressedBindings.AddRange(newlyPressed);
            }

            // exact matching may result in no pressed (new or old) bindings, in which case we want to trigger releases for existing actions
            if (simultaneousMode == SimultaneousBindingMode.NoneExact)
            {
                // only want to release pressed actions if no existing bindings would still remain pressed
                if (pressedBindings.Count > 0 && !pressedBindings.Any(m => m.KeyCombination.IsPressed(pressedCombination, simultaneousMode == SimultaneousBindingMode.NoneExact)))
                {
                    releasePressedActions();
                }
            }

            foreach (var newBinding in newlyPressed)
            {
                handled |= PropagatePressed(KeyBindingInputQueue, newBinding.GetAction <T>());

                // we only want to handle the first valid binding (the one with the most keys) in non-simultaneous mode.
                if ((simultaneousMode == SimultaneousBindingMode.None || simultaneousMode == SimultaneousBindingMode.NoneExact) && handled)
                {
                    break;
                }
            }

            return(handled);
        }
Exemple #4
0
        private void handleNewReleased(InputState state, InputKey releasedKey)
        {
            var pressedCombination = KeyCombination.FromInputState(state);

            // we don't want to consider exact matching here as we are dealing with bindings, not actions.
            var newlyReleased = pressedBindings.Where(b => !b.KeyCombination.IsPressed(pressedCombination, KeyCombinationMatchingMode.Any)).ToList();

            Trace.Assert(newlyReleased.All(b => b.KeyCombination.Keys.Contains(releasedKey)));

            foreach (var binding in newlyReleased)
            {
                pressedBindings.Remove(binding);
                PropagateReleased(getInputQueue(binding), binding.GetAction <T>());
                keyBindingQueues[binding].Clear();
            }
        }
        private bool handleNewReleased(InputState state, InputKey releasedKey)
        {
            var pressedCombination = KeyCombination.FromInputState(state);

            bool handled = false;

            var newlyReleased = pressedBindings.Where(b => !b.KeyCombination.IsPressed(pressedCombination)).ToList();

            Trace.Assert(newlyReleased.All(b => b.KeyCombination.Keys.Contains(releasedKey)));

            foreach (var binding in newlyReleased)
            {
                pressedBindings.Remove(binding);

                var action = binding.GetAction <T>();

                handled |= PropagateReleased(KeyBindingInputQueue, action);
            }

            return(handled);
        }
        private bool handleNewReleased(InputState state, InputKey releasedKey)
        {
            var pressedCombination = KeyCombination.FromInputState(state);

            bool handled = false;

            // we don't want to consider exact matching here as we are dealing with bindings, not actions.
            var newlyReleased = pressedBindings.Where(b => !b.KeyCombination.IsPressed(pressedCombination, KeyCombinationMatchingMode.Any)).ToList();

            Trace.Assert(newlyReleased.All(b => b.KeyCombination.Keys.Contains(releasedKey)));

            foreach (var binding in newlyReleased)
            {
                pressedBindings.Remove(binding);

                var action = binding.GetAction <T>();

                handled |= PropagateReleased(KeyBindingInputQueue, action);
            }

            return(handled);
        }
Exemple #7
0
        private bool handleNewPressed(InputState state, InputKey newKey, bool repeat, Vector2?scrollDelta = null, bool isPrecise = false)
        {
            float scrollAmount = 0;

            if (newKey == InputKey.MouseWheelUp)
            {
                scrollAmount = scrollDelta?.Y ?? 0;
            }
            else if (newKey == InputKey.MouseWheelDown)
            {
                scrollAmount = -(scrollDelta?.Y ?? 0);
            }
            var pressedCombination = KeyCombination.FromInputState(state, scrollDelta);

            bool handled      = false;
            var  bindings     = (repeat ? KeyBindings : KeyBindings?.Except(pressedBindings)) ?? Enumerable.Empty <KeyBinding>();
            var  newlyPressed = bindings.Where(m =>
                                               m.KeyCombination.Keys.Contains(newKey) && // only handle bindings matching current key (not required for correct logic)
                                               m.KeyCombination.IsPressed(pressedCombination, matchingMode));

            if (KeyCombination.IsModifierKey(newKey))
            {
                // if the current key pressed was a modifier, only handle modifier-only bindings.
                newlyPressed = newlyPressed.Where(b => b.KeyCombination.Keys.All(KeyCombination.IsModifierKey));
            }

            // we want to always handle bindings with more keys before bindings with less.
            newlyPressed = newlyPressed.OrderByDescending(b => b.KeyCombination.Keys.Length).ToList();

            if (!repeat)
            {
                pressedBindings.AddRange(newlyPressed);
            }

            // exact matching may result in no pressed (new or old) bindings, in which case we want to trigger releases for existing actions
            if (simultaneousMode == SimultaneousBindingMode.None && (matchingMode == KeyCombinationMatchingMode.Exact || matchingMode == KeyCombinationMatchingMode.Modifiers))
            {
                // only want to release pressed actions if no existing bindings would still remain pressed
                if (pressedBindings.Count > 0 && !pressedBindings.Any(m => m.KeyCombination.IsPressed(pressedCombination, matchingMode)))
                {
                    releasePressedActions();
                }
            }

            foreach (var newBinding in newlyPressed)
            {
                // we handled a new binding and there is an existing one. if we don't want concurrency, let's propagate a released event.
                if (simultaneousMode == SimultaneousBindingMode.None)
                {
                    releasePressedActions();
                }

                List <Drawable> inputQueue = getInputQueue(newBinding, true);
                Drawable        handledBy  = PropagatePressed(inputQueue, newBinding.GetAction <T>(), scrollAmount, isPrecise);

                if (handledBy != null)
                {
                    // only drawables up to the one that handled the press should handle the release, so remove all subsequent drawables from the queue (for future use).
                    var count = inputQueue.IndexOf(handledBy) + 1;
                    inputQueue.RemoveRange(count, inputQueue.Count - count);

                    handled = true;
                }

                // we only want to handle the first valid binding (the one with the most keys) in non-simultaneous mode.
                if (simultaneousMode == SimultaneousBindingMode.None && handled)
                {
                    break;
                }
            }

            return(handled);
        }