QmlProfiler: Apply d-pointer pattern to TimelineRenderer

TimelineRenderer will be a public class in the timeline library. We
don't want to expose its private members.

Change-Id: Ib82ab8b30f702293d1d8b5d101b7dd0e3380194c
Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2014-12-09 11:55:08 +01:00
parent 516c0d6020
commit f87622c363
5 changed files with 314 additions and 203 deletions

View File

@@ -86,7 +86,8 @@ HEADERS += \
timelinerenderpass.h \
timelinerenderstate.h \
timelinenotesmodel.h \
timelinenotesmodel_p.h
timelinenotesmodel_p.h \
timelinerenderer_p.h
RESOURCES += \
qml/qmlprofiler.qrc

View File

@@ -55,7 +55,7 @@ QtcPlugin {
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
"timelinenotesmodel.cpp", "timelinenotesmodel.h", "timelinenotesmodel_p.h",
"timelinenotesrenderpass.cpp", "timelinenotesrenderpass.h",
"timelinerenderer.cpp", "timelinerenderer.h",
"timelinerenderer.cpp", "timelinerenderer.h", "timelinerenderer_p.h",
"timelinerenderpass.cpp", "timelinerenderpass.h",
"timelinerenderstate.cpp", "timelinerenderstate.h",
"timelineselectionrenderpass.cpp", "timelineselectionrenderpass.h",

View File

@@ -28,7 +28,7 @@
**
****************************************************************************/
#include "timelinerenderer.h"
#include "timelinerenderer_p.h"
#include "timelinerenderpass.h"
#include "qmlprofilernotesmodel.h"
#include "timelineitemsrenderpass.h"
@@ -50,113 +50,159 @@
namespace Timeline {
TimelineRenderer::TimelineRendererPrivate::TimelineRendererPrivate(TimelineRenderer *q) :
model(0), zoomer(0), notes(0), selectedItem(-1), selectionLocked(true), modelDirty(false),
rowHeightsDirty(false), rowCountsDirty(false), lastState(0), q_ptr(q)
{
resetCurrentSelection();
}
TimelineRenderer::TimelineRenderer(QQuickItem *parent) :
QQuickItem(parent), m_model(0), m_zoomer(0), m_notes(0),
m_selectedItem(-1), m_selectionLocked(true), m_modelDirty(false),
m_rowHeightsDirty(false), m_rowCountsDirty(false), m_lastState(0)
QQuickItem(parent), d_ptr(new TimelineRendererPrivate(this))
{
setFlag(QQuickItem::ItemHasContents);
resetCurrentSelection();
setAcceptedMouseButtons(Qt::LeftButton);
setAcceptHoverEvents(true);
}
void TimelineRenderer::setModel(TimelineModel *model)
bool TimelineRenderer::selectionLocked() const
{
if (m_model == model)
return;
if (m_model) {
disconnect(m_model, SIGNAL(expandedChanged()), this, SLOT(update()));
disconnect(m_model, SIGNAL(hiddenChanged()), this, SLOT(update()));
disconnect(m_model, SIGNAL(expandedRowHeightChanged(int,int)),
this, SLOT(setRowHeightsDirty()));
disconnect(m_model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty()));
disconnect(m_model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty()));
disconnect(m_model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty()));
Q_D(const TimelineRenderer);
return d->selectionLocked;
}
m_model = model;
if (m_model) {
connect(m_model, SIGNAL(expandedChanged()), this, SLOT(update()));
connect(m_model, SIGNAL(hiddenChanged()), this, SLOT(update()));
connect(m_model, SIGNAL(expandedRowHeightChanged(int,int)),
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()));
connect(m_model, SIGNAL(emptyChanged()), this, SLOT(setModelDirty()));
connect(m_model, SIGNAL(expandedRowCountChanged()), this, SLOT(setRowCountsDirty()));
connect(m_model, SIGNAL(collapsedRowCountChanged()), this, SLOT(setRowCountsDirty()));
m_renderPasses = model->supportedRenderPasses();
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(m_model);
emit modelChanged(d->model);
}
TimelineZoomControl *TimelineRenderer::zoomer() const
{
Q_D(const TimelineRenderer);
return d->zoomer;
}
void TimelineRenderer::setZoomer(TimelineZoomControl *zoomer)
{
if (zoomer != m_zoomer) {
if (m_zoomer != 0)
disconnect(m_zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
m_zoomer = zoomer;
if (m_zoomer != 0)
connect(m_zoomer, SIGNAL(windowChanged(qint64,qint64)), this, SLOT(update()));
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)
{
if (m_notes == notes)
Q_D(TimelineRenderer);
if (d->notes == notes)
return;
if (m_notes)
disconnect(m_notes, &TimelineNotesModel::changed,
if (d->notes)
disconnect(d->notes, &TimelineNotesModel::changed,
this, &TimelineRenderer::setNotesDirty);
m_notes = notes;
if (m_notes)
connect(m_notes, &TimelineNotesModel::changed,
d->notes = notes;
if (d->notes)
connect(d->notes, &TimelineNotesModel::changed,
this, &TimelineRenderer::setNotesDirty);
emit notesChanged(m_notes);
emit notesChanged(d->notes);
update();
}
bool TimelineRenderer::modelDirty() const
{
return m_modelDirty;
Q_D(const TimelineRenderer);
return d->modelDirty;
}
bool TimelineRenderer::notesDirty() const
{
return m_notesDirty;
Q_D(const TimelineRenderer);
return d->notesDirty;
}
bool TimelineRenderer::rowHeightsDirty() const
{
return m_rowHeightsDirty;
Q_D(const TimelineRenderer);
return d->rowHeightsDirty;
}
void TimelineRenderer::resetCurrentSelection()
bool TimelineRenderer::rowCountsDirty() const
{
m_currentSelection.startTime = -1;
m_currentSelection.endTime = -1;
m_currentSelection.row = -1;
m_currentSelection.eventIndex = -1;
Q_D(const TimelineRenderer);
return d->rowCountsDirty;
}
TimelineRenderState *TimelineRenderer::findRenderState()
void TimelineRenderer::TimelineRendererPrivate::resetCurrentSelection()
{
currentSelection.startTime = -1;
currentSelection.endTime = -1;
currentSelection.row = -1;
currentSelection.eventIndex = -1;
}
TimelineRenderState *TimelineRenderer::TimelineRendererPrivate::findRenderState()
{
int newLevel = 0;
int newOffset = 0;
int level;
int offset;
qint64 newStart = m_zoomer->traceStart();
qint64 newEnd = m_zoomer->traceEnd();
qint64 newStart = zoomer->traceStart();
qint64 newEnd = zoomer->traceEnd();
qint64 start;
qint64 end;
do {
@@ -166,60 +212,61 @@ TimelineRenderState *TimelineRenderer::findRenderState()
end = newEnd;
newLevel = level + 1;
qint64 range = m_zoomer->traceDuration() >> newLevel;
newOffset = (m_zoomer->windowStart() - m_zoomer->traceStart() + range / 2) / range;
newStart = m_zoomer->traceStart() + newOffset * range - range / 2;
qint64 range = zoomer->traceDuration() >> newLevel;
newOffset = (zoomer->windowStart() - zoomer->traceStart() + range / 2) / range;
newStart = zoomer->traceStart() + newOffset * range - range / 2;
newEnd = newStart + range;
} while (newStart < m_zoomer->windowStart() && newEnd > m_zoomer->windowEnd());
} while (newStart < zoomer->windowStart() && newEnd > zoomer->windowEnd());
if (m_renderStates.length() <= level)
m_renderStates.resize(level + 1);
if (m_renderStates[level].length() <= offset)
m_renderStates[level].resize(offset + 1);
TimelineRenderState *state = m_renderStates[level][offset];
if (renderStates.length() <= level)
renderStates.resize(level + 1);
if (renderStates[level].length() <= offset)
renderStates[level].resize(offset + 1);
TimelineRenderState *state = renderStates[level][offset];
if (state == 0) {
state = new TimelineRenderState(start, end, 1.0 / static_cast<qreal>(SafeFloatMax),
m_renderPasses.size());
m_renderStates[level][offset] = state;
renderPasses.size());
renderStates[level][offset] = state;
}
return state;
}
QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node,
UpdatePaintNodeData *updatePaintNodeData)
QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node, UpdatePaintNodeData *updatePaintNodeData)
{
Q_D(TimelineRenderer);
Q_UNUSED(updatePaintNodeData)
if (!m_model || m_model->hidden() || m_model->isEmpty() || m_zoomer->windowDuration() <= 0) {
if (!d->model || d->model->hidden() || d->model->isEmpty() ||
d->zoomer->windowDuration() <= 0) {
delete node;
return 0;
} else if (node == 0) {
node = new QSGTransformNode;
}
qreal spacing = width() / m_zoomer->windowDuration();
qreal spacing = width() / d->zoomer->windowDuration();
if (m_modelDirty || m_rowCountsDirty) {
if (d->modelDirty || d->rowCountsDirty) {
node->removeAllChildNodes();
foreach (QVector<TimelineRenderState *> stateVector, m_renderStates)
foreach (QVector<TimelineRenderState *> stateVector, d->renderStates)
qDeleteAll(stateVector);
m_renderStates.clear();
m_lastState = 0;
d->renderStates.clear();
d->lastState = 0;
}
TimelineRenderState *state = findRenderState();
TimelineRenderState *state = d->findRenderState();
int lastIndex = m_model->lastIndex(m_zoomer->windowEnd());
int firstIndex = m_model->firstIndex(m_zoomer->windowStart());
int lastIndex = d->model->lastIndex(d->zoomer->windowEnd());
int firstIndex = d->model->firstIndex(d->zoomer->windowStart());
for (int i = 0; i < m_renderPasses.length(); ++i)
state->setPassState(i, m_renderPasses[i]->update(this, state, state->passState(i),
for (int i = 0; i < d->renderPasses.length(); ++i)
state->setPassState(i, d->renderPasses[i]->update(this, state, state->passState(i),
firstIndex, lastIndex + 1,
state != m_lastState, spacing));
state != d->lastState, spacing));
if (state->isEmpty()) { // new state
for (int pass = 0; pass < m_renderPasses.length(); ++pass) {
for (int pass = 0; pass < d->renderPasses.length(); ++pass) {
const TimelineRenderPass::State *passState = state->passState(pass);
if (!passState)
continue;
@@ -230,9 +277,9 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node,
}
int row = 0;
for (int i = 0; i < m_model->expandedRowCount(); ++i) {
for (int i = 0; i < d->model->expandedRowCount(); ++i) {
QSGTransformNode *rowNode = new QSGTransformNode;
for (int pass = 0; pass < m_renderPasses.length(); ++pass) {
for (int pass = 0; pass < d->renderPasses.length(); ++pass) {
const TimelineRenderPass::State *passState = state->passState(pass);
if (passState && passState->expandedRows.length() > row) {
QSGNode *rowChildNode = passState->expandedRows[row];
@@ -244,12 +291,12 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node,
++row;
}
for (int row = 0; row < m_model->collapsedRowCount(); ++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 < m_renderPasses.length(); ++pass) {
for (int pass = 0; pass < d->renderPasses.length(); ++pass) {
const TimelineRenderPass::State *passState = state->passState(pass);
if (passState && passState->collapsedRows.length() > row) {
QSGNode *rowChildNode = passState->collapsedRows[row];
@@ -261,12 +308,12 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node,
}
}
if (m_rowHeightsDirty || state != m_lastState) {
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 = m_model->expandedRowHeight(row++);
qreal rowHeight = d->model->expandedRowHeight(row++);
QMatrix4x4 matrix;
matrix.translate(0, offset, 0);
matrix.scale(1, rowHeight / TimelineModel::defaultRowHeight(), 1);
@@ -275,18 +322,18 @@ QSGNode *TimelineRenderer::updatePaintNode(QSGNode *node,
}
}
m_modelDirty = false;
m_notesDirty = false;
m_rowCountsDirty = false;
m_rowHeightsDirty = false;
m_lastState = state;
d->modelDirty = false;
d->notesDirty = false;
d->rowCountsDirty = false;
d->rowHeightsDirty = false;
d->lastState = state;
QSGNode *rowNode = m_model->expanded() ? state->expandedRowRoot() : state->collapsedRowRoot();
QSGNode *overlayNode = m_model->expanded() ? state->expandedOverlayRoot() :
QSGNode *rowNode = d->model->expanded() ? state->expandedRowRoot() : state->collapsedRowRoot();
QSGNode *overlayNode = d->model->expanded() ? state->expandedOverlayRoot() :
state->collapsedOverlayRoot();
QMatrix4x4 matrix;
matrix.translate((state->start() - m_zoomer->windowStart()) * spacing, 0, 0);
matrix.translate((state->start() - d->zoomer->windowStart()) * spacing, 0, 0);
matrix.scale(spacing / state->scale(), 1, 1);
QSGTransformNode *transform = static_cast<QSGTransformNode *>(node);
@@ -305,14 +352,14 @@ void TimelineRenderer::mousePressEvent(QMouseEvent *event)
Q_UNUSED(event);
}
int TimelineRenderer::rowFromPosition(int y)
int TimelineRenderer::TimelineRendererPrivate::rowFromPosition(int y) const
{
if (!m_model->expanded())
if (!model->expanded())
return y / TimelineModel::defaultRowHeight();
int ret = 0;
for (int row = 0; row < m_model->expandedRowCount(); ++row) {
y -= m_model->expandedRowHeight(row);
for (int row = 0; row < model->expandedRowCount(); ++row) {
y -= model->expandedRowHeight(row);
if (y <= 0) return ret;
++ret;
}
@@ -322,9 +369,10 @@ int TimelineRenderer::rowFromPosition(int y)
void TimelineRenderer::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(TimelineRenderer);
Q_UNUSED(event);
if (!m_model->isEmpty())
manageClicked();
if (!d->model->isEmpty())
d->manageClicked();
}
void TimelineRenderer::mouseMoveEvent(QMouseEvent *event)
@@ -332,131 +380,161 @@ void TimelineRenderer::mouseMoveEvent(QMouseEvent *event)
event->setAccepted(false);
}
void TimelineRenderer::hoverMoveEvent(QHoverEvent *event)
{
Q_D(TimelineRenderer);
Q_UNUSED(event);
manageHovered(event->pos().x(), event->pos().y());
if (m_currentSelection.eventIndex == -1)
d->manageHovered(event->pos().x(), event->pos().y());
if (d->currentSelection.eventIndex == -1)
event->setAccepted(false);
}
void TimelineRenderer::manageClicked()
void TimelineRenderer::TimelineRendererPrivate::manageClicked()
{
if (m_currentSelection.eventIndex != -1) {
if (m_currentSelection.eventIndex == m_selectedItem)
setSelectionLocked(!m_selectionLocked);
Q_Q(TimelineRenderer);
if (currentSelection.eventIndex != -1) {
if (currentSelection.eventIndex == selectedItem)
q->setSelectionLocked(!selectionLocked);
else
setSelectionLocked(true);
q->setSelectionLocked(true);
// itemPressed() will trigger an update of the events and JavaScript views. Make sure the
// correct event is already selected when that happens, to prevent confusion.
setSelectedItem(m_currentSelection.eventIndex);
emit itemPressed(m_currentSelection.eventIndex);
q->setSelectedItem(currentSelection.eventIndex);
emit q->itemPressed(currentSelection.eventIndex);
} else {
setSelectionLocked(false);
setSelectedItem(-1);
emit itemPressed(-1);
q->setSelectionLocked(false);
q->setSelectedItem(-1);
emit q->itemPressed(-1);
}
}
void TimelineRenderer::manageHovered(int mouseX, int mouseY)
void TimelineRenderer::TimelineRendererPrivate::manageHovered(int mouseX, int mouseY)
{
qint64 duration = m_zoomer->windowDuration();
Q_Q(TimelineRenderer);
qint64 duration = zoomer->windowDuration();
if (duration <= 0)
return;
// Make the "selected" area 3 pixels wide by adding/subtracting 1 to catch very narrow events.
qint64 startTime = (mouseX - 1) * duration / width() + m_zoomer->windowStart();
qint64 endTime = (mouseX + 1) * duration / width() + m_zoomer->windowStart();
qint64 startTime = (mouseX - 1) * duration / q->width() + zoomer->windowStart();
qint64 endTime = (mouseX + 1) * duration / q->width() + zoomer->windowStart();
qint64 exactTime = (startTime + endTime) / 2;
int row = rowFromPosition(mouseY);
// already covered? Only recheck selectionLocked and make sure m_selectedItem is correct.
if (m_currentSelection.eventIndex != -1 &&
exactTime >= m_currentSelection.startTime &&
exactTime < m_currentSelection.endTime &&
row == m_currentSelection.row) {
if (!m_selectionLocked)
setSelectedItem(m_currentSelection.eventIndex);
// already covered? Only recheck selectionLocked and make sure d->selectedItem is correct.
if (currentSelection.eventIndex != -1 &&
exactTime >= currentSelection.startTime &&
exactTime < currentSelection.endTime &&
row == currentSelection.row) {
if (!selectionLocked)
q->setSelectedItem(currentSelection.eventIndex);
return;
}
// find if there's items in the time range
int eventFrom = m_model->firstIndex(startTime);
int eventTo = m_model->lastIndex(endTime);
int eventFrom = model->firstIndex(startTime);
int eventTo = model->lastIndex(endTime);
m_currentSelection.eventIndex = -1;
if (eventFrom == -1 || eventTo < eventFrom || eventTo >= m_model->count())
currentSelection.eventIndex = -1;
if (eventFrom == -1 || eventTo < eventFrom || eventTo >= model->count())
return;
// find if we are in the right column
qint64 bestOffset = std::numeric_limits<qint64>::max();
for (int i=eventTo; i>=eventFrom; --i) {
if ( m_model->row(i) == row) {
if (model->row(i) == row) {
// There can be small events that don't reach the cursor position after large events
// that do but are in a different row.
qint64 itemEnd = m_model->endTime(i);
qint64 itemEnd = model->endTime(i);
if (itemEnd < startTime)
continue;
qint64 itemStart = m_model->startTime(i);
qint64 itemStart = model->startTime(i);
qint64 offset = qAbs(itemEnd - exactTime) + qAbs(itemStart - exactTime);
if (offset < bestOffset) {
// match
m_currentSelection.eventIndex = i;
m_currentSelection.startTime = itemStart;
m_currentSelection.endTime = itemEnd;
m_currentSelection.row = row;
currentSelection.eventIndex = i;
currentSelection.startTime = itemStart;
currentSelection.endTime = itemEnd;
currentSelection.row = row;
bestOffset = offset;
}
}
}
if (!m_selectionLocked && m_currentSelection.eventIndex != -1)
setSelectedItem(m_currentSelection.eventIndex);
if (!selectionLocked && currentSelection.eventIndex != -1)
q->setSelectedItem(currentSelection.eventIndex);
}
void TimelineRenderer::clearData()
{
resetCurrentSelection();
Q_D(TimelineRenderer);
d->resetCurrentSelection();
setSelectedItem(-1);
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)
{
setSelectedItem(m_model->nextItemBySelectionId(selectionId, m_zoomer->rangeStart(),
m_selectedItem));
Q_D(TimelineRenderer);
setSelectedItem(d->model->nextItemBySelectionId(selectionId, d->zoomer->rangeStart(),
d->selectedItem));
}
void TimelineRenderer::selectPrevFromSelectionId(int selectionId)
{
setSelectedItem(m_model->prevItemBySelectionId(selectionId, m_zoomer->rangeStart(),
m_selectedItem));
Q_D(TimelineRenderer);
setSelectedItem(d->model->prevItemBySelectionId(selectionId, d->zoomer->rangeStart(),
d->selectedItem));
}
void TimelineRenderer::setModelDirty()
{
m_modelDirty = true;
Q_D(TimelineRenderer);
d->modelDirty = true;
update();
}
void TimelineRenderer::setRowHeightsDirty()
{
m_rowHeightsDirty = true;
Q_D(TimelineRenderer);
d->rowHeightsDirty = true;
update();
}
void TimelineRenderer::setNotesDirty()
{
m_notesDirty = true;
Q_D(TimelineRenderer);
d->notesDirty = true;
update();
}
void TimelineRenderer::setRowCountsDirty()
{
m_rowCountsDirty = true;
Q_D(TimelineRenderer);
d->rowCountsDirty = true;
update();
}
} // namespace Timeline

View File

@@ -56,28 +56,22 @@ public:
explicit TimelineRenderer(QQuickItem *parent = 0);
bool selectionLocked() const
{
return m_selectionLocked;
}
bool selectionLocked() const;
int selectedItem() const;
int selectedItem() const
{
return m_selectedItem;
}
TimelineModel *model() const { return m_model; }
TimelineModel *model() const;
void setModel(TimelineModel *model);
TimelineZoomControl *zoomer() const { return m_zoomer; }
TimelineZoomControl *zoomer() const;
void setZoomer(TimelineZoomControl *zoomer);
TimelineNotesModel *notes() const { return m_notes; }
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 selectPrevFromSelectionId(int selectionId);
@@ -97,25 +91,9 @@ signals:
public slots:
void clearData();
void setSelectedItem(int itemIndex)
{
if (m_selectedItem != itemIndex) {
m_selectedItem = itemIndex;
update();
emit selectedItemChanged(itemIndex);
}
}
void setSelectedItem(int itemIndex);
void setSelectionLocked(bool locked);
void setSelectionLocked(bool locked)
{
if (m_selectionLocked != locked) {
m_selectionLocked = locked;
update();
emit selectionLockedChanged(locked);
}
}
private slots:
void setModelDirty();
void setRowHeightsDirty();
void setNotesDirty();
@@ -129,38 +107,9 @@ protected:
virtual void hoverMoveEvent(QHoverEvent *event);
private:
int rowFromPosition(int y);
void manageClicked();
void manageHovered(int mouseX, int mouseY);
static const int SafeFloatMax = 1 << 12;
void resetCurrentSelection();
TimelineRenderState *findRenderState();
TimelineModel *m_model;
TimelineZoomControl *m_zoomer;
TimelineNotesModel *m_notes;
struct {
qint64 startTime;
qint64 endTime;
int row;
int eventIndex;
} m_currentSelection;
int m_selectedItem;
bool m_selectionLocked;
bool m_modelDirty;
bool m_rowHeightsDirty;
bool m_notesDirty;
bool m_rowCountsDirty;
QList<const TimelineRenderPass *> m_renderPasses;
QVector<QVector<TimelineRenderState *> > m_renderStates;
TimelineRenderState *m_lastState;
class TimelineRendererPrivate;
TimelineRendererPrivate *d_ptr;
Q_DECLARE_PRIVATE(TimelineRenderer)
};
} // namespace Timeline

View File

@@ -0,0 +1,83 @@
/****************************************************************************
**
** 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 TIMELINERENDERER_P_H
#define TIMELINERENDERER_P_H
#include "timelinerenderer.h"
namespace Timeline {
class TimelineRenderer::TimelineRendererPrivate {
public:
TimelineRendererPrivate(TimelineRenderer *q);
int rowFromPosition(int y) const;
void manageClicked();
void manageHovered(int mouseX, int mouseY);
static const int SafeFloatMax = 1 << 12;
void resetCurrentSelection();
TimelineRenderState *findRenderState();
TimelineModel *model;
TimelineZoomControl *zoomer;
TimelineNotesModel *notes;
struct {
qint64 startTime;
qint64 endTime;
int row;
int eventIndex;
} currentSelection;
int selectedItem;
bool selectionLocked;
bool modelDirty;
bool rowHeightsDirty;
bool notesDirty;
bool rowCountsDirty;
QList<const TimelineRenderPass *> renderPasses;
QVector<QVector<TimelineRenderState *> > renderStates;
TimelineRenderState *lastState;
private:
TimelineRenderer *q_ptr;
Q_DECLARE_PUBLIC(TimelineRenderer)
};
} // namespace Timeline
#endif // TIMELINERENDERER_P_H