]> git.tdb.fi Git - libs/gui.git/blob - source/input/control.cpp
Allow event handling to be interrupted
[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 void Control::capture(Device &d)
55 {
56         notify_callbacks();
57         capture_dev = &d;
58         capture_dev->signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_press), false));
59         capture_dev->signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Control::axis_motion), false));
60 }
61
62 void Control::cancel_capture()
63 {
64         notify_callbacks();
65         capture_dev = 0;
66         connect_signals();
67 }
68
69 void Control::set_source(Device &d, ControlSrcType t, unsigned i)
70 {
71         set_source(ControlSource(d, t, i));
72 }
73
74 void Control::set_source(const ControlSource &s)
75 {
76         notify_callbacks();
77         src = s;
78         connect_signals();
79 }
80
81 void Control::connect_signals()
82 {
83         switch(src.type)
84         {
85         case NONE:
86                 break;
87         case BUTTON:
88                 src.dev->signal_button_press.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_press), false));
89                 src.dev->signal_button_release.connect(sigc::bind_return(sigc::mem_fun(this, &Control::button_release), false));
90                 break;
91         case AXIS_POS:
92         case AXIS_NEG:
93                 src.dev->signal_axis_motion.connect(sigc::bind_return(sigc::mem_fun(this, &Control::axis_motion), false));
94                 break;
95         }
96 }
97
98 void Control::button_press(unsigned i)
99 {
100         if(capture_dev)
101         {
102                 src.dev = capture_dev;
103                 src.type = BUTTON;
104                 src.index = i;
105
106                 notify_callbacks();
107                 capture_dev = 0;
108                 connect_signals();
109                 signal_capture_complete.emit();
110         }
111         else if(src.type==BUTTON && i==src.index)
112                 on_press();
113 }
114
115 void Control::button_release(unsigned i)
116 {
117         if(src.type==BUTTON && i==src.index)
118                 on_release();
119 }
120
121 void Control::axis_motion(unsigned i, float v, float r)
122 {
123         if(capture_dev)
124         {
125                 ControlSrcType type = NONE;
126                 if(v<-0.9)
127                         type = AXIS_NEG;
128                 else if(v>0.9)
129                         type = AXIS_POS;
130
131                 if(type!=NONE)
132                 {
133                         src.dev = capture_dev;
134                         src.type = type;
135                         src.index = i;
136
137                         notify_callbacks();
138                         capture_dev = 0;
139                         connect_signals();
140                         signal_capture_complete.emit();
141                 }
142         }
143         else if(src.type==AXIS_POS && i==src.index && v>=0)
144                 on_motion(v, r);
145         else if(src.type==AXIS_NEG && i==src.index && v<=0)
146                 on_motion(-v, -r);
147 }
148
149 } // namespace Input
150 } // namespace Msp