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