diff options
author | Knud Dollereder <knud.dollereder@qt.io> | 2019-03-12 15:18:16 +0100 |
---|---|---|
committer | Knud Dollereder <knud.dollereder@qt.io> | 2019-03-13 11:07:47 +0000 |
commit | c9807788db6219287ab1bff001fde7592171d7a8 (patch) | |
tree | dac47d6d041b0f987294ea9db7408723af84ac20 /src | |
parent | 789a9502f2385bd95c3ea8ce0c0cc1e297df737a (diff) |
Introduce playhead
Update example.
Do not construct the CurveEditorStyleDialog with a parent in order to prevent a crash on close.
Change-Id: I671138aa2304d0fefc39f6802e7aca9b2d9753f1
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/curveeditor/curveeditor.pri | 2 | ||||
-rw-r--r-- | src/curveeditor/curveeditormodel.cpp | 8 | ||||
-rw-r--r-- | src/curveeditor/curveeditormodel.h | 4 | ||||
-rw-r--r-- | src/curveeditor/detail/curveitem.cpp | 4 | ||||
-rw-r--r-- | src/curveeditor/detail/graphicsscene.cpp | 11 | ||||
-rw-r--r-- | src/curveeditor/detail/graphicsview.cpp | 52 | ||||
-rw-r--r-- | src/curveeditor/detail/graphicsview.h | 18 | ||||
-rw-r--r-- | src/curveeditor/detail/playhead.cpp | 134 | ||||
-rw-r--r-- | src/curveeditor/detail/playhead.h | 63 | ||||
-rw-r--r-- | src/curveeditor/detail/treemodel.cpp | 14 | ||||
-rw-r--r-- | src/curveeditor/detail/treemodel.h | 7 |
11 files changed, 300 insertions, 17 deletions
diff --git a/src/curveeditor/curveeditor.pri b/src/curveeditor/curveeditor.pri index aa18c92..f65a34a 100644 --- a/src/curveeditor/curveeditor.pri +++ b/src/curveeditor/curveeditor.pri @@ -14,6 +14,7 @@ HEADERS += \ $$PWD/detail/graphicsview.h \ $$PWD/detail/handleitem.h \ $$PWD/detail/keyframeitem.h \ + $$PWD/detail/playhead.h \ $$PWD/detail/treeitemdelegate.h \ $$PWD/detail/treemodel.h \ $$PWD/detail/treeview.h @@ -32,6 +33,7 @@ SOURCES += \ $$PWD/detail/graphicsview.cpp \ $$PWD/detail/handleitem.cpp \ $$PWD/detail/keyframeitem.cpp \ + $$PWD/detail/playhead.cpp \ $$PWD/detail/treeitemdelegate.cpp \ $$PWD/detail/treemodel.cpp \ $$PWD/detail/treeview.cpp \ diff --git a/src/curveeditor/curveeditormodel.cpp b/src/curveeditor/curveeditormodel.cpp index 7fd545a..3b8b26b 100644 --- a/src/curveeditor/curveeditormodel.cpp +++ b/src/curveeditor/curveeditormodel.cpp @@ -25,6 +25,7 @@ #include "curveeditormodel.h" #include "treeitem.h" +#include "detail/graphicsview.h" namespace DesignTools { @@ -34,10 +35,11 @@ CurveEditorModel::CurveEditorModel(QObject *parent) CurveEditorModel::~CurveEditorModel() {} -void CurveEditorModel::setCurrentTime(uint frame) + +void CurveEditorModel::setCurrentFrame(int frame) { - Q_UNUSED(frame); - printf("CurveEditorModel::setCurrentTime unimplememted!\n"); + if (graphicsView()) + graphicsView()->setCurrentFrame(frame); } void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve) diff --git a/src/curveeditor/curveeditormodel.h b/src/curveeditor/curveeditormodel.h index 1847158..840107c 100644 --- a/src/curveeditor/curveeditormodel.h +++ b/src/curveeditor/curveeditormodel.h @@ -44,6 +44,8 @@ class CurveEditorModel : public TreeModel Q_OBJECT signals: + void currentFrameChanged(int frame); + void curveChanged(PropertyTreeItem *item); public: @@ -58,7 +60,7 @@ public: ~CurveEditorModel() override; - void setCurrentTime(uint frame); + void setCurrentFrame(int frame); void setCurve(unsigned int id, const AnimationCurve &curve); diff --git a/src/curveeditor/detail/curveitem.cpp b/src/curveeditor/detail/curveitem.cpp index 68c22db..9136989 100644 --- a/src/curveeditor/detail/curveitem.cpp +++ b/src/curveeditor/detail/curveitem.cpp @@ -40,7 +40,7 @@ CurveItem::CurveItem(QGraphicsItem *parent) , m_keyframes() , m_selected(false) , m_preselected(false) - , m_itemDirty(true) + , m_itemDirty(false) , m_pathDirty(true) {} @@ -52,7 +52,7 @@ CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem , m_keyframes() , m_selected(false) , m_preselected(false) - , m_itemDirty(true) + , m_itemDirty(false) , m_pathDirty(true) { setAcceptHoverEvents(true); diff --git a/src/curveeditor/detail/graphicsscene.cpp b/src/curveeditor/detail/graphicsscene.cpp index ddafaf4..45e02c8 100644 --- a/src/curveeditor/detail/graphicsscene.cpp +++ b/src/curveeditor/detail/graphicsscene.cpp @@ -67,13 +67,10 @@ void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseMoveEvent(mouseEvent); - if (!mouseEvent->isAccepted()) { - const auto itemList = items(); - for (auto *item : itemList) { - if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) { - curveItem->setPreSelected(curveItem->contains(mouseEvent->scenePos())); - } - } + const auto itemList = items(); + for (auto *item : itemList) { + if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) + curveItem->setPreSelected(curveItem->contains(mouseEvent->scenePos())); } } diff --git a/src/curveeditor/detail/graphicsview.cpp b/src/curveeditor/detail/graphicsview.cpp index e6dfb11..29251aa 100644 --- a/src/curveeditor/detail/graphicsview.cpp +++ b/src/curveeditor/detail/graphicsview.cpp @@ -40,10 +40,13 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) , m_scene() , m_style(model->style()) , m_model(model) - , m_dialog(m_style, this) + , m_playhead() + , m_dialog(m_style) , m_zoomX(0.0) , m_zoomY(0.0) { + model->setGraphicsView(this); + setScene(&m_scene); setAlignment(Qt::AlignLeft | Qt::AlignVCenter); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); @@ -63,6 +66,16 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent) update(); } +CurveEditorModel *GraphicsView::model() const +{ + return m_model; +} + +CurveEditorStyle GraphicsView::editorStyle() const +{ + return m_style; +} + void GraphicsView::setStyle(const CurveEditorStyle &style) { m_style = style; @@ -89,12 +102,17 @@ void GraphicsView::zoomY(double zoom) viewport()->update(); } +void GraphicsView::setCurrentFrame(int frame) +{ + m_playhead.moveToFrame(frame, this); + viewport()->update(); +} + void GraphicsView::reset(const std::vector<CurveItem *> &items) { m_scene.clear(); - for (auto *item : items) { + for (auto *item : items) m_scene.addCurveItem(item); - } applyZoom(m_zoomX, m_zoomY); viewport()->update(); @@ -106,6 +124,26 @@ void GraphicsView::resizeEvent(QResizeEvent *event) QGraphicsView::resizeEvent(event); } +void GraphicsView::mousePressEvent(QMouseEvent *event) +{ + QPoint viewPos = viewport()->mapFromGlobal(event->globalPos()); + if (!m_playhead.mousePress(mapToScene(viewPos))) + QGraphicsView::mousePressEvent(event); +} + +void GraphicsView::mouseMoveEvent(QMouseEvent *event) +{ + QPoint viewPos = viewport()->mapFromGlobal(event->globalPos()); + if (!m_playhead.mouseMove(mapToScene(viewPos), this)) + QGraphicsView::mouseMoveEvent(event); +} + +void GraphicsView::mouseReleaseEvent(QMouseEvent *event) +{ + QGraphicsView::mouseReleaseEvent(event); + m_playhead.mouseRelease(this); +} + void GraphicsView::contextMenuEvent(QContextMenuEvent *event) { Q_UNUSED(event); @@ -123,6 +161,8 @@ void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect) { auto gap = QRectF(rect.topLeft(), QSizeF(m_style.valueAxisWidth, m_style.timeAxisHeight)); + m_playhead.paint(painter); + auto abscissa = QRectF(gap.topRight(), rect.topRight() + QPointF(0.0, gap.height())); if (abscissa.isValid()) drawTimeScale(painter, abscissa); @@ -182,11 +222,15 @@ void GraphicsView::applyZoom(double x, double y) m_transform = QTransform::fromScale(scaleX, scaleY); QRectF sceneBounds; - for (auto *item : items()) + const auto itemList = items(); + for (auto *item : itemList) { if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) sceneBounds = sceneBounds.united(curveItem->setComponentTransform(m_transform)); + } updateSceneRect(sceneBounds); + + m_playhead.resize(this); } void GraphicsView::updateSceneRect(const QRectF &rect) diff --git a/src/curveeditor/detail/graphicsview.h b/src/curveeditor/detail/graphicsview.h index db9933e..8d6c5f7 100644 --- a/src/curveeditor/detail/graphicsview.h +++ b/src/curveeditor/detail/graphicsview.h @@ -28,6 +28,7 @@ #include "curveeditorstyle.h" #include "curveeditorstyledialog.h" #include "graphicsscene.h" +#include "playhead.h" #include <QGraphicsView> @@ -35,25 +36,40 @@ namespace DesignTools { class CurveItem; class CurveEditorModel; +class Playhead; class GraphicsView : public QGraphicsView { Q_OBJECT + friend class Playhead; + public: GraphicsView(CurveEditorModel *model, QWidget *parent = nullptr); + CurveEditorModel *model() const; + + CurveEditorStyle editorStyle() const; + void setStyle(const CurveEditorStyle &style); void zoomX(double zoom); void zoomY(double zoom); + void setCurrentFrame(int frame); + void reset(const std::vector<CurveItem *> &items); protected: void resizeEvent(QResizeEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + + void mouseMoveEvent(QMouseEvent *event) override; + + void mouseReleaseEvent(QMouseEvent *event) override; + void contextMenuEvent(QContextMenuEvent *event) override; void drawForeground(QPainter *painter, const QRectF &rect) override; @@ -92,6 +108,8 @@ private: CurveEditorModel *m_model; + Playhead m_playhead; + CurveEditorStyleDialog m_dialog; double m_zoomX; diff --git a/src/curveeditor/detail/playhead.cpp b/src/curveeditor/detail/playhead.cpp new file mode 100644 index 0000000..b829cf9 --- /dev/null +++ b/src/curveeditor/detail/playhead.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "playhead.h" +#include "curveeditormodel.h" +#include "graphicsview.h" + +#include <QGraphicsScene> +#include <QPainter> + +#include <cmath> + +namespace DesignTools { + +Playhead::Playhead() + : m_frame(0) + , m_rect() +{} + +void Playhead::moveToFrame(int frame, GraphicsView *view) +{ + m_frame = frame; + m_rect.moveCenter(QPointF(view->mapTimeToX(m_frame), m_rect.center().y())); +} + +void Playhead::resize(GraphicsView *view) +{ + QRectF viewRect = view->mapToScene(view->viewport()->rect()).boundingRect(); + + CurveEditorStyle style = view->editorStyle(); + + QPointF topLeft = viewRect.topLeft() + QPointF(style.valueAxisWidth, style.timeAxisHeight + 5.); + + m_rect = QRectF(topLeft, QSizeF(20., viewRect.height() - style.timeAxisHeight - 10.)); + + moveToFrame(m_frame, view); +} + +bool Playhead::mousePress(const QPointF &pos) +{ + QRectF hitRect = m_rect; + hitRect.setBottom(hitRect.top() + hitRect.width()); + + if (hitRect.contains(pos)) { + m_mouse = pos; + m_center = m_rect.center().x(); + return true; + } else { + m_mouse = QPointF(); + m_center = 0.0; + } + return false; +} + +bool Playhead::mouseMove(const QPointF &pos, GraphicsView *view) +{ + if (!m_mouse.isNull()) { + m_center += pos.x() - m_mouse.x(); + m_mouse = pos; + view->setCurrentFrame(std::round(view->mapXtoTime(m_center))); + return true; + } + return false; +} + +void Playhead::mouseRelease(GraphicsView *view) +{ + if (!m_mouse.isNull()) + emit view->model()->currentFrameChanged(m_frame); + + m_mouse = QPointF(); + m_center = 0.0; +} + +void Playhead::paint(QPainter *painter) const +{ + painter->save(); + painter->setPen(Qt::yellow); + painter->setRenderHint(QPainter::Antialiasing, true); + + double radius = 6.0; + + QRectF rect = m_rect; + rect.setBottom(m_rect.top() + m_rect.width()); + + QPointF top(rect.center().x(), rect.top()); + QPointF right(rect.right(), rect.top()); + QPointF bottom(rect.center().x(), rect.bottom()); + QPointF left(rect.left(), rect.top()); + + QLineF rightToBottom(right, bottom); + rightToBottom.setLength(radius); + + QLineF leftToBottom(left, bottom); + leftToBottom.setLength(radius); + + QPainterPath path(top); + path.lineTo(right - QPointF(radius, 0.)); + path.quadTo(right, rightToBottom.p2()); + path.lineTo(bottom); + path.lineTo(leftToBottom.p2()); + path.quadTo(left, left + QPointF(radius, 0.)); + path.closeSubpath(); + + painter->fillPath(path, Qt::yellow); + + painter->drawLine(top + QPointF(0., 5.), QPointF(m_rect.center().x(), m_rect.bottom())); + + painter->restore(); +} + +} // End namespace DesignTools. diff --git a/src/curveeditor/detail/playhead.h b/src/curveeditor/detail/playhead.h new file mode 100644 index 0000000..f82a04d --- /dev/null +++ b/src/curveeditor/detail/playhead.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Tooling +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include <QGraphicsObject> + +namespace DesignTools { + +class GraphicsView; + +class Playhead +{ + friend class GraphicsView; + +public: + Playhead(); + + void paint(QPainter *painter) const; + + void moveToFrame(int frame, GraphicsView *view); + + void resize(GraphicsView *view); + + bool mousePress(const QPointF &pos); + + bool mouseMove(const QPointF &pos, GraphicsView *view); + + void mouseRelease(GraphicsView *view); + +private: + int m_frame; + + double m_center; + + QRectF m_rect; + + QPointF m_mouse; +}; + +} // End namespace DesignTools. diff --git a/src/curveeditor/detail/treemodel.cpp b/src/curveeditor/detail/treemodel.cpp index 1fc3fad..1ea0370 100644 --- a/src/curveeditor/detail/treemodel.cpp +++ b/src/curveeditor/detail/treemodel.cpp @@ -25,6 +25,7 @@ #include "treemodel.h" #include "treeitem.h" +#include "detail/graphicsview.h" #include <QIcon> @@ -32,6 +33,7 @@ namespace DesignTools { TreeModel::TreeModel(QObject *parent) : QAbstractItemModel(parent) + , m_view(nullptr) , m_root(new TreeItem("Root")) {} @@ -41,6 +43,8 @@ TreeModel::~TreeModel() delete m_root; m_root = nullptr; } + + m_view = nullptr; } QVariant TreeModel::data(const QModelIndex &index, int role) const @@ -121,6 +125,16 @@ int TreeModel::columnCount(const QModelIndex &parent) const return m_root->columnCount(); } +void TreeModel::setGraphicsView(GraphicsView *view) +{ + m_view = view; +} + +GraphicsView *TreeModel::graphicsView() const +{ + return m_view; +} + void TreeModel::initialize() { if (m_root) diff --git a/src/curveeditor/detail/treemodel.h b/src/curveeditor/detail/treemodel.h index 13d2518..209b2ee 100644 --- a/src/curveeditor/detail/treemodel.h +++ b/src/curveeditor/detail/treemodel.h @@ -31,6 +31,7 @@ namespace DesignTools { +class GraphicsView; class TreeItem; class TreeModel : public QAbstractItemModel @@ -54,7 +55,11 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override; + void setGraphicsView(GraphicsView *view); + protected: + GraphicsView *graphicsView() const; + void initialize(); TreeItem *root(); @@ -62,6 +67,8 @@ protected: TreeItem *find(unsigned int id); private: + GraphicsView *m_view; + TreeItem *m_root; }; |