Warning, /multimedia/kdenlive/src/timeline2/view/qml/Ruler.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 SPDX-FileCopyrightText: 2013 Meltytech LLC 0003 SPDX-FileCopyrightText: 2013 Dan Dennedy <dan@dennedy.org> 0004 0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 import QtQuick 2.15 0009 import QtQuick.Controls 2.15 0010 import com.enums 1.0 0011 0012 Item { 0013 id: rulerRoot 0014 // The standard width for labels. Depends on format used (frame number or full timecode) 0015 property int labelSize: fontMetrics.boundingRect(timeline.timecode(36000)).width 0016 // The spacing between labels. Depends on labelSize 0017 property real labelSpacing: labelSize 0018 // The space we want between each ticks in the ruler 0019 property real tickSpacing: timeline.scaleFactor 0020 property alias rulerZone : zone 0021 property int workingPreview : timeline.workingPreview 0022 property int labelMod: 1 0023 property bool useTimelineRuler : timeline.useRuler 0024 property int zoneHeight: Math.ceil(root.baseUnit / 2) + 1 0025 property bool showZoneLabels: false 0026 property bool resizeActive: false // Used to decide which mouse cursor we should display 0027 property bool hoverGuide: false 0028 property int cursorShape: resizeActive ? Qt.SizeHorCursor : hoverGuide ? Qt.PointingHandCursor : Qt.ArrowCursor 0029 property var effectZones: timeline.masterEffectZones 0030 property int guideLabelHeight: timeline.showMarkers ? fontMetrics.height : 0 0031 property int previewHeight: Math.ceil(timecodeContainer.height / 5) 0032 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) 0033 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) 0034 0035 function adjustStepSize() { 0036 if (timeline.scaleFactor > 19) { 0037 // Frame size >= 20 pixels 0038 rulerRoot.tickSpacing = timeline.scaleFactor 0039 // labelSpacing cannot be smaller than 1 frame 0040 rulerRoot.labelSpacing = timeline.scaleFactor > rulerRoot.labelSize * 1.3 ? timeline.scaleFactor : Math.floor(rulerRoot.labelSize/timeline.scaleFactor) * timeline.scaleFactor 0041 } else { 0042 rulerRoot.tickSpacing = Math.floor(3 * root.baseUnit / timeline.scaleFactor) * timeline.scaleFactor 0043 rulerRoot.labelSpacing = (Math.floor(rulerRoot.labelSize/rulerRoot.tickSpacing) + 1) * rulerRoot.tickSpacing 0044 } 0045 rulerRoot.labelMod = Math.max(1, Math.ceil((rulerRoot.labelSize + root.baseUnit) / rulerRoot.tickSpacing)) 0046 //console.log('LABELMOD: ', Math.ceil((rulerRoot.labelSize + root.fontUnit) / rulerRoot.tickSpacing))) 0047 tickRepeater.model = Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2 0048 } 0049 0050 function adjustFormat() { 0051 rulerRoot.labelSize = fontMetrics.boundingRect(timeline.timecode(36000)).width 0052 adjustStepSize() 0053 repaintRuler() 0054 } 0055 0056 function repaintRuler() { 0057 // Enforce repaint 0058 tickRepeater.model = 0 0059 tickRepeater.model = Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2 0060 } 0061 0062 // Timeline preview stuff 0063 Repeater { 0064 model: timeline.dirtyChunks 0065 anchors.fill: parent 0066 delegate: Rectangle { 0067 x: modelData * timeline.scaleFactor 0068 anchors.bottom: parent.bottom 0069 anchors.bottomMargin: zoneHeight 0070 width: 25 * timeline.scaleFactor 0071 height: previewHeight 0072 color: 'darkred' 0073 } 0074 } 0075 0076 Repeater { 0077 model: timeline.renderedChunks 0078 anchors.fill: parent 0079 delegate: Rectangle { 0080 x: modelData * timeline.scaleFactor 0081 anchors.bottom: parent.bottom 0082 anchors.bottomMargin: zoneHeight 0083 width: 25 * timeline.scaleFactor 0084 height: previewHeight 0085 color: 'darkgreen' 0086 } 0087 } 0088 Rectangle { 0089 id: working 0090 x: rulerRoot.workingPreview * timeline.scaleFactor 0091 anchors.bottom: parent.bottom 0092 anchors.bottomMargin: zoneHeight 0093 width: 25 * timeline.scaleFactor 0094 height: previewHeight 0095 color: 'orange' 0096 visible: rulerRoot.workingPreview > -1 0097 } 0098 0099 // Guides 0100 Repeater { 0101 id: guidesRepeater 0102 model: guidesModel 0103 property int radiusSize: timeline.guidesLocked ? 0 : guideLabelHeight / 2 0104 delegate: 0105 Item { 0106 id: guideRoot 0107 property bool activated : proxy.position == model.frame 0108 z: activated ? 20 : 10 0109 Rectangle { 0110 id: markerBase 0111 width: 1 0112 height: rulerRoot.height 0113 x: Math.round(model.frame * timeline.scaleFactor) 0114 color: guideRoot.activated ? Qt.lighter(model.color, 1.3) : model.color 0115 property int markerId: model.id 0116 Rectangle { 0117 0118 visible: timeline.showMarkers 0119 width: mlabel.contentWidth + 4 - guidesRepeater.radiusSize 0120 height: guideLabelHeight 0121 color: markerBase.color 0122 anchors { 0123 top: parent.top 0124 left: parent.left 0125 } 0126 ToolTip.visible: guideArea.containsMouse 0127 ToolTip.text: model.comment 0128 ToolTip.delay: 1000 0129 ToolTip.timeout: 5000 0130 Rectangle { 0131 visible: !timeline.guidesLocked 0132 color: markerBase.color 0133 anchors.fill: parent 0134 radius: guidesRepeater.radiusSize 0135 anchors.rightMargin: -guidesRepeater.radiusSize - 2 0136 } 0137 Rectangle { 0138 // Shadow delimiting marker start 0139 width: 1 0140 height: guideLabelHeight 0141 color: activePalette.dark 0142 anchors { 0143 right: parent.left 0144 } 0145 } 0146 Rectangle { 0147 // Shadow on marker top 0148 height: 1 0149 width: parent.width + guidesRepeater.radiusSize / 2 0150 color: Qt.darker(markerBase.color, 1.8) 0151 } 0152 Text { 0153 id: mlabel 0154 text: model.comment 0155 topPadding: -1 0156 leftPadding: 2 0157 rightPadding: 2 0158 font: miniFont 0159 color: '#000' 0160 } 0161 MouseArea { 0162 z: 10 0163 id: guideArea 0164 anchors.left: parent.left 0165 anchors.top: parent.top 0166 width: parent.width + guidesRepeater.radiusSize 0167 height: parent.height 0168 acceptedButtons: Qt.LeftButton | Qt.RightButton 0169 cursorShape: Qt.PointingHandCursor 0170 hoverEnabled: true 0171 property int prevFrame 0172 property int destFrame 0173 property int movingMarkerId 0174 property int xOffset: 0 0175 drag.axis: Drag.XAxis 0176 onPressed: { 0177 prevFrame = model.frame 0178 destFrame = prevFrame 0179 xOffset = mouseX 0180 anchors.left = undefined 0181 movingMarkerId = markerBase.markerId 0182 } 0183 onReleased: { 0184 if (prevFrame != destFrame) { 0185 timeline.moveGuideWithoutUndo(movingMarkerId, prevFrame) 0186 timeline.moveGuideById(movingMarkerId, destFrame) 0187 } 0188 movingMarkerId = -1 0189 anchors.left = parent.left 0190 } 0191 onPositionChanged: mouse => { 0192 if (pressed) { 0193 var newFrame = Math.max(0, Math.round(model.frame + (mouseX - xOffset) / timeline.scaleFactor)) 0194 newFrame = controller.suggestSnapPoint(newFrame, mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping) 0195 if (newFrame != destFrame) { 0196 var frame = timeline.moveGuideWithoutUndo(movingMarkerId, newFrame) 0197 if (frame > -1) { 0198 destFrame = frame 0199 } 0200 } 0201 } 0202 } 0203 drag.smoothed: false 0204 onDoubleClicked: timeline.editGuide(model.frame) 0205 onClicked: mouse => { 0206 if (root.activeTool !== ProjectTool.SlipTool) { 0207 proxy.position = model.frame 0208 } 0209 if (mouse.button == Qt.RightButton) { 0210 root.showRulerMenu() 0211 } 0212 } 0213 onEntered: { 0214 rulerRoot.hoverGuide = true 0215 } 0216 onExited: { 0217 rulerRoot.hoverGuide = false 0218 } 0219 } 0220 } 0221 } 0222 } 0223 } 0224 0225 // Ruler marks 0226 Item { 0227 id: timecodeContainer 0228 anchors.top: parent.top 0229 anchors.topMargin: guideLabelHeight 0230 anchors.bottom: parent.bottom 0231 anchors.bottomMargin: zoneHeight 0232 anchors.left: parent.left 0233 anchors.right: parent.right 0234 Repeater { 0235 id: tickRepeater 0236 model: Math.ceil(rulercontainer.width / rulerRoot.tickSpacing) + 2 0237 property int offset: Math.floor(scrollView.contentX /rulerRoot.tickSpacing) 0238 Item { 0239 property int realPos: (tickRepeater.offset + index) * rulerRoot.tickSpacing / timeline.scaleFactor 0240 x: Math.round(realPos * timeline.scaleFactor) 0241 height: parent.height 0242 property bool showText: (tickRepeater.offset + index)%rulerRoot.labelMod == 0 0243 Rectangle { 0244 anchors.bottom: parent.bottom 0245 height: parent.showText ? root.baseUnit * 0.8 : 4 0246 width: 1 0247 color: dimmedColor2 0248 } 0249 Label { 0250 visible: parent.showText 0251 anchors.top: parent.top 0252 text: timeline.timecode(parent.realPos) 0253 font: miniFont 0254 color: dimmedColor 0255 } 0256 } 0257 } 0258 } 0259 0260 RulerZone { 0261 id: zone 0262 Binding { 0263 target: zone 0264 property: "frameIn" 0265 value: timeline.zoneIn 0266 } 0267 Binding { 0268 target: zone 0269 property: "frameOut" 0270 value: timeline.zoneOut 0271 } 0272 color: useTimelineRuler ? Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.9) : 0273 Qt.rgba(activePalette.highlight.r,activePalette.highlight.g,activePalette.highlight.b,0.5) 0274 anchors.bottom: parent.bottom 0275 height: zoneHeight 0276 function updateZone(start, end, update) 0277 { 0278 timeline.updateZone(start, end, update) 0279 } 0280 } 0281 0282 // Master effect zones 0283 Repeater { 0284 model: effectZones 0285 Rectangle { 0286 x: effectZones[index].x * timeline.scaleFactor 0287 height: zoneHeight - 1 0288 width: (effectZones[index].y - effectZones[index].x) * timeline.scaleFactor 0289 color: "blueviolet" 0290 anchors.bottom: parent.bottom 0291 opacity: 0.4 0292 } 0293 } 0294 0295 // Effect zone 0296 RulerZone { 0297 id: effectZone 0298 Binding { 0299 target: effectZone 0300 property: "frameIn" 0301 value: timeline.effectZone.x 0302 } 0303 Binding { 0304 target: effectZone 0305 property: "frameOut" 0306 value: timeline.effectZone.y 0307 } 0308 color: "orchid" 0309 anchors.bottom: parent.bottom 0310 height: zoneHeight - 1 0311 opacity: 0.7 0312 function updateZone(start, end, update) 0313 { 0314 timeline.updateEffectZone(start, end, update) 0315 } 0316 } 0317 } 0318