forked from qt-creator/qt-creator
Update locking state from external views and cleanup
Improve treeview styling related to locking/pinning Use font icons. Show implicitly locked nodes by darkening text and icon. Show implicitly locked curves by darkening the text. Show unlocked/unpined icons only when hovering the mouse above the item. It is now possible to lock/pin multiple curves by locking/pinning the node items. Load unselected curves into the graphicsview when pinning them. Rename namespace DesignTools to QmlDesigner. Remove unused function from the timeline module. Get rid of a memory leak. Change-Id: I2c9c0a9e1ffe79520c4869178a11cc5825d04bbe Reviewed-by: Henning Gründl <henning.gruendl@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
AnimationCurve::AnimationCurve()
|
||||
: m_fromData(false)
|
||||
@@ -395,4 +395,4 @@ void AnimationCurve::analyze()
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -33,7 +33,7 @@
|
||||
QT_FORWARD_DECLARE_CLASS(QEasingCurve);
|
||||
QT_FORWARD_DECLARE_CLASS(QPainterPath);
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CurveSegment;
|
||||
|
||||
@@ -100,4 +100,4 @@ private:
|
||||
std::vector<Keyframe> m_frames;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <QSplitter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
@@ -52,10 +52,9 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
|
||||
box->addWidget(splitter);
|
||||
setLayout(box);
|
||||
|
||||
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::curveChanged);
|
||||
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::curveChanged);
|
||||
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
|
||||
connect(m_tree, &TreeView::treeItemPinned, model, &CurveEditorModel::setPinned);
|
||||
|
||||
connect(m_tree, &TreeView::treeItemLocked, m_view, &GraphicsView::setLocked);
|
||||
connect(m_tree->selectionModel(),
|
||||
&SelectionModel::curvesSelected,
|
||||
m_view,
|
||||
@@ -180,4 +179,4 @@ QToolBar *CurveEditor::createToolBar(CurveEditorModel *model)
|
||||
return bar;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <QToolBar>
|
||||
#include <QWidget>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CurveEditorModel;
|
||||
class GraphicsView;
|
||||
@@ -57,4 +57,4 @@ private:
|
||||
GraphicsView *m_view;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "curveeditormodel.h"
|
||||
#include "curveeditorstyle.h"
|
||||
#include "detail/treeview.h"
|
||||
#include "treeitem.h"
|
||||
|
||||
#include "detail/graphicsview.h"
|
||||
@@ -34,10 +35,11 @@
|
||||
#include "qmltimeline.h"
|
||||
|
||||
#include <bindingproperty.h>
|
||||
#include <nodeabstractproperty.h>
|
||||
#include <theme.h>
|
||||
#include <variantproperty.h>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
CurveEditorModel::CurveEditorModel(QObject *parent)
|
||||
: TreeModel(parent)
|
||||
@@ -57,10 +59,10 @@ double CurveEditorModel::maximumTime() const
|
||||
return m_maxTime;
|
||||
}
|
||||
|
||||
DesignTools::CurveEditorStyle CurveEditorModel::style() const
|
||||
CurveEditorStyle CurveEditorModel::style() const
|
||||
{
|
||||
// Pseudo auto generated. See: CurveEditorStyleDialog
|
||||
DesignTools::CurveEditorStyle out;
|
||||
CurveEditorStyle out;
|
||||
out.backgroundBrush = QBrush(QColor(21, 21, 21));
|
||||
out.backgroundAlternateBrush = QBrush(QColor(32, 32, 32));
|
||||
out.fontColor = QColor(255, 255, 255);
|
||||
@@ -98,9 +100,9 @@ void CurveEditorModel::setTimeline(const QmlDesigner::QmlTimeline &timeline)
|
||||
{
|
||||
m_minTime = timeline.startKeyframe();
|
||||
m_maxTime = timeline.endKeyframe();
|
||||
std::vector<DesignTools::TreeItem *> items;
|
||||
std::vector<TreeItem *> items;
|
||||
for (auto &&target : timeline.allTargets()) {
|
||||
if (DesignTools::TreeItem *item = createTopLevelItem(timeline, target))
|
||||
if (TreeItem *item = createTopLevelItem(timeline, target))
|
||||
items.push_back(item);
|
||||
}
|
||||
|
||||
@@ -135,6 +137,32 @@ void CurveEditorModel::setCurve(unsigned int id, const AnimationCurve &curve)
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEditorModel::setLocked(TreeItem *item, bool val)
|
||||
{
|
||||
item->setLocked(val);
|
||||
|
||||
if (auto *gview = graphicsView())
|
||||
gview->setLocked(item);
|
||||
|
||||
if (auto *tview = treeView())
|
||||
tview->viewport()->update();
|
||||
|
||||
emit curveChanged(item);
|
||||
}
|
||||
|
||||
void CurveEditorModel::setPinned(TreeItem *item, bool val)
|
||||
{
|
||||
item->setPinned(val);
|
||||
|
||||
if (auto *gview = graphicsView())
|
||||
gview->setPinned(item);
|
||||
|
||||
if (auto *tview = treeView())
|
||||
tview->viewport()->update();
|
||||
|
||||
emit curveChanged(item);
|
||||
}
|
||||
|
||||
bool contains(const std::vector<TreeItem::Path> &selection, const TreeItem::Path &path)
|
||||
{
|
||||
for (auto &&sel : selection)
|
||||
@@ -176,38 +204,57 @@ void CurveEditorModel::reset(const std::vector<TreeItem *> &items)
|
||||
sm->selectPaths(sel);
|
||||
}
|
||||
|
||||
DesignTools::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
PropertyTreeItem::ValueType typeFrom(const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
{
|
||||
if (group.valueType() == QmlDesigner::TypeName("double")
|
||||
|| group.valueType() == QmlDesigner::TypeName("real")
|
||||
|| group.valueType() == QmlDesigner::TypeName("float"))
|
||||
return DesignTools::ValueType::Double;
|
||||
return PropertyTreeItem::ValueType::Double;
|
||||
|
||||
if (group.valueType() == QmlDesigner::TypeName("boolean")
|
||||
|| group.valueType() == QmlDesigner::TypeName("bool"))
|
||||
return DesignTools::ValueType::Bool;
|
||||
return PropertyTreeItem::ValueType::Bool;
|
||||
|
||||
if (group.valueType() == QmlDesigner::TypeName("integer")
|
||||
|| group.valueType() == QmlDesigner::TypeName("int"))
|
||||
return DesignTools::ValueType::Integer;
|
||||
return PropertyTreeItem::ValueType::Integer;
|
||||
|
||||
// Ignoring: QColor / HAlignment / VAlignment
|
||||
return DesignTools::ValueType::Undefined;
|
||||
return PropertyTreeItem::ValueType::Undefined;
|
||||
}
|
||||
|
||||
DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
|
||||
const QmlDesigner::ModelNode &node)
|
||||
std::vector<QString> parentIds(const QmlDesigner::ModelNode &node)
|
||||
{
|
||||
std::vector<QString> out;
|
||||
|
||||
QmlDesigner::ModelNode parent = node.parentProperty().parentModelNode();
|
||||
while (parent.isValid()) {
|
||||
out.push_back(parent.id());
|
||||
|
||||
if (parent.hasParentProperty())
|
||||
parent = parent.parentProperty().parentModelNode();
|
||||
else
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
|
||||
const QmlDesigner::ModelNode &node)
|
||||
{
|
||||
if (!node.isValid())
|
||||
return nullptr;
|
||||
|
||||
auto *nodeItem = new DesignTools::NodeTreeItem(node.id(), QIcon(":/ICON_INSTANCE"));
|
||||
auto *nodeItem = new NodeTreeItem(node.id(), node.typeIcon(), parentIds(node));
|
||||
if (node.hasAuxiliaryData("locked"))
|
||||
nodeItem->setLocked(true);
|
||||
|
||||
for (auto &&grp : timeline.keyframeGroupsForTarget(node)) {
|
||||
if (grp.isValid()) {
|
||||
DesignTools::AnimationCurve curve = createAnimationCurve(grp);
|
||||
AnimationCurve curve = createAnimationCurve(grp);
|
||||
if (curve.isValid()) {
|
||||
QString name = QString::fromUtf8(grp.propertyName());
|
||||
auto propertyItem = new DesignTools::PropertyTreeItem(name, curve, typeFrom(grp));
|
||||
auto propertyItem = new PropertyTreeItem(name, curve, typeFrom(grp));
|
||||
|
||||
QmlDesigner::ModelNode target = grp.modelNode();
|
||||
if (target.hasAuxiliaryData("locked"))
|
||||
@@ -229,25 +276,24 @@ DesignTools::TreeItem *CurveEditorModel::createTopLevelItem(const QmlDesigner::Q
|
||||
return nodeItem;
|
||||
}
|
||||
|
||||
DesignTools::AnimationCurve CurveEditorModel::createAnimationCurve(
|
||||
const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
AnimationCurve CurveEditorModel::createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
{
|
||||
switch (typeFrom(group)) {
|
||||
case DesignTools::ValueType::Bool:
|
||||
case PropertyTreeItem::ValueType::Bool:
|
||||
return createDoubleCurve(group);
|
||||
|
||||
case DesignTools::ValueType::Integer:
|
||||
case PropertyTreeItem::ValueType::Integer:
|
||||
return createDoubleCurve(group);
|
||||
|
||||
case DesignTools::ValueType::Double:
|
||||
case PropertyTreeItem::ValueType::Double:
|
||||
return createDoubleCurve(group);
|
||||
|
||||
default:
|
||||
return DesignTools::AnimationCurve();
|
||||
return AnimationCurve();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode> nodes)
|
||||
std::vector<Keyframe> createKeyframes(QList<QmlDesigner::ModelNode> nodes)
|
||||
{
|
||||
auto byTime = [](const auto &a, const auto &b) {
|
||||
return a.variantProperty("frame").value().toDouble()
|
||||
@@ -255,7 +301,7 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
|
||||
};
|
||||
std::sort(nodes.begin(), nodes.end(), byTime);
|
||||
|
||||
std::vector<DesignTools::Keyframe> frames;
|
||||
std::vector<Keyframe> frames;
|
||||
for (auto &&node : nodes) {
|
||||
QVariant timeVariant = node.variantProperty("frame").value();
|
||||
QVariant valueVariant = node.variantProperty("value").value();
|
||||
@@ -264,7 +310,7 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
|
||||
|
||||
QPointF position(timeVariant.toDouble(), valueVariant.toDouble());
|
||||
|
||||
auto keyframe = DesignTools::Keyframe(position);
|
||||
auto keyframe = Keyframe(position);
|
||||
|
||||
if (node.hasBindingProperty("easing.bezierCurve")) {
|
||||
QmlDesigner::EasingCurve ecurve;
|
||||
@@ -276,15 +322,15 @@ std::vector<DesignTools::Keyframe> createKeyframes(QList<QmlDesigner::ModelNode>
|
||||
return frames;
|
||||
}
|
||||
|
||||
std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTools::Keyframe> &frames)
|
||||
std::vector<Keyframe> resolveSmallCurves(const std::vector<Keyframe> &frames)
|
||||
{
|
||||
std::vector<DesignTools::Keyframe> out;
|
||||
std::vector<Keyframe> out;
|
||||
for (auto &&frame : frames) {
|
||||
if (frame.hasData() && !out.empty()) {
|
||||
QEasingCurve curve = frame.data().toEasingCurve();
|
||||
// One-segment-curve: Since (0,0) is implicit => 3
|
||||
if (curve.toCubicSpline().count() == 3) {
|
||||
DesignTools::Keyframe &previous = out.back();
|
||||
Keyframe &previous = out.back();
|
||||
#if 0
|
||||
// Do not resolve when two adjacent keyframes have the same value.
|
||||
if (qFuzzyCompare(previous.position().y(), frame.position().y())) {
|
||||
@@ -292,7 +338,7 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTo
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
DesignTools::AnimationCurve acurve(curve, previous.position(), frame.position());
|
||||
AnimationCurve acurve(curve, previous.position(), frame.position());
|
||||
previous.setRightHandle(acurve.keyframeAt(0).rightHandle());
|
||||
out.push_back(acurve.keyframeAt(1));
|
||||
continue;
|
||||
@@ -303,10 +349,9 @@ std::vector<DesignTools::Keyframe> resolveSmallCurves(const std::vector<DesignTo
|
||||
return out;
|
||||
}
|
||||
|
||||
DesignTools::AnimationCurve CurveEditorModel::createDoubleCurve(
|
||||
const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
AnimationCurve CurveEditorModel::createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group)
|
||||
{
|
||||
std::vector<DesignTools::Keyframe> keyframes = createKeyframes(group.keyframePositions());
|
||||
std::vector<Keyframe> keyframes = createKeyframes(group.keyframePositions());
|
||||
keyframes = resolveSmallCurves(keyframes);
|
||||
|
||||
QString str;
|
||||
@@ -321,7 +366,7 @@ DesignTools::AnimationCurve CurveEditorModel::createDoubleCurve(
|
||||
}
|
||||
}
|
||||
|
||||
return DesignTools::AnimationCurve(keyframes);
|
||||
return AnimationCurve(keyframes);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -35,7 +35,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QPointF;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct CurveEditorStyle;
|
||||
|
||||
@@ -54,7 +54,7 @@ signals:
|
||||
|
||||
void commitEndFrame(int frame);
|
||||
|
||||
void curveChanged(PropertyTreeItem *item);
|
||||
void curveChanged(TreeItem *item);
|
||||
|
||||
public:
|
||||
CurveEditorModel(QObject *parent = nullptr);
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
double maximumTime() const;
|
||||
|
||||
DesignTools::CurveEditorStyle style() const;
|
||||
CurveEditorStyle style() const;
|
||||
|
||||
public:
|
||||
void setTimeline(const QmlDesigner::QmlTimeline &timeline);
|
||||
@@ -78,19 +78,23 @@ public:
|
||||
|
||||
void setCurve(unsigned int id, const AnimationCurve &curve);
|
||||
|
||||
void setLocked(TreeItem *item, bool val);
|
||||
|
||||
void setPinned(TreeItem *item, bool val);
|
||||
|
||||
void reset(const std::vector<TreeItem *> &items);
|
||||
|
||||
private:
|
||||
DesignTools::TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
|
||||
const QmlDesigner::ModelNode &node);
|
||||
TreeItem *createTopLevelItem(const QmlDesigner::QmlTimeline &timeline,
|
||||
const QmlDesigner::ModelNode &node);
|
||||
|
||||
DesignTools::AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
|
||||
AnimationCurve createAnimationCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
|
||||
|
||||
DesignTools::AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
|
||||
AnimationCurve createDoubleCurve(const QmlDesigner::QmlTimelineKeyframeGroup &group);
|
||||
|
||||
double m_minTime = 0.;
|
||||
|
||||
double m_maxTime = 0.;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,9 @@
|
||||
|
||||
#include "detail/shortcut.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/stylehelper.h>
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QBrush>
|
||||
@@ -38,15 +40,30 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct TreeItemStyleOption
|
||||
{
|
||||
double margins;
|
||||
QIcon pinnedIcon = QIcon(":/curveeditor/images/treeview_pin.png");
|
||||
QIcon unpinnedIcon = QIcon(":/curveeditor/images/treeview_unpin.png");
|
||||
QIcon lockedIcon = QIcon(":/curveeditor/images/treeview_lock.png");
|
||||
QIcon unlockedIcon = QIcon(":/curveeditor/images/treeview_unlock.png");
|
||||
|
||||
QIcon pinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin);
|
||||
QIcon unpinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::unpin);
|
||||
QIcon implicitlyPinnedIcon = iconFromFont(QmlDesigner::Theme::Icon::pin, Qt::gray);
|
||||
QIcon lockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn);
|
||||
QIcon unlockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOff);
|
||||
QIcon implicitlyLockedIcon = iconFromFont(QmlDesigner::Theme::Icon::lockOn, Qt::gray);
|
||||
|
||||
static QIcon iconFromFont(QmlDesigner::Theme::Icon type, const QColor &color = Qt::white)
|
||||
{
|
||||
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||
static const int fontSize = 28;
|
||||
static const int iconSize = 28;
|
||||
return Utils::StyleHelper::getIconFromIconFont(fontName,
|
||||
QmlDesigner::Theme::getIconUnicode(type),
|
||||
fontSize,
|
||||
iconSize,
|
||||
color);
|
||||
}
|
||||
};
|
||||
|
||||
struct HandleItemStyleOption
|
||||
@@ -122,15 +139,15 @@ struct CurveEditorStyle
|
||||
QColor iconColor = QColor(128, 128, 128);
|
||||
QColor iconHoverColor = QColor(170, 170, 170);
|
||||
QColor gridColor = QColor(128, 128, 128);
|
||||
double canvasMargin = 5.0;
|
||||
int canvasMargin = 5;
|
||||
int zoomInWidth = 100;
|
||||
int zoomInHeight = 100;
|
||||
double timeAxisHeight = 40.0;
|
||||
int timeAxisHeight = 40;
|
||||
double timeOffsetLeft = 10.0;
|
||||
double timeOffsetRight = 10.0;
|
||||
QColor rangeBarColor = QColor(128, 128, 128);
|
||||
QColor rangeBarCapsColor = QColor(50, 50, 255);
|
||||
double valueAxisWidth = 60.0;
|
||||
int valueAxisWidth = 60;
|
||||
double valueOffsetTop = 10.0;
|
||||
double valueOffsetBottom = 10.0;
|
||||
double labelDensityY = 2.0;
|
||||
@@ -151,4 +168,4 @@ inline QPixmap pixmapFromIcon(const QIcon &icon, const QSize &size, const QColor
|
||||
return mask;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "curveeditor.h"
|
||||
#include "curveeditormodel.h"
|
||||
#include "curvesegment.h"
|
||||
#include "treeitem.h"
|
||||
|
||||
#include <bindingproperty.h>
|
||||
#include <easingcurve.h>
|
||||
@@ -42,29 +43,14 @@ namespace QmlDesigner {
|
||||
CurveEditorView::CurveEditorView(QObject *parent)
|
||||
: AbstractView(parent)
|
||||
, m_block(false)
|
||||
, m_model(new DesignTools::CurveEditorModel())
|
||||
, m_editor(new DesignTools::CurveEditor(m_model))
|
||||
, m_model(new CurveEditorModel())
|
||||
, m_editor(new CurveEditor(m_model))
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
connect(m_model,
|
||||
&DesignTools::CurveEditorModel::commitCurrentFrame,
|
||||
this,
|
||||
&CurveEditorView::commitCurrentFrame);
|
||||
|
||||
connect(m_model,
|
||||
&DesignTools::CurveEditorModel::commitStartFrame,
|
||||
this,
|
||||
&CurveEditorView::commitStartFrame);
|
||||
|
||||
connect(m_model,
|
||||
&DesignTools::CurveEditorModel::commitEndFrame,
|
||||
this,
|
||||
&CurveEditorView::commitEndFrame);
|
||||
|
||||
connect(m_model,
|
||||
&DesignTools::CurveEditorModel::curveChanged,
|
||||
this,
|
||||
&CurveEditorView::commitKeyframes);
|
||||
connect(m_model, &CurveEditorModel::commitCurrentFrame, this, &CurveEditorView::commitCurrentFrame);
|
||||
connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame);
|
||||
connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame);
|
||||
connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes);
|
||||
}
|
||||
|
||||
CurveEditorView::~CurveEditorView() {}
|
||||
@@ -134,6 +120,18 @@ void CurveEditorView::nodeReparented(const ModelNode &node,
|
||||
updateKeyframes();
|
||||
}
|
||||
|
||||
void CurveEditorView::auxiliaryDataChanged(const ModelNode &node,
|
||||
const PropertyName &name,
|
||||
const QVariant &data)
|
||||
{
|
||||
if (name == "locked") {
|
||||
if (auto *item = m_model->find(node.id())) {
|
||||
QSignalBlocker blocker(m_model);
|
||||
m_model->setLocked(item, data.toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEditorView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName>> &propertyList)
|
||||
{
|
||||
Q_UNUSED(propertyList);
|
||||
@@ -261,9 +259,9 @@ void CurveEditorView::updateEndFrame(const ModelNode &node)
|
||||
m_model->setMaximumTime(static_cast<int>(std::round(timeline.endKeyframe())));
|
||||
}
|
||||
|
||||
ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline &timeline)
|
||||
ModelNode getTargetNode(PropertyTreeItem *item, const QmlTimeline &timeline)
|
||||
{
|
||||
if (const DesignTools::NodeTreeItem *nodeItem = item->parentNodeTreeItem()) {
|
||||
if (const NodeTreeItem *nodeItem = item->parentNodeTreeItem()) {
|
||||
QString targetId = nodeItem->name();
|
||||
if (timeline.isValid()) {
|
||||
for (auto &&target : timeline.allTargets()) {
|
||||
@@ -275,17 +273,16 @@ ModelNode getTargetNode1(DesignTools::PropertyTreeItem *item, const QmlTimeline
|
||||
return ModelNode();
|
||||
}
|
||||
|
||||
QmlTimelineKeyframeGroup timelineKeyframeGroup1(QmlTimeline &timeline,
|
||||
DesignTools::PropertyTreeItem *item)
|
||||
QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline, PropertyTreeItem *item)
|
||||
{
|
||||
ModelNode node = getTargetNode1(item, timeline);
|
||||
ModelNode node = getTargetNode(item, timeline);
|
||||
if (node.isValid())
|
||||
return timeline.keyframeGroup(node, item->name().toLatin1());
|
||||
|
||||
return QmlTimelineKeyframeGroup();
|
||||
}
|
||||
|
||||
void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimelineKeyframeGroup &group)
|
||||
void attachEasingCurve(const QmlTimelineKeyframeGroup &group, double frame, const QEasingCurve &curve)
|
||||
{
|
||||
ModelNode frameNode = group.keyframe(frame);
|
||||
if (frameNode.isValid()) {
|
||||
@@ -294,61 +291,73 @@ void attachEasingCurve1(double frame, const QEasingCurve &curve, const QmlTimeli
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEditorView::commitKeyframes(DesignTools::PropertyTreeItem *item)
|
||||
void commitAuxiliaryData(ModelNode &node, TreeItem *item)
|
||||
{
|
||||
QmlTimeline currentTimeline = activeTimeline();
|
||||
QmlTimelineKeyframeGroup group = timelineKeyframeGroup1(currentTimeline, item);
|
||||
if (node.isValid()) {
|
||||
if (item->locked())
|
||||
node.setAuxiliaryData("locked", true);
|
||||
else
|
||||
node.removeAuxiliaryData("locked");
|
||||
|
||||
if (group.isValid()) {
|
||||
ModelNode groupNode = group.modelNode();
|
||||
if (item->pinned())
|
||||
node.setAuxiliaryData("pinned", true);
|
||||
else
|
||||
node.removeAuxiliaryData("pinned");
|
||||
|
||||
if (groupNode.isValid()) {
|
||||
if (item->locked())
|
||||
groupNode.setAuxiliaryData("locked", true);
|
||||
if (auto *pitem = item->asPropertyItem()) {
|
||||
if (pitem->hasUnified())
|
||||
node.setAuxiliaryData("unified", pitem->unifyString());
|
||||
else
|
||||
groupNode.removeAuxiliaryData("locked");
|
||||
|
||||
if (item->pinned())
|
||||
groupNode.setAuxiliaryData("pinned", true);
|
||||
else
|
||||
groupNode.removeAuxiliaryData("pinned");
|
||||
|
||||
if (item->hasUnified())
|
||||
groupNode.setAuxiliaryData("unified", item->unifyString());
|
||||
else
|
||||
groupNode.removeAuxiliaryData("unified");
|
||||
node.removeAuxiliaryData("unified");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto replaceKeyframes = [&group, item, this]() {
|
||||
m_block = true;
|
||||
for (auto frame : group.keyframes())
|
||||
frame.destroy();
|
||||
void CurveEditorView::commitKeyframes(TreeItem *item)
|
||||
{
|
||||
if (auto *nitem = item->asNodeItem()) {
|
||||
ModelNode node = modelNodeForId(nitem->name());
|
||||
commitAuxiliaryData(node, item);
|
||||
|
||||
DesignTools::Keyframe previous;
|
||||
for (auto &&frame : item->curve().keyframes()) {
|
||||
QPointF pos = frame.position();
|
||||
group.setValue(QVariant(pos.y()), pos.x());
|
||||
} else if (auto *pitem = item->asPropertyItem()) {
|
||||
QmlTimeline currentTimeline = activeTimeline();
|
||||
QmlTimelineKeyframeGroup group = timelineKeyframeGroup(currentTimeline, pitem);
|
||||
|
||||
if (previous.isValid()) {
|
||||
if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Bezier) {
|
||||
DesignTools::CurveSegment segment(previous, frame);
|
||||
if (segment.isValid())
|
||||
attachEasingCurve1(pos.x(), segment.easingCurve(), group);
|
||||
} else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Easing) {
|
||||
QVariant data = frame.data();
|
||||
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
|
||||
attachEasingCurve1(pos.x(), data.value<QEasingCurve>(), group);
|
||||
} else if (frame.interpolation() == DesignTools::Keyframe::Interpolation::Step) {
|
||||
// Warning: Keyframe::Interpolation::Step not yet implemented
|
||||
if (group.isValid()) {
|
||||
ModelNode groupNode = group.modelNode();
|
||||
commitAuxiliaryData(groupNode, item);
|
||||
|
||||
auto replaceKeyframes = [&group, pitem, this]() {
|
||||
m_block = true;
|
||||
for (auto frame : group.keyframes())
|
||||
frame.destroy();
|
||||
|
||||
Keyframe previous;
|
||||
for (auto &&frame : pitem->curve().keyframes()) {
|
||||
QPointF pos = frame.position();
|
||||
group.setValue(QVariant(pos.y()), pos.x());
|
||||
|
||||
if (previous.isValid()) {
|
||||
if (frame.interpolation() == Keyframe::Interpolation::Bezier) {
|
||||
CurveSegment segment(previous, frame);
|
||||
if (segment.isValid())
|
||||
attachEasingCurve(group, pos.x(), segment.easingCurve());
|
||||
} else if (frame.interpolation() == Keyframe::Interpolation::Easing) {
|
||||
QVariant data = frame.data();
|
||||
if (data.type() == static_cast<int>(QMetaType::QEasingCurve))
|
||||
attachEasingCurve(group, pos.x(), data.value<QEasingCurve>());
|
||||
} else if (frame.interpolation() == Keyframe::Interpolation::Step) {
|
||||
// Warning: Keyframe::Interpolation::Step not yet implemented
|
||||
}
|
||||
}
|
||||
|
||||
previous = frame;
|
||||
}
|
||||
m_block = false;
|
||||
};
|
||||
|
||||
previous = frame;
|
||||
}
|
||||
m_block = false;
|
||||
};
|
||||
|
||||
executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes);
|
||||
executeInTransaction("CurveEditor::commitKeyframes", replaceKeyframes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,10 @@ public:
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
PropertyChangeFlags propertyChange) override;
|
||||
|
||||
void auxiliaryDataChanged(const ModelNode &node,
|
||||
const PropertyName &name,
|
||||
const QVariant &data) override;
|
||||
|
||||
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName>> &propertyList) override;
|
||||
|
||||
void variantPropertiesChanged(const QList<VariantProperty> &propertyList,
|
||||
@@ -77,15 +81,15 @@ private:
|
||||
void updateStartFrame(const ModelNode &node);
|
||||
void updateEndFrame(const ModelNode &node);
|
||||
|
||||
void commitKeyframes(DesignTools::PropertyTreeItem *item);
|
||||
void commitKeyframes(TreeItem *item);
|
||||
void commitCurrentFrame(int frame);
|
||||
void commitStartFrame(int frame);
|
||||
void commitEndFrame(int frame);
|
||||
|
||||
private:
|
||||
bool m_block;
|
||||
DesignTools::CurveEditorModel *m_model;
|
||||
DesignTools::CurveEditor *m_editor;
|
||||
CurveEditorModel *m_model;
|
||||
CurveEditor *m_editor;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CubicPolynomial
|
||||
{
|
||||
@@ -566,4 +566,4 @@ void CurveSegment::setInterpolation(const Keyframe::Interpolation &interpol)
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -36,7 +36,7 @@ class QEasingCurve;
|
||||
class QPainterPath;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CurveSegment
|
||||
{
|
||||
@@ -97,4 +97,4 @@ private:
|
||||
Keyframe m_right;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
// The following is based on: "An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes"
|
||||
// by Justin Talbot, Sharon Lin and Pat Hanrahan.
|
||||
@@ -210,4 +210,4 @@ Axis Axis::compute(double dmin, double dmax, double height, double pt)
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <QToolBar>
|
||||
#include <QWidget>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct Axis
|
||||
{
|
||||
@@ -39,4 +39,4 @@ struct Axis
|
||||
double lstep;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -30,7 +30,9 @@
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace StyleEditor {
|
||||
|
||||
ColorControl::ColorControl()
|
||||
: QWidget(nullptr)
|
||||
@@ -98,4 +100,6 @@ void ColorControl::mousePressEvent(QMouseEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace StyleEditor.
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,9 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace StyleEditor {
|
||||
|
||||
class ColorControl : public QWidget
|
||||
{
|
||||
@@ -60,4 +62,6 @@ private:
|
||||
QColor m_color;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace StyleEditor.
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
QHBoxLayout *createRow(const QString &title, QWidget *widget)
|
||||
{
|
||||
@@ -50,35 +50,35 @@ QHBoxLayout *createRow(const QString &title, QWidget *widget)
|
||||
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_background(new StyleEditor::ColorControl(style.backgroundBrush.color()))
|
||||
, m_backgroundAlternate(new StyleEditor::ColorControl(style.backgroundAlternateBrush.color()))
|
||||
, m_fontColor(new StyleEditor::ColorControl(style.fontColor))
|
||||
, m_gridColor(new StyleEditor::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_rangeBarColor(new StyleEditor::ColorControl(style.rangeBarCapsColor))
|
||||
, m_rangeBarCapsColor(new StyleEditor::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_handleColor(new StyleEditor::ColorControl(style.handleStyle.color))
|
||||
, m_handleSelectionColor(new StyleEditor::ColorControl(style.handleStyle.selectionColor))
|
||||
, m_keyframeSize(new QDoubleSpinBox())
|
||||
, m_keyframeColor(new ColorControl(style.keyframeStyle.color))
|
||||
, m_keyframeSelectionColor(new ColorControl(style.keyframeStyle.selectionColor))
|
||||
, m_keyframeColor(new StyleEditor::ColorControl(style.keyframeStyle.color))
|
||||
, m_keyframeSelectionColor(new StyleEditor::ColorControl(style.keyframeStyle.selectionColor))
|
||||
, m_curveWidth(new QDoubleSpinBox())
|
||||
, m_curveColor(new ColorControl(style.curveStyle.color))
|
||||
, m_curveSelectionColor(new ColorControl(style.curveStyle.selectionColor))
|
||||
, m_curveColor(new StyleEditor::ColorControl(style.curveStyle.color))
|
||||
, m_curveSelectionColor(new StyleEditor::ColorControl(style.curveStyle.selectionColor))
|
||||
, m_treeMargins(new QDoubleSpinBox())
|
||||
, m_playheadWidth(new QDoubleSpinBox())
|
||||
, m_playheadRadius(new QDoubleSpinBox())
|
||||
, m_playheadColor(new ColorControl(style.playhead.color))
|
||||
, m_playheadColor(new StyleEditor::ColorControl(style.playhead.color))
|
||||
|
||||
{
|
||||
setWindowFlag(Qt::Tool, true);
|
||||
@@ -111,35 +111,35 @@ CurveEditorStyleDialog::CurveEditorStyleDialog(CurveEditorStyle &style, QWidget
|
||||
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_background, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_backgroundAlternate, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_fontColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_gridColor, &StyleEditor::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_rangeBarColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_rangeBarCapsColor, &StyleEditor::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_handleColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_handleSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeSize, doubleSignal, doubleChanged);
|
||||
connect(m_keyframeColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeSelectionColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_keyframeSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveWidth, doubleSignal, doubleChanged);
|
||||
connect(m_curveColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveSelectionColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_curveSelectionColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
connect(m_treeMargins, doubleSignal, doubleChanged);
|
||||
connect(m_playheadWidth, doubleSignal, doubleChanged);
|
||||
connect(m_playheadRadius, doubleSignal, doubleChanged);
|
||||
connect(m_playheadColor, &ColorControl::valueChanged, colorChanged);
|
||||
connect(m_playheadColor, &StyleEditor::ColorControl::valueChanged, colorChanged);
|
||||
|
||||
auto *box = new QVBoxLayout;
|
||||
box->addLayout(createRow("Background Color", m_background));
|
||||
@@ -266,4 +266,4 @@ void CurveEditorStyleDialog::printStyle()
|
||||
qDebug() << "";
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -34,9 +34,11 @@ class QSpinBox;
|
||||
class QDoubleSpinBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace StyleEditor {
|
||||
class ColorControl;
|
||||
}
|
||||
|
||||
struct CurveEditorStyle;
|
||||
|
||||
@@ -60,13 +62,13 @@ private:
|
||||
private:
|
||||
QPushButton *m_printButton;
|
||||
|
||||
ColorControl *m_background;
|
||||
StyleEditor::ColorControl *m_background;
|
||||
|
||||
ColorControl *m_backgroundAlternate;
|
||||
StyleEditor::ColorControl *m_backgroundAlternate;
|
||||
|
||||
ColorControl *m_fontColor;
|
||||
StyleEditor::ColorControl *m_fontColor;
|
||||
|
||||
ColorControl *m_gridColor;
|
||||
StyleEditor::ColorControl *m_gridColor;
|
||||
|
||||
QDoubleSpinBox *m_canvasMargin;
|
||||
|
||||
@@ -80,9 +82,9 @@ private:
|
||||
|
||||
QDoubleSpinBox *m_timeOffsetRight;
|
||||
|
||||
ColorControl *m_rangeBarColor;
|
||||
StyleEditor::ColorControl *m_rangeBarColor;
|
||||
|
||||
ColorControl *m_rangeBarCapsColor;
|
||||
StyleEditor::ColorControl *m_rangeBarCapsColor;
|
||||
|
||||
QDoubleSpinBox *m_valueAxisWidth;
|
||||
|
||||
@@ -95,23 +97,23 @@ private:
|
||||
|
||||
QDoubleSpinBox *m_handleLineWidth;
|
||||
|
||||
ColorControl *m_handleColor;
|
||||
StyleEditor::ColorControl *m_handleColor;
|
||||
|
||||
ColorControl *m_handleSelectionColor;
|
||||
StyleEditor::ColorControl *m_handleSelectionColor;
|
||||
|
||||
// KeyframeItem
|
||||
QDoubleSpinBox *m_keyframeSize;
|
||||
|
||||
ColorControl *m_keyframeColor;
|
||||
StyleEditor::ColorControl *m_keyframeColor;
|
||||
|
||||
ColorControl *m_keyframeSelectionColor;
|
||||
StyleEditor::ColorControl *m_keyframeSelectionColor;
|
||||
|
||||
// CurveItem
|
||||
QDoubleSpinBox *m_curveWidth;
|
||||
|
||||
ColorControl *m_curveColor;
|
||||
StyleEditor::ColorControl *m_curveColor;
|
||||
|
||||
ColorControl *m_curveSelectionColor;
|
||||
StyleEditor::ColorControl *m_curveSelectionColor;
|
||||
|
||||
// TreeItem
|
||||
QDoubleSpinBox *m_treeMargins;
|
||||
@@ -121,7 +123,7 @@ private:
|
||||
|
||||
QDoubleSpinBox *m_playheadRadius;
|
||||
|
||||
ColorControl *m_playheadColor;
|
||||
StyleEditor::ColorControl *m_playheadColor;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -35,13 +35,13 @@
|
||||
#include <cmath>
|
||||
#include <sstream>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
CurveItem::CurveItem(QGraphicsItem *parent)
|
||||
: CurveEditorItem(parent)
|
||||
, m_id(0)
|
||||
, m_style()
|
||||
, m_type(ValueType::Undefined)
|
||||
, m_type(PropertyTreeItem::ValueType::Undefined)
|
||||
, m_component(PropertyTreeItem::Component::Generic)
|
||||
, m_transform()
|
||||
, m_keyframes()
|
||||
@@ -52,7 +52,7 @@ CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem
|
||||
: CurveEditorItem(parent)
|
||||
, m_id(id)
|
||||
, m_style()
|
||||
, m_type(ValueType::Undefined)
|
||||
, m_type(PropertyTreeItem::ValueType::Undefined)
|
||||
, m_component(PropertyTreeItem::Component::Generic)
|
||||
, m_transform()
|
||||
, m_keyframes()
|
||||
@@ -225,7 +225,7 @@ unsigned int CurveItem::id() const
|
||||
return m_id;
|
||||
}
|
||||
|
||||
ValueType CurveItem::valueType() const
|
||||
PropertyTreeItem::ValueType CurveItem::valueType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
@@ -385,7 +385,7 @@ void CurveItem::setHandleVisibility(bool visible)
|
||||
frame->setHandleVisibility(visible);
|
||||
}
|
||||
|
||||
void CurveItem::setValueType(ValueType type)
|
||||
void CurveItem::setValueType(PropertyTreeItem::ValueType type)
|
||||
{
|
||||
m_type = type;
|
||||
}
|
||||
@@ -508,4 +508,4 @@ void CurveItem::emitCurveChanged()
|
||||
update();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#include <string>
|
||||
#include <QGraphicsObject>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AnimationCurve;
|
||||
class KeyframeItem;
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
|
||||
unsigned int id() const;
|
||||
|
||||
ValueType valueType() const;
|
||||
PropertyTreeItem::ValueType valueType() const;
|
||||
|
||||
PropertyTreeItem::Component component() const;
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
|
||||
void setHandleVisibility(bool visible);
|
||||
|
||||
void setValueType(ValueType type);
|
||||
void setValueType(PropertyTreeItem::ValueType type);
|
||||
|
||||
void setComponent(PropertyTreeItem::Component comp);
|
||||
|
||||
@@ -140,7 +140,7 @@ private:
|
||||
|
||||
CurveItemStyleOption m_style;
|
||||
|
||||
ValueType m_type;
|
||||
PropertyTreeItem::ValueType m_type;
|
||||
|
||||
PropertyTreeItem::Component m_component;
|
||||
|
||||
@@ -151,4 +151,4 @@ private:
|
||||
bool m_itemDirty;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -33,7 +33,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
GraphicsScene::GraphicsScene(QObject *parent)
|
||||
: QGraphicsScene(parent)
|
||||
@@ -236,9 +236,34 @@ void GraphicsScene::doNotMoveItems(bool val)
|
||||
m_doNotMoveItems = val;
|
||||
}
|
||||
|
||||
void GraphicsScene::removeCurveItem(unsigned int id)
|
||||
{
|
||||
CurveItem *tmp = nullptr;
|
||||
for (auto *curve : m_curves) {
|
||||
if (curve->id() == id) {
|
||||
removeItem(curve);
|
||||
tmp = curve;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp) {
|
||||
Q_UNUSED(m_curves.removeOne(tmp));
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void GraphicsScene::addCurveItem(CurveItem *item)
|
||||
{
|
||||
m_dirty = true;
|
||||
for (auto *curve : m_curves) {
|
||||
if (curve->id() == item->id()) {
|
||||
delete item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
item->setDirty(false);
|
||||
item->connect(this);
|
||||
addItem(item);
|
||||
@@ -249,6 +274,8 @@ void GraphicsScene::addCurveItem(CurveItem *item)
|
||||
m_curves.push_back(item);
|
||||
|
||||
resetZValues();
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void GraphicsScene::moveToBottom(CurveItem *item)
|
||||
@@ -449,4 +476,4 @@ void GraphicsScene::resetZValues()
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <QGraphicsScene>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AnimationCurve;
|
||||
class CurveItem;
|
||||
@@ -95,6 +95,8 @@ public:
|
||||
|
||||
void doNotMoveItems(bool tmp);
|
||||
|
||||
void removeCurveItem(unsigned int id);
|
||||
|
||||
void addCurveItem(CurveItem *item);
|
||||
|
||||
void moveToBottom(CurveItem *item);
|
||||
@@ -140,4 +142,4 @@ private:
|
||||
bool m_doNotMoveItems;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -40,7 +40,7 @@
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||
: QGraphicsView(parent)
|
||||
@@ -75,18 +75,15 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||
|
||||
connect(m_scene, &GraphicsScene::curveChanged, itemSlot);
|
||||
|
||||
auto pinSlot = [this](PropertyTreeItem *pti) { m_scene->setPinned(pti->id(), pti->pinned()); };
|
||||
connect(m_model, &CurveEditorModel::curveChanged, pinSlot);
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
update();
|
||||
|
||||
QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
|
||||
auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged;
|
||||
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
|
||||
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
|
||||
});
|
||||
installEventFilter(filter);
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
update();
|
||||
}
|
||||
|
||||
GraphicsView::~GraphicsView()
|
||||
@@ -189,19 +186,62 @@ void GraphicsView::setStyle(const CurveEditorStyle &style)
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::setLocked(PropertyTreeItem *item)
|
||||
void GraphicsView::setLocked(TreeItem *item)
|
||||
{
|
||||
if (CurveItem *curve = m_scene->findCurve(item->id())) {
|
||||
if (item->locked()) {
|
||||
curve->setLocked(true);
|
||||
m_scene->moveToBottom(curve);
|
||||
} else {
|
||||
curve->setLocked(false);
|
||||
m_scene->moveToTop(curve);
|
||||
if (item->asNodeItem()) {
|
||||
for (auto *ci : item->children())
|
||||
setLocked(ci);
|
||||
} else if (item->asPropertyItem()) {
|
||||
if (CurveItem *curve = m_scene->findCurve(item->id())) {
|
||||
if (item->locked() || item->implicitlyLocked()) {
|
||||
curve->setLocked(true);
|
||||
m_scene->moveToBottom(curve);
|
||||
} else {
|
||||
curve->setLocked(false);
|
||||
m_scene->moveToTop(curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsView::setPinned(TreeItem *item)
|
||||
{
|
||||
auto pin = [this](PropertyTreeItem *pitem, bool pinned) {
|
||||
if (pinned) {
|
||||
if (CurveItem *curve = m_scene->findCurve(pitem->id()))
|
||||
curve->setPinned(pinned);
|
||||
else if (CurveItem *citem = TreeModel::curveItem(pitem))
|
||||
m_scene->addCurveItem(citem);
|
||||
} else if (!pinned) {
|
||||
if (!m_model->isSelected(pitem) && !pitem->pinned())
|
||||
m_scene->removeCurveItem(pitem->id());
|
||||
else if (CurveItem *curve = m_scene->findCurve(pitem->id()))
|
||||
curve->setPinned(pinned);
|
||||
}
|
||||
};
|
||||
|
||||
if (auto *pitem = item->asPropertyItem()) {
|
||||
pin(pitem, pitem->pinned() || pitem->implicitlyPinned());
|
||||
} else if (auto *nitem = item->asNodeItem()) {
|
||||
bool pinned = nitem->pinned();
|
||||
if (!pinned && m_model->isSelected(nitem)) {
|
||||
for (auto *i : nitem->children()) {
|
||||
if (CurveItem *curve = m_scene->findCurve(i->id()))
|
||||
curve->setPinned(pinned);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto *i : nitem->children()) {
|
||||
if (auto *pitem = i->asPropertyItem())
|
||||
pin(pitem, pinned);
|
||||
}
|
||||
}
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::setZoomX(double zoom, const QPoint &pivot)
|
||||
{
|
||||
applyZoom(zoom, m_zoomY, pivot);
|
||||
@@ -228,8 +268,8 @@ void GraphicsView::scrollContent(double x, double y)
|
||||
{
|
||||
QScrollBar *hs = horizontalScrollBar();
|
||||
QScrollBar *vs = verticalScrollBar();
|
||||
hs->setValue(hs->value() + x);
|
||||
vs->setValue(vs->value() + y);
|
||||
hs->setValue(hs->value() + static_cast<int>(x));
|
||||
vs->setValue(vs->value() + static_cast<int>(y));
|
||||
}
|
||||
|
||||
void GraphicsView::reset(const std::vector<CurveItem *> &items)
|
||||
@@ -242,15 +282,19 @@ void GraphicsView::reset(const std::vector<CurveItem *> &items)
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void GraphicsView::updateSelection(const std::vector<CurveItem *> &items)
|
||||
void GraphicsView::updateSelection()
|
||||
{
|
||||
std::vector<CurveItem *> preservedItems = m_scene->takePinnedItems();
|
||||
for (auto *curve : items) {
|
||||
std::vector<CurveItem *> deleteItems;
|
||||
for (auto *curve : m_model->selectedCurves()) {
|
||||
auto finder = [curve](CurveItem *item) { return curve->id() == item->id(); };
|
||||
auto iter = std::find_if(preservedItems.begin(), preservedItems.end(), finder);
|
||||
if (iter == preservedItems.end())
|
||||
preservedItems.push_back(curve);
|
||||
else
|
||||
deleteItems.push_back(curve);
|
||||
}
|
||||
freeClear(deleteItems);
|
||||
reset(preservedItems);
|
||||
}
|
||||
|
||||
@@ -304,7 +348,8 @@ void GraphicsView::mousePressEvent(QMouseEvent *event)
|
||||
QPointF pos = mapToScene(event->pos());
|
||||
if (timeScaleRect().contains(pos)) {
|
||||
m_dragging = true;
|
||||
setCurrentFrame(std::round(mapXtoTime(pos.x())));
|
||||
double t = mapXtoTime(static_cast<int>(pos.x()));
|
||||
setCurrentFrame(roundToInt(t));
|
||||
m_playhead.setMoving(true);
|
||||
event->accept();
|
||||
return;
|
||||
@@ -398,19 +443,18 @@ void GraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
void GraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
painter->fillRect(rect, m_style.backgroundBrush);
|
||||
painter->fillRect(scene()->sceneRect(), m_style.backgroundAlternateBrush);
|
||||
|
||||
drawGrid(painter, rect);
|
||||
drawGrid(painter);
|
||||
}
|
||||
|
||||
int GraphicsView::mapTimeToX(double time) const
|
||||
{
|
||||
return std::round(time * scaleX(m_transform));
|
||||
return roundToInt(time * scaleX(m_transform));
|
||||
}
|
||||
|
||||
int GraphicsView::mapValueToY(double y) const
|
||||
{
|
||||
return std::round(y * scaleY(m_transform));
|
||||
return roundToInt(y * scaleY(m_transform));
|
||||
}
|
||||
|
||||
double GraphicsView::mapXtoTime(int x) const
|
||||
@@ -430,7 +474,7 @@ QPointF GraphicsView::globalToScene(const QPoint &point) const
|
||||
|
||||
QPointF GraphicsView::globalToRaster(const QPoint &point) const
|
||||
{
|
||||
QPointF scene = globalToScene(point);
|
||||
QPoint scene = globalToScene(point).toPoint();
|
||||
return QPointF(mapXtoTime(scene.x()), mapYtoValue(scene.y()));
|
||||
}
|
||||
|
||||
@@ -480,7 +524,7 @@ void GraphicsView::applyZoom(double x, double y, const QPoint &pivot)
|
||||
m_scene->doNotMoveItems(false);
|
||||
}
|
||||
|
||||
void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
|
||||
void GraphicsView::drawGrid(QPainter *painter)
|
||||
{
|
||||
QRectF gridRect = scene()->sceneRect();
|
||||
|
||||
@@ -488,12 +532,16 @@ void GraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
|
||||
return;
|
||||
|
||||
auto drawVerticalLine = [painter, gridRect](double position) {
|
||||
painter->drawLine(position, gridRect.top(), position, gridRect.bottom());
|
||||
QPointF p1(position, gridRect.top());
|
||||
QPointF p2(position, gridRect.bottom());
|
||||
painter->drawLine(p1, p2);
|
||||
};
|
||||
|
||||
painter->save();
|
||||
painter->setPen(m_style.gridColor);
|
||||
|
||||
painter->fillRect(gridRect, m_style.backgroundAlternateBrush);
|
||||
|
||||
double timeIncrement = timeLabelInterval(painter, m_model->maximumTime());
|
||||
for (double i = minimumTime(); i <= maximumTime(); i += timeIncrement)
|
||||
drawVerticalLine(mapTimeToX(i));
|
||||
@@ -635,7 +683,7 @@ double GraphicsView::timeLabelInterval(QPainter *painter, double maxTime)
|
||||
double tickDistance = mapTimeToX(deltaTime);
|
||||
|
||||
while (true) {
|
||||
if (tickDistance == 0 && deltaTime >= maxTime)
|
||||
if (qFuzzyCompare(tickDistance, 0.) && deltaTime >= maxTime)
|
||||
return maxTime;
|
||||
|
||||
if (tickDistance > minTextSpacing)
|
||||
@@ -658,12 +706,12 @@ QRectF GraphicsView::rangeMinHandle(const QRectF &rect)
|
||||
QRectF labelRect = fontMetrics().boundingRect(QString("0"));
|
||||
labelRect.moveCenter(rect.center());
|
||||
|
||||
qreal top = rect.bottom() - 2;
|
||||
qreal bottom = labelRect.bottom() + 2;
|
||||
QSize size(10, top - bottom);
|
||||
qreal top = rect.bottom() - 2.;
|
||||
qreal bottom = labelRect.bottom() + 2.;
|
||||
QSize size(10, roundToInt(top - bottom));
|
||||
|
||||
int leftHandleLeft = mapTimeToX(m_model->minimumTime()) - size.width();
|
||||
return QRectF(QPointF(leftHandleLeft, bottom), size);
|
||||
int handle = mapTimeToX(m_model->minimumTime()) - size.width();
|
||||
return QRectF(QPointF(handle, bottom), size);
|
||||
}
|
||||
|
||||
QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
|
||||
@@ -671,10 +719,13 @@ QRectF GraphicsView::rangeMaxHandle(const QRectF &rect)
|
||||
QRectF labelRect = fontMetrics().boundingRect(QString("0"));
|
||||
labelRect.moveCenter(rect.center());
|
||||
|
||||
qreal bottom = rect.bottom() - 2;
|
||||
qreal top = labelRect.bottom() + 2;
|
||||
qreal bottom = rect.bottom() - 2.;
|
||||
qreal top = labelRect.bottom() + 2.;
|
||||
|
||||
return QRectF(QPointF(mapTimeToX(m_model->maximumTime()), bottom), QSize(10, top - bottom));
|
||||
QSize size(10, roundToInt(top - bottom));
|
||||
int handle = mapTimeToX(m_model->maximumTime());
|
||||
|
||||
return QRectF(QPointF(handle, bottom), size);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -33,12 +33,12 @@
|
||||
|
||||
#include <QGraphicsView>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CurveItem;
|
||||
class CurveEditorModel;
|
||||
class Playhead;
|
||||
class PropertyTreeItem;
|
||||
class TreeItem;
|
||||
|
||||
class GraphicsView : public QGraphicsView
|
||||
{
|
||||
@@ -92,7 +92,9 @@ public:
|
||||
|
||||
QRectF defaultRasterRect() const;
|
||||
|
||||
void setLocked(PropertyTreeItem *item);
|
||||
void setLocked(TreeItem *item);
|
||||
|
||||
void setPinned(TreeItem *item);
|
||||
|
||||
void setStyle(const CurveEditorStyle &style);
|
||||
|
||||
@@ -106,7 +108,7 @@ public:
|
||||
|
||||
void reset(const std::vector<CurveItem *> &items);
|
||||
|
||||
void updateSelection(const std::vector<CurveItem *> &items);
|
||||
void updateSelection();
|
||||
|
||||
void setInterpolation(Keyframe::Interpolation interpol);
|
||||
|
||||
@@ -134,7 +136,7 @@ protected:
|
||||
private:
|
||||
void applyZoom(double x, double y, const QPoint &pivot = QPoint());
|
||||
|
||||
void drawGrid(QPainter *painter, const QRectF &rect);
|
||||
void drawGrid(QPainter *painter);
|
||||
|
||||
#if 0
|
||||
void drawExtremaX(QPainter *painter, const QRectF &rect);
|
||||
@@ -176,4 +178,4 @@ private:
|
||||
CurveEditorStyleDialog m_dialog;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
struct HandleGeometry
|
||||
{
|
||||
@@ -196,4 +196,4 @@ QVariant HandleItem::itemChange(QGraphicsItem::GraphicsItemChange change, const
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include "curveeditorstyle.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class KeyframeItem;
|
||||
class CurveSegment;
|
||||
@@ -77,4 +77,4 @@ private:
|
||||
QPointF m_validPos;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
KeyframeItem::KeyframeItem(QGraphicsItem *parent)
|
||||
: SelectableItem(parent)
|
||||
@@ -408,9 +408,9 @@ QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons
|
||||
if (ok) {
|
||||
position.setX(std::round(position.x()));
|
||||
|
||||
if (curveItem->valueType() == ValueType::Integer)
|
||||
if (curveItem->valueType() == PropertyTreeItem::ValueType::Integer)
|
||||
position.setY(std::round(position.y()));
|
||||
else if (curveItem->valueType() == ValueType::Bool)
|
||||
else if (curveItem->valueType() == PropertyTreeItem::ValueType::Bool)
|
||||
position.setY(position.y() > 0.5 ? 1.0 : 0.0);
|
||||
|
||||
if (!legalLeft() || !legalRight()) {
|
||||
@@ -463,4 +463,4 @@ void KeyframeItem::selectionCallback()
|
||||
m_right->setSelected(selected());
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -32,7 +32,7 @@
|
||||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class HandleItem;
|
||||
|
||||
@@ -134,4 +134,4 @@ private:
|
||||
bool m_visibleOverride = true;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
constexpr double g_playheadMargin = 5.0;
|
||||
|
||||
@@ -149,6 +149,7 @@ void Playhead::mouseMoveOutOfBounds(GraphicsView *view)
|
||||
|
||||
void Playhead::mouseRelease(GraphicsView *view)
|
||||
{
|
||||
Q_UNUSED(view);
|
||||
m_moving = false;
|
||||
}
|
||||
|
||||
@@ -188,4 +189,4 @@ void Playhead::paint(QPainter *painter, GraphicsView *view) const
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -32,7 +32,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QPainter;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class GraphicsView;
|
||||
|
||||
@@ -69,4 +69,4 @@ private:
|
||||
QTimer m_timer;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include "selectableitem.h"
|
||||
#include "keyframeitem.h"
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
CurveEditorItem::CurveEditorItem(QGraphicsItem *parent)
|
||||
: QGraphicsObject(parent)
|
||||
@@ -193,4 +193,4 @@ void SelectableItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
activationCallback();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <QGraphicsObject>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class CurveEditorItem : public QGraphicsObject
|
||||
{
|
||||
@@ -58,13 +58,14 @@ enum ItemType {
|
||||
ItemTypeCurve = QGraphicsItem::UserType + 3
|
||||
};
|
||||
|
||||
enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle };
|
||||
|
||||
class SelectableItem : public CurveEditorItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class SelectionMode : unsigned int { Undefined, Clear, New, Add, Remove, Toggle };
|
||||
|
||||
SelectableItem(QGraphicsItem *parent = nullptr);
|
||||
|
||||
~SelectableItem() override;
|
||||
@@ -102,4 +103,4 @@ private:
|
||||
SelectionMode m_preSelected;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "curveitem.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
SelectionModel::SelectionModel(QAbstractItemModel *model)
|
||||
: QItemSelectionModel(model)
|
||||
@@ -46,10 +46,19 @@ void SelectionModel::select(const QItemSelection &selection,
|
||||
}
|
||||
}
|
||||
|
||||
bool SelectionModel::isSelected(TreeItem *item) const
|
||||
{
|
||||
for (auto *i : selectedTreeItems())
|
||||
if (i->id() == item->id())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<TreeItem::Path> SelectionModel::selectedPaths() const
|
||||
{
|
||||
std::vector<TreeItem::Path> out;
|
||||
for (auto &&item : selectedTreeItems())
|
||||
for (auto *item : selectedTreeItems())
|
||||
out.push_back(item->path());
|
||||
return out;
|
||||
}
|
||||
@@ -112,20 +121,11 @@ void SelectionModel::selectPaths(const std::vector<TreeItem::Path> &selection)
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::changeSelection(const QItemSelection &selected,
|
||||
const QItemSelection &deselected)
|
||||
void SelectionModel::changeSelection(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
Q_UNUSED(selected)
|
||||
Q_UNUSED(deselected)
|
||||
|
||||
std::vector<CurveItem *> curves;
|
||||
const auto ids = selectedIndexes();
|
||||
for (auto &&index : ids) {
|
||||
if (auto *curveItem = TreeModel::curveItem(index))
|
||||
curves.push_back(curveItem);
|
||||
}
|
||||
|
||||
emit curvesSelected(curves);
|
||||
emit curvesSelected();
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
#include <QItemSelectionModel>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TreeItem;
|
||||
class NodeTreeItem;
|
||||
@@ -41,13 +41,14 @@ class SelectionModel : public QItemSelectionModel
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void curvesSelected(const std::vector<CurveItem *> &curves);
|
||||
void curvesSelected();
|
||||
|
||||
public:
|
||||
SelectionModel(QAbstractItemModel *model = nullptr);
|
||||
|
||||
void select(const QItemSelection &selection,
|
||||
QItemSelectionModel::SelectionFlags command) override;
|
||||
void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
|
||||
|
||||
bool isSelected(TreeItem *item) const;
|
||||
|
||||
std::vector<TreeItem::Path> selectedPaths() const;
|
||||
|
||||
@@ -65,4 +66,4 @@ private:
|
||||
void changeSelection(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -36,7 +36,7 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
Selector::Selector() {}
|
||||
|
||||
@@ -139,7 +139,7 @@ void Selector::mouseRelease(QMouseEvent *event, GraphicsScene *scene)
|
||||
bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene)
|
||||
{
|
||||
auto selectWidthTool = [this,
|
||||
tool](SelectionMode mode, const QPointF &pos, GraphicsScene *scene) {
|
||||
tool](SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene) {
|
||||
switch (tool) {
|
||||
case SelectionTool::Lasso:
|
||||
return lassoSelection(mode, pos, scene);
|
||||
@@ -152,19 +152,19 @@ bool Selector::select(const SelectionTool &tool, const QPointF &pos, GraphicsSce
|
||||
|
||||
if (m_shortcut == m_shortcuts.newSelection) {
|
||||
clearSelection(scene);
|
||||
return selectWidthTool(SelectionMode::New, pos, scene);
|
||||
return selectWidthTool(SelectableItem::SelectionMode::New, pos, scene);
|
||||
} else if (m_shortcut == m_shortcuts.addToSelection) {
|
||||
return selectWidthTool(SelectionMode::Add, pos, scene);
|
||||
return selectWidthTool(SelectableItem::SelectionMode::Add, pos, scene);
|
||||
} else if (m_shortcut == m_shortcuts.removeFromSelection) {
|
||||
return selectWidthTool(SelectionMode::Remove, pos, scene);
|
||||
return selectWidthTool(SelectableItem::SelectionMode::Remove, pos, scene);
|
||||
} else if (m_shortcut == m_shortcuts.toggleSelection) {
|
||||
return selectWidthTool(SelectionMode::Toggle, pos, scene);
|
||||
return selectWidthTool(SelectableItem::SelectionMode::Toggle, pos, scene);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
bool Selector::pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
{
|
||||
bool out = false;
|
||||
const auto itemList = scene->items();
|
||||
@@ -190,7 +190,7 @@ bool Selector::pressSelection(SelectionMode mode, const QPointF &pos, GraphicsSc
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
bool Selector::rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
{
|
||||
bool out = false;
|
||||
m_rect.setBottomRight(pos);
|
||||
@@ -201,14 +201,14 @@ bool Selector::rectangleSelection(SelectionMode mode, const QPointF &pos, Graphi
|
||||
keyframeItem->setPreselected(mode);
|
||||
out = true;
|
||||
} else {
|
||||
keyframeItem->setPreselected(SelectionMode::Undefined);
|
||||
keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
bool Selector::lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene)
|
||||
{
|
||||
bool out = false;
|
||||
m_lasso.lineTo(pos);
|
||||
@@ -219,7 +219,7 @@ bool Selector::lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsSc
|
||||
keyframeItem->setPreselected(mode);
|
||||
out = true;
|
||||
} else {
|
||||
keyframeItem->setPreselected(SelectionMode::Undefined);
|
||||
keyframeItem->setPreselected(SelectableItem::SelectionMode::Undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,7 +231,7 @@ void Selector::clearSelection(GraphicsScene *scene)
|
||||
const auto itemList = scene->items();
|
||||
for (auto *item : itemList) {
|
||||
if (auto *frameItem = qgraphicsitem_cast<KeyframeItem *>(item)) {
|
||||
frameItem->setPreselected(SelectionMode::Clear);
|
||||
frameItem->setPreselected(SelectableItem::SelectionMode::Clear);
|
||||
frameItem->applyPreselection();
|
||||
frameItem->setActivated(false, HandleItem::Slot::Left);
|
||||
frameItem->setActivated(false, HandleItem::Slot::Right);
|
||||
@@ -248,4 +248,4 @@ void Selector::applyPreSelection(GraphicsScene *scene)
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,14 +28,12 @@
|
||||
#include "curveeditorstyle.h"
|
||||
#include "selectableitem.h"
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class GraphicsView;
|
||||
class GraphicsScene;
|
||||
class Playhead;
|
||||
|
||||
enum class SelectionTool { Undefined, Lasso, Rectangle };
|
||||
|
||||
class Selector
|
||||
{
|
||||
public:
|
||||
@@ -50,13 +48,15 @@ public:
|
||||
void mouseRelease(QMouseEvent *event, GraphicsScene *scene);
|
||||
|
||||
private:
|
||||
enum class SelectionTool { Undefined, Lasso, Rectangle };
|
||||
|
||||
bool select(const SelectionTool &tool, const QPointF &pos, GraphicsScene *scene);
|
||||
|
||||
bool pressSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
bool pressSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
|
||||
bool rectangleSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
bool rectangleSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
|
||||
bool lassoSelection(SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
bool lassoSelection(SelectableItem::SelectionMode mode, const QPointF &pos, GraphicsScene *scene);
|
||||
|
||||
void clearSelection(GraphicsScene *scene);
|
||||
|
||||
@@ -77,4 +77,4 @@ private:
|
||||
QRectF m_rect;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -24,7 +24,7 @@
|
||||
****************************************************************************/
|
||||
#include "shortcut.h"
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
Shortcut::Shortcut()
|
||||
: m_key()
|
||||
@@ -78,4 +78,4 @@ 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.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Shortcut
|
||||
{
|
||||
@@ -58,4 +58,4 @@ private:
|
||||
Qt::KeyboardModifiers m_modifiers;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -24,13 +24,14 @@
|
||||
****************************************************************************/
|
||||
#include "treeitemdelegate.h"
|
||||
#include "treeitem.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
TreeItemDelegate::TreeItemDelegate(const CurveEditorStyle &style, QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
@@ -50,56 +51,66 @@ QRect makeSquare(const QRect &rect)
|
||||
return r;
|
||||
}
|
||||
|
||||
QPixmap pixmapFromStyle(int column, const CurveEditorStyle &style, const QRect &rect, TreeItem *item, bool underMouse)
|
||||
{
|
||||
QColor color = underMouse ? style.iconHoverColor : style.iconColor;
|
||||
if (column == 1) {
|
||||
bool locked = item->locked();
|
||||
if (underMouse)
|
||||
locked = !locked;
|
||||
|
||||
if (locked)
|
||||
return pixmapFromIcon(style.treeItemStyle.lockedIcon, rect.size(), color);
|
||||
else
|
||||
return pixmapFromIcon(style.treeItemStyle.unlockedIcon, rect.size(), color);
|
||||
}
|
||||
|
||||
bool pinned = item->pinned();
|
||||
if (underMouse)
|
||||
pinned = !pinned;
|
||||
|
||||
if (pinned)
|
||||
return pixmapFromIcon(style.treeItemStyle.pinnedIcon, rect.size(), color);
|
||||
else
|
||||
return pixmapFromIcon(style.treeItemStyle.unpinnedIcon, rect.size(), color);
|
||||
}
|
||||
|
||||
void TreeItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == 1 || index.column() == 2) {
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
QColor high = Theme::getColor(Theme::Color::QmlDesigner_HighlightColor);
|
||||
opt.palette.setColor(QPalette::Active, QPalette::Highlight, high);
|
||||
opt.palette.setColor(QPalette::Inactive, QPalette::Highlight, high);
|
||||
|
||||
QPoint mousePos = QCursor::pos();
|
||||
mousePos = option.widget->mapFromGlobal(mousePos);
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||
|
||||
QRect iconRect = makeSquare(option.rect);
|
||||
bool underMouse = option.rect.contains(m_mousePos)
|
||||
&& option.state & QStyle::State_MouseOver;
|
||||
auto *treeItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||
bool textColumn = TreeModel::isTextColumn(index);
|
||||
bool lockedColumn = TreeModel::isLockedColumn(index);
|
||||
bool pinnedColumn = TreeModel::isPinnedColumn(index);
|
||||
|
||||
QPixmap pixmap = pixmapFromStyle(index.column(), m_style, iconRect, treeItem, underMouse);
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
QPixmap pixmap;
|
||||
QRect iconRect = makeSquare(option.rect);
|
||||
|
||||
if (lockedColumn) {
|
||||
if (treeItem->locked()) {
|
||||
pixmap = m_style.treeItemStyle.lockedIcon.pixmap(iconRect.size());
|
||||
} else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyLocked()) {
|
||||
pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size());
|
||||
} else if (option.state.testFlag(QStyle::State_MouseOver)) {
|
||||
if (treeItem->implicitlyLocked()) {
|
||||
pixmap = m_style.treeItemStyle.implicitlyLockedIcon.pixmap(iconRect.size());
|
||||
} else {
|
||||
pixmap = m_style.treeItemStyle.unlockedIcon.pixmap(iconRect.size());
|
||||
}
|
||||
}
|
||||
|
||||
} else if (pinnedColumn) {
|
||||
if (treeItem->pinned()) {
|
||||
pixmap = m_style.treeItemStyle.pinnedIcon.pixmap(iconRect.size());
|
||||
} else if (treeItem->asNodeItem() != nullptr && treeItem->implicitlyPinned()) {
|
||||
pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size());
|
||||
} else if (option.state.testFlag(QStyle::State_MouseOver)) {
|
||||
if (treeItem->implicitlyPinned()) {
|
||||
pixmap = m_style.treeItemStyle.implicitlyPinnedIcon.pixmap(iconRect.size());
|
||||
} else {
|
||||
pixmap = m_style.treeItemStyle.unpinnedIcon.pixmap(iconRect.size());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
if (textColumn && (treeItem->locked() || treeItem->implicitlyLocked())) {
|
||||
QColor col = opt.palette.color(QPalette::Disabled, QPalette::Text).darker();
|
||||
opt.palette.setColor(QPalette::Active, QPalette::Text, col);
|
||||
opt.palette.setColor(QPalette::Inactive, QPalette::Text, col);
|
||||
}
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
}
|
||||
|
||||
if (!pixmap.isNull())
|
||||
painter->drawPixmap(iconRect, pixmap);
|
||||
}
|
||||
|
||||
void TreeItemDelegate::setStyle(const CurveEditorStyle &style)
|
||||
@@ -118,4 +129,4 @@ bool TreeItemDelegate::editorEvent(QEvent *event,
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class TreeItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
@@ -60,4 +60,4 @@ private:
|
||||
QPoint m_mousePos;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -31,7 +31,22 @@
|
||||
|
||||
#include <QIcon>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
bool TreeModel::isTextColumn(const QModelIndex &index)
|
||||
{
|
||||
return index.column() == 0;
|
||||
}
|
||||
|
||||
bool TreeModel::isLockedColumn(const QModelIndex &index)
|
||||
{
|
||||
return index.column() == 1;
|
||||
}
|
||||
|
||||
bool TreeModel::isPinnedColumn(const QModelIndex &index)
|
||||
{
|
||||
return index.column() == 2;
|
||||
}
|
||||
|
||||
TreeItem *TreeModel::treeItem(const QModelIndex &index)
|
||||
{
|
||||
@@ -71,8 +86,8 @@ CurveItem *TreeModel::curveItem(TreeItem *item)
|
||||
auto *citem = new CurveItem(pti->id(), pti->curve());
|
||||
citem->setValueType(pti->valueType());
|
||||
citem->setComponent(pti->component());
|
||||
citem->setLocked(pti->locked());
|
||||
citem->setPinned(pti->pinned());
|
||||
citem->setLocked(pti->locked() || item->implicitlyLocked());
|
||||
citem->setPinned(pti->pinned() || item->implicitlyPinned());
|
||||
return citem;
|
||||
}
|
||||
|
||||
@@ -183,6 +198,11 @@ void TreeModel::setGraphicsView(GraphicsView *view)
|
||||
m_view = view;
|
||||
}
|
||||
|
||||
TreeView *TreeModel::treeView() const
|
||||
{
|
||||
return m_tree;
|
||||
}
|
||||
|
||||
GraphicsView *TreeModel::graphicsView() const
|
||||
{
|
||||
return m_view;
|
||||
@@ -208,6 +228,36 @@ QModelIndex TreeModel::findIdx(const QString &name, const QModelIndex &parent) c
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
bool TreeModel::isSelected(TreeItem *item) const
|
||||
{
|
||||
if (auto *sm = selectionModel())
|
||||
return sm->isSelected(item);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void addCurvesFromItem(TreeItem *item, std::vector<CurveItem *> &curves)
|
||||
{
|
||||
if (auto *pitem = item->asPropertyItem()) {
|
||||
if (auto *curveItem = TreeModel::curveItem(pitem))
|
||||
curves.push_back(curveItem);
|
||||
} else if (auto *nitem = item->asNodeItem()) {
|
||||
for (auto *child : nitem->children())
|
||||
addCurvesFromItem(child, curves);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CurveItem *> TreeModel::selectedCurves() const
|
||||
{
|
||||
std::vector<CurveItem *> curves;
|
||||
const auto ids = selectionModel()->selectedIndexes();
|
||||
for (auto &&index : ids) {
|
||||
if (auto *treeItem = TreeModel::treeItem(index))
|
||||
addCurvesFromItem(treeItem, curves);
|
||||
}
|
||||
return curves;
|
||||
}
|
||||
|
||||
QModelIndex TreeModel::indexOf(const TreeItem::Path &path) const
|
||||
{
|
||||
QModelIndex parent;
|
||||
@@ -238,4 +288,9 @@ TreeItem *TreeModel::find(unsigned int id)
|
||||
return m_root->find(id);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
TreeItem *TreeModel::find(const QString &id)
|
||||
{
|
||||
return m_root->find(id);
|
||||
}
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -31,13 +31,11 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class GraphicsView;
|
||||
class TreeView;
|
||||
class TreeItem;
|
||||
class CurveItem;
|
||||
class PropertyTreeItem;
|
||||
class SelectionModel;
|
||||
|
||||
class TreeModel : public QAbstractItemModel
|
||||
@@ -45,6 +43,12 @@ class TreeModel : public QAbstractItemModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static bool isTextColumn(const QModelIndex &index);
|
||||
|
||||
static bool isLockedColumn(const QModelIndex &index);
|
||||
|
||||
static bool isPinnedColumn(const QModelIndex &index);
|
||||
|
||||
static TreeItem *treeItem(const QModelIndex &index);
|
||||
|
||||
static NodeTreeItem *nodeItem(const QModelIndex &index);
|
||||
@@ -73,13 +77,23 @@ public:
|
||||
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
bool isSelected(TreeItem *item) const;
|
||||
|
||||
std::vector<CurveItem *> selectedCurves() const;
|
||||
|
||||
QModelIndex indexOf(const TreeItem::Path &path) const;
|
||||
|
||||
TreeItem *find(unsigned int id);
|
||||
|
||||
TreeItem *find(const QString &id);
|
||||
|
||||
void setTreeView(TreeView *view);
|
||||
|
||||
void setGraphicsView(GraphicsView *view);
|
||||
|
||||
protected:
|
||||
TreeView *treeView() const;
|
||||
|
||||
GraphicsView *graphicsView() const;
|
||||
|
||||
SelectionModel *selectionModel() const;
|
||||
@@ -88,8 +102,6 @@ protected:
|
||||
|
||||
TreeItem *root();
|
||||
|
||||
TreeItem *find(unsigned int id);
|
||||
|
||||
QModelIndex findIdx(const QString &name, const QModelIndex &parent) const;
|
||||
|
||||
private:
|
||||
@@ -100,4 +112,4 @@ private:
|
||||
TreeItem *m_root;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,11 +28,12 @@
|
||||
#include "selectionmodel.h"
|
||||
#include "treeitem.h"
|
||||
#include "treeitemdelegate.h"
|
||||
#include "treemodel.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QMouseEvent>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
TreeView::TreeView(CurveEditorModel *model, QWidget *parent)
|
||||
: QTreeView(parent)
|
||||
@@ -105,17 +106,12 @@ 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());
|
||||
if (auto *propertyItem = treeItem->asPropertyItem())
|
||||
emit treeItemLocked(propertyItem);
|
||||
} else if (index.column() == 2) {
|
||||
treeItem->setPinned(!treeItem->pinned());
|
||||
if (auto *propertyItem = treeItem->asPropertyItem())
|
||||
emit treeItemPinned(propertyItem);
|
||||
}
|
||||
if (TreeModel::isLockedColumn(index))
|
||||
emit treeItemLocked(treeItem, !treeItem->locked());
|
||||
else if (TreeModel::isPinnedColumn(index))
|
||||
emit treeItemPinned(treeItem, !treeItem->pinned());
|
||||
}
|
||||
QTreeView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
#include <QTreeView>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class AnimationCurve;
|
||||
class CurveEditorModel;
|
||||
@@ -44,9 +44,9 @@ class TreeView : public QTreeView
|
||||
signals:
|
||||
void curvesSelected(const std::vector<CurveItem *> &curves);
|
||||
|
||||
void treeItemLocked(PropertyTreeItem *item);
|
||||
void treeItemLocked(TreeItem *item, bool val);
|
||||
|
||||
void treeItemPinned(PropertyTreeItem *item);
|
||||
void treeItemPinned(TreeItem *item, bool val);
|
||||
|
||||
public:
|
||||
TreeView(CurveEditorModel *model, QWidget *parent = nullptr);
|
||||
@@ -63,4 +63,4 @@ protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -29,7 +29,7 @@
|
||||
#include <QRectF>
|
||||
#include <QTransform>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
double scaleX(const QTransform &transform)
|
||||
{
|
||||
@@ -92,4 +92,4 @@ QPalette singleColorPalette(const QColor &color)
|
||||
return palette;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <cmath>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QColor;
|
||||
@@ -37,7 +38,7 @@ QT_END_NAMESPACE
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
double scaleX(const QTransform &transform);
|
||||
|
||||
@@ -58,7 +59,7 @@ inline void freeClear(T &vec)
|
||||
}
|
||||
|
||||
template<typename TV, typename TC>
|
||||
inline double clamp(const TV &val, const TC &lo, const TC &hi)
|
||||
inline TV clamp(const TV &val, const TC &lo, const TC &hi)
|
||||
{
|
||||
return val < lo ? lo : (val > hi ? hi : val);
|
||||
}
|
||||
@@ -75,4 +76,10 @@ inline T reverseLerp(double blend, const T &a, const T &b)
|
||||
return (blend - b) / (a - b);
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
template<typename T>
|
||||
inline int roundToInt(const T &val)
|
||||
{
|
||||
return static_cast<int>(std::round(val));
|
||||
}
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
Keyframe::Keyframe()
|
||||
: m_interpolation(Interpolation::Undefined)
|
||||
@@ -193,4 +193,4 @@ std::string toString(Keyframe::Interpolation interpol)
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <QPointF>
|
||||
#include <QVariant>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class Keyframe
|
||||
{
|
||||
@@ -93,4 +93,4 @@ private:
|
||||
|
||||
std::string toString(Keyframe::Interpolation interpol);
|
||||
|
||||
} // End namespace DesignTools.
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -28,7 +28,7 @@
|
||||
#include <QIcon>
|
||||
#include <QVariant>
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
TreeItem::TreeItem(const QString &name)
|
||||
: m_name(name)
|
||||
@@ -123,9 +123,9 @@ bool TreeItem::compare(const std::vector<QString> &path) const
|
||||
int TreeItem::row() const
|
||||
{
|
||||
if (m_parent) {
|
||||
for (int i = 0, total = int(m_parent->m_children.size()); i < total; ++i) {
|
||||
for (size_t i = 0, total = m_parent->m_children.size(); i < total; ++i) {
|
||||
if (m_parent->m_children[i] == this)
|
||||
return i;
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,17 @@ int TreeItem::columnCount() const
|
||||
return 3;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::root() const
|
||||
{
|
||||
TreeItem *p = parent();
|
||||
while (p) {
|
||||
if (!p->parent())
|
||||
return p;
|
||||
p = p->parent();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::parent() const
|
||||
{
|
||||
return m_parent;
|
||||
@@ -154,10 +165,10 @@ TreeItem *TreeItem::parent() const
|
||||
|
||||
TreeItem *TreeItem::child(int row) const
|
||||
{
|
||||
if (row < 0 || row >= static_cast<int>(m_children.size()))
|
||||
if (row < 0 || row >= rowCount())
|
||||
return nullptr;
|
||||
|
||||
return m_children.at(row);
|
||||
return m_children.at(static_cast<size_t>(row));
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::find(unsigned int id) const
|
||||
@@ -173,6 +184,24 @@ TreeItem *TreeItem::find(unsigned int id) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::find(const QString &id) const
|
||||
{
|
||||
for (auto *child : m_children) {
|
||||
if (child->name() == id)
|
||||
return child;
|
||||
|
||||
if (auto *childsChild = child->find(id))
|
||||
return childsChild;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<TreeItem *> TreeItem::children() const
|
||||
{
|
||||
return m_children;
|
||||
}
|
||||
|
||||
QVariant TreeItem::data(int column) const
|
||||
{
|
||||
switch (column) {
|
||||
@@ -205,6 +234,11 @@ QVariant TreeItem::headerData(int column) const
|
||||
}
|
||||
}
|
||||
|
||||
bool TreeItem::operator==(unsigned int id) const
|
||||
{
|
||||
return m_id == id;
|
||||
}
|
||||
|
||||
void TreeItem::setId(unsigned int &id)
|
||||
{
|
||||
m_id = id;
|
||||
@@ -229,9 +263,10 @@ void TreeItem::setPinned(bool pinned)
|
||||
m_pinned = pinned;
|
||||
}
|
||||
|
||||
NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon)
|
||||
NodeTreeItem::NodeTreeItem(const QString &name, const QIcon &icon, const std::vector<QString> &parentIds)
|
||||
: TreeItem(name)
|
||||
, m_icon(icon)
|
||||
, m_parentIds(parentIds)
|
||||
{
|
||||
Q_UNUSED(icon)
|
||||
}
|
||||
@@ -241,6 +276,35 @@ NodeTreeItem *NodeTreeItem::asNodeItem()
|
||||
return this;
|
||||
}
|
||||
|
||||
bool NodeTreeItem::implicitlyLocked() const
|
||||
{
|
||||
TreeItem *r = root();
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
for (auto &&id : m_parentIds) {
|
||||
if (TreeItem *item = r->find(id))
|
||||
if (item->locked())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NodeTreeItem::implicitlyPinned() const
|
||||
{
|
||||
TreeItem *r = root();
|
||||
if (!r)
|
||||
return false;
|
||||
|
||||
for (auto &&id : m_parentIds) {
|
||||
if (TreeItem *item = r->find(id))
|
||||
if (item->pinned())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QIcon NodeTreeItem::icon() const
|
||||
{
|
||||
return m_icon;
|
||||
@@ -257,20 +321,6 @@ std::vector<PropertyTreeItem *> NodeTreeItem::properties() const
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string toString(ValueType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ValueType::Bool:
|
||||
return "Bool";
|
||||
case ValueType::Integer:
|
||||
return "Integer";
|
||||
case ValueType::Double:
|
||||
return "Double";
|
||||
default:
|
||||
return "Undefined";
|
||||
}
|
||||
}
|
||||
|
||||
PropertyTreeItem::PropertyTreeItem(const QString &name,
|
||||
const AnimationCurve &curve,
|
||||
const ValueType &type)
|
||||
@@ -280,6 +330,22 @@ PropertyTreeItem::PropertyTreeItem(const QString &name,
|
||||
, m_curve(curve)
|
||||
{}
|
||||
|
||||
bool PropertyTreeItem::implicitlyLocked() const
|
||||
{
|
||||
if (auto *parentNode = parentNodeTreeItem())
|
||||
return parentNode->locked() || parentNode->implicitlyLocked();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyTreeItem::implicitlyPinned() const
|
||||
{
|
||||
if (auto *parentNode = parentNodeTreeItem())
|
||||
return parentNode->pinned() || parentNode->implicitlyPinned();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PropertyTreeItem *PropertyTreeItem::asPropertyItem()
|
||||
{
|
||||
return this;
|
||||
@@ -296,7 +362,7 @@ const NodeTreeItem *PropertyTreeItem::parentNodeTreeItem() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ValueType PropertyTreeItem::valueType() const
|
||||
PropertyTreeItem::ValueType PropertyTreeItem::valueType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
@@ -331,4 +397,18 @@ void PropertyTreeItem::setComponent(const Component &comp)
|
||||
m_component = comp;
|
||||
}
|
||||
|
||||
} // End namespace DesignTools.
|
||||
std::string toString(PropertyTreeItem::ValueType type)
|
||||
{
|
||||
switch (type) {
|
||||
case PropertyTreeItem::ValueType::Bool:
|
||||
return "Bool";
|
||||
case PropertyTreeItem::ValueType::Integer:
|
||||
return "Integer";
|
||||
case PropertyTreeItem::ValueType::Double:
|
||||
return "Double";
|
||||
default:
|
||||
return "Undefined";
|
||||
}
|
||||
}
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -38,7 +38,7 @@ class QIcon;
|
||||
class QVariant;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace DesignTools {
|
||||
namespace QmlDesigner {
|
||||
|
||||
class NodeTreeItem;
|
||||
class PropertyTreeItem;
|
||||
@@ -48,6 +48,10 @@ class TreeItem
|
||||
public:
|
||||
using Path = std::vector<QString>;
|
||||
|
||||
virtual bool implicitlyLocked() const { return false; }
|
||||
|
||||
virtual bool implicitlyPinned() const { return false; }
|
||||
|
||||
public:
|
||||
TreeItem(const QString &name);
|
||||
|
||||
@@ -81,16 +85,24 @@ public:
|
||||
|
||||
int columnCount() const;
|
||||
|
||||
TreeItem *root() const;
|
||||
|
||||
TreeItem *parent() const;
|
||||
|
||||
TreeItem *child(int row) const;
|
||||
|
||||
TreeItem *find(unsigned int row) const;
|
||||
TreeItem *find(unsigned int id) const;
|
||||
|
||||
TreeItem *find(const QString &id) const;
|
||||
|
||||
std::vector<TreeItem *> children() const;
|
||||
|
||||
QVariant data(int column) const;
|
||||
|
||||
QVariant headerData(int column) const;
|
||||
|
||||
bool operator==(unsigned int id) const;
|
||||
|
||||
void setId(unsigned int &id);
|
||||
|
||||
void addChild(TreeItem *child);
|
||||
@@ -116,37 +128,45 @@ protected:
|
||||
class NodeTreeItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
NodeTreeItem(const QString &name, const QIcon &icon);
|
||||
NodeTreeItem(const QString &name, const QIcon &icon, const std::vector<QString> &parentIds);
|
||||
|
||||
NodeTreeItem *asNodeItem() override;
|
||||
|
||||
bool implicitlyLocked() const override;
|
||||
|
||||
bool implicitlyPinned() const override;
|
||||
|
||||
QIcon icon() const override;
|
||||
|
||||
std::vector<PropertyTreeItem *> properties() const;
|
||||
|
||||
private:
|
||||
QIcon m_icon;
|
||||
};
|
||||
|
||||
enum class ValueType {
|
||||
Undefined,
|
||||
Bool,
|
||||
Integer,
|
||||
Double,
|
||||
std::vector<QString> m_parentIds;
|
||||
};
|
||||
|
||||
std::string toString(ValueType type);
|
||||
|
||||
class PropertyTreeItem : public TreeItem
|
||||
{
|
||||
public:
|
||||
enum class Component { Generic, R, G, B, A, X, Y, Z, W };
|
||||
|
||||
enum class ValueType {
|
||||
Undefined,
|
||||
Bool,
|
||||
Integer,
|
||||
Double,
|
||||
};
|
||||
|
||||
public:
|
||||
PropertyTreeItem(const QString &name, const AnimationCurve &curve, const ValueType &type);
|
||||
|
||||
PropertyTreeItem *asPropertyItem() override;
|
||||
|
||||
bool implicitlyLocked() const override;
|
||||
|
||||
bool implicitlyPinned() const override;
|
||||
|
||||
const NodeTreeItem *parentNodeTreeItem() const;
|
||||
|
||||
ValueType valueType() const;
|
||||
@@ -173,4 +193,6 @@ private:
|
||||
AnimationCurve m_curve;
|
||||
};
|
||||
|
||||
} // End namespace DesignTools.
|
||||
std::string toString(PropertyTreeItem::ValueType type);
|
||||
|
||||
} // End namespace QmlDesigner.
|
||||
|
@@ -347,41 +347,6 @@ void TimelineWidget::scroll(const TimelineUtils::Side &side)
|
||||
m_scrollbar->setValue(m_scrollbar->value() + m_scrollbar->singleStep());
|
||||
}
|
||||
|
||||
ModelNode getTargetNode(DesignTools::PropertyTreeItem *item, const QmlTimeline &timeline)
|
||||
{
|
||||
if (const DesignTools::NodeTreeItem *nodeItem = item->parentNodeTreeItem()) {
|
||||
QString targetId = nodeItem->name();
|
||||
if (timeline.isValid()) {
|
||||
for (auto &&target : timeline.allTargets()) {
|
||||
if (target.displayName() == targetId)
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ModelNode();
|
||||
}
|
||||
|
||||
QmlTimelineKeyframeGroup timelineKeyframeGroup(QmlTimeline &timeline,
|
||||
DesignTools::PropertyTreeItem *item)
|
||||
{
|
||||
ModelNode node = getTargetNode(item, timeline);
|
||||
if (node.isValid())
|
||||
return timeline.keyframeGroup(node, item->name().toLatin1());
|
||||
|
||||
return QmlTimelineKeyframeGroup();
|
||||
}
|
||||
|
||||
void attachEasingCurve(double frame,
|
||||
const QEasingCurve &curve,
|
||||
const QmlTimelineKeyframeGroup &group)
|
||||
{
|
||||
ModelNode frameNode = group.keyframe(frame);
|
||||
if (frameNode.isValid()) {
|
||||
auto expression = EasingCurve(curve).toString();
|
||||
frameNode.bindingProperty("easing.bezierCurve").setExpression(expression);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::selectionChanged()
|
||||
{
|
||||
if (graphicsScene()->hasSelection())
|
||||
|
Reference in New Issue
Block a user