Commit df92fa26 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Timeline zoombar, related to #651 !184

parent 199d7d3a
import QtQuick 2.0
import QtQml.Models 2.11
import QtQuick.Controls 2.4
Rectangle {
id: zoomContainer
SystemPalette { id: barPalette; colorGroup: SystemPalette.Disabled }
height: Math.round(root.baseUnit * 0.7)
property bool hoveredBar: barArea.containsMouse || zoomArea.containsMouse || zoomArea.pressed || zoomStart.isActive || zoomEnd.isActive
color: hoveredBar ? barPalette.text : activePalette.window
//border.color: activePalette.dark
//border.width: 1
radius: height / 2
visible: root.zoomBarWidth < 1
MouseArea {
id: barArea
anchors.fill: parent
hoverEnabled: true
onWheel: {
if (wheel.modifiers & Qt.ControlModifier) {
zoomByWheel(wheel)
} else {
if (wheel.angleDelta.y < 0) {
var newPos = Math.min(zoomHandleContainer.width - zoomBar.width, zoomBar.x + 10)
} else {
var newPos = Math.max(0, zoomBar.x - 10)
}
scrollView.contentX = newPos / zoomHandleContainer.width * scrollView.contentWidth
}
}
onPressed: {
if (mouse.buttons === Qt.LeftButton) {
if (mouseX > zoomEnd.x + zoomEnd.width) {
scrollView.contentX = (zoomBar.x + zoomBar.width) / zoomHandleContainer.width * scrollView.contentWidth
} else if (mouseX < zoomBar.x) {
scrollView.contentX = Math.max(0, (zoomBar.x - zoomBar.width) / zoomHandleContainer.width * scrollView.contentWidth)
}
}
}
}
Item {
id: zoomHandleContainer
property int previousX: 0
property double previousScale: -1
anchors.fill: parent
//anchors.margins: 1
Rectangle {
id: zoomBar
color: (zoomArea.containsMouse || zoomArea.pressed || zoomStart.isActive || zoomEnd.isActive) ? activePalette.highlight : hoveredBar ? activePalette.text : barPalette.text
opacity: hoveredBar ? 0.6 : 1
height: parent.height
property bool placeHolderBar: !zoomStart.pressed && !zoomEnd.pressed && root.zoomBarWidth * zoomHandleContainer.width < root.baseUnit
width: placeHolderBar ? root.baseUnit : root.zoomBarWidth * zoomHandleContainer.width
x: root.zoomStart * zoomHandleContainer.width
radius: hoveredBar ? 0 : height / 2
MouseArea {
id: zoomArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
drag.target: zoomBar
drag.axis: Drag.XAxis
drag.smoothed: false
drag.minimumX: 0
drag.maximumX: zoomHandleContainer.width - zoomBar.width
onPositionChanged: {
if (mouse.buttons === Qt.LeftButton) {
scrollView.contentX = zoomBar.x / zoomHandleContainer.width * scrollView.contentWidth
}
}
onDoubleClicked: {
// Switch between current zoom and fit all project
if (zoomBar.x == 0 && timeline.scaleFactor == root.fitZoom()) {
// Restore previous pos
if (zoomHandleContainer.previousScale > -1) {
root.zoomOnBar = zoomHandleContainer.previousX
timeline.scaleFactor = zoomHandleContainer.previousScale
}
} else {
zoomHandleContainer.previousX = Math.round(zoomBar.x / (zoomHandleContainer.width) * scrollView.contentWidth / timeline.scaleFactor)
zoomHandleContainer.previousScale = timeline.scaleFactor
root.zoomOnBar = 0
timeline.scaleFactor = root.fitZoom()
}
}
}
}
//Start drag handle
MouseArea {
id: zoomStart
property bool isActive: zoomStart.containsMouse || zoomStart.pressed
anchors.right: zoomBar.left
anchors.bottom: zoomBar.bottom
width: zoomBar.height
height: zoomBar.height
hoverEnabled: true
drag.axis: Drag.XAxis
drag.smoothed: false
drag.maximumX: zoomEnd.x - width
cursorShape: Qt.SizeHorCursor
onPressed: {
anchors.right = undefined
startHandleRect.anchors.fill = undefined
}
onReleased: {
anchors.right = zoomBar.left
startHandleRect.anchors.fill = zoomStart
}
onPositionChanged: {
if (mouse.buttons === Qt.LeftButton) {
var updatedPos = Math.max(0, x + mouseX + width)
updatedPos = Math.min(updatedPos, zoomEnd.x - 1)
var firstFrame = Math.round(updatedPos / (zoomHandleContainer.width) * scrollView.contentWidth / timeline.scaleFactor)
var lastFrame = Math.round((zoomBar.x + zoomBar.width) / (zoomHandleContainer.width) * scrollView.contentWidth / timeline.scaleFactor)
root.zoomOnBar = firstFrame
timeline.scaleFactor = scrollView.width / (lastFrame - firstFrame)
startHandleRect.x = updatedPos - x - width
}
}
Rectangle {
id: startHandleRect
anchors.fill: parent
radius: height / 2
color: zoomStart.isActive ? activePalette.highlight : hoveredBar ? activePalette.text : barPalette.light
visible: hoveredBar
Rectangle {
anchors.fill: parent
anchors.leftMargin: height / 2
color: parent.color
}
}
}
//End drag handle
MouseArea {
id: zoomEnd
property bool isActive: zoomEnd.containsMouse || zoomEnd.pressed
anchors.left: zoomBar.right
anchors.bottom: zoomBar.bottom
width: zoomBar.height
height: zoomBar.height
hoverEnabled: true
cursorShape: Qt.SizeHorCursor
drag.minimumX: zoomStart.x + width
onPressed: {
anchors.left = undefined
endHandleRect.anchors.fill = undefined
}
onReleased: {
anchors.left = zoomBar.right
endHandleRect.anchors.fill = zoomEnd
}
onPositionChanged: {
if (mouse.buttons === Qt.LeftButton) {
var updatedPos = Math.min(zoomHandleContainer.width, x + mouseX)
updatedPos = Math.max(updatedPos, zoomBar.x + 1)
var lastFrame = Math.round(updatedPos / (zoomHandleContainer.width) * scrollView.contentWidth / timeline.scaleFactor)
var firstFrame = Math.round((zoomBar.x) / (zoomHandleContainer.width) * scrollView.contentWidth / timeline.scaleFactor)
root.zoomOnBar = firstFrame
timeline.scaleFactor = scrollView.width / (lastFrame - firstFrame)
endHandleRect.x = updatedPos - x
}
}
Rectangle {
id: endHandleRect
anchors.fill: parent
radius: height / 2
color: zoomEnd.isActive ? activePalette.highlight : hoveredBar ? activePalette.text : barPalette.light
visible: hoveredBar
Rectangle {
anchors.fill: parent
anchors.rightMargin: height / 2
color: parent.color
}
}
}
}
/*ToolTip {
visible: zoomArea.containsMouse
delay: 1000
timeout: 5000
background: Rectangle {
color: activePalette.alternateBase
border.color: activePalette.light
}
contentItem: Label {
color: activePalette.text
font: fixedFont
text: controller.toTimecode((root.duration + 1 )* root.zoomFactor)
}
}*/
}
......@@ -28,6 +28,10 @@ Rectangle {
signal processingDrag(bool dragging)
signal showSubtitleClipMenu()
// Zoombar properties
property double zoomStart: scrollView.visibleArea.xPosition
property double zoomBarWidth: scrollView.visibleArea.widthRatio
FontMetrics {
id: fontMetrics
font: miniFont
......@@ -163,7 +167,7 @@ Rectangle {
function verticalScroll(wheel) {
var newScroll = Math.min(
scrollView.contentY - wheel.angleDelta.y,
trackHeaders.height + subtitleTrackHeader.height - tracksArea.height + horScroll.height + ruler.height
trackHeaders.height + subtitleTrackHeader.height - tracksArea.height + horZoomBar.height + ruler.height
)
scrollView.contentY = Math.max(newScroll, 0)
}
......@@ -383,6 +387,8 @@ Rectangle {
property int trackHeight
property int copiedClip: -1
property int zoomOnMouse: -1
// The first visible frame in case of scaling triggered by zoombar
property int zoomOnBar: -1
property int viewActiveTrack: timeline.activeTrack
property int wheelAccumulatedDelta: 0
readonly property int defaultDeltasPerStep: 120
......@@ -407,10 +413,14 @@ Rectangle {
}
//onCurrentTrackChanged: timeline.selection = []
onTimeScaleChanged: {
if (root.zoomOnMouse >= 0) {
scrollView.contentX = Math.max(0, root.zoomOnMouse * timeline.scaleFactor - getMouseX())
root.zoomOnMouse = -1
} else if (root.zoomOnBar >= 0) {
scrollView.contentX = Math.max(0, root.zoomOnBar * timeline.scaleFactor )
root.zoomOnBar = -1
} else {
scrollView.contentX = Math.max(0, root.consumerPosition * timeline.scaleFactor - (scrollView.width / 2))
}
......@@ -427,11 +437,16 @@ Rectangle {
}
onViewActiveTrackChanged: {
if (timeline.activeTrack == -2) {
// subtitle track
scrollView.contentY = 0
return
}
var tk = Logic.getTrackById(timeline.activeTrack)
if (tk.y + subtitleTrack.height < scrollView.contentY) {
scrollView.contentY = Math.max(0, tk.y + subtitleTrack.height)
} else if (tk.y + tk.height + subtitleTrack.height > scrollView.contentY + scrollView.height) {
var newY = Math.min(trackHeaders.height + subtitleTrack.height - scrollView.height + scrollView.ScrollBar.horizontal.height, tk.y + tk.height - scrollView.height + subtitleTrack.height)
var newY = Math.min(trackHeaders.height + subtitleTrack.height - scrollView.height, tk.y + tk.height - scrollView.height + subtitleTrack.height)
if (newY >= 0) {
scrollView.contentY = newY
}
......@@ -1188,7 +1203,7 @@ Rectangle {
if (pressed && ((mouse.buttons === Qt.MidButton) || (mouse.buttons === Qt.LeftButton && root.activeTool == 0 && (mouse.modifiers & Qt.ControlModifier) && !shiftPress))) {
// Pan view
var newScroll = Math.min(scrollView.contentX - (mouseX - clickX), timeline.fullDuration * root.timeScale - (scrollView.width - scrollView.ScrollBar.vertical.width))
var vScroll = Math.min(scrollView.contentY - (mouseY - clickY), trackHeaders.height + subtitleTrackHeader.height - scrollView.height + scrollView.ScrollBar.horizontal.height)
var vScroll = Math.min(scrollView.contentY - (mouseY - clickY), trackHeaders.height + subtitleTrackHeader.height - scrollView.height+ horZoomBar.height)
scrollView.contentX = Math.max(newScroll, 0)
scrollView.contentY = Math.max(vScroll, 0)
clickX = mouseX
......@@ -1385,18 +1400,20 @@ Rectangle {
id: scrollView
anchors.fill: parent
anchors.rightMargin: vertScroll.visible ? vertScroll.width : 0
anchors.bottomMargin: horScroll.visible ? horScroll.height : 0
anchors.bottomMargin: horZoomBar.visible ? horZoomBar.height : 0
// Click and drag should seek, not scroll the timeline view
//flickableItem.interactive: false
clip: true
interactive: false
ScrollBar.horizontal: ScrollBar {
/*
// Replaced by our custom ZoomBar
ScrollBar.horizontal: ScrollBar {
id: horScroll
parent: scrollView.parent
anchors.top: scrollView.bottom
anchors.top: scrollView.top
anchors.left: scrollView.left
anchors.right: scrollView.right
}
}*/
ScrollBar.vertical: ScrollBar {
id: vertScroll
parent: scrollView.parent
......@@ -1665,6 +1682,14 @@ Rectangle {
}
}
}
ZoomBar {
id: horZoomBar
anchors {
left: parent.left
right: parent.right
top: scrollView.bottom
}
}
}
}
Rectangle {
......@@ -1891,7 +1916,7 @@ Rectangle {
vertical = 0
stop()
} else {
var maxScroll = trackHeaders.height - tracksArea.height + horScroll.height + ruler.height + subtitleTrack.height
var maxScroll = trackHeaders.height - tracksArea.height + horZoomBar.height + ruler.height + subtitleTrack.height
if (scrollView.contentY > maxScroll) {
scrollView.contentY = Math.max(0, maxScroll)
vertical = 0
......
......@@ -44,6 +44,7 @@
<file alias="EffectSlider.qml">effects/effectstack/view/qml/EffectSlider.qml</file>
<file alias="LiftGammaGain.qml">effects/effectstack/view/qml/LiftGammaGain.qml</file>
<file alias="splash.qml">qml/splash.qml</file>
<file alias="ZoomBar.qml">timeline2/view/qml/ZoomBar.qml</file>
</qresource>
<qresource prefix="/data">
<file alias="blacklisted_effects.txt">../data/blacklisted_effects.txt</file>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment