From d7cb00d10c3b79c99030fee8ba7a9e21a0595960 Mon Sep 17 00:00:00 2001 From: Ulf Hermann <ulf.hermann@digia.com> Date: Wed, 13 Nov 2013 12:10:48 +0100 Subject: [PATCH] QmlProfiler: Fix jaggy behavior of range start handle The left handle of the range mover element didn't properly follow the mouse movement. Also, a lot of code is duplicated between RangeMover and SelectionRange. This change prepares RangeMover for being reused in SelectionRange by eliminating external dependencies. Task-number: QTCREATORBUG-10762 Change-Id: Ia3b83101263e7af8ed46e1aaf4e92654b0068861 Reviewed-by: Kai Koehne <kai.koehne@digia.com> --- src/plugins/qmlprofiler/qml/Overview.qml | 42 +++++--- src/plugins/qmlprofiler/qml/RangeMover.qml | 117 ++++++++++----------- 2 files changed, 83 insertions(+), 76 deletions(-) diff --git a/src/plugins/qmlprofiler/qml/Overview.qml b/src/plugins/qmlprofiler/qml/Overview.qml index a1b54369cd7..7d0916787da 100644 --- a/src/plugins/qmlprofiler/qml/Overview.qml +++ b/src/plugins/qmlprofiler/qml/Overview.qml @@ -49,12 +49,15 @@ Canvas2D { } function updateRange() { - var newStartTime = Math.round(rangeMover.x * qmlProfilerModelProxy.traceDuration() / width) + qmlProfilerModelProxy.traceStartTime(); - var newEndTime = Math.round((rangeMover.x + rangeMover.width) * qmlProfilerModelProxy.traceDuration() / width) + qmlProfilerModelProxy.traceStartTime(); + var newStartTime = Math.round(rangeMover.getLeft() * qmlProfilerModelProxy.traceDuration() / width) + qmlProfilerModelProxy.traceStartTime(); + var newEndTime = Math.round(rangeMover.getRight() * qmlProfilerModelProxy.traceDuration() / width) + qmlProfilerModelProxy.traceStartTime(); if (startTime !== newStartTime || endTime !== newEndTime) { zoomControl.setRange(newStartTime, newEndTime); } + } + function clamp(val, min, max) { + return Math.min(Math.max(val, min), max); } // ***** connections to external objects @@ -62,14 +65,17 @@ Canvas2D { target: zoomControl onRangeChanged: { if (qmlProfilerModelProxy) { - startTime = zoomControl.startTime(); - endTime = zoomControl.endTime(); + startTime = clamp(zoomControl.startTime(), qmlProfilerModelProxy.traceStartTime(), qmlProfilerModelProxy.traceEndTime()); + endTime = clamp(zoomControl.endTime(), startTime, qmlProfilerModelProxy.traceEndTime()); var newRangeX = (startTime - qmlProfilerModelProxy.traceStartTime()) * width / qmlProfilerModelProxy.traceDuration(); - if (rangeMover.x !== newRangeX) - rangeMover.x = newRangeX; - var newWidth = (endTime-startTime) * width / qmlProfilerModelProxy.traceDuration(); - if (rangeMover.width !== newWidth) - rangeMover.width = newWidth; + var newWidth = (endTime - startTime) * width / qmlProfilerModelProxy.traceDuration(); + var widthChanged = Math.abs(newWidth - rangeMover.getWidth()) > 1; + var leftChanged = Math.abs(newRangeX - rangeMover.getLeft()) > 1; + if (leftChanged) + rangeMover.setLeft(newRangeX); + + if (leftChanged || widthChanged) + rangeMover.setRight(newRangeX + newWidth); } } } @@ -97,13 +103,20 @@ Canvas2D { MouseArea { anchors.fill: canvas function jumpTo(posX) { - var newX = posX - rangeMover.width/2; + var rangeWidth = rangeMover.getWidth(); + var newX = posX - rangeWidth / 2; if (newX < 0) newX = 0; - if (newX + rangeMover.width > canvas.width) - newX = canvas.width - rangeMover.width; - rangeMover.x = newX; - updateRange(); + if (newX + rangeWidth > canvas.width) + newX = canvas.width - rangeWidth; + + if (newX < rangeMover.getLeft()) { + rangeMover.setLeft(newX); + rangeMover.setRight(newX + rangeWidth); + } else if (newX > rangeMover.getLeft()) { + rangeMover.setRight(newX + rangeWidth); + rangeMover.setLeft(newX); + } } onPressed: { @@ -117,6 +130,7 @@ Canvas2D { RangeMover { id: rangeMover visible: dataReady + onRangeChanged: canvas.updateRange() } Rectangle { diff --git a/src/plugins/qmlprofiler/qml/RangeMover.qml b/src/plugins/qmlprofiler/qml/RangeMover.qml index 5c786153db8..157fffcc44e 100644 --- a/src/plugins/qmlprofiler/qml/RangeMover.qml +++ b/src/plugins/qmlprofiler/qml/RangeMover.qml @@ -31,41 +31,46 @@ import QtQuick 2.1 Rectangle { id: rangeMover + anchors.fill: parent + color: "transparent" + signal rangeChanged() + signal rangeDoubleClicked() - + property color handleColor: "#869cd1" property color rangeColor:"#444a64b8" + property color dragColor:"#664a64b8" property color borderColor:"#cc4a64b8" property color dragMarkerColor: "#4a64b8" - width: 20 - height: 50 + property color singleLineColor: "#4a64b8" - color: rangeColor + function setLeft(left) { leftRange.x = left } + function getLeft() { return leftRange.x } - property bool dragStarted: false - onXChanged: { - if (dragStarted) canvas.updateRange() - } + function setRight(right) { rightRange.x = right } + function getRight() { return rightRange.x } - MouseArea { - anchors.fill: parent - drag.target: rangeMover - drag.axis: "XAxis" - drag.minimumX: 0 - drag.maximumX: canvas.width - rangeMover.width - onPressed: { - parent.dragStarted = true; - } - onReleased: { - parent.dragStarted = false; - } + function getWidth() { return rightRange.x - leftRange.x } + + Rectangle { + id: selectedRange + + x: leftRange.x + width: rightRange.x - leftRange.x + height: parent.height + + color: width > 1 ? (dragArea.pressed ? dragColor : rangeColor) : singleLineColor + + onXChanged: parent.rangeChanged() + onWidthChanged: parent.rangeChanged() } Rectangle { id: leftRange - // used for dragging the borders - property real initialX: 0 - property real initialWidth: 0 + onXChanged: { + if (dragArea.drag.active) + rightRange.x = x + dragArea.origWidth; + } x: 0 height: parent.height @@ -75,9 +80,9 @@ Rectangle { Rectangle { id: leftBorderHandle height: parent.height - x: -width + anchors.right: parent.left width: 7 - color: "#869cd1" + color: handleColor visible: false Image { source: "range_handle.png" @@ -85,7 +90,7 @@ Rectangle { width: 4 height: 9 fillMode: Image.Tile - y: rangeMover.height / 2 - 4 + y: parent.height / 2 - 4 } } @@ -97,25 +102,14 @@ Rectangle { } } - onXChanged: { - if (x !== 0) { - rangeMover.width = initialWidth - x; - rangeMover.x = initialX + x; - x = 0; - canvas.updateRange(); - } - } - MouseArea { - x: -10 - width: 13 - y: 0 - height: parent.height + anchors.fill: leftBorderHandle drag.target: leftRange drag.axis: "XAxis" - drag.minimumX: -parent.initialX - drag.maximumX: parent.initialWidth - 2 + drag.minimumX: 0 + drag.maximumX: rangeMover.width + drag.onActiveChanged: drag.maximumX = rightRange.x hoverEnabled: true @@ -128,17 +122,13 @@ Rectangle { onReleased: { if (!containsMouse) parent.state = ""; } - onPressed: { - parent.initialX = rangeMover.x; - parent.initialWidth = rangeMover.width; - } } } Rectangle { id: rightRange - x: rangeMover.width + x: 1 height: parent.height width: 1 color: borderColor @@ -146,9 +136,9 @@ Rectangle { Rectangle { id: rightBorderHandle height: parent.height - x: 1 + anchors.left: parent.right width: 7 - color: "#869cd1" + color: handleColor visible: false Image { source: "range_handle.png" @@ -156,7 +146,7 @@ Rectangle { width: 4 height: 9 fillMode: Image.Tile - y: rangeMover.height / 2 - 4 + y: parent.height / 2 - 4 } } @@ -168,23 +158,14 @@ Rectangle { } } - onXChanged: { - if (x!=rangeMover.width) { - rangeMover.width = x; - canvas.updateRange(); - } - } - MouseArea { - x: -3 - width: 13 - y: 0 - height: parent.height + anchors.fill: rightBorderHandle drag.target: rightRange drag.axis: "XAxis" - drag.minimumX: 1 - drag.maximumX: canvas.width - rangeMover.x + drag.minimumX: 0 + drag.maximumX: rangeMover.width + drag.onActiveChanged: drag.minimumX = leftRange.x hoverEnabled: true @@ -200,4 +181,16 @@ Rectangle { } } + MouseArea { + id: dragArea + property int origWidth: 0 + + anchors.fill: selectedRange + drag.target: leftRange + drag.axis: "XAxis" + drag.minimumX: 0 + drag.maximumX: rangeMover.width - origWidth + drag.onActiveChanged: origWidth = selectedRange.width + onDoubleClicked: parent.rangeDoubleClicked() + } } -- GitLab