File: KeySet.h

package info (click to toggle)
spring 103.0%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,720 kB
  • ctags: 63,685
  • sloc: cpp: 368,283; ansic: 33,988; python: 12,417; java: 12,203; awk: 5,879; sh: 1,846; xml: 655; perl: 405; php: 211; objc: 194; makefile: 77; sed: 2
file content (134 lines) | stat: -rw-r--r-- 3,199 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef KEYSET_H
#define KEYSET_H

#include <string>
#include <deque>
#include "System/Misc/SpringTime.h"


class CKeySet {
	public:
		CKeySet() { Reset(); }
		CKeySet(int key, bool release);

		void Reset();
		void SetAnyBit();
		void ClearModifiers();
		bool Parse(const std::string& token, bool showerror = true);

		std::string GetString(bool useDefaultKeysym) const;

		enum CKeySetModifiers {
			KS_ALT     = (1 << 0),
			KS_CTRL    = (1 << 1),
			KS_META    = (1 << 2),
			KS_SHIFT   = (1 << 3),
			KS_ANYMOD  = (1 << 4),
			KS_RELEASE = (1 << 5)
		};

		int  Key()     const { return key; }
		unsigned char Mod() const { return modifiers; }
		bool Alt()     const { return !!(modifiers & KS_ALT); }
		bool Ctrl()    const { return !!(modifiers & KS_CTRL); }
		bool Meta()    const { return !!(modifiers & KS_META); }
		bool Shift()   const { return !!(modifiers & KS_SHIFT); }
		bool AnyMod()  const { return !!(modifiers & KS_ANYMOD); }
		bool Release() const { return !!(modifiers & KS_RELEASE); }

		bool IsPureModifier() const;

		bool operator<(const CKeySet& ks) const
		{
			if (key < ks.key) { return true; }
			if (key > ks.key) { return false; }
			if (modifiers < ks.modifiers) { return true; }
			if (modifiers > ks.modifiers) { return false; }
			return false;
		}

		bool fit(const CKeySet& ks) const
		{
			return (key == ks.key) && ((modifiers == ks.modifiers) || AnyMod() || ks.AnyMod());
		}

		bool operator==(const CKeySet& ks) const
		{
			return ((key == ks.key) && (modifiers == ks.modifiers));
		}

		bool operator!=(const CKeySet& ks) const
		{
			return ((key != ks.key) || (modifiers != ks.modifiers));
		}

	protected:
		bool ParseModifier(std::string& s, const std::string& token, const std::string& abbr);

	protected:
		int key;
		unsigned char modifiers;
};


class CKeyChain : public std::deque<CKeySet>
{
	public:
		bool operator<(const CKeyChain& kc) const
		{
			if (size() < kc.size()) { return true;  }
			if (size() > kc.size()) { return false; }
			if (empty())            { return false; }
			return (back() < kc.back());
		}

		bool operator==(const CKeyChain& needle) const
		{
			if (size() != needle.size())
				return false;

			return std::equal(needle.rbegin(), needle.rend(), rbegin());
		}

		bool fit(const CKeyChain& needle) const
		{
			// Scans the chain (*this) for a needle from the _back_
			// e.g. chain=a,b,c,d will fit needle=b,c,d but won't fit needle=a,b,c!

			if (size() < needle.size())
				return false;

			return std::equal(needle.rbegin(), needle.rend(), rbegin(), [](const CKeySet& a, const CKeySet& b) { return b.fit(a); });
		}

		std::string GetString() const
		{
			std::string s;
			for (const CKeySet& ks: *this) {
				if (!s.empty()) s += ",";
				s += ks.GetString(true);
			}
			return s;
		}
};


class CTimedKeyChain : public CKeyChain
{
	public:
		std::deque<spring_time> times;

		void clear()
		{
			CKeyChain::clear();
			times.clear();
		}

		void push_back(const int key, const spring_time t, const bool isRepeat);
		void emplace_back(const CKeySet& ks, const spring_time t) { assert(false); }
};


#endif /* KEYSET_H */