andrewm@0
|
1 /*
|
andrewm@0
|
2 TouchKeys: multi-touch musical keyboard control software
|
andrewm@0
|
3 Copyright (c) 2013 Andrew McPherson
|
andrewm@0
|
4
|
andrewm@0
|
5 This program is free software: you can redistribute it and/or modify
|
andrewm@0
|
6 it under the terms of the GNU General Public License as published by
|
andrewm@0
|
7 the Free Software Foundation, either version 3 of the License, or
|
andrewm@0
|
8 (at your option) any later version.
|
andrewm@0
|
9
|
andrewm@0
|
10 This program is distributed in the hope that it will be useful,
|
andrewm@0
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
andrewm@0
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
andrewm@0
|
13 GNU General Public License for more details.
|
andrewm@0
|
14
|
andrewm@0
|
15 You should have received a copy of the GNU General Public License
|
andrewm@0
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
|
andrewm@0
|
17
|
andrewm@0
|
18 =====================================================================
|
andrewm@0
|
19
|
andrewm@0
|
20 TouchkeyMultiFingerTriggerMappingFactory.cpp: factory for the multiple-
|
andrewm@0
|
21 finger trigger mapping, which performs actions when two or more fingers
|
andrewm@0
|
22 are added or removed from the key.
|
andrewm@0
|
23 */
|
andrewm@0
|
24
|
andrewm@0
|
25 #include "TouchkeyMultiFingerTriggerMappingFactory.h"
|
andrewm@42
|
26 #include "TouchkeyMultiFingerTriggerMappingShortEditor.h"
|
andrewm@42
|
27
|
andrewm@42
|
28 TouchkeyMultiFingerTriggerMappingFactory::TouchkeyMultiFingerTriggerMappingFactory(PianoKeyboard &keyboard, MidiKeyboardSegment& segment)
|
andrewm@42
|
29 : TouchkeyBaseMappingFactory<TouchkeyMultiFingerTriggerMapping>(keyboard, segment),
|
andrewm@42
|
30 numTouchesForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumTouchesForTrigger),
|
andrewm@42
|
31 numFramesForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumFramesForTrigger),
|
andrewm@42
|
32 numConsecutiveTapsForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumConsecutiveTapsForTrigger),
|
andrewm@42
|
33 maxTapSpacing_(TouchkeyMultiFingerTriggerMapping::kDefaultMaxTapSpacing),
|
andrewm@42
|
34 needsMidiNoteOn_(true),
|
andrewm@42
|
35 triggerOnAction_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnAction),
|
andrewm@42
|
36 triggerOffAction_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffAction),
|
andrewm@42
|
37 triggerOnNoteNum_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnNoteNum),
|
andrewm@42
|
38 triggerOffNoteNum_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffNoteNum),
|
andrewm@42
|
39 triggerOnNoteVel_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnNoteVel),
|
andrewm@42
|
40 triggerOffNoteVel_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffNoteVel)
|
andrewm@42
|
41 {
|
andrewm@42
|
42
|
andrewm@42
|
43 }
|
andrewm@42
|
44
|
andrewm@42
|
45 void TouchkeyMultiFingerTriggerMappingFactory::setTouchesForTrigger(int touches) {
|
andrewm@42
|
46 if(touches < 1)
|
andrewm@42
|
47 touches = 1;
|
andrewm@42
|
48 if(touches > 3)
|
andrewm@42
|
49 touches = 3;
|
andrewm@42
|
50 numTouchesForTrigger_ = touches;
|
andrewm@42
|
51 }
|
andrewm@42
|
52
|
andrewm@42
|
53 void TouchkeyMultiFingerTriggerMappingFactory::setFramesForTrigger(int frames) {
|
andrewm@42
|
54 if(frames < 1)
|
andrewm@42
|
55 frames = 1;
|
andrewm@42
|
56 numFramesForTrigger_ = frames;
|
andrewm@42
|
57 }
|
andrewm@42
|
58
|
andrewm@42
|
59 void TouchkeyMultiFingerTriggerMappingFactory::setConsecutiveTapsForTrigger(int taps) {
|
andrewm@42
|
60 if(taps < 1)
|
andrewm@42
|
61 taps = 1;
|
andrewm@42
|
62 numConsecutiveTapsForTrigger_ = taps;
|
andrewm@42
|
63 }
|
andrewm@42
|
64
|
andrewm@42
|
65 void TouchkeyMultiFingerTriggerMappingFactory::setMaxTimeBetweenTapsForTrigger(timestamp_diff_type timeDiff) {
|
andrewm@42
|
66 if(timeDiff < 0)
|
andrewm@42
|
67 timeDiff = 0;
|
andrewm@42
|
68 maxTapSpacing_ = timeDiff;
|
andrewm@42
|
69 }
|
andrewm@42
|
70
|
andrewm@42
|
71 void TouchkeyMultiFingerTriggerMappingFactory::setNeedsMidiNoteOn(bool needsMidi) {
|
andrewm@42
|
72 needsMidiNoteOn_ = needsMidi;
|
andrewm@42
|
73 }
|
andrewm@42
|
74
|
andrewm@42
|
75 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnAction(int action) {
|
andrewm@42
|
76 if(action > 0 && action < TouchkeyMultiFingerTriggerMapping::kActionMax)
|
andrewm@42
|
77 triggerOnAction_ = action;
|
andrewm@42
|
78 }
|
andrewm@42
|
79
|
andrewm@42
|
80 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffAction(int action) {
|
andrewm@42
|
81 if(action > 0 && action < TouchkeyMultiFingerTriggerMapping::kActionMax)
|
andrewm@42
|
82 triggerOffAction_ = action;
|
andrewm@42
|
83 }
|
andrewm@42
|
84
|
andrewm@42
|
85 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnNoteNumber(int note) {
|
andrewm@42
|
86 triggerOnNoteNum_ = note;
|
andrewm@42
|
87 }
|
andrewm@42
|
88
|
andrewm@42
|
89 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffNoteNumber(int note) {
|
andrewm@42
|
90 triggerOffNoteNum_ = note;
|
andrewm@42
|
91 }
|
andrewm@42
|
92
|
andrewm@42
|
93 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnNoteVelocity(int velocity) {
|
andrewm@42
|
94 if(velocity > 127)
|
andrewm@42
|
95 velocity = 127;
|
andrewm@42
|
96 triggerOnNoteVel_ = velocity;
|
andrewm@42
|
97 }
|
andrewm@42
|
98
|
andrewm@42
|
99 void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffNoteVelocity(int velocity) {
|
andrewm@42
|
100 if(velocity > 127)
|
andrewm@42
|
101 velocity = 127;
|
andrewm@42
|
102 triggerOffNoteVel_ = velocity;
|
andrewm@42
|
103 }
|
andrewm@42
|
104
|
andrewm@49
|
105 #ifndef TOUCHKEYS_NO_GUI
|
andrewm@42
|
106 // ***** GUI Support *****
|
andrewm@42
|
107 MappingEditorComponent* TouchkeyMultiFingerTriggerMappingFactory::createBasicEditor() {
|
andrewm@42
|
108 return new TouchkeyMultiFingerTriggerMappingShortEditor(*this);
|
andrewm@42
|
109 }
|
andrewm@49
|
110 #endif
|
andrewm@49
|
111
|
andrewm@49
|
112 // ****** OSC Control Support ******
|
andrewm@49
|
113 OscMessage* TouchkeyMultiFingerTriggerMappingFactory::oscControlMethod(const char *path, const char *types,
|
andrewm@49
|
114 int numValues, lo_arg **values, void *data) {
|
andrewm@49
|
115 // TODO
|
andrewm@49
|
116
|
andrewm@49
|
117 // If no match, check the base class
|
andrewm@49
|
118 return TouchkeyBaseMappingFactory<TouchkeyMultiFingerTriggerMapping>::oscControlMethod(path, types, numValues, values, data);
|
andrewm@49
|
119 }
|
andrewm@36
|
120
|
andrewm@36
|
121 // ****** Preset Save/Load ******
|
andrewm@36
|
122 XmlElement* TouchkeyMultiFingerTriggerMappingFactory::getPreset() {
|
andrewm@36
|
123 PropertySet properties;
|
andrewm@36
|
124
|
andrewm@36
|
125 storeCommonProperties(properties);
|
andrewm@36
|
126
|
andrewm@42
|
127 properties.setValue("numTouchesForTrigger", numTouchesForTrigger_);
|
andrewm@42
|
128 properties.setValue("numFramesForTrigger", numFramesForTrigger_);
|
andrewm@42
|
129 properties.setValue("numConsecutiveTapsForTrigger", numConsecutiveTapsForTrigger_);
|
andrewm@42
|
130 properties.setValue("maxTapSpacing", maxTapSpacing_);
|
andrewm@42
|
131 properties.setValue("needsMidiNoteOn", needsMidiNoteOn_);
|
andrewm@42
|
132 properties.setValue("triggerOnAction", triggerOnAction_);
|
andrewm@42
|
133 properties.setValue("triggerOffAction", triggerOffAction_);
|
andrewm@42
|
134 properties.setValue("triggerOnNoteNum", triggerOnNoteNum_);
|
andrewm@42
|
135 properties.setValue("triggerOffNoteNum", triggerOffNoteNum_);
|
andrewm@42
|
136 properties.setValue("triggerOnNoteVel", triggerOnNoteVel_);
|
andrewm@42
|
137 properties.setValue("triggerOffNoteVel", triggerOffNoteVel_);
|
andrewm@36
|
138
|
andrewm@36
|
139 XmlElement* preset = properties.createXml("MappingFactory");
|
andrewm@36
|
140 preset->setAttribute("type", "MultiFingerTrigger");
|
andrewm@36
|
141
|
andrewm@36
|
142 return preset;
|
andrewm@36
|
143 }
|
andrewm@36
|
144
|
andrewm@36
|
145 bool TouchkeyMultiFingerTriggerMappingFactory::loadPreset(XmlElement const* preset) {
|
andrewm@36
|
146 if(preset == 0)
|
andrewm@36
|
147 return false;
|
andrewm@36
|
148
|
andrewm@36
|
149 PropertySet properties;
|
andrewm@36
|
150 properties.restoreFromXml(*preset);
|
andrewm@36
|
151
|
andrewm@36
|
152 if(!loadCommonProperties(properties))
|
andrewm@36
|
153 return false;
|
andrewm@36
|
154
|
andrewm@42
|
155 // Load specific properties
|
andrewm@42
|
156 if(properties.containsKey("numTouchesForTrigger"))
|
andrewm@42
|
157 numTouchesForTrigger_ = properties.getIntValue("numTouchesForTrigger");
|
andrewm@42
|
158 if(properties.containsKey("numFramesForTrigger"))
|
andrewm@42
|
159 numFramesForTrigger_ = properties.getIntValue("numFramesForTrigger");
|
andrewm@42
|
160 if(properties.containsKey("numConsecutiveTapsForTrigger"))
|
andrewm@42
|
161 numConsecutiveTapsForTrigger_ = properties.getIntValue("numConsecutiveTapsForTrigger");
|
andrewm@42
|
162 if(properties.containsKey("maxTapSpacing"))
|
andrewm@42
|
163 maxTapSpacing_ = properties.getDoubleValue("maxTapSpacing");
|
andrewm@42
|
164 if(properties.containsKey("needsMidiNoteOn"))
|
andrewm@42
|
165 needsMidiNoteOn_ = properties.getBoolValue("needsMidiNoteOn");
|
andrewm@42
|
166 if(properties.containsKey("triggerOnAction"))
|
andrewm@42
|
167 triggerOnAction_ = properties.getBoolValue("triggerOnAction");
|
andrewm@42
|
168 if(properties.containsKey("triggerOffAction"))
|
andrewm@42
|
169 triggerOffAction_ = properties.getBoolValue("triggerOffAction");
|
andrewm@42
|
170 if(properties.containsKey("triggerOnNoteNum"))
|
andrewm@42
|
171 triggerOnNoteNum_ = properties.getBoolValue("triggerOnNoteNum");
|
andrewm@42
|
172 if(properties.containsKey("triggerOffNoteNum"))
|
andrewm@42
|
173 triggerOffNoteNum_ = properties.getBoolValue("triggerOffNoteNum");
|
andrewm@42
|
174 if(properties.containsKey("triggerOnNoteVel"))
|
andrewm@42
|
175 triggerOnNoteVel_ = properties.getBoolValue("triggerOnNoteVel");
|
andrewm@42
|
176 if(properties.containsKey("triggerOffNoteVel"))
|
andrewm@42
|
177 triggerOffNoteVel_ = properties.getBoolValue("triggerOffNoteVel");
|
andrewm@36
|
178
|
andrewm@36
|
179 return true;
|
andrewm@36
|
180 }
|
andrewm@42
|
181
|
andrewm@42
|
182 // ***** Private Methods *****
|
andrewm@42
|
183
|
andrewm@42
|
184 // Set the initial parameters for a new mapping
|
andrewm@42
|
185 void TouchkeyMultiFingerTriggerMappingFactory::initializeMappingParameters(int noteNumber, TouchkeyMultiFingerTriggerMapping *mapping) {
|
andrewm@42
|
186 mapping->setTouchesForTrigger(numTouchesForTrigger_);
|
andrewm@42
|
187 mapping->setFramesForTrigger(numFramesForTrigger_);
|
andrewm@42
|
188 mapping->setConsecutiveTapsForTrigger(numConsecutiveTapsForTrigger_);
|
andrewm@42
|
189 mapping->setMaxTimeBetweenTapsForTrigger(maxTapSpacing_);
|
andrewm@42
|
190 mapping->setNeedsMidiNoteOn(needsMidiNoteOn_);
|
andrewm@42
|
191 mapping->setTriggerOnAction(triggerOnAction_);
|
andrewm@42
|
192 mapping->setTriggerOffAction(triggerOffAction_);
|
andrewm@42
|
193 mapping->setTriggerOnNoteNumber(triggerOnNoteNum_);
|
andrewm@42
|
194 mapping->setTriggerOffNoteNumber(triggerOffNoteNum_);
|
andrewm@42
|
195 mapping->setTriggerOnNoteVelocity(triggerOnNoteVel_);
|
andrewm@42
|
196 mapping->setTriggerOffNoteVelocity(triggerOffNoteVel_);
|
andrewm@42
|
197 }
|