aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-07-28 19:51:27 (GMT)
committerPavel Labath <pavelo@centrum.sk>2013-02-18 21:04:24 (GMT)
commita1c9a872b19915a0fadf83ff4dc88aa202147e1c (patch)
tree21e5eae4756ca3ef6bb202a3cc3e300d262e9e73
parent69306982fbf1b66be52c3c784dedef1be77cd2d2 (diff)
downloadfluxbox_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.
-rw-r--r--src/Keys.cc68
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'
140class Keys::t_key { 140class Keys::t_key: private FbTk::NotCopyable {
141public: 141public:
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
198int Keys::t_key::addBindingWrapper(lua::state *l) 197int 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
284void Keys::t_key::addBinding(vector<string> val, const FbTk::RefCount<FbTk::Command<void> > &cmd ) { 285Keys::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