Warning, /multimedia/kdenlive/src/monitor/view/kdenlivemonitoreffectscene.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2015 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005
0006 import QtQuick 2.15
0007
0008 Item {
0009 id: root
0010 objectName: "rooteffectscene"
0011 SystemPalette { id: activePalette }
0012
0013 // default size, but scalable by user
0014 height: 300; width: 400
0015 property string comment
0016 property string framenum
0017 property rect framesize
0018 property rect adjustedFrame
0019 property point profile: controller.profile
0020 property int overlayType: controller.overlayType
0021 property color overlayColor: controller.overlayColor
0022 property point center
0023 property double scalex
0024 property double scaley
0025 property bool captureRightClick: false
0026 // Zoombar properties
0027 property double zoomStart: 0
0028 property double zoomFactor: 1
0029 property int zoomOffset: 0
0030 property bool showZoomBar: false
0031 property double offsetx : 0
0032 property double offsety : 0
0033 property double lockratio : -1
0034 property double timeScale: 1
0035 property double frameSize: 10
0036 property int duration: 300
0037 property real baseUnit: fontMetrics.font.pixelSize * 0.8
0038 property int mouseRulerPos: 0
0039 onScalexChanged: canvas.requestPaint()
0040 onScaleyChanged: canvas.requestPaint()
0041 onOffsetxChanged: canvas.requestPaint()
0042 onOffsetyChanged: canvas.requestPaint()
0043 property bool iskeyframe
0044 property int requestedKeyFrame: 0
0045 property var centerPoints: []
0046 property var centerPointsTypes: []
0047 onCenterPointsChanged: canvas.requestPaint()
0048 signal effectChanged()
0049 signal centersChanged()
0050
0051 function updateClickCapture() {
0052 root.captureRightClick = false
0053 }
0054
0055 onDurationChanged: {
0056 clipMonitorRuler.updateRuler()
0057 }
0058 onWidthChanged: {
0059 clipMonitorRuler.updateRuler()
0060 }
0061
0062 FontMetrics {
0063 id: fontMetrics
0064 font.family: "Arial"
0065 }
0066
0067 Canvas {
0068 id: canvas
0069 property double handleSize
0070 width: root.width
0071 height: root.height
0072 anchors.centerIn: root
0073 contextType: "2d";
0074 handleSize: root.baseUnit / 2
0075 renderStrategy: Canvas.Threaded;
0076 onPaint:
0077 {
0078 if (context && root.centerPoints.length > 0) {
0079 context.beginPath()
0080 context.strokeStyle = Qt.rgba(1, 0, 0, 0.5)
0081 context.fillStyle = Qt.rgba(1, 0, 0, 1)
0082 context.lineWidth = 1
0083 context.setLineDash([3,3])
0084 var p1 = convertPoint(root.centerPoints[0])
0085 context.moveTo(p1.x, p1.y)
0086 context.clearRect(0,0, width, height);
0087 for(var i = 0; i < root.centerPoints.length; i++)
0088 {
0089 context.translate(p1.x, p1.y)
0090 context.rotate(Math.PI/4);
0091 context.fillRect(- handleSize, 0, 2 * handleSize, 1);
0092 context.fillRect(0, - handleSize, 1, 2 * handleSize);
0093 context.rotate(-Math.PI/4);
0094 context.translate(-p1.x, -p1.y)
0095 if (i + 1 < root.centerPoints.length)
0096 {
0097 var end = convertPoint(root.centerPoints[i + 1])
0098
0099 if (root.centerPointsTypes.length != root.centerPoints.length || root.centerPointsTypes[i] == 0) {
0100 context.lineTo(end.x, end.y)
0101 p1 = end
0102 continue
0103 }
0104
0105 var j = i - 1
0106 if (j < 0) {
0107 j = 0
0108 }
0109 var pre = convertPoint(root.centerPoints[j])
0110 j = i + 2
0111 if (j >= root.centerPoints.length) {
0112 j = root.centerPoints.length - 1
0113 }
0114 var post = convertPoint(root.centerPoints[j])
0115 var c1 = substractPoints(end, pre, 6.0)
0116 var c2 = substractPoints(p1, post, 6.0)
0117 c1 = addPoints(c1, p1)
0118 c2 = addPoints(c2, end)
0119 context.bezierCurveTo(c1.x, c1.y, c2.x, c2.y, end.x, end.y);
0120 } else {
0121 context.lineTo(p1.x, p1.y)
0122 }
0123 p1 = end
0124 }
0125 context.stroke()
0126 context.restore()
0127 }
0128 }
0129
0130 function convertPoint(p)
0131 {
0132 var x = frame.x + p.x * root.scalex
0133 var y = frame.y + p.y * root.scaley
0134 return Qt.point(x,y);
0135 }
0136 function addPoints(p1, p2)
0137 {
0138 var x = p1.x + p2.x
0139 var y = p1.y + p2.y
0140 return Qt.point(x,y);
0141 }
0142 function distance(p1, p2)
0143 {
0144 var x = p1.x + p2.x
0145 var y = p1.y + p2.y
0146 return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
0147 }
0148 function substractPoints(p1, p2, f)
0149 {
0150 var x = (p1.x - p2.x) / f
0151 var y = (p1.y - p2.y) / f
0152 return Qt.point(x,y);
0153 }
0154 }
0155 Rectangle {
0156 id: frame
0157 objectName: "referenceframe"
0158 width: root.profile.x * root.scalex
0159 height: root.profile.y * root.scaley
0160 x: root.center.x - width / 2 - root.offsetx;
0161 y: root.center.y - height / 2 - root.offsety;
0162 color: "transparent"
0163 border.color: "#ffffff00"
0164 Loader {
0165 anchors.fill: parent
0166 source: {
0167 switch(root.overlayType)
0168 {
0169 case 0:
0170 return '';
0171 case 1:
0172 return "OverlayStandard.qml";
0173 case 2:
0174 return "OverlayMinimal.qml";
0175 case 3:
0176 return "OverlayCenter.qml";
0177 case 4:
0178 return "OverlayCenterDiagonal.qml";
0179 case 5:
0180 return "OverlayThirds.qml";
0181 }
0182 }
0183 }
0184 }
0185 MouseArea {
0186 id: global
0187 property bool isMoving : false
0188 anchors.fill: parent
0189 anchors.bottomMargin: clipMonitorRuler.height
0190 hoverEnabled: true
0191 acceptedButtons: Qt.LeftButton
0192 cursorShape: handleContainsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
0193 readonly property bool handleContainsMouse: {
0194 if (isMoving) {
0195 return true;
0196 }
0197 for(var i = 0; i < root.centerPoints.length; i++)
0198 {
0199 var p1 = canvas.convertPoint(root.centerPoints[i])
0200 if (Math.abs(p1.x - mouseX) <= canvas.handleSize && Math.abs(p1.y - mouseY) <= canvas.handleSize) {
0201 root.requestedKeyFrame = i
0202 return true
0203 }
0204 }
0205 root.requestedKeyFrame = -1
0206 return false
0207 }
0208
0209 onPositionChanged: mouse => {
0210 if (!pressed) {
0211 mouse.accepted = false
0212 return
0213 }
0214 if (root.requestedKeyFrame != -1) {
0215 isMoving = true
0216 root.centerPoints[root.requestedKeyFrame].x = (mouseX - frame.x) / root.scalex;
0217 root.centerPoints[root.requestedKeyFrame].y = (mouseY - frame.y) / root.scaley;
0218 canvas.requestPaint()
0219 root.centersChanged()
0220 }
0221 }
0222
0223 onPressed: mouse => {
0224 root.captureRightClick = true
0225 if (mouse.button & Qt.LeftButton) {
0226 if (root.requestedKeyFrame >= 0 && !isMoving) {
0227 controller.seekToKeyframe();
0228 }
0229 }
0230 isMoving = false
0231 }
0232 onDoubleClicked: {
0233 controller.addRemoveKeyframe()
0234 }
0235 onReleased: {
0236 root.captureRightClick = false
0237 root.requestedKeyFrame = -1
0238 isMoving = false;
0239 }
0240 onEntered: {
0241 controller.setWidgetKeyBinding(xi18nc("@info:whatsthis","<shortcut>Double click</shortcut> to add a keyframe, <shortcut>Shift drag</shortcut> for proportional rescale, <shortcut>Ctrl drag</shortcut> for center-based rescale, <shortcut>Hover right</shortcut> for toolbar, <shortcut>Click</shortcut> on a center to seek to its keyframe"));
0242 }
0243 onExited: {
0244 controller.setWidgetKeyBinding();
0245 }
0246 onWheel: wheel => {
0247 controller.seek(wheel.angleDelta.x + wheel.angleDelta.y, wheel.modifiers)
0248 }
0249 }
0250
0251 Rectangle {
0252 id: framerect
0253 property color hoverColor: activePalette.highlight //"#ffff00"
0254 x: frame.x + root.framesize.x * root.scalex
0255 y: frame.y + root.framesize.y * root.scaley
0256 width: root.framesize.width * root.scalex
0257 height: root.framesize.height * root.scaley
0258 color: "transparent"
0259 border.color: "#ffff0000"
0260 Rectangle {
0261 id: tlhandle
0262 anchors {
0263 top: parent.top
0264 left: parent.left
0265 }
0266 width: root.baseUnit
0267 height: width
0268 color: "red"
0269 visible: root.iskeyframe || controller.autoKeyframe
0270 opacity: root.iskeyframe ? 1 : 0.4
0271 MouseArea {
0272 property int oldMouseX
0273 property int oldMouseY
0274 property double handleRatio: 1
0275 acceptedButtons: Qt.LeftButton
0276 width: parent.width; height: parent.height
0277 anchors.centerIn: parent
0278 hoverEnabled: true
0279 cursorShape: Qt.SizeFDiagCursor
0280 onEntered: {
0281 if (!pressed) {
0282 tlhandle.color = framerect.hoverColor
0283 }
0284 }
0285 onExited: {
0286 if (!pressed) {
0287 tlhandle.color = '#ff0000'
0288 }
0289 }
0290 onPressed: mouse => {
0291 root.captureRightClick = true
0292 if (root.iskeyframe == false && controller.autoKeyframe) {
0293 console.log('ADDREMOVE THAND PRESSED')
0294 controller.addRemoveKeyframe();
0295 }
0296 oldMouseX = mouseX
0297 oldMouseY = mouseY
0298 effectsize.visible = true
0299 tlhandle.color = framerect.hoverColor
0300 handleRatio = framesize.width / framesize.height
0301 }
0302 onPositionChanged: mouse => {
0303 if (pressed) {
0304 adjustedFrame = framesize
0305 if (root.lockratio > 0 || mouse.modifiers & Qt.ShiftModifier) {
0306 var delta = Math.max(mouseX - oldMouseX, mouseY - oldMouseY)
0307 var newwidth = framerect.width - delta
0308 adjustedFrame.width = Math.round(newwidth / root.scalex);
0309 adjustedFrame.height = Math.round(adjustedFrame.width / (root.lockratio > 0 ?root.lockratio : handleRatio))
0310 adjustedFrame.y = (framerect.y - frame.y) / root.scaley + framesize.height - adjustedFrame.height;
0311 adjustedFrame.x = (framerect.x - frame.x) / root.scalex + framesize.width - adjustedFrame.width;
0312 } else {
0313 adjustedFrame.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
0314 adjustedFrame.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
0315 adjustedFrame.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
0316 adjustedFrame.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
0317 }
0318 if (mouse.modifiers & Qt.ControlModifier) {
0319 adjustedFrame.width -= (framesize.width - adjustedFrame.width)
0320 adjustedFrame.height -= (framesize.height - adjustedFrame.height)
0321 }
0322 framesize = adjustedFrame
0323 root.effectChanged()
0324 }
0325 }
0326 onReleased: {
0327 root.captureRightClick = false
0328 effectsize.visible = false
0329 tlhandle.color = '#ff0000'
0330 handleRatio = 1
0331 }
0332 }
0333 Text {
0334 id: effectpos
0335 objectName: "effectpos"
0336 color: "red"
0337 visible: false
0338 anchors {
0339 top: parent.bottom
0340 left: parent.right
0341 }
0342 text: framesize.x.toFixed(0) + "x" + framesize.y.toFixed(0)
0343 }
0344 }
0345 Rectangle {
0346 id: trhandle
0347 anchors {
0348 top: parent.top
0349 right: parent.right
0350 }
0351 width: root.baseUnit
0352 height: width
0353 color: "red"
0354 visible: root.iskeyframe || controller.autoKeyframe
0355 opacity: root.iskeyframe ? 1 : 0.4
0356 MouseArea {
0357 property int oldMouseX
0358 property int oldMouseY
0359 property double handleRatio: 1
0360 width: parent.width; height: parent.height
0361 anchors.centerIn: parent
0362 hoverEnabled: true
0363 cursorShape: Qt.SizeBDiagCursor
0364 onEntered: {
0365 if (!pressed) {
0366 trhandle.color = framerect.hoverColor
0367 }
0368 }
0369 onExited: {
0370 if (!pressed) {
0371 trhandle.color = '#ff0000'
0372 }
0373 }
0374 onPressed: mouse => {
0375 root.captureRightClick = true
0376 if (root.iskeyframe == false && controller.autoKeyframe) {
0377 console.log('ADDREMOVE TRAND PRESSED')
0378 controller.addRemoveKeyframe();
0379 }
0380 oldMouseX = mouseX
0381 oldMouseY = mouseY
0382 effectsize.visible = true
0383 trhandle.color = framerect.hoverColor
0384 handleRatio = framesize.width / framesize.height
0385 }
0386 onPositionChanged: mouse => {
0387 if (pressed) {
0388 adjustedFrame = framesize
0389 if (root.lockratio > 0 || mouse.modifiers & Qt.ShiftModifier) {
0390 var delta = Math.max(oldMouseX - mouseX, mouseY - oldMouseY)
0391 var newwidth = framerect.width - delta
0392 adjustedFrame.width = Math.round(newwidth / root.scalex);
0393 adjustedFrame.height = Math.round(adjustedFrame.width / (root.lockratio > 0 ?root.lockratio : handleRatio))
0394 adjustedFrame.y = (framerect.y - frame.y) / root.scaley + framesize.height - adjustedFrame.height;
0395 } else {
0396 adjustedFrame.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
0397 adjustedFrame.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
0398 adjustedFrame.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
0399 }
0400 if (mouse.modifiers & Qt.ControlModifier) {
0401 var xOffset = framesize.width - adjustedFrame.width
0402 adjustedFrame.x += xOffset
0403 adjustedFrame.width -= xOffset
0404 adjustedFrame.height -= (framesize.height - adjustedFrame.height)
0405 }
0406 framesize = adjustedFrame
0407 root.effectChanged()
0408 }
0409 }
0410 onReleased: {
0411 root.captureRightClick = false
0412 effectsize.visible = false
0413 trhandle.color = '#ff0000'
0414 handleRatio = 1
0415 }
0416 }
0417 }
0418 Rectangle {
0419 id: blhandle
0420 anchors {
0421 bottom: parent.bottom
0422 left: parent.left
0423 }
0424 width: root.baseUnit
0425 height: width
0426 color: "red"
0427 visible: root.iskeyframe || controller.autoKeyframe
0428 opacity: root.iskeyframe ? 1 : 0.4
0429 MouseArea {
0430 property int oldMouseX
0431 property int oldMouseY
0432 property double handleRatio: 1
0433 width: parent.width; height: parent.height
0434 anchors.centerIn: parent
0435 hoverEnabled: true
0436 cursorShape: Qt.SizeBDiagCursor
0437 onEntered: {
0438 if (!pressed) {
0439 blhandle.color = framerect.hoverColor
0440 }
0441 }
0442 onExited: {
0443 if (!pressed) {
0444 blhandle.color = '#ff0000'
0445 }
0446 }
0447 onPressed: mouse => {
0448 root.captureRightClick = true
0449 if (root.iskeyframe == false && controller.autoKeyframe) {
0450 console.log('ADDREMOVE BLAND PRESSED')
0451 controller.addRemoveKeyframe();
0452 }
0453 oldMouseX = mouseX
0454 oldMouseY = mouseY
0455 effectsize.visible = true
0456 blhandle.color = framerect.hoverColor
0457 handleRatio = framesize.width / framesize.height
0458 }
0459 onPositionChanged: mouse => {
0460 if (pressed) {
0461 adjustedFrame = framesize
0462 if (root.lockratio > 0 || mouse.modifiers & Qt.ShiftModifier) {
0463 var delta = Math.max(mouseX - oldMouseX, oldMouseY - mouseY)
0464 var newwidth = framerect.width - delta
0465 adjustedFrame.x = (framerect.x + (framerect.width - newwidth) - frame.x) / root.scalex;
0466 adjustedFrame.width = Math.round(newwidth / root.scalex);
0467 adjustedFrame.height = Math.round(adjustedFrame.width / (root.lockratio > 0 ?root.lockratio : handleRatio))
0468 } else {
0469 adjustedFrame.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
0470 adjustedFrame.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
0471 adjustedFrame.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
0472 }
0473 if (mouse.modifiers & Qt.ControlModifier) {
0474 adjustedFrame.width -= (framesize.width - adjustedFrame.width)
0475 var yOffset = framesize.height - adjustedFrame.height
0476 adjustedFrame.y += yOffset
0477 adjustedFrame.height -= yOffset
0478 }
0479 framesize = adjustedFrame
0480 root.effectChanged()
0481 }
0482 }
0483 onReleased: {
0484 root.captureRightClick = false
0485 effectsize.visible = false
0486 blhandle.color = '#ff0000'
0487 handleRatio = 1
0488 }
0489 }
0490 }
0491 Rectangle {
0492 id: brhandle
0493 anchors {
0494 bottom: parent.bottom
0495 right: parent.right
0496 }
0497 width: root.baseUnit
0498 height: width
0499 color: "red"
0500 visible: root.iskeyframe || controller.autoKeyframe
0501 opacity: root.iskeyframe ? 1 : 0.4
0502 MouseArea {
0503 property int oldMouseX
0504 property int oldMouseY
0505 property double handleRatio: 1
0506 width: parent.width; height: parent.height
0507 anchors.centerIn: parent
0508 hoverEnabled: true
0509 cursorShape: Qt.SizeFDiagCursor
0510 onEntered: {
0511 if (!pressed) {
0512 brhandle.color = framerect.hoverColor
0513 }
0514 }
0515 onExited: {
0516 if (!pressed) {
0517 brhandle.color = '#ff0000'
0518 }
0519 }
0520 onPressed: mouse => {
0521 root.captureRightClick = true
0522 if (root.iskeyframe == false && controller.autoKeyframe) {
0523 console.log('ADDREMOVE BRHAND PRESSED')
0524 controller.addRemoveKeyframe();
0525 }
0526 oldMouseX = mouseX
0527 oldMouseY = mouseY
0528 effectsize.visible = true
0529 brhandle.color = framerect.hoverColor
0530 handleRatio = framesize.width / framesize.height
0531 }
0532 onPositionChanged: mouse => {
0533 if (pressed) {
0534 adjustedFrame = framesize
0535 if (root.lockratio > 0 || mouse.modifiers & Qt.ShiftModifier) {
0536 var delta = Math.max(oldMouseX - mouseX, oldMouseY - mouseY)
0537 var newwidth = framerect.width - delta
0538 adjustedFrame.width = Math.round(newwidth / root.scalex);
0539 adjustedFrame.height = Math.round(adjustedFrame.width / (root.lockratio > 0 ?root.lockratio : handleRatio))
0540 } else {
0541 adjustedFrame.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
0542 adjustedFrame.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
0543 }
0544 if (mouse.modifiers & Qt.ControlModifier) {
0545 var xOffset = framesize.width - adjustedFrame.width
0546 adjustedFrame.x += xOffset
0547 adjustedFrame.width -= xOffset
0548 var yOffset = framesize.height - adjustedFrame.height
0549 adjustedFrame.y += yOffset
0550 adjustedFrame.height -= yOffset
0551 }
0552 framesize = adjustedFrame
0553 root.effectChanged()
0554 }
0555 }
0556 onReleased: {
0557 root.captureRightClick = false
0558 effectsize.visible = false
0559 brhandle.color = '#ff0000'
0560 handleRatio = 1
0561 }
0562 }
0563 Text {
0564 id: effectsize
0565 objectName: "effectsize"
0566 color: "red"
0567 visible: false
0568 anchors {
0569 bottom: parent.top
0570 right: parent.left
0571 }
0572 text: framesize.width.toFixed(0) + "x" + framesize.height.toFixed(0)
0573 }
0574 }
0575 Rectangle {
0576 anchors.centerIn: parent
0577 width: root.iskeyframe ? effectsize.height : effectsize.height / 2
0578 height: width
0579 radius: width / 2
0580 border.color: centerArea.containsMouse || centerArea.pressed ? framerect.hoverColor : "#ff0000"
0581 border.width: 1
0582 color: centerArea.containsMouse || centerArea.pressed ? framerect.hoverColor : "transparent"
0583 opacity: centerArea.containsMouse || centerArea.pressed ? 0.5 : 1
0584 MouseArea {
0585 id: centerArea
0586 width: effectsize.height * 1.5; height: effectsize.height * 1.5
0587 anchors.centerIn: parent
0588 property int oldMouseX
0589 property int oldMouseY
0590 hoverEnabled: true
0591 enabled: root.iskeyframe || controller.autoKeyframe
0592 cursorShape: enabled ? Qt.SizeAllCursor : Qt.ArrowCursor
0593 onPressed: {
0594 root.captureRightClick = true
0595 if (root.iskeyframe == false && controller.autoKeyframe) {
0596 console.log('ADDREMOVE CENTER PRESSED')
0597 controller.addRemoveKeyframe();
0598 }
0599 oldMouseX = mouseX
0600 oldMouseY = mouseY
0601 effectpos.visible = true
0602 }
0603 onPositionChanged: {
0604 if (pressed) {
0605 framesize.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
0606 framesize.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
0607 root.effectChanged()
0608 }
0609 }
0610 onReleased: {
0611 root.captureRightClick = false
0612 effectpos.visible = false
0613 }
0614 }
0615 }
0616 }
0617
0618 EffectToolBar {
0619 id: effectToolBar
0620 anchors {
0621 right: parent.right
0622 top: parent.top
0623 bottom: parent.bottom
0624 rightMargin: 4
0625 leftMargin: 4
0626 }
0627 }
0628 MonitorRuler {
0629 id: clipMonitorRuler
0630 anchors {
0631 left: root.left
0632 right: root.right
0633 bottom: root.bottom
0634 }
0635 height: controller.rulerHeight
0636 }
0637 }