Пример #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);
        }
Пример #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);
        }
Пример #4
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);
        }
Пример #5
0
        private bool handleNewPressed(InputState state, InputKey newKey, Vector2?scrollDelta = null, bool isPrecise = false)
        {
            pressedInputKeys.Add(newKey);

            float scrollAmount       = getScrollAmount(newKey, scrollDelta);
            var   pressedCombination = new KeyCombination(pressedInputKeys);

            bool handled      = false;
            var  bindings     = KeyBindings?.Except(pressedBindings) ?? Enumerable.Empty <IKeyBinding>();
            var  newlyPressed = bindings.Where(m =>
                                               m.KeyCombination.IsPressed(pressedCombination, matchingMode));

            if (KeyCombination.IsModifierKey(newKey))
            {
                // if the current key pressed was a modifier, only handle modifier-only bindings.
                // lambda expression is used so that the delegate is cached (see: https://github.com/dotnet/roslyn/issues/5835)
                newlyPressed = newlyPressed.Where(b => b.KeyCombination.Keys.All(key => KeyCombination.IsModifierKey(key)));
            }

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

            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(state);
                }
            }

            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(state);
                }

                List <Drawable> inputQueue = getInputQueue(newBinding, true);
                Drawable        handledBy  = PropagatePressed(inputQueue, state, 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).
                    int count = inputQueue.IndexOf(handledBy) + 1;
                    inputQueue.RemoveRange(count, inputQueue.Count - count);

                    handled = true;
                }

                keyRepeatInputQueue = inputQueue;

                // 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);
        }