]> git.tdb.fi Git - libs/gui.git/blobdiff - source/input/keys.cpp
Reimplement reverse key lookup with a sorted vector
[libs/gui.git] / source / input / keys.cpp
index 4a6df371776a843ab159c9dc4493e92ee9c586f8..d5687ae2c9e1142a92bc8b6d8b4844a2c0b3a1d6 100644 (file)
@@ -1,7 +1,8 @@
-#include <map>
+#include "keys.h"
 #include <stdexcept>
+#include <vector>
+#include <msp/core/algorithm.h>
 #include <msp/strings/format.h>
-#include "keys.h"
 
 using namespace std;
 
@@ -12,21 +13,25 @@ extern unsigned sys_keymap[];
 
 unsigned key_from_sys(unsigned code)
 {
-       static bool init_done = false;
-       static map<unsigned, unsigned> reverse_map;
+       struct MappedKey
+       {
+               unsigned code;
+               Key key;
+       };
 
-       if(!init_done)
+       static vector<MappedKey> reverse_map;
+
+       if(reverse_map.empty())
        {
                for(unsigned i=0; i<N_KEYS_; ++i)
                        if(sys_keymap[i])
-                               reverse_map[sys_keymap[i]] = i;
-
-               init_done = true;
+                               reverse_map.push_back({ sys_keymap[i], static_cast<Key>(i) });
+               sort_member(reverse_map, &MappedKey::code);
        }
 
-       map<unsigned, unsigned>::const_iterator i = reverse_map.find(code);
-       if(i!=reverse_map.end())
-               return i->second;
+       auto i = lower_bound_member(reverse_map, code, &MappedKey::code);
+       if(i!=reverse_map.end() && i->code==code)
+               return i->key;
 
        return 0;
 }
@@ -333,5 +338,54 @@ void operator<<(LexicalConverter &conv, Key key)
        }
 }
 
+void operator>>(const LexicalConverter &conv, MouseAxis &axis)
+{
+       if(conv.get()=="X")
+               axis = MOUSE_X_AXIS;
+       else if(conv.get()=="Y")
+               axis = MOUSE_Y_AXIS;
+       else
+               throw lexical_error(format("conversion of '%s' to MouseAxis", conv.get()));
+}
+
+void operator<<(LexicalConverter &conv, MouseAxis axis)
+{
+       switch(axis)
+       {
+       case MOUSE_X_AXIS: conv.result("X"); break;
+       case MOUSE_Y_AXIS: conv.result("Y"); break;
+       default: conv.result(format("MouseAxis(%#x)", static_cast<int>(axis)));
+       }
+}
+
+void operator>>(const LexicalConverter &conv, MouseButton &btn)
+{
+       if(conv.get()=="LEFT")
+               btn = MOUSE_LEFT;
+       else if(conv.get()=="MIDDLE")
+               btn = MOUSE_MIDDLE;
+       else if(conv.get()=="RIGHT")
+               btn = MOUSE_RIGHT;
+       else if(conv.get()=="WHEEL_UP")
+               btn = MOUSE_WHEEL_UP;
+       else if(conv.get()=="WHEEL_DOWN")
+               btn = MOUSE_WHEEL_DOWN;
+       else
+               throw lexical_error(format("conversion of '%s' to MouseButton", conv.get()));
+}
+
+void operator<<(LexicalConverter &conv, MouseButton btn)
+{
+       switch(btn)
+       {
+       case MOUSE_LEFT: conv.result("LEFT"); break;
+       case MOUSE_MIDDLE: conv.result("MIDDLE"); break;
+       case MOUSE_RIGHT: conv.result("RIGHT"); break;
+       case MOUSE_WHEEL_UP: conv.result("WHEEL_UP"); break;
+       case MOUSE_WHEEL_DOWN: conv.result("WHEEL_DOWN"); break;
+       default: conv.result(format("MouseButton(%#x)", static_cast<int>(btn)));
+       }
+}
+
 } // namespace Input
 } // namespace Msp