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