forked from qt-creator/qt-creator
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:
@@ -66,6 +66,8 @@ Rectangle {
|
|||||||
property date recordingStartDate
|
property date recordingStartDate
|
||||||
property real elapsedTime
|
property real elapsedTime
|
||||||
|
|
||||||
|
color: "#dcdcdc"
|
||||||
|
|
||||||
// ***** connections with external objects
|
// ***** connections with external objects
|
||||||
Connections {
|
Connections {
|
||||||
target: zoomControl
|
target: zoomControl
|
||||||
@@ -230,12 +232,51 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Flickable {
|
Flickable {
|
||||||
id: vertflick
|
id: labelsflick
|
||||||
flickableDirection: Flickable.VerticalFlick
|
flickableDirection: Flickable.VerticalFlick
|
||||||
anchors.fill: parent
|
interactive: false
|
||||||
clip: true
|
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
|
contentHeight: labels.height
|
||||||
|
contentWidth: 0
|
||||||
|
flickableDirection: Flickable.HorizontalAndVerticalFlick
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
clip:true
|
||||||
|
|
||||||
// ScrollView will try to deinteractivate it. We don't want that
|
// ScrollView will try to deinteractivate it. We don't want that
|
||||||
// as the horizontal flickable is interactive, too. We do occasionally
|
// as the horizontal flickable is interactive, too. We do occasionally
|
||||||
@@ -244,41 +285,27 @@ Rectangle {
|
|||||||
onInteractiveChanged: interactive = stayInteractive
|
onInteractiveChanged: interactive = stayInteractive
|
||||||
onStayInteractiveChanged: 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() {
|
function setContentWidth() {
|
||||||
var duration = Math.abs(zoomControl.endTime() - zoomControl.startTime());
|
var duration = Math.abs(zoomControl.endTime() - zoomControl.startTime());
|
||||||
if (duration > 0)
|
if (duration > 0)
|
||||||
contentWidth = qmlProfilerModelProxy.traceDuration() * width / duration;
|
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()
|
onContentXChanged: view.updateZoomControl()
|
||||||
onWidthChanged: setContentWidth()
|
onWidthChanged: setContentWidth()
|
||||||
|
|
||||||
clip:true
|
// ***** child items
|
||||||
|
TimeMarks {
|
||||||
|
id: backgroundMarks
|
||||||
|
y: flick.contentY
|
||||||
|
x: flick.contentX
|
||||||
|
height: flick.height
|
||||||
|
width: scroller.width
|
||||||
|
}
|
||||||
|
|
||||||
SelectionRange {
|
SelectionRange {
|
||||||
id: selectionRange
|
id: selectionRange
|
||||||
visible: root.selectionRangeMode && creationState !== 0
|
visible: root.selectionRangeMode && creationState !== 0
|
||||||
height: parent.height
|
|
||||||
z: 2
|
z: 2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,9 +315,11 @@ Rectangle {
|
|||||||
profilerModelProxy: qmlProfilerModelProxy
|
profilerModelProxy: qmlProfilerModelProxy
|
||||||
|
|
||||||
x: flick.contentX
|
x: flick.contentX
|
||||||
y: vertflick.contentY
|
y: flick.contentY
|
||||||
width: flick.width
|
|
||||||
height: vertflick.height
|
// paint "under" the vertical scrollbar, so that it always matches with the timemarks
|
||||||
|
width: scroller.width
|
||||||
|
height: flick.height
|
||||||
|
|
||||||
onEndTimeChanged: requestPaint()
|
onEndTimeChanged: requestPaint()
|
||||||
onYChanged: requestPaint()
|
onYChanged: requestPaint()
|
||||||
@@ -360,6 +389,7 @@ Rectangle {
|
|||||||
width: flick.width
|
width: flick.width
|
||||||
height: flick.height
|
height: flick.height
|
||||||
x: flick.contentX
|
x: flick.contentX
|
||||||
|
y: flick.contentY
|
||||||
hoverEnabled: enabled
|
hoverEnabled: enabled
|
||||||
z: 2
|
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 {
|
ScrollView {
|
||||||
contentItem: vertflick
|
id: scroller
|
||||||
anchors.fill: parent
|
contentItem: flick
|
||||||
|
anchors.left: labelsborder.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectionRangeDetails {
|
SelectionRangeDetails {
|
||||||
|
|||||||
@@ -107,8 +107,7 @@ RangeMover {
|
|||||||
// creation control
|
// creation control
|
||||||
function releasedOnCreation() {
|
function releasedOnCreation() {
|
||||||
if (selectionRange.creationState === 2) {
|
if (selectionRange.creationState === 2) {
|
||||||
flick.interactive = true;
|
flick.stayInteractive = true;
|
||||||
vertflick.stayInteractive = true;
|
|
||||||
selectionRange.creationState = 3;
|
selectionRange.creationState = 3;
|
||||||
selectionRangeControl.enabled = false;
|
selectionRangeControl.enabled = false;
|
||||||
}
|
}
|
||||||
@@ -116,8 +115,7 @@ RangeMover {
|
|||||||
|
|
||||||
function pressedOnCreation() {
|
function pressedOnCreation() {
|
||||||
if (selectionRange.creationState === 1) {
|
if (selectionRange.creationState === 1) {
|
||||||
flick.interactive = false;
|
flick.stayInteractive = false;
|
||||||
vertflick.stayInteractive = false;
|
|
||||||
selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
|
selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
|
||||||
selectionRange.creationState = 2;
|
selectionRange.creationState = 2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ Canvas {
|
|||||||
// bottom
|
// bottom
|
||||||
if (height > labels.height - y) {
|
if (height > labels.height - y) {
|
||||||
context.fillStyle = "#f5f5f5";
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user