forked from qt-creator/qt-creator
Add curve editor
Moved qmldesignerextension into component Updated build systems Change-Id: I8d2d0757a1639a472d426b66c0c8ae6fb84cc3d2 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -25,7 +25,7 @@ add_qtc_plugin(QmlDesigner
|
||||
switchsplittabwidget.cpp switchsplittabwidget.h
|
||||
EXPLICIT_MOC
|
||||
components/propertyeditor/propertyeditorvalue.h
|
||||
qmldesignerextension/connectioneditor/connectionviewwidget.h
|
||||
components/connectioneditor/connectionviewwidget.h
|
||||
SKIP_DEBUG_CMAKE_FILE_CHECK
|
||||
)
|
||||
|
||||
@@ -499,12 +499,12 @@ extend_qtc_plugin(QmlDesigner
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX qmldesignerextension/colortool
|
||||
SOURCES_PREFIX components/colortool
|
||||
SOURCES colortool.cpp colortool.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX qmldesignerextension/connectioneditor
|
||||
SOURCES_PREFIX components/connectioneditor
|
||||
SOURCES
|
||||
addnewbackenddialog.cpp addnewbackenddialog.h addnewbackenddialog.ui
|
||||
backendmodel.cpp backendmodel.h
|
||||
@@ -518,7 +518,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX qmldesignerextension
|
||||
SOURCES_PREFIX components
|
||||
SOURCES
|
||||
pathtool/controlpoint.cpp pathtool/controlpoint.h
|
||||
pathtool/cubicsegment.cpp pathtool/cubicsegment.h
|
||||
@@ -527,9 +527,6 @@ extend_qtc_plugin(QmlDesigner
|
||||
pathtool/pathtool.cpp pathtool/pathtool.h
|
||||
pathtool/pathtoolview.cpp pathtool/pathtoolview.h
|
||||
|
||||
qmldesignerextensionconstants.h
|
||||
qmldesignerextension_global.h
|
||||
|
||||
sourcetool/sourcetool.cpp sourcetool/sourcetool.h
|
||||
|
||||
texttool/textedititem.cpp texttool/textedititem.h
|
||||
@@ -538,7 +535,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX qmldesignerextension/timelineeditor
|
||||
SOURCES_PREFIX components/timelineeditor
|
||||
SOURCES
|
||||
canvas.cpp canvas.h
|
||||
canvasstyledialog.cpp canvasstyledialog.h
|
||||
@@ -576,6 +573,33 @@ extend_qtc_plugin(QmlDesigner
|
||||
timelinewidget.cpp timelinewidget.h
|
||||
)
|
||||
|
||||
extend_qtc_plugin(QmlDesigner
|
||||
SOURCES_PREFIX components/curveeditor
|
||||
SOURCES
|
||||
animationcurve.cpp animationcurve.h
|
||||
curveeditor.cpp curveeditor.h
|
||||
curveeditormodel.cpp curveeditormodel.h
|
||||
curveeditorstyle.h
|
||||
keyframe.cpp keyframe.h
|
||||
treeitem.cpp treeitem.h
|
||||
detail/colorcontrol.cpp detail/colorcontrol.h
|
||||
detail/curveeditorstyledialog.cpp detail/curveeditorstyledialog.h
|
||||
detail/curveitem.cpp detail/curveitem.h
|
||||
detail/curvesegment.cpp detail/curvesegment.h
|
||||
detail/graphicsscene.cpp detail/graphicsscene.h
|
||||
detail/graphicsview.cpp detail/graphicsview.h
|
||||
detail/handleitem.cpp detail/handleitem.h
|
||||
detail/keyframeitem.cpp detail/keyframeitem.h
|
||||
detail/playhead.cpp detail/playhead.h
|
||||
detail/selectableitem.cpp detail/selectableitem.h
|
||||
detail/selector.cpp detail/selector.h
|
||||
detail/shortcut.cpp detail/shortcut.h
|
||||
detail/treeitemdelegate.cpp detail/treeitemdelegate.h
|
||||
detail/treemodel.cpp detail/treemodel.h
|
||||
detail/treeview.cpp detail/treeview.h
|
||||
detail/utils.cpp detail/utils.h
|
||||
)
|
||||
|
||||
# Do the file comparison at the end, due to all the extend_qtc_plugin calls
|
||||
if (WITH_DEBUG_CMAKE)
|
||||
foreach(plugin QmlDesigner componentsplugin qtquickplugin)
|
||||
|
@@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "animationcurve.h"
|
||||
#include "detail/curvesegment.h"
|
||||
|
||||
#include <QLineF>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
AnimationCurve::AnimationCurve()
|
||||
: m_frames()
|
||||
{}
|
||||
|
||||
AnimationCurve::AnimationCurve(const std::vector<Keyframe> &frames)
|
||||
: m_frames(frames)
|
||||
, m_minY(std::numeric_limits<double>::max())
|
||||
, m_maxY(std::numeric_limits<double>::lowest())
|
||||
{
|
||||
if (isValid()) {
|
||||
|
||||
for (auto e : extrema()) {
|
||||
|
||||
if (m_minY > e.y())
|
||||
m_minY = e.y();
|
||||
|
||||
if (m_maxY < e.y())
|
||||
m_maxY = e.y();
|
||||
}
|
||||
|
||||
for (auto &frame : qAsConst(m_frames)) {
|
||||
if (frame.position().y() < m_minY)
|
||||
m_minY = frame.position().y();
|
||||
|
||||
if (frame.position().y() > m_maxY)
|
||||
m_maxY = frame.position().y();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AnimationCurve::isValid() const
|
||||
{
|
||||
return m_frames.size() >= 2;
|
||||
}
|
||||
|
||||
double AnimationCurve::minimumTime() const
|
||||
{
|
||||
if (!m_frames.empty())
|
||||
return m_frames.front().position().x();
|
||||
|
||||
return std::numeric_limits<double>::max();
|
||||
}
|
||||
|
||||
double AnimationCurve::maximumTime() const
|
||||
{
|
||||
if (!m_frames.empty())
|
||||
return m_frames.back().position().x();
|
||||
|
||||
return std::numeric_limits<double>::lowest();
|
||||
}
|
||||
|
||||
double AnimationCurve::minimumValue() const
|
||||
{
|
||||
return m_minY;
|
||||
}
|
||||
|
||||
double AnimationCurve::maximumValue() const
|
||||
{
|
||||
return m_maxY;
|
||||
}
|
||||
|
||||
std::vector<Keyframe> AnimationCurve::keyframes() const
|
||||
{
|
||||
return m_frames;
|
||||
}
|
||||
|
||||
std::vector<QPointF> AnimationCurve::extrema() const
|
||||
{
|
||||
std::vector<QPointF> out;
|
||||
|
||||
CurveSegment segment;
|
||||
segment.setLeft(m_frames.at(0));
|
||||
|
||||
for (size_t i = 1; i < m_frames.size(); ++i) {
|
||||
|
||||
segment.setRight(m_frames[i]);
|
||||
|
||||
const auto es = segment.extrema();
|
||||
out.insert(std::end(out), std::begin(es), std::end(es));
|
||||
|
||||
segment.setLeft(m_frames[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<double> AnimationCurve::yForX(double x) const
|
||||
{
|
||||
if (m_frames.front().position().x() > x)
|
||||
return std::vector<double>();
|
||||
|
||||
CurveSegment segment;
|
||||
for (auto &frame : m_frames) {
|
||||
if (frame.position().x() > x) {
|
||||
segment.setRight(frame);
|
||||
return segment.yForX(x);
|
||||
}
|
||||
segment.setLeft(frame);
|
||||
}
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
std::vector<double> AnimationCurve::xForY(double y, uint segment) const
|
||||
{
|
||||
if (m_frames.size() > segment + 1) {
|
||||
CurveSegment seg(m_frames[segment], m_frames[segment + 1]);
|
||||
return seg.xForY(y);
|
||||
}
|
||||
return std::vector<double>();
|
||||
}
|
||||
|
||||
bool AnimationCurve::intersects(const QPointF &coord, double radius)
|
||||
{
|
||||
if (m_frames.size() < 2)
|
||||
return false;
|
||||
|
||||
std::vector<CurveSegment> influencer;
|
||||
|
||||
CurveSegment current;
|
||||
current.setLeft(m_frames.at(0));
|
||||
|
||||
for (size_t i = 1; i < m_frames.size(); ++i) {
|
||||
Keyframe &frame = m_frames.at(i);
|
||||
|
||||
current.setRight(frame);
|
||||
|
||||
if (current.containsX(coord.x() - radius) ||
|
||||
current.containsX(coord.x()) ||
|
||||
current.containsX(coord.x() + radius)) {
|
||||
influencer.push_back(current);
|
||||
}
|
||||
|
||||
if (frame.position().x() > coord.x() + radius)
|
||||
break;
|
||||
|
||||
current.setLeft(frame);
|
||||
}
|
||||
|
||||
for (auto &segment : influencer) {
|
||||
for (auto &y : segment.yForX(coord.x())) {
|
||||
QLineF line(coord.x(), y, coord.x(), coord.y());
|
||||
if (line.length() < radius)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto &x : segment.xForY(coord.y())) {
|
||||
QLineF line(x, coord.y(), coord.x(), coord.y());
|
||||
if (line.length() < radius)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "keyframe.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class AnimationCurve
|
||||
{
|
||||
public:
|
||||
AnimationCurve();
|
||||
|
||||
AnimationCurve(const std::vector<Keyframe> &frames);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
double minimumTime() const;
|
||||
|
||||
double maximumTime() const;
|
||||
|
||||
double minimumValue() const;
|
||||
|
||||
double maximumValue() const;
|
||||
|
||||
std::vector<Keyframe> keyframes() const;
|
||||
|
||||
std::vector<QPointF> extrema() const;
|
||||
|
||||
std::vector<double> yForX(double x) const;
|
||||
|
||||
std::vector<double> xForY(double y, uint segment) const;
|
||||
|
||||
bool intersects(const QPointF &coord, double radius);
|
||||
|
||||
private:
|
||||
std::vector<Keyframe> m_frames;
|
||||
|
||||
double m_minY;
|
||||
|
||||
double m_maxY;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditor.h"
|
||||
#include "curveeditormodel.h"
|
||||
#include "detail/curveitem.h"
|
||||
#include "detail/graphicsview.h"
|
||||
#include "detail/treeview.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QSplitter>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_tree(new TreeView(model, this))
|
||||
, m_view(new GraphicsView(model))
|
||||
{
|
||||
QSplitter *splitter = new QSplitter;
|
||||
splitter->addWidget(m_tree);
|
||||
splitter->addWidget(m_view);
|
||||
splitter->setStretchFactor(1, 2);
|
||||
|
||||
QHBoxLayout *box = new QHBoxLayout;
|
||||
box->addWidget(splitter);
|
||||
setLayout(box);
|
||||
|
||||
connect(m_tree, &TreeView::curvesSelected, m_view, &GraphicsView::reset);
|
||||
}
|
||||
|
||||
void CurveEditor::zoomX(double zoom)
|
||||
{
|
||||
m_view->setZoomX(zoom);
|
||||
}
|
||||
|
||||
void CurveEditor::zoomY(double zoom)
|
||||
{
|
||||
m_view->setZoomY(zoom);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -1,9 +1,9 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
** This file is part of the Qt Design Tooling
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
@@ -25,11 +25,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace QmlDesignerExtension {
|
||||
namespace Constants {
|
||||
#include <QWidget>
|
||||
|
||||
const char ACTION_ID[] = "QmlDesignerExtension.Action";
|
||||
const char MENU_ID[] = "QmlDesignerExtension.Menu";
|
||||
namespace DesignTools {
|
||||
|
||||
} // namespace QmlDesignerExtension
|
||||
} // namespace Constants
|
||||
class CurveEditorModel;
|
||||
class GraphicsView;
|
||||
class TreeView;
|
||||
|
||||
class CurveEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CurveEditor(CurveEditorModel *model, QWidget *parent = nullptr);
|
||||
|
||||
void zoomX(double zoom);
|
||||
|
||||
void zoomY(double zoom);
|
||||
|
||||
private:
|
||||
TreeView *m_tree;
|
||||
|
||||
GraphicsView *m_view;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,46 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/animationcurve.h \
|
||||
$$PWD/curveeditor.h \
|
||||
$$PWD/curveeditormodel.h \
|
||||
$$PWD/detail/colorcontrol.h \
|
||||
$$PWD/detail/curveeditorstyledialog.h \
|
||||
$$PWD/detail/curveitem.h \
|
||||
$$PWD/detail/curvesegment.h \
|
||||
$$PWD/detail/graphicsscene.h \
|
||||
$$PWD/detail/graphicsview.h \
|
||||
$$PWD/detail/handleitem.h \
|
||||
$$PWD/detail/keyframeitem.h \
|
||||
$$PWD/detail/playhead.h \
|
||||
$$PWD/detail/selectableitem.h \
|
||||
$$PWD/detail/selector.h \
|
||||
$$PWD/detail/shortcut.h \
|
||||
$$PWD/detail/treeitemdelegate.h \
|
||||
$$PWD/detail/treemodel.h \
|
||||
$$PWD/detail/treeview.h \
|
||||
$$PWD/keyframe.h \
|
||||
$$PWD/treeitem.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/animationcurve.cpp \
|
||||
$$PWD/curveeditor.cpp \
|
||||
$$PWD/curveeditormodel.cpp \
|
||||
$$PWD/detail/colorcontrol.cpp \
|
||||
$$PWD/detail/curveeditorstyledialog.cpp \
|
||||
$$PWD/detail/curveitem.cpp \
|
||||
$$PWD/detail/curvesegment.cpp \
|
||||
$$PWD/detail/graphicsscene.cpp \
|
||||
$$PWD/detail/graphicsview.cpp \
|
||||
$$PWD/detail/handleitem.cpp \
|
||||
$$PWD/detail/keyframeitem.cpp \
|
||||
$$PWD/detail/playhead.cpp \
|
||||
$$PWD/detail/selectableitem.cpp \
|
||||
$$PWD/detail/selector.cpp \
|
||||
$$PWD/detail/shortcut.cpp \
|
||||
$$PWD/detail/treeitemdelegate.cpp \
|
||||
$$PWD/detail/treemodel.cpp \
|
||||
$$PWD/detail/treeview.cpp \
|
||||
$$PWD/detail/utils.cpp \
|
||||
$$PWD/keyframe.cpp \
|
||||
$$PWD/treeitem.cpp
|
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditormodel.h"
|
||||
#include "treeitem.h"
|
||||
#include "detail/graphicsview.h"
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
CurveEditorModel::CurveEditorModel(QObject *parent)
|
||||
: TreeModel(parent)
|
||||
{}
|
||||
|
||||
CurveEditorModel::~CurveEditorModel() {}
|
||||
|
||||
|
||||
void CurveEditorModel::setCurrentFrame(int frame)
|
||||
{
|
||||
if (graphicsView())
|
||||
graphicsView()->setCurrentFrame(frame);
|
||||
}
|
||||
|
||||
void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve)
|
||||
{
|
||||
if (TreeItem *item = find(id)) {
|
||||
if (PropertyTreeItem *propertyItem = item->asPropertyItem()) {
|
||||
propertyItem->setCurve(curve);
|
||||
emit curveChanged(propertyItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEditorModel::reset(const std::vector<TreeItem *> &items)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
initialize();
|
||||
|
||||
unsigned int counter = 0;
|
||||
for (auto *item : items) {
|
||||
item->setId(++counter);
|
||||
root()->addChild(item);
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "detail/treemodel.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class QPointF;
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
struct CurveEditorStyle;
|
||||
|
||||
class AnimationCurve;
|
||||
class PropertyTreeItem;
|
||||
class TreeItem;
|
||||
|
||||
class CurveEditorModel : public TreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void currentFrameChanged(int frame);
|
||||
|
||||
void curveChanged(PropertyTreeItem *item);
|
||||
|
||||
public:
|
||||
virtual double minimumTime() const = 0;
|
||||
|
||||
virtual double maximumTime() const = 0;
|
||||
|
||||
virtual CurveEditorStyle style() const = 0;
|
||||
|
||||
public:
|
||||
CurveEditorModel(QObject *parent = nullptr);
|
||||
|
||||
~CurveEditorModel() override;
|
||||
|
||||
void setCurrentFrame(int frame);
|
||||
|
||||
void setCurve(unsigned int id, const AnimationCurve &curve);
|
||||
|
||||
void reset(const std::vector<TreeItem *> &items);
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,125 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "detail/shortcut.h"
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QBrush>
|
||||
#include <QColor>
|
||||
#include <QDialog>
|
||||
#include <QIcon>
|
||||
#include <QKeySequence>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
struct TreeItemStyleOption
|
||||
{
|
||||
double margins;
|
||||
QIcon pinnedIcon = QIcon(":/ICON_PINNED");
|
||||
QIcon unpinnedIcon = QIcon(":/ICON_UNPINNED");
|
||||
QIcon lockedIcon = QIcon(":/ICON_LOCKED");
|
||||
QIcon unlockedIcon = QIcon(":/ICON_UNLOCKED");
|
||||
};
|
||||
|
||||
struct HandleItemStyleOption
|
||||
{
|
||||
double size = 10.0;
|
||||
double lineWidth = 1.0;
|
||||
QColor color = QColor(200, 0, 0);
|
||||
QColor selectionColor = QColor(200, 200, 200);
|
||||
};
|
||||
|
||||
struct KeyframeItemStyleOption
|
||||
{
|
||||
double size = 10.0;
|
||||
QColor color = QColor(200, 200, 0);
|
||||
QColor selectionColor = QColor(200, 200, 200);
|
||||
};
|
||||
|
||||
struct CurveItemStyleOption
|
||||
{
|
||||
double width = 1.0;
|
||||
QColor color = QColor(0, 200, 0);
|
||||
QColor selectionColor = QColor(200, 200, 200);
|
||||
};
|
||||
|
||||
struct PlayheadStyleOption
|
||||
{
|
||||
double width = 20.0;
|
||||
double radius = 4.0;
|
||||
QColor color = QColor(200, 200, 0);
|
||||
};
|
||||
|
||||
struct Shortcuts
|
||||
{
|
||||
Shortcut newSelection = Shortcut(Qt::LeftButton);
|
||||
Shortcut addToSelection = Shortcut(Qt::LeftButton, Qt::ControlModifier | Qt::ShiftModifier);
|
||||
Shortcut removeFromSelection = Shortcut(Qt::LeftButton, Qt::ShiftModifier);
|
||||
Shortcut toggleSelection = Shortcut(Qt::LeftButton, Qt::ControlModifier);
|
||||
|
||||
Shortcut zoom = Shortcut(Qt::RightButton, Qt::AltModifier);
|
||||
Shortcut pan = Shortcut(Qt::MiddleButton, Qt::AltModifier);
|
||||
Shortcut frameAll = Shortcut(Qt::NoModifier, Qt::Key_A);
|
||||
};
|
||||
|
||||
struct CurveEditorStyle
|
||||
{
|
||||
Shortcuts shortcuts;
|
||||
|
||||
QBrush backgroundBrush = QBrush(QColor(5, 0, 100));
|
||||
QBrush backgroundAlternateBrush = QBrush(QColor(0, 0, 50));
|
||||
QColor fontColor = QColor(200, 200, 200);
|
||||
QColor gridColor = QColor(128, 128, 128);
|
||||
double canvasMargin = 5.0;
|
||||
int zoomInWidth = 100;
|
||||
int zoomInHeight = 100;
|
||||
double timeAxisHeight = 40.0;
|
||||
double timeOffsetLeft = 10.0;
|
||||
double timeOffsetRight = 10.0;
|
||||
QColor rangeBarColor = QColor(128, 128, 128);
|
||||
QColor rangeBarCapsColor = QColor(50, 50, 255);
|
||||
double valueAxisWidth = 60.0;
|
||||
double valueOffsetTop = 10.0;
|
||||
double valueOffsetBottom = 10.0;
|
||||
|
||||
HandleItemStyleOption handleStyle;
|
||||
KeyframeItemStyleOption keyframeStyle;
|
||||
CurveItemStyleOption curveStyle;
|
||||
TreeItemStyleOption treeItemStyle;
|
||||
PlayheadStyleOption playhead;
|
||||
};
|
||||
|
||||
inline QPixmap pixmapFromIcon(const QIcon &icon, const QSize &size, const QColor &color)
|
||||
{
|
||||
QPixmap pixmap = icon.pixmap(size);
|
||||
QPixmap mask(pixmap.size());
|
||||
mask.fill(color);
|
||||
mask.setMask(pixmap.createMaskFromColor(Qt::transparent));
|
||||
return mask;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,101 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "colorcontrol.h"
|
||||
|
||||
#include <QColorDialog>
|
||||
#include <QEvent>
|
||||
#include <QHelpEvent>
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
ColorControl::ColorControl()
|
||||
: QWidget(nullptr)
|
||||
, m_color(Qt::black)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setFixedHeight(20);
|
||||
}
|
||||
|
||||
ColorControl::ColorControl(const QColor &color, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_color(color)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
setFixedHeight(20);
|
||||
}
|
||||
|
||||
ColorControl::~ColorControl() = default;
|
||||
|
||||
QColor ColorControl::value() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
void ColorControl::setValue(const QColor &val)
|
||||
{
|
||||
m_color = val;
|
||||
}
|
||||
|
||||
bool ColorControl::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::ToolTip) {
|
||||
if (auto helpEvent = static_cast<const QHelpEvent *>(event)) {
|
||||
QToolTip::showText(helpEvent->globalPos(), m_color.name());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void ColorControl::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.fillRect(event->rect(), m_color);
|
||||
}
|
||||
|
||||
void ColorControl::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QColor color = QColorDialog::getColor(m_color, this);
|
||||
|
||||
event->accept();
|
||||
|
||||
if (color != m_color) {
|
||||
m_color = color;
|
||||
update();
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void ColorControl::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
// Required if embedded in a QGraphicsProxywidget
|
||||
// in order to call mouseRelease properly.
|
||||
QWidget::mousePressEvent(event);
|
||||
event->accept();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -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 <QWidget>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class ColorControl : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ColorControl();
|
||||
|
||||
ColorControl(const QColor &color, QWidget *parent = nullptr);
|
||||
|
||||
~ColorControl() override;
|
||||
|
||||
QColor value() const;
|
||||
|
||||
void setValue(const QColor &val);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *event) override;
|
||||
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
signals:
|
||||
void valueChanged();
|
||||
|
||||
private:
|
||||
QColor m_color;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,267 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyledialog.h"
|
||||
#include "colorcontrol.h"
|
||||
#include "curveeditorstyle.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
QHBoxLayout *createRow(const QString &title, QWidget *widget)
|
||||
{
|
||||
auto *label = new QLabel(title);
|
||||
label->setFixedWidth(200);
|
||||
label->setAlignment(Qt::AlignRight);
|
||||
|
||||
auto *box = new QHBoxLayout;
|
||||
box->addWidget(label);
|
||||
box->addWidget(widget);
|
||||
return box;
|
||||
}
|
||||
|
||||
CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_printButton(new QPushButton("Print"))
|
||||
, m_background(new ColorControl(style.backgroundBrush.color()))
|
||||
, m_backgroundAlternate(new ColorControl(style.backgroundAlternateBrush.color()))
|
||||
, m_fontColor(new ColorControl(style.fontColor))
|
||||
, m_gridColor(new ColorControl(style.gridColor))
|
||||
, m_canvasMargin(new QDoubleSpinBox())
|
||||
, m_zoomInWidth(new QSpinBox())
|
||||
, m_zoomInHeight(new QSpinBox())
|
||||
, m_timeAxisHeight(new QDoubleSpinBox())
|
||||
, m_timeOffsetLeft(new QDoubleSpinBox())
|
||||
, m_timeOffsetRight(new QDoubleSpinBox())
|
||||
, m_rangeBarColor(new ColorControl(style.rangeBarCapsColor))
|
||||
, m_rangeBarCapsColor(new ColorControl(style.rangeBarCapsColor))
|
||||
, m_valueAxisWidth(new QDoubleSpinBox())
|
||||
, m_valueOffsetTop(new QDoubleSpinBox())
|
||||
, m_valueOffsetBottom(new QDoubleSpinBox())
|
||||
, m_handleSize(new QDoubleSpinBox())
|
||||
, m_handleLineWidth(new QDoubleSpinBox())
|
||||
, m_handleColor(new ColorControl(style.handleStyle.color))
|
||||
, m_handleSelectionColor(new ColorControl(style.handleStyle.selectionColor))
|
||||
, m_keyframeSize(new QDoubleSpinBox())
|
||||
, m_keyframeColor(new ColorControl(style.keyframeStyle.color))
|
||||
, m_keyframeSelectionColor(new ColorControl(style.keyframeStyle.selectionColor))
|
||||
, m_curveWidth(new QDoubleSpinBox())
|
||||
, m_curveColor(new ColorControl(style.curveStyle.color))
|
||||
, m_curveSelectionColor(new ColorControl(style.curveStyle.selectionColor))
|
||||
, m_treeMargins(new QDoubleSpinBox())
|
||||
, m_playheadWidth(new QDoubleSpinBox())
|
||||
, m_playheadRadius(new QDoubleSpinBox())
|
||||
, m_playheadColor(new ColorControl(style.playhead.color))
|
||||
|
||||
{
|
||||
m_canvasMargin->setValue(style.canvasMargin);
|
||||
m_zoomInWidth->setValue(style.zoomInWidth);
|
||||
m_zoomInHeight->setValue(style.zoomInHeight);
|
||||
m_zoomInHeight->setMaximum(9000);
|
||||
|
||||
m_timeAxisHeight->setValue(style.timeAxisHeight);
|
||||
m_timeOffsetLeft->setValue(style.timeOffsetLeft);
|
||||
m_timeOffsetRight->setValue(style.timeOffsetRight);
|
||||
m_valueAxisWidth->setValue(style.valueAxisWidth);
|
||||
m_valueOffsetTop->setValue(style.valueOffsetTop);
|
||||
m_valueOffsetBottom->setValue(style.valueOffsetBottom);
|
||||
m_handleSize->setValue(style.handleStyle.size);
|
||||
m_handleLineWidth->setValue(style.handleStyle.lineWidth);
|
||||
m_keyframeSize->setValue(style.keyframeStyle.size);
|
||||
m_curveWidth->setValue(style.curveStyle.width);
|
||||
m_treeMargins->setValue(style.treeItemStyle.margins);
|
||||
m_playheadWidth->setValue(style.playhead.width);
|
||||
m_playheadRadius->setValue(style.playhead.radius);
|
||||
|
||||
connect(m_printButton, &QPushButton::released, this, &CurveEditorStyleDialog::printStyle);
|
||||
|
||||
auto intChanged = [this](int) { emitStyleChanged(); };
|
||||
auto doubleChanged = [this](double) { emitStyleChanged(); };
|
||||
auto colorChanged = [this]() { emitStyleChanged(); };
|
||||
|
||||
auto intSignal = static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged);
|
||||
auto doubleSignal = static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged);
|
||||
|
||||
connect(m_background, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_backgroundAlternate, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_fontColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_gridColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_canvasMargin, doubleSignal, doubleChanged);
|
||||
connect(m_zoomInWidth, intSignal, intChanged);
|
||||
connect(m_zoomInHeight, intSignal, intChanged);
|
||||
connect(m_timeAxisHeight, doubleSignal, doubleChanged);
|
||||
connect(m_timeOffsetLeft, doubleSignal, doubleChanged);
|
||||
connect(m_timeOffsetRight, doubleSignal, doubleChanged);
|
||||
connect(m_rangeBarColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_rangeBarCapsColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_valueAxisWidth, doubleSignal, doubleChanged);
|
||||
connect(m_valueOffsetTop, doubleSignal, doubleChanged);
|
||||
connect(m_valueOffsetBottom, doubleSignal, doubleChanged);
|
||||
connect(m_handleSize, doubleSignal, doubleChanged);
|
||||
connect(m_handleLineWidth, doubleSignal, doubleChanged);
|
||||
connect(m_handleColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_handleSelectionColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeSize, doubleSignal, doubleChanged);
|
||||
connect(m_keyframeColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeSelectionColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveWidth, doubleSignal, doubleChanged);
|
||||
connect(m_curveColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveSelectionColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_treeMargins, doubleSignal, doubleChanged);
|
||||
connect(m_playheadWidth, doubleSignal, doubleChanged);
|
||||
connect(m_playheadRadius, doubleSignal, doubleChanged);
|
||||
connect(m_playheadColor, &ColorControl::valueChanged, colorChanged);
|
||||
|
||||
auto *box = new QVBoxLayout;
|
||||
box->addLayout(createRow("Background Color", m_background));
|
||||
box->addLayout(createRow("Alternate Background Color", m_backgroundAlternate));
|
||||
box->addLayout(createRow("Font Color", m_fontColor));
|
||||
box->addLayout(createRow("Grid Color", m_gridColor));
|
||||
box->addLayout(createRow("Canvas Margin", m_canvasMargin));
|
||||
box->addLayout(createRow("Zoom In Width", m_zoomInWidth));
|
||||
box->addLayout(createRow("Zoom In Height", m_zoomInHeight));
|
||||
box->addLayout(createRow("Time Axis Height", m_timeAxisHeight));
|
||||
box->addLayout(createRow("Time Axis Left Offset", m_timeOffsetLeft));
|
||||
box->addLayout(createRow("Time Axis Right Offset", m_timeOffsetRight));
|
||||
box->addLayout(createRow("Range Bar Color", m_rangeBarColor));
|
||||
box->addLayout(createRow("Range Bar Caps Color", m_rangeBarCapsColor));
|
||||
box->addLayout(createRow("Value Axis Width", m_valueAxisWidth));
|
||||
box->addLayout(createRow("Value Axis Top Offset", m_valueOffsetTop));
|
||||
box->addLayout(createRow("Value Axis Bottom Offset", m_valueOffsetBottom));
|
||||
box->addLayout(createRow("Handle Size", m_handleSize));
|
||||
box->addLayout(createRow("Handle Line Width", m_handleLineWidth));
|
||||
box->addLayout(createRow("Handle Color", m_handleColor));
|
||||
box->addLayout(createRow("Handle Selection Color", m_handleSelectionColor));
|
||||
box->addLayout(createRow("Keyframe Size", m_keyframeSize));
|
||||
box->addLayout(createRow("Keyframe Color", m_keyframeColor));
|
||||
box->addLayout(createRow("Keyframe Selection Color", m_keyframeSelectionColor));
|
||||
box->addLayout(createRow("Curve Width", m_curveWidth));
|
||||
box->addLayout(createRow("Curve Color", m_curveColor));
|
||||
box->addLayout(createRow("Curve Selection Color", m_curveSelectionColor));
|
||||
box->addLayout(createRow("Treeview margins", m_treeMargins));
|
||||
box->addLayout(createRow("Playhead width", m_playheadWidth));
|
||||
box->addLayout(createRow("Playhead radius", m_playheadRadius));
|
||||
box->addLayout(createRow("Playhead color", m_playheadColor));
|
||||
|
||||
box->addWidget(m_printButton);
|
||||
setLayout(box);
|
||||
}
|
||||
|
||||
CurveEditorStyle CurveEditorStyleDialog::style() const
|
||||
{
|
||||
CurveEditorStyle style;
|
||||
style.backgroundBrush = QBrush(m_background->value());
|
||||
style.backgroundAlternateBrush = QBrush(m_backgroundAlternate->value());
|
||||
style.fontColor = m_fontColor->value();
|
||||
style.gridColor = m_gridColor->value();
|
||||
style.canvasMargin = m_canvasMargin->value();
|
||||
style.zoomInWidth = m_zoomInWidth->value();
|
||||
style.zoomInHeight = m_zoomInHeight->value();
|
||||
style.timeAxisHeight = m_timeAxisHeight->value();
|
||||
style.timeOffsetLeft = m_timeOffsetLeft->value();
|
||||
style.timeOffsetRight = m_timeOffsetRight->value();
|
||||
style.rangeBarColor = m_rangeBarColor->value();
|
||||
style.rangeBarCapsColor = m_rangeBarCapsColor->value();
|
||||
style.valueAxisWidth = m_valueAxisWidth->value();
|
||||
style.valueOffsetTop = m_valueOffsetTop->value();
|
||||
style.valueOffsetBottom = m_valueOffsetBottom->value();
|
||||
style.handleStyle.size = m_handleSize->value();
|
||||
style.handleStyle.lineWidth = m_handleLineWidth->value();
|
||||
style.handleStyle.color = m_handleColor->value();
|
||||
style.handleStyle.selectionColor = m_handleSelectionColor->value();
|
||||
style.keyframeStyle.size = m_keyframeSize->value();
|
||||
style.keyframeStyle.color = m_keyframeColor->value();
|
||||
style.keyframeStyle.selectionColor = m_keyframeSelectionColor->value();
|
||||
style.curveStyle.width = m_curveWidth->value();
|
||||
style.curveStyle.color = m_curveColor->value();
|
||||
style.curveStyle.selectionColor = m_curveSelectionColor->value();
|
||||
style.treeItemStyle.margins = m_treeMargins->value();
|
||||
style.playhead.width = m_playheadWidth->value();
|
||||
style.playhead.radius = m_playheadRadius->value();
|
||||
style.playhead.color = m_playheadColor->value();
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
void CurveEditorStyleDialog::emitStyleChanged()
|
||||
{
|
||||
emit styleChanged(style());
|
||||
}
|
||||
|
||||
void CurveEditorStyleDialog::printStyle()
|
||||
{
|
||||
auto toString = [](const QColor &color) {
|
||||
QString tmp
|
||||
= QString("QColor(%1, %2, %3)").arg(color.red()).arg(color.green()).arg(color.blue());
|
||||
return qPrintable(tmp);
|
||||
};
|
||||
|
||||
CurveEditorStyle s = style();
|
||||
qDebug() << "";
|
||||
qDebug().nospace() << "CurveEditorStyle out;";
|
||||
qDebug().nospace() << "out.backgroundBrush = QBrush(" << toString(s.backgroundBrush.color())
|
||||
<< ");";
|
||||
qDebug().nospace() << "out.backgroundAlternateBrush = QBrush("
|
||||
<< toString(s.backgroundAlternateBrush.color()) << ");";
|
||||
qDebug().nospace() << "out.fontColor = " << toString(s.fontColor) << ";";
|
||||
qDebug().nospace() << "out.gridColor = " << toString(s.gridColor) << ";";
|
||||
qDebug().nospace() << "out.canvasMargin = " << s.canvasMargin << ";";
|
||||
qDebug().nospace() << "out.zoomInWidth = " << s.zoomInWidth << ";";
|
||||
qDebug().nospace() << "out.zoomInHeight = " << s.zoomInHeight << ";";
|
||||
qDebug().nospace() << "out.timeAxisHeight = " << s.timeAxisHeight << ";";
|
||||
qDebug().nospace() << "out.timeOffsetLeft = " << s.timeOffsetLeft << ";";
|
||||
qDebug().nospace() << "out.timeOffsetRight = " << s.timeOffsetRight << ";";
|
||||
qDebug().nospace() << "out.rangeBarColor = " << toString(s.rangeBarColor) << ";";
|
||||
qDebug().nospace() << "out.rangeBarCapsColor = " << toString(s.rangeBarCapsColor) << ";";
|
||||
qDebug().nospace() << "out.valueAxisWidth = " << s.valueAxisWidth << ";";
|
||||
qDebug().nospace() << "out.valueOffsetTop = " << s.valueOffsetTop << ";";
|
||||
qDebug().nospace() << "out.valueOffsetBottom = " << s.valueOffsetBottom << ";";
|
||||
qDebug().nospace() << "out.handleStyle.size = " << s.handleStyle.size << ";";
|
||||
qDebug().nospace() << "out.handleStyle.lineWidth = " << s.handleStyle.lineWidth << ";";
|
||||
qDebug().nospace() << "out.handleStyle.color = " << toString(s.handleStyle.color) << ";";
|
||||
qDebug().nospace() << "out.handleStyle.selectionColor = "
|
||||
<< toString(s.handleStyle.selectionColor) << ";";
|
||||
qDebug().nospace() << "out.keyframeStyle.size = " << s.keyframeStyle.size << ";";
|
||||
qDebug().nospace() << "out.keyframeStyle.color = " << toString(s.keyframeStyle.color) << ";";
|
||||
qDebug().nospace() << "out.keyframeStyle.selectionColor = "
|
||||
<< toString(s.keyframeStyle.selectionColor) << ";";
|
||||
qDebug().nospace() << "out.curveStyle.width = " << s.curveStyle.width << ";";
|
||||
qDebug().nospace() << "out.curveStyle.color = " << toString(s.curveStyle.color) << ";";
|
||||
qDebug().nospace() << "out.curveStyle.selectionColor = "
|
||||
<< toString(s.curveStyle.selectionColor) << ";";
|
||||
qDebug().nospace() << "out.treeItemStyle.margins = " << s.treeItemStyle.margins << ";";
|
||||
qDebug().nospace() << "out.playheadStyle.width = " << s.playhead.width << ";";
|
||||
qDebug().nospace() << "out.playheadStyle.radius = " << s.playhead.radius << ";";
|
||||
qDebug().nospace() << "out.playheadStyle.color = " << toString(s.playhead.color) << ";";
|
||||
qDebug().nospace() << "return out;";
|
||||
qDebug() << "";
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,125 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QDialog>
|
||||
|
||||
class QPushButton;
|
||||
class QSpinBox;
|
||||
class QDoubleSpinBox;
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class ColorControl;
|
||||
|
||||
struct CurveEditorStyle;
|
||||
|
||||
class CurveEditorStyleDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void styleChanged(const CurveEditorStyle &style);
|
||||
|
||||
public:
|
||||
CurveEditorStyleDialog(CurveEditorStyle &style, QWidget *parent = nullptr);
|
||||
|
||||
CurveEditorStyle style() const;
|
||||
|
||||
private:
|
||||
void emitStyleChanged();
|
||||
|
||||
void printStyle();
|
||||
|
||||
private:
|
||||
QPushButton *m_printButton;
|
||||
|
||||
ColorControl *m_background;
|
||||
|
||||
ColorControl *m_backgroundAlternate;
|
||||
|
||||
ColorControl *m_fontColor;
|
||||
|
||||
ColorControl *m_gridColor;
|
||||
|
||||
QDoubleSpinBox *m_canvasMargin;
|
||||
|
||||
QSpinBox *m_zoomInWidth;
|
||||
|
||||
QSpinBox *m_zoomInHeight;
|
||||
|
||||
QDoubleSpinBox *m_timeAxisHeight;
|
||||
|
||||
QDoubleSpinBox *m_timeOffsetLeft;
|
||||
|
||||
QDoubleSpinBox *m_timeOffsetRight;
|
||||
|
||||
ColorControl *m_rangeBarColor;
|
||||
|
||||
ColorControl *m_rangeBarCapsColor;
|
||||
|
||||
QDoubleSpinBox *m_valueAxisWidth;
|
||||
|
||||
QDoubleSpinBox *m_valueOffsetTop;
|
||||
|
||||
QDoubleSpinBox *m_valueOffsetBottom;
|
||||
|
||||
// HandleItem
|
||||
QDoubleSpinBox *m_handleSize;
|
||||
|
||||
QDoubleSpinBox *m_handleLineWidth;
|
||||
|
||||
ColorControl *m_handleColor;
|
||||
|
||||
ColorControl *m_handleSelectionColor;
|
||||
|
||||
// KeyframeItem
|
||||
QDoubleSpinBox *m_keyframeSize;
|
||||
|
||||
ColorControl *m_keyframeColor;
|
||||
|
||||
ColorControl *m_keyframeSelectionColor;
|
||||
|
||||
// CurveItem
|
||||
QDoubleSpinBox *m_curveWidth;
|
||||
|
||||
ColorControl *m_curveColor;
|
||||
|
||||
ColorControl *m_curveSelectionColor;
|
||||
|
||||
// TreeItem
|
||||
QDoubleSpinBox *m_treeMargins;
|
||||
|
||||
// Playhead
|
||||
QDoubleSpinBox *m_playheadWidth;
|
||||
|
||||
QDoubleSpinBox *m_playheadRadius;
|
||||
|
||||
ColorControl *m_playheadColor;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,224 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveitem.h"
|
||||
#include "animationcurve.h"
|
||||
#include "graphicsscene.h"
|
||||
#include "keyframeitem.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
CurveItem::CurveItem(QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent)
|
||||
, m_id(0)
|
||||
, m_style()
|
||||
, m_transform()
|
||||
, m_keyframes()
|
||||
, m_underMouse(false)
|
||||
, m_itemDirty(false)
|
||||
, m_pathDirty(true)
|
||||
{}
|
||||
|
||||
CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent)
|
||||
, m_id(id)
|
||||
, m_style()
|
||||
, m_transform()
|
||||
, m_keyframes()
|
||||
, m_underMouse(false)
|
||||
, m_itemDirty(false)
|
||||
, m_pathDirty(true)
|
||||
{
|
||||
setAcceptHoverEvents(true);
|
||||
|
||||
setFlag(QGraphicsItem::ItemIsMovable, false);
|
||||
|
||||
auto emitCurveChanged = [this]() {
|
||||
m_itemDirty = true;
|
||||
m_pathDirty = true;
|
||||
update();
|
||||
};
|
||||
|
||||
for (auto frame : curve.keyframes()) {
|
||||
auto *item = new KeyframeItem(frame, this);
|
||||
QObject::connect(item, &KeyframeItem::redrawCurve, emitCurveChanged);
|
||||
m_keyframes.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
CurveItem::~CurveItem() {}
|
||||
|
||||
int CurveItem::type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
QRectF CurveItem::boundingRect() const
|
||||
{
|
||||
auto bbox = [](QRectF &bounds, const Keyframe &frame) {
|
||||
grow(bounds, frame.position());
|
||||
grow(bounds, frame.leftHandle());
|
||||
grow(bounds, frame.rightHandle());
|
||||
};
|
||||
|
||||
QRectF bounds;
|
||||
for (auto *item : m_keyframes)
|
||||
bbox(bounds, item->keyframe());
|
||||
|
||||
return m_transform.mapRect(bounds);
|
||||
}
|
||||
|
||||
bool CurveItem::contains(const QPointF &point) const
|
||||
{
|
||||
bool valid = false;
|
||||
QPointF transformed(m_transform.inverted(&valid).map(point));
|
||||
|
||||
double width = abs(20.0 / scaleY(m_transform));
|
||||
|
||||
if (valid)
|
||||
return curve().intersects(transformed, width);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CurveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
|
||||
{
|
||||
if (m_keyframes.size() > 1) {
|
||||
QPen pen = painter->pen();
|
||||
QColor col = m_underMouse ? Qt::red : m_style.color;
|
||||
|
||||
pen.setWidthF(m_style.width);
|
||||
pen.setColor(hasSelection() ? m_style.selectionColor : col);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
painter->drawPath(path());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
bool CurveItem::isDirty() const
|
||||
{
|
||||
return m_itemDirty;
|
||||
}
|
||||
|
||||
bool CurveItem::hasSelection() const
|
||||
{
|
||||
for (auto *frame : m_keyframes) {
|
||||
if (frame->selected())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int CurveItem::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
QPainterPath CurveItem::path() const
|
||||
{
|
||||
if (m_pathDirty) {
|
||||
Keyframe previous = m_keyframes.front()->keyframe();
|
||||
Keyframe current;
|
||||
|
||||
m_path = QPainterPath(m_transform.map(previous.position()));
|
||||
for (size_t i = 1; i < m_keyframes.size(); ++i) {
|
||||
current = m_keyframes[i]->keyframe();
|
||||
|
||||
if (previous.rightHandle().isNull() || current.leftHandle().isNull()) {
|
||||
m_path.lineTo(m_transform.map(current.position()));
|
||||
} else {
|
||||
m_path.cubicTo(
|
||||
m_transform.map(previous.rightHandle()),
|
||||
m_transform.map(current.leftHandle()),
|
||||
m_transform.map(current.position()));
|
||||
}
|
||||
|
||||
previous = current;
|
||||
}
|
||||
m_pathDirty = false;
|
||||
}
|
||||
|
||||
return m_path;
|
||||
}
|
||||
|
||||
AnimationCurve CurveItem::curve() const
|
||||
{
|
||||
std::vector<Keyframe> out;
|
||||
out.reserve(m_keyframes.size());
|
||||
for (auto item : m_keyframes)
|
||||
out.push_back(item->keyframe());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void CurveItem::setDirty(bool dirty)
|
||||
{
|
||||
m_itemDirty = dirty;
|
||||
}
|
||||
|
||||
QRectF CurveItem::setComponentTransform(const QTransform &transform)
|
||||
{
|
||||
m_pathDirty = true;
|
||||
|
||||
prepareGeometryChange();
|
||||
m_transform = transform;
|
||||
for (auto frame : m_keyframes)
|
||||
frame->setComponentTransform(transform);
|
||||
|
||||
return boundingRect();
|
||||
}
|
||||
|
||||
void CurveItem::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
m_style = style.curveStyle;
|
||||
|
||||
for (auto *frame : m_keyframes)
|
||||
frame->setStyle(style);
|
||||
}
|
||||
|
||||
void CurveItem::connect(GraphicsScene *scene)
|
||||
{
|
||||
for (auto *frame : m_keyframes) {
|
||||
QObject::connect(frame, &KeyframeItem::keyframeMoved, scene, &GraphicsScene::keyframeMoved);
|
||||
QObject::connect(frame, &KeyframeItem::handleMoved, scene, &GraphicsScene::handleMoved);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveItem::setIsUnderMouse(bool under)
|
||||
{
|
||||
if (under != m_underMouse) {
|
||||
m_underMouse = under;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyle.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class AnimationCurve;
|
||||
class KeyframeItem;
|
||||
class GraphicsScene;
|
||||
|
||||
class CurveItem : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CurveItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem *parent = nullptr);
|
||||
|
||||
~CurveItem() override;
|
||||
|
||||
enum { Type = ItemTypeCurve };
|
||||
|
||||
int type() const override;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
bool contains(const QPointF &point) const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
bool isDirty() const;
|
||||
|
||||
bool hasSelection() const;
|
||||
|
||||
unsigned int id() const;
|
||||
|
||||
AnimationCurve curve() const;
|
||||
|
||||
void setDirty(bool dirty);
|
||||
|
||||
QRectF setComponentTransform(const QTransform &transform);
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
void connect(GraphicsScene *scene);
|
||||
|
||||
void setIsUnderMouse(bool under);
|
||||
|
||||
private:
|
||||
QPainterPath path() const;
|
||||
|
||||
unsigned int m_id;
|
||||
|
||||
CurveItemStyleOption m_style;
|
||||
|
||||
QTransform m_transform;
|
||||
|
||||
std::vector<KeyframeItem *> m_keyframes;
|
||||
|
||||
bool m_underMouse;
|
||||
|
||||
bool m_itemDirty;
|
||||
|
||||
mutable bool m_pathDirty;
|
||||
|
||||
mutable QPainterPath m_path;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,277 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curvesegment.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <qmath.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class CubicPolynomial
|
||||
{
|
||||
public:
|
||||
CubicPolynomial(double p0, double p1, double p2, double p3);
|
||||
|
||||
std::vector<double> extrema() const;
|
||||
|
||||
std::vector<double> roots() const;
|
||||
|
||||
private:
|
||||
double m_a;
|
||||
double m_b;
|
||||
double m_c;
|
||||
double m_d;
|
||||
};
|
||||
|
||||
CubicPolynomial::CubicPolynomial(double p0, double p1, double p2, double p3)
|
||||
: m_a(p3 - 3.0 * p2 + 3.0 * p1 - p0)
|
||||
, m_b(3.0 * p2 - 6.0 * p1 + 3.0 * p0)
|
||||
, m_c(3.0 * p1 - 3.0 * p0)
|
||||
, m_d(p0)
|
||||
{}
|
||||
|
||||
std::vector<double> CubicPolynomial::extrema() const
|
||||
{
|
||||
std::vector<double> out;
|
||||
|
||||
auto addValidValue = [&out](double value) {
|
||||
if (!std::isnan(value) && !std::isinf(value))
|
||||
out.push_back(clamp(value, 0.0, 1.0));
|
||||
};
|
||||
|
||||
// Find the roots of the first derivative of y.
|
||||
auto pd2 = (2.0 * m_b) / (3.0 * m_a) / 2.0;
|
||||
auto q = m_c / (3.0 * m_a);
|
||||
|
||||
auto radi = std::pow(pd2, 2.0) - q;
|
||||
|
||||
auto x1 = -pd2 + std::sqrt(radi);
|
||||
auto x2 = -pd2 - std::sqrt(radi);
|
||||
|
||||
addValidValue(x1);
|
||||
addValidValue(x2);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<double> CubicPolynomial::roots() const
|
||||
{
|
||||
std::vector<double> out;
|
||||
|
||||
auto addValidValue = [&out](double value) {
|
||||
if (!(std::isnan(value) || std::isinf(value)))
|
||||
out.push_back(value);
|
||||
};
|
||||
|
||||
if (m_a == 0.0) {
|
||||
// Linear
|
||||
if (m_b == 0.0) {
|
||||
if (m_c != 0.0)
|
||||
out.push_back(-m_d / m_c);
|
||||
// Quadratic
|
||||
} else {
|
||||
const double p = m_c / m_b / 2.0;
|
||||
const double q = m_d / m_b;
|
||||
addValidValue(-p + std::sqrt(std::pow(p, 2.0) - q));
|
||||
addValidValue(-p - std::sqrt(std::pow(p, 2.0) - q));
|
||||
}
|
||||
// Cubic
|
||||
} else {
|
||||
const double p = 3.0 * m_a * m_c - std::pow(m_b, 2.0);
|
||||
const double q = 2.0 * std::pow(m_b, 3.0) - 9.0 * m_a * m_b * m_c
|
||||
+ 27.0 * std::pow(m_a, 2.0) * m_d;
|
||||
|
||||
auto disc = std::pow(q, 2.0) + 4.0 * std::pow(p, 3.0);
|
||||
|
||||
auto toX = [&](double y) { return (y - m_b) / (3.0 * m_a); };
|
||||
|
||||
// One real solution.
|
||||
if (disc >= 0) {
|
||||
auto u = (1.0 / 2.0)
|
||||
* std::cbrt(-4.0 * q
|
||||
+ 4.0 * std::sqrt(std::pow(q, 2.0) + 4.0 * std::pow(p, 3.0)));
|
||||
auto v = (1.0 / 2.0)
|
||||
* std::cbrt(-4.0 * q
|
||||
- 4.0 * std::sqrt(std::pow(q, 2.0) + 4.0 * std::pow(p, 3.0)));
|
||||
|
||||
addValidValue(toX(u + v));
|
||||
// Three real solutions.
|
||||
} else {
|
||||
auto phi = acos(-q / (2 * std::sqrt(-std::pow(p, 3.0))));
|
||||
auto y1 = std::sqrt(-p) * 2.0 * cos(phi / 3.0);
|
||||
auto y2 = std::sqrt(-p) * 2.0 * cos((phi / 3.0) + (2.0 * M_PI / 3.0));
|
||||
auto y3 = std::sqrt(-p) * 2.0 * cos((phi / 3.0) + (4.0 * M_PI / 3.0));
|
||||
|
||||
addValidValue(toX(y1));
|
||||
addValidValue(toX(y2));
|
||||
addValidValue(toX(y3));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
CurveSegment::CurveSegment()
|
||||
: m_left()
|
||||
, m_right()
|
||||
{}
|
||||
|
||||
CurveSegment::CurveSegment(const Keyframe &left, const Keyframe &right)
|
||||
: m_left(left)
|
||||
, m_right(right)
|
||||
{}
|
||||
|
||||
bool CurveSegment::containsX(double x) const
|
||||
{
|
||||
return m_left.position().x() <= x && m_right.position().x() >= x;
|
||||
}
|
||||
|
||||
double evaluateForT(double t, double p0, double p1, double p2, double p3)
|
||||
{
|
||||
assert(t >= 0. && t <= 1.);
|
||||
|
||||
const double it = 1.0 - t;
|
||||
|
||||
return p0 * std::pow(it, 3.0) + p1 * 3.0 * std::pow(it, 2.0) * t
|
||||
+ p2 * 3.0 * it * std::pow(t, 2.0) + p3 * std::pow(t, 3.0);
|
||||
}
|
||||
|
||||
QPointF CurveSegment::evaluate(double t) const
|
||||
{
|
||||
const double x = evaluateForT(
|
||||
t,
|
||||
m_left.position().x(),
|
||||
m_left.rightHandle().x(),
|
||||
m_right.leftHandle().x(),
|
||||
m_right.position().x());
|
||||
|
||||
const double y = evaluateForT(
|
||||
t,
|
||||
m_left.position().y(),
|
||||
m_left.rightHandle().y(),
|
||||
m_right.leftHandle().y(),
|
||||
m_right.position().y());
|
||||
|
||||
return QPointF(x, y);
|
||||
}
|
||||
|
||||
std::vector<QPointF> CurveSegment::extrema() const
|
||||
{
|
||||
std::vector<QPointF> out;
|
||||
|
||||
auto polynomial = CubicPolynomial(
|
||||
m_left.position().y(),
|
||||
m_left.rightHandle().y(),
|
||||
m_right.leftHandle().y(),
|
||||
m_right.position().y());
|
||||
|
||||
for (double t : polynomial.extrema()) {
|
||||
|
||||
const double x = evaluateForT(
|
||||
t,
|
||||
m_left.position().x(),
|
||||
m_left.rightHandle().x(),
|
||||
m_right.leftHandle().x(),
|
||||
m_right.position().x());
|
||||
|
||||
const double y = evaluateForT(
|
||||
t,
|
||||
m_left.position().y(),
|
||||
m_left.rightHandle().y(),
|
||||
m_right.leftHandle().y(),
|
||||
m_right.position().y());
|
||||
|
||||
out.push_back(QPointF(x, y));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<double> CurveSegment::yForX(double x) const
|
||||
{
|
||||
std::vector<double> out;
|
||||
|
||||
auto polynomial = CubicPolynomial(
|
||||
m_left.position().x() - x,
|
||||
m_left.rightHandle().x() - x,
|
||||
m_right.leftHandle().x() - x,
|
||||
m_right.position().x() - x);
|
||||
|
||||
for (double t : polynomial.roots()) {
|
||||
if (t < 0.0 || t > 1.0)
|
||||
continue;
|
||||
|
||||
const double y = evaluateForT(
|
||||
t,
|
||||
m_left.position().y(),
|
||||
m_left.rightHandle().y(),
|
||||
m_right.leftHandle().y(),
|
||||
m_right.position().y());
|
||||
|
||||
out.push_back(y);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<double> CurveSegment::xForY(double y) const
|
||||
{
|
||||
std::vector<double> out;
|
||||
|
||||
auto polynomial = CubicPolynomial(
|
||||
m_left.position().y() - y,
|
||||
m_left.rightHandle().y() - y,
|
||||
m_right.leftHandle().y() - y,
|
||||
m_right.position().y() - y);
|
||||
|
||||
for (double t : polynomial.roots()) {
|
||||
if (t < 0.0 || t > 1.0)
|
||||
continue;
|
||||
|
||||
const double x = evaluateForT(
|
||||
t,
|
||||
m_left.position().x(),
|
||||
m_left.rightHandle().x(),
|
||||
m_right.leftHandle().x(),
|
||||
m_right.position().x());
|
||||
|
||||
out.push_back(x);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void CurveSegment::setLeft(const Keyframe &frame)
|
||||
{
|
||||
m_left = frame;
|
||||
}
|
||||
|
||||
void CurveSegment::setRight(const Keyframe &frame)
|
||||
{
|
||||
m_right = frame;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -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 "keyframe.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class QPointF;
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class CurveSegment
|
||||
{
|
||||
public:
|
||||
CurveSegment();
|
||||
|
||||
CurveSegment(const Keyframe &first, const Keyframe &last);
|
||||
|
||||
bool containsX(double x) const;
|
||||
|
||||
QPointF evaluate(double t) const;
|
||||
|
||||
std::vector<QPointF> extrema() const;
|
||||
|
||||
std::vector<double> yForX(double x) const;
|
||||
|
||||
std::vector<double> xForY(double y) const;
|
||||
|
||||
void setLeft(const Keyframe &frame);
|
||||
|
||||
void setRight(const Keyframe &frame);
|
||||
|
||||
private:
|
||||
Keyframe m_left;
|
||||
|
||||
Keyframe m_right;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,225 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "graphicsscene.h"
|
||||
#include "animationcurve.h"
|
||||
#include "curveitem.h"
|
||||
#include "graphicsview.h"
|
||||
#include "handleitem.h"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
GraphicsScene::GraphicsScene(QObject *parent)
|
||||
: QGraphicsScene(parent)
|
||||
, m_dirty(true)
|
||||
, m_limits()
|
||||
{}
|
||||
|
||||
bool GraphicsScene::empty() const
|
||||
{
|
||||
return items().empty();
|
||||
}
|
||||
|
||||
double GraphicsScene::minimumTime() const
|
||||
{
|
||||
return limits().left();
|
||||
}
|
||||
|
||||
double GraphicsScene::maximumTime() const
|
||||
{
|
||||
return limits().right();
|
||||
}
|
||||
|
||||
double GraphicsScene::minimumValue() const
|
||||
{
|
||||
return limits().bottom();
|
||||
}
|
||||
|
||||
double GraphicsScene::maximumValue() const
|
||||
{
|
||||
return limits().top();
|
||||
}
|
||||
|
||||
void GraphicsScene::addCurveItem(CurveItem *item)
|
||||
{
|
||||
m_dirty = true;
|
||||
addItem(item);
|
||||
item->connect(this);
|
||||
}
|
||||
|
||||
void GraphicsScene::setComponentTransform(const QTransform &transform)
|
||||
{
|
||||
QRectF bounds;
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item))
|
||||
bounds = bounds.united(curveItem->setComponentTransform(transform));
|
||||
}
|
||||
|
||||
if (bounds.isNull()) {
|
||||
if (GraphicsView *gview = graphicsView())
|
||||
bounds = gview->defaultRasterRect();
|
||||
}
|
||||
|
||||
if (bounds.isValid())
|
||||
setSceneRect(bounds);
|
||||
}
|
||||
|
||||
void GraphicsScene::keyframeMoved(KeyframeItem *movedItem, const QPointF &direction)
|
||||
{
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (item == movedItem)
|
||||
continue;
|
||||
|
||||
if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
if (frameItem->selected())
|
||||
frameItem->moveKeyframe(direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsScene::handleMoved(KeyframeItem *frame,
|
||||
HandleSlot handle,
|
||||
double angle,
|
||||
double deltaLength)
|
||||
{
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (item == frame)
|
||||
continue;
|
||||
|
||||
if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
if (frameItem->selected())
|
||||
frameItem->moveHandle(handle, angle, deltaLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
QGraphicsScene::mouseMoveEvent(mouseEvent);
|
||||
|
||||
if (hasActiveItem())
|
||||
return;
|
||||
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item))
|
||||
curveItem->setIsUnderMouse(curveItem->contains(mouseEvent->scenePos()));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
||||
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) {
|
||||
if (curveItem->contains(mouseEvent->scenePos()))
|
||||
curveItem->setSelected(true);
|
||||
|
||||
if (curveItem->isDirty()) {
|
||||
emit curveChanged(curveItem->id(), curveItem->curve());
|
||||
curveItem->setDirty(false);
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GraphicsScene::hasActiveKeyframe() const
|
||||
{
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *kitem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
if (kitem->activated())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GraphicsScene::hasActiveHandle() const
|
||||
{
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *hitem = qgraphicsitem_cast<HandleItem *>(item)) {
|
||||
if (hitem->activated())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GraphicsScene::hasActiveItem() const
|
||||
{
|
||||
return hasActiveKeyframe() || hasActiveHandle();
|
||||
}
|
||||
|
||||
GraphicsView *GraphicsScene::graphicsView() const
|
||||
{
|
||||
const QList<QGraphicsView *> viewList = views();
|
||||
for (auto &&view : viewList) {
|
||||
if (GraphicsView *gview = qobject_cast<GraphicsView *>(view))
|
||||
return gview;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QRectF GraphicsScene::limits() const
|
||||
{
|
||||
if (m_dirty) {
|
||||
QPointF min(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
|
||||
QPointF max(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
|
||||
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item)) {
|
||||
auto curve = curveItem->curve();
|
||||
if (min.x() > curve.minimumTime())
|
||||
min.rx() = curve.minimumTime();
|
||||
|
||||
if (min.y() > curve.minimumValue())
|
||||
min.ry() = curve.minimumValue();
|
||||
|
||||
if (max.x() < curve.maximumTime())
|
||||
max.rx() = curve.maximumTime();
|
||||
|
||||
if (max.y() < curve.maximumValue())
|
||||
max.ry() = curve.maximumValue();
|
||||
}
|
||||
}
|
||||
|
||||
m_limits = QRectF(QPointF(min.x(), max.y()), QPointF(max.x(), min.y()));
|
||||
m_dirty = false;
|
||||
}
|
||||
return m_limits;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "keyframeitem.h"
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class AnimationCurve;
|
||||
class CurveItem;
|
||||
class GraphicsView;
|
||||
|
||||
class GraphicsScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void curveChanged(unsigned int id, const AnimationCurve &curve);
|
||||
|
||||
public:
|
||||
GraphicsScene(QObject *parent = nullptr);
|
||||
|
||||
bool empty() const;
|
||||
|
||||
bool hasActiveKeyframe() const;
|
||||
|
||||
bool hasActiveHandle() const;
|
||||
|
||||
bool hasActiveItem() const;
|
||||
|
||||
double minimumTime() const;
|
||||
|
||||
double maximumTime() const;
|
||||
|
||||
double minimumValue() const;
|
||||
|
||||
double maximumValue() const;
|
||||
|
||||
void addCurveItem(CurveItem *item);
|
||||
|
||||
void setComponentTransform(const QTransform &transform);
|
||||
|
||||
void keyframeMoved(KeyframeItem *item, const QPointF &direction);
|
||||
|
||||
void handleMoved(KeyframeItem *frame, HandleSlot handle, double angle, double deltaLength);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
|
||||
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
|
||||
|
||||
private:
|
||||
using QGraphicsScene::addItem;
|
||||
|
||||
GraphicsView *graphicsView() const;
|
||||
|
||||
QRectF limits() const;
|
||||
|
||||
mutable bool m_dirty;
|
||||
|
||||
mutable QRectF m_limits;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,523 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "graphicsview.h"
|
||||
#include "curveeditormodel.h"
|
||||
#include "curveitem.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||
: QGraphicsView(parent)
|
||||
, m_zoomX(0.0)
|
||||
, m_zoomY(0.0)
|
||||
, m_transform()
|
||||
, m_scene()
|
||||
, m_model(model)
|
||||
, m_playhead(this)
|
||||
, m_selector()
|
||||
, m_style(model->style())
|
||||
, m_dialog(m_style)
|
||||
{
|
||||
model->setGraphicsView(this);
|
||||
|
||||
setScene(&m_scene);
|
||||
setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||
setResizeAnchor(QGraphicsView::NoAnchor);
|
||||
setTransformationAnchor(QGraphicsView::NoAnchor);
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
||||
|
||||
connect(&m_dialog, &CurveEditorStyleDialog::styleChanged, this, &GraphicsView::setStyle);
|
||||
|
||||
auto itemSlot = [this](unsigned int id, const AnimationCurve &curve) {
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
m_model->setCurve(id, curve);
|
||||
};
|
||||
|
||||
connect(&m_scene, &GraphicsScene::curveChanged, itemSlot);
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
update();
|
||||
}
|
||||
|
||||
CurveEditorModel *GraphicsView::model() const
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
CurveEditorStyle GraphicsView::editorStyle() const
|
||||
{
|
||||
return m_style;
|
||||
}
|
||||
|
||||
bool GraphicsView::hasActiveItem() const
|
||||
{
|
||||
return m_scene.hasActiveItem();
|
||||
}
|
||||
|
||||
bool GraphicsView::hasActiveHandle() const
|
||||
{
|
||||
return m_scene.hasActiveHandle();
|
||||
}
|
||||
|
||||
double GraphicsView::minimumTime() const
|
||||
{
|
||||
bool check = m_model->minimumTime() < m_scene.minimumTime();
|
||||
return check ? m_model->minimumTime() : m_scene.minimumTime();
|
||||
}
|
||||
|
||||
double GraphicsView::maximumTime() const
|
||||
{
|
||||
bool check = m_model->maximumTime() > m_scene.maximumTime();
|
||||
return check ? m_model->maximumTime() : m_scene.maximumTime();
|
||||
}
|
||||
|
||||
double GraphicsView::minimumValue() const
|
||||
{
|
||||
return m_scene.empty() ? -1.0 : m_scene.minimumValue();
|
||||
}
|
||||
|
||||
double GraphicsView::maximumValue() const
|
||||
{
|
||||
return m_scene.empty() ? 1.0 : m_scene.maximumValue();
|
||||
}
|
||||
|
||||
double GraphicsView::zoomX() const
|
||||
{
|
||||
return m_zoomX;
|
||||
}
|
||||
|
||||
double GraphicsView::zoomY() const
|
||||
{
|
||||
return m_zoomY;
|
||||
}
|
||||
|
||||
QRectF GraphicsView::canvasRect() const
|
||||
{
|
||||
QRect r = viewport()->rect().adjusted(
|
||||
m_style.valueAxisWidth + m_style.canvasMargin,
|
||||
m_style.timeAxisHeight + m_style.canvasMargin,
|
||||
-m_style.canvasMargin,
|
||||
-m_style.canvasMargin);
|
||||
|
||||
return mapToScene(r).boundingRect();
|
||||
}
|
||||
|
||||
QRectF GraphicsView::timeScaleRect() const
|
||||
{
|
||||
QRect vp(viewport()->rect());
|
||||
QPoint tl = vp.topLeft() + QPoint(m_style.valueAxisWidth, 0);
|
||||
QPoint br = vp.topRight() + QPoint(0, m_style.timeAxisHeight);
|
||||
return mapToScene(QRect(tl, br)).boundingRect();
|
||||
}
|
||||
|
||||
QRectF GraphicsView::valueScaleRect() const
|
||||
{
|
||||
QRect vp(viewport()->rect());
|
||||
QPoint tl = vp.topLeft() + QPoint(0, m_style.timeAxisHeight);
|
||||
QPoint br = vp.bottomLeft() + QPoint(m_style.valueAxisWidth, 0);
|
||||
return mapToScene(QRect(tl, br)).boundingRect();
|
||||
}
|
||||
|
||||
QRectF GraphicsView::defaultRasterRect() const
|
||||
{
|
||||
QPointF topLeft(mapTimeToX(minimumTime()), mapValueToY(maximumValue()));
|
||||
QPointF bottomRight(mapTimeToX(maximumTime()), mapValueToY(minimumValue()));
|
||||
return QRectF(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
void GraphicsView::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
m_style = style;
|
||||
|
||||
const auto itemList = items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(item))
|
||||
curveItem->setStyle(style);
|
||||
}
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::setZoomX(double zoom, const QPoint &pivot)
|
||||
{
|
||||
applyZoom(zoom, m_zoomY, pivot);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::setZoomY(double zoom, const QPoint &pivot)
|
||||
{
|
||||
applyZoom(m_zoomX, zoom, pivot);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::setCurrentFrame(int frame)
|
||||
{
|
||||
int clampedFrame = clamp(frame, m_model->minimumTime(), m_model->maximumTime());
|
||||
m_playhead.moveToFrame(clampedFrame, this);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::scrollContent(double x, double y)
|
||||
{
|
||||
QScrollBar *hs = horizontalScrollBar();
|
||||
QScrollBar *vs = verticalScrollBar();
|
||||
hs->setValue(hs->value() + x);
|
||||
vs->setValue(vs->value() + y);
|
||||
}
|
||||
|
||||
void GraphicsView::reset(const std::vector<CurveItem *> &items)
|
||||
{
|
||||
m_scene.clear();
|
||||
for (auto *item : items)
|
||||
m_scene.addCurveItem(item);
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QGraphicsView::resizeEvent(event);
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
}
|
||||
|
||||
void GraphicsView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
Shortcut shortcut(event->modifiers(), static_cast<Qt::Key>(event->key()));
|
||||
if (shortcut == m_style.shortcuts.frameAll)
|
||||
applyZoom(0.0, 0.0);
|
||||
}
|
||||
|
||||
void GraphicsView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_playhead.mousePress(globalToScene(event->globalPos())))
|
||||
return;
|
||||
|
||||
Shortcut shortcut(event);
|
||||
if (shortcut == Shortcut(Qt::LeftButton)) {
|
||||
QPointF pos = mapToScene(event->pos());
|
||||
if (timeScaleRect().contains(pos)) {
|
||||
setCurrentFrame(std::round(mapXtoTime(pos.x())));
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
|
||||
m_selector.mousePress(event, this);
|
||||
}
|
||||
|
||||
void GraphicsView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_playhead.mouseMove(globalToScene(event->globalPos()), this))
|
||||
return;
|
||||
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
|
||||
m_selector.mouseMove(event, this, m_playhead);
|
||||
}
|
||||
|
||||
void GraphicsView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
|
||||
m_playhead.mouseRelease(this);
|
||||
m_selector.mouseRelease(event, this);
|
||||
this->viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (event->modifiers().testFlag(Qt::AltModifier))
|
||||
return;
|
||||
|
||||
QGraphicsView::wheelEvent(event);
|
||||
}
|
||||
|
||||
void GraphicsView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
if (event->modifiers() != Qt::NoModifier)
|
||||
return;
|
||||
|
||||
auto openStyleEditor = [this]() { m_dialog.show(); };
|
||||
|
||||
QMenu menu;
|
||||
QAction *openEditorAction = menu.addAction(tr("Open Style Editor"));
|
||||
connect(openEditorAction, &QAction::triggered, openStyleEditor);
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
QRectF abscissa = timeScaleRect();
|
||||
if (abscissa.isValid())
|
||||
drawTimeScale(painter, abscissa);
|
||||
|
||||
auto ordinate = valueScaleRect();
|
||||
if (ordinate.isValid())
|
||||
drawValueScale(painter, ordinate);
|
||||
|
||||
m_playhead.paint(painter, this);
|
||||
|
||||
painter->fillRect(QRectF(rect.topLeft(), abscissa.bottomLeft()),
|
||||
m_style.backgroundAlternateBrush);
|
||||
|
||||
m_selector.paint(painter);
|
||||
}
|
||||
|
||||
void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->fillRect(rect, m_style.backgroundBrush);
|
||||
painter->fillRect(scene()->sceneRect(), m_style.backgroundAlternateBrush);
|
||||
|
||||
drawGrid(painter, rect);
|
||||
drawExtremaX(painter, rect);
|
||||
drawExtremaY(painter, rect);
|
||||
}
|
||||
|
||||
int GraphicsView::mapTimeToX(double time) const
|
||||
{
|
||||
return std::round(time * scaleX(m_transform));
|
||||
}
|
||||
|
||||
int GraphicsView::mapValueToY(double y) const
|
||||
{
|
||||
return std::round(y * scaleY(m_transform));
|
||||
}
|
||||
|
||||
double GraphicsView::mapXtoTime(int x) const
|
||||
{
|
||||
return static_cast<double>(x) / scaleX(m_transform);
|
||||
}
|
||||
|
||||
double GraphicsView::mapYtoValue(int y) const
|
||||
{
|
||||
return static_cast<double>(y) / scaleY(m_transform);
|
||||
}
|
||||
|
||||
QPointF GraphicsView::globalToScene(const QPoint &point) const
|
||||
{
|
||||
return mapToScene(viewport()->mapFromGlobal(point));
|
||||
}
|
||||
|
||||
QPointF GraphicsView::globalToRaster(const QPoint &point) const
|
||||
{
|
||||
QPointF scene = globalToScene(point);
|
||||
return QPointF(mapXtoTime(scene.x()), mapYtoValue(scene.y()));
|
||||
}
|
||||
|
||||
void GraphicsView::applyZoom(double x, double y, const QPoint &pivot)
|
||||
{
|
||||
QPointF pivotRaster(globalToRaster(pivot));
|
||||
|
||||
m_zoomX = clamp(x, 0.0, 1.0);
|
||||
m_zoomY = clamp(y, 0.0, 1.0);
|
||||
|
||||
double minTime = minimumTime();
|
||||
double maxTime = maximumTime();
|
||||
|
||||
double minValue = minimumValue();
|
||||
double maxValue = maximumValue();
|
||||
|
||||
QRectF canvas = canvasRect();
|
||||
|
||||
double xZoomedOut = canvas.width() / (maxTime - minTime);
|
||||
double xZoomedIn = m_style.zoomInWidth;
|
||||
double scaleX = lerp(clamp(m_zoomX, 0.0, 1.0), xZoomedOut, xZoomedIn);
|
||||
|
||||
double yZoomedOut = canvas.height() / (maxValue - minValue);
|
||||
double yZoomedIn = m_style.zoomInHeight;
|
||||
double scaleY = lerp(clamp(m_zoomY, 0.0, 1.0), -yZoomedOut, -yZoomedIn);
|
||||
|
||||
m_transform = QTransform::fromScale(scaleX, scaleY);
|
||||
|
||||
m_scene.setComponentTransform(m_transform);
|
||||
|
||||
QRectF sr = m_scene.sceneRect().adjusted(
|
||||
-m_style.valueAxisWidth - m_style.canvasMargin,
|
||||
-m_style.timeAxisHeight - m_style.canvasMargin,
|
||||
m_style.canvasMargin,
|
||||
m_style.canvasMargin);
|
||||
|
||||
setSceneRect(sr);
|
||||
|
||||
m_playhead.resize(this);
|
||||
|
||||
if (!pivot.isNull()) {
|
||||
QPointF deltaTransformed = pivotRaster - globalToRaster(pivot);
|
||||
scrollContent(mapTimeToX(deltaTransformed.x()), mapValueToY(deltaTransformed.y()));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
QRectF gridRect = rect.adjusted(
|
||||
m_style.valueAxisWidth + m_style.canvasMargin,
|
||||
m_style.timeAxisHeight + m_style.canvasMargin,
|
||||
-m_style.canvasMargin,
|
||||
-m_style.canvasMargin);
|
||||
|
||||
if (!gridRect.isValid())
|
||||
return;
|
||||
|
||||
auto drawVerticalLine = [painter, gridRect](double position) {
|
||||
painter->drawLine(position, gridRect.top(), position, gridRect.bottom());
|
||||
};
|
||||
|
||||
painter->save();
|
||||
painter->setPen(m_style.gridColor);
|
||||
|
||||
double timeIncrement = timeLabelInterval(painter, m_model->maximumTime());
|
||||
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
|
||||
drawVerticalLine(mapTimeToX(i));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraphicsView::drawExtremaX(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
auto drawVerticalLine = [rect, painter](double position) {
|
||||
painter->drawLine(position, rect.top(), position, rect.bottom());
|
||||
};
|
||||
|
||||
painter->save();
|
||||
painter->setPen(Qt::red);
|
||||
drawVerticalLine(mapTimeToX(m_model->minimumTime()));
|
||||
drawVerticalLine(mapTimeToX(m_model->maximumTime()));
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraphicsView::drawExtremaY(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
if (m_scene.empty())
|
||||
return;
|
||||
|
||||
auto drawHorizontalLine = [rect, painter](double position) {
|
||||
painter->drawLine(rect.left(), position, rect.right(), position);
|
||||
};
|
||||
|
||||
painter->save();
|
||||
painter->setPen(Qt::blue);
|
||||
drawHorizontalLine(mapValueToY(m_scene.minimumValue()));
|
||||
drawHorizontalLine(mapValueToY(m_scene.maximumValue()));
|
||||
|
||||
drawHorizontalLine(mapValueToY(0.0));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraphicsView::drawTimeScale(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(m_style.fontColor);
|
||||
painter->fillRect(rect, m_style.backgroundAlternateBrush);
|
||||
|
||||
QFontMetrics fm(painter->font());
|
||||
|
||||
auto paintLabeledTick = [this, painter, rect, fm](double time) {
|
||||
QString timeText = QString("%1").arg(time);
|
||||
|
||||
int position = mapTimeToX(time);
|
||||
|
||||
QRect textRect = fm.boundingRect(timeText);
|
||||
textRect.moveCenter(QPoint(position, rect.center().y()));
|
||||
|
||||
painter->drawText(textRect, Qt::AlignCenter, timeText);
|
||||
painter->drawLine(position, rect.bottom() - 2, position, textRect.bottom() + 2);
|
||||
};
|
||||
|
||||
double timeIncrement = timeLabelInterval(painter, maximumTime());
|
||||
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
|
||||
paintLabeledTick(i);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GraphicsView::drawValueScale(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(m_style.fontColor);
|
||||
painter->fillRect(rect, m_style.backgroundAlternateBrush);
|
||||
|
||||
QFontMetrics fm(painter->font());
|
||||
auto paintLabeledTick = [this, painter, rect, fm](double value) {
|
||||
QString valueText = QString("%1").arg(value);
|
||||
|
||||
int position = mapValueToY(value);
|
||||
|
||||
QRect textRect = fm.boundingRect(valueText);
|
||||
textRect.moveCenter(QPoint(rect.center().x(), position));
|
||||
painter->drawText(textRect, Qt::AlignCenter, valueText);
|
||||
};
|
||||
|
||||
paintLabeledTick(minimumValue());
|
||||
paintLabeledTick(maximumValue());
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime)
|
||||
{
|
||||
QFontMetrics fm(painter->font());
|
||||
int minTextSpacing = fm.width(QString("X%1X").arg(maxTime));
|
||||
|
||||
int deltaTime = 1;
|
||||
int nextFactor = 5;
|
||||
|
||||
double tickDistance = mapTimeToX(deltaTime);
|
||||
|
||||
while (true) {
|
||||
if (tickDistance == 0 && deltaTime > maxTime)
|
||||
return maxTime;
|
||||
|
||||
if (tickDistance > minTextSpacing)
|
||||
break;
|
||||
|
||||
deltaTime *= nextFactor;
|
||||
tickDistance = mapTimeToX(deltaTime);
|
||||
|
||||
if (nextFactor == 5)
|
||||
nextFactor = 2;
|
||||
else
|
||||
nextFactor = 5;
|
||||
}
|
||||
|
||||
return deltaTime;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,157 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyle.h"
|
||||
#include "curveeditorstyledialog.h"
|
||||
#include "graphicsscene.h"
|
||||
#include "playhead.h"
|
||||
#include "selector.h"
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
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;
|
||||
|
||||
bool hasActiveItem() const;
|
||||
|
||||
bool hasActiveHandle() const;
|
||||
|
||||
int mapTimeToX(double time) const;
|
||||
|
||||
int mapValueToY(double value) const;
|
||||
|
||||
double mapXtoTime(int x) const;
|
||||
|
||||
double mapYtoValue(int y) const;
|
||||
|
||||
QPointF globalToScene(const QPoint &point) const;
|
||||
|
||||
QPointF globalToRaster(const QPoint &point) const;
|
||||
|
||||
double minimumTime() const;
|
||||
|
||||
double maximumTime() const;
|
||||
|
||||
double minimumValue() const;
|
||||
|
||||
double maximumValue() const;
|
||||
|
||||
double zoomX() const;
|
||||
|
||||
double zoomY() const;
|
||||
|
||||
QRectF canvasRect() const;
|
||||
|
||||
QRectF timeScaleRect() const;
|
||||
|
||||
QRectF valueScaleRect() const;
|
||||
|
||||
QRectF defaultRasterRect() const;
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
void setZoomX(double zoom, const QPoint &pivot = QPoint());
|
||||
|
||||
void setZoomY(double zoom, const QPoint &pivot = QPoint());
|
||||
|
||||
void setCurrentFrame(int frame);
|
||||
|
||||
void scrollContent(double x, double y);
|
||||
|
||||
void reset(const std::vector<CurveItem *> &items);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
void wheelEvent(QWheelEvent *event) override;
|
||||
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
||||
void drawForeground(QPainter *painter, const QRectF &rect) override;
|
||||
|
||||
void drawBackground(QPainter *painter, const QRectF &rect) override;
|
||||
|
||||
private:
|
||||
void applyZoom(double x, double y, const QPoint &pivot = QPoint());
|
||||
|
||||
void drawGrid(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void drawExtremaX(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void drawExtremaY(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void drawTimeScale(QPainter *painter, const QRectF &rect);
|
||||
|
||||
void drawValueScale(QPainter *painter, const QRectF &rect);
|
||||
|
||||
double timeLabelInterval(QPainter *painter, double maxTime);
|
||||
|
||||
private:
|
||||
double m_zoomX;
|
||||
|
||||
double m_zoomY;
|
||||
|
||||
QTransform m_transform;
|
||||
|
||||
GraphicsScene m_scene;
|
||||
|
||||
CurveEditorModel *m_model;
|
||||
|
||||
Playhead m_playhead;
|
||||
|
||||
Selector m_selector;
|
||||
|
||||
CurveEditorStyle m_style;
|
||||
|
||||
CurveEditorStyleDialog m_dialog;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,104 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "handleitem.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
struct HandleGeometry
|
||||
{
|
||||
HandleGeometry(const QPointF &pos, const HandleItemStyleOption &style)
|
||||
{
|
||||
QPointF topLeft(-style.size / 2.0, -style.size / 2.0);
|
||||
handle = QRectF(topLeft, -topLeft);
|
||||
toKeyframe = QLineF(QPointF(0.0, 0.0), -pos);
|
||||
angle = -toKeyframe.angle() + 45.0;
|
||||
}
|
||||
|
||||
QRectF handle;
|
||||
|
||||
QLineF toKeyframe;
|
||||
|
||||
double angle;
|
||||
};
|
||||
|
||||
HandleItem::HandleItem(QGraphicsItem *parent)
|
||||
: SelectableItem(parent)
|
||||
, m_style()
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemStacksBehindParent, true);
|
||||
}
|
||||
|
||||
HandleItem::~HandleItem() {}
|
||||
|
||||
int HandleItem::type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
QRectF HandleItem::boundingRect() const
|
||||
{
|
||||
HandleGeometry geom(pos(), m_style);
|
||||
|
||||
QTransform transform;
|
||||
transform.rotate(geom.angle);
|
||||
|
||||
QRectF bounds = bbox(geom.handle, transform);
|
||||
grow(bounds, -pos());
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void HandleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QColor handleColor(isSelected() ? m_style.selectionColor : m_style.color);
|
||||
|
||||
HandleGeometry geom(pos(), m_style);
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setWidthF(m_style.lineWidth);
|
||||
pen.setColor(handleColor);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
|
||||
painter->drawLine(geom.toKeyframe);
|
||||
painter->rotate(geom.angle);
|
||||
painter->fillRect(geom.handle, handleColor);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void HandleItem::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
m_style = style.handleStyle;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,56 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyle.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class HandleItem : public SelectableItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HandleItem(QGraphicsItem *parent);
|
||||
|
||||
~HandleItem() override;
|
||||
|
||||
enum { Type = ItemTypeHandle };
|
||||
|
||||
int type() const override;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
private:
|
||||
HandleItemStyleOption m_style;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,251 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "keyframeitem.h"
|
||||
#include "handleitem.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
KeyframeItem::KeyframeItem(QGraphicsItem *parent)
|
||||
: SelectableItem(parent)
|
||||
, m_frame()
|
||||
{}
|
||||
|
||||
KeyframeItem::KeyframeItem(const Keyframe &keyframe, QGraphicsItem *parent)
|
||||
: SelectableItem(parent)
|
||||
, m_transform()
|
||||
, m_frame(keyframe)
|
||||
, m_left(keyframe.hasLeftHandle() ? new HandleItem(this) : nullptr)
|
||||
, m_right(keyframe.hasRightHandle() ? new HandleItem(this) : nullptr)
|
||||
{
|
||||
auto updatePosition = [this]() { this->updatePosition(true); };
|
||||
connect(this, &QGraphicsObject::xChanged, updatePosition);
|
||||
connect(this, &QGraphicsObject::yChanged, updatePosition);
|
||||
|
||||
if (m_left) {
|
||||
m_left->setPos(m_frame.leftHandle() - m_frame.position());
|
||||
auto updateLeftHandle = [this]() { updateHandle(m_left); };
|
||||
connect(m_left, &QGraphicsObject::xChanged, updateLeftHandle);
|
||||
connect(m_left, &QGraphicsObject::yChanged, updateLeftHandle);
|
||||
m_left->hide();
|
||||
}
|
||||
|
||||
if (m_right) {
|
||||
m_right->setPos(m_frame.rightHandle() - m_frame.position());
|
||||
auto updateRightHandle = [this]() { updateHandle(m_right); };
|
||||
connect(m_right, &QGraphicsObject::xChanged, updateRightHandle);
|
||||
connect(m_right, &QGraphicsObject::yChanged, updateRightHandle);
|
||||
m_right->hide();
|
||||
}
|
||||
|
||||
setPos(m_frame.position());
|
||||
}
|
||||
|
||||
int KeyframeItem::type() const
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
|
||||
QRectF KeyframeItem::boundingRect() const
|
||||
{
|
||||
QPointF topLeft(-m_style.size / 2.0, -m_style.size / 2.0);
|
||||
return QRectF(topLeft, -topLeft);
|
||||
}
|
||||
|
||||
void KeyframeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(widget);
|
||||
|
||||
QPen pen = painter->pen();
|
||||
pen.setColor(Qt::black);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
painter->setBrush(selected() ? Qt::red : m_style.color);
|
||||
painter->drawEllipse(boundingRect());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
KeyframeItem::~KeyframeItem() {}
|
||||
|
||||
Keyframe KeyframeItem::keyframe() const
|
||||
{
|
||||
return m_frame;
|
||||
}
|
||||
|
||||
void KeyframeItem::setComponentTransform(const QTransform &transform)
|
||||
{
|
||||
m_transform = transform;
|
||||
|
||||
if (m_left)
|
||||
m_left->setPos(m_transform.map(m_frame.leftHandle() - m_frame.position()));
|
||||
|
||||
if (m_right)
|
||||
m_right->setPos(m_transform.map(m_frame.rightHandle() - m_frame.position()));
|
||||
|
||||
setPos(m_transform.map(m_frame.position()));
|
||||
}
|
||||
|
||||
void KeyframeItem::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
m_style = style.keyframeStyle;
|
||||
|
||||
if (m_left)
|
||||
m_left->setStyle(style);
|
||||
|
||||
if (m_right)
|
||||
m_right->setStyle(style);
|
||||
}
|
||||
|
||||
void KeyframeItem::updatePosition(bool update)
|
||||
{
|
||||
bool ok = false;
|
||||
QPointF position = m_transform.inverted(&ok).map(pos());
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
QPointF oldPosition = m_frame.position();
|
||||
m_frame.setPosition(position);
|
||||
|
||||
if (m_left)
|
||||
updateHandle(m_left, false);
|
||||
|
||||
if (m_right)
|
||||
updateHandle(m_right, false);
|
||||
|
||||
if (update) {
|
||||
emit redrawCurve();
|
||||
emit keyframeMoved(this, position - oldPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeItem::moveKeyframe(const QPointF &direction)
|
||||
{
|
||||
this->blockSignals(true);
|
||||
setPos(m_transform.map(m_frame.position() + direction));
|
||||
updatePosition(false);
|
||||
this->blockSignals(false);
|
||||
emit redrawCurve();
|
||||
}
|
||||
|
||||
void KeyframeItem::moveHandle(HandleSlot handle, double deltaAngle, double deltaLength)
|
||||
{
|
||||
auto move = [this, deltaAngle, deltaLength](HandleItem *item) {
|
||||
QLineF current(QPointF(0.0, 0.0), item->pos());
|
||||
current.setAngle(current.angle() + deltaAngle);
|
||||
current.setLength(current.length() + deltaLength);
|
||||
item->setPos(current.p2());
|
||||
updateHandle(item, false);
|
||||
};
|
||||
|
||||
this->blockSignals(true);
|
||||
|
||||
if (handle == HandleSlot::Left)
|
||||
move(m_left);
|
||||
else if (handle == HandleSlot::Right)
|
||||
move(m_right);
|
||||
|
||||
this->blockSignals(false);
|
||||
|
||||
emit redrawCurve();
|
||||
}
|
||||
|
||||
void KeyframeItem::updateHandle(HandleItem *handle, bool emitChanged)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
QPointF handlePosition = m_transform.inverted(&ok).map(handle->pos());
|
||||
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
QPointF oldPosition;
|
||||
QPointF newPosition;
|
||||
HandleSlot slot = HandleSlot::Undefined;
|
||||
if (handle == m_left) {
|
||||
slot = HandleSlot::Left;
|
||||
oldPosition = m_frame.leftHandle();
|
||||
m_frame.setLeftHandle(m_frame.position() + handlePosition);
|
||||
newPosition = m_frame.leftHandle();
|
||||
} else {
|
||||
slot = HandleSlot::Right;
|
||||
oldPosition = m_frame.rightHandle();
|
||||
m_frame.setRightHandle(m_frame.position() + handlePosition);
|
||||
newPosition = m_frame.rightHandle();
|
||||
}
|
||||
|
||||
if (emitChanged) {
|
||||
QLineF oldLine(m_frame.position(), oldPosition);
|
||||
QLineF newLine(m_frame.position(), newPosition);
|
||||
|
||||
QLineF mappedOld = m_transform.map(oldLine);
|
||||
QLineF mappedNew = m_transform.map(newLine);
|
||||
|
||||
auto angle = mappedOld.angleTo(mappedNew);
|
||||
auto deltaLength = mappedNew.length() - mappedOld.length();
|
||||
|
||||
emit redrawCurve();
|
||||
emit handleMoved(this, slot, angle, deltaLength);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == ItemPositionChange) {
|
||||
bool ok;
|
||||
QPointF position = m_transform.inverted(&ok).map(value.toPointF());
|
||||
if (ok) {
|
||||
position.setX(std::round(position.x()));
|
||||
return QVariant(m_transform.map(position));
|
||||
}
|
||||
}
|
||||
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
void KeyframeItem::selectionCallback()
|
||||
{
|
||||
auto setHandleVisibility = [](HandleItem *handle, bool visible) {
|
||||
if (handle)
|
||||
handle->setVisible(visible);
|
||||
};
|
||||
|
||||
if (selected()) {
|
||||
setHandleVisibility(m_left, true);
|
||||
setHandleVisibility(m_right, true);
|
||||
} else {
|
||||
setHandleVisibility(m_left, false);
|
||||
setHandleVisibility(m_right, false);
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyle.h"
|
||||
#include "keyframe.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class HandleItem;
|
||||
|
||||
enum class HandleSlot { Undefined, Left, Right };
|
||||
|
||||
class KeyframeItem : public SelectableItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void redrawCurve();
|
||||
|
||||
void keyframeMoved(KeyframeItem *item, const QPointF &direction);
|
||||
|
||||
void handleMoved(KeyframeItem *frame, HandleSlot handle, double angle, double deltaLength);
|
||||
|
||||
public:
|
||||
KeyframeItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
KeyframeItem(const Keyframe &keyframe, QGraphicsItem *parent = nullptr);
|
||||
|
||||
~KeyframeItem() override;
|
||||
|
||||
enum { Type = ItemTypeKeyframe };
|
||||
|
||||
int type() const override;
|
||||
|
||||
QRectF boundingRect() const override;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
|
||||
Keyframe keyframe() const;
|
||||
|
||||
void setComponentTransform(const QTransform &transform);
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
void moveKeyframe(const QPointF &direction);
|
||||
|
||||
void moveHandle(HandleSlot handle, double deltaAngle, double deltaLength);
|
||||
|
||||
protected:
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||
|
||||
void selectionCallback() override;
|
||||
|
||||
private:
|
||||
void updatePosition(bool emit = true);
|
||||
|
||||
void updateHandle(HandleItem *handle, bool emit = true);
|
||||
|
||||
private:
|
||||
QTransform m_transform;
|
||||
|
||||
KeyframeItemStyleOption m_style;
|
||||
|
||||
Keyframe m_frame;
|
||||
|
||||
HandleItem *m_left;
|
||||
|
||||
HandleItem *m_right;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QApplication>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
constexpr double g_playheadMargin = 5.0;
|
||||
|
||||
Playhead::Playhead(GraphicsView *view)
|
||||
: m_frame(0)
|
||||
, m_moving(false)
|
||||
, m_rect()
|
||||
, m_timer()
|
||||
{
|
||||
m_timer.setSingleShot(true);
|
||||
m_timer.setInterval(30);
|
||||
QObject::connect(&m_timer, &QTimer::timeout, view, [this, view]() {
|
||||
if (QApplication::mouseButtons() == Qt::LeftButton)
|
||||
mouseMoveOutOfBounds(view);
|
||||
});
|
||||
}
|
||||
|
||||
int Playhead::currentFrame() const
|
||||
{
|
||||
return m_frame;
|
||||
}
|
||||
|
||||
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 tlr(style.valueAxisWidth, style.timeAxisHeight - style.playhead.width);
|
||||
QPointF brr(style.valueAxisWidth + style.playhead.width, -g_playheadMargin);
|
||||
|
||||
QPointF tl = viewRect.topLeft() + tlr;
|
||||
QPointF br = viewRect.bottomLeft() + brr;
|
||||
|
||||
m_rect = QRectF(tl, br);
|
||||
|
||||
moveToFrame(m_frame, view);
|
||||
}
|
||||
|
||||
bool Playhead::mousePress(const QPointF &pos)
|
||||
{
|
||||
QRectF hitRect = m_rect;
|
||||
hitRect.setBottom(hitRect.top() + hitRect.width());
|
||||
|
||||
m_moving = hitRect.contains(pos);
|
||||
|
||||
return m_moving;
|
||||
}
|
||||
|
||||
bool Playhead::mouseMove(const QPointF &pos, GraphicsView *view)
|
||||
{
|
||||
if (m_moving) {
|
||||
CurveEditorStyle style = view->editorStyle();
|
||||
|
||||
QRectF canvas = view->canvasRect().adjusted(0.0, -style.timeAxisHeight, 0.0, 0.0);
|
||||
|
||||
if (canvas.contains(pos))
|
||||
view->setCurrentFrame(std::round(view->mapXtoTime(pos.x())));
|
||||
else if (!m_timer.isActive())
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
return m_moving;
|
||||
}
|
||||
|
||||
void Playhead::mouseMoveOutOfBounds(GraphicsView *view)
|
||||
{
|
||||
if (QApplication::mouseButtons() != Qt::LeftButton)
|
||||
return;
|
||||
|
||||
CurveEditorStyle style = view->editorStyle();
|
||||
QRectF canvas = view->canvasRect();
|
||||
QPointF pos = view->globalToScene(QCursor::pos());
|
||||
|
||||
if (pos.x() > canvas.right()) {
|
||||
double speed = (pos.x() - canvas.right());
|
||||
double nextCenter = m_rect.center().x() + speed;
|
||||
double frame = std::round(view->mapXtoTime(nextCenter));
|
||||
view->setCurrentFrame(frame);
|
||||
|
||||
double framePosition = view->mapTimeToX(frame);
|
||||
double rightSideOut = framePosition + style.playhead.width / 2.0 + style.canvasMargin;
|
||||
double overshoot = rightSideOut - canvas.right();
|
||||
view->scrollContent(overshoot, 0.0);
|
||||
|
||||
} else if (pos.x() < canvas.left()) {
|
||||
double speed = (canvas.left() - pos.x());
|
||||
double nextCenter = m_rect.center().x() - speed;
|
||||
double frame = std::round(view->mapXtoTime(nextCenter));
|
||||
view->setCurrentFrame(frame);
|
||||
|
||||
double framePosition = view->mapTimeToX(frame);
|
||||
double leftSideOut = framePosition - style.playhead.width / 2.0 - style.canvasMargin;
|
||||
double undershoot = canvas.left() - leftSideOut;
|
||||
view->scrollContent(-undershoot, 0.0);
|
||||
}
|
||||
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
void Playhead::mouseRelease(GraphicsView *view)
|
||||
{
|
||||
if (m_moving)
|
||||
emit view->model()->currentFrameChanged(m_frame);
|
||||
|
||||
m_moving = false;
|
||||
}
|
||||
|
||||
void Playhead::paint(QPainter *painter, GraphicsView *view) const
|
||||
{
|
||||
CurveEditorStyle style = view->editorStyle();
|
||||
|
||||
painter->save();
|
||||
painter->setPen(style.playhead.color);
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
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(style.playhead.radius);
|
||||
|
||||
QLineF leftToBottom(left, bottom);
|
||||
leftToBottom.setLength(style.playhead.radius);
|
||||
|
||||
QPainterPath path(top);
|
||||
path.lineTo(right - QPointF(style.playhead.radius, 0.));
|
||||
path.quadTo(right, rightToBottom.p2());
|
||||
path.lineTo(bottom);
|
||||
path.lineTo(leftToBottom.p2());
|
||||
path.quadTo(left, left + QPointF(style.playhead.radius, 0.));
|
||||
path.closeSubpath();
|
||||
|
||||
painter->fillPath(path, style.playhead.color);
|
||||
painter->drawLine(top + QPointF(0., 5.), QPointF(m_rect.center().x(), m_rect.bottom()));
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QRectF>
|
||||
#include <QTimer>
|
||||
|
||||
class QPainter;
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class GraphicsView;
|
||||
|
||||
class Playhead
|
||||
{
|
||||
public:
|
||||
Playhead(GraphicsView *view);
|
||||
|
||||
int currentFrame() const;
|
||||
|
||||
void paint(QPainter *painter, GraphicsView *view) 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:
|
||||
void mouseMoveOutOfBounds(GraphicsView *view);
|
||||
|
||||
int m_frame;
|
||||
|
||||
bool m_moving;
|
||||
|
||||
QRectF m_rect;
|
||||
|
||||
QTimer m_timer;
|
||||
|
||||
GraphicsView *m_view;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,112 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "selectableitem.h"
|
||||
#include "keyframeitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
SelectableItem::SelectableItem(QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent)
|
||||
, m_active(false)
|
||||
, m_selected(false)
|
||||
, m_preSelected(SelectionMode::Undefined)
|
||||
{
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, false);
|
||||
|
||||
setFlag(QGraphicsItem::ItemIsMovable, true);
|
||||
setFlag(QGraphicsItem::ItemIgnoresTransformations, true);
|
||||
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
||||
}
|
||||
|
||||
SelectableItem::~SelectableItem() {}
|
||||
|
||||
bool SelectableItem::activated() const
|
||||
{
|
||||
return m_active;
|
||||
}
|
||||
|
||||
bool SelectableItem::selected() const
|
||||
{
|
||||
switch (m_preSelected) {
|
||||
case SelectionMode::Clear:
|
||||
return false;
|
||||
case SelectionMode::New:
|
||||
return true;
|
||||
case SelectionMode::Add:
|
||||
return true;
|
||||
case SelectionMode::Remove:
|
||||
return false;
|
||||
case SelectionMode::Toggle:
|
||||
return !m_selected;
|
||||
default:
|
||||
return m_selected;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SelectableItem::setActivated(bool active)
|
||||
{
|
||||
m_active = active;
|
||||
}
|
||||
|
||||
void SelectableItem::setPreselected(SelectionMode mode)
|
||||
{
|
||||
m_preSelected = mode;
|
||||
selectionCallback();
|
||||
}
|
||||
|
||||
void SelectableItem::applyPreselection()
|
||||
{
|
||||
m_selected = selected();
|
||||
m_preSelected = SelectionMode::Undefined;
|
||||
}
|
||||
|
||||
void SelectableItem::selectionCallback() {}
|
||||
|
||||
void SelectableItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
m_active = true;
|
||||
QGraphicsObject::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void SelectableItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (type() == KeyframeItem::Type && !selected())
|
||||
return;
|
||||
|
||||
QGraphicsObject::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void SelectableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
m_active = false;
|
||||
QGraphicsObject::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 {
|
||||
|
||||
enum ItemType
|
||||
{
|
||||
ItemTypeKeyframe = QGraphicsItem::UserType + 1,
|
||||
ItemTypeHandle = QGraphicsItem::UserType + 2,
|
||||
ItemTypeCurve = QGraphicsItem::UserType + 3
|
||||
};
|
||||
|
||||
enum class SelectionMode : unsigned int
|
||||
{
|
||||
Undefined,
|
||||
Clear,
|
||||
New,
|
||||
Add,
|
||||
Remove,
|
||||
Toggle
|
||||
};
|
||||
|
||||
class SelectableItem : public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SelectableItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
~SelectableItem() override;
|
||||
|
||||
bool activated() const;
|
||||
|
||||
bool selected() const;
|
||||
|
||||
void setActivated(bool active);
|
||||
|
||||
void setPreselected(SelectionMode mode);
|
||||
|
||||
void applyPreselection();
|
||||
|
||||
protected:
|
||||
virtual void selectionCallback();
|
||||
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
bool m_active;
|
||||
|
||||
bool m_selected;
|
||||
|
||||
SelectionMode m_preSelected;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,219 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "selector.h"
|
||||
#include "graphicsview.h"
|
||||
#include "keyframeitem.h"
|
||||
#include "playhead.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
Selector::Selector() {}
|
||||
|
||||
void Selector::paint(QPainter *painter)
|
||||
{
|
||||
QPen pen(Qt::white);
|
||||
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
|
||||
if (!m_lasso.isEmpty())
|
||||
painter->drawPath(m_lasso);
|
||||
|
||||
if (!m_rect.isNull())
|
||||
painter->drawRect(m_rect);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void Selector::mousePress(QMouseEvent *event, GraphicsView *view)
|
||||
{
|
||||
m_shortcut = Shortcut(event);
|
||||
|
||||
if (view->hasActiveHandle())
|
||||
return;
|
||||
|
||||
if (select(SelectionTool::Undefined, view->globalToScene(event->globalPos()), view))
|
||||
applyPreSelection(view);
|
||||
|
||||
m_mouseInit = event->globalPos();
|
||||
m_mouseCurr = event->globalPos();
|
||||
|
||||
QPointF click = view->globalToScene(m_mouseInit);
|
||||
|
||||
m_lasso = QPainterPath(click);
|
||||
m_lasso.closeSubpath();
|
||||
|
||||
m_rect = QRectF(click, click);
|
||||
}
|
||||
|
||||
void Selector::mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playhead)
|
||||
{
|
||||
if (m_mouseInit.isNull())
|
||||
return;
|
||||
|
||||
QPointF delta = event->globalPos() - m_mouseInit;
|
||||
if (delta.manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
if (m_shortcut == m_shortcuts.newSelection || m_shortcut == m_shortcuts.addToSelection
|
||||
|| m_shortcut == m_shortcuts.removeFromSelection
|
||||
|| m_shortcut == m_shortcuts.toggleSelection) {
|
||||
if (view->hasActiveItem())
|
||||
return;
|
||||
|
||||
select(m_tool, view->globalToScene(event->globalPos()), view);
|
||||
|
||||
event->accept();
|
||||
view->viewport()->update();
|
||||
|
||||
} else if (m_shortcut == m_shortcuts.zoom) {
|
||||
double bigger = std::abs(delta.x()) > std::abs(delta.y()) ? delta.x() : delta.y();
|
||||
double factor = bigger / view->width();
|
||||
view->setZoomX(view->zoomX() + factor, m_mouseInit);
|
||||
m_mouseCurr = event->globalPos();
|
||||
event->accept();
|
||||
|
||||
} else if (m_shortcut == m_shortcuts.pan) {
|
||||
view->scrollContent(-delta.x(), -delta.y());
|
||||
playhead.resize(view);
|
||||
m_mouseCurr = event->globalPos();
|
||||
}
|
||||
}
|
||||
|
||||
void Selector::mouseRelease(QMouseEvent *event, GraphicsView *view)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
applyPreSelection(view);
|
||||
|
||||
m_shortcut = Shortcut();
|
||||
m_mouseInit = QPoint();
|
||||
m_mouseCurr = QPoint();
|
||||
m_lasso = QPainterPath();
|
||||
m_rect = QRectF();
|
||||
}
|
||||
|
||||
bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsView *view)
|
||||
{
|
||||
auto selectWidthTool = [this, tool](SelectionMode mode, const QPointF &pos, GraphicsView *view) {
|
||||
switch (tool) {
|
||||
case SelectionTool::Lasso:
|
||||
return lassoSelection(mode, pos, view);
|
||||
case SelectionTool::Rectangle:
|
||||
return rectangleSelection(mode, pos, view);
|
||||
default:
|
||||
return pressSelection(mode, pos, view);
|
||||
}
|
||||
};
|
||||
|
||||
if (m_shortcut == m_shortcuts.newSelection) {
|
||||
clearSelection(view);
|
||||
return selectWidthTool(SelectionMode::New, pos, view);
|
||||
} else if (m_shortcut == m_shortcuts.addToSelection) {
|
||||
return selectWidthTool(SelectionMode::Add, pos, view);
|
||||
} else if (m_shortcut == m_shortcuts.removeFromSelection) {
|
||||
return selectWidthTool(SelectionMode::Remove, pos, view);
|
||||
} else if (m_shortcut == m_shortcuts.toggleSelection) {
|
||||
return selectWidthTool(SelectionMode::Toggle, pos, view);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view)
|
||||
{
|
||||
bool out = false;
|
||||
const auto itemList = view->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *frame = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
QRectF itemRect = frame->mapRectToScene(frame->boundingRect());
|
||||
if (itemRect.contains(pos)) {
|
||||
frame->setPreselected(mode);
|
||||
out = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view)
|
||||
{
|
||||
bool out = false;
|
||||
m_rect.setBottomRight(pos);
|
||||
const auto itemList = view->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
if (m_rect.contains(keyframeItem->pos())) {
|
||||
keyframeItem->setPreselected(mode);
|
||||
out = true;
|
||||
} else {
|
||||
keyframeItem->setPreselected(SelectionMode::Undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view)
|
||||
{
|
||||
bool out = false;
|
||||
m_lasso.lineTo(pos);
|
||||
const auto itemList = view->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
if (m_lasso.contains(keyframeItem->pos())) {
|
||||
keyframeItem->setPreselected(mode);
|
||||
out = true;
|
||||
} else {
|
||||
keyframeItem->setPreselected(SelectionMode::Undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
void Selector::clearSelection(GraphicsView *view)
|
||||
{
|
||||
const auto itemList = view->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
frameItem->setPreselected(SelectionMode::Clear);
|
||||
frameItem->applyPreselection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Selector::applyPreSelection(GraphicsView *view)
|
||||
{
|
||||
const auto itemList = view->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *keyframeItem = qgraphicsitem_cast<KeyframeItem *>(item))
|
||||
keyframeItem->applyPreselection();
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,86 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "curveeditorstyle.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QPoint>
|
||||
#include <QRectF>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class GraphicsView;
|
||||
class Playhead;
|
||||
|
||||
enum class SelectionTool { Undefined, Lasso, Rectangle };
|
||||
|
||||
class Selector
|
||||
{
|
||||
public:
|
||||
Selector();
|
||||
|
||||
void paint(QPainter *painter);
|
||||
|
||||
void mousePress(QMouseEvent *event, GraphicsView *view);
|
||||
|
||||
void mouseMove(QMouseEvent *event, GraphicsView *view, Playhead &playhead);
|
||||
|
||||
void mouseRelease(QMouseEvent *event, GraphicsView *view);
|
||||
|
||||
private:
|
||||
bool select(const SelectionTool &tool, const QPointF &pos, GraphicsView *view);
|
||||
|
||||
bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view);
|
||||
|
||||
bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view);
|
||||
|
||||
bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsView *view);
|
||||
|
||||
void clearSelection(GraphicsView *view);
|
||||
|
||||
void applyPreSelection(GraphicsView *view);
|
||||
|
||||
Shortcuts m_shortcuts = Shortcuts();
|
||||
|
||||
Shortcut m_shortcut;
|
||||
|
||||
SelectionMode m_mode = SelectionMode::Undefined;
|
||||
|
||||
SelectionTool m_tool = SelectionTool::Rectangle;
|
||||
|
||||
QPoint m_mouseInit = QPoint();
|
||||
|
||||
QPoint m_mouseCurr = QPoint();
|
||||
|
||||
QPainterPath m_lasso = QPainterPath();
|
||||
|
||||
QRectF m_rect = QRectF();
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,81 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "shortcut.h"
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
Shortcut::Shortcut()
|
||||
: m_key()
|
||||
, m_buttons()
|
||||
, m_modifiers()
|
||||
{}
|
||||
|
||||
Shortcut::Shortcut(QMouseEvent *event)
|
||||
: m_key()
|
||||
, m_buttons(event->buttons())
|
||||
, m_modifiers(event->modifiers())
|
||||
{}
|
||||
|
||||
Shortcut::Shortcut(const Qt::KeyboardModifiers &mods, const Qt::Key &key)
|
||||
: m_key(key)
|
||||
, m_buttons()
|
||||
, m_modifiers(mods)
|
||||
{}
|
||||
|
||||
Shortcut::Shortcut(const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &mods)
|
||||
: m_key()
|
||||
, m_buttons(buttons)
|
||||
, m_modifiers(mods)
|
||||
{}
|
||||
|
||||
Shortcut::Shortcut(const Qt::MouseButtons &buttons,
|
||||
const Qt::KeyboardModifiers &mods,
|
||||
const Qt::Key &key)
|
||||
: m_key(key)
|
||||
, m_buttons(buttons)
|
||||
, m_modifiers(mods)
|
||||
{}
|
||||
|
||||
bool Shortcut::exactMatch(const Qt::Key &key) const
|
||||
{
|
||||
return m_key == key;
|
||||
}
|
||||
|
||||
bool Shortcut::exactMatch(const Qt::MouseButton &button) const
|
||||
{
|
||||
return static_cast<int>(m_buttons) == static_cast<int>(button);
|
||||
}
|
||||
|
||||
bool Shortcut::exactMatch(const Qt::KeyboardModifier &modifier) const
|
||||
{
|
||||
return static_cast<int>(m_modifiers) == static_cast<int>(modifier);
|
||||
}
|
||||
|
||||
bool Shortcut::operator==(const Shortcut &other) const
|
||||
{
|
||||
return m_key == other.m_key && m_buttons == other.m_buttons && m_modifiers == other.m_modifiers;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QMouseEvent>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class Shortcut
|
||||
{
|
||||
public:
|
||||
Shortcut();
|
||||
|
||||
Shortcut(QMouseEvent *event);
|
||||
|
||||
Shortcut(const Qt::KeyboardModifiers &mods, const Qt::Key &key);
|
||||
|
||||
Shortcut(const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &mods = Qt::NoModifier);
|
||||
|
||||
Shortcut(const Qt::MouseButtons &buttons, const Qt::KeyboardModifiers &mods, const Qt::Key &key);
|
||||
|
||||
bool exactMatch(const Qt::Key &key) const;
|
||||
|
||||
bool exactMatch(const Qt::MouseButton &button) const;
|
||||
|
||||
bool exactMatch(const Qt::KeyboardModifier &modifier) const;
|
||||
|
||||
bool operator==(const Shortcut &other) const;
|
||||
|
||||
private:
|
||||
Qt::Key m_key;
|
||||
|
||||
Qt::MouseButtons m_buttons;
|
||||
|
||||
Qt::KeyboardModifiers m_modifiers;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "treeitemdelegate.h"
|
||||
#include "treeitem.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
TreeItemDelegate::TreeItemDelegate(const CurveEditorStyle &style, QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
, m_style(style)
|
||||
{}
|
||||
|
||||
QSize TreeItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
return QStyledItemDelegate::sizeHint(option, index);
|
||||
}
|
||||
|
||||
void TreeItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == 1 || index.column() == 2) {
|
||||
|
||||
int height = option.rect.size().height();
|
||||
QRect iconRect(QPoint(0, 0), QSize(height, height));
|
||||
iconRect.moveCenter(option.rect.center());
|
||||
|
||||
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
if (option.state & QStyle::State_MouseOver && iconRect.contains(m_mousePos)) {
|
||||
|
||||
painter->fillRect(option.rect, option.backgroundBrush);
|
||||
|
||||
if (index.column() == 1) {
|
||||
|
||||
if (treeItem->locked()) {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.unlockedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
|
||||
} else {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.lockedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
}
|
||||
|
||||
} else if (index.column() == 2) {
|
||||
|
||||
if (treeItem->pinned()) {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.unpinnedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
|
||||
} else {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.pinnedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (treeItem->locked() && index.column() == 1) {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.lockedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
|
||||
} else if (treeItem->pinned() && index.column() == 2) {
|
||||
|
||||
QPixmap pixmap = pixmapFromIcon(
|
||||
m_style.treeItemStyle.pinnedIcon,
|
||||
iconRect.size(),
|
||||
m_style.fontColor);
|
||||
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
}
|
||||
|
||||
void TreeItemDelegate::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
m_style = style;
|
||||
}
|
||||
|
||||
bool TreeItemDelegate::editorEvent(QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index)
|
||||
{
|
||||
if (event->type() == QEvent::MouseMove)
|
||||
m_mousePos = static_cast<QMouseEvent *>(event)->pos();
|
||||
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -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 "curveeditorstyle.h"
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class TreeItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeItemDelegate(const CurveEditorStyle &style, QObject *parent = nullptr);
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
void paint(
|
||||
QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
protected:
|
||||
bool editorEvent(
|
||||
QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) override;
|
||||
|
||||
private:
|
||||
CurveEditorStyle m_style;
|
||||
|
||||
QPoint m_mousePos;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,156 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "treemodel.h"
|
||||
#include "treeitem.h"
|
||||
#include "detail/graphicsview.h"
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
TreeModel::TreeModel(QObject *parent)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_view(nullptr)
|
||||
, m_root(new TreeItem("Root"))
|
||||
{}
|
||||
|
||||
TreeModel::~TreeModel()
|
||||
{
|
||||
if (m_root) {
|
||||
delete m_root;
|
||||
m_root = nullptr;
|
||||
}
|
||||
|
||||
m_view = nullptr;
|
||||
}
|
||||
|
||||
QVariant TreeModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
|
||||
|
||||
if (role == Qt::DecorationRole && index.column() == 0)
|
||||
return item->icon();
|
||||
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
|
||||
QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
return m_root->headerData(section);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *parentItem = m_root;
|
||||
|
||||
if (parent.isValid())
|
||||
parentItem = static_cast<TreeItem *>(parent.internalPointer());
|
||||
|
||||
if (TreeItem *childItem = parentItem->child(row))
|
||||
return createIndex(row, column, childItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
TreeItem *childItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
|
||||
if (TreeItem *parentItem = childItem->parent()) {
|
||||
if (parentItem == m_root)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int TreeModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
TreeItem *parentItem = m_root;
|
||||
|
||||
if (parent.isValid())
|
||||
parentItem = static_cast<TreeItem *>(parent.internalPointer());
|
||||
|
||||
return parentItem->rowCount();
|
||||
}
|
||||
|
||||
int TreeModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
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)
|
||||
delete m_root;
|
||||
|
||||
m_root = new TreeItem("Root");
|
||||
}
|
||||
|
||||
TreeItem *TreeModel::root()
|
||||
{
|
||||
return m_root;
|
||||
}
|
||||
|
||||
TreeItem *TreeModel::find(unsigned int id)
|
||||
{
|
||||
return m_root->find(id);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,75 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QAbstractItemModel>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class GraphicsView;
|
||||
class TreeItem;
|
||||
|
||||
class TreeModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TreeModel(QObject *parent = nullptr);
|
||||
|
||||
~TreeModel() override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
void setGraphicsView(GraphicsView *view);
|
||||
|
||||
protected:
|
||||
GraphicsView *graphicsView() const;
|
||||
|
||||
void initialize();
|
||||
|
||||
TreeItem *root();
|
||||
|
||||
TreeItem *find(unsigned int id);
|
||||
|
||||
private:
|
||||
GraphicsView *m_view;
|
||||
|
||||
TreeItem *m_root;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,127 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "treeview.h"
|
||||
#include "curveeditormodel.h"
|
||||
#include "curveitem.h"
|
||||
#include "treeitem.h"
|
||||
#include "treeitemdelegate.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
TreeView::TreeView(CurveEditorModel *model, QWidget *parent)
|
||||
: QTreeView(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
setUniformRowHeights(true);
|
||||
setRootIsDecorated(false);
|
||||
setMouseTracking(true);
|
||||
setHeaderHidden(true);
|
||||
|
||||
model->setParent(this);
|
||||
setModel(model);
|
||||
|
||||
auto expandItems = [this]() { expandAll(); };
|
||||
connect(model, &QAbstractItemModel::modelReset, expandItems);
|
||||
|
||||
auto *delegate = new TreeItemDelegate(model->style(), this);
|
||||
setItemDelegate(delegate);
|
||||
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &TreeView::changeSelection);
|
||||
setStyle(model->style());
|
||||
|
||||
header()->setSectionResizeMode(0, QHeaderView::Stretch);
|
||||
header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
header()->setSectionResizeMode(2, QHeaderView::Fixed);
|
||||
|
||||
header()->setStretchLastSection(false);
|
||||
header()->resizeSection(1, 20);
|
||||
header()->resizeSection(2, 20);
|
||||
}
|
||||
|
||||
void TreeView::setStyle(const CurveEditorStyle &style)
|
||||
{
|
||||
QPalette pal = palette();
|
||||
pal.setBrush(QPalette::Base, style.backgroundBrush);
|
||||
pal.setBrush(QPalette::Button, style.backgroundAlternateBrush);
|
||||
pal.setBrush(QPalette::Text, style.fontColor);
|
||||
|
||||
// Tmp to see what happens on windows/macOS.
|
||||
pal.setBrush(backgroundRole(), Qt::white);
|
||||
pal.setBrush(foregroundRole(), Qt::white);
|
||||
|
||||
setPalette(pal);
|
||||
|
||||
if (auto *delegate = qobject_cast<TreeItemDelegate *>(itemDelegate()))
|
||||
delegate->setStyle(style);
|
||||
}
|
||||
|
||||
void TreeView::changeCurve(unsigned int id, const AnimationCurve &curve)
|
||||
{
|
||||
if (auto *curveModel = qobject_cast<CurveEditorModel *>(model()))
|
||||
curveModel->setCurve(id, curve);
|
||||
}
|
||||
|
||||
void TreeView::changeSelection(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
Q_UNUSED(selected);
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
std::vector<CurveItem *> curves;
|
||||
for (auto index : selectedIndexes()) {
|
||||
if (index.isValid() && index.column() == 0) {
|
||||
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
if (auto *propertyItem = treeItem->asPropertyItem())
|
||||
curves.push_back(new CurveItem(treeItem->id(), propertyItem->curve()));
|
||||
}
|
||||
}
|
||||
|
||||
emit curvesSelected(curves);
|
||||
}
|
||||
|
||||
QSize TreeView::sizeHint() const
|
||||
{
|
||||
return QSize(170, 300);
|
||||
}
|
||||
|
||||
void TreeView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (index.isValid()) {
|
||||
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
if (index.column() == 1)
|
||||
treeItem->setLocked(!treeItem->locked());
|
||||
else if (index.column() == 2)
|
||||
treeItem->setPinned(!treeItem->pinned());
|
||||
}
|
||||
QTreeView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QTreeView>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class AnimationCurve;
|
||||
class CurveEditorModel;
|
||||
class CurveItem;
|
||||
|
||||
struct CurveEditorStyle;
|
||||
|
||||
class TreeView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void curvesSelected(const std::vector<CurveItem *> &curves);
|
||||
|
||||
public:
|
||||
TreeView(CurveEditorModel *model, QWidget *parent = nullptr);
|
||||
|
||||
void changeCurve(unsigned int id, const AnimationCurve &curve);
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override;
|
||||
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void changeSelection(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
107
src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp
Normal file
107
src/plugins/qmldesigner/components/curveeditor/detail/utils.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QPalette>
|
||||
#include <QPointF>
|
||||
#include <QRectF>
|
||||
#include <QTransform>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
double clamp(double val, double lo, double hi)
|
||||
{
|
||||
return val < lo ? lo : (val > hi ? hi : val);
|
||||
}
|
||||
|
||||
double lerp(double blend, double a, double b)
|
||||
{
|
||||
return (1.0 - blend) * a + blend * b;
|
||||
}
|
||||
|
||||
double scaleX(const QTransform &transform)
|
||||
{
|
||||
return transform.m11();
|
||||
}
|
||||
|
||||
double scaleY(const QTransform &transform)
|
||||
{
|
||||
return transform.m22();
|
||||
}
|
||||
|
||||
void grow(QRectF &rect, const QPointF &point)
|
||||
{
|
||||
if (rect.left() > point.x())
|
||||
rect.setLeft(point.x());
|
||||
|
||||
if (rect.right() < point.x())
|
||||
rect.setRight(point.x());
|
||||
|
||||
if (rect.top() > point.y())
|
||||
rect.setTop(point.y());
|
||||
|
||||
if (rect.bottom() < point.y())
|
||||
rect.setBottom(point.y());
|
||||
}
|
||||
|
||||
QRectF bbox(const QRectF &rect, const QTransform &transform)
|
||||
{
|
||||
QRectF out = rect;
|
||||
grow(out, transform.map(rect.topLeft()));
|
||||
grow(out, transform.map(rect.topRight()));
|
||||
grow(out, transform.map(rect.bottomLeft()));
|
||||
grow(out, transform.map(rect.bottomRight()));
|
||||
return out;
|
||||
}
|
||||
|
||||
QPalette singleColorPalette(const QColor &color)
|
||||
{
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Window, color);
|
||||
palette.setColor(QPalette::Background, color);
|
||||
palette.setColor(QPalette::WindowText, color);
|
||||
palette.setColor(QPalette::Foreground, color);
|
||||
palette.setColor(QPalette::Base, color);
|
||||
palette.setColor(QPalette::AlternateBase, color);
|
||||
palette.setColor(QPalette::ToolTipBase, color);
|
||||
palette.setColor(QPalette::ToolTipText, color);
|
||||
palette.setColor(QPalette::Text, color);
|
||||
|
||||
palette.setColor(QPalette::Button, color);
|
||||
palette.setColor(QPalette::ButtonText, color);
|
||||
palette.setColor(QPalette::BrightText, color);
|
||||
palette.setColor(QPalette::Light, color);
|
||||
palette.setColor(QPalette::Midlight, color);
|
||||
palette.setColor(QPalette::Dark, color);
|
||||
palette.setColor(QPalette::Mid, color);
|
||||
palette.setColor(QPalette::Shadow, color);
|
||||
palette.setColor(QPalette::Highlight, color);
|
||||
palette.setColor(QPalette::HighlightedText, color);
|
||||
palette.setColor(QPalette::Link, color);
|
||||
palette.setColor(QPalette::LinkVisited, color);
|
||||
return palette;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
@@ -1,9 +1,9 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
** This file is part of the Qt Design Tooling
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
@@ -25,10 +25,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
class QColor;
|
||||
class QPalette;
|
||||
class QPointF;
|
||||
class QRectF;
|
||||
class QTransform;
|
||||
|
||||
#if defined(QMLDESIGNEREXTENSION_LIBRARY)
|
||||
# define QMLDESIGNEREXTENSIONSHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define QMLDESIGNEREXTENSIONSHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
namespace DesignTools {
|
||||
|
||||
double clamp(double val, double lo, double hi);
|
||||
|
||||
double lerp(double blend, double a, double b);
|
||||
|
||||
double scaleX(const QTransform &transform);
|
||||
|
||||
double scaleY(const QTransform &transform);
|
||||
|
||||
void grow(QRectF &rect, const QPointF &point);
|
||||
|
||||
QRectF bbox(const QRectF &rect, const QTransform &transform);
|
||||
|
||||
QPalette singleColorPalette(const QColor &color);
|
||||
|
||||
} // End namespace DesignTools.
|
88
src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
Normal file
88
src/plugins/qmldesigner/components/curveeditor/keyframe.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "keyframe.h"
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
Keyframe::Keyframe()
|
||||
: m_position()
|
||||
, m_leftHandle()
|
||||
, m_rightHandle()
|
||||
{}
|
||||
|
||||
Keyframe::Keyframe(const QPointF &position)
|
||||
: m_position(position)
|
||||
, m_leftHandle()
|
||||
, m_rightHandle()
|
||||
{}
|
||||
|
||||
Keyframe::Keyframe(const QPointF &position, const QPointF &leftHandle, const QPointF &rightHandle)
|
||||
: m_position(position)
|
||||
, m_leftHandle(leftHandle)
|
||||
, m_rightHandle(rightHandle)
|
||||
{}
|
||||
|
||||
bool Keyframe::hasLeftHandle() const
|
||||
{
|
||||
return !m_leftHandle.isNull();
|
||||
}
|
||||
|
||||
bool Keyframe::hasRightHandle() const
|
||||
{
|
||||
return !m_rightHandle.isNull();
|
||||
}
|
||||
|
||||
QPointF Keyframe::position() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
QPointF Keyframe::leftHandle() const
|
||||
{
|
||||
return m_leftHandle;
|
||||
}
|
||||
|
||||
QPointF Keyframe::rightHandle() const
|
||||
{
|
||||
return m_rightHandle;
|
||||
}
|
||||
|
||||
void Keyframe::setPosition(const QPointF &pos)
|
||||
{
|
||||
m_position = pos;
|
||||
}
|
||||
|
||||
void Keyframe::setLeftHandle(const QPointF &pos)
|
||||
{
|
||||
m_leftHandle = pos;
|
||||
}
|
||||
|
||||
void Keyframe::setRightHandle(const QPointF &pos)
|
||||
{
|
||||
m_rightHandle = pos;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
65
src/plugins/qmldesigner/components/curveeditor/keyframe.h
Normal file
65
src/plugins/qmldesigner/components/curveeditor/keyframe.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 <QPointF>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class Keyframe
|
||||
{
|
||||
public:
|
||||
Keyframe();
|
||||
|
||||
Keyframe(const QPointF &position);
|
||||
|
||||
Keyframe(const QPointF &position, const QPointF &leftHandle, const QPointF &rightHandle);
|
||||
|
||||
bool hasLeftHandle() const;
|
||||
|
||||
bool hasRightHandle() const;
|
||||
|
||||
QPointF position() const;
|
||||
|
||||
QPointF leftHandle() const;
|
||||
|
||||
QPointF rightHandle() const;
|
||||
|
||||
void setPosition(const QPointF &pos);
|
||||
|
||||
void setLeftHandle(const QPointF &pos);
|
||||
|
||||
void setRightHandle(const QPointF &pos);
|
||||
|
||||
private:
|
||||
QPointF m_position;
|
||||
|
||||
QPointF m_leftHandle;
|
||||
|
||||
QPointF m_rightHandle;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
227
src/plugins/qmldesigner/components/curveeditor/treeitem.cpp
Normal file
227
src/plugins/qmldesigner/components/curveeditor/treeitem.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "treeitem.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
TreeItem::TreeItem(const QString &name)
|
||||
: m_name(name)
|
||||
, m_id(0)
|
||||
, m_locked(false)
|
||||
, m_pinned(false)
|
||||
, m_parent(nullptr)
|
||||
, m_children()
|
||||
{}
|
||||
|
||||
TreeItem::~TreeItem()
|
||||
{
|
||||
m_parent = nullptr;
|
||||
|
||||
qDeleteAll(m_children);
|
||||
}
|
||||
|
||||
QIcon TreeItem::icon() const
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
NodeTreeItem *TreeItem::asNodeItem()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PropertyTreeItem *TreeItem::asPropertyItem()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
unsigned int TreeItem::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool TreeItem::locked() const
|
||||
{
|
||||
return m_locked;
|
||||
}
|
||||
|
||||
bool TreeItem::pinned() const
|
||||
{
|
||||
return m_pinned;
|
||||
}
|
||||
|
||||
int TreeItem::row() const
|
||||
{
|
||||
if (m_parent) {
|
||||
for (size_t i = 0; i < m_parent->m_children.size(); ++i) {
|
||||
if (m_parent->m_children[i] == this)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TreeItem::column() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TreeItem::rowCount() const
|
||||
{
|
||||
return m_children.size();
|
||||
}
|
||||
|
||||
int TreeItem::columnCount() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::parent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::child(int row) const
|
||||
{
|
||||
if (row < 0 || row >= static_cast<int>(m_children.size()))
|
||||
return nullptr;
|
||||
|
||||
return m_children.at(row);
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::find(unsigned int id) const
|
||||
{
|
||||
for (auto *child : m_children) {
|
||||
if (child->id() == id)
|
||||
return child;
|
||||
|
||||
if (auto *childsChild = child->find(id))
|
||||
return childsChild;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
switch (column) {
|
||||
case 0:
|
||||
return QVariant(m_name);
|
||||
case 1:
|
||||
return QVariant(m_locked);
|
||||
case 2:
|
||||
return QVariant(m_pinned);
|
||||
case 3:
|
||||
return QVariant(m_id);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant TreeItem::headerData(int column) const
|
||||
{
|
||||
switch (column) {
|
||||
case 0:
|
||||
return QString("Name");
|
||||
case 1:
|
||||
return QString("L");
|
||||
case 2:
|
||||
return QString("P");
|
||||
case 3:
|
||||
return QString("Id");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void TreeItem::setId(unsigned int &id)
|
||||
{
|
||||
m_id = id;
|
||||
|
||||
for (auto *child : m_children)
|
||||
child->setId(++id);
|
||||
}
|
||||
|
||||
void TreeItem::addChild(TreeItem *child)
|
||||
{
|
||||
child->m_parent = this;
|
||||
m_children.push_back(child);
|
||||
}
|
||||
|
||||
void TreeItem::setLocked(bool locked)
|
||||
{
|
||||
m_locked = locked;
|
||||
}
|
||||
|
||||
void TreeItem::setPinned(bool pinned)
|
||||
{
|
||||
m_pinned = pinned;
|
||||
}
|
||||
|
||||
|
||||
NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon)
|
||||
: TreeItem(name)
|
||||
, m_icon(icon)
|
||||
{
|
||||
Q_UNUSED(icon);
|
||||
}
|
||||
|
||||
NodeTreeItem *NodeTreeItem::asNodeItem()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
QIcon NodeTreeItem::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
|
||||
PropertyTreeItem::PropertyTreeItem(const QString &name, const AnimationCurve &curve)
|
||||
: TreeItem(name)
|
||||
, m_curve(curve)
|
||||
{}
|
||||
|
||||
PropertyTreeItem *PropertyTreeItem::asPropertyItem()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
AnimationCurve PropertyTreeItem::curve() const
|
||||
{
|
||||
return m_curve;
|
||||
}
|
||||
|
||||
void PropertyTreeItem::setCurve(const AnimationCurve &curve)
|
||||
{
|
||||
m_curve = curve;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
135
src/plugins/qmldesigner/components/curveeditor/treeitem.h
Normal file
135
src/plugins/qmldesigner/components/curveeditor/treeitem.h
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 "animationcurve.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QString>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class QIcon;
|
||||
class QVariant;
|
||||
|
||||
namespace DesignTools {
|
||||
|
||||
class NodeTreeItem;
|
||||
class PropertyTreeItem;
|
||||
|
||||
class TreeItem
|
||||
{
|
||||
public:
|
||||
TreeItem(const QString &name);
|
||||
|
||||
virtual ~TreeItem();
|
||||
|
||||
virtual QIcon icon() const;
|
||||
|
||||
virtual NodeTreeItem *asNodeItem();
|
||||
|
||||
virtual PropertyTreeItem *asPropertyItem();
|
||||
|
||||
unsigned int id() const;
|
||||
|
||||
bool locked() const;
|
||||
|
||||
bool pinned() const;
|
||||
|
||||
int row() const;
|
||||
|
||||
int column() const;
|
||||
|
||||
int rowCount() const;
|
||||
|
||||
int columnCount() const;
|
||||
|
||||
TreeItem *parent() const;
|
||||
|
||||
TreeItem *child(int row) const;
|
||||
|
||||
TreeItem *find(unsigned int row) const;
|
||||
|
||||
QVariant data(int column) const;
|
||||
|
||||
QVariant headerData(int column) const;
|
||||
|
||||
void setId(unsigned int &id);
|
||||
|
||||
void addChild(TreeItem *child);
|
||||
|
||||
void setLocked(bool locked);
|
||||
|
||||
void setPinned(bool pinned);
|
||||
|
||||
protected:
|
||||
QString m_name;
|
||||
|
||||
unsigned int m_id;
|
||||
|
||||
bool m_locked;
|
||||
|
||||
bool m_pinned;
|
||||
|
||||
TreeItem *m_parent;
|
||||
|
||||
std::vector<TreeItem *> m_children;
|
||||
};
|
||||
|
||||
|
||||
class NodeTreeItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
NodeTreeItem(const QString &name, const QIcon &icon);
|
||||
|
||||
NodeTreeItem *asNodeItem() override;
|
||||
|
||||
QIcon icon() const override;
|
||||
|
||||
private:
|
||||
QIcon m_icon;
|
||||
};
|
||||
|
||||
|
||||
class PropertyTreeItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
PropertyTreeItem(const QString &name, const AnimationCurve &curve);
|
||||
|
||||
PropertyTreeItem *asPropertyItem() override;
|
||||
|
||||
AnimationCurve curve() const;
|
||||
|
||||
void setCurve(const AnimationCurve &curve);
|
||||
|
||||
private:
|
||||
using TreeItem::addChild;
|
||||
|
||||
AnimationCurve m_curve;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user