andrewm@0: /*
andrewm@0: TouchKeys: multi-touch musical keyboard control software
andrewm@0: Copyright (c) 2013 Andrew McPherson
andrewm@0:
andrewm@0: This program is free software: you can redistribute it and/or modify
andrewm@0: it under the terms of the GNU General Public License as published by
andrewm@0: the Free Software Foundation, either version 3 of the License, or
andrewm@0: (at your option) any later version.
andrewm@0:
andrewm@0: This program is distributed in the hope that it will be useful,
andrewm@0: but WITHOUT ANY WARRANTY; without even the implied warranty of
andrewm@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
andrewm@0: GNU General Public License for more details.
andrewm@0:
andrewm@0: You should have received a copy of the GNU General Public License
andrewm@0: along with this program. If not, see .
andrewm@0:
andrewm@0: =====================================================================
andrewm@0:
andrewm@0: TouchkeyMultiFingerTriggerMappingFactory.cpp: factory for the multiple-
andrewm@0: finger trigger mapping, which performs actions when two or more fingers
andrewm@0: are added or removed from the key.
andrewm@0: */
andrewm@0:
andrewm@0: #include "TouchkeyMultiFingerTriggerMappingFactory.h"
andrewm@42: #include "TouchkeyMultiFingerTriggerMappingShortEditor.h"
andrewm@42:
andrewm@42: TouchkeyMultiFingerTriggerMappingFactory::TouchkeyMultiFingerTriggerMappingFactory(PianoKeyboard &keyboard, MidiKeyboardSegment& segment)
andrewm@42: : TouchkeyBaseMappingFactory(keyboard, segment),
andrewm@42: numTouchesForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumTouchesForTrigger),
andrewm@42: numFramesForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumFramesForTrigger),
andrewm@42: numConsecutiveTapsForTrigger_(TouchkeyMultiFingerTriggerMapping::kDefaultNumConsecutiveTapsForTrigger),
andrewm@42: maxTapSpacing_(TouchkeyMultiFingerTriggerMapping::kDefaultMaxTapSpacing),
andrewm@42: needsMidiNoteOn_(true),
andrewm@42: triggerOnAction_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnAction),
andrewm@42: triggerOffAction_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffAction),
andrewm@42: triggerOnNoteNum_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnNoteNum),
andrewm@42: triggerOffNoteNum_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffNoteNum),
andrewm@42: triggerOnNoteVel_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOnNoteVel),
andrewm@42: triggerOffNoteVel_(TouchkeyMultiFingerTriggerMapping::kDefaultTriggerOffNoteVel)
andrewm@42: {
andrewm@42:
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTouchesForTrigger(int touches) {
andrewm@42: if(touches < 1)
andrewm@42: touches = 1;
andrewm@42: if(touches > 3)
andrewm@42: touches = 3;
andrewm@42: numTouchesForTrigger_ = touches;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setFramesForTrigger(int frames) {
andrewm@42: if(frames < 1)
andrewm@42: frames = 1;
andrewm@42: numFramesForTrigger_ = frames;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setConsecutiveTapsForTrigger(int taps) {
andrewm@42: if(taps < 1)
andrewm@42: taps = 1;
andrewm@42: numConsecutiveTapsForTrigger_ = taps;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setMaxTimeBetweenTapsForTrigger(timestamp_diff_type timeDiff) {
andrewm@42: if(timeDiff < 0)
andrewm@42: timeDiff = 0;
andrewm@42: maxTapSpacing_ = timeDiff;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setNeedsMidiNoteOn(bool needsMidi) {
andrewm@42: needsMidiNoteOn_ = needsMidi;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnAction(int action) {
andrewm@42: if(action > 0 && action < TouchkeyMultiFingerTriggerMapping::kActionMax)
andrewm@42: triggerOnAction_ = action;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffAction(int action) {
andrewm@42: if(action > 0 && action < TouchkeyMultiFingerTriggerMapping::kActionMax)
andrewm@42: triggerOffAction_ = action;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnNoteNumber(int note) {
andrewm@42: triggerOnNoteNum_ = note;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffNoteNumber(int note) {
andrewm@42: triggerOffNoteNum_ = note;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOnNoteVelocity(int velocity) {
andrewm@42: if(velocity > 127)
andrewm@42: velocity = 127;
andrewm@42: triggerOnNoteVel_ = velocity;
andrewm@42: }
andrewm@42:
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::setTriggerOffNoteVelocity(int velocity) {
andrewm@42: if(velocity > 127)
andrewm@42: velocity = 127;
andrewm@42: triggerOffNoteVel_ = velocity;
andrewm@42: }
andrewm@42:
andrewm@49: #ifndef TOUCHKEYS_NO_GUI
andrewm@42: // ***** GUI Support *****
andrewm@42: MappingEditorComponent* TouchkeyMultiFingerTriggerMappingFactory::createBasicEditor() {
andrewm@42: return new TouchkeyMultiFingerTriggerMappingShortEditor(*this);
andrewm@42: }
andrewm@49: #endif
andrewm@49:
andrewm@49: // ****** OSC Control Support ******
andrewm@49: OscMessage* TouchkeyMultiFingerTriggerMappingFactory::oscControlMethod(const char *path, const char *types,
andrewm@49: int numValues, lo_arg **values, void *data) {
andrewm@49: // TODO
andrewm@49:
andrewm@49: // If no match, check the base class
andrewm@49: return TouchkeyBaseMappingFactory::oscControlMethod(path, types, numValues, values, data);
andrewm@49: }
andrewm@36:
andrewm@36: // ****** Preset Save/Load ******
andrewm@36: XmlElement* TouchkeyMultiFingerTriggerMappingFactory::getPreset() {
andrewm@36: PropertySet properties;
andrewm@36:
andrewm@36: storeCommonProperties(properties);
andrewm@36:
andrewm@42: properties.setValue("numTouchesForTrigger", numTouchesForTrigger_);
andrewm@42: properties.setValue("numFramesForTrigger", numFramesForTrigger_);
andrewm@42: properties.setValue("numConsecutiveTapsForTrigger", numConsecutiveTapsForTrigger_);
andrewm@42: properties.setValue("maxTapSpacing", maxTapSpacing_);
andrewm@42: properties.setValue("needsMidiNoteOn", needsMidiNoteOn_);
andrewm@42: properties.setValue("triggerOnAction", triggerOnAction_);
andrewm@42: properties.setValue("triggerOffAction", triggerOffAction_);
andrewm@42: properties.setValue("triggerOnNoteNum", triggerOnNoteNum_);
andrewm@42: properties.setValue("triggerOffNoteNum", triggerOffNoteNum_);
andrewm@42: properties.setValue("triggerOnNoteVel", triggerOnNoteVel_);
andrewm@42: properties.setValue("triggerOffNoteVel", triggerOffNoteVel_);
andrewm@36:
andrewm@36: XmlElement* preset = properties.createXml("MappingFactory");
andrewm@36: preset->setAttribute("type", "MultiFingerTrigger");
andrewm@36:
andrewm@36: return preset;
andrewm@36: }
andrewm@36:
andrewm@36: bool TouchkeyMultiFingerTriggerMappingFactory::loadPreset(XmlElement const* preset) {
andrewm@36: if(preset == 0)
andrewm@36: return false;
andrewm@36:
andrewm@36: PropertySet properties;
andrewm@36: properties.restoreFromXml(*preset);
andrewm@36:
andrewm@36: if(!loadCommonProperties(properties))
andrewm@36: return false;
andrewm@36:
andrewm@42: // Load specific properties
andrewm@42: if(properties.containsKey("numTouchesForTrigger"))
andrewm@42: numTouchesForTrigger_ = properties.getIntValue("numTouchesForTrigger");
andrewm@42: if(properties.containsKey("numFramesForTrigger"))
andrewm@42: numFramesForTrigger_ = properties.getIntValue("numFramesForTrigger");
andrewm@42: if(properties.containsKey("numConsecutiveTapsForTrigger"))
andrewm@42: numConsecutiveTapsForTrigger_ = properties.getIntValue("numConsecutiveTapsForTrigger");
andrewm@42: if(properties.containsKey("maxTapSpacing"))
andrewm@42: maxTapSpacing_ = properties.getDoubleValue("maxTapSpacing");
andrewm@42: if(properties.containsKey("needsMidiNoteOn"))
andrewm@42: needsMidiNoteOn_ = properties.getBoolValue("needsMidiNoteOn");
andrewm@42: if(properties.containsKey("triggerOnAction"))
andrewm@42: triggerOnAction_ = properties.getBoolValue("triggerOnAction");
andrewm@42: if(properties.containsKey("triggerOffAction"))
andrewm@42: triggerOffAction_ = properties.getBoolValue("triggerOffAction");
andrewm@42: if(properties.containsKey("triggerOnNoteNum"))
andrewm@42: triggerOnNoteNum_ = properties.getBoolValue("triggerOnNoteNum");
andrewm@42: if(properties.containsKey("triggerOffNoteNum"))
andrewm@42: triggerOffNoteNum_ = properties.getBoolValue("triggerOffNoteNum");
andrewm@42: if(properties.containsKey("triggerOnNoteVel"))
andrewm@42: triggerOnNoteVel_ = properties.getBoolValue("triggerOnNoteVel");
andrewm@42: if(properties.containsKey("triggerOffNoteVel"))
andrewm@42: triggerOffNoteVel_ = properties.getBoolValue("triggerOffNoteVel");
andrewm@36:
andrewm@36: return true;
andrewm@36: }
andrewm@42:
andrewm@42: // ***** Private Methods *****
andrewm@42:
andrewm@42: // Set the initial parameters for a new mapping
andrewm@42: void TouchkeyMultiFingerTriggerMappingFactory::initializeMappingParameters(int noteNumber, TouchkeyMultiFingerTriggerMapping *mapping) {
andrewm@42: mapping->setTouchesForTrigger(numTouchesForTrigger_);
andrewm@42: mapping->setFramesForTrigger(numFramesForTrigger_);
andrewm@42: mapping->setConsecutiveTapsForTrigger(numConsecutiveTapsForTrigger_);
andrewm@42: mapping->setMaxTimeBetweenTapsForTrigger(maxTapSpacing_);
andrewm@42: mapping->setNeedsMidiNoteOn(needsMidiNoteOn_);
andrewm@42: mapping->setTriggerOnAction(triggerOnAction_);
andrewm@42: mapping->setTriggerOffAction(triggerOffAction_);
andrewm@42: mapping->setTriggerOnNoteNumber(triggerOnNoteNum_);
andrewm@42: mapping->setTriggerOffNoteNumber(triggerOffNoteNum_);
andrewm@42: mapping->setTriggerOnNoteVelocity(triggerOnNoteVel_);
andrewm@42: mapping->setTriggerOffNoteVelocity(triggerOffNoteVel_);
andrewm@42: }