]> git.tdb.fi Git - libs/gui.git/blob - source/input/control.cpp
Normalize device axis ranges to [-1, 1]
[libs/gui.git] / source / input / control.cpp
1 /* $Id$
2
3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/core/except.h>
9 #include <msp/strings/lexicalcast.h>
10 #include "control.h"
11 #include "device.h"
12
13 namespace Msp {
14 namespace Input {
15
16 ControlSource::ControlSource():
17         dev(0),
18         type(NONE),
19         index(0)
20 { }
21
22 ControlSource::ControlSource(Device &d, ControlSrcType t, unsigned i):
23         dev(&d),
24         type(t),
25         index(i)
26 { }
27
28 std::string ControlSource::str() const
29 {
30         if(type==BUTTON)
31                 return dev->get_button_name(index);
32         else if(type==AXIS_POS)
33                 return dev->get_axis_name(index)+" +";
34         else if(type==AXIS_NEG)
35                 return dev->get_axis_name(index)+" -";
36         else if(type==NONE)
37                 return "None";
38
39         return lexical_cast(index);
40 }
41
42
43 Control::Control():
44         capture_dev(0)
45 { }
46
47 Control::Control(const ControlSource &s):
48         src(s),
49         capture_dev(0)
50 { }
51
52 Control::Control(Device &d, ControlSrcType t, unsigned i):
53         src(d, t, i),
54         capture_dev(0)
55 {
56         connect_signals();
57 }
58
59 void Control::capture(Device &d)
60 {
61         notify_callbacks();
62         capture_dev=&d;
63         capture_dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
64         capture_dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
65 }
66
67 void Control::cancel_capture()
68 {
69         notify_callbacks();
70         capture_dev=0;
71         connect_signals();
72 }
73
74 void Control::set_source(Device &d, ControlSrcType t, unsigned i)
75 {
76         set_source(ControlSource(d, t, i));
77 }
78
79 void Control::set_source(const ControlSource &s)
80 {
81         notify_callbacks();
82         src=s;
83         connect_signals();
84 }
85
86 void Control::connect_signals()
87 {
88         switch(src.type)
89         {
90         case NONE:
91                 break;
92         case BUTTON:
93                 src.dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
94                 src.dev->signal_button_release.connect(sigc::mem_fun(this, &Control::button_release));
95                 break;
96         case AXIS_POS:
97         case AXIS_NEG:
98                 src.dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
99                 break;
100         default:
101                 throw Exception("Invalid source in Control");
102         }
103 }
104
105 void Control::button_press(unsigned i)
106 {
107         if(capture_dev)
108         {
109                 src.dev=capture_dev;
110                 src.type=BUTTON;
111                 src.index=i;
112
113                 notify_callbacks();
114                 capture_dev=0;
115                 connect_signals();
116                 signal_capture_complete.emit();
117         }
118         else if(src.type==BUTTON && i==src.index)
119                 on_press();
120 }
121
122 void Control::button_release(unsigned i)
123 {
124         if(src.type==BUTTON && i==src.index)
125                 on_release();
126 }
127
128 void Control::axis_motion(unsigned i, float v, float r)
129 {
130         if(capture_dev)
131         {
132                 ControlSrcType type=NONE;
133                 if(v<-0.9)
134                         type=AXIS_NEG;
135                 else if(v>0.9)
136                         type=AXIS_POS;
137
138                 if(type!=NONE)
139                 {
140                         src.dev=capture_dev;
141                         src.type=type;
142                         src.index=i;
143
144                         notify_callbacks();
145                         capture_dev=0;
146                         connect_signals();
147                         signal_capture_complete.emit();
148                 }
149         }
150         else if(src.type==AXIS_POS && i==src.index && v>=0)
151                 on_motion(v, r);
152         else if(src.type==AXIS_NEG && i==src.index && v<=0)
153                 on_motion(-v, -r);
154 }
155
156 } // namespace Input
157 } // namespace Msp