Disable unsupported properties if qtForMCUs is set

When qtForMCUs is enable in the project, disables the action to open
the easing curve editor in the timeline and the actions to set an
interpolation to anything else than linear in the animation curve editor.
Shows the disabled reason in the tooltip and paint non linear curve
segments in the error color and without handles.

Fixes: QDS-10061
Change-Id: I71b2af0dd6f6c10714fceb75ff3ac16c88504adf
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
Knud Dollereder
2023-06-26 15:57:45 +02:00
parent 8537d96270
commit 185ce52561
16 changed files with 142 additions and 40 deletions

View File

@@ -47,7 +47,7 @@ AnimationCurve::AnimationCurve(
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y()); return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
}; };
QVector<QPointF> points = easing.toCubicSpline(); QList<QPointF> points = easing.toCubicSpline();
int numSegments = points.size() / 3; int numSegments = points.size() / 3;
Keyframe current; Keyframe current;

View File

@@ -8,6 +8,7 @@
#include "detail/graphicsview.h" #include "detail/graphicsview.h"
#include "detail/treeview.h" #include "detail/treeview.h"
#include <designermcumanager.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
@@ -106,6 +107,7 @@ CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
auto updateTimeline = [this, model](bool validTimeline) { auto updateTimeline = [this, model](bool validTimeline) {
if (validTimeline) { if (validTimeline) {
updateStatusLine(); updateStatusLine();
updateMcuState();
m_view->setCurrentFrame(m_view->model()->currentFrame(), false); m_view->setCurrentFrame(m_view->model()->currentFrame(), false);
m_toolbar->updateBoundsSilent(model->minimumTime(), model->maximumTime()); m_toolbar->updateBoundsSilent(model->minimumTime(), model->maximumTime());
m_toolbar->show(); m_toolbar->show();
@@ -163,4 +165,11 @@ void CurveEditor::updateStatusLine()
m_statusLine->setText(currentText); m_statusLine->setText(currentText);
} }
void CurveEditor::updateMcuState()
{
bool isMcu = DesignerMcuManager::instance().isMCUProject();
m_toolbar->setIsMcuProject(isMcu);
m_view->setIsMcu(isMcu);
}
} // End namespace QmlDesigner. } // End namespace QmlDesigner.

View File

@@ -38,6 +38,7 @@ protected:
private: private:
void updateStatusLine(); void updateStatusLine();
void updateMcuState();
QLabel *m_infoText; QLabel *m_infoText;

View File

@@ -60,7 +60,9 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
, m_startSpin(nullptr) , m_startSpin(nullptr)
, m_endSpin(nullptr) , m_endSpin(nullptr)
, m_currentSpin(new QSpinBox) , m_currentSpin(new QSpinBox)
, m_stepAction(nullptr)
, m_splineAction(nullptr)
, m_unifyAction(nullptr)
{ {
setFloatable(false); setFloatable(false);
setFixedHeight(Theme::toolbarSize()); setFixedHeight(Theme::toolbarSize());
@@ -68,11 +70,10 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
addSpace(5); addSpace(5);
QAction *tangentLinearAction = addAction(Theme::iconFromName(Theme::linear_medium), "Linear"); QAction *tangentLinearAction = addAction(Theme::iconFromName(Theme::linear_medium), tr("Linear"));
QAction *tangentStepAction = addAction(Theme::iconFromName(Theme::step_medium), "Step"); m_stepAction = addAction(Theme::iconFromName(Theme::step_medium), tr(m_stepLabel));
QAction *tangentSplineAction = addAction(Theme::iconFromName(Theme::bezier_medium), "Spline"); m_splineAction = addAction(Theme::iconFromName(Theme::bezier_medium), tr(m_splineLabel));
m_unifyAction = addAction(Theme::iconFromName(Theme::unify_medium), tr(m_unifyLabel));
QAction *tangentUnifyAction = addAction(Theme::iconFromName(Theme::unify_medium), tr("Unify"));
auto setLinearInterpolation = [this]() { auto setLinearInterpolation = [this]() {
emit interpolationClicked(Keyframe::Interpolation::Linear); emit interpolationClicked(Keyframe::Interpolation::Linear);
@@ -88,9 +89,9 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
}; };
connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation); connect(tangentLinearAction, &QAction::triggered, setLinearInterpolation);
connect(tangentStepAction, &QAction::triggered, setStepInterpolation); connect(m_stepAction, &QAction::triggered, setStepInterpolation);
connect(tangentSplineAction, &QAction::triggered, setSplineInterpolation); connect(m_splineAction, &QAction::triggered, setSplineInterpolation);
connect(tangentUnifyAction, &QAction::triggered, toggleUnifyKeyframe); connect(m_unifyAction, &QAction::triggered, toggleUnifyKeyframe);
auto validateStart = [this](int val) -> bool { auto validateStart = [this](int val) -> bool {
if (m_endSpin==nullptr) if (m_endSpin==nullptr)
@@ -189,6 +190,25 @@ CurveEditorToolBar::CurveEditorToolBar(CurveEditorModel *model, QWidget* parent)
addSpace(5); addSpace(5);
} }
void CurveEditorToolBar::setIsMcuProject(bool isMcu)
{
m_stepAction->setDisabled(isMcu);
m_splineAction->setDisabled(isMcu);
m_unifyAction->setDisabled(isMcu);
static constexpr const char* notSupportedString = QT_TR_NOOP("Not supported for MCUs");
if (isMcu) {
m_stepAction->setText(tr(notSupportedString));
m_splineAction->setText(tr(notSupportedString));
m_unifyAction->setText(tr(notSupportedString));
} else {
m_stepAction->setText(tr(m_stepLabel));
m_splineAction->setText(tr(m_splineLabel));
m_unifyAction->setText(tr(m_unifyLabel));
}
}
void CurveEditorToolBar::setZoom(double zoom) void CurveEditorToolBar::setZoom(double zoom)
{ {
QSignalBlocker blocker(m_zoomSlider); QSignalBlocker blocker(m_zoomSlider);

View File

@@ -50,6 +50,8 @@ signals:
public: public:
CurveEditorToolBar(CurveEditorModel *model, QWidget* parent = nullptr); CurveEditorToolBar(CurveEditorModel *model, QWidget* parent = nullptr);
void setIsMcuProject(bool isMcu);
void setZoom(double zoom); void setZoom(double zoom);
void setCurrentFrame(int current, bool notify); void setCurrentFrame(int current, bool notify);
@@ -65,6 +67,13 @@ private:
ValidatableSpinBox *m_endSpin; ValidatableSpinBox *m_endSpin;
QSpinBox *m_currentSpin; QSpinBox *m_currentSpin;
QSlider *m_zoomSlider; QSlider *m_zoomSlider;
QAction *m_stepAction;
QAction *m_splineAction;
QAction *m_unifyAction;
static constexpr const char* m_stepLabel = QT_TR_NOOP("Step");
static constexpr const char* m_splineLabel = QT_TR_NOOP("Spline");
static constexpr const char* m_unifyLabel = QT_TR_NOOP("Unify");
}; };
} // End namespace QmlDesigner. } // End namespace QmlDesigner.

View File

@@ -165,6 +165,13 @@ bool CurveSegment::isLegal() const
return ex.size() == 0; return ex.size() == 0;
} }
bool CurveSegment::isLegalMcu() const
{
if (interpolation() == Keyframe::Interpolation::Linear)
return isValid();
return false;
}
bool CurveSegment::containsX(double x) const bool CurveSegment::containsX(double x) const
{ {
return m_left.position().x() <= x && m_right.position().x() >= x; return m_left.position().x() <= x && m_right.position().x() >= x;
@@ -243,7 +250,7 @@ void CurveSegment::extendWithEasingCurve(QPainterPath &path, const QEasingCurve
return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y()); return QPointF(start.x() + slope.x() * pos.x(), start.y() + slope.y() * pos.y());
}; };
QVector<QPointF> points = curve.toCubicSpline(); QList<QPointF> points = curve.toCubicSpline();
int numSegments = points.size() / 3; int numSegments = points.size() / 3;
for (int i = 0; i < numSegments; i++) { for (int i = 0; i < numSegments; i++) {
QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3)); QPointF p1 = mapEasing(m_left.position(), m_right.position(), points.at(i * 3));

View File

@@ -27,6 +27,8 @@ public:
bool isLegal() const; bool isLegal() const;
bool isLegalMcu() const;
bool containsX(double x) const; bool containsX(double x) const;
Keyframe left() const; Keyframe left() const;

View File

@@ -23,6 +23,7 @@ CurveItem::CurveItem(unsigned int id, const AnimationCurve &curve, QGraphicsItem
, m_component(PropertyTreeItem::Component::Generic) , m_component(PropertyTreeItem::Component::Generic)
, m_transform() , m_transform()
, m_keyframes() , m_keyframes()
, m_mcu(false)
, m_itemDirty(false) , m_itemDirty(false)
{ {
setFlag(QGraphicsItem::ItemIsMovable, false); setFlag(QGraphicsItem::ItemIsMovable, false);
@@ -96,7 +97,7 @@ void CurveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidg
} else { } else {
if (locked()) if (locked())
pen.setColor(m_style.lockedColor); pen.setColor(m_style.lockedColor);
else if (!segment.isLegal()) else if (!segment.isLegal() || (m_mcu && !segment.isLegalMcu()))
pen.setColor(m_style.errorColor); pen.setColor(m_style.errorColor);
else if (isUnderMouse()) else if (isUnderMouse())
pen.setColor(m_style.hoverColor); pen.setColor(m_style.hoverColor);
@@ -269,14 +270,14 @@ std::vector<AnimationCurve> CurveItem::curves() const
return out; return out;
} }
QVector<KeyframeItem *> CurveItem::keyframes() const QList<KeyframeItem *> CurveItem::keyframes() const
{ {
return m_keyframes; return m_keyframes;
} }
QVector<KeyframeItem *> CurveItem::selectedKeyframes() const QList<KeyframeItem *> CurveItem::selectedKeyframes() const
{ {
QVector<KeyframeItem *> out; QList<KeyframeItem *> out;
for (auto *frame : m_keyframes) { for (auto *frame : m_keyframes) {
if (frame->selected()) if (frame->selected())
out.push_back(frame); out.push_back(frame);
@@ -284,9 +285,9 @@ QVector<KeyframeItem *> CurveItem::selectedKeyframes() const
return out; return out;
} }
QVector<HandleItem *> CurveItem::handles() const QList<HandleItem *> CurveItem::handles() const
{ {
QVector<HandleItem *> out; QList<HandleItem *> out;
for (auto *frame : m_keyframes) { for (auto *frame : m_keyframes) {
if (auto *left = frame->leftHandle()) if (auto *left = frame->leftHandle())
out.push_back(left); out.push_back(left);
@@ -353,6 +354,12 @@ void CurveItem::setDirty(bool dirty)
m_itemDirty = dirty; m_itemDirty = dirty;
} }
void CurveItem::setIsMcu(bool isMcu)
{
m_mcu = isMcu;
setHandleVisibility(!m_mcu);
}
void CurveItem::setHandleVisibility(bool visible) void CurveItem::setHandleVisibility(bool visible)
{ {
for (auto *frame : std::as_const(m_keyframes)) for (auto *frame : std::as_const(m_keyframes))

View File

@@ -77,11 +77,11 @@ public:
std::vector<AnimationCurve> curves() const; std::vector<AnimationCurve> curves() const;
QVector<KeyframeItem *> keyframes() const; QList<KeyframeItem *> keyframes() const;
QVector<KeyframeItem *> selectedKeyframes() const; QList<KeyframeItem *> selectedKeyframes() const;
QVector<HandleItem *> handles() const; QList<HandleItem *> handles() const;
CurveSegment segment(const KeyframeItem *keyframe, HandleItem::Slot slot) const; CurveSegment segment(const KeyframeItem *keyframe, HandleItem::Slot slot) const;
@@ -89,6 +89,8 @@ public:
void setDirty(bool dirty); void setDirty(bool dirty);
void setIsMcu(bool isMcu);
void setHandleVisibility(bool visible); void setHandleVisibility(bool visible);
void setValueType(PropertyTreeItem::ValueType type); void setValueType(PropertyTreeItem::ValueType type);
@@ -126,7 +128,9 @@ private:
QTransform m_transform; QTransform m_transform;
QVector<KeyframeItem *> m_keyframes; QList<KeyframeItem *> m_keyframes;
bool m_mcu;
bool m_itemDirty; bool m_itemDirty;
}; };

View File

@@ -120,14 +120,14 @@ QRectF GraphicsScene::rect() const
return rect; return rect;
} }
QVector<CurveItem *> GraphicsScene::curves() const QList<CurveItem *> GraphicsScene::curves() const
{ {
return m_curves; return m_curves;
} }
QVector<CurveItem *> GraphicsScene::selectedCurves() const QList<CurveItem *> GraphicsScene::selectedCurves() const
{ {
QVector<CurveItem *> out; QList<CurveItem *> out;
for (auto *curve : m_curves) { for (auto *curve : m_curves) {
if (curve->hasSelectedKeyframe()) if (curve->hasSelectedKeyframe())
out.push_back(curve); out.push_back(curve);
@@ -135,18 +135,18 @@ QVector<CurveItem *> GraphicsScene::selectedCurves() const
return out; return out;
} }
QVector<KeyframeItem *> GraphicsScene::keyframes() const QList<KeyframeItem *> GraphicsScene::keyframes() const
{ {
QVector<KeyframeItem *> out; QList<KeyframeItem *> out;
for (auto *curve : m_curves) for (auto *curve : m_curves)
out.append(curve->keyframes()); out.append(curve->keyframes());
return out; return out;
} }
QVector<KeyframeItem *> GraphicsScene::selectedKeyframes() const QList<KeyframeItem *> GraphicsScene::selectedKeyframes() const
{ {
QVector<KeyframeItem *> out; QList<KeyframeItem *> out;
for (auto *curve : m_curves) for (auto *curve : m_curves)
out.append(curve->selectedKeyframes()); out.append(curve->selectedKeyframes());
@@ -191,6 +191,13 @@ void GraphicsScene::setDirty(bool dirty)
m_dirty = dirty; m_dirty = dirty;
} }
void GraphicsScene::setIsMcu(bool isMcu)
{
m_isMcu = isMcu;
for (auto* curve : curves())
curve->setIsMcu(isMcu);
}
void GraphicsScene::reset() void GraphicsScene::reset()
{ {
m_curves.clear(); m_curves.clear();
@@ -244,6 +251,9 @@ void GraphicsScene::removeCurveItem(unsigned int id)
void GraphicsScene::addCurveItem(CurveItem *item) void GraphicsScene::addCurveItem(CurveItem *item)
{ {
if (!item)
return;
for (auto *curve : std::as_const(m_curves)) { for (auto *curve : std::as_const(m_curves)) {
if (curve->id() == item->id()) { if (curve->id() == item->id()) {
delete item; delete item;
@@ -251,6 +261,7 @@ void GraphicsScene::addCurveItem(CurveItem *item)
} }
} }
item->setIsMcu(m_isMcu);
item->setDirty(false); item->setDirty(false);
item->connect(this); item->connect(this);
addItem(item); addItem(item);
@@ -267,6 +278,9 @@ void GraphicsScene::addCurveItem(CurveItem *item)
void GraphicsScene::moveToBottom(CurveItem *item) void GraphicsScene::moveToBottom(CurveItem *item)
{ {
if (!item)
return;
if (m_curves.removeAll(item) > 0) { if (m_curves.removeAll(item) > 0) {
m_curves.push_front(item); m_curves.push_front(item);
resetZValues(); resetZValues();
@@ -275,6 +289,9 @@ void GraphicsScene::moveToBottom(CurveItem *item)
void GraphicsScene::moveToTop(CurveItem *item) void GraphicsScene::moveToTop(CurveItem *item)
{ {
if (!item)
return;
if (m_curves.removeAll(item) > 0) { if (m_curves.removeAll(item) > 0) {
m_curves.push_back(item); m_curves.push_back(item);
resetZValues(); resetZValues();

View File

@@ -54,15 +54,15 @@ public:
QRectF rect() const; QRectF rect() const;
QVector<CurveItem *> curves() const; QList<CurveItem *> curves() const;
QVector<CurveItem *> selectedCurves() const; QList<CurveItem *> selectedCurves() const;
QVector<KeyframeItem *> keyframes() const; QList<KeyframeItem *> keyframes() const;
QVector<KeyframeItem *> selectedKeyframes() const; QList<KeyframeItem *> selectedKeyframes() const;
QVector<HandleItem *> handles() const; QList<HandleItem *> handles() const;
CurveItem *findCurve(unsigned int id) const; CurveItem *findCurve(unsigned int id) const;
@@ -70,6 +70,8 @@ public:
void setDirty(bool dirty); void setDirty(bool dirty);
void setIsMcu(bool isMcu);
void reset(); void reset();
void deleteSelectedKeyframes(); void deleteSelectedKeyframes();
@@ -120,7 +122,7 @@ private:
void resetZValues(); void resetZValues();
QVector<CurveItem *> m_curves; QList<CurveItem *> m_curves;
mutable bool m_dirty; mutable bool m_dirty;
@@ -129,6 +131,8 @@ private:
bool m_doNotMoveItems; bool m_doNotMoveItems;
QElapsedTimer m_usageTimer; QElapsedTimer m_usageTimer;
bool m_isMcu;
}; };
} // End namespace QmlDesigner. } // End namespace QmlDesigner.

View File

@@ -189,6 +189,11 @@ void GraphicsView::setStyle(const CurveEditorStyle &style)
viewport()->update(); viewport()->update();
} }
void GraphicsView::setIsMcu(bool isMcu)
{
m_scene->setIsMcu(isMcu);
}
void GraphicsView::setLocked(TreeItem *item) void GraphicsView::setLocked(TreeItem *item)
{ {
if (item->asNodeItem()) { if (item->asNodeItem()) {

View File

@@ -72,6 +72,8 @@ public:
QRectF defaultRasterRect() const; QRectF defaultRasterRect() const;
void setIsMcu(bool isMcu);
void setLocked(TreeItem *item); void setLocked(TreeItem *item);
void setPinned(TreeItem *item); void setPinned(TreeItem *item);

View File

@@ -187,6 +187,15 @@ void TimelineToolBar::setPlayState(bool state)
m_playing->setChecked(state); m_playing->setChecked(state);
} }
void TimelineToolBar::setIsMcu(bool isMcu)
{
m_curvePicker->setDisabled(isMcu);
if (isMcu)
m_curvePicker->setText(tr("Not Supported for MCUs"));
else
m_curvePicker->setText(tr(m_curveEditorName));
}
void TimelineToolBar::setActionEnabled(const QString &name, bool enabled) void TimelineToolBar::setActionEnabled(const QString &name, bool enabled)
{ {
for (auto *action : actions()) for (auto *action : actions())
@@ -378,14 +387,14 @@ void TimelineToolBar::createCenterControls()
addSpacing(10); addSpacing(10);
auto *curvePicker = createAction(TimelineConstants::C_CURVE_PICKER, m_curvePicker = createAction(TimelineConstants::C_CURVE_PICKER,
Theme::iconFromName(Theme::Icon::curveDesigner_medium), Theme::iconFromName(Theme::Icon::curveDesigner_medium),
tr("Easing Curve Editor"), tr(m_curveEditorName),
QKeySequence(Qt::Key_C)); QKeySequence(Qt::Key_C));
curvePicker->setObjectName("Easing Curve Editor"); m_curvePicker->setObjectName("Easing Curve Editor");
connect(curvePicker, &QAction::triggered, this, &TimelineToolBar::openEasingCurveEditor); connect(m_curvePicker, &QAction::triggered, this, &TimelineToolBar::openEasingCurveEditor);
addAction(curvePicker); addAction(m_curvePicker);
addSpacing(10); addSpacing(10);
@@ -394,7 +403,7 @@ void TimelineToolBar::createCenterControls()
addSpacing(10); addSpacing(10);
auto *curveEditor = new QAction(TimelineIcons::CURVE_PICKER.icon(), tr("Curve Editor")); auto *curveEditor = new QAction(TimelineIcons::CURVE_PICKER.icon(), tr(m_curveEditorName));
addAction(curveEditor); addAction(curveEditor);
#endif #endif
} }

View File

@@ -60,6 +60,7 @@ public:
void setEndFrame(qreal frame); void setEndFrame(qreal frame);
void setScaleFactor(int factor); void setScaleFactor(int factor);
void setPlayState(bool state); void setPlayState(bool state);
void setIsMcu(bool isMcu);
void setActionEnabled(const QString &name, bool enabled); void setActionEnabled(const QString &name, bool enabled);
void removeTimeline(const QmlTimeline &timeline); void removeTimeline(const QmlTimeline &timeline);
@@ -86,7 +87,10 @@ private:
QAction *m_playing = nullptr; QAction *m_playing = nullptr;
QAction *m_recording = nullptr; QAction *m_recording = nullptr;
QAction *m_curvePicker = nullptr;
bool m_blockReflection = false; bool m_blockReflection = false;
static constexpr const char* m_curveEditorName = QT_TR_NOOP("Easing Curve Editor");
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -21,6 +21,7 @@
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <designermcumanager.h>
#include <theme.h> #include <theme.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
@@ -478,6 +479,7 @@ void TimelineWidget::init(int zoom)
// setScaleFactor uses QSignalBlocker. // setScaleFactor uses QSignalBlocker.
m_toolbar->setScaleFactor(zoom); m_toolbar->setScaleFactor(zoom);
m_toolbar->setIsMcu(DesignerMcuManager::instance().isMCUProject());
m_graphicsScene->setZoom(zoom); m_graphicsScene->setZoom(zoom);
} }