[multimedia/kdenlive] src: Fix all remaining unqualified access qmllint warnings
Julius Künzel <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit ecaf30f46d2ed29662142f26549c721e52e257cc by Julius Künzel.
Committed on 03/08/2026 at 21:27.
Pushed by jlskuz into branch 'master'.
Fix all remaining unqualified access qmllint warnings
M +5 -0 src/monitor/view/EffectToolBar.qml
M +13 -19 src/monitor/view/MaskToolBar.qml
M +23 -0 src/monitor/view/MonitorAutomask.qml
M +4 -3 src/monitor/view/MonitorZoomButton.qml
M +5 -0 src/monitor/view/MultiScreenToolBar.qml
M +5 -0 src/monitor/view/SceneToolBar.qml
M +104 -39 src/timeline2/view/qml/Clip.qml
M +13 -11 src/timeline2/view/qml/ClipThumbs.qml
M +59 -11 src/timeline2/view/qml/Composition.qml
M +17 -9 src/timeline2/view/qml/KeyframeDelegate.qml
M +23 -10 src/timeline2/view/qml/KeyframeView.qml
M +35 -40 src/timeline2/view/qml/Ruler.qml
M +12 -9 src/timeline2/view/qml/RulerZone.qml
M +30 -23 src/timeline2/view/qml/SubTitle.qml
M +3 -2 src/timeline2/view/qml/SubtitleTrackHead.qml
M +58 -11 src/timeline2/view/qml/Timeline.qml
M +82 -14 src/timeline2/view/qml/Track.qml
https://invent.kde.org/multimedia/kdenlive/-/commit/ecaf30f46d2ed29662142f26549c721e52e257cc
diff --git a/src/monitor/view/EffectToolBar.qml b/src/monitor/view/EffectToolBar.qml
index 241c1e58ae..41e6f384e1 100644
--- a/src/monitor/view/EffectToolBar.qml
+++ b/src/monitor/view/EffectToolBar.qml
@@ -127,6 +127,11 @@ MouseArea {
id: zoomButton
monitorController: barZone.monitorController
isClipMonitor: barZone.isClipMonitor
+ onPopupAboutToHide: {
+ if (!barZone.containsMouse) {
+ effecttoolbar.opacity = 0
+ }
+ }
}
K.MonitorToolButton {
objectName: "moveBar"
diff --git a/src/monitor/view/MaskToolBar.qml b/src/monitor/view/MaskToolBar.qml
index e5fad86450..e0c3036f30 100644
--- a/src/monitor/view/MaskToolBar.qml
+++ b/src/monitor/view/MaskToolBar.qml
@@ -15,21 +15,16 @@ MouseArea {
hoverEnabled: true
required property K.MonitorProxy monitorController
required property bool isClipMonitor
+ required property int maskMode
property bool rightSide: true
acceptedButtons: Qt.NoButton
width: 2.4 * K.UiUtils.baseSizeMedium
height: parent.height
- Timer {
- id: hideTimer
- interval: 3000
- running: false
- repeat: false
- onTriggered: {
- generateLabel.visible = false
- }
- }
SystemPalette { id: activePalette }
+ signal generateMask()
+ signal exitMaskPreview()
+
Rectangle {
id: effecttoolbar
objectName: "effecttoolbar"
@@ -69,15 +64,9 @@ MouseArea {
iconName: "media-record"
toolTipText: KI18n.i18n("Generate Mask")
checkable: false
- visible: root.maskMode != MaskModeType.MaskPreview
+ visible: barZone.maskMode != MaskModeType.MaskPreview
onClicked: {
- generateLabel.visible = true
- if (root.keyframes.length > 0 || (root.boxCoords[2] > 0 && root.boxCoords[3] > 0)) {
- root.generateMask()
- } else {
- // Display the message for 3 seconds
- hideTimer.start()
- }
+ barZone.generateMask()
}
}
K.MonitorToolButton {
@@ -105,16 +94,21 @@ MouseArea {
K.MonitorToolButton {
objectName: "abortMask"
iconName: "dialog-close"
- toolTipText: root.maskMode != MaskModeType.MaskPreview ? KI18n.i18n("Exit Mask Creation") : KI18n.i18n("Exit Preview Mode")
+ toolTipText: barZone.maskMode != MaskModeType.MaskPreview ? KI18n.i18n("Exit Mask Creation") : KI18n.i18n("Exit Preview Mode")
checkable: false
onClicked: {
- root.exitMaskPreview()
+ barZone.exitMaskPreview()
}
}
K.MonitorZoomButton {
id: zoomButton
monitorController: barZone.monitorController
isClipMonitor: barZone.isClipMonitor
+ onPopupAboutToHide: {
+ if (!barZone.containsMouse) {
+ effecttoolbar.opacity = 0
+ }
+ }
}
K.MonitorToolButton {
diff --git a/src/monitor/view/MonitorAutomask.qml b/src/monitor/view/MonitorAutomask.qml
index 805270faf5..e3f634e815 100644
--- a/src/monitor/view/MonitorAutomask.qml
+++ b/src/monitor/view/MonitorAutomask.qml
@@ -333,6 +333,15 @@ Item {
}
}
}
+ Timer {
+ id: hideGenerateLabelTimer
+ interval: 3000
+ running: false
+ repeat: false
+ onTriggered: {
+ generateLabel.visible = false
+ }
+ }
Label {
id: generateLabel
anchors.top: parent.top
@@ -393,6 +402,20 @@ Item {
}
monitorController: root.controller
isClipMonitor: root.isClipMonitor
+ maskMode: root.maskMode
+
+ onExitMaskPreview: () => root.exitMaskPreview()
+ onGenerateMask: () => {
+ generateLabel.visible = true
+
+ var hasObjectSelected = root.keyframes.length > 0 || (root.boxCoords[2] > 0 && root.boxCoords[3] > 0)
+ if (hasObjectSelected) {
+ root.generateMask()
+ } else {
+ // Display the message for 3 seconds
+ hideGenerateLabelTimer.start()
+ }
+ }
}
Timer {
id: firstTimer
diff --git a/src/monitor/view/MonitorZoomButton.qml b/src/monitor/view/MonitorZoomButton.qml
index 20da6ff87e..ec3dbdc0fd 100644
--- a/src/monitor/view/MonitorZoomButton.qml
+++ b/src/monitor/view/MonitorZoomButton.qml
@@ -18,6 +18,9 @@ K.MonitorToolButton {
required property K.MonitorProxy monitorController
required property bool isClipMonitor
property bool menuVisible: zoomContextMenu.visible
+
+ signal popupAboutToHide()
+
onClicked: {
if (zoomContextMenu.visible) {
zoomContextMenu.close()
@@ -31,9 +34,7 @@ K.MonitorToolButton {
padding: 0
margins: 0
onAboutToHide: {
- if (!barZone.containsMouse) {
- scenetoolbar.opacity = 0
- }
+ zoomButton.popupAboutToHide()
}
ColumnLayout {
diff --git a/src/monitor/view/MultiScreenToolBar.qml b/src/monitor/view/MultiScreenToolBar.qml
index 01cf7a08c1..e2a3a61046 100644
--- a/src/monitor/view/MultiScreenToolBar.qml
+++ b/src/monitor/view/MultiScreenToolBar.qml
@@ -75,6 +75,11 @@ MouseArea {
id: zoomButton
monitorController: barZone.monitorController
isClipMonitor: barZone.isClipMonitor
+ onPopupAboutToHide: {
+ if (!barZone.containsMouse) {
+ scenetoolbar.opacity = 0
+ }
+ }
}
K.MonitorToolButton {
objectName: "moveBar"
diff --git a/src/monitor/view/SceneToolBar.qml b/src/monitor/view/SceneToolBar.qml
index 5bae8057d1..a7955912f6 100644
--- a/src/monitor/view/SceneToolBar.qml
+++ b/src/monitor/view/SceneToolBar.qml
@@ -94,6 +94,11 @@ MouseArea {
id: zoomButton
monitorController: barZone.monitorController
isClipMonitor: barZone.isClipMonitor
+ onPopupAboutToHide: {
+ if (!barZone.containsMouse) {
+ scenetoolbar.opacity = 0
+ }
+ }
}
K.MonitorToolButton {
objectName: "addMarker"
diff --git a/src/timeline2/view/qml/Clip.qml b/src/timeline2/view/qml/Clip.qml
index 7a004146ac..314c9e45b2 100644
--- a/src/timeline2/view/qml/Clip.qml
+++ b/src/timeline2/view/qml/Clip.qml
@@ -79,8 +79,21 @@ Rectangle {
required property double speed
required property string clipThumbId
required property bool forceReloadAudioThumb
- required property bool dragInProgress
- required property bool snapping
+ required property bool clipDragInProgress
+ required property bool someDragInProgress
+ required property int snapping
+ required property bool isMixSelected
+ required property bool isDragProxied
+ required property int thumbsFormat
+ required property Item dragContainer
+ required property var dragProxyCursorShape
+ required property bool isDragProxyAreaPressed
+ required property int timelineScrollViewWidth
+ required property bool isTimlineCursorOnClip
+ required property bool minClipWidthForViews
+ required property int scrollStart
+ required property bool dragProxyMovesComposition
+ required property int trimmingOffset
readonly property int maxLabelWidth: 20 * K.UiUtils.baseSizeMedium * Math.sqrt(timeScale)
@@ -93,14 +106,13 @@ Rectangle {
readonly property bool isLocked: parentTrack && parentTrack.isLocked === true
property color borderColor: "#000000"
property bool isComposition: false
- readonly property int slipOffset: boundValue(outPoint - maxDuration + 1, root.trimmingOffset, inPoint)
- property int scrollStart: visible ? scrollView.contentX - (clipRoot.modelStart * timeScale) : 0
+ readonly property int slipOffset: boundValue(outPoint - maxDuration + 1, trimmingOffset, inPoint)
readonly property bool trimInProgress: trimInMixArea.pressed || trimInMouseArea.pressed || trimOutMouseArea.pressed
readonly property bool isUserInteracting: mouseArea.pressed || mixArea.pressed || trimInProgress || fadeInMouseArea.pressed || fadeOutMouseArea.pressed
- readonly property bool hideClipViews: !visible || clipRoot.width < root.minClipWidthForViews
+ readonly property bool hideClipViews: !visible || clipRoot.width < minClipWidthForViews
readonly property bool hideDecorations: !K.KdenliveSettings.showClipOverlays || !visible || trimInMouseArea.drag.active || trimOutMouseArea.drag.active || fadeInMouseArea.drag.active || fadeOutMouseArea.drag.active
width : Math.round(clipDuration * timeScale)
- opacity: dragInProgress ? 0.8 : 1.0
+ opacity: clipDragInProgress ? 0.8 : 1.0
signal trimmingIn(var clip, real newDuration, bool shiftTrim, bool controlTrim)
signal trimmedIn(var clip, bool shiftTrim, bool controlTrim)
@@ -114,6 +126,15 @@ Rectangle {
signal seek(int pos)
signal zoomByWheel(var wheel)
+ signal initDrag(var itemCoord)
+ signal endDrag()
+ signal endDragIfFocused(int itemId)
+
+ signal clearGroupTrimData()
+ signal regainFocus(var x, var y)
+
+ signal blockAutoScroll(bool enabled)
+
onVisibleChanged: {
if (clipRoot.visible) {
updateLabelOffset()
@@ -129,7 +150,7 @@ Rectangle {
if (isAudio && thumbsLoader.item) {
(thumbsLoader.item as ClipAudioThumbs).reload(1)
}
- if (!clipRoot.hideClipViews && clipRoot.width > scrollView.width) {
+ if (!clipRoot.hideClipViews && clipRoot.width > timelineScrollViewWidth) {
let kfrView = effectRow.item as KeyframeView
if (kfrView && kfrView.kfrCanvas) {
kfrView.kfrCanvas.requestPaint()
@@ -246,7 +267,7 @@ Rectangle {
function updateDrag() {
var itemPos = Qt.rect(0, 0, clipRoot.width, clipRoot.height)
- initDrag(clipRoot, itemPos, clipRoot.clipId, clipRoot.modelStart, clipRoot.trackId, false)
+ clipRoot.initDrag(itemPos)
}
function showClipInfo() {
@@ -305,17 +326,17 @@ Rectangle {
} else {
clipRoot.controller.copyClipEffect(clipRoot.clipId, dropSource)
}
- if (K.KdenliveSettings.seekonaddeffect && (proxy.position < clipRoot.modelStart || proxy.position > clipRoot.modelStart + clipRoot.clipDuration)) {
+ if (K.KdenliveSettings.seekonaddeffect && !clipRoot.isTimlineCursorOnClip) {
// If timeline cursor is not inside clip, seek to drop position
clipRoot.seek(clipRoot.modelStart + drag.x / clipRoot.timeScale)
}
dropSource = ''
drag.acceptProposedAction()
- root.regainFocus(mapToItem(root, drag.x, drag.y))
+ clipRoot.regainFocus(drag.x, drag.y)
//console.log('KFR VIEW VISIBLE: ', effectRow.visible, ', SOURCE: ', effectRow.source, '\n HIDEVIEW:', clipRoot.hideClipViews<<', UNDEFINED: ', (clipRoot.keyframeModel == undefined))
}
onExited: {
- root.endDrag()
+ clipRoot.endDrag()
}
}
MouseArea {
@@ -324,14 +345,15 @@ Rectangle {
anchors.fill: clipRoot
acceptedButtons: Qt.RightButton
hoverEnabled: !clipRoot.isPanning && (K.Core.activeTool === K.ToolType.SelectTool || K.Core.activeTool === K.ToolType.RippleTool)
- cursorShape: (trimInMouseArea.drag.active || trimOutMouseArea.drag.active)? Qt.SizeHorCursor : dragProxyArea.cursorShape
+ cursorShape: (trimInMouseArea.drag.active || trimOutMouseArea.drag.active)? Qt.SizeHorCursor : clipRoot.dragProxyCursorShape
+
onPressed: mouse => {
clipRoot.makeMainItem(true)
if (mouse.button == Qt.RightButton) {
if (clipRoot.timeline.selection.indexOf(clipRoot.clipId) === -1) {
clipRoot.controller.requestAddToSelection(clipRoot.clipId, true)
}
- clipRoot.showClipMenu(clipRoot.clipId, Math.round(mouse.x / clipRoot.timeline.scaleFactor))
+ clipRoot.showClipMenu(clipRoot.clipId, Math.round(mouse.x / clipRoot.timeScale))
}
}
Keys.onShortcutOverride: event => {event.accepted = clipRoot.isGrabbed && (event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Up || event.key === Qt.Key_Down || event.key === Qt.Key_Escape)}
@@ -384,7 +406,7 @@ Rectangle {
}
if (clipRoot.clipId > -1) {
var itemPos = Qt.rect(0, 0, width, height)
- initDrag(clipRoot, itemPos, clipRoot.clipId, clipRoot.modelStart, clipRoot.trackId, false)
+ clipRoot.initDrag(itemPos)
}
clipRoot.showClipInfo()
}
@@ -393,8 +415,8 @@ Rectangle {
if (clipRoot.isPanning) {
return
}
- if (!dragProxyArea.pressed) {
- root.endDragIfFocused(clipRoot.clipId)
+ if (!clipRoot.isDragProxyAreaPressed) {
+ clipRoot.endDragIfFocused(clipRoot.clipId)
}
if (pressed) {
if (!trimInMouseArea.containsMouse && !trimOutMouseArea.containsMouse && !compInArea.containsMouse && !compOutArea.containsMouse) {
@@ -411,7 +433,9 @@ Rectangle {
visible: !clipRoot.isAudio
opacity: clipRoot.clipState === K.PlaylistState.Disabled ? 0.2 : 1
parentClip: clipRoot
- initialSpeed: clipRoot.speed
+ thumbsFormat: clipRoot.thumbsFormat
+ timeScale: clipRoot.timeScale
+ timelineScrollViewWidth: clipRoot.timelineScrollViewWidth
}
}
@@ -529,10 +553,11 @@ Rectangle {
Rectangle {
id: mixBackground
property double mixPos: mixBackground.width - clipRoot.mixCut * clipRoot.timeScale
- property bool mixSelected: root.selectedMix == clipRoot.clipId
anchors.fill: parent
visible: clipRoot.mixDuration > 0
- color: mixSelected ? Qt.rgba(clipRoot.timeline.selectionColor.r, clipRoot.timeline.selectionColor.g, clipRoot.timeline.selectionColor.b, 0.5) : "transparent"
+ color: clipRoot.isMixSelected
+ ? Qt.rgba(clipRoot.timeline.selectionColor.r, clipRoot.timeline.selectionColor.g, clipRoot.timeline.selectionColor.b, 0.5)
+ : "transparent"
Loader {
active: mixBackground.visible && container.handleVisible && mixContainer.width > 2 * K.UiUtils.baseSizeMedium
asynchronous: true
@@ -540,8 +565,8 @@ Rectangle {
sourceComponent: MixShape {}
}
- opacity: mixArea.containsMouse || trimInMixArea.pressed || trimInMixArea.containsMouse || mixSelected ? 1 : 0.7
- border.color: mixSelected ? clipRoot.timeline.selectionColor : "white"
+ opacity: mixArea.containsMouse || trimInMixArea.pressed || trimInMixArea.containsMouse || clipRoot.isMixSelected ? 1 : 0.7
+ border.color: clipRoot.isMixSelected ? clipRoot.timeline.selectionColor : "white"
border.width: clipRoot.mixDuration > 0 ? 2 : 0
radius: 3
Rectangle {
@@ -568,7 +593,7 @@ Rectangle {
}
clipRoot.controller.requestMixSelection(clipRoot.clipId);
if (mouse.button == Qt.RightButton) {
- clipRoot.showMixMenu(clipRoot.clipId, Math.round(mouse.x / clipRoot.timeline.scaleFactor))
+ clipRoot.showMixMenu(clipRoot.clipId, Math.round(mouse.x / clipRoot.timeScale))
}
}
onEntered: {
@@ -1070,7 +1095,9 @@ Rectangle {
return false
}
- enabled: !clipRoot.isLocked && (pressed || (container.handleVisible && (mixArea.enabled || clipRoot.mixDuration == 0))) && clipRoot.clipId == dragProxy.draggedItem
+ enabled: !clipRoot.isLocked
+ && (pressed || (container.handleVisible && (mixArea.enabled || clipRoot.mixDuration == 0)))
+ && clipRoot.isDragProxied
hoverEnabled: true
drag.target: trimInMouseArea
drag.axis: Drag.XAxis
@@ -1104,7 +1131,7 @@ Rectangle {
if (!controlTrim && K.Core.activeTool !== K.ToolType.RippleTool) {
clipRoot.updateDrag()
} else {
- root.endDrag()
+ clipRoot.endDrag()
}
} else {
if (K.Core.activeTool === K.ToolType.RippleTool) { //TODO
@@ -1114,8 +1141,7 @@ Rectangle {
} else if (shiftTrim) {
clipRoot.controller.requestRemoveFromSelection(clipRoot.clipId)
}
-
- root.groupTrimData = undefined
+ clipRoot.clearGroupTrimData()
}
}
onDoubleClicked: {
@@ -1156,10 +1182,10 @@ Rectangle {
}
}
onEntered: {
- if (!pressed && !root.isDragging()) {
+ if (!pressed && !clipRoot.someDragInProgress) {
trimIn.opacity = 1
var itemPos = Qt.rect(0, 0, width, height)
- initDrag(clipRoot, itemPos, clipRoot.clipId, clipRoot.modelStart, clipRoot.trackId, false)
+ clipRoot.initDrag(itemPos)
var s = KI18n.i18n("In:%1, Position:%2", clipRoot.timeline.simplifiedTC(clipRoot.inPoint),clipRoot.timeline.simplifiedTC(clipRoot.modelStart))
clipRoot.timeline.showToolTip(s)
if (clipRoot.mixDuration == 0) {
@@ -1195,7 +1221,9 @@ Rectangle {
hoverEnabled: true
visible: enabled && (K.Core.activeTool === K.ToolType.SelectTool
|| (K.Core.activeTool === K.ToolType.RippleTool && clipRoot.mixDuration <= 0))
- enabled: !clipRoot.isLocked && (pressed || container.handleVisible) && clipRoot.clipId == dragProxy.draggedItem
+ enabled: !clipRoot.isLocked
+ && (pressed || container.handleVisible)
+ && clipRoot.isDragProxied
property bool shiftTrim: false
property bool controlTrim: false
property bool sizeChanged: false
@@ -1231,7 +1259,7 @@ Rectangle {
if (!controlTrim && K.Core.activeTool !== K.ToolType.RippleTool) {
clipRoot.updateDrag()
} else {
- root.endDrag()
+ clipRoot.endDrag()
}
} else {
if (K.Core.activeTool === K.ToolType.RippleTool) {
@@ -1241,7 +1269,7 @@ Rectangle {
} else if (shiftTrim) {
clipRoot.controller.requestRemoveFromSelection(clipRoot.clipId)
}
- root.groupTrimData = undefined
+ clipRoot.clearGroupTrimData()
}
}
onDoubleClicked: {
@@ -1261,10 +1289,10 @@ Rectangle {
}
}
onEntered: {
- if (!pressed && !root.isDragging()) {
+ if (!pressed && !clipRoot.someDragInProgress) {
trimOut.opacity = 1
var itemPos = Qt.rect(0, 0, width, height)
- initDrag(clipRoot, itemPos, clipRoot.clipId, clipRoot.modelStart, clipRoot.trackId, false)
+ clipRoot.initDrag(itemPos)
var s = KI18n.i18n("Out:%1, Position:%2", clipRoot.timeline.simplifiedTC(clipRoot.outPoint),clipRoot.timeline.simplifiedTC(clipRoot.modelStart + clipRoot.clipDuration))
clipRoot.timeline.showToolTip(s)
if (!fadeOutMouseArea.containsMouse) {
@@ -1596,11 +1624,48 @@ Rectangle {
when: effectRow.status == Loader.Ready && effectRow.item
restoreMode: Binding.RestoreBindingOrValue
}
+ Binding {
+ target: effectRow.item
+ property: "timelineScrollViewWidth"
+ value: clipRoot.timelineScrollViewWidth
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "timeline"
+ value: clipRoot.timeline
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "timeScale"
+ value: clipRoot.timeScale
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "isPanning"
+ value: clipRoot.isPanning
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+
}
Connections {
target: effectRow.item
function onSeek(position) { clipRoot.seek(position) }
}
+ Connections {
+ target: effectRow.item
+ function onUpdateEffectKeyframe(clipId, oldFrame, newFrame) { clipRoot.timeline.updateEffectKeyframe(clipId, oldFrame, newFrame) }
+ }
+ Connections {
+ target: effectRow.item
+ function onBlockAutoScroll(enabled) { clipRoot.blockAutoScroll(enabled) }
+ }
}
states: [
@@ -1664,7 +1729,7 @@ Rectangle {
width: compInArea.containsMouse ? parent.width : 5
height: width
radius: width / 2
- visible: clipRoot.width > 4 * parent.width && mouseArea.containsMouse && !clipRoot.dragInProgress
+ visible: clipRoot.width > 4 * parent.width && mouseArea.containsMouse && !clipRoot.clipDragInProgress
color: Qt.darker('mediumpurple')
border.width: 3
border.color: 'mediumpurple'
@@ -1705,7 +1770,7 @@ Rectangle {
width: compOutArea.containsMouse ? parent.height : 5
height: width
radius: width / 2
- visible: clipRoot.width > 4 * parent.width && mouseArea.containsMouse && !clipRoot.dragInProgress
+ visible: clipRoot.width > 4 * parent.width && mouseArea.containsMouse && !clipRoot.clipDragInProgress
color: Qt.darker('mediumpurple')
border.width: 3
border.color: 'mediumpurple'
@@ -1727,7 +1792,7 @@ Rectangle {
drag.axis: Drag.XAxis
drag.minimumX: - Math.ceil(width / 2)
drag.maximumX: container.width + Math.ceil(width / 4)
- visible: container.handleVisible && mouseArea.containsMouse && !clipRoot.dragInProgress
+ visible: container.handleVisible && mouseArea.containsMouse && !clipRoot.clipDragInProgress
property int startFadeOut
property int lastDuration: -1
property int startMousePos
@@ -1806,7 +1871,7 @@ Rectangle {
color: 'darkred'
border.width: 3
border.color: 'red'
- enabled: !clipRoot.isLocked && !dragProxy.isComposition
+ enabled: !clipRoot.isLocked && !clipRoot.dragProxyMovesComposition
Drag.active: fadeOutMouseArea.drag.active
Behavior on width { NumberAnimation { duration: 100 } }
Rectangle {
@@ -1843,7 +1908,7 @@ Rectangle {
property int startMousePos
property bool dragStarted: false
property string fadeString: clipRoot.timeline.simplifiedTC(clipRoot.fadeIn)
- visible: container.handleVisible && mouseArea.containsMouse && !clipRoot.dragInProgress
+ visible: container.handleVisible && mouseArea.containsMouse && !clipRoot.clipDragInProgress
onClicked: {
if (clipRoot.fadeIn == 0) {
clipRoot.timeline.adjustFade(clipRoot.clipId, 'fadein', 0, -2)
@@ -1915,7 +1980,7 @@ Rectangle {
color: 'green'
border.width: 3
border.color: '#FF66FFFF'
- enabled: !clipRoot.isLocked && !dragProxy.isComposition
+ enabled: !clipRoot.isLocked && !clipRoot.dragProxyMovesComposition
Drag.active: fadeInMouseArea.drag.active
Behavior on width { NumberAnimation { duration: 100 } }
Rectangle {
diff --git a/src/timeline2/view/qml/ClipThumbs.qml b/src/timeline2/view/qml/ClipThumbs.qml
index 188dccacd7..0758fe63ff 100644
--- a/src/timeline2/view/qml/ClipThumbs.qml
+++ b/src/timeline2/view/qml/ClipThumbs.qml
@@ -20,16 +20,18 @@ Row {
// When increasing the Qt dependency, we can revert to use :
// required property Clip parentClip
required property var parentClip
- property real initialSpeed: 1
- property bool fixedThumbs: parentClip.itemType === K.ClipType.Image || parentClip.itemType === K.ClipType.Text || parentClip.itemType === K.ClipType.TextTemplate
- property int thumbWidth: parent.height * K.Core.getCurrentDar()
- property bool enableCache: parentClip.itemType === K.ClipType.Video || parentClip.itemType === K.ClipType.AV
+ required property int thumbsFormat
+ required property real timeScale
+ required property int timelineScrollViewWidth
+ readonly property bool fixedThumbs: parentClip.itemType === K.ClipType.Image || parentClip.itemType === K.ClipType.Text || parentClip.itemType === K.ClipType.TextTemplate
+ readonly property int thumbWidth: parent.height * K.Core.getCurrentDar()
+ readonly property bool enableCache: parentClip.itemType === K.ClipType.Video || parentClip.itemType === K.ClipType.AV
Repeater {
id: thumbRepeater
// switching the model allows one to have different view modes.
// We set the model to the number of frames we want to show
- model: switch (parentTrack.trackThumbsFormat) {
+ model: switch (thumbRow.thumbsFormat) {
case 0:
// in/out
if (parent.width > thumbRow.thumbWidth) {
@@ -57,12 +59,12 @@ Row {
property real imageWidth: Math.max(thumbRow.thumbWidth, parent.width / thumbRepeater.count)
property int thumbStartFrame: thumbRow.fixedThumbs ? 0 :
(thumbRow.parentClip.speed >= 0)
- ? Math.round(thumbRow.parentClip.inPoint * thumbRow.initialSpeed)
- : Math.round((thumbRow.parentClip.maxDuration - thumbRow.parentClip.inPoint) * -thumbRow.initialSpeed - 1)
+ ? Math.round(thumbRow.parentClip.inPoint * thumbRow.parentClip.speed)
+ : Math.round((thumbRow.parentClip.maxDuration - thumbRow.parentClip.inPoint) * -thumbRow.parentClip.speed - 1)
property int thumbEndFrame: thumbRow.fixedThumbs ? 0 :
(thumbRow.parentClip.speed >= 0)
- ? Math.round(thumbRow.parentClip.outPoint * thumbRow.initialSpeed)
- : Math.round((thumbRow.parentClip.maxDuration - thumbRow.parentClip.outPoint) * -thumbRow.initialSpeed - 1)
+ ? Math.round(thumbRow.parentClip.outPoint * thumbRow.parentClip.speed)
+ : Math.round((thumbRow.parentClip.maxDuration - thumbRow.parentClip.outPoint) * -thumbRow.parentClip.speed - 1)
Image {
id: thumbImage
@@ -79,12 +81,12 @@ Row {
? 0
: thumbRepeater.count < 3
? (index === 0 ? thumbRepeater.thumbStartFrame : thumbRepeater.thumbEndFrame)
- : Math.floor(thumbRow.parentClip.inPoint * thumbRow.initialSpeed + Math.round((index) * width / timeline.scaleFactor)* thumbRow.parentClip.speed)
+ : Math.floor((thumbRow.parentClip.inPoint + Math.round(index * width / thumbRow.timeScale))* thumbRow.parentClip.speed)
horizontalAlignment: thumbRepeater.count < 3
? (index === 0 ? Image.AlignLeft : Image.AlignRight)
: Image.AlignLeft
source: thumbRepeater.count < 3 ? thumbPath
- : (index * width < thumbRow.parentClip.scrollStart - width || index * width > thumbRow.parentClip.scrollStart + scrollView.width)? '' : thumbPath
+ : (index * width < thumbRow.parentClip.scrollStart - width || index * width > thumbRow.parentClip.scrollStart + thumbRow.timelineScrollViewWidth) ? '' : thumbPath
onStatusChanged: {
if (status === Image.Ready && (index === 0 || index === thumbRepeater.count - 1)) {
thumbPlaceholder.source = source
diff --git a/src/timeline2/view/qml/Composition.qml b/src/timeline2/view/qml/Composition.qml
index 50f4237da3..db54d5380f 100644
--- a/src/timeline2/view/qml/Composition.qml
+++ b/src/timeline2/view/qml/Composition.qml
@@ -42,6 +42,13 @@ Item {
required property int aTrack
required property int clipId // Id of the clip in the model
required property int displayHeight
+ required property int scrollStart
+ required property int minClipWidthForViews
+ required property bool clipDragInProgress
+ required property Item dragContainer
+ required property int timelineScrollViewWidth
+ required property var dragProxyCursorShape
+ required property bool isDragProxyAreaPressed
property bool isAudio: false
property int originalTrackId: trackId
@@ -56,10 +63,8 @@ Item {
property color borderColor: 'black'
readonly property bool trimInProgress: trimInMouseArea.pressed || trimOutMouseArea.pressed
readonly property bool isUserInteracting: mouseArea.pressed || trimInProgress
- readonly property bool hideCompoViews: !visible || width < root.minClipWidthForViews
+ readonly property bool hideCompoViews: !visible || width < minClipWidthForViews
readonly property bool hideDecorations: !K.KdenliveSettings.showClipOverlays || trimInMouseArea.drag.active || trimOutMouseArea.drag.active
- visible: scrollView.lastVisibleFrame > compositionRoot.modelStart && scrollView.firstVisibleFrame <= (compositionRoot.modelStart + compositionRoot.clipDuration)
- property int scrollStart: visible ? scrollView.contentX - (compositionRoot.modelStart * compositionRoot.timeScale) : 0
// We set coordinates to ensure the item can be found using childAt in timeline.qml getItemAtPosq
property int trackOffset: 0
@@ -73,12 +78,19 @@ Item {
signal seek(int pos)
signal zoomByWheel(var wheel)
+ signal blockAutoScroll(bool enabled)
+ signal showCompositionMenu()
+ signal makeMainItem()
+
+ signal initDrag(var itemCoord)
+ signal endDragIfFocused(int itemId)
+
onScrollStartChanged: {
if (!compositionRoot.visible) {
return
}
updateLabelOffset()
- if (compositionRoot.width > scrollView.width) {
+ if (compositionRoot.width > timelineScrollViewWidth) {
let kfrView = effectRow.item as KeyframeView
if (kfrView && kfrView.kfrCanvas) {
kfrView.kfrCanvas.requestPaint()
@@ -171,7 +183,7 @@ Item {
function updateDrag() {
console.log('XXXXXXXXXXXXXXX\n\nXXXXXXXXXXXXX \nUPDATING COMPO DRAG')
var itemPos = Qt.rect(0, displayRect.y, displayRect.width, displayRect.height)
- initDrag(compositionRoot, itemPos, compositionRoot.clipId, compositionRoot.modelStart, compositionRoot.trackId, true)
+ compositionRoot.initDrag(itemPos)
}
Rectangle {
@@ -185,7 +197,7 @@ Item {
color: Qt.darker('mediumpurple')
border.color: compositionRoot.grouped ? compositionRoot.timeline.groupColor : mouseArea.containsMouse ? activePalette.highlight : compositionRoot.borderColor
border.width: compositionRoot.isGrabbed ? 8 : 2
- opacity: dragProxyArea.drag.active && dragProxy.draggedItem == compositionRoot.clipId ? 0.5 : 1.0
+ opacity: compositionRoot.clipDragInProgress ? 0.5 : 1.0
states: [
State {
@@ -219,7 +231,7 @@ Item {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.RightButton
- enabled: !compositionRoot.isPanning && K.Core.activeTool === K.ToolType.SelectTool && !dragProxyArea.pressed
+ enabled: !compositionRoot.isPanning && K.Core.activeTool === K.ToolType.SelectTool && !compositionRoot.isDragProxyAreaPressed
hoverEnabled: !compositionRoot.isPanning && K.Core.activeTool === K.ToolType.SelectTool
Keys.onShortcutOverride: event => {event.accepted = compositionRoot.isGrabbed && (event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Up || event.key === Qt.Key_Down || event.key === Qt.Key_Escape)}
Keys.onLeftPressed: event => {
@@ -239,16 +251,16 @@ Item {
Keys.onEscapePressed: {
compositionRoot.timeline.grabCurrent()
}
- cursorShape: (trimInMouseArea.drag.active || trimOutMouseArea.drag.active)? Qt.SizeHorCursor : dragProxyArea.cursorShape
+ cursorShape: (trimInMouseArea.drag.active || trimOutMouseArea.drag.active) ? Qt.SizeHorCursor : compositionRoot.dragProxyCursorShape
onPressed: mouse => {
compositionRoot.forceActiveFocus();
- root.mainItemId = compositionRoot.clipId
+ compositionRoot.makeMainItem()
if (mouse.button == Qt.RightButton) {
if (compositionRoot.timeline.selection.indexOf(compositionRoot.clipId) === -1) {
compositionRoot.controller.requestAddToSelection(compositionRoot.clipId, true)
}
- root.showCompositionMenu()
+ compositionRoot.showCompositionMenu()
}
}
onEntered: {
@@ -257,7 +269,7 @@ Item {
compositionRoot.timeline.showToolTip(s)
}
onExited: {
- root.endDragIfFocused(compositionRoot.clipId)
+ compositionRoot.endDragIfFocused(compositionRoot.clipId)
if (!trimInMouseArea.containsMouse && !trimOutMouseArea.containsMouse) {
compositionRoot.timeline.showToolTip()
}
@@ -525,11 +537,47 @@ Item {
value: compositionRoot.clipId
when: effectRow.status == Loader.Ready && effectRow.item
}
+ Binding {
+ target: effectRow.item
+ property: "timelineScrollViewWidth"
+ value: compositionRoot.timelineScrollViewWidth
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "timeline"
+ value: compositionRoot.timeline
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "timeScale"
+ value: compositionRoot.timeScale
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
+ Binding {
+ target: effectRow.item
+ property: "isPanning"
+ value: compositionRoot.isPanning
+ when: effectRow.status == Loader.Ready && effectRow.item
+ restoreMode: Binding.RestoreBindingOrValue
+ }
}
Connections {
target: effectRow.item
function onSeek(position) { compositionRoot.seek(position) }
}
+ Connections {
+ target: effectRow.item
+ function onUpdateEffectKeyframe(clipId, oldFrame, newFrame) { compositionRoot.timeline.updateEffectKeyframe(clipId, oldFrame, newFrame) }
+ }
+ Connections {
+ target: effectRow.item
+ function onBlockAutoScroll(enabled) { compositionRoot.blockAutoScroll(enabled) }
+ }
}
}
}
diff --git a/src/timeline2/view/qml/KeyframeDelegate.qml b/src/timeline2/view/qml/KeyframeDelegate.qml
index 89edf6e8f3..b507bf0323 100644
--- a/src/timeline2/view/qml/KeyframeDelegate.qml
+++ b/src/timeline2/view/qml/KeyframeDelegate.qml
@@ -19,17 +19,22 @@ Rectangle {
required property K.TimelineController timeline
required property var kfrModel
required property double timeScale
+ required property int keyframeModelOffset
required property int parentInPoint
required property int parentItemId
required property bool allowUserInteraction
+ required property int keyframeContainerHeight
+ required property int keyframeContainerWidth
readonly property bool isUserInteracting: kfMouseArea.pressed || kf1MouseArea.pressed
readonly property bool isInsideVisibleAreaX: x > K.UiUtils.baseSizeMedium / 2 && x < parent.width - K.UiUtils.baseSizeMedium / 2
signal requestRepaint()
signal seek(int position)
+ signal seekToIx(int ix)
signal keyframeSelected(int index, bool add, bool setActive)
signal resetSelection()
+ signal focusKeyframeContainer()
property int frame : model.frame
property int frameType : model.type
@@ -50,6 +55,9 @@ Rectangle {
}
width: Math.max(1, timeScale / 2)
color: kfMouseArea.containsMouse ? 'darkred' : 'transparent'
+
+ SystemPalette { id: activePalette }
+
MouseArea {
id: kfMouseArea
anchors.fill: parent
@@ -81,7 +89,7 @@ Rectangle {
parent.x = keyframe.parentInPoint * keyframe.timeScale
return
}
- var newPos = Math.min(Math.round(parent.x / keyframe.timeScale), Math.round(keyframeContainer.width / keyframe.timeScale) - 1)
+ var newPos = Math.min(Math.round(parent.x / keyframe.timeScale), Math.round(keyframe.keyframeContainerWidth / keyframe.timeScale) - 1)
if (newPos < 1) {
newPos = 1
}
@@ -104,12 +112,12 @@ Rectangle {
Rectangle {
id: keyframeVal
x: - K.UiUtils.baseSizeMedium / 2
- y: keyframeContainer.height - keyframe.value - K.UiUtils.baseSizeMedium / 2
+ y: keyframe.keyframeContainerHeight - keyframe.value - K.UiUtils.baseSizeMedium / 2
width: K.UiUtils.baseSizeMedium
height: width
radius: width / 2
- color: keyframe.model.active ? 'red' : keyframe.model.selected ? 'orange' : (kf1MouseArea.containsMouse || kf1MouseArea.pressed) ? root.textColor : root.videoColor
- border.color: kf1MouseArea.containsMouse || kf1MouseArea.pressed ? activePalette.highlight : root.textColor
+ color: keyframe.model.active ? 'red' : keyframe.model.selected ? 'orange' : (kf1MouseArea.containsMouse || kf1MouseArea.pressed) ? activePalette.text : keyframe.timeline.videoColor
+ border.color: kf1MouseArea.containsMouse || kf1MouseArea.pressed ? activePalette.highlight : activePalette.text
MouseArea {
id: kf1MouseArea
@@ -127,7 +135,7 @@ Rectangle {
drag.axis = keyframe.model.moveOnly ? Drag.XAxis : (mouse.modifiers & Qt.ShiftModifier) ? Drag.YAxis : Drag.XAndYAxis
}
onClicked: mouse => {
- keyframeContainer.focus = true
+ keyframe.focusKeyframeContainer()
if (mouse.modifiers & Qt.ControlModifier && keyframe.model.selected) {
keyframe.keyframeSelected(keyframe.index, true, false)
} else {
@@ -135,7 +143,7 @@ Rectangle {
}
var ix = keyframe.kfrModel.activeKeyframe()
if (ix > -1) {
- keyframe.seek(keyframes.itemAt(ix).frame + keyframeContainer.modelStart - keyframe.parentInPoint)
+ keyframe.seekToIx(ix)
}
}
onReleased: {
@@ -144,7 +152,7 @@ Rectangle {
}
var newPos = keyframe.frame == keyframe.parentInPoint ? keyframe.parentInPoint : Math.round((keyframe.x + parent.x + K.UiUtils.baseSizeMedium / 2) / keyframe.timeScale) + keyframe.parentInPoint
if (newPos === keyframe.frame && keyframe.value == keyframe.height - parent.y - K.UiUtils.baseSizeMedium / 2) {
- var pos = keyframeContainer.modelStart + keyframe.frame - keyframe.parentInPoint
+ var pos = keyframe.keyframeModelOffset + keyframe.frame - keyframe.parentInPoint
keyframe.seek(pos)
return
}
@@ -179,7 +187,7 @@ Rectangle {
if (keyframe.frame == keyframe.parentInPoint) {
parent.x = - K.UiUtils.baseSizeMedium / 2
} else {
- var newPos = Math.min(Math.round((parent.x + K.UiUtils.baseSizeMedium / 2) / keyframe.timeScale), Math.round(keyframeContainer.width / keyframe.timeScale) - keyframe.frame + keyframeContainer.inPoint - 1)
+ var newPos = Math.min(Math.round((parent.x + K.UiUtils.baseSizeMedium / 2) / keyframe.timeScale), Math.round(keyframe.keyframeContainerWidth / keyframe.timeScale) - keyframe.frame + keyframe.parentInPoint - 1)
if (keyframe.frame + newPos <= keyframe.parentInPoint) {
newPos = keyframe.parentInPoint + 1 - keyframe.frame
}
@@ -192,7 +200,7 @@ Rectangle {
}
}
keyframe.requestRepaint()
- newVal = (keyframeContainer.height - (parent.y + mouse.y)) / keyframeContainer.height
+ newVal = (keyframe.keyframeContainerHeight - (parent.y + mouse.y)) / keyframe.keyframeContainerHeight
movingVal = keyframe.kfrModel.realValue(Math.min(Math.max(newVal, 0), 1))
}
}
diff --git a/src/timeline2/view/qml/KeyframeView.qml b/src/timeline2/view/qml/KeyframeView.qml
index 4c491e2e09..fee1a3da48 100644
--- a/src/timeline2/view/qml/KeyframeView.qml
+++ b/src/timeline2/view/qml/KeyframeView.qml
@@ -22,8 +22,14 @@ Rectangle
property bool selected
property var kfrModel
property int scrollStart
+ property int timelineScrollViewWidth
+ property real timeScale
+ property bool isPanning
+ property var timeline
property alias kfrCanvas: keyframecanvas
signal seek(int position)
+ signal updateEffectKeyframe(int clipId, int oldFrame, int newFrame)
+ signal blockAutoScroll(bool enabled)
onKfrCountChanged: {
parent.hasKeyframes = kfrCount > 1
@@ -58,7 +64,7 @@ Rectangle
var oldFrame = activeKeyframe.value
var newPos = Math.max(oldFrame - 1 - keyframeContainer.inPoint, 0)
if (newPos != oldFrame) {
- timeline.updateEffectKeyframe(clipId, oldFrame, newPos)
+ keyframeContainer.updateEffectKeyframe(clipId, oldFrame, newPos)
event.accepted = true
}
}
@@ -73,7 +79,7 @@ Rectangle
var oldFrame = activeKeyframe.value
var newPos = Math.min(oldFrame + 1 - keyframeContainer.inPoint, keyframeContainer.outPoint - keyframeContainer.inPoint)
if (newPos != oldFrame) {
- timeline.updateEffectKeyframe(clipId, oldFrame, newPos)
+ keyframeContainer.updateEffectKeyframe(clipId, oldFrame, newPos)
}
}
event.accepted = true
@@ -108,11 +114,12 @@ Rectangle
model: keyframeContainer.kfrModel
KeyframeDelegate {
id: keyframe
- timeScale: root.timeScale
+ timeScale: keyframeContainer.timeScale
kfrModel: keyframeContainer.kfrModel
- timeline: root.timeline
+ timeline: keyframeContainer.timeline
+ keyframeModelOffset: keyframeContainer.modelStart
parentInPoint: keyframeContainer.inPoint
- allowUserInteraction: !root.isPanning
+ allowUserInteraction: !keyframeContainer.isPanning
parentItemId: keyframeContainer.clipId
onRequestRepaint: {
@@ -123,6 +130,10 @@ Rectangle
keyframeContainer.seek(position)
}
+ onSeekToIx: (ix) => {
+ keyframeContainer.seek((keyframes.itemAt(ix) as KeyframeDelegate).frame + keyframe.keyframeModelOffset - keyframe.parentInPoint)
+ }
+
onKeyframeSelected: (index, add, setActive) => {
keyframeContainer.kfrModel.setActiveKeyframe(setActive ? keyframe.index : -1)
keyframeContainer.activeIndex = setActive ? index : -1
@@ -131,7 +142,9 @@ Rectangle
onResetSelection: { keyframeContainer.resetSelection() }
- onIsUserInteractingChanged: { root.blockAutoScroll = isUserInteracting }
+ onIsUserInteractingChanged: { keyframeContainer.blockAutoScroll(isUserInteracting) }
+
+ onFocusKeyframeContainer: () => { keyframeContainer.focus = true }
}
}
}
@@ -139,10 +152,10 @@ Rectangle
id: keyframecanvas
contextType: "2d"
renderStrategy: Canvas.Threaded
- property int offset: keyframeContainer.scrollStart < 0 || parent.width <= scrollView.width ? 0 : keyframeContainer.scrollStart
+ property int offset: keyframeContainer.scrollStart < 0 || parent.width <= keyframeContainer.timelineScrollViewWidth ? 0 : keyframeContainer.scrollStart
anchors.left: parent.left
anchors.leftMargin: offset
- width: keyframeContainer.kfrCount > 0 ? Math.min(parent.width, scrollView.width) : 0
+ width: keyframeContainer.kfrCount > 0 ? Math.min(parent.width, keyframeContainer.timelineScrollViewWidth) : 0
height: keyframeContainer.kfrCount > 0 ? parent.height : 0
opacity: keyframeContainer.selected ? 1 : 0.5
Component {
@@ -165,7 +178,7 @@ Rectangle
Path {
id: myPath
startX: 0
- startY: parent.height
+ startY: keyframeContainer.parent.height
}
onPaint: {
@@ -428,7 +441,7 @@ Rectangle
paths.push(compline.createObject(keyframecanvas, {"x": xpos, "y": ypos} ))
break;
}
- if (xpos > scrollView.width) {
+ if (xpos > keyframeContainer.timelineScrollViewWidth) {
break;
}
}
diff --git a/src/timeline2/view/qml/Ruler.qml b/src/timeline2/view/qml/Ruler.qml
index 9df9a1ceea..58c2be7900 100644
--- a/src/timeline2/view/qml/Ruler.qml
+++ b/src/timeline2/view/qml/Ruler.qml
@@ -21,6 +21,9 @@ Item {
required property K.TimelineItemModel controller
required property K.MonitorProxy monitorProxy
required property K.MarkerSortModel guidesModel
+ required property int snapping
+ required property int rulercontainerWidth
+ required property int scrollViewContentX
FontMetrics {
id: fontMetrics
@@ -34,21 +37,25 @@ Item {
// The space we want between each ticks in the ruler
property real tickSpacing: timeline.scaleFactor
property alias rulerZone : zone
- property int workingPreview : timeline.workingPreview
- property int timecodeOffset : timeline.timecodeOffset
+ readonly property int workingPreview : timeline.workingPreview
+ readonly property int timecodeOffset : timeline.timecodeOffset
property int labelMod: 1
property int zoneHeight: Math.ceil(K.UiUtils.baseSizeMedium / 2) + 1
property bool showZoneLabels: false
readonly property bool resizeActive: zone.resizeActive || effectZone.resizeActive // Used to decide which mouse cursor we should display
property bool hoverGuide: false
property bool hoverResizeHandle: false
- property int cursorShape: resizeActive ? Qt.SizeHorCursor : hoverResizeHandle ? Qt.SizeHorCursor : hoverGuide ? Qt.PointingHandCursor : Qt.ArrowCursor
- property var effectZones: timeline.masterEffectZones
- property int guideLabelHeight: K.KdenliveSettings.showmarkers ? fontMetrics.height : 0
- property int previewHeight: Math.ceil(timecodeContainer.height / 5)
+ readonly property int cursorShape: resizeActive ? Qt.SizeHorCursor : hoverResizeHandle ? Qt.SizeHorCursor : hoverGuide ? Qt.PointingHandCursor : Qt.ArrowCursor
+ readonly property var effectZones: timeline.masterEffectZones
+ readonly property int guideLabelHeight: K.KdenliveSettings.showmarkers ? fontMetrics.height : 0
+ readonly property int previewHeight: Math.ceil(timecodeContainer.height / 5)
property color dimmedColor: (activePalette.text.r + activePalette.text.g + activePalette.text.b > 1.5) ? Qt.darker(activePalette.text, 1.3) : Qt.lighter(activePalette.text, 1.3)
property color dimmedColor2: (activePalette.text.r + activePalette.text.g + activePalette.text.b > 1.5) ? Qt.darker(activePalette.text, 2.2) : Qt.lighter(activePalette.text, 2.2)
+ signal showRulerMenu()
+ signal zoomByWheel(var wheel)
+ signal markerActivated(int frame)
+
function adjustStepSize() {
if (timeline.scaleFactor > 19) {
// Frame size >= 20 pixels
@@ -61,7 +68,7 @@ Item {
}
rulerRoot.labelMod = Math.max(1, Math.ceil((rulerRoot.labelSize + K.UiUtils.baseSizeMedium) / rulerRoot.tickSpacing))
//console.log('LABELMOD: ', Math.ceil((rulerRoot.labelSize + root.fontUnit) / rulerRoot.tickSpacing)))
- tickRepeater.model = Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2
+ tickRepeater.model = Math.ceil(rulercontainerWidth / rulerRoot.tickSpacing) + 2
}
function adjustFormat() {
@@ -73,7 +80,7 @@ Item {
function repaintRuler() {
// Enforce repaint
tickRepeater.model = 0
- tickRepeater.model = Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2
+ tickRepeater.model = Math.ceil(rulercontainerWidth / rulerRoot.tickSpacing) + 2
}
// Timeline preview stuff
@@ -225,7 +232,7 @@ Item {
onPositionChanged: mouse => {
if (pressed) {
var newFrame = Math.max(0, Math.round(guideRoot.model.frame + (mouseX - xOffset) / rulerRoot.timeline.scaleFactor))
- newFrame = rulerRoot.controller.suggestSnapPoint(newFrame, mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping)
+ newFrame = rulerRoot.controller.suggestSnapPoint(newFrame, mouse.modifiers & Qt.ShiftModifier ? -1 : rulerRoot.snapping)
if (newFrame != destFrame) {
var frame = rulerRoot.timeline.moveGuideWithoutUndo(movingMarkerId, newFrame)
if (frame > -1) {
@@ -241,7 +248,7 @@ Item {
rulerRoot.monitorProxy.position = guideRoot.model.frame
}
if (mouse.button == Qt.RightButton) {
- root.showRulerMenu()
+ rulerRoot.showRulerMenu()
}
}
onEntered: {
@@ -300,7 +307,7 @@ Item {
var deltaFrames = Math.round(realDeltaX / rulerRoot.timeline.scaleFactor)
var newStartPosition = Math.max(0, startPosition + deltaFrames)
- newStartPosition = rulerRoot.controller.suggestSnapPoint(newStartPosition, mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping)
+ newStartPosition = rulerRoot.controller.suggestSnapPoint(newStartPosition, mouse.modifiers & Qt.ShiftModifier ? -1 : rulerRoot.snapping)
var newDuration = Math.max(1, originalEndPosition - newStartPosition)
currentNewStartPosition = newStartPosition
@@ -387,7 +394,7 @@ Item {
var deltaFrames = Math.round(realDeltaX / rulerRoot.timeline.scaleFactor)
var newDuration = Math.max(1, startDuration + deltaFrames)
- newDuration = rulerRoot.controller.suggestSnapPoint(newDuration + startPosition, mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping) - startPosition
+ newDuration = rulerRoot.controller.suggestSnapPoint(newDuration + startPosition, mouse.modifiers & Qt.ShiftModifier ? -1 : rulerRoot.snapping) - startPosition
rangeSpan.width = Math.max(1, newDuration * rulerRoot.timeline.scaleFactor)
@@ -504,7 +511,7 @@ Item {
rulerRoot.timeline.moveGuideWithoutUndo(movingMarkerId, prevFrame)
rulerRoot.timeline.moveGuideById(movingMarkerId, destFrame)
} else {
- root.markerActivated(prevFrame)
+ rulerRoot.markerActivated(prevFrame)
}
rulerRoot.timeline.pauseGuideSorting(false)
anchors.left = parent.left
@@ -513,7 +520,7 @@ Item {
onPositionChanged: mouse => {
if (pressed) {
var newFrame = Math.max(0, Math.round(guideRoot.model.frame + (mouseX - xOffset) / rulerRoot.timeline.scaleFactor))
- newFrame = rulerRoot.controller.suggestSnapPoint(newFrame, mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping)
+ newFrame = rulerRoot.controller.suggestSnapPoint(newFrame, mouse.modifiers & Qt.ShiftModifier ? -1 : rulerRoot.snapping)
if (newFrame != destFrame) {
var frame = rulerRoot.timeline.moveGuideWithoutUndo(movingMarkerId, newFrame)
if (frame > -1) {
@@ -529,7 +536,7 @@ Item {
rulerRoot.monitorProxy.position = guideRoot.model.frame
}
if (mouse.button == Qt.RightButton) {
- root.showRulerMenu()
+ rulerRoot.showRulerMenu()
}
}
onEntered: {
@@ -555,8 +562,8 @@ Item {
anchors.right: parent.right
Repeater {
id: tickRepeater
- model: Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2
- property int offset: Math.floor(scrollView.contentX /rulerRoot.tickSpacing)
+ model: Math.ceil(rulerRoot.rulercontainerWidth / rulerRoot.tickSpacing) + 2
+ property int offset: Math.floor(rulerRoot.scrollViewContentX / rulerRoot.tickSpacing)
Item {
required property int index
property int realPos: (tickRepeater.offset + index) * rulerRoot.tickSpacing / rulerRoot.timeline.scaleFactor
@@ -591,7 +598,7 @@ Item {
var pos = Math.max(mouseX, 0)
var frame = Math.round(pos / rulerRoot.timeline.scaleFactor)
if (mouse.modifiers & Qt.AltModifier) {
- frame = rulerRoot.controller.suggestPlayheadSnapPoint(frame, root.snapping)
+ frame = rulerRoot.controller.suggestPlayheadSnapPoint(frame, rulerRoot.snapping)
}
rulerRoot.monitorProxy.position = frame
mouse.accepted = true
@@ -602,7 +609,7 @@ Item {
var pos = Math.max(mouseX, 0)
var frame = Math.round(pos / rulerRoot.timeline.scaleFactor)
if (mouse.modifiers & Qt.AltModifier) {
- frame = rulerRoot.controller.suggestPlayheadSnapPoint(frame, root.snapping)
+ frame = rulerRoot.controller.suggestPlayheadSnapPoint(frame, rulerRoot.snapping)
}
rulerRoot.monitorProxy.position = frame
}
@@ -614,7 +621,7 @@ Item {
}
onWheel: wheel => {
if (wheel.modifiers & Qt.ControlModifier) {
- root.zoomByWheel(wheel)
+ rulerRoot.zoomByWheel(wheel)
} else {
wheel.accepted = false
}
@@ -625,16 +632,10 @@ Item {
id: zone
z: 3
timeline: rulerRoot.timeline
- Binding {
- target: zone
- property: "frameIn"
- value: rulerRoot.timeline.zoneIn
- }
- Binding {
- target: zone
- property: "frameOut"
- value: rulerRoot.timeline.zoneOut
- }
+ frameIn: rulerRoot.timeline.zoneIn
+ frameOut: rulerRoot.timeline.zoneOut
+ snapping: rulerRoot.snapping
+ showZoneLabels: rulerRoot.showZoneLabels
color: rulerRoot.timeline.useRuler ? Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.9) :
Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.5)
anchors.bottom: parent.bottom
@@ -663,16 +664,10 @@ Item {
id: effectZone
z: 2
timeline: rulerRoot.timeline
- Binding {
- target: effectZone
- property: "frameIn"
- value: rulerRoot.timeline.effectZone.x
- }
- Binding {
- target: effectZone
- property: "frameOut"
- value: rulerRoot.timeline.effectZone.y
- }
+ frameIn: rulerRoot.timeline.effectZone.x
+ frameOut: rulerRoot.timeline.effectZone.y
+ snapping: rulerRoot.snapping
+ showZoneLabels: rulerRoot.showZoneLabels
color: "orchid"
anchors.bottom: parent.bottom
height: rulerRoot.zoneHeight - 1
diff --git a/src/timeline2/view/qml/RulerZone.qml b/src/timeline2/view/qml/RulerZone.qml
index 0c77b357fd..2ef444772b 100644
--- a/src/timeline2/view/qml/RulerZone.qml
+++ b/src/timeline2/view/qml/RulerZone.qml
@@ -14,8 +14,11 @@ Rectangle {
id: rzone
required property K.TimelineController timeline
- property int frameIn: 0
- property int frameOut: 0
+ required property int frameIn
+ required property int frameOut
+ required property int snapping
+ required property bool showZoneLabels
+
property bool resizeActive: false
signal updateZone(point start, point end, bool update)
@@ -84,12 +87,12 @@ Rectangle {
onPositionChanged: mouse => {
if (mouse.buttons === Qt.LeftButton) {
rzone.resizeActive = true
- var offset = Math.round(mouseX/ rzone.timeline.scaleFactor)
+ var offset = Math.round(mouseX / rzone.timeline.scaleFactor)
if (offset != 0) {
- var newPos = Math.max(0, controller.suggestSnapPoint(rzone.frameIn + offset,mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping))
+ var newPos = Math.max(0, rzone.timeline.suggestSnapPoint(rzone.frameIn + offset, mouse.modifiers & Qt.ShiftModifier ? -1 : rzone.snapping))
if (newPos == rzone.frameIn + offset) {
// No snap at start, check end
- var newPos = Math.max(0, controller.suggestSnapPoint(rzone.frameOut + offset,mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping))
+ var newPos = Math.max(0, rzone.timeline.suggestSnapPoint(rzone.frameOut + offset, mouse.modifiers & Qt.ShiftModifier ? -1 : rzone.snapping))
if (newPos == rzone.frameOut + offset) {
newPos = rzone.frameIn + offset
} else {
@@ -142,7 +145,7 @@ Rectangle {
id: durationRect
anchors.bottom: rzone.top
visible: (!rzone.timeline.useRuler && moveMouseArea.containsMouse && !moveMouseArea.pressed)
- || ((rzone.timeline.useRuler || trimInMouseArea.drag.active || trimOutMouseArea.drag.active) && showZoneLabels && parent.width > 3 * width)
+ || ((rzone.timeline.useRuler || trimInMouseArea.drag.active || trimOutMouseArea.drag.active) && rzone.showZoneLabels && parent.width > 3 * width)
|| (rzone.timeline.useRuler && !trimInMouseArea.drag.active && !trimOutMouseArea.drag.active)
anchors.horizontalCenter: parent.horizontalCenter
width: durationLabel.contentWidth + 4
@@ -197,7 +200,7 @@ Rectangle {
onPositionChanged: mouse => {
if (mouse.buttons === Qt.LeftButton) {
rzone.resizeActive = true
- var newPos = controller.suggestSnapPoint(rzone.frameIn + Math.round(trimIn.x / rzone.timeline.scaleFactor), mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping)
+ var newPos = rzone.timeline.suggestSnapPoint(rzone.frameIn + Math.round(trimIn.x / rzone.timeline.scaleFactor), mouse.modifiers & Qt.ShiftModifier ? -1 : rzone.snapping)
if (newPos < 0) {
newPos = 0
}
@@ -247,8 +250,8 @@ Rectangle {
if (mouse.buttons === Qt.LeftButton) {
rzone.resizeActive = true
rzone.frameOut = Math.max(
- controller.suggestSnapPoint(rzone.frameIn + Math.round((trimOut.x + trimOut.width) / rzone.timeline.scaleFactor),
- mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping),
+ rzone.timeline.suggestSnapPoint(rzone.frameIn + Math.round((trimOut.x + trimOut.width) / rzone.timeline.scaleFactor),
+ mouse.modifiers & Qt.ShiftModifier ? -1 : rzone.snapping),
rzone.frameIn + 1)
}
}
diff --git a/src/timeline2/view/qml/SubTitle.qml b/src/timeline2/view/qml/SubTitle.qml
index b4e34313fc..a400ece71b 100644
--- a/src/timeline2/view/qml/SubTitle.qml
+++ b/src/timeline2/view/qml/SubTitle.qml
@@ -20,6 +20,10 @@ Item {
required property K.TimelineItemModel controller
required property bool isPanning
required property double timeScale
+ required property int snapping
+ required property Flickable timelineScrollView
+ required property int consumerPosition
+ required property var groupTrimData
readonly property bool isUserInteracting: subtitleClipArea.pressed || startMouseArea.pressed || endMouseArea.pressed
@@ -33,10 +37,15 @@ Item {
property bool selected
property bool isGrabbed: false
property int subLayer
- height: subtitleTrack.height / (timeline.maxSubLayer + 1)
property int handleWidth: Math.max(2, Math.ceil(K.UiUtils.baseSizeMedium / 4))
y: height * subLayer
+ signal subtitleMoving(var subtitleItem)
+ signal setGroupTrimData(var data)
+ signal editSubtitle(int id, string newText, string oldText)
+ signal showSubtitleClipMenu()
+ signal continuousScrolling(int x, int y, int upMove)
+
function editText()
{
subtitleBase.textEditBegin = true
@@ -135,7 +144,7 @@ Item {
return
}
console.log('ENTERED ITEM CLICKED:', subtitleRoot.subtitle, ' ID: ', subtitleRoot.subId, 'START FRAME: ', subtitleRoot.startFrame)
- oldStartX = scrollView.contentX + mapToItem(scrollView, mouseX, 0).x
+ subtitleRoot.oldStartX = subtitleRoot.timelineScrollView.contentX + mapToItem(subtitleRoot.timelineScrollView, mouseX, 0).x
oldStartFrame = subtitleRoot.startFrame
oldLayer = subtitleRoot.subLayer
snappedFrame = oldStartFrame
@@ -143,8 +152,7 @@ Item {
x = subtitleBase.x
startMove = mouse.button & Qt.LeftButton
if (startMove) {
- root.subtitleMoving = true
- root.subtitleItem = subtitleClipArea
+ subtitleRoot.subtitleMoving(subtitleClipArea)
incrementalOffset = 0
}
if (subtitleRoot.timeline.selection.indexOf(subtitleRoot.subId) === -1) {
@@ -162,9 +170,9 @@ Item {
function checkOffset(offset) {
if (pressed && !subtitleBase.textEditBegin && startMove) {
incrementalOffset += offset
- newStart = Math.max(0, oldStartFrame + (scrollView.contentX + mapToItem(scrollView,mouseX, 0).x + incrementalOffset - subtitleRoot.oldStartX)/ subtitleRoot.timeScale)
- snappedFrame = subtitleRoot.controller.suggestSubtitleMove(subtitleRoot.subId, subtitleRoot.subLayer, newStart, root.consumerPosition, root.snapping)
- root.continuousScrolling(scrollView.contentX + mapToItem(scrollView, mouseX, 0).x + incrementalOffset, subtitleRoot.timeScale)
+ newStart = Math.max(0, oldStartFrame + (subtitleRoot.timelineScrollView.contentX + mapToItem(subtitleRoot.timelineScrollView, mouseX, 0).x + incrementalOffset - subtitleRoot.oldStartX)/ subtitleRoot.timeScale)
+ snappedFrame = subtitleRoot.controller.suggestSubtitleMove(subtitleRoot.subId, subtitleRoot.subLayer, newStart, subtitleRoot.consumerPosition, subtitleRoot.snapping)
+ subtitleRoot.continuousScrolling(subtitleRoot.timelineScrollView.contentX + mapToItem(subtitleRoot.timelineScrollView, mouseX, 0).x + incrementalOffset, subtitleRoot.timeScale)
}
}
onPositionChanged: (mouse) => {
@@ -180,8 +188,7 @@ Item {
}
}
onReleased: mouse => {
- root.subtitleMoving = false
- root.subtitleItem = undefined
+ subtitleRoot.subtitleMoving(undefined)
if (subtitleBase.textEditBegin) {
mouse.accepted = false
return
@@ -194,7 +201,7 @@ Item {
if (mouse.y > subtitleRoot.height && mouse.modifiers & Qt.ShiftModifier) {
snappedLayer++
}
- console.log("old start frame", oldStartFrame/subtitleRoot.timeline.scaleFactor, "new frame after shifting ", oldStartFrame/subtitleRoot.timeline.scaleFactor + delta)
+ console.log("old start frame", oldStartFrame/subtitleRoot.timeline.scaleFactor, "new frame after shifting ", oldStartFrame / subtitleRoot.timeline.scaleFactor + delta)
subtitleRoot.controller.requestSubtitleMove(subtitleRoot.subId, oldLayer, oldStartFrame, false, false)
subtitleRoot.controller.requestSubtitleMove(subtitleRoot.subId, snappedLayer, snappedFrame, true, true, true)
x = snappedFrame * subtitleRoot.timeScale
@@ -204,7 +211,7 @@ Item {
onClicked: mouse => {
if (mouse.button == Qt.RightButton) {
//console.log('RIGHT BUTTON CLICKED')
- root.showSubtitleClipMenu()
+ subtitleRoot.showSubtitleClipMenu()
}
}
onDoubleClicked: {
@@ -252,7 +259,7 @@ Item {
subtitleEdit.focus = false
parent.textEditBegin = false
if (subtitleRoot.subtitle != subtitleEdit.text) {
- subtitleModel.editSubtitle(subtitleRoot.subId, subtitleEdit.text, subtitleRoot.subtitle)
+ subtitleRoot.editSubtitle(subtitleRoot.subId, subtitleEdit.text, subtitleRoot.subtitle)
}
}
anchors.fill: parent
@@ -320,14 +327,14 @@ Item {
newDuration = subtitleRoot.duration
shiftTrim = mouse.modifiers & Qt.ShiftModifier
if (!shiftTrim && (subtitleRoot.controller.isInGroup(subtitleRoot.subId) || subtitleRoot.controller.hasMultipleSelection())) {
- root.groupTrimData = subtitleRoot.controller.getGroupData(subtitleRoot.subId)
+ subtitleRoot.setGroupTrimData(subtitleRoot.controller.getGroupData(subtitleRoot.subId))
}
}
onPositionChanged: {
if (pressed) {
newDuration = subtitleRoot.endFrame - Math.round(leftstart.x / subtitleRoot.timeScale)
if (newDuration != originalDuration && subtitleBase.x >= 0) {
- var frame = subtitleRoot.controller.requestItemResize(subtitleRoot.subId, newDuration , false, false, root.snapping, shiftTrim);
+ var frame = subtitleRoot.controller.requestItemResize(subtitleRoot.subId, newDuration , false, false, subtitleRoot.snapping, shiftTrim);
if (frame > 0) {
newStart = subtitleRoot.endFrame - frame
}
@@ -339,15 +346,15 @@ Item {
trimIn.opacity = 0
leftstart.anchors.left = subtitleBase.left
if (oldStartFrame != newStart) {
- if (shiftTrim || (root.groupTrimData == undefined || K.Core.activeTool === K.ToolType.RippleTool)) {
+ if (shiftTrim || (subtitleRoot.groupTrimData == undefined || K.Core.activeTool === K.ToolType.RippleTool)) {
subtitleRoot.controller.requestItemResize(subtitleRoot.subId, subtitleRoot.endFrame - oldStartFrame, false, false);
subtitleRoot.controller.requestItemResize(subtitleRoot.subId, subtitleRoot.endFrame - newStart, false, true, -1, shiftTrim);
} else {
var updatedGroupData = subtitleRoot.controller.getGroupData(subtitleRoot.subId)
- subtitleRoot.controller.processGroupResize(root.groupTrimData, updatedGroupData, false)
+ subtitleRoot.controller.processGroupResize(subtitleRoot.groupTrimData, updatedGroupData, false)
}
}
- root.groupTrimData = undefined
+ subtitleRoot.setGroupTrimData(undefined)
}
onEntered: {
if (!pressed) {
@@ -418,7 +425,7 @@ Item {
oldMouseX = mouseX
shiftTrim = mouse.modifiers & Qt.ShiftModifier
if (!shiftTrim && (subtitleRoot.controller.isInGroup(subtitleRoot.subId) || subtitleRoot.controller.hasMultipleSelection())) {
- root.groupTrimData = subtitleRoot.controller.getGroupData(subtitleRoot.subId)
+ subtitleRoot.setGroupTrimData(subtitleRoot.controller.getGroupData(subtitleRoot.subId))
}
}
onPositionChanged: {
@@ -426,9 +433,9 @@ Item {
if ((mouseX != oldMouseX && subtitleRoot.duration > 1) || (subtitleRoot.duration <= 1 && mouseX > oldMouseX)) {
sizeChanged = true
//duration = subtitleBase.width + (mouseX - oldMouseX)/ timeline.scaleFactor
- newDuration = Math.round((subtitleBase.width + mouseX - oldMouseX)/timeScale)
+ newDuration = Math.round((subtitleBase.width + mouseX - oldMouseX) / subtitleRoot.timeScale)
// Perform resize without changing model
- var frame = subtitleRoot.controller.requestItemResize(subtitleRoot.subId, newDuration , true, false, root.snapping, shiftTrim);
+ var frame = subtitleRoot.controller.requestItemResize(subtitleRoot.subId, newDuration , true, false, subtitleRoot.snapping, shiftTrim);
if (frame > 0) {
newDuration = frame
}
@@ -440,18 +447,18 @@ Item {
rightend.anchors.right = subtitleBase.right
console.log(' GOT RESIZE: ', newDuration, ' > ', originalDuration)
if (mouseX != oldMouseX || sizeChanged) {
- if (shiftTrim || (root.groupTrimData == undefined || K.Core.activeTool === K.ToolType.RippleTool)) {
+ if (shiftTrim || (subtitleRoot.groupTrimData == undefined || K.Core.activeTool === K.ToolType.RippleTool)) {
// Restore original size
subtitleRoot.controller.requestItemResize(subtitleRoot.subId, originalDuration , true, false);
// Perform real resize
subtitleRoot.controller.requestItemResize(subtitleRoot.subId, newDuration , true, true, -1, shiftTrim)
} else {
var updatedGroupData = subtitleRoot.controller.getGroupData(subtitleRoot.subId)
- subtitleRoot.controller.processGroupResize(root.groupTrimData, updatedGroupData, true)
+ subtitleRoot.controller.processGroupResize(subtitleRoot.groupTrimData, updatedGroupData, true)
}
sizeChanged = false
}
- root.groupTrimData = undefined
+ subtitleRoot.setGroupTrimData(undefined)
}
onEntered: {
console.log('ENTER MOUSE END AREA')
diff --git a/src/timeline2/view/qml/SubtitleTrackHead.qml b/src/timeline2/view/qml/SubtitleTrackHead.qml
index d607501fb1..55c2e57785 100644
--- a/src/timeline2/view/qml/SubtitleTrackHead.qml
+++ b/src/timeline2/view/qml/SubtitleTrackHead.qml
@@ -31,6 +31,7 @@ Rectangle {
required property color selectedTrackColor
required property color frameColor
required property int trackTagWidth
+ required property bool isSubtitleTrackVisible
signal toogleExpandTrack()
@@ -70,7 +71,7 @@ Rectangle {
anchors.right: parent.right
anchors.top: expandSubButton.bottom
anchors.left: subtitleLayerIndicator.right
- visible: (subtitleTrack.visible && !trackHeader.collapsed)
+ visible: (trackHeader.isSubtitleTrackVisible && !trackHeader.collapsed)
flat: true
onActivated: index => {
trackHeader.timeline.subtitlesMenuActivatedAsync(index)
@@ -161,7 +162,7 @@ Rectangle {
anchors.top: trackHeader.top
anchors.bottom: trackHeader.bottom
property color bgColor: Qt.darker(trackHeader.trackHeaderColor, 0.55)
- visible: trackHeader.timeline.maxSubLayer > 0 && subtitleTrack.visible && !trackHeader.collapsed
+ visible: trackHeader.timeline.maxSubLayer > 0 && trackHeader.isSubtitleTrackVisible && !trackHeader.collapsed
Repeater {
model: subtitleLayerIndicator.visible ? trackHeader.timeline.maxSubLayer + 1 : 0
diff --git a/src/timeline2/view/qml/Timeline.qml b/src/timeline2/view/qml/Timeline.qml
index 0eaf7ace30..7ecf022c12 100644
--- a/src/timeline2/view/qml/Timeline.qml
+++ b/src/timeline2/view/qml/Timeline.qml
@@ -34,17 +34,16 @@ Rectangle {
required property K.SubtitleModel subtitleModel
property bool validMenu: false
- property bool subtitleMoving: false
- property var subtitleItem
+ property var subtitleItem: undefined
property color textColor: activePalette.text
property var groupTrimData
property bool trimInProgress: false
- property bool isPanning: tracksArea.isCursorHidden
- property bool dragInProgress: dragProxyArea.pressed || dragProxyArea.drag.active || groupTrimData !== undefined || spacerGroup > -1 || trimInProgress || clipDropArea.containsDrag || compoArea.containsDrag
+ readonly property bool isPanning: tracksArea.isCursorHidden
+ readonly property bool isItemDragInProgress: compoArea.containsDrag || clipDropArea.containsDrag
+ readonly property bool dragInProgress: dragProxyArea.pressed || dragProxyArea.drag.active || groupTrimData !== undefined || spacerGroup > -1 || trimInProgress || isItemDragInProgress
property int trimmingOffset: 0
property int trimmingClickFrame: -1
- readonly property bool isItemDragInProgress: compoArea.containsDrag || clipDropArea.containsDrag
function screenForGlobalPos(globalPos) {
const screens = Application.screens
@@ -395,14 +394,10 @@ function getTrackColor(audio, header) {
sameTrackIndicator.visible = false
}
- function isDragging() {
- return dragInProgress
- }
-
function initDrag(itemObject, itemCoord, itemId, itemPos, itemTrack, isComposition) {
var mappedItemCoord = itemObject.mapToItem(tracksContainerArea, itemCoord)
- dragProxy.x = itemObject.modelStart * root.timeScale
+ dragProxy.x = itemPos * root.timeScale
dragProxy.y = mappedItemCoord.y
dragProxy.width = itemObject.clipDuration * root.timeScale
dragProxy.height = mappedItemCoord.height
@@ -1256,6 +1251,7 @@ function getTrackColor(audio, header) {
selectedTrackColor: root.selectedTrackColor
trackHeaderColor: root.getTrackColor(false, true)
trackTagWidth: root.trackTagWidth
+ isSubtitleTrackVisible: subtitleTrack.visible
onToogleExpandTrack: {
if (subtitleTrack.height > root.collapsedHeight) {
@@ -1852,6 +1848,14 @@ function getTrackColor(audio, header) {
controller: root.controller
monitorProxy: root.proxy
guidesModel: root.guidesModel
+ snapping: root.snapping
+ rulercontainerWidth: rulercontainer.width
+ scrollViewContentX: scrollView.contentX
+
+ onShowRulerMenu: () => { root.showRulerMenu() }
+ onZoomByWheel: (wheel) => { root.zoomByWheel(wheel) }
+ onMarkerActivated: (frame) => { root.markerActivated(frame) }
+
K.TimelinePlayhead {
id: playhead
height: Math.round(K.UiUtils.baseSizeMedium * .8)
@@ -2528,6 +2532,22 @@ function getTrackColor(audio, header) {
snapping: root.snapping
isPanning: root.isPanning
isItemDragInProgress: root.isItemDragInProgress
+ groupTrimData: root.groupTrimData
+ timelineDragContainer: dragContainer
+ // timelineDragContainer: dragProxyArea
+ dragProxyCursorShape: dragProxyArea.cursorShape
+ draggedItemId: dragProxy.draggedItem
+ isDragProxyAreaPressed: dragProxyArea.pressed
+ isDragProxyAreaDragActive: dragProxyArea.drag.active
+ playheadPos: root.proxy.position
+ timelineScrollView: scrollView
+ minClipWidthForViews: root.minClipWidthForViews
+ mainItemId: root.mainItemId
+ trimmingOffset: root.trimmingOffset
+ selectedMix: root.selectedMix
+ dragProxyMovesComposition: dragProxy.isComposition
+ isSomeDragInProgress: root.dragInProgress
+
z: tracksRepeater.count - index
onBlockAutoScroll: (enabled) => { root.blockAutoScroll = enabled }
@@ -2542,6 +2562,23 @@ function getTrackColor(audio, header) {
root.clickFrame = clickFrame
root.showClipMenu(clipId)
}
+
+ onShowCompositionMenu: () => { root.showCompositionMenu() }
+
+ onInitDrag:(itemObject, itemCoord, itemId, itemPos, itemTrack, isComposition) => {
+ root.initDrag(itemObject, itemCoord, itemId, itemPos, itemTrack, isComposition)
+ }
+
+ onUpdateGroupTrimData: (data) => { root.groupTrimData = data }
+
+ onUpdateTrimInProgress: (trimInProgress) => { root.trimInProgress = trimInProgress }
+
+ onRegainFocus: (x, y) => { root.regainFocus(mapToItem(root, x, y)) }
+
+ onEndDragIfFocused: (itemId) => { root.endDragIfFocused(itemId) }
+
+ onEndDrag: () => { root.endDrag() }
+
}
}
@@ -2569,6 +2606,9 @@ function getTrackColor(audio, header) {
model: root.subtitleModel
delegate: SubTitle {
required property var model
+
+ height: subtitleTrack.height / (timeline.maxSubLayer + 1)
+
subId: model.id
selected: model.selected
startFrame: model.startframe
@@ -2581,8 +2621,15 @@ function getTrackColor(audio, header) {
controller: root.controller
isPanning: root.isPanning
timeScale: root.timeScale
+ consumerPosition: root.consumerPosition
+ groupTrimData: root.groupTrimData
onIsUserInteractingChanged: { root.blockAutoScroll = isUserInteracting }
+ onSubtitleMoving: (subtitleItem) => { root.subtitleItem = subtitleItem }
+ onSetGroupTrimData: (data) => { root.groupTrimData = data }
+ onEditSubtitle: (id, newText, oldText) => { root.subtitleModel.editSubtitle(id, newText, oldText) }
+ onShowSubtitleClipMenu: () => { root.showSubtitleClipMenu() }
+ onContinuousScrolling: (x, y, upMove) => { root.continuousScrolling(x, y, upMove) }
}
}
@@ -2649,7 +2696,7 @@ function getTrackColor(audio, header) {
dragProxyArea.moveItem()
}
if (scrollView.contentX == 0 || (root.clipBeingMovedId == -1 && root.clipBeingDroppedId == -1 && !rubberSelect.visible)) {
- if (root.subtitleMoving) {
+ if (root.subtitleItem) {
root.subtitleItem.checkOffset(horizontal)
} else {
horizontal = 0
diff --git a/src/timeline2/view/qml/Track.qml b/src/timeline2/view/qml/Track.qml
index fd383f51ed..304bc5a9f1 100644
--- a/src/timeline2/view/qml/Track.qml
+++ b/src/timeline2/view/qml/Track.qml
@@ -26,12 +26,35 @@ Item {
required property var effectZones
required property bool isPanning
required property bool isItemDragInProgress
+ required property bool isSomeDragInProgress
+ required property var groupTrimData
+ required property Item timelineDragContainer
+ required property var dragProxyCursorShape
+ required property bool dragProxyMovesComposition
+ required property int draggedItemId
+ required property bool isDragProxyAreaPressed
+ required property bool isDragProxyAreaDragActive
+ required property int playheadPos
+ required property var timelineScrollView
+ required property int minClipWidthForViews
+ required property int mainItemId
+ required property int trimmingOffset
+ required property int selectedMix
signal blockAutoScroll(bool enabled)
signal seek(int pos)
signal zoomByWheel(var wheel)
signal showMixMenu(int clipId, int clickFrame)
signal showClipMenu(int clipId, int clickFrame)
+ signal showCompositionMenu()
+ signal updateGroupTrimData(var data)
+ signal updateTrimInProgress(bool trimInProgress)
+ signal regainFocus(var x, var y)
+ signal endDragIfFocused(int itemId)
+ signal endDrag()
+
+
+ signal initDrag(var itemObject, var itemCoord, var itemId, var itemPos, var itemTrack, var isComposition)
property alias trackModel: trackModel.model
property alias rootIndex : trackModel.rootIndex
@@ -116,7 +139,7 @@ Item {
function trimedClip(clip, shiftTrim, controlTrim, right) {
//bubbleHelp.hide()
trackRoot.timeline.showToolTip();
- if (shiftTrim || (root.groupTrimData == undefined/*TODO > */ || K.Core.activeTool === K.ToolType.RippleTool /* < TODO*/) || controlTrim) {
+ if (shiftTrim || (trackRoot.groupTrimData == undefined/*TODO > */ || K.Core.activeTool === K.ToolType.RippleTool /* < TODO*/) || controlTrim) {
// We only resize one element
if (K.Core.activeTool === K.ToolType.RippleTool) {
trackRoot.timeline.requestItemRippleResize(clip.clipId, clip.originalDuration, right, false, 0, shiftTrim)
@@ -139,9 +162,9 @@ Item {
}
} else {
var updatedGroupData = trackRoot.controller.getGroupData(clip.clipId)
- trackRoot.controller.processGroupResize(root.groupTrimData, updatedGroupData, right)
+ trackRoot.controller.processGroupResize(trackRoot.groupTrimData, updatedGroupData, right)
}
- root.groupTrimData = undefined
+ trackRoot.updateGroupTrimData(undefined)
}
width: clipRow.width
@@ -176,11 +199,12 @@ Item {
Loader {
id: clipLoader
active: trackRoot.isClip(itemOnTrack.model.clipType)
- sourceComponent: Clip {
+ sourceComponent: Clip {
+ id: clipItem
height: trackRoot.height
enabled: !trackRoot.isItemDragInProgress
- visible: fakeTid > -1 || (scrollView.lastVisibleFrame > modelStart && scrollView.firstVisibleFrame <= (modelStart + clipDuration))
+ visible: fakeTid > -1 || (trackRoot.timelineScrollView.lastVisibleFrame > modelStart && trackRoot.timelineScrollView.firstVisibleFrame <= (modelStart + clipDuration))
parentTrack: trackRoot
timeline: trackRoot.timeline
@@ -208,7 +232,7 @@ Item {
fadeOutMethod: itemOnTrack.model.fadeOutMethod
showKeyframes: itemOnTrack.model.showKeyframes
isGrabbed: itemOnTrack.model.isGrabbed
- isMainItem: root.mainItemId == clipId
+ isMainItem: trackRoot.mainItemId == clipId
keyframeModel: itemOnTrack.model.keyframeModel
clipDuration: itemOnTrack.model.duration
inPoint: itemOnTrack.model.in
@@ -234,27 +258,52 @@ Item {
itemType: itemOnTrack.model.clipType
trackId: itemOnTrack.model.trackId
isPanning: trackRoot.isPanning
- dragInProgress: dragProxyArea.drag.active && dragProxy.draggedItem === clipId
+ clipDragInProgress: trackRoot.isDragProxyAreaDragActive && trackRoot.draggedItemId === clipId
+ someDragInProgress: trackRoot.isSomeDragInProgress
snapping: trackRoot.snapping
+ isMixSelected: trackRoot.selectedMix == clipId
+ isDragProxied: trackRoot.draggedItemId == clipId
+ thumbsFormat: trackRoot.trackThumbsFormat
+ dragContainer: trackRoot.timelineDragContainer
+ dragProxyCursorShape: trackRoot.dragProxyCursorShape
+ isDragProxyAreaPressed: trackRoot.isDragProxyAreaPressed
+ isTimlineCursorOnClip: trackRoot.playheadPos > clipItem.modelStart && trackRoot.playheadPos < clipItem.modelStart + clipItem.clipDuration
+ timelineScrollViewWidth: trackRoot.timelineScrollView.width
+ minClipWidthForViews: trackRoot.minClipWidthForViews
+ scrollStart: visible ? trackRoot.timelineScrollView.contentX - (modelStart * timeScale) : 0
+ dragProxyMovesComposition: trackRoot.dragProxyMovesComposition
+ trimmingOffset: trackRoot.trimmingOffset
onInitGroupTrim: clipId => {
// We are resizing a group, remember coordinates of all elements
- root.groupTrimData = trackRoot.controller.getGroupData(clipId)
+ trackRoot.updateGroupTrimData(trackRoot.controller.getGroupData(clipId))
}
onTrimmingIn: (clip, newDuration, shiftTrim, controlTrim) => { trackRoot.clipTrimming(clip, newDuration, shiftTrim, controlTrim, false) }
onTrimmedIn: (clip, shiftTrim, controlTrim) => { trackRoot.trimedClip(clip, shiftTrim, controlTrim, false) }
onTrimmingOut: (clip, newDuration, shiftTrim, controlTrim) => { trackRoot.clipTrimming(clip, newDuration, shiftTrim, controlTrim, true) }
onTrimmedOut: (clip, shiftTrim, controlTrim) => { trackRoot.trimedClip(clip, shiftTrim, controlTrim, true) }
onIsUserInteractingChanged: { trackRoot.blockAutoScroll(isUserInteracting) }
- onTrimInProgressChanged: { root.trimInProgress = trimInProgress }
+ onBlockAutoScroll: (enabled) => { trackRoot.blockAutoScroll(enabled) }
+
+ onTrimInProgressChanged: { trackRoot.updateTrimInProgress(trimInProgress) }
onShowMixMenu: (clipId, clickFrame) => trackRoot.showMixMenu(clipId, clickFrame)
onShowClipMenu: (clipId, clickFrame) => trackRoot.showClipMenu(clipId, clickFrame)
- onMakeMainItem: (enabled) => { root.mainItemId = enabled ? clipId : -1 }
-
+ onMakeMainItem: (enabled) => { trackRoot.mainItemId = enabled ? clipId : -1 }
onSeek: (pos) => { trackRoot.seek(pos) }
onZoomByWheel: (wheel) => { trackRoot.zoomByWheel(wheel) }
+
+ onInitDrag: (itemCoord) => {
+ trackRoot.initDrag(clipItem, itemCoord, clipItem.clipId, clipItem.modelStart, clipItem.trackId, false)
+ }
+
+ onEndDrag: () => { trackRoot.endDrag() }
+ onEndDragIfFocused: (itemId) => { trackRoot.endDragIfFocused(itemId) }
+
+ onClearGroupTrimData: () => { trackRoot.updateGroupTrimData(undefined) }
+
+ onRegainFocus: (x, y) => { trackRoot.regainFocus(x, y) }
}
onLoaded: {
console.log('loaded clip: ', itemOnTrack.model.start, ', ID: ', itemOnTrack.model.item, ', index: ', trackRoot.DelegateModel.itemsIndex,', TYPE:', itemOnTrack.model.clipType)
@@ -265,8 +314,8 @@ Item {
id: compositionLoader
active: itemOnTrack.model.clipType == K.ClipType.Composition
sourceComponent: Composition {
+ id: compositionItem
opacity: 0.8
-
enabled: !trackRoot.isItemDragInProgress
parentTrack: trackRoot
@@ -286,7 +335,8 @@ Item {
isGrabbed: itemOnTrack.model.isGrabbed
keyframeModel: itemOnTrack.model.keyframeModel
aTrack: itemOnTrack.model.a_track
- visible: !itemOnTrack.model.hideItem
+ readonly property bool isInViewFrame: trackRoot.timelineScrollView.lastVisibleFrame > modelStart && trackRoot.timelineScrollView.firstVisibleFrame <= (modelStart + clipDuration)
+ visible: !itemOnTrack.model.hideItem && isInViewFrame
clipDuration: itemOnTrack.model.duration
inPoint: itemOnTrack.model.in
outPoint: itemOnTrack.model.out
@@ -294,6 +344,13 @@ Item {
clipName: itemOnTrack.model.name
selected: itemOnTrack.model.selected
isPanning: trackRoot.isPanning
+ scrollStart: visible ? trackRoot.timelineScrollView.contentX - (modelStart * timeScale) : 0
+ minClipWidthForViews: trackRoot.minClipWidthForViews
+ clipDragInProgress: trackRoot.isDragProxyAreaDragActive && trackRoot.draggedItemId === clipId
+ dragContainer: trackRoot.timelineDragContainer
+ dragProxyCursorShape: trackRoot.dragProxyCursorShape
+ isDragProxyAreaPressed: trackRoot.isDragProxyAreaPressed
+ timelineScrollViewWidth: trackRoot.timelineScrollView.width
onTrimmingIn: (clip, newDuration) => {
var new_duration = trackRoot.controller.requestItemResize(clip.clipId, newDuration, false, false, trackRoot.snapping)
@@ -334,10 +391,21 @@ Item {
}
onIsUserInteractingChanged: { trackRoot.blockAutoScroll(isUserInteracting) }
- onTrimInProgressChanged: { root.trimInProgress = trimInProgress }
+ onBlockAutoScroll: (enabled) => { trackRoot.blockAutoScroll(enabled) }
+
+ onTrimInProgressChanged: { trackRoot.updateTrimInProgress(trimInProgress) }
+
+ onShowCompositionMenu: () => trackRoot.showCompositionMenu()
+ onMakeMainItem: () => { trackRoot.mainItemId = clipId }
onSeek: (pos) => { trackRoot.seek(pos) }
onZoomByWheel: (wheel) => { trackRoot.zoomByWheel(wheel) }
+
+
+ onInitDrag: (itemCoord) => {
+ trackRoot.initDrag(compositionItem, itemCoord, compositionItem.clipId, compositionItem.modelStart, compositionItem.trackId, true)
+ }
+ onEndDragIfFocused: (itemId) => { trackRoot.endDragIfFocused(itemId) }
}
onLoaded: {
console.log('loaded composition: ', itemOnTrack.model.start, ', ID: ', itemOnTrack.model.item, ', index: ', trackRoot.DelegateModel.itemsIndex)