]> git.tdb.fi Git - libs/gui.git/blob - source/input/smoothcontrol.cpp
Improve SmoothControl range API
[libs/gui.git] / source / input / smoothcontrol.cpp
1 #include <stdexcept>
2 #include "smoothcontrol.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace Input {
8
9 SmoothControl::SmoothControl():
10         value(0),
11         paired_ctrl(0),
12         dead_zone(0.1),
13         threshold(0.9)
14 { }
15
16 SmoothControl::SmoothControl(const ControlSource &s):
17         Control(s),
18         value(0),
19         paired_ctrl(0),
20         dead_zone(0.1),
21         threshold(0.9)
22 { }
23
24 SmoothControl::SmoothControl(Device &d, ControlSrcType t, unsigned i):
25         Control(d, t, i),
26         value(0),
27         paired_ctrl(0),
28         dead_zone(0.1),
29         threshold(0.9)
30 { }
31
32 SmoothControl::~SmoothControl()
33 {
34         pair(0);
35 }
36
37 void SmoothControl::set_dead_zone(float d)
38 {
39         if(d<0 || (threshold>0 && d>=threshold))
40                 throw invalid_argument("SmoothControl::set_dead_zone");
41         dead_zone = d;
42 }
43
44 void SmoothControl::set_threshold(float t)
45 {
46         if(t>=0 && t<=dead_zone)
47                 throw invalid_argument("SmoothControl::set_threshold");
48         threshold = t;
49 }
50
51 void SmoothControl::set_range(float d, float t)
52 {
53         if(d<0 || (t>=0 && d>=t))
54                 throw invalid_argument("SmoothControl::set_range");
55         dead_zone = d;
56         threshold = t;
57 }
58
59 void SmoothControl::pair(SmoothControl *ctrl)
60 {
61         if(ctrl==paired_ctrl)
62                 return;
63
64         if(paired_ctrl)
65         {
66                 SmoothControl *old_pair = paired_ctrl;
67                 paired_ctrl = 0;
68                 old_pair->pair(0);
69         }
70
71         paired_ctrl = ctrl;
72
73         if(paired_ctrl)
74                 paired_ctrl->pair(this);
75 }
76
77 void SmoothControl::on_press()
78 {
79         on_motion(1, 1-value);
80 }
81
82 void SmoothControl::on_release()
83 {
84         if(value>0)
85                 on_motion(0, -value);
86 }
87
88 void SmoothControl::on_motion(float v, float r)
89 {
90         if(v<-dead_zone)
91                 value = v+dead_zone;
92         else if(v>dead_zone)
93                 value = v-dead_zone;
94         else
95                 value = 0;
96
97         if(threshold>=0)
98         {
99                 if(v<-threshold)
100                         value = -1;
101                 else if(v>threshold)
102                         value = 1;
103                 else
104                         value /= threshold-dead_zone;
105         }
106
107         signal_motion.emit(value);
108
109         if(paired_ctrl && (v>0 || (v==0 && paired_ctrl->value!=0)))
110                 paired_ctrl->on_motion(-v, -r);
111 }
112
113 } // namespace Input
114 } // namespace Msp