aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-06-06 19:23:15 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-06-18 12:35:36 +0000
commit5f9f8f9f167d7f21d4b2b7c9c2b143a8e86a9d8c (patch)
tree6652253c5f6ae8e3613ff65b2fa5e30ac72a1dfc /src/libs
parentb16ba2ba59b2877d6b6827f2d3717fd40c6a6627 (diff)
Tracing: Handle mouse events in FlameGraph QQuickItem
Having an additional MouseArea as child of a ScrollView or a Flickable is not well defined and leads to inconsistent behavior on different systems. We can easily catch the relevant events in the FlameGraph item itself. Also, don't redirect the typeSelected() signals through the model. They don't belong there. Change-Id: I77c17977b5a51d57ccd2ef880d3d6c6a604b7f78 Task-number: QTCREATORBUG-20573 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/tracing/flamegraph.cpp21
-rw-r--r--src/libs/tracing/flamegraph.h22
-rw-r--r--src/libs/tracing/qml/FlameGraphView.qml49
3 files changed, 65 insertions, 27 deletions
diff --git a/src/libs/tracing/flamegraph.cpp b/src/libs/tracing/flamegraph.cpp
index 2fa38313ed..9d7df037f5 100644
--- a/src/libs/tracing/flamegraph.cpp
+++ b/src/libs/tracing/flamegraph.cpp
@@ -30,6 +30,8 @@ namespace FlameGraph {
FlameGraph::FlameGraph(QQuickItem *parent) :
QQuickItem(parent)
{
+ setAcceptedMouseButtons(Qt::LeftButton);
+
// Queue the rebuild in this case so that a delegate can set the root without getting deleted
// during the call.
connect(this, &FlameGraph::rootChanged, this, &FlameGraph::rebuild, Qt::QueuedConnection);
@@ -130,7 +132,6 @@ QObject *FlameGraph::appendChild(QObject *parentObject, QQuickItem *parentItem,
return childObject;
}
-
int FlameGraph::buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth,
int maximumDepth)
{
@@ -194,4 +195,22 @@ void FlameGraph::rebuild()
emit depthChanged(m_depth);
}
+void FlameGraph::mousePressEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+void FlameGraph::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+ setSelectedTypeId(-1);
+}
+
+void FlameGraph::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+ setSelectedTypeId(-1);
+ resetRoot();
+}
+
} // namespace FlameGraph
diff --git a/src/libs/tracing/flamegraph.h b/src/libs/tracing/flamegraph.h
index 265423e393..a9f6ecc371 100644
--- a/src/libs/tracing/flamegraph.h
+++ b/src/libs/tracing/flamegraph.h
@@ -45,6 +45,8 @@ class TRACING_EXPORT FlameGraph : public QQuickItem
NOTIFY maximumDepthChanged)
Q_PROPERTY(int depth READ depth NOTIFY depthChanged)
Q_PROPERTY(QPersistentModelIndex root READ root WRITE setRoot NOTIFY rootChanged)
+ Q_PROPERTY(int selectedTypeId READ selectedTypeId WRITE setSelectedTypeId
+ NOTIFY selectedTypeIdChanged)
public:
FlameGraph(QQuickItem *parent = nullptr);
@@ -101,6 +103,20 @@ public:
static FlameGraphAttached *qmlAttachedProperties(QObject *object);
+ int selectedTypeId() const
+ {
+ return m_selectedTypeId;
+ }
+
+ void setSelectedTypeId(int selectedTypeId)
+ {
+ if (m_selectedTypeId == selectedTypeId)
+ return;
+
+ m_selectedTypeId = selectedTypeId;
+ emit selectedTypeIdChanged(m_selectedTypeId);
+ }
+
signals:
void delegateChanged(QQmlComponent *delegate);
void modelChanged(QAbstractItemModel *model);
@@ -109,6 +125,7 @@ signals:
void depthChanged(int depth);
void maximumDepthChanged();
void rootChanged(const QPersistentModelIndex &root);
+ void selectedTypeIdChanged(int selectedTypeId);
private:
void rebuild();
@@ -120,11 +137,16 @@ private:
int m_depth = 0;
qreal m_sizeThreshold = 0;
int m_maximumDepth = std::numeric_limits<int>::max();
+ int m_selectedTypeId = -1;
int buildNode(const QModelIndex &parentIndex, QObject *parentObject, int depth,
int maximumDepth);
QObject *appendChild(QObject *parentObject, QQuickItem *parentItem, QQmlContext *context,
const QModelIndex &childIndex, qreal position, qreal size);
+
+ void mousePressEvent(QMouseEvent *event) final;
+ void mouseReleaseEvent(QMouseEvent *event) final;
+ void mouseDoubleClickEvent(QMouseEvent *event) final;
};
} // namespace FlameGraph
diff --git a/src/libs/tracing/qml/FlameGraphView.qml b/src/libs/tracing/qml/FlameGraphView.qml
index b8706d0379..8f99b304c8 100644
--- a/src/libs/tracing/qml/FlameGraphView.qml
+++ b/src/libs/tracing/qml/FlameGraphView.qml
@@ -32,7 +32,16 @@ import QtQuick.Controls 1.3
ScrollView {
id: root
+
property int selectedTypeId: -1
+ signal typeSelected(int typeId)
+
+ onSelectedTypeIdChanged: {
+ // selectedTypeId can be set from outside. Don't send typeSelected() from here.
+ tooltip.hoveredNode = null;
+ flamegraph.selectedTypeId = selectedTypeId;
+ }
+
property int sizeRole: -1
property var model: null
@@ -117,25 +126,6 @@ ScrollView {
}
}
- onSelectedTypeIdChanged: tooltip.hoveredNode = null
-
- MouseArea {
- anchors.fill: parent
- onClicked: {
- selectedTypeId = -1;
- tooltip.selectedNode = null;
- if (model !== null)
- model.typeSelected(-1);
- }
- onDoubleClicked: {
- selectedTypeId = -1;
- tooltip.selectedNode = null;
- if (model !== null)
- model.typeSelected(-1);
- flamegraph.resetRoot();
- }
- }
-
Flickable {
id: flickable
contentHeight: flamegraph.height
@@ -158,6 +148,14 @@ ScrollView {
maximumDepth: 128
y: flickable.height > height ? flickable.height - height : 0
+ onSelectedTypeIdChanged: {
+ if (selectedTypeId !== root.selectedTypeId) {
+ // Change originates from inside. Send typeSelected().
+ root.selectedTypeId = selectedTypeId;
+ root.typeSelected(selectedTypeId);
+ }
+ }
+
delegate: FlameGraphDelegate {
id: flamegraphItem
@@ -165,7 +163,7 @@ ScrollView {
property bool isHighlighted: root.isHighlighted(flamegraphItem)
itemHeight: flamegraph.delegateHeight
- isSelected: typeId !== -1 && typeId === root.selectedTypeId
+ isSelected: typeId !== -1 && typeId === flamegraph.selectedTypeId
borderColor: {
if (isSelected)
@@ -189,7 +187,7 @@ ScrollView {
onIsSelectedChanged: {
if (isSelected && (tooltip.selectedNode === null ||
- tooltip.selectedNode.typeId !== root.selectedTypeId)) {
+ tooltip.selectedNode.typeId !== flamegraph.selectedTypeId)) {
tooltip.selectedNode = flamegraphItem;
} else if (!isSelected && tooltip.selectedNode === flamegraphItem) {
tooltip.selectedNode = null;
@@ -222,7 +220,7 @@ ScrollView {
if (tooltip.hoveredNode === flamegraphItem) {
// Keep the window around until something else is hovered or selected.
if (tooltip.selectedNode === null
- || tooltip.selectedNode.typeId !== root.selectedTypeId) {
+ || tooltip.selectedNode.typeId !== flamegraph.selectedTypeId) {
tooltip.selectedNode = flamegraphItem;
}
tooltip.hoveredNode = null;
@@ -232,8 +230,7 @@ ScrollView {
function selectClicked() {
if (FlameGraph.dataValid) {
tooltip.selectedNode = flamegraphItem;
- selectedTypeId = FlameGraph.data(root.typeIdRole);
- model.typeSelected(selectedTypeId);
+ flamegraph.selectedTypeId = FlameGraph.data(root.typeIdRole);
model.gotoSourceLocation(
FlameGraph.data(root.sourceFileRole),
FlameGraph.data(root.sourceLineRole),
@@ -246,6 +243,7 @@ ScrollView {
tooltip.selectedNode = null;
tooltip.hoveredNode = null;
flamegraph.root = FlameGraph.modelIndex;
+ selectClicked();
}
// Functions, not properties to limit the initial overhead when creating the nodes,
@@ -288,9 +286,8 @@ ScrollView {
}
onClearSelection: {
- selectedTypeId = -1;
+ flamegraph.selectedTypeId = -1;
selectedNode = null;
- root.model.typeSelected(-1);
}
dialogTitle: {