protected override bool OnJoystickRelease(InputState state, JoystickEventArgs args) => handleNewReleased(state, KeyCombination.FromJoystickButton(args.Button));
 protected override bool OnKeyUp(InputState state, KeyUpEventArgs args) => handleNewReleased(state, KeyCombination.FromKey(args.Key));
 protected override bool OnJoystickPress(InputState state, JoystickEventArgs args) => handleNewPressed(state, KeyCombination.FromJoystickButton(args.Button), false);
 protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) => handleNewPressed(state, KeyCombination.FromMouseButton(args.Button), false);
 protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) => handleNewReleased(state, KeyCombination.FromMouseButton(args.Button));
示例#6
0
        protected override bool Handle(UIEvent e)
        {
            var state = e.CurrentState;

            switch (e)
            {
            case MouseDownEvent mouseDown:
                return(handleNewPressed(state, KeyCombination.FromMouseButton(mouseDown.Button)));

            case MouseUpEvent mouseUp:
                handleNewReleased(state, KeyCombination.FromMouseButton(mouseUp.Button));
                return(false);

            case KeyDownEvent keyDown:
                if (keyDown.Repeat)
                {
                    return(handleRepeat(state));
                }
                else
                {
                    return(handleNewPressed(state, KeyCombination.FromKey(keyDown.Key)));
                }

            case KeyUpEvent keyUp:
                handleNewReleased(state, KeyCombination.FromKey(keyUp.Key));
                return(false);

            case JoystickPressEvent joystickPress:
                return(handleNewPressed(state, KeyCombination.FromJoystickButton(joystickPress.Button)));

            case JoystickReleaseEvent joystickRelease:
                handleNewReleased(state, KeyCombination.FromJoystickButton(joystickRelease.Button));
                return(false);

            case MidiDownEvent midiDown:
                return(handleNewPressed(state, KeyCombination.FromMidiKey(midiDown.Key)));

            case MidiUpEvent midiUp:
                handleNewReleased(state, KeyCombination.FromMidiKey(midiUp.Key));
                return(false);

            case TabletPenButtonPressEvent tabletPenButtonPress:
                return(handleNewPressed(state, KeyCombination.FromTabletPenButton(tabletPenButtonPress.Button)));

            case TabletPenButtonReleaseEvent tabletPenButtonRelease:
                handleNewReleased(state, KeyCombination.FromTabletPenButton(tabletPenButtonRelease.Button));
                return(false);

            case TabletAuxiliaryButtonPressEvent tabletAuxiliaryButtonPress:
                return(handleNewPressed(state, KeyCombination.FromTabletAuxiliaryButton(tabletAuxiliaryButtonPress.Button)));

            case TabletAuxiliaryButtonReleaseEvent tabletAuxiliaryButtonRelease:
                handleNewReleased(state, KeyCombination.FromTabletAuxiliaryButton(tabletAuxiliaryButtonRelease.Button));
                return(false);

            case ScrollEvent scroll:
            {
                var  keys    = KeyCombination.FromScrollDelta(scroll.ScrollDelta);
                bool handled = false;

                foreach (var key in keys)
                {
                    handled |= handleNewPressed(state, key, scroll.ScrollDelta, scroll.IsPrecise);
                    handleNewReleased(state, key);
                }

                return(handled);
            }
            }

            return(false);
        }
示例#7
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);
        }
        protected override bool Handle(UIEvent e)
        {
            switch (e)
            {
            case MouseDownEvent mouseDown:
                return(handleNewPressed(KeyCombination.FromMouseButton(mouseDown.Button), false));

            case MouseUpEvent mouseUp:
                handleNewReleased(KeyCombination.FromMouseButton(mouseUp.Button));
                return(false);

            case KeyDownEvent keyDown:
                if (keyDown.Repeat && !SendRepeats)
                {
                    return(pressedBindings.Count > 0);
                }

                if (handleNewPressed(KeyCombination.FromKey(keyDown.Key), keyDown.Repeat))
                {
                    return(true);
                }

                return(false);

            case KeyUpEvent keyUp:
                handleNewReleased(KeyCombination.FromKey(keyUp.Key));
                return(false);

            case JoystickPressEvent joystickPress:
                return(handleNewPressed(KeyCombination.FromJoystickButton(joystickPress.Button), false));

            case JoystickReleaseEvent joystickRelease:
                handleNewReleased(KeyCombination.FromJoystickButton(joystickRelease.Button));
                return(false);

            case MidiDownEvent midiDown:
                return(handleNewPressed(KeyCombination.FromMidiKey(midiDown.Key), false));

            case MidiUpEvent midiUp:
                handleNewReleased(KeyCombination.FromMidiKey(midiUp.Key));
                return(false);

            case TabletPenButtonPressEvent tabletPenButtonPress:
                return(handleNewPressed(KeyCombination.FromTabletPenButton(tabletPenButtonPress.Button), false));

            case TabletPenButtonReleaseEvent tabletPenButtonRelease:
                handleNewReleased(KeyCombination.FromTabletPenButton(tabletPenButtonRelease.Button));
                return(false);

            case TabletAuxiliaryButtonPressEvent tabletAuxiliaryButtonPress:
                return(handleNewPressed(KeyCombination.FromTabletAuxiliaryButton(tabletAuxiliaryButtonPress.Button), false));

            case TabletAuxiliaryButtonReleaseEvent tabletAuxiliaryButtonRelease:
                handleNewReleased(KeyCombination.FromTabletAuxiliaryButton(tabletAuxiliaryButtonRelease.Button));
                return(false);

            case ScrollEvent scroll:
            {
                var  keys    = KeyCombination.FromScrollDelta(scroll.ScrollDelta);
                bool handled = false;

                foreach (var key in keys)
                {
                    handled |= handleNewPressed(key, false, scroll.ScrollDelta, scroll.IsPrecise);
                    handleNewReleased(key);
                }

                return(handled);
            }
            }

            return(false);
        }
 protected override bool PropagateKeyUp(IEnumerable <Drawable> drawables, InputState state, KeyUpEventArgs args) =>
 base.PropagateKeyUp(drawables, state, args) || handleNewReleased(state, KeyCombination.FromKey(args.Key));
        protected override bool PropagateKeyDown(IEnumerable <Drawable> drawables, InputState state, KeyDownEventArgs args)
        {
            if (args.Repeat)
            {
                if (pressedBindings.Count > 0)
                {
                    return(true);
                }

                return(base.PropagateKeyDown(drawables, state, args));
            }

            return(base.PropagateKeyDown(drawables, state, args) || handleNewPressed(state, KeyCombination.FromKey(args.Key)));
        }
 protected override bool PropagateMouseUp(IEnumerable <Drawable> drawables, InputState state, MouseUpEventArgs args) =>
 base.PropagateMouseUp(drawables, state, args) || handleNewReleased(state, KeyCombination.FromMouseButton(args.Button));
示例#12
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.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)
            {
                // 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();
                }

                handled |= PropagatePressed(getInputQueue(newBinding, true), 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);
        }