diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-07-28 19:51:27 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2013-02-18 21:04:24 (GMT) |
commit | a1c9a872b19915a0fadf83ff4dc88aa202147e1c (patch) | |
tree | 21e5eae4756ca3ef6bb202a3cc3e300d262e9e73 /src | |
parent | 69306982fbf1b66be52c3c784dedef1be77cd2d2 (diff) | |
download | fluxbox_pavel-a1c9a872b19915a0fadf83ff4dc88aa202147e1c.zip fluxbox_pavel-a1c9a872b19915a0fadf83ff4dc88aa202147e1c.tar.bz2 |
Refactor keys code a bit
I uncoupled the binding lookup from actual adding. This will make it easier to add functions for
removing bindings.
Diffstat (limited to 'src')
-rw-r--r-- | src/Keys.cc | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/src/Keys.cc b/src/Keys.cc index 40c3bfa..aa040b2 100644 --- a/src/Keys.cc +++ b/src/Keys.cc | |||
@@ -137,17 +137,23 @@ const char default_keymode[] = "default_keymode"; | |||
137 | } // end of anonymous namespace | 137 | } // end of anonymous namespace |
138 | 138 | ||
139 | // helper class 'keytree' | 139 | // helper class 'keytree' |
140 | class Keys::t_key { | 140 | class Keys::t_key: private FbTk::NotCopyable { |
141 | public: | 141 | public: |
142 | 142 | ||
143 | // typedefs | 143 | // typedefs |
144 | typedef std::list<RefKey> keylist_t; | 144 | typedef std::list<RefKey> keylist_t; |
145 | typedef std::pair<keylist_t::iterator, t_key &> FindPair; | ||
145 | 146 | ||
146 | static void initKeys(FbTk::Lua &l); | 147 | static void initKeys(FbTk::Lua &l); |
147 | static int addBindingWrapper(lua::state *l); | 148 | static int addBinding(lua::state *l); |
148 | static int newKeyMode(lua::state *l); | 149 | static int newKeyMode(lua::state *l); |
149 | 150 | ||
150 | // constructor / destructor | 151 | bool equalExact(const RefKey &x) { |
152 | return type == x->type && key == x->key && context == x->context | ||
153 | && isdouble == x->isdouble && mod == x->mod; | ||
154 | } | ||
155 | |||
156 | // constructor | ||
151 | t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, | 157 | t_key(int type = 0, unsigned int mod = 0, unsigned int key = 0, |
152 | const std::string &key_str = std::string(), int context = 0, | 158 | const std::string &key_str = std::string(), int context = 0, |
153 | bool isdouble = false); | 159 | bool isdouble = false); |
@@ -167,18 +173,11 @@ public: | |||
167 | return RefKey(); | 173 | return RefKey(); |
168 | } | 174 | } |
169 | 175 | ||
170 | RefKey find_or_insert(int type_, unsigned int mod_, unsigned int key_, | 176 | /** |
171 | const std::string &key_str_, int context_, bool isdouble_) { | 177 | * Returns the t_key object corresponding to the binding val and it's parent. |
172 | 178 | * The parent comes in handy when we want to remove the binding. | |
173 | RefKey t = find(type_, mod_, key_, context_, isdouble_); | 179 | */ |
174 | if(! t) { | 180 | FindPair findBinding(vector<string> val, bool insert); |
175 | t.reset(new t_key(type_, mod_, key_, key_str_, context_, isdouble_)); | ||
176 | keylist.push_back(t); | ||
177 | } | ||
178 | return t; | ||
179 | } | ||
180 | |||
181 | void addBinding(vector<string> val, const FbTk::RefCount<FbTk::Command<void> > &cmd ); | ||
182 | 181 | ||
183 | // member variables | 182 | // member variables |
184 | 183 | ||
@@ -195,14 +194,14 @@ public: | |||
195 | static FbTk::Lua::RegisterInitFunction registerInitKeys; | 194 | static FbTk::Lua::RegisterInitFunction registerInitKeys; |
196 | }; | 195 | }; |
197 | 196 | ||
198 | int Keys::t_key::addBindingWrapper(lua::state *l) | 197 | int Keys::t_key::addBinding(lua::state *l) |
199 | { | 198 | { |
200 | l->checkstack(2); | 199 | l->checkstack(2); |
201 | 200 | ||
202 | try { | 201 | try { |
203 | l->checkargno(3); | 202 | l->checkargno(3); |
204 | 203 | ||
205 | const RefKey &k = *l->checkudata<RefKey>(1, keymode_metatable); | 204 | RefKey k = *l->checkudata<RefKey>(1, keymode_metatable); |
206 | 205 | ||
207 | if(! l->isstring(2)) { | 206 | if(! l->isstring(2)) { |
208 | throw KeyError(_FB_CONSOLETEXT(Keys, Bad2ndArg, "2nd argument is not a string.", | 207 | throw KeyError(_FB_CONSOLETEXT(Keys, Bad2ndArg, "2nd argument is not a string.", |
@@ -223,7 +222,11 @@ int Keys::t_key::addBindingWrapper(lua::state *l) | |||
223 | cmd.reset(new FbCommands::LuaCmd(*l)); | 222 | cmd.reset(new FbCommands::LuaCmd(*l)); |
224 | } | 223 | } |
225 | 224 | ||
226 | k->addBinding(val, cmd); | 225 | FindPair p = k->findBinding(val, true); |
226 | |||
227 | k = *p.first; | ||
228 | k->m_command = cmd; | ||
229 | k->keylist.clear(); | ||
227 | } | 230 | } |
228 | catch(std::runtime_error &e) { | 231 | catch(std::runtime_error &e) { |
229 | cerr << "addBinding: " << e.what() << endl; | 232 | cerr << "addBinding: " << e.what() << endl; |
@@ -250,7 +253,7 @@ void Keys::t_key::initKeys(FbTk::Lua &l) { | |||
250 | l.rawsetfield(-2, "__gc"); | 253 | l.rawsetfield(-2, "__gc"); |
251 | 254 | ||
252 | l.newtable(); { | 255 | l.newtable(); { |
253 | l.pushfunction(&addBindingWrapper); | 256 | l.pushfunction(&addBinding); |
254 | l.rawsetfield(-2, "addBinding"); | 257 | l.rawsetfield(-2, "addBinding"); |
255 | 258 | ||
256 | l.pushfunction(&setKeyModeWrapper); | 259 | l.pushfunction(&setKeyModeWrapper); |
@@ -274,14 +277,12 @@ Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, | |||
274 | mod(mod_), | 277 | mod(mod_), |
275 | key(key_), | 278 | key(key_), |
276 | key_str(key_str_), | 279 | key_str(key_str_), |
277 | context(context_), | 280 | context(context_ ? context_ : GLOBAL), |
278 | isdouble(isdouble_), | 281 | isdouble(isdouble_), |
279 | m_command(0) { | 282 | m_command(0) { |
280 | |||
281 | context = context_ ? context_ : GLOBAL; | ||
282 | } | 283 | } |
283 | 284 | ||
284 | void Keys::t_key::addBinding(vector<string> val, const FbTk::RefCount<FbTk::Command<void> > &cmd ) { | 285 | Keys::t_key::FindPair Keys::t_key::findBinding(vector<string> val, bool insert ) { |
285 | 286 | ||
286 | unsigned int key = 0, mod = 0; | 287 | unsigned int key = 0, mod = 0; |
287 | int type = 0, context = 0; | 288 | int type = 0, context = 0; |
@@ -381,24 +382,23 @@ void Keys::t_key::addBinding(vector<string> val, const FbTk::RefCount<FbTk::Comm | |||
381 | } // end while | 382 | } // end while |
382 | 383 | ||
383 | 384 | ||
384 | if (key == 0 && (type == KeyPress || type == ButtonPress || type == ButtonRelease)) | 385 | if (key == 0 && (type == 0 || type == KeyPress || type == ButtonPress || type == ButtonRelease)) |
385 | throw KeyError("Invalid key combination:" + processed); | 386 | throw KeyError("Invalid key combination:" + processed); |
386 | 387 | ||
387 | if (type != ButtonPress) | 388 | if (type != ButtonPress) |
388 | isdouble = false; | 389 | isdouble = false; |
389 | 390 | ||
390 | RefKey new_key = find_or_insert(type, mod, key, key_str, context, isdouble); | 391 | RefKey new_key = RefKey(new t_key(type, mod, key, key_str, context, isdouble)); |
391 | 392 | keylist_t::iterator new_it = std::find_if(keylist.begin(), keylist.end(), | |
392 | if (new_key->m_command) | 393 | FbTk::MemFun(*new_key, &t_key::equalExact)); |
393 | throw KeyError("Key combination already used:" + processed); | ||
394 | 394 | ||
395 | if(val.empty()) { | 395 | if(new_it == keylist.end() && insert) |
396 | if(! new_key->keylist.empty()) | 396 | new_it = keylist.insert(new_it, new_key); |
397 | throw KeyError("Key combination already used as a keychain:" + processed); | ||
398 | 397 | ||
399 | new_key->m_command = cmd; | 398 | if(new_it == keylist.end() || val.empty()) |
400 | } else | 399 | return FindPair(new_it, *this); |
401 | new_key->addBinding(val, cmd); | 400 | else |
401 | return (*new_it)->findBinding(val, insert); | ||
402 | } | 402 | } |
403 | 403 | ||
404 | 404 | ||