QmlProfiler: Provide a horizontal scroll bar for the timeline

This requires the consolidation of the nested Flickable elements into
one, which is probably a good idea anyway. The horizontal scroll bar is
important because people might not understand that they can use the
overview for scrolling.

Change-Id: Ie1555265fc3edafaf6e6e4f34d77b0d034d45639
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Ulf Hermann
2014-02-27 12:14:45 +01:00
parent 1817c48c7b
commit 3cc743f1bf
3 changed files with 164 additions and 167 deletions

View File

@@ -66,6 +66,8 @@ Rectangle {
property date recordingStartDate
property real elapsedTime
color: "#dcdcdc"
// ***** connections with external objects
Connections {
target: zoomControl
@@ -230,12 +232,51 @@ Rectangle {
}
Flickable {
id: vertflick
id: labelsflick
flickableDirection: Flickable.VerticalFlick
anchors.fill: parent
clip: true
interactive: false
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
width: labels.width
contentY: flick.contentY
Rectangle {
id: labels
anchors.left: parent.left
width: 150
color: root.color
height: col.height
property int rowCount: qmlProfilerModelProxy.categoryCount();
Column {
id: col
Repeater {
model: labels.rowCount
delegate: CategoryLabel { }
}
}
}
}
// border between labels and timeline
Rectangle {
id: labelsborder
anchors.left: labelsflick.right
anchors.top: parent.top
anchors.bottom: parent.bottom
width: 1
color: "#858585"
}
Flickable {
id: flick
contentHeight: labels.height
contentWidth: 0
flickableDirection: Flickable.HorizontalAndVerticalFlick
boundsBehavior: Flickable.StopAtBounds
clip:true
// ScrollView will try to deinteractivate it. We don't want that
// as the horizontal flickable is interactive, too. We do occasionally
@@ -244,41 +285,27 @@ Rectangle {
onInteractiveChanged: interactive = stayInteractive
onStayInteractiveChanged: interactive = stayInteractive
// ***** child items
TimeMarks {
id: backgroundMarks
y: vertflick.contentY
height: vertflick.height
width: root.width - labels.width
anchors.left: labels.right
}
Flickable {
function setContentWidth() {
var duration = Math.abs(zoomControl.endTime() - zoomControl.startTime());
if (duration > 0)
contentWidth = qmlProfilerModelProxy.traceDuration() * width / duration;
}
id: flick
anchors.top: parent.top
anchors.topMargin: labels.y
anchors.right: parent.right
anchors.left: labels.right
contentWidth: 0
height: labels.height + labelsTail.height
flickableDirection: Flickable.HorizontalFlick
boundsBehavior: Flickable.StopAtBounds
onContentXChanged: view.updateZoomControl()
onWidthChanged: setContentWidth()
clip:true
// ***** child items
TimeMarks {
id: backgroundMarks
y: flick.contentY
x: flick.contentX
height: flick.height
width: scroller.width
}
SelectionRange {
id: selectionRange
visible: root.selectionRangeMode && creationState !== 0
height: parent.height
z: 2
}
@@ -288,9 +315,11 @@ Rectangle {
profilerModelProxy: qmlProfilerModelProxy
x: flick.contentX
y: vertflick.contentY
width: flick.width
height: vertflick.height
y: flick.contentY
// paint "under" the vertical scrollbar, so that it always matches with the timemarks
width: scroller.width
height: flick.height
onEndTimeChanged: requestPaint()
onYChanged: requestPaint()
@@ -360,6 +389,7 @@ Rectangle {
width: flick.width
height: flick.height
x: flick.contentX
y: flick.contentY
hoverEnabled: enabled
z: 2
@@ -378,44 +408,13 @@ Rectangle {
}
}
Rectangle {
id: labels
width: 150
color: "#dcdcdc"
height: col.height
property int rowCount: qmlProfilerModelProxy.categoryCount();
Column {
id: col
Repeater {
model: labels.rowCount
delegate: CategoryLabel { }
}
}
}
Rectangle {
id: labelsTail
anchors.top: labels.bottom
height: Math.max(0, vertflick.height - labels.height)
width: labels.width
color: labels.color
}
// border between labels and timeline
Rectangle {
anchors.left: labels.right
anchors.top: labels.top
anchors.bottom: labelsTail.bottom
width: 1
color: "#858585"
}
}
ScrollView {
contentItem: vertflick
anchors.fill: parent
id: scroller
contentItem: flick
anchors.left: labelsborder.right
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
}
SelectionRangeDetails {

View File

@@ -107,8 +107,7 @@ RangeMover {
// creation control
function releasedOnCreation() {
if (selectionRange.creationState === 2) {
flick.interactive = true;
vertflick.stayInteractive = true;
flick.stayInteractive = true;
selectionRange.creationState = 3;
selectionRangeControl.enabled = false;
}
@@ -116,8 +115,7 @@ RangeMover {
function pressedOnCreation() {
if (selectionRange.creationState === 1) {
flick.interactive = false;
vertflick.stayInteractive = false;
flick.stayInteractive = false;
selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
selectionRange.creationState = 2;
}

View File

@@ -128,7 +128,7 @@ Canvas {
// bottom
if (height > labels.height - y) {
context.fillStyle = "#f5f5f5";
context.fillRect(0, labels.height - y, width, Math.min(height - labels.height + y, labelsTail.height));
context.fillRect(0, labels.height - y, width, height - labels.height + y);
}
}
}