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 }