aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavelo@centrum.sk>2011-07-28 19:51:27 (GMT)
committerPavel Labath <pavelo@centrum.sk>2011-11-01 09:57:24 (GMT)
commitbb5af5d19cdaea6c01fca59c48e01b47b09be70f (patch)
tree5e735a8c85097494238ddcf807ef4ea2643e7152
parent400ca5f8196c0b3af0479c06d202b04aa6f010d5 (diff)
downloadfluxbox_pavel-bb5af5d19cdaea6c01fca59c48e01b47b09be70f.zip
fluxbox_pavel-bb5af5d19cdaea6c01fca59c48e01b47b09be70f.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 ed514ef..5c0be86 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;
@@ -379,24 +380,23 @@ void Keys::t_key::addBinding(vector<string> val, const FbTk::RefCount<FbTk::Comm
379 } // end while 380 } // end while
380 381
381 382
382 if (key == 0 && (type == KeyPress || type == ButtonPress || type == ButtonRelease)) 383 if (key == 0 && (type == 0 || type == KeyPress || type == ButtonPress || type == ButtonRelease))
383 throw KeyError("Invalid key combination:" + processed); 384 throw KeyError("Invalid key combination:" + processed);
384 385
385 if (type != ButtonPress) 386 if (type != ButtonPress)
386 isdouble = false; 387 isdouble = false;
387 388
388 RefKey new_key = find_or_insert(type, mod, key, key_str, context, isdouble); 389 RefKey new_key = RefKey(new t_key(type, mod, key, key_str, context, isdouble));
389 390 keylist_t::iterator new_it = std::find_if(keylist.begin(), keylist.end(),
390 if (new_key->m_command) 391 FbTk::MemFun(*new_key, &t_key::equalExact));
391 throw KeyError("Key combination already used:" + processed);
392 392
393 if(val.empty()) { 393 if(new_it == keylist.end() && insert)
394 if(! new_key->keylist.empty()) 394 new_it = keylist.insert(new_it, new_key);
395 throw KeyError("Key combination already used as a keychain:" + processed);
396 395
397 new_key->m_command = cmd; 396 if(new_it == keylist.end() || val.empty())
398 } else 397 return FindPair(new_it, *this);
399 new_key->addBinding(val, cmd); 398 else
399 return (*new_it)->findBinding(val, insert);
400} 400}
401 401
402 402