/// <summary> /// used to add/remove/update a specific <see cref="KBind"/> /// </summary> /// <param name="kBind"></param> /// <param name="add"></param> private bool UpdateKeyBindGroups(KBind kBind, KBindChange change) { bool changeHappened = false; kBind.Init(); //if(kBind.keyCombinations != null && kBind.keyCombinations[0].modifiers != null) // Log(kBind.keyCombinations[0].modifiers[0]); //Log(kBind); EnsureInitializedKeyBinding(); if (change == KBindChange.Update) { changeHappened |= UpdateKeyBindGroups(kBind, KBindChange.Remove); change = KBindChange.Add; } for (int k = 0; k < keyBindGroups.Length; ++k) { KBindGroup group = keyBindGroups[k]; changeHappened |= group.UpdateKeyBinding(kBind, change); } if (updateText && changeHappened) { UpdateCurrentKeyBindText(); } return(changeHappened); }
public bool SetEnableKeybind(string name, bool enable) { KBind kBind = keyBinds.Find(kb => kb.name == name); if (kBind != null) { kBind.disable = !enable; return(true); } return(false); }
public bool RemoveKeyBind(KBind kBind) { int index = KeyBinds.IndexOf(kBind); if (index < 0) { return(false); } return(RemoveListener(kBind, index)); }
public static bool SetEnableBind(List <KBind> KeyBinds, string name, bool enable) { KBind kBind = KeyBinds.Find(kb => kb.name == name); if (kBind != null) { kBind.disable = !enable; return(true); } return(false); }
/// <param name="kb">check if this key bind is being triggered</param> /// <param name="list">where to mark if this is indeed triggered</param> /// <param name="additionalFilter">an additional gate that might prevent this particluar keybind from triggering. possibly heavy method, so only checked if the key is triggered</param> bool KeyCheck(KBind kb, List <KeyTrigger> list, Func <KBind, bool> additionalFilter = null) { KCombination kp = trigger(kb); if (kp != null && (additionalFilter == null || !additionalFilter.Invoke(kb))) { list.Add(new KeyTrigger { kb = kb, kp = kp }); return(true); } return(false); }
/// <param name="kb">check if this key bind is being triggered</param> /// <param name="list">where to mark if this is indeed triggered</param> /// <param name="additionalFilter">an additional gate that might prevent this particluar keybind from triggering. possibly heavy method, so only checked if the key is triggered</param> bool KeyCheck(KBind kb, List <KeyTrigger> list, Func <KBind, bool> additionalFilter = null) { KCombo kp = trigger.Invoke(kb); if (kp != null && (additionalFilter == null || !additionalFilter.Invoke(kb))) { //Debug.Log("triggered: " + kp + " -> " + kb.name); list.Add(new KeyTrigger { kb = kb, kp = kp }); return(true); } return(false); }
bool IsKeyBindAmbiguousWithTextInput(KBind kBind) { for (int i = 0; i < kBind.keyCombinations.Length; ++i) { bool isSimpleKeyPress = kBind.keyCombinations[i].modifiers == null || kBind.keyCombinations[i].modifiers.Length == 0; bool shiftModified = !isSimpleKeyPress && kBind.keyCombinations[i].modifiers[0].key == KCode.LeftShift; bool isFunctionKey = (kBind.keyCombinations[i].key >= KCode.F1 && kBind.keyCombinations[i].key <= KCode.F15); bool couldInterfereWithKeyboardInput = (isSimpleKeyPress && !isFunctionKey) || (shiftModified && !isFunctionKey); if (couldInterfereWithKeyboardInput) { return(true); } } return(false); }
public bool AddKeyBind(KBind kBind) { int index = (!string.IsNullOrEmpty(kBind.name)) ? KeyBinds.FindIndex(kb => kb.name == kBind.name) : -1; KBindChange kindOfChange = KBindChange.Add; if (index >= 0) { kindOfChange = KBindChange.Update; // will cause lists to Remove then re-Add return(false); } else { KeyBinds.Add(kBind); } return(UpdateKeyBindGroups(kBind, kindOfChange)); }
/// <param name="kBind"></param> /// <param name="kind"></param> /// <returns></returns> public bool UpdateKeyBinding(KBind kBind, KBindChange kind) { if (kind == KBindChange.Add && !putInList(kBind)) { return(false); } bool changeHappened = false; int index = keyBindList.IndexOf(kBind); switch (kind) { case KBindChange.Add: if (index >= 0) { Log("already added " + name + " " + kBind.name + "?"); } if (index < 0) { keyBindList.Add(kBind); keyBindList.Sort(); changeHappened = true; //Log($"added {name} {kBind.name}"); } else { if (index >= 0) { Log("will not add duplicate " + name + " " + kBind.name); } } break; case KBindChange.Remove: if (index >= 0) { keyBindList.RemoveAt(index); changeHappened = true; } break; case KBindChange.Update: throw new Exception("Update is composed of a Remove and Add, should never be called directly like this."); } return(changeHappened); }
public int AddListener(KBind kBind) { int index = KeyBinds.FindIndex(kb => kb.name == kBind.name); if (index >= 0) { KeyBinds[index] = kBind; } else { index = KeyBinds.Count; KeyBinds.Add(kBind); } if (enabled) { AppInput.AddListener(kBind); } return(index); }
private bool RemoveListener(KBind kBind, int kBindIndex) { KeyBinds.RemoveAt(kBindIndex); UpdateKeyBindGroups(kBind, KBindChange.Remove); return(true); }
/// <summary> /// resolves key conflicts (giving priority to more complex key presses first) before invoking all triggered keys /// </summary> public void Resolve(bool showConflict, bool logActivatedKeyBinds) { if (triggerList.Count <= 0) { return; } // sort by KCode in the triggering ComplexKeyPress, with the most complex first triggerList.Sort(); // if there are multiple keybinds with the same kcode for (int a = 0; a < triggerList.Count; ++a) { int conflictHere = -1; for (int b = a + 1; b < triggerList.Count; ++b) { if (triggerList[a].kp.key == triggerList[b].kp.key) { conflictHere = b; } } // go through all of those keybinds if (conflictHere != -1) { string debugOutput = showConflict ? "possible " + name + " conflict" : ""; int complexityToKeep = triggerList[a].kp.GetComplexity(); // if a keybind's modifiers are all fulfilled by a more complex keybind, ignore this keybind (remove from list) for (int i = a; i <= conflictHere; ++i) { KBind kb = triggerList[i].kb; if (showConflict) { debugOutput += "\n" + kb + kb.priority; } if (triggerList[i].kp.GetComplexity() < complexityToKeep) { triggerList.RemoveAt(i); if (showConflict) { debugOutput += "[REMOVED]"; } } } if (showConflict) { Show.Log(debugOutput); } } } string debugText = null; if (logActivatedKeyBinds) { debugText = name + " activating: "; } // trigger everything left in the list for (int i = 0; i < triggerList.Count; ++i) { KBind kb = triggerList[i].kb; KBind eventConsumed; s_eventConsumed.TryGetValue(triggerList[i].kp.key, out eventConsumed); if (logActivatedKeyBinds) { if (i > 0) { debugText += ", "; } debugText += kb.name; } bool activated = false; // invoke non-consumptive events, or consumptive events as long as the event is not consumed if (eventConsumed == null || kb.alwaysTriggerable) { activated = action.Invoke(kb); } // high-priority key mappings that consume events should prevent future events that also consume. if (!kb.alwaysTriggerable && activated) { //Log($"{kb.name} consumed {name}"); s_eventConsumed[triggerList[i].kp.key] = kb; } } if (logActivatedKeyBinds) { Show.Log(debugText); } s_eventConsumed.Clear(); triggerList.Clear(); }
public string CalcualteCurrentKeyBindText() { EnsureInitializedKeyBinding(); StringBuilder sb = new StringBuilder(); for (int s = 0; s < keyBindGroups.Length; ++s) { KBindGroup ks = keyBindGroups[s]; if (ks.allKeyBindings.Count == 0) { continue; } sb.Append("[" + ks.name + "]\n"); for (int i = 0; i < ks.allKeyBindings.Count; ++i) { KBind kb = ks.allKeyBindings[i]; bool needsPriority = true; bool hasKeys = true; if (kb.keyCombinations.Length != 0 && (kb.keyCombinations.Length != 1 || kb.keyCombinations[0].key != KCode.None)) { KCombo theseKeys = kb.keyCombinations[0]; bool hasPrev = i > 0; bool hasNext = i < ks.allKeyBindings.Count - 1; KBind prev = (hasPrev) ? ks.allKeyBindings[i - 1] : null; KBind next = (hasNext) ? ks.allKeyBindings[i + 1] : null; KCombo prevKeys = hasPrev && prev.keyCombinations.Length > 0 ? prev.keyCombinations[0] : null; KCombo nextKeys = hasNext && next.keyCombinations.Length > 0 ? next.keyCombinations[0] : null; needsPriority = (prevKeys != null && prevKeys.CompareTo(theseKeys) == 0 || nextKeys != null && nextKeys.CompareTo(theseKeys) == 0); } else { hasKeys = false; } if (hasKeys) { sb.Append(kb.ShortDescribe(" | ")); } else { sb.Append("(no keys)"); } sb.Append(" :"); if (needsPriority) { sb.Append(kb.priority.ToString()); } sb.Append(": "); sb.Append(kb.name); sb.Append("\n"); } } if (AxisBinds.Count > 0) { sb.Append("[Axis]\n"); for (int i = 0; i < AxisBinds.Count; ++i) { AxBind ab = AxisBinds[i]; sb.Append(ab.ShortDescribe(" | ")); sb.Append(" :: "); sb.Append(ab.name); sb.Append("\n"); } } return(sb.ToString()); }
/// <param name="kBind"></param> /// <param name="kind"></param> /// <returns></returns> public bool UpdateKeyBinding(KBind kBind, KBindChange kind) { if (kind == KBindChange.Add && putInList != null && !putInList.Invoke(kBind)) { return(false); } bool changeHappened = false; int index = allKeyBindings.IndexOf(kBind); // TODO get index from sorted list with IList extension? switch (kind) { case KBindChange.Add: if (index >= 0) { Show.Log("already added " + name + " " + kBind.name + "?"); } if (index < 0) { allKeyBindings.Add(kBind); allKeyBindings.Sort(); // TODO insert sorted in IList extension? for (int i = 0; i < kBind.keyCombinations.Length; ++i) { KCombo kCombo = kBind.keyCombinations[i]; if (!bindingsByKey.TryGetValue(kCombo.key, out List <KBindTrigger> kBinds)) { kBinds = new List <KBindTrigger>(); bindingsByKey[kCombo.key] = kBinds; } kBinds.Add(new KBindTrigger { kCombo = kCombo, kBind = kBind }); kBinds.Sort(); // TODO insert sorted in IList extension? } changeHappened = true; //Log($"added {name} {kBind.name}"); } else { if (index >= 0) { Show.Log("will not add duplicate " + name + " " + kBind.name); } } break; case KBindChange.Remove: if (index >= 0) { allKeyBindings.RemoveAt(index); changeHappened = true; for (int i = 0; i < kBind.keyCombinations.Length; ++i) { KCombo kCombo = kBind.keyCombinations[i]; if (bindingsByKey.TryGetValue(kCombo.key, out List <KBindTrigger> kBinds)) { int subIndex = kBinds.FindIndex(k => k.kBind == kBind); // TODO get index from sorted list with IList extension? kBinds.RemoveAt(subIndex); } } } break; case KBindChange.Update: throw new Exception("Update is composed of a Remove and Add, should never be called directly like this."); } return(changeHappened); }
public static bool RemoveListener(KBind kBind) { return(Instance.RemoveKeyBind(kBind)); }
private static bool UpdateLists(KBind kBind, KBindChange change) { return(Instance.UpdateKeyBindGroups(kBind, change)); }
public static bool AddListener(KBind kBind) { return(Instance.AddKeyBind(kBind)); }
public static bool HasKeyBind(KBind kBind) { int index = kBind != null?Instance.KeyBinds.IndexOf(kBind) : -1; return(index >= 0); }