1/*
2 * Copyright (c) 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.1
19import Shotcut.Controls 1.0 as Shotcut
20
21Shotcut.VuiBase {
22    property string rectProperty: 'rect'
23    property real zoom: (video.zoom > 0)? video.zoom : 1.0
24    property rect filterRect: Qt.rect(-1, -1, -1, -1)
25    property bool blockUpdate: false
26    property string startValue: '_shotcut:startValue'
27    property string middleValue: '_shotcut:middleValue'
28    property string endValue:  '_shotcut:endValue'
29
30    Component.onCompleted: {
31        application.showStatusMessage(qsTr('Click in rectangle + hold Shift to drag'))
32        setRectangleControl()
33    }
34
35    function getPosition() {
36        return Math.max(producer.position - (filter.in - producer.in), 0)
37    }
38
39    function setRectangleControl() {
40        if (blockUpdate) return
41        var position = getPosition()
42        var newValue = filter.getRect(rectProperty, position)
43        if (filterRect !== newValue) {
44            filterRect = newValue
45            rectangle.setHandles(filterRect)
46        }
47        rectangle.enabled = position <= 0 || (position >= (filter.animateIn - 1) && position <= (filter.duration - filter.animateOut)) || position >= (filter.duration - 1)
48    }
49
50    function setFilter(position) {
51        blockUpdate = true
52        var rect = rectangle.rectangle
53        filterRect.x = Math.round(rect.x / rectangle.widthScale)
54        filterRect.y = Math.round(rect.y / rectangle.heightScale)
55        filterRect.width = Math.round(rect.width / rectangle.widthScale)
56        filterRect.height = Math.round(rect.height / rectangle.heightScale)
57
58        if (position !== null) {
59            filter.blockSignals = true
60            if (position <= 0 && filter.animateIn > 0)
61                filter.set(startValue, filterRect)
62            else if (position >= filter.duration - 1 && filter.animateOut > 0)
63                filter.set(endValue, filterRect)
64            else
65                filter.set(middleValue, filterRect)
66            filter.blockSignals = false
67        }
68
69        if (filter.animateIn > 0 || filter.animateOut > 0) {
70            filter.resetProperty(rectProperty)
71            if (filter.animateIn > 0) {
72                filter.set(rectProperty, filter.getRect(startValue), 1.0, 0)
73                filter.set(rectProperty, filter.getRect(middleValue), 1.0, filter.animateIn - 1)
74            }
75            if (filter.animateOut > 0) {
76                filter.set(rectProperty, filter.getRect(middleValue), 1.0, filter.duration - filter.animateOut)
77                filter.set(rectProperty, filter.getRect(endValue), 1.0, filter.duration - 1)
78            }
79        } else if (filter.keyframeCount(rectProperty) <= 0) {
80            filter.resetProperty(rectProperty)
81            filter.set(rectProperty, filter.getRect(middleValue))
82        } else if (position !== null) {
83            filter.set(rectProperty, filterRect, 1.0, position)
84        }
85        blockUpdate = false
86    }
87
88    Flickable {
89        anchors.fill: parent
90        interactive: false
91        clip: true
92        contentWidth: video.rect.width * zoom
93        contentHeight: video.rect.height * zoom
94        contentX: video.offset.x
95        contentY: video.offset.y
96
97        Item {
98            id: videoItem
99            x: video.rect.x
100            y: video.rect.y
101            width: video.rect.width
102            height: video.rect.height
103            scale: zoom
104
105            Shotcut.RectangleControl {
106                id: rectangle
107                widthScale: video.rect.width / profile.width
108                heightScale: video.rect.height / profile.height
109                handleSize: Math.max(Math.round(8 / zoom), 4)
110                borderSize: Math.max(Math.round(1.33 / zoom), 1)
111                onWidthScaleChanged: setHandles(filterRect)
112                onHeightScaleChanged: setHandles(filterRect)
113                onRectChanged: setFilter(getPosition())
114            }
115        }
116    }
117
118    Connections {
119        target: filter
120        onChanged: {
121            setRectangleControl()
122            videoItem.enabled = filter.get('disable') !== '1'
123        }
124    }
125
126    Connections {
127        target: producer
128        onPositionChanged: setRectangleControl()
129    }
130}
131