]> git.tdb.fi Git - libs/gui.git/blob - source/input/control.cpp
Add set_source method to Control
[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 || type==AXIS_NEG)
33                 return dev->get_axis_name(index);
34         else if(type==NONE)
35                 return "None";
36
37         return lexical_cast(index);
38 }
39
40
41 Control::Control():
42         capture_dev(0)
43 { }
44
45 Control::Control(const ControlSource &s):
46         src(s),
47         capture_dev(0)
48 { }
49
50 Control::Control(Device &d, ControlSrcType t, unsigned i):
51         src(d, t, i),
52         capture_dev(0)
53 {
54         connect_signals();
55 }
56
57 Control::Control(const Control &c):
58         trackable(c),
59         src(c.src),
60         capture_dev(0)
61 {
62         connect_signals();
63 }
64
65 Control &Control::operator=(const Control &c)
66 {
67         notify_callbacks();
68         src=c.src;
69         capture_dev=0;
70         connect_signals();
71
72         return *this;
73 }
74
75 void Control::capture(Device &d)
76 {
77         notify_callbacks();
78         capture_dev=&d;
79         capture_dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
80         capture_dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
81 }
82
83 void Control::cancel_capture()
84 {
85         notify_callbacks();
86         capture_dev=0;
87         connect_signals();
88 }
89
90 void Control::set_source(Device &d, ControlSrcType t, unsigned i)
91 {
92         set_source(ControlSource(d, t, i));
93 }
94
95 void Control::set_source(const ControlSource &s)
96 {
97         notify_callbacks();
98         src=s;
99         connect_signals();
100 }
101
102 void Control::connect_signals()
103 {
104         switch(src.type)
105         {
106         case NONE:
107                 break;
108         case BUTTON:
109                 src.dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
110                 src.dev->signal_button_release.connect(sigc::mem_fun(this, &Control::button_release));
111                 break;
112         case AXIS_POS:
113         case AXIS_NEG:
114                 src.dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
115                 break;
116         default:
117                 throw Exception("Invalid source in Control");
118         }
119 }
120
121 void Control::button_press(unsigned i)
122 {
123         if(capture_dev)
124         {
125                 src.dev=capture_dev;
126                 src.type=BUTTON;
127                 src.index=i;
128
129                 notify_callbacks();
130                 capture_dev=0;
131                 connect_signals();
132                 signal_capture_complete.emit();
133         }
134         else if(src.type==BUTTON && i==src.index)
135                 on_press();
136 }
137
138 void Control::button_release(unsigned i)
139 {
140         if(src.type==BUTTON && i==src.index)
141                 on_release();
142 }
143
144 void Control::axis_motion(unsigned i, float v, float r)
145 {
146         if(capture_dev)
147         {
148                 ControlSrcType type=NONE;
149                 if(v<-src.dev->get_axis_threshold())
150                         type=AXIS_NEG;
151                 else if(v>src.dev->get_axis_threshold())
152                         type=AXIS_POS;
153
154                 if(type!=NONE)
155                 {
156                         src.dev=capture_dev;
157                         src.type=type;
158                         src.index=i;
159
160                         notify_callbacks();
161                         capture_dev=0;
162                         connect_signals();
163                         signal_capture_complete.emit();
164                 }
165         }
166         else if(src.type==AXIS_POS && i==src.index && v>=0)
167                 on_motion(v, r);
168         else if(src.type==AXIS_NEG && i==src.index && v<=0)
169                 on_motion(-v, -r);
170 }
171
172 } // namespace Input
173 } // namespace Msp