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