예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        public bool RemoveKeyBind(KBind kBind)
        {
            int index = KeyBinds.IndexOf(kBind);

            if (index < 0)
            {
                return(false);
            }
            return(RemoveListener(kBind, index));
        }
예제 #4
0
        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);
        }
예제 #5
0
            /// <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);
            }
예제 #6
0
            /// <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);
            }
예제 #7
0
 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);
 }
예제 #8
0
        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));
        }
예제 #9
0
            /// <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);
            }
예제 #10
0
        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);
        }
예제 #11
0
 private bool RemoveListener(KBind kBind, int kBindIndex)
 {
     KeyBinds.RemoveAt(kBindIndex);
     UpdateKeyBindGroups(kBind, KBindChange.Remove);
     return(true);
 }
예제 #12
0
            /// <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();
            }
예제 #13
0
        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());
        }
예제 #14
0
            /// <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);
            }
예제 #15
0
 public static bool RemoveListener(KBind kBind)
 {
     return(Instance.RemoveKeyBind(kBind));
 }
예제 #16
0
 private static bool UpdateLists(KBind kBind, KBindChange change)
 {
     return(Instance.UpdateKeyBindGroups(kBind, change));
 }
예제 #17
0
 public static bool AddListener(KBind kBind)
 {
     return(Instance.AddKeyBind(kBind));
 }
예제 #18
0
        public static bool HasKeyBind(KBind kBind)
        {
            int index = kBind != null?Instance.KeyBinds.IndexOf(kBind) : -1;

            return(index >= 0);
        }