1/*
2    SPDX-FileCopyrightText: 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
3    SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
4*/
5
6import QtQuick 2.11
7
8Item {
9    id: root
10    objectName: "rootcornerscene"
11    SystemPalette { id: activePalette }
12
13    // default size, but scalable by user
14    height: 300; width: 400
15    property string comment
16    property string framenum
17    property rect framesize
18    property point profile: controller.profile
19    property int overlayType: controller.overlayType
20    property color overlayColor: 'cyan'
21    property point center
22    property double scalex
23    property double scaley
24    property bool captureRightClick: false
25    // Zoombar properties
26    property double zoomStart: 0
27    property double zoomFactor: 1
28    property int zoomOffset: 0
29    property bool showZoomBar: false
30    property double stretch : 1
31    property double sourcedar : 1
32    onScalexChanged: canvas.requestPaint()
33    onScaleyChanged: canvas.requestPaint()
34    property double offsetx : 0
35    property double offsety : 0
36    onOffsetxChanged: canvas.requestPaint()
37    onOffsetyChanged: canvas.requestPaint()
38    onSourcedarChanged: refreshdar()
39    property bool iskeyframe
40    property int requestedKeyFrame
41    property real baseUnit: fontMetrics.font.pixelSize * 0.8
42    property int duration: 300
43    property int mouseRulerPos: 0
44    property double frameSize: 10
45    property double timeScale: 1
46    property var centerPoints: []
47    onCenterPointsChanged: canvas.requestPaint()
48    signal effectPolygonChanged()
49
50    function refreshdar() {
51        canvas.darOffset = root.sourcedar < root.profile.x * root.stretch / root.profile.y ? (root.profile.x * root.stretch - root.profile.y * root.sourcedar) / (2 * root.profile.x * root.stretch) :(root.profile.y - root.profile.x * root.stretch / root.sourcedar) / (2 * root.profile.y);
52        canvas.requestPaint()
53    }
54
55    onDurationChanged: {
56        clipMonitorRuler.updateRuler()
57    }
58    onWidthChanged: {
59        clipMonitorRuler.updateRuler()
60    }
61
62    FontMetrics {
63        id: fontMetrics
64        font.family: "Arial"
65    }
66
67    Canvas {
68      id: canvas
69      property double handleSize
70      property double darOffset : 0
71      width: root.width
72      height: root.height
73      anchors.centerIn: root
74      contextType: "2d";
75      handleSize: root.baseUnit / 2
76      renderTarget: Canvas.FramebufferObject
77      renderStrategy: Canvas.Cooperative
78      onPaint:
79      {
80        var ctx = getContext('2d')
81        //if (context) {
82            ctx.clearRect(0,0, width, height);
83            ctx.beginPath()
84            ctx.strokeStyle = Qt.rgba(1, 0, 0, 0.5)
85            ctx.fillStyle = Qt.rgba(1, 0, 0, 0.5)
86            ctx.lineWidth = 2
87            var p1 = convertPoint(root.centerPoints[0])
88            var p2 = convertPoint(root.centerPoints[1])
89            var p3 = convertPoint(root.centerPoints[2])
90            var p4 = convertPoint(root.centerPoints[3])
91            //console.log('paint' + p1);
92
93          // Handles
94          if (root.iskeyframe == true) {
95            if (root.requestedKeyFrame == 0) {
96                ctx.fillStyle = Qt.rgba(1, 1, 0, 1)
97                ctx.fillRect(p1.x - handleSize, p1.y - handleSize, 2 * handleSize, 2 * handleSize);
98                ctx.fillStyle = Qt.rgba(1, 0, 0, 0.5)
99            }
100            else ctx.fillRect(p1.x - handleSize, p1.y - handleSize, 2 * handleSize, 2 * handleSize);
101            if (root.requestedKeyFrame == 1) {
102                ctx.fillStyle = Qt.rgba(1, 1, 0, 1)
103                ctx.fillRect(p2.x - handleSize, p2.y - handleSize, 2 * handleSize, 2 * handleSize);
104                ctx.fillStyle = Qt.rgba(1, 0, 0, 0.5)
105            }
106            else ctx.fillRect(p2.x - handleSize, p2.y - handleSize, 2 * handleSize, 2 * handleSize);
107            if (root.requestedKeyFrame == 2) {
108                ctx.fillStyle = Qt.rgba(1, 1, 0, 1)
109                ctx.fillRect(p3.x - handleSize, p3.y - handleSize, 2 * handleSize, 2 * handleSize);
110                ctx.fillStyle = Qt.rgba(1, 0, 0, 0.5)
111            }
112            else ctx.fillRect(p3.x - handleSize, p3.y - handleSize, 2 * handleSize, 2 * handleSize);
113            if (root.requestedKeyFrame == 3) {
114                ctx.fillStyle = Qt.rgba(1, 1, 0, 1)
115                ctx.fillRect(p4.x - handleSize, p4.y - handleSize, 2 * handleSize, 2 * handleSize);
116                ctx.fillStyle = Qt.rgba(1, 0, 0, 0.5)
117            }
118            else ctx.fillRect(p4.x - handleSize, p4.y - handleSize, 2 * handleSize, 2 * handleSize);
119          }
120          // Rect
121          ctx.moveTo(p1.x, p1.y)
122          ctx.lineTo(p2.x, p2.y)
123          ctx.lineTo(p3.x, p3.y)
124          ctx.lineTo(p4.x, p4.y)
125          ctx.lineTo(p1.x, p1.y)
126
127          // Source rect
128          if (canvas.darOffset != 0 && root.sourcedar > 0) {
129              if (root.sourcedar < root.profile.x / root.profile.y) {
130                  // vertical bars
131                  ctx.moveTo(p1.x + (darOffset * (p2.x - p1.x)), p1.y + (darOffset * (p2.y - p1.y)))
132                  ctx.lineTo(p4.x + (darOffset * (p3.x - p4.x)), p4.y + (darOffset * (p3.y-p4.y)))
133                  ctx.moveTo(p2.x + (darOffset * (p1.x - p2.x)), p2.y + (darOffset * (p1.y - p2.y)))
134                  ctx.lineTo(p3.x + (darOffset * (p4.x - p3.x)), p3.y + (darOffset * (p4.y-p3.y)))
135              } else {
136                  // horizontal bars
137                  ctx.moveTo(p1.x + (darOffset * (p4.x - p1.x)), p1.y + (darOffset * (p4.y - p1.y)))
138                  ctx.lineTo(p2.x + (darOffset * (p3.x - p2.x)), p2.y + (darOffset * (p3.y-p2.y)))
139                  ctx.moveTo(p4.x + (darOffset * (p1.x - p4.x)), p4.y + (darOffset * (p1.y - p4.y)))
140                  ctx.lineTo(p3.x + (darOffset * (p2.x - p3.x)), p3.y + (darOffset * (p2.y-p3.y)))
141              }
142          }
143          ctx.stroke()
144            //ctx.restore()
145        //}
146    }
147
148    function convertPoint(p)
149    {
150        var x = frame.x + p.x * root.scalex
151        var y = frame.y + p.y * root.scaley
152        return Qt.point(x,y);
153    }
154  }
155    Rectangle {
156        id: frame
157        objectName: "referenceframe"
158        property color hoverColor: "#ff0000"
159        width: root.profile.x * root.scalex
160        height: root.profile.y * root.scaley
161        x: root.center.x - width / 2 - root.offsetx
162        y: root.center.y - height / 2 - root.offsety
163        color: "transparent"
164        border.color: "#ffffff00"
165        Loader {
166            anchors.fill: parent
167            source: {
168                switch(root.overlayType)
169                {
170                    case 0:
171                        return '';
172                    case 1:
173                        return "OverlayStandard.qml";
174                    case 2:
175                        return "OverlayMinimal.qml";
176                    case 3:
177                        return "OverlayCenter.qml";
178                    case 4:
179                        return "OverlayCenterDiagonal.qml";
180                    case 5:
181                        return "OverlayThirds.qml";
182                }
183            }
184        }
185    }
186    MouseArea {
187        id: global
188        objectName: "global"
189        width: root.width; height: root.height
190        property bool containsMouse
191        anchors.centerIn: root
192        hoverEnabled: true
193        cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
194        onWheel: {
195            controller.seek(wheel.angleDelta.x + wheel.angleDelta.y, wheel.modifiers)
196        }
197        onDoubleClicked: {
198            controller.addRemoveKeyframe()
199        }
200
201        onPositionChanged: {
202            if (root.iskeyframe == false) return;
203            if (pressed && root.requestedKeyFrame >= 0) {
204                root.centerPoints[root.requestedKeyFrame].x = (mouseX - frame.x) / root.scalex;
205                root.centerPoints[root.requestedKeyFrame].y = (mouseY - frame.y) / root.scaley;
206                canvas.requestPaint()
207                root.effectPolygonChanged()
208            } else {
209              for(var i = 0; i < root.centerPoints.length; i++)
210              {
211                var p1 = canvas.convertPoint(root.centerPoints[i])
212                if (Math.abs(p1.x - mouseX) <= canvas.handleSize && Math.abs(p1.y - mouseY) <= canvas.handleSize) {
213                    if (i == root.requestedKeyFrame) {
214                        containsMouse = true;
215                        return;
216                    }
217                    root.requestedKeyFrame = i
218                    canvas.requestPaint()
219                    containsMouse = true;
220                    return;
221                }
222              }
223              if (root.requestedKeyFrame == -1) {
224                  return;
225              }
226              root.requestedKeyFrame = -1
227              containsMouse = false;
228              canvas.requestPaint()
229            }
230        }
231    }
232    EffectToolBar {
233        id: effectToolBar
234        anchors {
235            right: parent.right
236            top: parent.top
237            bottom: parent.bottom
238            rightMargin: 4
239            leftMargin: 4
240        }
241    }
242    MonitorRuler {
243        id: clipMonitorRuler
244        anchors {
245            left: root.left
246            right: root.right
247            bottom: root.bottom
248        }
249        height: controller.rulerHeight
250    }
251}
252