forked from qt-creator/qt-creator
QmlProfiler: drag&drop reordering of models in timeline
Task-number: QTCREATORBUG-12337 Change-Id: I399593f44aa8ff8dd79c623108fecb3c317cb63c Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
@@ -33,13 +33,18 @@ import QtQuick.Controls.Styles 1.2
|
||||
|
||||
Item {
|
||||
id: labelContainer
|
||||
property string text: qmlProfilerModelProxy.displayName(modelIndex)
|
||||
property string text: trigger(1) ? qmlProfilerModelProxy.displayName(modelIndex) : ""
|
||||
property bool expanded: trigger(qmlProfilerModelProxy.expanded(modelIndex))
|
||||
property int modelIndex: index
|
||||
property int bindingTrigger: 1
|
||||
property var descriptions: []
|
||||
property var extdescriptions: []
|
||||
property var eventIds: []
|
||||
property bool dragging
|
||||
property Item draggerParent
|
||||
|
||||
signal dragStarted;
|
||||
signal dragStopped;
|
||||
|
||||
readonly property int dragHeight: 5
|
||||
|
||||
@@ -83,6 +88,32 @@ Item {
|
||||
Connections {
|
||||
target: qmlProfilerModelProxy
|
||||
onStateChanged: updateDescriptions()
|
||||
onModelsChanged: updateDescriptions()
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: dragArea
|
||||
anchors.fill: txt
|
||||
drag.target: dragger
|
||||
cursorShape: dragging ? Qt.DragMoveCursor : Qt.OpenHandCursor
|
||||
}
|
||||
|
||||
DropArea {
|
||||
id: dropArea
|
||||
|
||||
onPositionChanged: {
|
||||
if ((drag.source.modelIndex > labelContainer.modelIndex &&
|
||||
drag.source.y < labelContainer.y + drag.source.height) ||
|
||||
(drag.source.modelIndex < labelContainer.modelIndex &&
|
||||
drag.source.y > labelContainer.y + labelContainer.height -
|
||||
drag.source.height)) {
|
||||
qmlProfilerModelProxy.swapModels(drag.source.modelIndex,
|
||||
labelContainer.modelIndex);
|
||||
drag.source.modelIndex = labelContainer.modelIndex;
|
||||
}
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -178,4 +209,67 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: dragger
|
||||
property int modelIndex
|
||||
width: labelContainer.width
|
||||
height: 0
|
||||
color: "black"
|
||||
opacity: 0.5
|
||||
anchors.left: parent.left
|
||||
|
||||
// anchor to top so that it reliably snaps back after dragging
|
||||
anchors.top: parent.top
|
||||
|
||||
Drag.active: dragArea.drag.active
|
||||
Drag.onActiveChanged: {
|
||||
// We don't want height, text, or modelIndex to be changed when reordering occurs, so we
|
||||
// don't make them properties.
|
||||
draggerText.text = txt.text;
|
||||
modelIndex = labelContainer.modelIndex;
|
||||
if (Drag.active) {
|
||||
height = labelContainer.height;
|
||||
labelContainer.dragStarted();
|
||||
} else {
|
||||
height = 0;
|
||||
labelContainer.dragStopped();
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
when: dragger.Drag.active
|
||||
ParentChange {
|
||||
target: dragger
|
||||
parent: draggerParent
|
||||
}
|
||||
PropertyChanges {
|
||||
target: dragger
|
||||
anchors.top: undefined
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Text {
|
||||
id: draggerText
|
||||
visible: parent.Drag.active
|
||||
x: txt.x
|
||||
font.pixelSize: txt.font.pixelSize
|
||||
color: "white"
|
||||
width: txt.width
|
||||
height: txt.height
|
||||
verticalAlignment: txt.verticalAlignment
|
||||
renderType: txt.renderType
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.top: dragArea.bottom
|
||||
anchors.bottom: labelContainer.dragging ? labelContainer.bottom : dragArea.bottom
|
||||
anchors.left: labelContainer.left
|
||||
anchors.right: labelContainer.right
|
||||
cursorShape: dragArea.cursorShape
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ Rectangle {
|
||||
view.requestPaint();
|
||||
}
|
||||
onStateChanged: backgroundMarks.requestPaint()
|
||||
onModelsChanged: backgroundMarks.requestPaint()
|
||||
onExpandedChanged: backgroundMarks.requestPaint()
|
||||
onRowHeightChanged: backgroundMarks.requestPaint()
|
||||
}
|
||||
@@ -211,10 +212,20 @@ Rectangle {
|
||||
|
||||
Column {
|
||||
id: col
|
||||
|
||||
// Dispatch the cursor shape to all labels. When dragging the DropArea receiving
|
||||
// the drag events is not necessarily related to the MouseArea receiving the mouse
|
||||
// events, so we can't use the drag events to determine the cursor shape.
|
||||
property bool dragging: false
|
||||
|
||||
Repeater {
|
||||
model: labels.rowCount
|
||||
delegate: CategoryLabel {
|
||||
dragging: col.dragging
|
||||
reverseSelect: root.shiftPressed
|
||||
onDragStarted: col.dragging = true
|
||||
onDragStopped: col.dragging = false
|
||||
draggerParent: labels
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ void TimelineModelAggregator::addModel(AbstractTimelineModel *m)
|
||||
d->modelList << m;
|
||||
connect(m,SIGNAL(expandedChanged()),this,SIGNAL(expandedChanged()));
|
||||
connect(m,SIGNAL(rowHeightChanged()),this,SIGNAL(rowHeightChanged()));
|
||||
emit modelsChanged();
|
||||
emit modelsChanged(d->modelList.length(), d->modelList.length());
|
||||
}
|
||||
|
||||
QVariantList TimelineModelAggregator::models() const
|
||||
@@ -255,6 +255,12 @@ int TimelineModelAggregator::eventIdForLocation(int modelIndex, const QString &f
|
||||
return d->modelList[modelIndex]->eventIdForLocation(filename, line, column);
|
||||
}
|
||||
|
||||
void TimelineModelAggregator::swapModels(int modelIndex1, int modelIndex2)
|
||||
{
|
||||
qSwap(d->modelList[modelIndex1], d->modelList[modelIndex2]);
|
||||
emit modelsChanged(modelIndex1, modelIndex2);
|
||||
}
|
||||
|
||||
void TimelineModelAggregator::dataChanged()
|
||||
{
|
||||
// this is a slot connected for every modelproxy
|
||||
|
||||
@@ -62,6 +62,7 @@ public:
|
||||
Q_INVOKABLE int rowHeight(int modelIndex, int row) const;
|
||||
Q_INVOKABLE void setRowHeight(int modelIndex, int row, int height);
|
||||
Q_INVOKABLE int rowOffset(int modelIndex, int row) const;
|
||||
|
||||
Q_INVOKABLE bool expanded(int modelIndex) const;
|
||||
Q_INVOKABLE void setExpanded(int modelIndex, bool expanded);
|
||||
Q_INVOKABLE int rowCount(int modelIndex) const;
|
||||
@@ -91,12 +92,14 @@ public:
|
||||
Q_INVOKABLE int eventIdForLocation(int modelIndex, const QString &filename, int line,
|
||||
int column) const;
|
||||
|
||||
Q_INVOKABLE void swapModels(int modelIndex1, int modelIndex2);
|
||||
|
||||
signals:
|
||||
void dataAvailable();
|
||||
void stateChanged();
|
||||
void expandedChanged();
|
||||
void rowHeightChanged();
|
||||
void modelsChanged();
|
||||
void modelsChanged(int modelIndex1, int modelIndex2);
|
||||
|
||||
protected slots:
|
||||
void dataChanged();
|
||||
|
||||
@@ -56,12 +56,16 @@ void TimelineRenderer::setProfilerModelProxy(QObject *profilerModelProxy)
|
||||
if (m_profilerModelProxy) {
|
||||
disconnect(m_profilerModelProxy, SIGNAL(expandedChanged()), this, SLOT(requestPaint()));
|
||||
disconnect(m_profilerModelProxy, SIGNAL(rowHeightChanged()), this, SLOT(requestPaint()));
|
||||
disconnect(m_profilerModelProxy, SIGNAL(modelsChanged(int,int)),
|
||||
this, SLOT(swapSelections(int,int)));
|
||||
}
|
||||
m_profilerModelProxy = qobject_cast<TimelineModelAggregator *>(profilerModelProxy);
|
||||
|
||||
if (m_profilerModelProxy) {
|
||||
connect(m_profilerModelProxy, SIGNAL(expandedChanged()), this, SLOT(requestPaint()));
|
||||
connect(m_profilerModelProxy, SIGNAL(rowHeightChanged()), this, SLOT(requestPaint()));
|
||||
connect(m_profilerModelProxy, SIGNAL(modelsChanged(int,int)),
|
||||
this, SLOT(swapSelections(int,int)));
|
||||
}
|
||||
emit profilerModelProxyChanged(m_profilerModelProxy);
|
||||
}
|
||||
@@ -84,6 +88,20 @@ void TimelineRenderer::requestPaint()
|
||||
update();
|
||||
}
|
||||
|
||||
void TimelineRenderer::swapSelections(int modelIndex1, int modelIndex2)
|
||||
{
|
||||
// Any hovered event is most likely useless now. Reset it.
|
||||
resetCurrentSelection();
|
||||
|
||||
// Explicitly selected events can be tracked in a useful way.
|
||||
if (m_selectedModel == modelIndex1)
|
||||
setSelectedModel(modelIndex2);
|
||||
else if (m_selectedModel == modelIndex2)
|
||||
setSelectedModel(modelIndex1);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
inline void TimelineRenderer::getItemXExtent(int modelIndex, int i, int ¤tX, int &itemWidth)
|
||||
{
|
||||
qint64 start = m_profilerModelProxy->startTime(modelIndex, i) - m_startTime;
|
||||
|
||||
@@ -116,7 +116,7 @@ signals:
|
||||
public slots:
|
||||
void clearData();
|
||||
void requestPaint();
|
||||
|
||||
void swapSelections(int modelIndex1, int modelIndex2);
|
||||
|
||||
void setStartTime(qint64 arg)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user