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