diff --git a/src/monitor/view/MonitorRuler.qml b/src/monitor/view/MonitorRuler.qml index 20b1f34fd..aa355a130 100644 --- a/src/monitor/view/MonitorRuler.qml +++ b/src/monitor/view/MonitorRuler.qml @@ -1,251 +1,252 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Window 2.2 import Kdenlive.Controls 1.0 import QtQuick 2.4 // Monitor ruler Rectangle { id: ruler color: activePalette.window + property bool containsMouse: rulerMouseArea.containsMouse Timer { id: zoneToolTipTimer interval: 3000; running: false; } function forceRepaint() { ruler.color = activePalette.window // Enforce repaint rulerTicks.model = 0 rulerTicks.model = ruler.width / frameSize + 2 playhead.fillColor = activePalette.windowText } function updateRuler() { var projectFps = controller.fps() root.timeScale = width / root.duration if (root.duration < 10 * projectFps) { root.frameSize = projectFps * root.timeScale * 0.2 } else if (duration < 100 * projectFps) { frameSize = projectFps * root.timeScale } else if (duration < 400 * projectFps) { root.frameSize = projectFps * root.timeScale * 2 } else { root.frameSize = projectFps * root.timeScale * 4 while (root.frameSize < 10) { root.frameSize *= 4 } } } // frame ticks Repeater { id: rulerTicks model: ruler.width / frameSize + 2 Rectangle { property int realPos: index x: realPos * frameSize anchors.bottom: ruler.bottom height: (realPos % 4)? ((realPos % 2) ? 3 : 7) : 12 width: 1 color: activePalette.windowText opacity: 0.5 } } MouseArea { id: rulerMouseArea anchors.fill: parent hoverEnabled: true onPressed: { if (mouse.buttons === Qt.LeftButton) { var pos = Math.max(mouseX, 0) controller.requestSeekPosition(Math.min(pos / root.timeScale, root.duration)); } } onPositionChanged: { if (mouse.buttons === Qt.LeftButton) { var pos = Math.max(mouseX, 0) root.mouseRulerPos = pos if (pressed) { controller.requestSeekPosition(Math.min(pos / root.timeScale, root.duration)); } } } } // Zone duration indicator Rectangle { visible: inZoneMarker.visible || zoneToolTipTimer.running width: inLabel.contentWidth + 4 height: inLabel.contentHeight property int centerPos: zone.x + zone.width / 2 - inLabel.contentWidth / 2 x: centerPos < 0 ? 0 : centerPos > ruler.width - inLabel.contentWidth ? ruler.width - inLabel.contentWidth : centerPos color: activePalette.highlight anchors.bottom: ruler.top Label { id: inLabel anchors.fill: parent horizontalAlignment: Text.AlignHCenter text: trimInMouseArea.containsMouse || trimInMouseArea.pressed ? controller.toTimecode(controller.zoneIn) + '>' + controller.toTimecode(controller.zoneOut - controller.zoneIn) : trimOutMouseArea.containsMouse || trimOutMouseArea.pressed ? controller.toTimecode(controller.zoneOut - controller.zoneIn) + '<' + controller.toTimecode(controller.zoneOut) : controller.toTimecode(controller.zoneOut - controller.zoneIn) font.pixelSize: root.baseUnit color: activePalette.highlightedText } } TimelinePlayhead { id: playhead visible: controller.position > -1 height: ruler.height * 0.5 width: ruler.height * 1 opacity: 0.8 anchors.top: ruler.top fillColor: activePalette.windowText x: controller.position * root.timeScale - (width / 2) } // monitor zone Rectangle { id: inZoneMarker x: controller.zoneIn * root.timeScale anchors.bottom: parent.bottom anchors.top: parent.top width: 1 color: activePalette.highlight visible: controller.zoneOut > controller.zoneIn && (rulerMouseArea.containsMouse || trimOutMouseArea.containsMouse || trimOutMouseArea.pressed || trimInMouseArea.containsMouse) } Rectangle { x: controller.zoneOut * root.timeScale anchors.bottom: parent.bottom anchors.top: parent.top width: 1 color: activePalette.highlight visible: inZoneMarker.visible } Rectangle { id: zone visible: controller.zoneOut > controller.zoneIn color: activePalette.highlight x: controller.zoneIn * root.timeScale width: (controller.zoneOut - controller.zoneIn) * root.timeScale anchors.bottom: parent.bottom height: ruler.height / 2 opacity: 0.4 onXChanged: zoneToolTipTimer.start() onWidthChanged: zoneToolTipTimer.start() } Rectangle { id: trimIn x: zone.x - root.baseUnit / 3 y: zone.y height: zone.height width: root.baseUnit * .8 color: 'lawngreen' opacity: trimInMouseArea.containsMouse || trimInMouseArea.drag.active ? 0.5 : 0 Drag.active: trimInMouseArea.drag.active Drag.proposedAction: Qt.MoveAction MouseArea { id: trimInMouseArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.SizeHorCursor drag.target: parent drag.axis: Drag.XAxis drag.smoothed: false drag.minimumX: 0 drag.maximumX: ruler.width onPositionChanged: { if (mouse.buttons === Qt.LeftButton) { controller.zoneIn = Math.round(trimIn.x / root.timeScale) } } } } Rectangle { id: trimOut width: root.baseUnit * .8 x: zone.x + zone.width - (width * .7) y: zone.y height: zone.height color: 'darkred' opacity: trimOutMouseArea.containsMouse || trimOutMouseArea.drag.active ? 0.5 : 0 Drag.active: trimOutMouseArea.drag.active Drag.proposedAction: Qt.MoveAction MouseArea { id: trimOutMouseArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.SizeHorCursor drag.target: parent drag.axis: Drag.XAxis drag.smoothed: false drag.minimumX: 0 drag.maximumX: ruler.width - trimOut.width onPositionChanged: { if (mouse.buttons === Qt.LeftButton) { controller.zoneOut = Math.round((trimOut.x + trimOut.width) / root.timeScale) } } } } // markers Repeater { model: markersModel delegate: Item { anchors.fill: parent Rectangle { id: markerBase width: 1 height: parent.height x: (model.frame) * root.timeScale; color: model.color } Rectangle { visible: !rulerMouseArea.pressed && (guideArea.containsMouse || (rulerMouseArea.containsMouse && Math.abs(rulerMouseArea.mouseX - markerBase.x) < 4)) opacity: 0.7 property int guidePos: markerBase.x - mlabel.contentWidth / 2 x: guidePos < 0 ? 0 : (guidePos > (parent.width - mlabel.contentWidth) ? parent.width - mlabel.contentWidth : guidePos) radius: 2 width: mlabel.contentWidth height: mlabel.contentHeight * .8 anchors { bottom: parent.top } color: model.color Text { id: mlabel text: model.comment font.pixelSize: root.baseUnit verticalAlignment: Text.AlignVCenter anchors { fill: parent } color: 'white' } MouseArea { z: 10 id: guideArea anchors.fill: parent acceptedButtons: Qt.LeftButton cursorShape: Qt.PointingHandCursor hoverEnabled: true //onDoubleClicked: timeline.editMarker(clipRoot.binId, model.frame) onClicked: { controller.requestSeekPosition(model.frame) } } } } } Rectangle { id: seekCursor visible: controller.seekPosition > -1 color: activePalette.highlight width: 4 height: ruler.height opacity: 0.5 x: controller.seekPosition * root.timeScale y: 0 } } diff --git a/src/monitor/view/kdenliveclipmonitor.qml b/src/monitor/view/kdenliveclipmonitor.qml index a1f45e438..39084a419 100644 --- a/src/monitor/view/kdenliveclipmonitor.qml +++ b/src/monitor/view/kdenliveclipmonitor.qml @@ -1,262 +1,253 @@ import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Window 2.2 import Kdenlive.Controls 1.0 import QtQuick 2.6 import AudioThumb 1.0 Item { id: root objectName: "root" SystemPalette { id: activePalette } // default size, but scalable by user height: 300; width: 400 property string markerText property point profile property double zoom property double scalex property double scaley property bool dropped property string fps property bool showMarkers property bool showTimecode property bool showFps property bool showSafezone property bool showAudiothumb property bool showToolbar: false property bool hasAV: controller.clipHasAV property real baseUnit: fontMetrics.font.pixelSize * 0.8 property int duration: 300 property int mouseRulerPos: 0 property double frameSize: 10 property double timeScale: 1 property int overlayType: controller.overlayType property color overlayColor: 'cyan' property bool isClipMonitor: true property int dragType: 0 FontMetrics { id: fontMetrics font.family: "Arial" } signal editCurrentMarker() signal toolBarChanged(bool doAccept) onDurationChanged: { clipMonitorRuler.updateRuler() } onWidthChanged: { clipMonitorRuler.updateRuler() } function updatePalette() { clipMonitorRuler.forceRepaint() } function switchOverlay() { if (controller.overlayType >= 5) { controller.overlayType = 0 } else { controller.overlayType = controller.overlayType + 1; } root.overlayType = controller.overlayType } MouseArea { id: barOverArea hoverEnabled: true acceptedButtons: Qt.NoButton anchors.fill: parent } SceneToolBar { id: sceneToolBar anchors { right: parent.right top: parent.top topMargin: 4 rightMargin: 4 } visible: barOverArea.mouseX >= x - 10 } Item { height: root.height - controller.rulerHeight width: root.width Item { id: frame objectName: "referenceframe" width: root.profile.x * root.scalex height: root.profile.y * root.scaley anchors.centerIn: parent Loader { anchors.fill: parent source: { switch(root.overlayType) { case 0: return ''; case 1: return "OverlayStandard.qml"; case 2: return "OverlayMinimal.qml"; case 3: return "OverlayCenter.qml"; case 4: return "OverlayCenterDiagonal.qml"; case 5: return "OverlayThirds.qml"; } } } } Item { id: monitorOverlay anchors.fill: parent QmlAudioThumb { id: audioThumb objectName: "audiothumb" - property bool stateVisible: true + property bool stateVisible: (barOverArea.mouseY >= root.height * 0.7 || dragOverArea.containsMouse || clipMonitorRuler.containsMouse) anchors { left: parent.left bottom: parent.bottom } height: parent.height / 6 //font.pixelSize * 3 width: parent.width visible: root.showAudiothumb - MouseArea { - id: mouseOverArea - hoverEnabled: true - onExited: audioThumb.stateVisible = false - onEntered: audioThumb.stateVisible = true - acceptedButtons: Qt.NoButton - anchors.fill: parent - } - states: [ State { when: audioThumb.stateVisible; PropertyChanges { target: audioThumb; opacity: 1.0 } }, State { when: !audioThumb.stateVisible; PropertyChanges { target: audioThumb; opacity: 0.0 } } ] transitions: [ Transition { NumberAnimation { property: "opacity"; duration: 500} } ] } Text { id: timecode font: fixedFont objectName: "timecode" color: "white" style: Text.Outline; styleColor: "black" text: controller.toTimecode(controller.position) visible: root.showTimecode anchors { right: parent.right bottom: parent.bottom rightMargin: 4 } } Text { id: fpsdropped font: fixedFont objectName: "fpsdropped" color: root.dropped ? "red" : "white" style: Text.Outline; styleColor: "black" text: i18n("%1 fps", root.fps) visible: root.showFps anchors { right: timecode.visible ? timecode.left : parent.right bottom: parent.bottom rightMargin: 10 } } TextField { id: marker font: fixedFont objectName: "markertext" activeFocusOnPress: true onEditingFinished: { root.markerText = marker.displayText marker.focus = false root.editCurrentMarker() } anchors { left: parent.left bottom: parent.bottom } visible: root.showMarkers && text != "" text: controller.markerComment maximumLength: 20 style: TextFieldStyle { textColor: "white" background: Rectangle { color: controller.position == controller.zoneIn ? "#9900ff00" : controller.position == controller.zoneOut ? "#99ff0000" : "#990000ff" width: marker.width } } } } MouseArea { id: dragOverArea hoverEnabled: true acceptedButtons: Qt.LeftButton x: 0 width: parent.width height: 2 * audioDragButton.height y: parent.height - height propagateComposedEvents: true onPressed: { // First found child is the Column var clickedChild = childAt(mouseX,mouseY) ? childAt(mouseX,mouseY).childAt(mouseX,mouseY).childAt(mouseX,mouseY) : "" if (clickedChild == audioDragButton) { dragType = 1 } else if (clickedChild == videoDragButton) { dragType = 2 } else { dragType = 0 } mouse.accepted = false } Rectangle { x: 5 width: childrenRect.width height: childrenRect.height color: Qt.rgba(activePalette.window.r, activePalette.window.g, activePalette.window.b, 0.5) radius: 4 visible: root.hasAV && dragOverArea.containsMouse Row { ToolButton { id: videoDragButton iconName: "kdenlive-show-video" tooltip: i18n("Video only drag") enabled: false } ToolButton { id: audioDragButton iconName: "audio-volume-medium" tooltip: i18n("Audio only drag") enabled: false } } } } } MonitorRuler { id: clipMonitorRuler anchors { left: root.left right: root.right bottom: root.bottom } height: controller.rulerHeight } }