]> git.tdb.fi Git - libs/gui.git/blob - source/input/control.cpp
8ddcdd772cf2af96cc7e7f51f42e978edebe87cd
[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::connect_signals()
91 {
92         switch(src.type)
93         {
94         case NONE:
95                 break;
96         case BUTTON:
97                 src.dev->signal_button_press.connect(sigc::mem_fun(this, &Control::button_press));
98                 src.dev->signal_button_release.connect(sigc::mem_fun(this, &Control::button_release));
99                 break;
100         case AXIS_POS:
101         case AXIS_NEG:
102                 src.dev->signal_axis_motion.connect(sigc::mem_fun(this, &Control::axis_motion));
103                 break;
104         default:
105                 throw Exception("Invalid source in Control");
106         }
107 }
108
109 void Control::button_press(unsigned i)
110 {
111         if(capture_dev)
112         {
113                 src.dev=capture_dev;
114                 src.type=BUTTON;
115                 src.index=i;
116
117                 notify_callbacks();
118                 capture_dev=0;
119                 connect_signals();
120                 signal_capture_complete.emit();
121         }
122         else if(src.type==BUTTON && i==src.index)
123                 on_press();
124 }
125
126 void Control::button_release(unsigned i)
127 {
128         if(src.type==BUTTON && i==src.index)
129                 on_release();
130 }
131
132 void Control::axis_motion(unsigned i, float v, float r)
133 {
134         if(capture_dev)
135         {
136                 ControlSrcType type=NONE;
137                 if(v<-src.dev->get_axis_threshold())
138                         type=AXIS_NEG;
139                 else if(v>src.dev->get_axis_threshold())
140                         type=AXIS_POS;
141
142                 if(type!=NONE)
143                 {
144                         src.dev=capture_dev;
145                         src.type=type;
146                         src.index=i;
147
148                         notify_callbacks();
149                         capture_dev=0;
150                         connect_signals();
151                         signal_capture_complete.emit();
152                 }
153         }
154         else if(src.type==AXIS_POS && i==src.index && v>=0)
155                 on_motion(v, r);
156         else if(src.type==AXIS_NEG && i==src.index && v<=0)
157                 on_motion(-v, -r);
158 }
159
160 } // namespace Input
161 } // namespace Msp