1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ 2 3 #ifndef KEYSET_H 4 #define KEYSET_H 5 6 #include <string> 7 #include <deque> 8 #include "System/Misc/SpringTime.h" 9 10 11 class CKeySet { 12 public: CKeySet()13 CKeySet() { Reset(); } 14 CKeySet(int key, bool release); 15 16 void Reset(); 17 void SetAnyBit(); 18 void ClearModifiers(); 19 bool Parse(const std::string& token, bool showerror = true); 20 21 std::string GetString(bool useDefaultKeysym) const; 22 23 enum CKeySetModifiers { 24 KS_ALT = (1 << 0), 25 KS_CTRL = (1 << 1), 26 KS_META = (1 << 2), 27 KS_SHIFT = (1 << 3), 28 KS_ANYMOD = (1 << 4), 29 KS_RELEASE = (1 << 5) 30 }; 31 Key()32 int Key() const { return key; } Mod()33 unsigned char Mod() const { return modifiers; } Alt()34 bool Alt() const { return !!(modifiers & KS_ALT); } Ctrl()35 bool Ctrl() const { return !!(modifiers & KS_CTRL); } Meta()36 bool Meta() const { return !!(modifiers & KS_META); } Shift()37 bool Shift() const { return !!(modifiers & KS_SHIFT); } AnyMod()38 bool AnyMod() const { return !!(modifiers & KS_ANYMOD); } Release()39 bool Release() const { return !!(modifiers & KS_RELEASE); } 40 41 bool IsPureModifier() const; 42 43 bool operator<(const CKeySet& ks) const 44 { 45 if (key < ks.key) { return true; } 46 if (key > ks.key) { return false; } 47 if (modifiers < ks.modifiers) { return true; } 48 if (modifiers > ks.modifiers) { return false; } 49 return false; 50 } 51 fit(const CKeySet & ks)52 bool fit(const CKeySet& ks) const 53 { 54 return (key == ks.key) && ((modifiers == ks.modifiers) || AnyMod() || ks.AnyMod()); 55 } 56 57 bool operator==(const CKeySet& ks) const 58 { 59 return ((key == ks.key) && (modifiers == ks.modifiers)); 60 } 61 62 bool operator!=(const CKeySet& ks) const 63 { 64 return ((key != ks.key) || (modifiers != ks.modifiers)); 65 } 66 67 protected: 68 bool ParseModifier(std::string& s, const std::string& token, const std::string& abbr); 69 70 protected: 71 int key; 72 unsigned char modifiers; 73 }; 74 75 76 class CKeyChain : public std::deque<CKeySet> 77 { 78 public: 79 bool operator<(const CKeyChain& kc) const 80 { 81 if (size() < kc.size()) { return true; } 82 if (size() > kc.size()) { return false; } 83 if (empty()) { return false; } 84 return (back() < kc.back()); 85 } 86 87 bool operator==(const CKeyChain& needle) const 88 { 89 if (size() != needle.size()) 90 return false; 91 92 return std::equal(needle.rbegin(), needle.rend(), rbegin()); 93 } 94 fit(const CKeyChain & needle)95 bool fit(const CKeyChain& needle) const 96 { 97 // Scans the chain (*this) for a needle from the _back_ 98 // e.g. chain=a,b,c,d will fit needle=b,c,d but won't fit needle=a,b,c! 99 100 if (size() < needle.size()) 101 return false; 102 103 return std::equal(needle.rbegin(), needle.rend(), rbegin(), [](const CKeySet& a, const CKeySet& b) { return b.fit(a); }); 104 } 105 GetString()106 std::string GetString() const 107 { 108 std::string s; 109 for (const CKeySet& ks: *this) { 110 if (!s.empty()) s += ","; 111 s += ks.GetString(true); 112 } 113 return s; 114 } 115 }; 116 117 118 class CTimedKeyChain : public CKeyChain 119 { 120 public: 121 std::deque<spring_time> times; 122 clear()123 void clear() 124 { 125 CKeyChain::clear(); 126 times.clear(); 127 } 128 129 void push_back(const int key, const spring_time t, const bool isRepeat); emplace_back(const CKeySet & ks,const spring_time t)130 void emplace_back(const CKeySet& ks, const spring_time t) { assert(false); } 131 }; 132 133 134 #endif /* KEYSET_H */ 135