Ruler.qml 6.39 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * Copyright (c) 2013 Meltytech, LLC
 * Author: Dan Dennedy <dan@dennedy.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

19
20
import QtQuick 2.11
import QtQuick.Controls 2.4
21

22
Item {
23
    id: rulerRoot
24
    // The standard width for labels. Depends on format used (frame number or full timecode)
25
    property int labelSize: fontMetrics.boundingRect(timeline.timecode(36000)).width
26
27
28
29
    // The spacing between labels. Depends on labelSize
    property real labelSpacing: labelSize
    // The space we want between each ticks in the ruler
    property real tickSpacing: timeline.scaleFactor
30
    property alias rulerZone : zone
31
    property int workingPreview : timeline.workingPreview
32
    property int labelMod: 1
33
    property bool useTimelineRuler : timeline.useRuler
34
    property int zoneHeight: Math.ceil(root.baseUnit / 2)
35
    property bool showZoneLabels: false
36
    property bool resizeActive: false // Used to decide which mouse cursor we should display
37

38
    function adjustStepSize() {
39
40
41
42
43
        if (timeline.scaleFactor > 19) {
            // Frame size >= 20 pixels
            rulerRoot.tickSpacing = timeline.scaleFactor
            // labelSpacing cannot be smaller than 1 frame
            rulerRoot.labelSpacing = timeline.scaleFactor > rulerRoot.labelSize * 1.3 ? timeline.scaleFactor : Math.floor(rulerRoot.labelSize/timeline.scaleFactor) * timeline.scaleFactor
44
        } else {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
45
            rulerRoot.tickSpacing = Math.floor(3 * root.fontUnit / timeline.scaleFactor) * timeline.scaleFactor
46
            rulerRoot.labelSpacing = (Math.floor(rulerRoot.labelSize/rulerRoot.tickSpacing) + 1) * rulerRoot.tickSpacing
47
        }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
48
49
        rulerRoot.labelMod = Math.max(1, Math.ceil((rulerRoot.labelSize + root.fontUnit) / rulerRoot.tickSpacing))
        //console.log('LABELMOD: ', Math.ceil((rulerRoot.labelSize + root.fontUnit) / rulerRoot.tickSpacing)))
50
        tickRepeater.model = Math.ceil(scrollView.width / rulerRoot.tickSpacing) + 2
51
52
    }

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
53
    function adjustFormat() {
54
        rulerRoot.labelSize = fontMetrics.boundingRect(timeline.timecode(36000)).width
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
55
        adjustStepSize()
56
        repaintRuler()
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
57
    }
58

59
60
61
    function repaintRuler() {
        // Enforce repaint
        tickRepeater.model = 0
62
        tickRepeater.model = Math.ceil(scrollView.width / rulerRoot.tickSpacing) + 2
63
    }
64

65
    // Timeline preview stuff
66
67
    Repeater {
        model: timeline.dirtyChunks
68
        anchors.fill: parent
69
        delegate: Rectangle {
70
            x: modelData * timeline.scaleFactor
71
            y: 0
72
            width: 25 * timeline.scaleFactor
73
            height: parent.height / 4
74
75
76
77
78
79
            color: 'darkred'
        }
    }

    Repeater {
        model: timeline.renderedChunks
80
        anchors.fill: parent
81
        delegate: Rectangle {
82
            x: modelData * timeline.scaleFactor
83
            y: 0
84
            width: 25 * timeline.scaleFactor
85
            height: parent.height / 4
86
87
88
89
90
            color: 'darkgreen'
        }
    }
    Rectangle {
        id: working
91
        x: rulerRoot.workingPreview * timeline.scaleFactor
92
        y: 0
93
        width: 25 * timeline.scaleFactor
94
        height: parent.height / 4
95
        color: 'orange'
96
        visible: rulerRoot.workingPreview > -1
97
    }
98
    
99
    // Ruler marks
100
    Repeater {
101
        id: tickRepeater
102
        model: Math.ceil(scrollView.width / rulerRoot.tickSpacing) + 2
103
        property int offset: Math.floor(scrollView.contentX /rulerRoot.tickSpacing)
104
105
106
107
108
109
110
        Item {
            property int realPos: (tickRepeater.offset + index) * rulerRoot.tickSpacing / timeline.scaleFactor
            x: realPos * timeline.scaleFactor
            height: parent.height
            property bool showText: (tickRepeater.offset + index)%rulerRoot.labelMod == 0
            Rectangle {
                anchors.bottom: parent.bottom
111
                anchors.bottomMargin: root.baseUnit / 2
112
113
114
115
116
117
118
119
                height: parent.showText ? 8 : 4
                width: 1
                color: activePalette.windowText
                opacity: 0.5
            }
            Label {
                visible: parent.showText
                anchors.top: parent.top
120
                opacity: 0.7
121
                text: timeline.timecode(parent.realPos)
122
                font: miniFont
123
124
                color: activePalette.windowText
            }
125
126
        }
    }
127

128
    // monitor zone
129
130
131
132
    Rectangle {
        width: rulerRoot.width
        height: 1
        anchors.bottom: parent.bottom
133
        anchors.bottomMargin: zoneHeight
134
135
136
137
138
139
140
141
        color: activePalette.shadow
        Rectangle {
            width: rulerRoot.width
            height: 1
            anchors.top: parent.bottom
            color: activePalette.light
        }
    }
142
    RulerZone {
143
        id: zone
144
145
146
147
148
149
150
151
152
153
        Binding {
            target: zone
            property: "frameIn"
            value: timeline.zoneIn
        }
        Binding {
            target: zone
            property: "frameOut"
            value: timeline.zoneOut
        }
154
155
        color: useTimelineRuler ? 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)
156
        anchors.bottom: parent.bottom
157
        height: zoneHeight
158
159
160
        function updateZone(start, end, update)
        {
            timeline.updateZone(start, end, update)
161
        }
162
    }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
    // Effect zone
    RulerZone {
        id: effectZone
        Binding {
            target: effectZone
            property: "frameIn"
            value: timeline.effectZone.x
        }
        Binding {
            target: effectZone
            property: "frameOut"
            value: timeline.effectZone.y
        }
        color: 'yellow'
        opacity: 0.9
        anchors.bottom: parent.bottom
179
        height: zoneHeight
180
181
182
183
184
        function updateZone(start, end, update)
        {
            timeline.updateEffectZone(start, end, update)
        }
    }
185
186
}