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