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@42
|
105 // ***** GUI Support *****
|
andrewm@42
|
106 MappingEditorComponent* TouchkeyMultiFingerTriggerMappingFactory::createBasicEditor() {
|
andrewm@42
|
107 return new TouchkeyMultiFingerTriggerMappingShortEditor(*this);
|
andrewm@42
|
108 }
|
andrewm@36
|
109
|
andrewm@36
|
110 // ****** Preset Save/Load ******
|
andrewm@36
|
111 XmlElement* TouchkeyMultiFingerTriggerMappingFactory::getPreset() {
|
andrewm@36
|
112 PropertySet properties;
|
andrewm@36
|
113
|
andrewm@36
|
114 storeCommonProperties(properties);
|
andrewm@36
|
115
|
andrewm@42
|
116 properties.setValue("numTouchesForTrigger", numTouchesForTrigger_);
|
andrewm@42
|
117 properties.setValue("numFramesForTrigger", numFramesForTrigger_);
|
andrewm@42
|
118 properties.setValue("numConsecutiveTapsForTrigger", numConsecutiveTapsForTrigger_);
|
andrewm@42
|
119 properties.setValue("maxTapSpacing", maxTapSpacing_);
|
andrewm@42
|
120 properties.setValue("needsMidiNoteOn", needsMidiNoteOn_);
|
andrewm@42
|
121 properties.setValue("triggerOnAction", triggerOnAction_);
|
andrewm@42
|
122 properties.setValue("triggerOffAction", triggerOffAction_);
|
andrewm@42
|
123 properties.setValue("triggerOnNoteNum", triggerOnNoteNum_);
|
andrewm@42
|
124 properties.setValue("triggerOffNoteNum", triggerOffNoteNum_);
|
andrewm@42
|
125 properties.setValue("triggerOnNoteVel", triggerOnNoteVel_);
|
andrewm@42
|
126 properties.setValue("triggerOffNoteVel", triggerOffNoteVel_);
|
andrewm@36
|
127
|
andrewm@36
|
128 XmlElement* preset = properties.createXml("MappingFactory");
|
andrewm@36
|
129 preset->setAttribute("type", "MultiFingerTrigger");
|
andrewm@36
|
130
|
andrewm@36
|
131 return preset;
|
andrewm@36
|
132 }
|
andrewm@36
|
133
|
andrewm@36
|
134 bool TouchkeyMultiFingerTriggerMappingFactory::loadPreset(XmlElement const* preset) {
|
andrewm@36
|
135 if(preset == 0)
|
andrewm@36
|
136 return false;
|
andrewm@36
|
137
|
andrewm@36
|
138 PropertySet properties;
|
andrewm@36
|
139 properties.restoreFromXml(*preset);
|
andrewm@36
|
140
|
andrewm@36
|
141 if(!loadCommonProperties(properties))
|
andrewm@36
|
142 return false;
|
andrewm@36
|
143
|
andrewm@42
|
144 // Load specific properties
|
andrewm@42
|
145 if(properties.containsKey("numTouchesForTrigger"))
|
andrewm@42
|
146 numTouchesForTrigger_ = properties.getIntValue("numTouchesForTrigger");
|
andrewm@42
|
147 if(properties.containsKey("numFramesForTrigger"))
|
andrewm@42
|
148 numFramesForTrigger_ = properties.getIntValue("numFramesForTrigger");
|
andrewm@42
|
149 if(properties.containsKey("numConsecutiveTapsForTrigger"))
|
andrewm@42
|
150 numConsecutiveTapsForTrigger_ = properties.getIntValue("numConsecutiveTapsForTrigger");
|
andrewm@42
|
151 if(properties.containsKey("maxTapSpacing"))
|
andrewm@42
|
152 maxTapSpacing_ = properties.getDoubleValue("maxTapSpacing");
|
andrewm@42
|
153 if(properties.containsKey("needsMidiNoteOn"))
|
andrewm@42
|
154 needsMidiNoteOn_ = properties.getBoolValue("needsMidiNoteOn");
|
andrewm@42
|
155 if(properties.containsKey("triggerOnAction"))
|
andrewm@42
|
156 triggerOnAction_ = properties.getBoolValue("triggerOnAction");
|
andrewm@42
|
157 if(properties.containsKey("triggerOffAction"))
|
andrewm@42
|
158 triggerOffAction_ = properties.getBoolValue("triggerOffAction");
|
andrewm@42
|
159 if(properties.containsKey("triggerOnNoteNum"))
|
andrewm@42
|
160 triggerOnNoteNum_ = properties.getBoolValue("triggerOnNoteNum");
|
andrewm@42
|
161 if(properties.containsKey("triggerOffNoteNum"))
|
andrewm@42
|
162 triggerOffNoteNum_ = properties.getBoolValue("triggerOffNoteNum");
|
andrewm@42
|
163 if(properties.containsKey("triggerOnNoteVel"))
|
andrewm@42
|
164 triggerOnNoteVel_ = properties.getBoolValue("triggerOnNoteVel");
|
andrewm@42
|
165 if(properties.containsKey("triggerOffNoteVel"))
|
andrewm@42
|
166 triggerOffNoteVel_ = properties.getBoolValue("triggerOffNoteVel");
|
andrewm@36
|
167
|
andrewm@36
|
168 return true;
|
andrewm@36
|
169 }
|
andrewm@42
|
170
|
andrewm@42
|
171 // ***** Private Methods *****
|
andrewm@42
|
172
|
andrewm@42
|
173 // Set the initial parameters for a new mapping
|
andrewm@42
|
174 void TouchkeyMultiFingerTriggerMappingFactory::initializeMappingParameters(int noteNumber, TouchkeyMultiFingerTriggerMapping *mapping) {
|
andrewm@42
|
175 mapping->setTouchesForTrigger(numTouchesForTrigger_);
|
andrewm@42
|
176 mapping->setFramesForTrigger(numFramesForTrigger_);
|
andrewm@42
|
177 mapping->setConsecutiveTapsForTrigger(numConsecutiveTapsForTrigger_);
|
andrewm@42
|
178 mapping->setMaxTimeBetweenTapsForTrigger(maxTapSpacing_);
|
andrewm@42
|
179 mapping->setNeedsMidiNoteOn(needsMidiNoteOn_);
|
andrewm@42
|
180 mapping->setTriggerOnAction(triggerOnAction_);
|
andrewm@42
|
181 mapping->setTriggerOffAction(triggerOffAction_);
|
andrewm@42
|
182 mapping->setTriggerOnNoteNumber(triggerOnNoteNum_);
|
andrewm@42
|
183 mapping->setTriggerOffNoteNumber(triggerOffNoteNum_);
|
andrewm@42
|
184 mapping->setTriggerOnNoteVelocity(triggerOnNoteVel_);
|
andrewm@42
|
185 mapping->setTriggerOffNoteVelocity(triggerOffNoteVel_);
|
andrewm@42
|
186 }
|