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