1/* 2 * Copyright (c) 2019-2020 Meltytech, LLC 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18import QtQuick 2.5 19 20Item { 21 // NOTE: This item only works for numeric parameters. 22 23 // The following 4 arrays should be the same length and aligned to the 24 // same parameters added to keyframableParameters. They should be set 25 // by the filter that inherits this item. 26 property var keyframableParameters: [] // strings of MLT property names 27 // The following 3 arrays are for simple keyframes. 28 property var startValues: [] 29 property var middleValues: [] 30 property var endValues: [] 31 32 // Set this property true to guard against updateFilter() getting 33 // called when setting a control value in code. Do not forget to reset it 34 // to false when you are done setting controls' values. 35 property bool blockUpdate: true 36 37 Component.onCompleted: { 38 if (!filter.isNew) 39 initializeSimpleKeyframes() 40 } 41 42 // This function should be called in your Preset.beforePresetSelected handler. 43 function resetSimpleKeyframes() { 44 for (var i in keyframableParameters) 45 filter.resetProperty(keyframableParameters[i]) 46 } 47 48 // This function should be called in your Preset.presetSelected handler. 49 function initializeSimpleKeyframes() { 50 for (var i in keyframableParameters) { 51 var parameter = keyframableParameters[i] 52 middleValues[i] = filter.getDouble(parameter, filter.animateIn) 53 if (filter.animateIn > 0) 54 startValues[i] = filter.getDouble(parameter, 0) 55 if (filter.animateOut > 0) 56 endValues[i] = filter.getDouble(parameter, filter.duration - 1) 57 } 58 } 59 60 // This function should be called when calling updateFilter() (except 61 // in filter Connections). 62 function getPosition() { 63 return Math.max(producer.position - (filter.in - producer.in), 0) 64 } 65 66 // This function can be called in your setControls() function to determine 67 // whether to enable keyframable controls. 68 function isSimpleKeyframesActive() { 69 var position = getPosition() 70 return position <= 0 71 || (position >= (filter.animateIn - 1) && 72 position <= (filter.duration - filter.animateOut)) 73 || position >= (filter.duration - 1) 74 } 75 76 // This function should be called in your controls' valueChanged handler. 77 function updateFilter(parameter, value, button, position) { 78 if (blockUpdate) return 79 var index = keyframableParameters.indexOf(parameter) 80 81 if (position !== null) { 82 if (position <= 0 && filter.animateIn > 0) 83 startValues[index] = value 84 else if (position >= filter.duration - 1 && filter.animateOut > 0) 85 endValues[index] = value 86 else 87 middleValues[index] = value 88 } 89 90 if (filter.animateIn > 0 || filter.animateOut > 0) { 91 filter.resetProperty(parameter) 92 button.checked = false 93 if (filter.animateIn > 0) { 94 filter.set(parameter, startValues[index], 0) 95 filter.set(parameter, middleValues[index], filter.animateIn - 1) 96 } 97 if (filter.animateOut > 0) { 98 filter.set(parameter, middleValues[index], filter.duration - filter.animateOut) 99 filter.set(parameter, endValues[index], filter.duration - 1) 100 } 101 } else if (!button.checked) { 102 filter.resetProperty(parameter) 103 filter.set(parameter, middleValues[index]) 104 } else if (position !== null) { 105 filter.set(parameter, value, position) 106 } 107 } 108 109 // This function should be called in the KeyframesButton.toggled handler. 110 function toggleKeyframes(isEnabled, parameter, value) { 111 if (isEnabled) { 112 blockUpdate = true 113 if (filter.animateIn > 0 || filter.animateOut > 0) { 114 // Reset all of the simple keyframes. 115 resetSimpleKeyframes() 116 filter.animateIn = 0 117 blockUpdate = false 118 filter.animateOut = 0 119 } else { 120 filter.clearSimpleAnimation(parameter) 121 blockUpdate = false 122 } 123 // Set this keyframe value. 124 filter.set(parameter, value, getPosition()) 125 } else { 126 // Remove keyframes and set the parameter. 127 filter.resetProperty(parameter) 128 filter.set(parameter, value) 129 } 130 } 131} 132