QmlProfiler: Require only subset of renderer to execute render passes

Like that we can easily add different renderers to use the same render
passes, e.g. for the overview.

Change-Id: Ib7dcb77a45e74488971011310f53f7639286768d
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2014-12-09 14:18:05 +01:00
parent 2b143cf810
commit 9c53c1dbea
20 changed files with 505 additions and 326 deletions

View File

@@ -41,7 +41,8 @@ SOURCES += \
timelinenotesrenderpass.cpp \ timelinenotesrenderpass.cpp \
timelinerenderpass.cpp \ timelinerenderpass.cpp \
timelinerenderstate.cpp \ timelinerenderstate.cpp \
timelinenotesmodel.cpp timelinenotesmodel.cpp \
timelineabstractrenderer.cpp
HEADERS += \ HEADERS += \
abstractqmlprofilerrunner.h \ abstractqmlprofilerrunner.h \
@@ -88,7 +89,9 @@ HEADERS += \
timelinenotesmodel.h \ timelinenotesmodel.h \
timelinenotesmodel_p.h \ timelinenotesmodel_p.h \
timelinerenderer_p.h \ timelinerenderer_p.h \
timelinerenderstate_p.h timelinerenderstate_p.h \
timelineabstractrenderer.h \
timelineabstractrenderer_p.h
RESOURCES += \ RESOURCES += \
qml/qmlprofiler.qrc qml/qmlprofiler.qrc

View File

@@ -50,6 +50,8 @@ QtcPlugin {
"qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h", "qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h",
"qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h", "qv8profilerdatamodel.cpp", "qv8profilerdatamodel.h",
"qv8profilereventview.h", "qv8profilereventview.cpp", "qv8profilereventview.h", "qv8profilereventview.cpp",
"timelineabstractrenderer.cpp", "timelineabstractrenderer.h",
"timelineabstractrenderer_p.h",
"timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h", "timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h",
"timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h", "timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h",
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h", "timelinemodelaggregator.cpp", "timelinemodelaggregator.h",

View File

@@ -149,7 +149,7 @@ void updateNodes(const QmlProfilerRangeModel *model, int from, int to,
} }
Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update( Timeline::TimelineRenderPass::State *QmlProfilerBindingLoopsRenderPass::update(
const Timeline::TimelineRenderer *renderer, const Timeline::TimelineAbstractRenderer *renderer,
const Timeline::TimelineRenderState *parentState, State *oldState, const Timeline::TimelineRenderState *parentState, State *oldState,
int indexFrom, int indexTo, bool stateChanged, qreal spacing) const int indexFrom, int indexTo, bool stateChanged, qreal spacing) const
{ {

View File

@@ -31,7 +31,7 @@
#ifndef QMLPROFILERBINDINGLOOPSRENDERPASS_H #ifndef QMLPROFILERBINDINGLOOPSRENDERPASS_H
#define QMLPROFILERBINDINGLOOPSRENDERPASS_H #define QMLPROFILERBINDINGLOOPSRENDERPASS_H
#include "timelinerenderer.h" #include "timelineabstractrenderer.h"
#include "timelinerenderpass.h" #include "timelinerenderpass.h"
#include "timelinerenderstate.h" #include "timelinerenderstate.h"
#include "qmlprofilerrangemodel.h" #include "qmlprofilerrangemodel.h"
@@ -44,7 +44,7 @@ class QmlProfilerBindingLoopsRenderPass : public Timeline::TimelineRenderPass
{ {
public: public:
static const QmlProfilerBindingLoopsRenderPass *instance(); static const QmlProfilerBindingLoopsRenderPass *instance();
State *update(const Timeline::TimelineRenderer *renderer, State *update(const Timeline::TimelineAbstractRenderer *renderer,
const Timeline::TimelineRenderState *parentState, const Timeline::TimelineRenderState *parentState,
State *oldState, int indexFrom, int indexTo, bool stateChanged, State *oldState, int indexFrom, int indexTo, bool stateChanged,
qreal spacing) const; qreal spacing) const;

View File

@@ -0,0 +1,200 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "timelineabstractrenderer_p.h"
namespace Timeline {
TimelineAbstractRenderer::TimelineAbstractRendererPrivate::TimelineAbstractRendererPrivate() :
selectedItem(-1), selectionLocked(true), model(0), notes(0), zoomer(0), modelDirty(false),
rowHeightsDirty(false)
{
}
TimelineAbstractRenderer::TimelineAbstractRenderer(TimelineAbstractRendererPrivate &dd,
QQuickItem *parent) :
QQuickItem(parent), d_ptr(&dd)
{
}
int TimelineAbstractRenderer::selectedItem() const
{
Q_D(const TimelineAbstractRenderer);
return d->selectedItem;
}
void TimelineAbstractRenderer::setSelectedItem(int itemIndex)
{
Q_D(TimelineAbstractRenderer);
if (d->selectedItem != itemIndex) {
d->selectedItem = itemIndex;
update();
emit selectedItemChanged(itemIndex);
}
}
bool TimelineAbstractRenderer::selectionLocked() const
{
Q_D(const TimelineAbstractRenderer);
return d->selectionLocked;
}
void TimelineAbstractRenderer::setSelectionLocked(bool locked)
{
Q_D(TimelineAbstractRenderer);
if (d->selectionLocked != locked) {
d->selectionLocked = locked;
update();
emit selectionLockedChanged(locked);
}
}
TimelineModel *TimelineAbstractRenderer::model() const
{
Q_D(const TimelineAbstractRenderer);
return d->model;
}
void TimelineAbstractRenderer::setModel(TimelineModel *model)
{
Q_D(TimelineAbstractRenderer);
if (d->model == model)
return;
if (d->model) {
disconnect(d->model, &TimelineModel::expandedChanged, this, &QQuickItem::update);
disconnect(d->model, &TimelineModel::hiddenChanged, this, &QQuickItem::update);
disconnect(d->model, &TimelineModel::expandedRowHeightChanged,
this, &TimelineAbstractRenderer::setRowHeightsDirty);
disconnect(d->model, &TimelineModel::emptyChanged,
this, &TimelineAbstractRenderer::setModelDirty);
}
d->model = model;
if (d->model) {
connect(d->model, &TimelineModel::expandedChanged, this, &QQuickItem::update);
connect(d->model, &TimelineModel::hiddenChanged, this, &QQuickItem::update);
connect(d->model, &TimelineModel::expandedRowHeightChanged,
this, &TimelineAbstractRenderer::setRowHeightsDirty);
connect(d->model, &TimelineModel::emptyChanged,
this, &TimelineAbstractRenderer::setModelDirty);
d->renderPasses = d->model->supportedRenderPasses();
}
setModelDirty();
emit modelChanged(d->model);
}
TimelineNotesModel *TimelineAbstractRenderer::notes() const
{
Q_D(const TimelineAbstractRenderer);
return d->notes;
}
void TimelineAbstractRenderer::setNotes(TimelineNotesModel *notes)
{
Q_D(TimelineAbstractRenderer);
if (d->notes == notes)
return;
if (d->notes)
disconnect(d->notes, &TimelineNotesModel::changed,
this, &TimelineAbstractRenderer::setNotesDirty);
d->notes = notes;
if (d->notes)
connect(d->notes, &TimelineNotesModel::changed,
this, &TimelineAbstractRenderer::setNotesDirty);
emit notesChanged(d->notes);
update();
}
TimelineZoomControl *TimelineAbstractRenderer::zoomer() const
{
Q_D(const TimelineAbstractRenderer);
return d->zoomer;
}
void TimelineAbstractRenderer::setZoomer(TimelineZoomControl *zoomer)
{
Q_D(TimelineAbstractRenderer);
if (zoomer != d->zoomer) {
if (d->zoomer != 0)
disconnect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
d->zoomer = zoomer;
if (d->zoomer != 0)
connect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
emit zoomerChanged(zoomer);
update();
}
}
bool TimelineAbstractRenderer::modelDirty() const
{
Q_D(const TimelineAbstractRenderer);
return d->modelDirty;
}
bool TimelineAbstractRenderer::notesDirty() const
{
Q_D(const TimelineAbstractRenderer);
return d->notesDirty;
}
bool TimelineAbstractRenderer::rowHeightsDirty() const
{
Q_D(const TimelineAbstractRenderer);
return d->rowHeightsDirty;
}
void TimelineAbstractRenderer::setModelDirty()
{
Q_D(TimelineAbstractRenderer);
d->modelDirty = true;
update();
}
void TimelineAbstractRenderer::setRowHeightsDirty()
{
Q_D(TimelineAbstractRenderer);
d->rowHeightsDirty = true;
update();
}
void TimelineAbstractRenderer::setNotesDirty()
{
Q_D(TimelineAbstractRenderer);
d->notesDirty = true;
update();
}
} // namespace Timeline

View File

@@ -0,0 +1,99 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef TIMELINEABSTRACTRENDERER_H
#define TIMELINEABSTRACTRENDERER_H
#include <QQuickItem>
#include <QSGTransformNode>
#include <QQuickItem>
#include "timelinezoomcontrol.h"
#include "timelinemodel.h"
#include "timelinenotesmodel.h"
#include "timelinerenderpass.h"
namespace Timeline {
class TimelineRenderPass;
class TimelineRenderState;
class TimelineAbstractRenderer : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(Timeline::TimelineModel *model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(Timeline::TimelineNotesModel *notes READ notes WRITE setNotes NOTIFY notesChanged)
Q_PROPERTY(Timeline::TimelineZoomControl *zoomer READ zoomer WRITE setZoomer NOTIFY zoomerChanged)
Q_PROPERTY(bool selectionLocked READ selectionLocked WRITE setSelectionLocked NOTIFY selectionLockedChanged)
Q_PROPERTY(int selectedItem READ selectedItem WRITE setSelectedItem NOTIFY selectedItemChanged)
public:
bool selectionLocked() const;
int selectedItem() const;
TimelineModel *model() const;
void setModel(TimelineModel *model);
TimelineNotesModel *notes() const;
void setNotes(TimelineNotesModel *notes);
TimelineZoomControl *zoomer() const;
void setZoomer(TimelineZoomControl *zoomer);
bool modelDirty() const;
bool notesDirty() const;
bool rowHeightsDirty() const;
signals:
void modelChanged(const TimelineModel *model);
void notesChanged(TimelineNotesModel *notes);
void zoomerChanged(TimelineZoomControl *zoomer);
void selectionLockedChanged(bool locked);
void selectedItemChanged(int itemIndex);
public slots:
void setSelectedItem(int itemIndex);
void setSelectionLocked(bool locked);
void setModelDirty();
void setNotesDirty();
void setRowHeightsDirty();
protected:
class TimelineAbstractRendererPrivate;
TimelineAbstractRenderer(TimelineAbstractRendererPrivate &dd, QQuickItem *parent = 0);
TimelineAbstractRendererPrivate *d_ptr;
Q_DECLARE_PRIVATE(TimelineAbstractRenderer)
};
} // namespace Timeline
#endif // TIMELINEABSTRACTRENDERER_H

View File

@@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://www.qt.io/licensing. For further information
** use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef TIMELINEABSTRACTRENDERER_P_H
#define TIMELINEABSTRACTRENDERER_P_H
#include "timelineabstractrenderer.h"
namespace Timeline {
class TimelineAbstractRenderer::TimelineAbstractRendererPrivate {
public:
TimelineAbstractRendererPrivate();
int selectedItem;
bool selectionLocked;
TimelineModel *model;
TimelineNotesModel *notes;
TimelineZoomControl *zoomer;
bool modelDirty;
bool rowHeightsDirty;
bool notesDirty;
QList<const TimelineRenderPass *> renderPasses;
};
}
#endif // TIMELINEABSTRACTRENDERER_P_H

View File

@@ -190,10 +190,9 @@ public:
virtual ~TimelineExpandedRowNode() {} virtual ~TimelineExpandedRowNode() {}
}; };
static void updateNodes(int from, int to, const TimelineRenderer *renderer, static void updateNodes(int from, int to, const TimelineModel *model,
const TimelineRenderState *parentState, TimelineItemsRenderPassState *state) const TimelineRenderState *parentState, TimelineItemsRenderPassState *state)
{ {
const TimelineModel *model = renderer->model();
float defaultRowHeight = TimelineModel::defaultRowHeight(); float defaultRowHeight = TimelineModel::defaultRowHeight();
QVector<TimelineItemsGeometry> expandedPerRow(model->expandedRowCount()); QVector<TimelineItemsGeometry> expandedPerRow(model->expandedRowCount());
@@ -274,7 +273,7 @@ const TimelineItemsRenderPass *TimelineItemsRenderPass::instance()
return &pass; return &pass;
} }
TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineRenderer *renderer, TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineAbstractRenderer *renderer,
const TimelineRenderState *parentState, const TimelineRenderState *parentState,
State *oldState, int indexFrom, State *oldState, int indexFrom,
int indexTo, bool stateChanged, int indexTo, bool stateChanged,
@@ -315,16 +314,16 @@ TimelineRenderPass::State *TimelineItemsRenderPass::update(const TimelineRendere
for (int i = indexFrom; i < state->indexFrom; for (int i = indexFrom; i < state->indexFrom;
i+= TimelineItemsGeometry::maxEventsPerNode) i+= TimelineItemsGeometry::maxEventsPerNode)
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, state->indexFrom), updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, state->indexFrom),
renderer, parentState, state); model, parentState, state);
} }
if (indexTo > state->indexTo) { if (indexTo > state->indexTo) {
for (int i = state->indexTo; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode) for (int i = state->indexTo; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode)
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), renderer, updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model,
parentState, state); parentState, state);
} }
} else { } else {
for (int i = indexFrom; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode) for (int i = indexFrom; i < indexTo; i+= TimelineItemsGeometry::maxEventsPerNode)
updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), renderer, updateNodes(i, qMin(i + TimelineItemsGeometry::maxEventsPerNode, indexTo), model,
parentState, state); parentState, state);
} }

View File

@@ -31,7 +31,7 @@
#ifndef TIMELINEITEMSRENDERPASS_H #ifndef TIMELINEITEMSRENDERPASS_H
#define TIMELINEITEMSRENDERPASS_H #define TIMELINEITEMSRENDERPASS_H
#include "timelinerenderer.h" #include "timelineabstractrenderer.h"
#include "timelinerenderpass.h" #include "timelinerenderpass.h"
#include <QSGMaterial> #include <QSGMaterial>
@@ -41,7 +41,7 @@ class TimelineItemsRenderPass : public TimelineRenderPass
{ {
public: public:
static const TimelineItemsRenderPass *instance(); static const TimelineItemsRenderPass *instance();
State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
State *state, int firstIndex, int lastIndex, bool stateChanged, State *state, int firstIndex, int lastIndex, bool stateChanged,
qreal spacing) const; qreal spacing) const;
protected: protected:

View File

@@ -96,7 +96,7 @@ TimelineNotesRenderPass::TimelineNotesRenderPass()
{ {
} }
TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineRenderer *renderer, TimelineRenderPass::State *TimelineNotesRenderPass::update(const TimelineAbstractRenderer *renderer,
const TimelineRenderState *parentState, const TimelineRenderState *parentState,
State *oldState, int firstIndex, State *oldState, int firstIndex,
int lastIndex, bool stateChanged, int lastIndex, bool stateChanged,

View File

@@ -31,7 +31,7 @@
#ifndef TIMELINENOTESRENDERPASS_H #ifndef TIMELINENOTESRENDERPASS_H
#define TIMELINENOTESRENDERPASS_H #define TIMELINENOTESRENDERPASS_H
#include "timelinerenderer.h" #include "timelineabstractrenderer.h"
#include <QSGMaterial> #include <QSGMaterial>
namespace Timeline { namespace Timeline {
@@ -41,7 +41,7 @@ class TimelineNotesRenderPass : public TimelineRenderPass
public: public:
static const TimelineNotesRenderPass *instance(); static const TimelineNotesRenderPass *instance();
State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
State *oldState, int firstIndex, int lastIndex, bool stateChanged, State *oldState, int firstIndex, int lastIndex, bool stateChanged,
qreal spacing) const; qreal spacing) const;

View File

@@ -0,0 +1,5 @@
#ifndef TIMELINEOVERLAYRENDERER_P_H
#define TIMELINEOVERLAYRENDERER_P_H
#endif // TIMELINEOVERLAYRENDERER_P_H

View File

@@ -51,141 +51,19 @@
namespace Timeline { namespace Timeline {
TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate(TimelineRenderer *q) : TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate(TimelineRenderer *q) :
model(0), zoomer(0), notes(0), selectedItem(-1), selectionLocked(true), modelDirty(false), lastState(0), q_ptr(q)
rowHeightsDirty(false), rowCountsDirty(false), lastState(0), q_ptr(q)
{ {
resetCurrentSelection(); resetCurrentSelection();
} }
TimelineRenderer::TimelineRenderer(QQuickItem *parent) : TimelineRenderer::TimelineRenderer(QQuickItem *parent) :
QQuickItem(parent), d_ptr(new TimelineRendererPrivate(this)) TimelineAbstractRenderer(*(new TimelineRendererPrivate(this)), parent)
{ {
setFlag(QQuickItem::ItemHasContents); setFlag(QQuickItem::ItemHasContents);
setAcceptedMouseButtons(Qt::LeftButton); setAcceptedMouseButtons(Qt::LeftButton);
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
} }
bool TimelineRenderer::selectionLocked() const
{
Q_D(const TimelineRenderer);
return d->selectionLocked;
}
int TimelineRenderer::selectedItem() const
{
Q_D(const TimelineRenderer);
return d->selectedItem;
}
TimelineModel *TimelineRenderer::model() const
{
Q_D(const TimelineRenderer);
return d->model;
}
void TimelineRenderer::setModel(TimelineModel *model)
{
Q_D(TimelineRenderer);
if (d->model == model)
return;
if (d->model) {
disconnect(d->model, SIGNAL(expandedChanged()), this, SLOT(update()));
disconnect(d->model, SIGNAL(hiddenChanged()), this, SLOT(update()));
disconnect(d->model, SIGNAL(expandedRowHeightChanged(int,int)),
this, SLOT(setRowHeightsDirty()));
disconnect(d->model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty()));
disconnect(d->model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty()));
disconnect(d->model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty()));
}
d->model = model;
if (d->model) {
connect(d->model, SIGNAL(expandedChanged()), this, SLOT(update()));
connect(d->model, SIGNAL(hiddenChanged()), this, SLOT(update()));
connect(d->model, SIGNAL(expandedRowHeightChanged(int,int)),
this, SLOT(setRowHeightsDirty()));
connect(d->model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty()));
connect(d->model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty()));
connect(d->model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty()));
d->renderPasses = d->model->supportedRenderPasses();
}
setModelDirty();
setRowHeightsDirty();
setRowCountsDirty();
emit modelChanged(d->model);
}
TimelineZoomControl *TimelineRenderer::zoomer() const
{
Q_D(const TimelineRenderer);
return d->zoomer;
}
void TimelineRenderer::setZoomer(TimelineZoomControl *zoomer)
{
Q_D(TimelineRenderer);
if (zoomer != d->zoomer) {
if (d->zoomer != 0)
disconnect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
d->zoomer = zoomer;
if (d->zoomer != 0)
connect(d->zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
emit zoomerChanged(zoomer);
update();
}
}
TimelineNotesModel *TimelineRenderer::notes() const
{
Q_D(const TimelineRenderer);
return d->notes;
}
void TimelineRenderer::setNotes(TimelineNotesModel *notes)
{
Q_D(TimelineRenderer);
if (d->notes == notes)
return;
if (d->notes)
disconnect(d->notes, &TimelineNotesModel::changed,
this, &TimelineRenderer::setNotesDirty);
d->notes = notes;
if (d->notes)
connect(d->notes, &TimelineNotesModel::changed,
this, &TimelineRenderer::setNotesDirty);
emit notesChanged(d->notes);
update();
}
bool TimelineRenderer::modelDirty() const
{
Q_D(const TimelineRenderer);
return d->modelDirty;
}
bool TimelineRenderer::notesDirty() const
{
Q_D(const TimelineRenderer);
return d->notesDirty;
}
bool TimelineRenderer::rowHeightsDirty() const
{
Q_D(const TimelineRenderer);
return d->rowHeightsDirty;
}
bool TimelineRenderer::rowCountsDirty() const
{
Q_D(const TimelineRenderer);
return d->rowCountsDirty;
}
void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection() void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection()
{ {
currentSelection.startTime = -1; currentSelection.startTime = -1;
@@ -241,14 +119,13 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u
d->zoomer->windowDuration() <= 0) { d->zoomer->windowDuration() <= 0) {
delete node; delete node;
return 0; return 0;
} else if (node == 0) {
node = new QSGTransformNode;
} }
qreal spacing = width() / d->zoomer->windowDuration(); qreal spacing = width() / d->zoomer->windowDuration();
if (d->modelDirty || d->rowCountsDirty) { if (d->modelDirty) {
node->removeAllChildNodes(); if (node)
node->removeAllChildNodes();
foreach (QVector<TimelineRenderState *> stateVector, d->renderStates) foreach (QVector<TimelineRenderState *> stateVector, d->renderStates)
qDeleteAll(stateVector); qDeleteAll(stateVector);
d->renderStates.clear(); d->renderStates.clear();
@@ -266,91 +143,23 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *u
state != d->lastState, spacing)); state != d->lastState, spacing));
if (state->isEmpty()) { // new state if (state->isEmpty()) { // new state
for (int pass = 0; pass < d->renderPasses.length(); ++pass) { state->assembleNodeTree(d->model, TimelineModel::defaultRowHeight(),
const TimelineRenderPass::State *passState = state->passState(pass); TimelineModel::defaultRowHeight());
if (!passState) } else if (d->rowHeightsDirty || state != d->lastState) {
continue; state->updateExpandedRowHeights(d->model, TimelineModel::defaultRowHeight(),
if (passState->expandedOverlay()) TimelineModel::defaultRowHeight());
state->expandedOverlayRoot()->appendChildNode(passState->expandedOverlay());
if (passState->collapsedOverlay())
state->collapsedOverlayRoot()->appendChildNode(passState->collapsedOverlay());
}
int row = 0;
for (int i = 0; i < d->model->expandedRowCount(); ++i) {
QSGTransformNode *rowNode = new QSGTransformNode;
for (int pass = 0; pass < d->renderPasses.length(); ++pass) {
const TimelineRenderPass::State *passState = state->passState(pass);
if (!passState)
continue;
const QVector<QSGNode *> &rows = passState->expandedRows();
if (rows.length() > row) {
QSGNode *rowChildNode = rows[row];
if (rowChildNode)
rowNode->appendChildNode(rowChildNode);
}
}
state->expandedRowRoot()->appendChildNode(rowNode);
++row;
}
for (int row = 0; row < d->model->collapsedRowCount(); ++row) {
QSGTransformNode *rowNode = new QSGTransformNode;
QMatrix4x4 matrix;
matrix.translate(0, row * TimelineModel::defaultRowHeight(), 0);
rowNode->setMatrix(matrix);
for (int pass = 0; pass < d->renderPasses.length(); ++pass) {
const TimelineRenderPass::State *passState = state->passState(pass);
if (!passState)
continue;
const QVector<QSGNode *> &rows = passState->collapsedRows();
if (rows.length() > row) {
QSGNode *rowChildNode = rows[row];
if (rowChildNode)
rowNode->appendChildNode(rowChildNode);
}
}
state->collapsedRowRoot()->appendChildNode(rowNode);
}
}
if (d->rowHeightsDirty || state != d->lastState) {
int row = 0;
qreal offset = 0;
for (QSGNode *rowNode = state->expandedRowRoot()->firstChild(); rowNode != 0;
rowNode = rowNode->nextSibling()) {
qreal rowHeight = d->model->expandedRowHeight(row++);
QMatrix4x4 matrix;
matrix.translate(0, offset, 0);
matrix.scale(1, rowHeight / TimelineModel::defaultRowHeight(), 1);
offset += rowHeight;
static_cast<QSGTransformNode *>(rowNode)->setMatrix(matrix);
}
} }
d->modelDirty = false; d->modelDirty = false;
d->notesDirty = false; d->notesDirty = false;
d->rowCountsDirty = false;
d->rowHeightsDirty = false; d->rowHeightsDirty = false;
d->lastState = state; d->lastState = state;
QSGNode *rowNode = d->model->expanded() ? state->expandedRowRoot() : state->collapsedRowRoot();
QSGNode *overlayNode = d->model->expanded() ? state->expandedOverlayRoot() :
state->collapsedOverlayRoot();
QMatrix4x4 matrix; QMatrix4x4 matrix;
matrix.translate((state->start() - d->zoomer->windowStart()) * spacing, 0, 0); matrix.translate((state->start() - d->zoomer->windowStart()) * spacing, 0, 0);
matrix.scale(spacing / state->scale(), 1, 1); matrix.scale(spacing / state->scale(), 1, 1);
QSGTransformNode *transform = static_cast<QSGTransformNode *>(node); return state->finalize(node, d->model->expanded(), matrix);
transform->setMatrix(matrix);
if (node->firstChild() != rowNode || node->lastChild() != overlayNode) {
node->removeAllChildNodes();
node->appendChildNode(rowNode);
node->appendChildNode(overlayNode);
}
return node;
} }
void TimelineRenderer::mousePressEvent(QMouseEvent *event) void TimelineRenderer::mousePressEvent(QMouseEvent *event)
@@ -481,26 +290,6 @@ void TimelineRenderer::clearData()
setSelectionLocked(true); setSelectionLocked(true);
} }
void TimelineRenderer::setSelectedItem(int itemIndex)
{
Q_D(TimelineRenderer);
if (d->selectedItem != itemIndex) {
d->selectedItem = itemIndex;
update();
emit selectedItemChanged(itemIndex);
}
}
void TimelineRenderer::setSelectionLocked(bool locked)
{
Q_D(TimelineRenderer);
if (d->selectionLocked != locked) {
d->selectionLocked = locked;
update();
emit selectionLockedChanged(locked);
}
}
void TimelineRenderer::selectNextFromSelectionId(int selectionId) void TimelineRenderer::selectNextFromSelectionId(int selectionId)
{ {
Q_D(TimelineRenderer); Q_D(TimelineRenderer);
@@ -515,32 +304,4 @@ void TimelineRenderer::selectPrevFromSelectionId(int selectionId)
d->selectedItem)); d->selectedItem));
} }
void TimelineRenderer::setModelDirty()
{
Q_D(TimelineRenderer);
d->modelDirty = true;
update();
}
void TimelineRenderer::setRowHeightsDirty()
{
Q_D(TimelineRenderer);
d->rowHeightsDirty = true;
update();
}
void TimelineRenderer::setNotesDirty()
{
Q_D(TimelineRenderer);
d->notesDirty = true;
update();
}
void TimelineRenderer::setRowCountsDirty()
{
Q_D(TimelineRenderer);
d->rowCountsDirty = true;
update();
}
} // namespace Timeline } // namespace Timeline

View File

@@ -36,43 +36,20 @@
#include "timelinezoomcontrol.h" #include "timelinezoomcontrol.h"
#include "timelinemodel.h" #include "timelinemodel.h"
#include "timelinenotesmodel.h" #include "timelinenotesmodel.h"
#include "timelinerenderpass.h" #include "timelineabstractrenderer.h"
namespace Timeline { namespace Timeline {
class TimelineRenderPass; class TimelineRenderPass;
class TimelineRenderState; class TimelineRenderState;
class TimelineRenderer : public QQuickItem class TimelineRenderer : public TimelineAbstractRenderer
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(Timeline::TimelineModel *model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(Timeline::TimelineZoomControl *zoomer READ zoomer WRITE setZoomer NOTIFY zoomerChanged)
Q_PROPERTY(Timeline::TimelineNotesModel *notes READ notes WRITE setNotes NOTIFY notesChanged)
Q_PROPERTY(bool selectionLocked READ selectionLocked WRITE setSelectionLocked NOTIFY selectionLockedChanged)
Q_PROPERTY(int selectedItem READ selectedItem WRITE setSelectedItem NOTIFY selectedItemChanged)
public: public:
explicit TimelineRenderer(QQuickItem *parent = 0); explicit TimelineRenderer(QQuickItem *parent = 0);
bool selectionLocked() const;
int selectedItem() const;
TimelineModel *model() const;
void setModel(TimelineModel *model);
TimelineZoomControl *zoomer() const;
void setZoomer(TimelineZoomControl *zoomer);
TimelineNotesModel *notes() const;
void setNotes(TimelineNotesModel *notes);
bool modelDirty() const;
bool notesDirty() const;
bool rowHeightsDirty() const;
bool rowCountsDirty() const;
Q_INVOKABLE void selectNextFromSelectionId(int selectionId); Q_INVOKABLE void selectNextFromSelectionId(int selectionId);
Q_INVOKABLE void selectPrevFromSelectionId(int selectionId); Q_INVOKABLE void selectPrevFromSelectionId(int selectionId);
@@ -80,25 +57,11 @@ public:
// need arises. // need arises.
signals: signals:
void modelChanged(const TimelineModel *model);
void zoomerChanged(TimelineZoomControl *zoomer);
void notesChanged(TimelineNotesModel *notes);
void selectionLockedChanged(bool locked);
void selectedItemChanged(int itemIndex);
void itemPressed(int pressedItem); void itemPressed(int pressedItem);
public slots: public slots:
void clearData(); void clearData();
void setSelectedItem(int itemIndex);
void setSelectionLocked(bool locked);
void setModelDirty();
void setRowHeightsDirty();
void setNotesDirty();
void setRowCountsDirty();
protected: protected:
virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData); virtual QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
virtual void mousePressEvent(QMouseEvent *event); virtual void mousePressEvent(QMouseEvent *event);
@@ -108,7 +71,6 @@ protected:
private: private:
class TimelineRendererPrivate; class TimelineRendererPrivate;
TimelineRendererPrivate *d_ptr;
Q_DECLARE_PRIVATE(TimelineRenderer) Q_DECLARE_PRIVATE(TimelineRenderer)
}; };

View File

@@ -32,10 +32,12 @@
#define TIMELINERENDERER_P_H #define TIMELINERENDERER_P_H
#include "timelinerenderer.h" #include "timelinerenderer.h"
#include "timelineabstractrenderer_p.h"
namespace Timeline { namespace Timeline {
class TimelineRenderer::TimelineRendererPrivate { class TimelineRenderer::TimelineRendererPrivate :
TimelineAbstractRenderer::TimelineAbstractRendererPrivate {
public: public:
TimelineRendererPrivate(TimelineRenderer *q); TimelineRendererPrivate(TimelineRenderer *q);
@@ -50,10 +52,6 @@ public:
TimelineRenderState *findRenderState(); TimelineRenderState *findRenderState();
TimelineModel *model;
TimelineZoomControl *zoomer;
TimelineNotesModel *notes;
struct { struct {
qint64 startTime; qint64 startTime;
qint64 endTime; qint64 endTime;
@@ -61,14 +59,6 @@ public:
int eventIndex; int eventIndex;
} currentSelection; } currentSelection;
int selectedItem;
bool selectionLocked;
bool modelDirty;
bool rowHeightsDirty;
bool notesDirty;
bool rowCountsDirty;
QList<const TimelineRenderPass *> renderPasses;
QVector<QVector<TimelineRenderState *> > renderStates; QVector<QVector<TimelineRenderState *> > renderStates;
TimelineRenderState *lastState; TimelineRenderState *lastState;

View File

@@ -36,7 +36,7 @@
QT_FORWARD_DECLARE_CLASS(QSGNode) QT_FORWARD_DECLARE_CLASS(QSGNode)
namespace Timeline { namespace Timeline {
class TimelineRenderer; class TimelineAbstractRenderer;
class TimelineRenderState; class TimelineRenderState;
class TimelineRenderPass { class TimelineRenderPass {
@@ -50,7 +50,8 @@ public:
}; };
virtual ~TimelineRenderPass(); virtual ~TimelineRenderPass();
virtual State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, virtual State *update(const TimelineAbstractRenderer *renderer,
const TimelineRenderState *parentState,
State *state, int indexFrom, int indexTo, bool stateChanged, State *state, int indexFrom, int indexTo, bool stateChanged,
qreal spacing) const = 0; qreal spacing) const = 0;
}; };

View File

@@ -134,6 +134,98 @@ bool TimelineRenderState::isEmpty() const
d->collapsedOverlayRoot->childCount() == 0 && d->expandedOverlayRoot->childCount() == 0; d->collapsedOverlayRoot->childCount() == 0 && d->expandedOverlayRoot->childCount() == 0;
} }
void TimelineRenderState::assembleNodeTree(const TimelineModel *model, int defaultRowHeight,
int defaultRowOffset)
{
Q_D(TimelineRenderState);
for (int pass = 0; pass < d->passes.length(); ++pass) {
const TimelineRenderPass::State *passState = d->passes[pass];
if (!passState)
continue;
if (passState->expandedOverlay())
d->expandedOverlayRoot->appendChildNode(passState->expandedOverlay());
if (passState->collapsedOverlay())
d->collapsedOverlayRoot->appendChildNode(passState->collapsedOverlay());
}
int row = 0;
for (int i = 0; i < model->expandedRowCount(); ++i) {
QSGTransformNode *rowNode = new QSGTransformNode;
for (int pass = 0; pass < d->passes.length(); ++pass) {
const TimelineRenderPass::State *passState = d->passes[pass];
if (!passState)
continue;
const QVector<QSGNode *> &rows = passState->expandedRows();
if (rows.length() > row) {
QSGNode *rowChildNode = rows[row];
if (rowChildNode)
rowNode->appendChildNode(rowChildNode);
}
}
d->expandedRowRoot->appendChildNode(rowNode);
++row;
}
for (int row = 0; row < model->collapsedRowCount(); ++row) {
QSGTransformNode *rowNode = new QSGTransformNode;
QMatrix4x4 matrix;
matrix.translate(0, row * defaultRowOffset, 0);
matrix.scale(1.0, static_cast<float>(defaultRowHeight) /
static_cast<float>(TimelineModel::defaultRowHeight()), 1.0);
rowNode->setMatrix(matrix);
for (int pass = 0; pass < d->passes.length(); ++pass) {
const TimelineRenderPass::State *passState = d->passes[pass];
if (!passState)
continue;
const QVector<QSGNode *> &rows = passState->collapsedRows();
if (rows.length() > row) {
QSGNode *rowChildNode = rows[row];
if (rowChildNode)
rowNode->appendChildNode(rowChildNode);
}
}
d->collapsedRowRoot->appendChildNode(rowNode);
}
updateExpandedRowHeights(model, defaultRowHeight, defaultRowOffset);
}
void TimelineRenderState::updateExpandedRowHeights(const TimelineModel *model, int defaultRowHeight,
int defaultRowOffset)
{
Q_D(TimelineRenderState);
int row = 0;
qreal offset = 0;
for (QSGNode *rowNode = d->expandedRowRoot->firstChild(); rowNode != 0;
rowNode = rowNode->nextSibling()) {
qreal rowHeight = model->expandedRowHeight(row++);
QMatrix4x4 matrix;
matrix.translate(0, offset, 0);
matrix.scale(1, rowHeight / defaultRowHeight, 1);
offset += defaultRowOffset * rowHeight / defaultRowHeight;
static_cast<QSGTransformNode *>(rowNode)->setMatrix(matrix);
}
}
QSGTransformNode *TimelineRenderState::finalize(QSGNode *oldNode, bool expanded,
const QMatrix4x4 &transform)
{
Q_D(TimelineRenderState);
QSGNode *rowNode = expanded ? d->expandedRowRoot : d->collapsedRowRoot;
QSGNode *overlayNode = expanded ?d->expandedOverlayRoot : d->collapsedOverlayRoot;
QSGTransformNode *node = oldNode ? static_cast<QSGTransformNode *>(oldNode) :
new QSGTransformNode;
node->setMatrix(transform);
if (node->firstChild() != rowNode || node->lastChild() != overlayNode) {
node->removeAllChildNodes();
node->appendChildNode(rowNode);
node->appendChildNode(overlayNode);
}
return node;
}
TimelineRenderPass::State *TimelineRenderState::passState(int i) TimelineRenderPass::State *TimelineRenderState::passState(int i)
{ {
Q_D(TimelineRenderState); Q_D(TimelineRenderState);

View File

@@ -33,6 +33,7 @@
#include <QSGNode> #include <QSGNode>
#include "timelinerenderpass.h" #include "timelinerenderpass.h"
#include "timelinemodel.h"
namespace Timeline { namespace Timeline {
@@ -60,6 +61,10 @@ public:
QSGNode *collapsedOverlayRoot(); QSGNode *collapsedOverlayRoot();
bool isEmpty() const; bool isEmpty() const;
void assembleNodeTree(const TimelineModel *model, int defaultRowHeight, int defaultRowOffset);
void updateExpandedRowHeights(const TimelineModel *model, int defaultRowHeight,
int defaultRowOffset);
QSGTransformNode *finalize(QSGNode *oldNode, bool expanded, const QMatrix4x4 &transform);
private: private:
class TimelineRenderStatePrivate; class TimelineRenderStatePrivate;

View File

@@ -55,9 +55,9 @@ struct TimelineSelectionRenderPassState : public TimelineRenderPass::State {
QSGNode *collapsedOverlay() const { return m_collapsedOverlay; } QSGNode *collapsedOverlay() const { return m_collapsedOverlay; }
}; };
TimelineRenderPass::State *TimelineSelectionRenderPass::update(const TimelineRenderer *renderer, TimelineRenderPass::State *TimelineSelectionRenderPass::update(
const TimelineRenderState *parentState, State *oldState, int firstIndex, int lastIndex, const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
bool stateChanged, qreal spacing) const State *oldState, int firstIndex, int lastIndex, bool stateChanged, qreal spacing) const
{ {
Q_UNUSED(stateChanged); Q_UNUSED(stateChanged);

View File

@@ -31,7 +31,7 @@
#ifndef TIMELINESELECTIONRENDERPASS_H #ifndef TIMELINESELECTIONRENDERPASS_H
#define TIMELINESELECTIONRENDERPASS_H #define TIMELINESELECTIONRENDERPASS_H
#include "timelinerenderer.h" #include "timelineabstractrenderer.h"
#include "timelinerenderpass.h" #include "timelinerenderpass.h"
#include "timelinerenderstate.h" #include "timelinerenderstate.h"
@@ -42,7 +42,7 @@ class TimelineSelectionRenderPass : public TimelineRenderPass
public: public:
static const TimelineSelectionRenderPass *instance(); static const TimelineSelectionRenderPass *instance();
State *update(const TimelineRenderer *renderer, const TimelineRenderState *parentState, State *update(const TimelineAbstractRenderer *renderer, const TimelineRenderState *parentState,
State *state, int firstIndex, int lastIndex, bool stateChanged, State *state, int firstIndex, int lastIndex, bool stateChanged,
qreal spacing) const; qreal spacing) const;