]> git.tdb.fi Git - libs/gui.git/blob - source/input/bindings.cpp
1d33292c57ca91f4d305d0ad73bce57e65c724bc
[libs/gui.git] / source / input / bindings.cpp
1 #include <msp/strings/format.h>
2 #include "bindings.h"
3 #include "controlscheme.h"
4
5 using namespace std;
6
7 namespace Msp {
8 namespace Input {
9
10 vector<Device *> Bindings::resolve_devices(Device &dev) const
11 {
12         vector<Device *> resolved_devs;
13         resolved_devs.reserve(devices.size());
14         for(vector<DeviceRef>::const_iterator i=devices.begin(); i!=devices.end(); ++i)
15         {
16                 if(i->type!=UNSPECIFIED)
17                         resolved_devs.push_back(dev.find_subdevice(i->type));
18                 else if(!i->name.empty())
19                         resolved_devs.push_back(dev.find_subdevice(i->name));
20                 else
21                         resolved_devs.push_back(0);
22         }
23         return resolved_devs;
24 }
25
26 bool Bindings::is_compatible(Device &dev) const
27 {
28         vector<Device *> resolved_devs = resolve_devices(dev);
29         for(vector<Device *>::const_iterator i=resolved_devs.begin(); i!=resolved_devs.end(); ++i)
30                 if(!*i)
31                         return false;
32         return true;
33 }
34
35 bool Bindings::apply_to(ControlScheme &control_scheme, Device &dev)
36 {
37         vector<Device *> resolved_devs = resolve_devices(dev);
38         bool applied = false;
39         for(vector<Binding>::const_iterator i=bindings.begin(); i!=bindings.end(); ++i)
40         {
41                 Control *ctrl = control_scheme.find(i->control);
42                 Device *bdev = (i->device<resolved_devs.size() ? resolved_devs[i->device] : 0);
43                 if(ctrl && bdev)
44                 {
45                         ctrl->set_source(*bdev, i->type, i->index);
46                         applied = true;
47                 }
48         }
49
50         return applied;
51 }
52
53
54 DataFile::Loader::ActionMap Bindings::Loader::shared_actions;
55
56 Bindings::Loader::Loader(Bindings &b):
57         ObjectLoader<Bindings>(b)
58 {
59         set_actions(shared_actions);
60 }
61
62 void Bindings::Loader::init_actions()
63 {
64         add("binding", &Loader::binding);
65         add("device", &Loader::device_type);
66         add("device", &Loader::device_name);
67 }
68
69 void Bindings::Loader::binding(const string &c)
70 {
71         Binding bind;
72         bind.control = c;
73         load_sub(bind);
74         obj.bindings.push_back(bind);
75 }
76
77 void Bindings::Loader::device_type(DeviceType t)
78 {
79         DeviceRef dev;
80         dev.type = t;
81         obj.devices.push_back(dev);
82 }
83
84 void Bindings::Loader::device_name(const string &n)
85 {
86         DeviceRef dev;
87         dev.name = n;
88         obj.devices.push_back(dev);
89 }
90
91
92 DataFile::Loader::ActionMap Bindings::Binding::Loader::shared_actions;
93
94 Bindings::Binding::Loader::Loader(Binding &b):
95         ObjectLoader<Binding>(b)
96 {
97         set_actions(shared_actions);
98 }
99
100 void Bindings::Binding::Loader::init_actions()
101 {
102         add("axis", &Loader::axis);
103         add("button", &Loader::button);
104         add("device", &Binding::device);
105         add("key", &Loader::key);
106         add("mouse_axis", &Loader::mouse_axis);
107         add("mouse_button", &Loader::mouse_button);
108 }
109
110 void Bindings::Binding::Loader::axis(unsigned a, AxisSide s)
111 {
112         obj.type = (s==NEGATIVE ? AXIS_NEG : AXIS_POS);
113         obj.index = a;
114 }
115
116 void Bindings::Binding::Loader::button(unsigned b)
117 {
118         obj.type = BUTTON;
119         obj.index = b;
120 }
121
122
123 void operator>>(const LexicalConverter &conv, Bindings::AxisSide &side)
124 {
125         if(conv.get()=="POSITIVE")
126                 side = Bindings::POSITIVE;
127         else if(conv.get()=="NEGATIVE")
128                 side = Bindings::NEGATIVE;
129         else
130                 throw lexical_error(format("conversion of '%s' to AxisSide", conv.get()));
131 }
132
133 void operator<<(LexicalConverter &conv, Bindings::AxisSide side)
134 {
135         switch(side)
136         {
137         case Bindings::POSITIVE: conv.result("POSITIVE"); break;
138         case Bindings::NEGATIVE: conv.result("NEGATIVE"); break;
139         default: conv.result(format("AxisSide(%#x)", static_cast<int>(side)));
140         }
141 }
142
143 } // namespace Input
144 } // namespace Msp;