1
2
3import QtQuick 2.12
4import QtQuick.Controls 2.12
5import QtQuick.Layouts 1.12
6import Shotcut.Controls 1.0 as Shotcut
7
8
9Item {
10    width: 350
11    height: 550
12    property bool blockUpdate: true
13
14    property double yawStart : 0.0; property double yawMiddle : 0.0; property double yawEnd : 0.0;
15    property double pitchStart : 0.0; property double pitchMiddle : 0.0; property double pitchEnd : 0.0;
16    property double rollStart : 0.0; property double rollMiddle : 0.0; property double rollEnd : 0.0;
17
18    property double frontXStart : 0.0; property double frontXMiddle : 0.0; property double frontXEnd : 0.0;
19    property double frontYStart : 0.0; property double frontYMiddle : 0.0; property double frontYEnd : 0.0;
20    property double frontUpStart : 0.0; property double frontUpMiddle : 0.0; property double frontUpEnd : 0.0;
21
22    property double backXStart : 0.0; property double backXMiddle : 0.0; property double backXEnd : 0.0;
23    property double backYStart : 0.0; property double backYMiddle : 0.0; property double backYEnd : 0.0;
24    property double backUpStart : 0.0; property double backUpMiddle : 0.0; property double backUpEnd : 0.0;
25
26    property double fovStart : 0.0; property double fovMiddle : 0.0; property double fovEnd : 0.0;
27    property double radiusStart : 0.0; property double radiusMiddle : 0.0; property double radiusEnd : 0.0;
28
29    property double nadirRadiusStart : 0.0; property double nadirRadiusMiddle : 0.0; property double nadirRadiusEnd : 0.0;
30    property double nadirCorrectionStartStart : 0.0; property double nadirCorrectionStartMiddle : 0.0; property double nadirCorrectionStartEnd : 0.0;
31
32    property int interpolationValue : 0;
33    property int projectionValue : 0;
34
35    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_yaw (null); } onOutChanged: { updateProperty_yaw (null); } onAnimateInChanged: { updateProperty_yaw (null); } onAnimateOutChanged: { updateProperty_yaw (null); } }
36    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_pitch (null); } onOutChanged: { updateProperty_pitch (null); } onAnimateInChanged: { updateProperty_pitch (null); } onAnimateOutChanged: { updateProperty_pitch (null); } }
37    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_roll (null); } onOutChanged: { updateProperty_roll (null); } onAnimateInChanged: { updateProperty_roll (null); } onAnimateOutChanged: { updateProperty_roll (null); } }
38
39    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_frontX (null); } onOutChanged: { updateProperty_frontX (null); } onAnimateInChanged: { updateProperty_frontX (null); } onAnimateOutChanged: { updateProperty_frontX (null); } }
40    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_frontY (null); } onOutChanged: { updateProperty_frontY (null); } onAnimateInChanged: { updateProperty_frontY (null); } onAnimateOutChanged: { updateProperty_frontY (null); } }
41    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_frontUp (null); } onOutChanged: { updateProperty_frontUp (null); } onAnimateInChanged: { updateProperty_frontUp (null); } onAnimateOutChanged: { updateProperty_frontUp (null); } }
42
43    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_backX (null); } onOutChanged: { updateProperty_backX (null); } onAnimateInChanged: { updateProperty_backX (null); } onAnimateOutChanged: { updateProperty_backX (null); } }
44    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_backY (null); } onOutChanged: { updateProperty_backY (null); } onAnimateInChanged: { updateProperty_backY (null); } onAnimateOutChanged: { updateProperty_backY (null); } }
45    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_backUp (null); } onOutChanged: { updateProperty_backUp (null); } onAnimateInChanged: { updateProperty_backUp (null); } onAnimateOutChanged: { updateProperty_backUp (null); } }
46
47    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_fov (null); } onOutChanged: { updateProperty_fov (null); } onAnimateInChanged: { updateProperty_fov (null); } onAnimateOutChanged: { updateProperty_fov (null); } }
48    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_radius (null); } onOutChanged: { updateProperty_radius (null); } onAnimateInChanged: { updateProperty_radius (null); } onAnimateOutChanged: { updateProperty_radius (null); } }
49
50    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_nadirRadius (null); } onOutChanged: { updateProperty_nadirRadius (null); } onAnimateInChanged: { updateProperty_nadirRadius (null); } onAnimateOutChanged: { updateProperty_nadirRadius (null); } }
51    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_nadirCorrectionStart (null); } onOutChanged: { updateProperty_nadirCorrectionStart (null); } onAnimateInChanged: { updateProperty_nadirCorrectionStart (null); } onAnimateOutChanged: { updateProperty_nadirCorrectionStart (null); } }
52
53    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_interpolation (); } onOutChanged: { updateProperty_interpolation (); } onAnimateInChanged: { updateProperty_interpolation (); } onAnimateOutChanged: { updateProperty_interpolation (); } }
54    Connections { target: filter; onChanged: setControls(); onInChanged: { updateProperty_projection (); } onOutChanged: { updateProperty_projection (); } onAnimateInChanged: { updateProperty_projection (); } onAnimateOutChanged: { updateProperty_projection (); } }
55
56    Component.onCompleted: {
57        if (filter.isNew) { filter.set("yaw", 0); } else { yawMiddle = filter.getDouble("yaw", filter.animateIn); if (filter.animateIn > 0) { yawStart = filter.getDouble("yaw", 0); } if (filter.animateOut > 0) { yawEnd = filter.getDouble("yaw", filter.duration - 1); } }
58        if (filter.isNew) { filter.set("pitch", 0); } else { pitchMiddle = filter.getDouble("pitch", filter.animateIn); if (filter.animateIn > 0) { pitchStart = filter.getDouble("pitch", 0); } if (filter.animateOut > 0) { pitchEnd = filter.getDouble("pitch", filter.duration - 1); } }
59        if (filter.isNew) { filter.set("roll", 0); } else { rollMiddle = filter.getDouble("roll", filter.animateIn); if (filter.animateIn > 0) { rollStart = filter.getDouble("roll", 0); } if (filter.animateOut > 0) { rollEnd = filter.getDouble("roll", filter.duration - 1); } }
60        if (filter.isNew) { filter.set("frontX", 0.75); } else { frontXMiddle = filter.getDouble("frontX", filter.animateIn); if (filter.animateIn > 0) { frontXStart = filter.getDouble("frontX", 0); } if (filter.animateOut > 0) { frontXEnd = filter.getDouble("frontX", filter.duration - 1); } }
61        if (filter.isNew) { filter.set("frontY", 0.5); } else { frontYMiddle = filter.getDouble("frontY", filter.animateIn); if (filter.animateIn > 0) { frontYStart = filter.getDouble("frontY", 0); } if (filter.animateOut > 0) { frontYEnd = filter.getDouble("frontY", filter.duration - 1); } }
62        if (filter.isNew) { filter.set("frontUp", 90); } else { frontUpMiddle = filter.getDouble("frontUp", filter.animateIn); if (filter.animateIn > 0) { frontUpStart = filter.getDouble("frontUp", 0); } if (filter.animateOut > 0) { frontUpEnd = filter.getDouble("frontUp", filter.duration - 1); } }
63        if (filter.isNew) { filter.set("backX", 0.25); } else { backXMiddle = filter.getDouble("backX", filter.animateIn); if (filter.animateIn > 0) { backXStart = filter.getDouble("backX", 0); } if (filter.animateOut > 0) { backXEnd = filter.getDouble("backX", filter.duration - 1); } }
64        if (filter.isNew) { filter.set("backY", 0.5); } else { backYMiddle = filter.getDouble("backY", filter.animateIn); if (filter.animateIn > 0) { backYStart = filter.getDouble("backY", 0); } if (filter.animateOut > 0) { backYEnd = filter.getDouble("backY", filter.duration - 1); } }
65        if (filter.isNew) { filter.set("backUp", 270); } else { backUpMiddle = filter.getDouble("backUp", filter.animateIn); if (filter.animateIn > 0) { backUpStart = filter.getDouble("backUp", 0); } if (filter.animateOut > 0) { backUpEnd = filter.getDouble("backUp", filter.duration - 1); } }
66
67        if (filter.isNew) { filter.set("fov", 180); } else { fovMiddle = filter.getDouble("fov", filter.animateIn); if (filter.animateIn > 0) { fovStart = filter.getDouble("fov", 0); } if (filter.animateOut > 0) { fovEnd = filter.getDouble("fov", filter.duration - 1); } }
68        if (filter.isNew) { filter.set("radius", 0.25); } else { radiusMiddle = filter.getDouble("radius", filter.animateIn); if (filter.animateIn > 0) { radiusStart = filter.getDouble("radius", 0); } if (filter.animateOut > 0) { radiusEnd = filter.getDouble("radius", filter.duration - 1); } }
69
70        if (filter.isNew) { filter.set("nadirRadius", 0.2229); } else { nadirRadiusMiddle = filter.getDouble("nadirRadius", filter.animateIn); if (filter.animateIn > 0) { nadirRadiusStart = filter.getDouble("nadirRadius", 0); } if (filter.animateOut > 0) { nadirRadiusEnd = filter.getDouble("nadirRadius", filter.duration - 1); } }
71        if (filter.isNew) { filter.set("nadirCorrectionStart", 0.8); } else { nadirCorrectionStartMiddle = filter.getDouble("nadirCorrectionStart", filter.animateIn); if (filter.animateIn > 0) { nadirCorrectionStartStart = filter.getDouble("nadirCorrectionStart", 0); } if (filter.animateOut > 0) { nadirCorrectionStartEnd = filter.getDouble("nadirCorrectionStart", filter.duration - 1); } }
72
73        if (filter.isNew) { filter.set("interpolation", 1); } else { interpolationValue = filter.get("interpolation"); }
74        if (filter.isNew) { filter.set("projection", 0); } else { projectionValue = filter.get("projection"); }
75
76        if (filter.isNew) {
77            filter.savePreset(preset.parameters)
78        }
79        setControls()
80    }
81
82    function setControls() {
83        var position = getPosition()
84        blockUpdate = true
85        yawSlider.value = filter.getDouble("yaw", position)
86        yawKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("yaw") > 0
87        pitchSlider.value = filter.getDouble("pitch", position)
88        pitchKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("pitch") > 0
89        rollSlider.value = filter.getDouble("roll", position)
90        rollKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("roll") > 0
91        frontXSlider.value = filter.getDouble("frontX", position)
92        frontXKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("frontX") > 0
93        frontYSlider.value = filter.getDouble("frontY", position)
94        frontYKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("frontY") > 0
95        frontUpSlider.value = filter.getDouble("frontUp", position)
96        frontUpKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("frontUp") > 0
97        backXSlider.value = filter.getDouble("backX", position)
98        backXKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("backX") > 0
99        backYSlider.value = filter.getDouble("backY", position)
100        backYKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("backY") > 0
101        backUpSlider.value = filter.getDouble("backUp", position)
102        backUpKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("backUp") > 0
103        fovSlider.value = filter.getDouble("fov", position)
104        fovKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("fov") > 0
105        radiusSlider.value = filter.getDouble("radius", position)
106        radiusKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("radius") > 0
107        nadirRadiusSlider.value = filter.getDouble("nadirRadius", position)
108        nadirRadiusKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("nadirRadius") > 0
109        nadirCorrectionStartSlider.value = filter.getDouble("nadirCorrectionStart", position)
110        nadirCorrectionStartKeyframesButton.checked = filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("nadirCorrectionStart") > 0
111        interpolationComboBox.currentIndex = filter.get("interpolation")
112        projectionComboBox.currentIndex = filter.get("projection")
113
114        blockUpdate = false
115    }
116
117    function updateProperty_yaw (position) { if (blockUpdate) return; var value = yawSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { yawStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { yawEnd = value; } else { yawMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("yaw"); yawKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("yaw", yawStart, 0); filter.set("yaw", yawMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("yaw", yawMiddle, filter.duration - filter.animateOut); filter.set("yaw", yawEnd, filter.duration - 1); } } else if (!yawKeyframesButton.checked) { filter.resetProperty("yaw"); filter.set("yaw", yawMiddle); } else if (position !== null) { filter.set("yaw", value, position); } }
118    function updateProperty_pitch (position) { if (blockUpdate) return; var value = pitchSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { pitchStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { pitchEnd = value; } else { pitchMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("pitch"); pitchKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("pitch", pitchStart, 0); filter.set("pitch", pitchMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("pitch", pitchMiddle, filter.duration - filter.animateOut); filter.set("pitch", pitchEnd, filter.duration - 1); } } else if (!pitchKeyframesButton.checked) { filter.resetProperty("pitch"); filter.set("pitch", pitchMiddle); } else if (position !== null) { filter.set("pitch", value, position); } }
119    function updateProperty_roll (position) { if (blockUpdate) return; var value = rollSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { rollStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { rollEnd = value; } else { rollMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("roll"); rollKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("roll", rollStart, 0); filter.set("roll", rollMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("roll", rollMiddle, filter.duration - filter.animateOut); filter.set("roll", rollEnd, filter.duration - 1); } } else if (!rollKeyframesButton.checked) { filter.resetProperty("roll"); filter.set("roll", rollMiddle); } else if (position !== null) { filter.set("roll", value, position); } }
120
121    function updateProperty_frontX (position) { if (blockUpdate) return; var value = frontXSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { frontXStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { frontXEnd = value; } else { frontXMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontX"); frontXKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("frontX", frontXStart, 0); filter.set("frontX", frontXMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("frontX", frontXMiddle, filter.duration - filter.animateOut); filter.set("frontX", frontXEnd, filter.duration - 1); } } else if (!frontXKeyframesButton.checked) { filter.resetProperty("frontX"); filter.set("frontX", frontXMiddle); } else if (position !== null) { filter.set("frontX", value, position); } }
122    function updateProperty_frontY (position) { if (blockUpdate) return; var value = frontYSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { frontYStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { frontYEnd = value; } else { frontYMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontY"); frontYKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("frontY", frontYStart, 0); filter.set("frontY", frontYMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("frontY", frontYMiddle, filter.duration - filter.animateOut); filter.set("frontY", frontYEnd, filter.duration - 1); } } else if (!frontYKeyframesButton.checked) { filter.resetProperty("frontY"); filter.set("frontY", frontYMiddle); } else if (position !== null) { filter.set("frontY", value, position); } }
123    function updateProperty_frontUp (position) { if (blockUpdate) return; var value = frontUpSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { frontUpStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { frontUpEnd = value; } else { frontUpMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontUp"); frontUpKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("frontUp", frontUpStart, 0); filter.set("frontUp", frontUpMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("frontUp", frontUpMiddle, filter.duration - filter.animateOut); filter.set("frontUp", frontUpEnd, filter.duration - 1); } } else if (!frontUpKeyframesButton.checked) { filter.resetProperty("frontUp"); filter.set("frontUp", frontUpMiddle); } else if (position !== null) { filter.set("frontUp", value, position); } }
124
125    function updateProperty_backX (position) { if (blockUpdate) return; var value = backXSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { backXStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { backXEnd = value; } else { backXMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backX"); backXKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("backX", backXStart, 0); filter.set("backX", backXMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("backX", backXMiddle, filter.duration - filter.animateOut); filter.set("backX", backXEnd, filter.duration - 1); } } else if (!backXKeyframesButton.checked) { filter.resetProperty("backX"); filter.set("backX", backXMiddle); } else if (position !== null) { filter.set("backX", value, position); } }
126    function updateProperty_backY (position) { if (blockUpdate) return; var value = backYSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { backYStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { backYEnd = value; } else { backYMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backY"); backYKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("backY", backYStart, 0); filter.set("backY", backYMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("backY", backYMiddle, filter.duration - filter.animateOut); filter.set("backY", backYEnd, filter.duration - 1); } } else if (!backYKeyframesButton.checked) { filter.resetProperty("backY"); filter.set("backY", backYMiddle); } else if (position !== null) { filter.set("backY", value, position); } }
127    function updateProperty_backUp (position) { if (blockUpdate) return; var value = backUpSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { backUpStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { backUpEnd = value; } else { backUpMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backUp"); backUpKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("backUp", backUpStart, 0); filter.set("backUp", backUpMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("backUp", backUpMiddle, filter.duration - filter.animateOut); filter.set("backUp", backUpEnd, filter.duration - 1); } } else if (!backUpKeyframesButton.checked) { filter.resetProperty("backUp"); filter.set("backUp", backUpMiddle); } else if (position !== null) { filter.set("backUp", value, position); } }
128
129    function updateProperty_fov (position) { if (blockUpdate) return; var value = fovSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { fovStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { fovEnd = value; } else { fovMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("fov"); fovKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("fov", fovStart, 0); filter.set("fov", fovMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("fov", fovMiddle, filter.duration - filter.animateOut); filter.set("fov", fovEnd, filter.duration - 1); } } else if (!fovKeyframesButton.checked) { filter.resetProperty("fov"); filter.set("fov", fovMiddle); } else if (position !== null) { filter.set("fov", value, position); } }
130    function updateProperty_radius (position) { if (blockUpdate) return; var value = radiusSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { radiusStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { radiusEnd = value; } else { radiusMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("radius"); radiusKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("radius", radiusStart, 0); filter.set("radius", radiusMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("radius", radiusMiddle, filter.duration - filter.animateOut); filter.set("radius", radiusEnd, filter.duration - 1); } } else if (!radiusKeyframesButton.checked) { filter.resetProperty("radius"); filter.set("radius", radiusMiddle); } else if (position !== null) { filter.set("radius", value, position); } }
131    function updateProperty_nadirRadius (position) { if (blockUpdate) return; var value = nadirRadiusSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { nadirRadiusStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { nadirRadiusEnd = value; } else { nadirRadiusMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("nadirRadius"); nadirRadiusKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("nadirRadius", nadirRadiusStart, 0); filter.set("nadirRadius", nadirRadiusMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("nadirRadius", nadirRadiusMiddle, filter.duration - filter.animateOut); filter.set("nadirRadius", nadirRadiusEnd, filter.duration - 1); } } else if (!nadirRadiusKeyframesButton.checked) { filter.resetProperty("nadirRadius"); filter.set("nadirRadius", nadirRadiusMiddle); } else if (position !== null) { filter.set("nadirRadius", value, position); } }
132    function updateProperty_nadirCorrectionStart (position) { if (blockUpdate) return; var value = nadirCorrectionStartSlider.value; if (position !== null) { if (position <= 0 && filter.animateIn > 0) { nadirCorrectionStartStart = value; } else if (position >= filter.duration - 1 && filter.animateOut > 0) { nadirCorrectionStartEnd = value; } else { nadirCorrectionStartMiddle = value; } } if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("nadirCorrectionStart"); nadirCorrectionStartKeyframesButton.checked = false; if (filter.animateIn > 0) { filter.set("nadirCorrectionStart", nadirCorrectionStartStart, 0); filter.set("nadirCorrectionStart", nadirCorrectionStartMiddle, filter.animateIn - 1); } if (filter.animateOut > 0) { filter.set("nadirCorrectionStart", nadirCorrectionStartMiddle, filter.duration - filter.animateOut); filter.set("nadirCorrectionStart", nadirCorrectionStartEnd, filter.duration - 1); } } else if (!nadirCorrectionStartKeyframesButton.checked) { filter.resetProperty("nadirCorrectionStart"); filter.set("nadirCorrectionStart", nadirCorrectionStartMiddle); } else if (position !== null) { filter.set("nadirCorrectionStart", value, position); } }
133
134    function updateProperty_interpolation () { if (blockUpdate) return; var value = interpolationComboBox.currentIndex; filter.set("interpolation", value); }
135    function updateProperty_projection () { if (blockUpdate) return; var value = projectionComboBox.currentIndex; filter.set("projection", value); }
136
137    function getPosition() {
138        return Math.max(producer.position - (filter.in - producer.in), 0)
139    }
140
141    GridLayout {
142        columns: 4
143        anchors.fill: parent
144        anchors.margins: 8
145
146        Label {
147            text: qsTr('Preset')
148            Layout.alignment: Qt.AlignRight
149        }
150        Shotcut.Preset {
151            id: preset
152            parameters: ["yaw", "pitch", "roll", "frontX", "frontY", "frontUp", "backX", "backY", "backUp", "fov", "radius", "nadirRadius", "nadirCorrectionStart", "interpolation", "projection"]
153            Layout.columnSpan: 3
154            onBeforePresetLoaded: {
155                filter.resetProperty('yaw')
156                filter.resetProperty('pitch')
157                filter.resetProperty('roll')
158                filter.resetProperty('frontX')
159                filter.resetProperty('frontY')
160                filter.resetProperty('frontUp')
161                filter.resetProperty('backX')
162                filter.resetProperty('backY')
163                filter.resetProperty('backUp')
164                filter.resetProperty('fov')
165                filter.resetProperty('radius')
166                filter.resetProperty('nadirRadius')
167                filter.resetProperty('nadirCorrectionStart')
168                filter.resetProperty('interpolation')
169                filter.resetProperty('projection')
170            }
171            onPresetSelected: {
172                yawMiddle = filter.getDouble("yaw", filter.animateIn); if (filter.animateIn > 0) { yawStart = filter.getDouble("yaw", 0); } if (filter.animateOut > 0) { yawEnd = filter.getDouble("yaw", filter.duration - 1); }
173                pitchMiddle = filter.getDouble("pitch", filter.animateIn); if (filter.animateIn > 0) { pitchStart = filter.getDouble("pitch", 0); } if (filter.animateOut > 0) { pitchEnd = filter.getDouble("pitch", filter.duration - 1); }
174                rollMiddle = filter.getDouble("roll", filter.animateIn); if (filter.animateIn > 0) { rollStart = filter.getDouble("roll", 0); } if (filter.animateOut > 0) { rollEnd = filter.getDouble("roll", filter.duration - 1); }
175                frontXMiddle = filter.getDouble("frontX", filter.animateIn); if (filter.animateIn > 0) { frontXStart = filter.getDouble("frontX", 0); } if (filter.animateOut > 0) { frontXEnd = filter.getDouble("frontX", filter.duration - 1); }
176                frontYMiddle = filter.getDouble("frontY", filter.animateIn); if (filter.animateIn > 0) { frontYStart = filter.getDouble("frontY", 0); } if (filter.animateOut > 0) { frontYEnd = filter.getDouble("frontY", filter.duration - 1); }
177                frontUpMiddle = filter.getDouble("frontUp", filter.animateIn); if (filter.animateIn > 0) { frontUpStart = filter.getDouble("frontUp", 0); } if (filter.animateOut > 0) { frontUpEnd = filter.getDouble("frontUp", filter.duration - 1); }
178                backXMiddle = filter.getDouble("backX", filter.animateIn); if (filter.animateIn > 0) { backXStart = filter.getDouble("backX", 0); } if (filter.animateOut > 0) { backXEnd = filter.getDouble("backX", filter.duration - 1); }
179                backYMiddle = filter.getDouble("backY", filter.animateIn); if (filter.animateIn > 0) { backYStart = filter.getDouble("backY", 0); } if (filter.animateOut > 0) { backYEnd = filter.getDouble("backY", filter.duration - 1); }
180                backUpMiddle = filter.getDouble("backUp", filter.animateIn); if (filter.animateIn > 0) { backUpStart = filter.getDouble("backUp", 0); } if (filter.animateOut > 0) { backUpEnd = filter.getDouble("backUp", filter.duration - 1); }
181                fovMiddle = filter.getDouble("fov", filter.animateIn); if (filter.animateIn > 0) { fovStart = filter.getDouble("fov", 0); } if (filter.animateOut > 0) { fovEnd = filter.getDouble("fov", filter.duration - 1); }
182                radiusMiddle = filter.getDouble("radius", filter.animateIn); if (filter.animateIn > 0) { radiusStart = filter.getDouble("radius", 0); } if (filter.animateOut > 0) { radiusEnd = filter.getDouble("radius", filter.duration - 1); }
183                nadirRadiusMiddle = filter.getDouble("nadirRadius", filter.animateIn); if (filter.animateIn > 0) { nadirRadiusStart = filter.getDouble("nadirRadius", 0); } if (filter.animateOut > 0) { nadirRadiusEnd = filter.getDouble("nadirRadius", filter.duration - 1); }
184                nadirCorrectionStartMiddle = filter.getDouble("nadirCorrectionStart", filter.animateIn); if (filter.animateIn > 0) { nadirCorrectionStartStart = filter.getDouble("nadirCorrectionStart", 0); } if (filter.animateOut > 0) { nadirCorrectionStartEnd = filter.getDouble("nadirCorrectionStart", filter.duration - 1); }
185                interpolationValue = filter.get("interpolation");
186                projectionValue = filter.get("projection");
187                setControls(null);
188            }
189        }
190
191        Label {
192            text: qsTr('Interpolation')
193            Layout.alignment: Qt.AlignRight
194        }
195        Shotcut.ComboBox {
196            currentIndex: 0
197            model: ["Nearest-neighbor", "Bilinear"]
198            id: interpolationComboBox
199            Layout.columnSpan: 2
200            onCurrentIndexChanged: updateProperty_interpolation()
201        }
202        Shotcut.UndoButton {
203            id: interpolationUndo
204            onClicked: interpolationComboBox.currentIndex = 0
205        }
206
207        Label {
208            text: qsTr('Alignment')
209            Layout.alignment: Qt.AlignLeft
210            Layout.columnSpan: 4
211        }
212
213
214        Label {
215            text: qsTr('Yaw')
216            Layout.alignment: Qt.AlignRight
217        }
218        Shotcut.SliderSpinner {
219            id: yawSlider
220            minimumValue: -360
221            maximumValue: 360
222            spinnerWidth: 120; suffix: ' deg'; decimals: 3; stepSize: 1;
223            onValueChanged: updateProperty_yaw(getPosition())
224        }
225        Shotcut.KeyframesButton { id: yawKeyframesButton; onToggled: { var value = yawSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("yaw"); yawSlider.enabled = true; } filter.clearSimpleAnimation("yaw"); blockUpdate = false; filter.set("yaw", value, getPosition()); } else { filter.resetProperty("yaw"); filter.set("yaw", value); } } }
226        Shotcut.UndoButton {
227            id: yawUndo
228            onClicked: yawSlider.value = 0
229        }
230
231        Label {
232            text: qsTr('Pitch')
233            Layout.alignment: Qt.AlignRight
234        }
235        Shotcut.SliderSpinner {
236            id: pitchSlider
237            minimumValue: -180
238            maximumValue: 180
239            spinnerWidth: 120; suffix: ' deg'; decimals: 3; stepSize: 1;
240            onValueChanged: updateProperty_pitch(getPosition())
241        }
242        Shotcut.KeyframesButton { id: pitchKeyframesButton; checked: filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("pitch") > 0; onToggled: { var value = pitchSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("pitch"); pitchSlider.enabled = true; } filter.clearSimpleAnimation("pitch"); blockUpdate = false; filter.set("pitch", value, getPosition()); } else { filter.resetProperty("pitch"); filter.set("pitch", value); } } }
243        Shotcut.UndoButton {
244            id: pitchUndo
245            onClicked: pitchSlider.value = 0
246        }
247
248        Label {
249            text: qsTr('Roll')
250            Layout.alignment: Qt.AlignRight
251        }
252        Shotcut.SliderSpinner {
253            id: rollSlider
254            minimumValue: -180
255            maximumValue: 180
256            spinnerWidth: 120; suffix: ' deg'; decimals: 3; stepSize: 1;
257            onValueChanged: updateProperty_roll(getPosition())
258        }
259        Shotcut.KeyframesButton { id: rollKeyframesButton; onToggled: { var value = rollSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("roll"); rollSlider.enabled = true; } filter.clearSimpleAnimation("roll"); blockUpdate = false; filter.set("roll", value, getPosition()); } else { filter.resetProperty("roll"); filter.set("roll", value); } } }
260        Shotcut.UndoButton {
261            id: rollUndo
262            onClicked: rollSlider.value = 0
263        }
264
265        Label {
266            text: qsTr('Lens')
267            Layout.alignment: Qt.AlignLeft
268            Layout.columnSpan: 4
269        }
270
271        Label {
272            text: qsTr('Projection')
273            Layout.alignment: Qt.AlignRight
274        }
275        Shotcut.ComboBox {
276            currentIndex: 0
277            model: ["Equidistant Fisheye"]
278            id: projectionComboBox
279            Layout.columnSpan: 2
280            onCurrentIndexChanged: updateProperty_projection()
281        }
282        Shotcut.UndoButton {
283            id: projectionUndo
284            onClicked: projectionComboBox.currentIndex = 0
285        }
286
287        Label {
288            text: qsTr('FOV')
289            Layout.alignment: Qt.AlignRight
290        }
291        Shotcut.SliderSpinner {
292            id: fovSlider
293            minimumValue: 0
294            maximumValue: 360
295            spinnerWidth: 120
296            suffix: ' deg'
297            decimals: 4
298            stepSize: 0.0001
299            onValueChanged: updateProperty_fov(getPosition())
300        }
301        Shotcut.KeyframesButton { id: fovKeyframesButton; onToggled: { var value = fovSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("fov"); fovSlider.enabled = true; } filter.clearSimpleAnimation("fov"); blockUpdate = false; filter.set("fov", value, getPosition()); } else { filter.resetProperty("fov"); filter.set("fov", value); } } }
302        Shotcut.UndoButton {
303            id: fovUndo
304            onClicked: fovSlider.value = 180
305        }
306
307        Label {
308            text: qsTr('Radius')
309            Layout.alignment: Qt.AlignRight
310        }
311        Shotcut.SliderSpinner {
312            id: radiusSlider
313            minimumValue: 0
314            maximumValue: 1
315            suffix: ' '
316            decimals: 4
317            stepSize: 0.0001
318            onValueChanged: updateProperty_radius(getPosition())
319        }
320        Shotcut.KeyframesButton { id: radiusKeyframesButton; onToggled: { var value = radiusSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("radius"); radiusSlider.enabled = true; } filter.clearSimpleAnimation("radius"); blockUpdate = false; filter.set("radius", value, getPosition()); } else { filter.resetProperty("radius"); filter.set("radius", value); } } }
321        Shotcut.UndoButton {
322            id: radiusUndo
323            onClicked: radiusSlider.value = 0.25
324        }
325
326
327        Label {
328            text: qsTr('Front')
329            Layout.alignment: Qt.AlignLeft
330            Layout.columnSpan: 4
331        }
332
333        Label {
334            text: qsTr('X')
335            Layout.alignment: Qt.AlignRight
336        }
337        Shotcut.SliderSpinner {
338            id: frontXSlider
339            minimumValue: 0
340            maximumValue: 1
341            stepSize: 0.0001
342            decimals: 4
343            suffix: ' '
344            onValueChanged: updateProperty_frontX(getPosition())
345        }
346        Shotcut.KeyframesButton { id: frontXKeyframesButton; onToggled: { var value = frontXSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontX"); frontXSlider.enabled = true; } filter.clearSimpleAnimation("frontX"); blockUpdate = false; filter.set("frontX", value, getPosition()); } else { filter.resetProperty("frontX"); filter.set("frontX", value); } } }
347        Shotcut.UndoButton {
348            id: frontXUndo
349            onClicked: frontXSlider.value = 0.25
350        }
351
352        Label {
353            text: qsTr('Y')
354            Layout.alignment: Qt.AlignRight
355        }
356        Shotcut.SliderSpinner {
357            id: frontYSlider
358            minimumValue: 0
359            maximumValue: 1
360            stepSize: 0.0001
361            decimals: 4
362            suffix: ' '
363            onValueChanged: updateProperty_frontY(getPosition())
364        }
365        Shotcut.KeyframesButton { id: frontYKeyframesButton; onToggled: { var value = frontYSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontY"); frontYSlider.enabled = true; } filter.clearSimpleAnimation("frontY"); blockUpdate = false; filter.set("frontY", value, getPosition()); } else { filter.resetProperty("frontY"); filter.set("frontY", value); } } }
366        Shotcut.UndoButton {
367            id: frontYUndo
368            onClicked: frontYSlider.value = 0.25
369        }
370
371        Label {
372            text: qsTr('Up')
373            Layout.alignment: Qt.AlignRight
374        }
375        Shotcut.SliderSpinner {
376            id: frontUpSlider
377            minimumValue: 0
378            maximumValue: 360
379            spinnerWidth: 120; suffix: ' deg'; decimals: 3; stepSize: 1;
380            onValueChanged: updateProperty_frontUp(getPosition())
381        }
382        Shotcut.KeyframesButton { id: frontUpKeyframesButton; checked: filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("frontUp") > 0; onToggled: { var value = frontUpSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("frontUp"); frontUpSlider.enabled = true; } filter.clearSimpleAnimation("frontUp"); blockUpdate = false; filter.set("frontUp", value, getPosition()); } else { filter.resetProperty("frontUp"); filter.set("frontUp", value); } } }
383        Shotcut.UndoButton {
384            id: frontUpUndo
385            onClicked: frontUpSlider.value = 90
386        }
387
388
389        Label {
390            text: qsTr('Back')
391            Layout.alignment: Qt.AlignLeft
392            Layout.columnSpan: 4
393        }
394
395        Label {
396            text: qsTr('X')
397            Layout.alignment: Qt.AlignRight
398        }
399        Shotcut.SliderSpinner {
400            id: backXSlider
401            minimumValue: 0
402            maximumValue: 1
403            stepSize: 0.0001
404            decimals: 4
405            suffix: ' '
406            onValueChanged: updateProperty_backX(getPosition())
407        }
408        Shotcut.KeyframesButton { id: backXKeyframesButton; onToggled: { var value = backXSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backX"); backXSlider.enabled = true; } filter.clearSimpleAnimation("backX"); blockUpdate = false; filter.set("backX", value, getPosition()); } else { filter.resetProperty("backX"); filter.set("backX", value); } } }
409        Shotcut.UndoButton {
410            id: backXUndo
411            onClicked: backXSlider.value = 0.25
412        }
413
414        Label {
415            text: qsTr('Y')
416            Layout.alignment: Qt.AlignRight
417        }
418        Shotcut.SliderSpinner {
419            id: backYSlider
420            minimumValue: 0
421            maximumValue: 1
422            stepSize: 0.0001
423            decimals: 4
424            suffix: ' '
425            onValueChanged: updateProperty_backY(getPosition())
426        }
427        Shotcut.KeyframesButton { id: backYKeyframesButton; onToggled: { var value = backYSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backY"); backYSlider.enabled = true; } filter.clearSimpleAnimation("backY"); blockUpdate = false; filter.set("backY", value, getPosition()); } else { filter.resetProperty("backY"); filter.set("backY", value); } } }
428        Shotcut.UndoButton {
429            id: backYUndo
430            onClicked: backYSlider.value = 0.25
431        }
432
433        Label {
434            text: qsTr('Up')
435            Layout.alignment: Qt.AlignRight
436        }
437        Shotcut.SliderSpinner {
438            id: backUpSlider
439            minimumValue: 0
440            maximumValue: 360
441            spinnerWidth: 120; suffix: ' deg'; decimals: 3; stepSize: 1;
442            onValueChanged: updateProperty_backUp(getPosition())
443        }
444        Shotcut.KeyframesButton { id: backUpKeyframesButton; checked: filter.animateIn <= 0 && filter.animateOut <= 0 && filter.keyframeCount("backUp") > 0; onToggled: { var value = backUpSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("backUp"); backUpSlider.enabled = true; } filter.clearSimpleAnimation("backUp"); blockUpdate = false; filter.set("backUp", value, getPosition()); } else { filter.resetProperty("backUp"); filter.set("backUp", value); } } }
445        Shotcut.UndoButton {
446            id: backUpUndo
447            onClicked: backUpSlider.value = 90
448        }
449
450
451        Label {
452            text: qsTr('Nadir')
453            Layout.alignment: Qt.AlignLeft
454            Layout.columnSpan: 4
455        }
456
457
458        Label {
459            text: qsTr('Radius')
460            Layout.alignment: Qt.AlignRight
461        }
462        Shotcut.SliderSpinner {
463            id: nadirRadiusSlider
464            minimumValue: 0
465            maximumValue: 1
466            suffix: ' '
467            decimals: 4
468            stepSize: 0.0001
469            onValueChanged: updateProperty_nadirRadius(getPosition())
470        }
471        Shotcut.KeyframesButton { id: nadirRadiusKeyframesButton; onToggled: { var value = nadirRadiusSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("nadirRadius"); nadirRadiusSlider.enabled = true; } filter.clearSimpleAnimation("nadirRadius"); blockUpdate = false; filter.set("nadirRadius", value, getPosition()); } else { filter.resetProperty("nadirRadius"); filter.set("nadirRadius", value); } } }
472        Shotcut.UndoButton {
473            id: nadirRadiusUndo
474            onClicked: nadirRadiusSlider.value = 0.2229
475        }
476
477        Label {
478            text: qsTr('Start')
479            Layout.alignment: Qt.AlignRight
480        }
481        Shotcut.SliderSpinner {
482            id: nadirCorrectionStartSlider
483            minimumValue: 0
484            maximumValue: 1
485            suffix: ' '
486            decimals: 4
487            stepSize: 0.0001
488            onValueChanged: updateProperty_nadirCorrectionStart(getPosition())
489        }
490        Shotcut.KeyframesButton { id: nadirCorrectionStartKeyframesButton; onToggled: { var value = nadirCorrectionStartSlider.value; if (checked) { blockUpdate = true; if (filter.animateIn > 0 || filter.animateOut > 0) { filter.resetProperty("nadirCorrectionStart"); nadirCorrectionStartSlider.enabled = true; } filter.clearSimpleAnimation("nadirCorrectionStart"); blockUpdate = false; filter.set("nadirCorrectionStart", value, getPosition()); } else { filter.resetProperty("nadirCorrectionStart"); filter.set("nadirCorrectionStart", value); } } }
491        Shotcut.UndoButton {
492            id: nadirCorrectionStartUndo
493            onClicked: radiusSlider.value = 0.8
494        }
495        Item {
496            Layout.fillHeight: true
497        }
498    }
499
500    Connections {
501        target: producer
502        onPositionChanged: setControls()
503    }
504}
505