1/* 2 * Copyright (c) 2016-2021 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.12 19import QtQuick.Controls 2.12 20import QtQuick.Layouts 1.12 21import Shotcut.Controls 1.0 as Shotcut 22 23Item { 24 width: 200 25 height: 50 26 property bool blockUpdate: true 27 property double startValue: 1.0 28 property double middleValue: 1.0 29 property double endValue: 1.0 30 31 Component.onCompleted: { 32 if (filter.isNew) { 33 // Set default parameter values 34 filter.set('alpha', 1.0) 35 filter.set('opacity', 1.0) 36 filter.savePreset(preset.parameters) 37 } else { 38 middleValue = filter.getDouble('opacity', filter.animateIn) 39 if (filter.animateIn > 0) 40 startValue = filter.getDouble('opacity', 0) 41 if (filter.animateOut > 0) 42 endValue = filter.getDouble('opacity', filter.duration - 1) 43 } 44 setControls() 45 } 46 47 Connections { 48 target: filter 49 onInChanged: updateFilter(null) 50 onOutChanged: updateFilter(null) 51 onAnimateInChanged: updateFilter(null) 52 onAnimateOutChanged: updateFilter(null) 53 } 54 55 Connections { 56 target: producer 57 onPositionChanged: { 58 if (filter.animateIn > 0 || filter.animateOut > 0) { 59 setControls() 60 } else { 61 blockUpdate = true 62 brightnessSlider.value = filter.getDouble('opacity', getPosition()) * 100.0 63 blockUpdate = false 64 brightnessSlider.enabled = true 65 } 66 } 67 } 68 69 function getPosition() { 70 return Math.max(producer.position - (filter.in - producer.in), 0) 71 } 72 73 function setControls() { 74 var position = getPosition() 75 blockUpdate = true 76 brightnessSlider.value = filter.getDouble('opacity', position) * 100.0 77 brightnessKeyframesButton.checked = filter.keyframeCount('opacity') > 0 && filter.animateIn <= 0 && filter.animateOut <= 0 78 blockUpdate = false 79 brightnessSlider.enabled = position <= 0 || (position >= (filter.animateIn - 1) && position <= (filter.duration - filter.animateOut)) || position >= (filter.duration - 1) 80 } 81 82 function updateFilter(position) { 83 if (blockUpdate) return 84 var value = brightnessSlider.value / 100.0 85 86 if (position !== null) { 87 if (position <= 0 && filter.animateIn > 0) 88 startValue = value 89 else if (position >= filter.duration - 1 && filter.animateOut > 0) 90 endValue = value 91 else 92 middleValue = value 93 } 94 95 if (filter.animateIn > 0 || filter.animateOut > 0) { 96 filter.resetProperty('opacity') 97 brightnessKeyframesButton.checked = false 98 if (filter.animateIn > 0) { 99 filter.set('opacity', startValue, 0) 100 filter.set('opacity', middleValue, filter.animateIn - 1) 101 } 102 if (filter.animateOut > 0) { 103 filter.set('opacity', middleValue, filter.duration - filter.animateOut) 104 filter.set('opacity', endValue, filter.duration - 1) 105 } 106 } else if (!brightnessKeyframesButton.checked) { 107 filter.resetProperty('opacity') 108 filter.set('opacity', middleValue) 109 } else if (position !== null) { 110 filter.set('opacity', value, position) 111 } 112 } 113 114 GridLayout { 115 columns: 4 116 anchors.fill: parent 117 anchors.margins: 8 118 119 Label { 120 text: qsTr('Preset') 121 Layout.alignment: Qt.AlignRight 122 } 123 Shotcut.Preset { 124 id: preset 125 Layout.columnSpan: parent.columns - 1 126 parameters: ['opacity'] 127 onBeforePresetLoaded: { 128 filter.resetProperty(parameters[0]) 129 } 130 onPresetSelected: { 131 setControls() 132 middleValue = filter.getDouble(parameters[0], filter.animateIn) 133 if (filter.animateIn > 0) 134 startValue = filter.getDouble(parameters[0], 0) 135 if (filter.animateOut > 0) 136 endValue = filter.getDouble(parameters[0], filter.duration - 1) 137 } 138 } 139 140 Label { 141 text: qsTr('Level') 142 Layout.alignment: Qt.AlignRight 143 } 144 Shotcut.SliderSpinner { 145 id: brightnessSlider 146 minimumValue: 0.0 147 maximumValue: 200.0 148 decimals: 1 149 suffix: ' %' 150 onValueChanged: updateFilter(getPosition()) 151 } 152 Shotcut.UndoButton { 153 onClicked: brightnessSlider.value = 100 154 } 155 Shotcut.KeyframesButton { 156 id: brightnessKeyframesButton 157 onToggled: { 158 var value = brightnessSlider.value / 100.0 159 if (checked) { 160 blockUpdate = true 161 filter.clearSimpleAnimation('opacity') 162 blockUpdate = false 163 filter.set('opacity', value, getPosition()) 164 } else { 165 filter.resetProperty('opacity') 166 filter.set('opacity', value) 167 } 168 } 169 } 170 171 172 Item { 173 Layout.fillHeight: true 174 } 175 } 176} 177