Warning, /multimedia/kdenlive/src/monitor/view/kdenliveclipmonitor.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.Controls 2.15 0007 import QtQuick.Window 2.15 0008 import Kdenlive.Controls 1.0 0009 import QtQuick 2.15 0010 import com.enums 1.0 0011 0012 Item { 0013 id: root 0014 objectName: "root" 0015 0016 SystemPalette { id: activePalette } 0017 0018 // default size, but scalable by user 0019 height: 300; width: 400 0020 property string markerText 0021 property int itemType: 0 0022 property point profile: controller.profile 0023 property double zoom 0024 property point center 0025 property double scalex 0026 property double scaley 0027 property bool captureRightClick: false 0028 // Zoombar properties 0029 // The start position of the zoomed area, between 0 and 1 0030 property double zoomStart: 0 0031 // The zoom factor (between 0 and 1). 0.5 means 2x zoom 0032 property double zoomFactor: 1 0033 // The pixel height of zoom bar, used to offset markers info 0034 property int zoomOffset: 0 0035 property bool showZoomBar: false 0036 property double offsetx : 0 0037 property double offsety : 0 0038 property bool dropped: false 0039 property string fps: '-' 0040 property bool showMarkers: false 0041 property bool showTimecode: false 0042 property bool showFps: false 0043 property bool showSafezone: false 0044 // Display hover audio thumbnails overlay 0045 property bool showAudiothumb: false 0046 property bool showClipJobs: false 0047 // Always display audio thumbs under video 0048 property bool permanentAudiothumb: false 0049 property bool showToolbar: false 0050 property string clipName: controller.clipName 0051 property real baseUnit: fontMetrics.font.pixelSize * 0.8 0052 property int duration: 300 0053 property int mouseRulerPos: 0 0054 property double frameSize: 10 0055 property double timeScale: 1 0056 property int overlayType: controller.overlayType 0057 property color thumbColor1: controller.thumbColor1 0058 property color thumbColor2: controller.thumbColor2 0059 property color overlayColor: controller.overlayColor 0060 property bool isClipMonitor: true 0061 property int dragType: 0 0062 property string baseThumbPath 0063 property int overlayMargin: (audioThumb.stateVisible && !audioThumb.isAudioClip && audioThumb.visible) ? (audioThumb.height + root.zoomOffset) : root.zoomOffset + (audioThumb.isAudioClip && audioSeekZone.visible) ? audioSeekZone.height : 0 0064 0065 function updateClickCapture() { 0066 root.captureRightClick = false 0067 } 0068 0069 FontMetrics { 0070 id: fontMetrics 0071 font: fixedFont 0072 } 0073 0074 Timer { 0075 id: thumbTimer 0076 interval: 3000; running: false; 0077 } 0078 0079 signal editCurrentMarker() 0080 signal endDrag() 0081 0082 function updateScrolling() 0083 { 0084 if (thumbMouseArea.pressed) { 0085 var pos = Math.max(thumbMouseArea.mouseX, 0) 0086 pos += audioThumb.width/root.zoomFactor * root.zoomStart 0087 controller.setPosition(Math.min(pos / root.timeScale, root.duration)); 0088 0089 } 0090 } 0091 0092 onDurationChanged: { 0093 clipMonitorRuler.updateRuler() 0094 } 0095 onWidthChanged: { 0096 clipMonitorRuler.updateRuler() 0097 } 0098 onClipNameChanged: { 0099 // Animate clip name 0100 labelContainer.opacity = 1 0101 contextMenu.opacity = 1 0102 if (!clipNameLabel.hovered) { 0103 showAnimate.restart() 0104 } 0105 0106 // adjust monitor image size if audio thumb is displayed 0107 if (audioThumb.stateVisible && root.permanentAudiothumb && audioThumb.visible) { 0108 controller.rulerHeight = audioThumb.height + root.zoomOffset 0109 } else { 0110 controller.rulerHeight = root.zoomOffset 0111 } 0112 } 0113 0114 onZoomOffsetChanged: { 0115 if (audioThumb.stateVisible && root.permanentAudiothumb && audioThumb.visible) { 0116 controller.rulerHeight = audioThumb.height + root.zoomOffset 0117 } else { 0118 controller.rulerHeight = root.zoomOffset 0119 } 0120 } 0121 0122 onHeightChanged: { 0123 if (audioThumb.stateVisible && root.permanentAudiothumb && audioThumb.visible) { 0124 controller.rulerHeight = (audioThumb.isAudioClip ? (root.height - controller.rulerHeight) : (root.height - controller.rulerHeight)/ 6) + root.zoomOffset 0125 } else { 0126 controller.rulerHeight = root.zoomOffset 0127 } 0128 } 0129 0130 function updatePalette() { 0131 clipMonitorRuler.forceRepaint() 0132 } 0133 0134 function switchOverlay() { 0135 if (controller.overlayType >= 5) { 0136 controller.overlayType = 0 0137 } else { 0138 controller.overlayType = controller.overlayType + 1; 0139 } 0140 root.overlayType = controller.overlayType 0141 } 0142 0143 MouseArea { 0144 id: barOverArea 0145 hoverEnabled: true 0146 // Enable to block hide menu event 0147 acceptedButtons: contextMenu.visible ? Qt.LeftButton : Qt.NoButton 0148 anchors.fill: parent 0149 onPositionChanged: mouse => { 0150 if (mouse.modifiers & Qt.ShiftModifier) { 0151 var pos = Math.max(mouseX, 0) 0152 pos += width/root.zoomFactor * root.zoomStart 0153 controller.setPosition(Math.min(pos / root.timeScale, root.duration)); 0154 } 0155 } 0156 onWheel: wheel => { 0157 controller.seek(wheel.angleDelta.x + wheel.angleDelta.y, wheel.modifiers) 0158 } 0159 onEntered: { 0160 // Show clip name 0161 labelContainer.opacity = 1 0162 contextMenu.opacity = 1 0163 if (!clipNameLabel.hovered) { 0164 showAnimate.restart() 0165 } 0166 controller.setWidgetKeyBinding(xi18nc("@info:whatsthis", "<shortcut>Click</shortcut> to play, <shortcut>Double click</shortcut> for fullscreen, <shortcut>Hover right</shortcut> for toolbar, <shortcut>Wheel</shortcut> or <shortcut>arrows</shortcut> to seek, <shortcut>Ctrl wheel</shortcut> to zoom")); 0167 } 0168 onExited: { 0169 controller.setWidgetKeyBinding(); 0170 } 0171 } 0172 0173 SceneToolBar { 0174 id: sceneToolBar 0175 anchors { 0176 right: parent.right 0177 top: parent.top 0178 topMargin: 4 0179 rightMargin: 4 0180 leftMargin: 4 0181 } 0182 } 0183 0184 Item { 0185 height: root.height - controller.rulerHeight 0186 width: root.width 0187 Item { 0188 id: frame 0189 objectName: "referenceframe" 0190 width: root.profile.x * root.scalex 0191 height: root.profile.y * root.scaley 0192 x: root.center.x - width / 2 - root.offsetx; 0193 y: root.center.y - height / 2 - root.offsety; 0194 0195 Loader { 0196 anchors.fill: parent 0197 source: { 0198 switch(root.overlayType) 0199 { 0200 case 0: 0201 return ''; 0202 case 1: 0203 return "OverlayStandard.qml"; 0204 case 2: 0205 return "OverlayMinimal.qml"; 0206 case 3: 0207 return "OverlayCenter.qml"; 0208 case 4: 0209 return "OverlayCenterDiagonal.qml"; 0210 case 5: 0211 return "OverlayThirds.qml"; 0212 } 0213 } 0214 } 0215 } 0216 DropArea { //Drop area for effects 0217 id: effectArea 0218 anchors.fill: parent 0219 keys: 'kdenlive/effect' 0220 property string droppedData 0221 property string droppedDataSource 0222 onEntered: drag => { 0223 drag.acceptProposedAction() 0224 droppedData = drag.getDataAsString('kdenlive/effect') 0225 droppedDataSource = drag.getDataAsString('kdenlive/effectsource') 0226 } 0227 onDropped: { 0228 controller.addEffect(droppedData, droppedDataSource) 0229 droppedData = "" 0230 droppedDataSource = "" 0231 } 0232 } 0233 Item { 0234 id: monitorOverlay 0235 anchors.fill: parent 0236 0237 Item { 0238 id: audioThumb 0239 property bool stateVisible: (root.permanentAudiothumb || clipMonitorRuler.containsMouse || thumbMouseArea.containsMouse || dragZone.opacity == 1 || thumbTimer.running || root.showZoomBar) 0240 property bool isAudioClip: controller.clipType == ProducerType.Audio 0241 anchors { 0242 left: parent.left 0243 bottom: parent.bottom 0244 bottomMargin: root.zoomOffset 0245 } 0246 height: isAudioClip ? parent.height : parent.height / 6 0247 //font.pixelSize * 3 0248 width: parent.width 0249 visible: (root.permanentAudiothumb || root.showAudiothumb) && (isAudioClip || controller.clipType == ProducerType.AV || controller.clipHasAV) 0250 Label { 0251 id: clipStreamLabel 0252 font: fixedFont 0253 anchors { 0254 bottom: audioThumb.isAudioClip ? parent.bottom : parent.top 0255 horizontalCenter: parent.horizontalCenter 0256 } 0257 color: "white" 0258 text: controller.clipStream 0259 background: Rectangle { 0260 color: "#222277" 0261 } 0262 visible: text != "" 0263 padding :4 0264 } 0265 onStateVisibleChanged: { 0266 // adjust monitor image size 0267 if (stateVisible && root.permanentAudiothumb && audioThumb.visible) { 0268 controller.rulerHeight = audioThumb.height + root.zoomOffset 0269 } else { 0270 controller.rulerHeight = root.zoomOffset 0271 } 0272 } 0273 0274 states: [ 0275 State { when: audioThumb.stateVisible || audioThumb.isAudioClip; 0276 PropertyChanges { target: audioThumb; opacity: 1.0 } }, 0277 State { when: !audioThumb.stateVisible && !audioThumb.isAudioClip; 0278 PropertyChanges { target: audioThumb; opacity: 0.0 } } 0279 ] 0280 transitions: [ Transition { 0281 NumberAnimation { property: "opacity"; duration: audioThumb.isAudioClip ? 0 : 500} 0282 } ] 0283 Rectangle { 0284 color: "black" 0285 opacity: audioThumb.isAudioClip || root.permanentAudiothumb ? 1 : 0.6 0286 anchors.fill: parent 0287 } 0288 Rectangle { 0289 color: "yellow" 0290 opacity: 0.3 0291 height: parent.height 0292 x: controller.zoneIn * timeScale - (audioThumb.width/root.zoomFactor * root.zoomStart) 0293 width: (controller.zoneOut - controller.zoneIn) * timeScale 0294 visible: controller.zoneIn > 0 || controller.zoneOut < duration - 1 0295 } 0296 Repeater { 0297 id: streamThumb 0298 model: controller.audioStreams.length 0299 onCountChanged: { 0300 thumbTimer.start() 0301 } 0302 property double streamHeight: audioThumb.height / streamThumb.count 0303 Item { 0304 anchors.fill: parent 0305 TimelineWaveform { 0306 anchors.right: parent.right 0307 anchors.left: parent.left 0308 height: streamThumb.streamHeight 0309 property int aChannels: controller.audioChannels[model.index] 0310 y: model.index * height 0311 channels: aChannels 0312 binId: controller.clipId 0313 audioStream: controller.audioStreams[model.index] 0314 isFirstChunk: false 0315 format: controller.audioThumbFormat 0316 normalize: controller.audioThumbNormalize 0317 scaleFactor: audioThumb.width / (root.duration - 1) / root.zoomFactor 0318 waveInPoint: (root.duration - 1) * root.zoomStart * aChannels 0319 waveOutPointWithUpdate: (root.duration - 1) * (root.zoomStart + root.zoomFactor) * aChannels 0320 fillColor1: root.thumbColor1 0321 fillColor2: root.thumbColor2 0322 } 0323 Rectangle { 0324 width: parent.width 0325 y: (model.index + 1) * streamThumb.streamHeight 0326 height: 1 0327 visible: streamThumb.count > 1 && model.index < streamThumb.count - 1 0328 color: 'yellow' 0329 } 0330 } 0331 } 0332 Rectangle { 0333 color: "red" 0334 width: 1 0335 height: parent.height 0336 x: controller.position * timeScale - (audioThumb.width/root.zoomFactor * root.zoomStart) 0337 } 0338 MouseArea { 0339 id: thumbMouseArea 0340 anchors.fill: parent 0341 acceptedButtons: Qt.LeftButton 0342 hoverEnabled: true 0343 propagateComposedEvents: true 0344 onPressed: { 0345 if (audioThumb.isAudioClip && mouseY < audioSeekZone.y) { 0346 mouse.accepted = false 0347 return 0348 } 0349 var pos = Math.max(mouseX, 0) 0350 pos += audioThumb.width/root.zoomFactor * root.zoomStart 0351 controller.setPosition(Math.min(pos / root.timeScale, root.duration)); 0352 } 0353 onPositionChanged: mouse => { 0354 if (!(mouse.modifiers & Qt.ShiftModifier) && audioThumb.isAudioClip && mouseY < audioSeekZone.y) { 0355 mouse.accepted = false 0356 return 0357 } 0358 if (mouse.modifiers & Qt.ShiftModifier || pressed) { 0359 var pos = Math.max(mouseX, 0) 0360 pos += audioThumb.width/root.zoomFactor * root.zoomStart 0361 controller.setPosition(Math.min(pos / root.timeScale, root.duration)); 0362 } 0363 } 0364 onWheel: wheel => { 0365 if (wheel.modifiers & Qt.ControlModifier) { 0366 if (wheel.angleDelta.y < 0) { 0367 // zoom out 0368 clipMonitorRuler.zoomOutRuler(wheel.x) 0369 } else { 0370 // zoom in 0371 clipMonitorRuler.zoomInRuler(wheel.x) 0372 } 0373 } else { 0374 wheel.accepted = false 0375 } 0376 0377 } 0378 Rectangle { 0379 id: audioSeekZone 0380 width: parent.width 0381 height: parent.height / 6 0382 anchors.centerIn: parent 0383 anchors.verticalCenterOffset: audioThumb.isAudioClip ? parent.height * 5 / 12 : 0 0384 visible: audioThumb.isAudioClip && thumbMouseArea.containsMouse && thumbMouseArea.mouseY > y 0385 color: 'yellow' 0386 opacity: 0.5 0387 Rectangle { 0388 width: parent.width 0389 height: 1 0390 color: '#000' 0391 anchors.top: parent.top 0392 } 0393 // frame ticks 0394 Repeater { 0395 id: rulerAudioTicks 0396 model: parent.width / root.frameSize + 2 0397 Rectangle { 0398 x: index * root.frameSize - (clipMonitorRuler.rulerZoomOffset % root.frameSize) 0399 anchors.top: audioSeekZone.top 0400 height: (index % 5) ? audioSeekZone.height / 6 : audioSeekZone.height / 3 0401 width: 1 0402 color: '#000' 0403 opacity: 0.8 0404 } 0405 } 0406 } 0407 } 0408 } 0409 Menu { 0410 id: contextMenu 0411 Instantiator { 0412 model: controller.lastClips 0413 MenuItem { 0414 text: modelData 0415 font: fixedFont 0416 onTriggered: { 0417 controller.selectClip(index) 0418 //showAnimate.restart() 0419 } 0420 } 0421 // Update model when needed 0422 onObjectAdded: (index, object) => contextMenu.insertItem(index, object) 0423 onObjectRemoved: (index, object) => contextMenu.removeItem(object) 0424 } 0425 } 0426 Rectangle { 0427 id: labelContainer 0428 width: childrenRect.width 0429 height: childrenRect.height 0430 anchors { 0431 top: parent.top 0432 horizontalCenter: parent.horizontalCenter 0433 } 0434 color: clipNameLabel.hovered || contextMenu.visible ? "#CC222277" : "#88222277" 0435 border.color: clipNameLabel.hovered ? "#000000" : "transparent" 0436 border.width: 1 0437 radius: 2 0438 visible: clipName != "" 0439 ToolButton { 0440 id: clipNameLabel 0441 hoverEnabled: true 0442 icon.name: controller.lastClips.length > 1 ? "arrow-down" : "" 0443 text: clipName 0444 enabled: labelContainer.opacity > 0.5 0445 onTextChanged: { 0446 if (thumbTimer.running) { 0447 thumbTimer.stop() 0448 } 0449 thumbTimer.start() 0450 } 0451 bottomPadding: 0 0452 topPadding: 0 0453 topInset: 0 0454 bottomInset: 0 0455 SequentialAnimation { 0456 id: showAnimate 0457 running: false 0458 NumberAnimation { target: labelContainer; duration: 3000 } 0459 onStarted: { 0460 contextMenu.opacity = 1 0461 } 0462 onFinished: { 0463 if (contextMenu.visible) { 0464 contextMenu.close() 0465 } 0466 fadeAnimate.start() 0467 } 0468 } 0469 ParallelAnimation { 0470 id: fadeAnimate 0471 running: false 0472 NumberAnimation { target: labelContainer; property: "opacity"; to: 0; duration: 1000 } 0473 } 0474 onClicked: { 0475 if (controller.lastClips.length > 1) { 0476 if (contextMenu.visible) { 0477 contextMenu.close() 0478 } else { 0479 contextMenu.popup() 0480 } 0481 } 0482 } 0483 onHoveredChanged: { 0484 if (hovered) { 0485 showAnimate.stop() 0486 opacity = 1 0487 } else { 0488 if (!contextMenu.visible) { 0489 showAnimate.restart() 0490 } 0491 } 0492 } 0493 } 0494 } 0495 0496 Label { 0497 id: timecode 0498 font.family: fontMetrics.font.family 0499 font.pointSize: 1.5 * fontMetrics.font.pointSize 0500 objectName: "timecode" 0501 color: "#ffffff" 0502 padding: 2 0503 background: Rectangle { 0504 color: "#66000000" 0505 } 0506 text: controller.timecode 0507 visible: root.showTimecode 0508 anchors { 0509 right: parent.right 0510 bottom: parent.bottom 0511 bottomMargin: overlayMargin 0512 } 0513 } 0514 Label { 0515 id: fpsdropped 0516 font.family: fontMetrics.font.family 0517 font.pointSize: 1.5 * fontMetrics.font.pointSize 0518 objectName: "fpsdropped" 0519 color: "#ffffff" 0520 padding: 2 0521 background: Rectangle { 0522 color: root.dropped ? "#99ff0000" : "#66004400" 0523 } 0524 text: i18n("%1fps", root.fps) 0525 visible: root.showFps 0526 anchors { 0527 right: timecode.visible ? timecode.left : parent.right 0528 bottom: parent.bottom 0529 bottomMargin: overlayMargin 0530 } 0531 } 0532 Label { 0533 id: labelSpeed 0534 font: fixedFont 0535 anchors { 0536 left: parent.left 0537 top: parent.top 0538 } 0539 visible: Math.abs(controller.speed) > 1 0540 text: "x" + controller.speed 0541 color: "white" 0542 background: Rectangle { 0543 color: "darkgreen" 0544 } 0545 padding: 5 0546 horizontalAlignment: TextInput.AlignHCenter 0547 } 0548 Label { 0549 id: inPoint 0550 font: fixedFont 0551 anchors { 0552 left: parent.left 0553 bottom: parent.bottom 0554 bottomMargin: overlayMargin 0555 } 0556 visible: root.showMarkers && controller.position == controller.zoneIn 0557 text: controller.zoneIn == controller.zoneOut ? i18n("In/Out Point") : i18n("In Point") 0558 color: "white" 0559 background: Rectangle { 0560 color: "#228b22" 0561 } 0562 padding:4 0563 horizontalAlignment: TextInput.AlignHCenter 0564 MouseArea { 0565 id: inPointArea 0566 anchors.fill: parent 0567 hoverEnabled: true 0568 } 0569 } 0570 Label { 0571 id: outPoint 0572 font: fixedFont 0573 anchors { 0574 left: inPoint.visible ? inPoint.right : parent.left 0575 bottom: parent.bottom 0576 bottomMargin: overlayMargin 0577 } 0578 visible: root.showMarkers && controller.position == controller.zoneOut && controller.zoneOut > controller.zoneIn 0579 text: i18n("Out Point") 0580 color: "white" 0581 background: Rectangle { 0582 color: "#770000" 0583 } 0584 padding: 4 0585 horizontalAlignment: TextInput.AlignHCenter 0586 MouseArea { 0587 id: outPointArea 0588 anchors.fill: parent 0589 hoverEnabled: true 0590 } 0591 } 0592 TextField { 0593 id: marker 0594 font: fixedFont 0595 objectName: "markertext" 0596 activeFocusOnPress: true 0597 text: controller.markerComment 0598 onEditingFinished: { 0599 root.markerText = marker.displayText 0600 marker.focus = false 0601 root.editCurrentMarker() 0602 } 0603 anchors { 0604 left: outPoint.visible ? outPoint.right : inPoint.visible ? inPoint.right : parent.left 0605 bottom: parent.bottom 0606 bottomMargin: overlayMargin 0607 } 0608 visible: root.showMarkers && text != "" 0609 height: inPoint.height 0610 width: fontMetrics.boundingRect(displayText).width + 10 0611 horizontalAlignment: displayText == text ? TextInput.AlignHCenter : TextInput.AlignLeft 0612 background: Rectangle { 0613 color: controller.markerColor 0614 } 0615 color: "#000" 0616 padding: 0 0617 maximumLength: 20 0618 } 0619 } 0620 0621 Rectangle { 0622 // Audio or video only drag zone 0623 id: dragZone 0624 property string uuid 0625 x: 2 0626 y: inPoint.visible || outPoint.visible || marker.visible ? parent.height - inPoint.height - height - 2 - overlayMargin : parent.height - height - 2 - overlayMargin 0627 width: childrenRect.width 0628 height: childrenRect.height 0629 color: Qt.rgba(activePalette.highlight.r, activePalette.highlight.g, activePalette.highlight.b, 0.7) 0630 radius: 4 0631 opacity: (dragAudioArea.containsMouse || dragVideoArea.containsMouse || thumbMouseArea.containsMouse || marker.hovered || inPointArea.containsMouse || outPointArea.containsMouse || dragAudioArea.pressed || dragVideoArea.pressed 0632 || (barOverArea.containsMouse && (barOverArea.mouseY >= (parent.height - inPoint.height - height - 2 - (audioThumb.height + root.zoomOffset) - root.baseUnit)))) ? 1 : 0 0633 visible: controller.clipHasAV 0634 onOpacityChanged: { 0635 if (opacity == 1) { 0636 videoDragButton.x = 0 0637 videoDragButton.y = 0 0638 audioDragButton.x = videoDragButton.x + videoDragButton.width 0639 audioDragButton.y = 0 0640 } 0641 } 0642 Row { 0643 id: dragRow 0644 ToolButton { 0645 id: videoDragButton 0646 icon.name: "kdenlive-show-video" 0647 opacity: dragAudioArea.pressed ? 0 : 1 0648 focusPolicy: Qt.NoFocus 0649 Drag.active: dragVideoArea.drag.active 0650 Drag.dragType: Drag.Automatic 0651 Drag.mimeData: { 0652 "text/producerslist" : "V" + controller.clipId + "/" + controller.zoneIn + "/" + (controller.zoneOut - 1), 0653 "text/dragid" : dragZone.uuid 0654 } 0655 Drag.onDragStarted: { 0656 dragZone.uuid = controller.getUuid() 0657 } 0658 Drag.onDragFinished: dropAction => { 0659 root.endDrag() 0660 root.captureRightClick = false 0661 } 0662 MouseArea { 0663 id: dragVideoArea 0664 hoverEnabled: true 0665 anchors.fill: videoDragButton 0666 cursorShape: Qt.PointingHand 0667 drag.target: videoDragButton 0668 onPressed: mouse => { 0669 root.captureRightClick = true 0670 mouse.accepted = true 0671 } 0672 onReleased: mouse => { 0673 mouse.accepted = true 0674 root.captureRightClick = false 0675 } 0676 } 0677 } 0678 ToolButton { 0679 id: audioDragButton 0680 opacity: dragVideoArea.pressed ? 0 : 1 0681 icon.name: "audio-volume-medium" 0682 focusPolicy: Qt.NoFocus 0683 Drag.active: dragAudioArea.drag.active 0684 Drag.dragType: Drag.Automatic 0685 Drag.mimeData: { 0686 "text/producerslist" : "A" + controller.clipId + "/" + controller.zoneIn + "/" + (controller.zoneOut - 1), 0687 "text/dragid" : dragZone.uuid 0688 } 0689 Drag.onDragStarted: { 0690 dragZone.uuid = controller.getUuid() 0691 } 0692 Drag.onDragFinished: { 0693 root.endDrag() 0694 root.captureRightClick = false 0695 } 0696 MouseArea { 0697 id: dragAudioArea 0698 hoverEnabled: true 0699 anchors.fill: audioDragButton 0700 cursorShape: Qt.PointingHand 0701 drag.target: audioDragButton 0702 onPressed: mouse => { 0703 root.captureRightClick = true 0704 mouse.accepted = true 0705 } 0706 onReleased: mouse => { 0707 mouse.accepted = true 0708 root.captureRightClick = false 0709 } 0710 } 0711 } 0712 } 0713 } 0714 } 0715 Item { 0716 id: clipJobInfo 0717 x: sceneToolBar.visible && sceneToolBar.rightSide == false ? sceneToolBar.width + 10 : 10 0718 y: 10 0719 width: parent.width - 20 0720 height: childrenRect.height 0721 visible: root.showClipJobs && controller.clipId > 0 0722 Column { 0723 Repeater { 0724 model: controller.runningJobs 0725 delegate: Rectangle { 0726 id: jobContainer 0727 property var uuid: controller.jobsUuids[model.index] 0728 width: childrenRect.width + 4 0729 height: jobLabel.height + progressBar.height + 4 0730 color: "#80333333" 0731 radius: 5 0732 MouseArea { 0733 id: jobsArea 0734 hoverEnabled: true 0735 anchors.fill: parent 0736 } 0737 Row { 0738 id: labelRow 0739 MonitorToolButton { 0740 id: iconButton 0741 iconName: "window-close" 0742 anchors.leftMargin: 4 0743 height: jobLabel.height 0744 width: height 0745 toolTipText: i18n("Terminate Job") 0746 onClicked: controller.terminateJob(uuid) 0747 } 0748 Text { 0749 id: jobLabel 0750 horizontalAlignment: Text.AlignLeft 0751 anchors.leftMargin: 4 0752 padding: 2 0753 text: modelData 0754 font.pointSize: fontMetrics.font.pointSize 0755 elide: Text.ElideMiddle 0756 color: 'white' 0757 } 0758 } 0759 Rectangle { 0760 id: progressBar 0761 anchors.top: labelRow.bottom 0762 anchors.left: parent.left 0763 anchors.right: parent.right 0764 anchors.leftMargin: 4 0765 anchors.rightMargin: 4 0766 height: 6 0767 radius: 2 0768 color: "#33ffffff" 0769 border { 0770 color: "#99000000" 0771 width: 1 0772 } 0773 Rectangle { 0774 anchors.fill: parent 0775 anchors.margins: 1 0776 color: 'steelblue' 0777 anchors.rightMargin: (parent.width - 2) * (100 - controller.jobsProgress[model.index]) / 100 0778 } 0779 } 0780 } 0781 } 0782 } 0783 } 0784 MonitorRuler { 0785 id: clipMonitorRuler 0786 anchors { 0787 left: root.left 0788 right: root.right 0789 bottom: root.bottom 0790 } 0791 height: controller.rulerHeight 0792 Repeater { 0793 model:controller.clipBounds 0794 anchors.fill: parent 0795 Rectangle { 0796 anchors.top: parent.top 0797 anchors.topMargin: 1 0798 property point bd: controller.clipBoundary(model.index) 0799 x: bd.x * root.timeScale - (audioThumb.width/root.zoomFactor * root.zoomStart) 0800 width: bd.y * root.timeScale 0801 height: 2 0802 color: 'goldenrod' 0803 } 0804 } 0805 } 0806 }