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