diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-06-06 19:23:15 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-06-18 12:35:36 +0000 |
commit | 5f9f8f9f167d7f21d4b2b7c9c2b143a8e86a9d8c (patch) | |
tree | 6652253c5f6ae8e3613ff65b2fa5e30ac72a1dfc /src/libs | |
parent | b16ba2ba59b2877d6b6827f2d3717fd40c6a6627 (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.cpp | 21 | ||||
-rw-r--r-- | src/libs/tracing/flamegraph.h | 22 | ||||
-rw-r--r-- | src/libs/tracing/qml/FlameGraphView.qml | 49 |
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: { |