QmlDesigner: Add effect maker composition node color value

Since no StudioControls ColorEditor exists, using the HelperWidgets
one and adding dummy context and backend to get it to work.

Task-number: QDS-10404
Change-Id: Ifc1506b4b1f761b6abf4144791f5b0397a90cdf0
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2023-08-24 15:21:52 +03:00
parent c496434ad8
commit 29a207c59f
10 changed files with 322 additions and 5 deletions

View File

@@ -24,10 +24,10 @@ Item {
valueLoader.source = "ValueVec4.qml" valueLoader.source = "ValueVec4.qml"
else if (uniformType === "bool") else if (uniformType === "bool")
valueLoader.source = "ValueBool.qml" valueLoader.source = "ValueBool.qml"
// else if (uniformType === "color") // TODO else if (uniformType === "color")
// valueLoader.sourceComponent = colorValue valueLoader.source = "ValueColor.qml"
// else if (uniformType === "image") // TODO // else if (uniformType === "image") // TODO
// valueLoader.sourceComponent = imageValue // valueLoader.source = valueImage
else else
valueLoader.source = "ValueFloat.qml" valueLoader.source = "ValueFloat.qml"
} }

View File

@@ -4,13 +4,18 @@
import QtQuick import QtQuick
import QtQuickDesignerTheme import QtQuickDesignerTheme
import HelperWidgets as HelperWidgets import HelperWidgets as HelperWidgets
import StudioControls as StudioControls
import StudioTheme 1.0 as StudioTheme import StudioTheme 1.0 as StudioTheme
import EffectMakerBackend import EffectMakerBackend
Row { Row {
id: itemPane
width: parent.width width: parent.width
spacing: 5 spacing: 5
// TODO HelperWidgets.ColorEditor {
backendValue: uniformBackendValue
onValueChanged: uniformValue = convertColorToString(color)
}
} }

View File

@@ -720,6 +720,7 @@ extend_qtc_plugin(QmlDesigner
compositionnode.cpp compositionnode.h compositionnode.cpp compositionnode.h
uniform.cpp uniform.h uniform.cpp uniform.h
effectutils.cpp effectutils.h effectutils.cpp effectutils.h
coloreditorcontextobject.cpp coloreditorcontextobject.h
) )
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner

View File

@@ -0,0 +1,185 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "coloreditorcontextobject.h"
#include <abstractview.h>
#include <bindingproperty.h>
#include <documentmanager.h>
#include <nodemetainfo.h>
#include <rewritingexception.h>
#include <qmldesignerplugin.h>
#include <qmlmodelnodeproxy.h>
#include <qmlobjectnode.h>
#include <qmltimeline.h>
#include <qmltimelinekeyframegroup.h>
#include <variantproperty.h>
#include <coreplugin/messagebox.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QApplication>
#include <QCursor>
#include <QMessageBox>
#include <QQmlContext>
#include <QWindow>
#include <coreplugin/icore.h>
namespace QmlDesigner {
ColorEditorContextObject::ColorEditorContextObject(QQmlContext *context, QObject *parent)
: QObject(parent)
, m_qmlContext(context)
{
}
QString ColorEditorContextObject::convertColorToString(const QVariant &color)
{
QString colorString;
QColor theColor;
if (color.canConvert(QVariant::Color)) {
theColor = color.value<QColor>();
} else if (color.canConvert(QVariant::Vector3D)) {
auto vec = color.value<QVector3D>();
theColor = QColor::fromRgbF(vec.x(), vec.y(), vec.z());
}
colorString = theColor.name(QColor::HexArgb);
return colorString;
}
// TODO: this method is used by the ColorEditor helper widget, check if at all needed?
QColor ColorEditorContextObject::colorFromString(const QString &colorString)
{
return colorString;
}
int ColorEditorContextObject::majorVersion() const
{
return m_majorVersion;
}
void ColorEditorContextObject::setMajorVersion(int majorVersion)
{
if (m_majorVersion == majorVersion)
return;
m_majorVersion = majorVersion;
emit majorVersionChanged();
}
void ColorEditorContextObject::setStateName(const QString &newStateName)
{
if (newStateName == m_stateName)
return;
m_stateName = newStateName;
emit stateNameChanged();
}
void ColorEditorContextObject::setAllStateNames(const QStringList &allStates)
{
if (allStates == m_allStateNames)
return;
m_allStateNames = allStates;
emit allStateNamesChanged();
}
void ColorEditorContextObject::setIsBaseState(bool newIsBaseState)
{
if (newIsBaseState == m_isBaseState)
return;
m_isBaseState = newIsBaseState;
emit isBaseStateChanged();
}
void ColorEditorContextObject::setSelectionChanged(bool newSelectionChanged)
{
if (newSelectionChanged == m_selectionChanged)
return;
m_selectionChanged = newSelectionChanged;
emit selectionChangedChanged();
}
void ColorEditorContextObject::setBackendValues(QQmlPropertyMap *newBackendValues)
{
if (newBackendValues == m_backendValues)
return;
m_backendValues = newBackendValues;
emit backendValuesChanged();
}
void ColorEditorContextObject::setModel(Model *model)
{
m_model = model;
}
void ColorEditorContextObject::triggerSelectionChanged()
{
setSelectionChanged(!m_selectionChanged);
}
void ColorEditorContextObject::hideCursor()
{
if (QApplication::overrideCursor())
return;
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
if (QWidget *w = QApplication::activeWindow())
m_lastPos = QCursor::pos(w->screen());
}
void ColorEditorContextObject::restoreCursor()
{
if (!QApplication::overrideCursor())
return;
QApplication::restoreOverrideCursor();
if (QWidget *w = QApplication::activeWindow())
QCursor::setPos(w->screen(), m_lastPos);
}
void ColorEditorContextObject::holdCursorInPlace()
{
if (!QApplication::overrideCursor())
return;
if (QWidget *w = QApplication::activeWindow())
QCursor::setPos(w->screen(), m_lastPos);
}
int ColorEditorContextObject::devicePixelRatio()
{
if (QWidget *w = QApplication::activeWindow())
return w->devicePixelRatio();
return 1;
}
QStringList ColorEditorContextObject::allStatesForId(const QString &id)
{
if (m_model && m_model->rewriterView()) {
const QmlObjectNode node = m_model->rewriterView()->modelNodeForId(id);
if (node.isValid())
return node.allStateNames();
}
return {};
}
bool ColorEditorContextObject::isBlocked(const QString &) const
{
return false;
}
} // QmlDesigner

View File

@@ -0,0 +1,101 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <model.h>
#include <modelnode.h>
#include <QObject>
#include <QUrl>
#include <QQmlPropertyMap>
#include <QQmlComponent>
#include <QColor>
#include <QPoint>
#include <QMouseEvent>
namespace QmlDesigner {
class ColorEditorContextObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString stateName READ stateName WRITE setStateName NOTIFY stateNameChanged)
Q_PROPERTY(QStringList allStateNames READ allStateNames WRITE setAllStateNames NOTIFY allStateNamesChanged)
Q_PROPERTY(int possibleTypeIndex READ possibleTypeIndex NOTIFY possibleTypeIndexChanged)
Q_PROPERTY(bool isBaseState READ isBaseState WRITE setIsBaseState NOTIFY isBaseStateChanged)
Q_PROPERTY(bool selectionChanged READ selectionChanged WRITE setSelectionChanged NOTIFY selectionChangedChanged)
Q_PROPERTY(int majorVersion READ majorVersion WRITE setMajorVersion NOTIFY majorVersionChanged)
Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
public:
ColorEditorContextObject(QQmlContext *context, QObject *parent = nullptr);
QString stateName() const { return m_stateName; }
QStringList allStateNames() const { return m_allStateNames; }
int possibleTypeIndex() const { return m_possibleTypeIndex; }
bool isBaseState() const { return m_isBaseState; }
bool selectionChanged() const { return m_selectionChanged; }
QQmlPropertyMap *backendValues() const { return m_backendValues; }
Q_INVOKABLE QString convertColorToString(const QVariant &color);
Q_INVOKABLE QColor colorFromString(const QString &colorString);
Q_INVOKABLE void hideCursor();
Q_INVOKABLE void restoreCursor();
Q_INVOKABLE void holdCursorInPlace();
Q_INVOKABLE int devicePixelRatio();
Q_INVOKABLE QStringList allStatesForId(const QString &id);
Q_INVOKABLE bool isBlocked(const QString &propName) const;
int majorVersion() const;
void setMajorVersion(int majorVersion);
void setStateName(const QString &newStateName);
void setAllStateNames(const QStringList &allStates);
void setIsBaseState(bool newIsBaseState);
void setSelectionChanged(bool newSelectionChanged);
void setBackendValues(QQmlPropertyMap *newBackendValues);
void setModel(QmlDesigner::Model *model);
void triggerSelectionChanged();
signals:
void stateNameChanged();
void allStateNamesChanged();
void possibleTypeIndexChanged();
void isBaseStateChanged();
void selectionChangedChanged();
void backendValuesChanged();
void majorVersionChanged();
private:
void updatePossibleTypeIndex();
QQmlContext *m_qmlContext = nullptr;
QString m_stateName;
QStringList m_allStateNames;
int m_possibleTypeIndex = -1;
QString m_currentType;
int m_majorVersion = 1;
QQmlPropertyMap *m_backendValues = nullptr;
Model *m_model = nullptr;
QPoint m_lastPos;
bool m_isBaseState = false;
bool m_selectionChanged = false;
};
} // QmlDesigner

View File

@@ -20,6 +20,7 @@ QHash<int, QByteArray> EffectMakerUniformsModel::roleNames() const
roles[NameRole] = "uniformName"; roles[NameRole] = "uniformName";
roles[DescriptionRole] = "uniformDescription"; roles[DescriptionRole] = "uniformDescription";
roles[ValueRole] = "uniformValue"; roles[ValueRole] = "uniformValue";
roles[BackendValueRole] = "uniformBackendValue";
roles[DefaultValueRole] = "uniformDefaultValue"; roles[DefaultValueRole] = "uniformDefaultValue";
roles[MinValueRole] = "uniformMinValue"; roles[MinValueRole] = "uniformMinValue";
roles[MaxValueRole] = "uniformMaxValue"; roles[MaxValueRole] = "uniformMaxValue";

View File

@@ -30,6 +30,7 @@ private:
NameRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 1,
DescriptionRole, DescriptionRole,
ValueRole, ValueRole,
BackendValueRole,
DefaultValueRole, DefaultValueRole,
MaxValueRole, MaxValueRole,
MinValueRole, MinValueRole,

View File

@@ -3,11 +3,13 @@
#include "effectmakerwidget.h" #include "effectmakerwidget.h"
#include "coloreditorcontextobject.h"
#include "effectmakermodel.h" #include "effectmakermodel.h"
#include "effectmakernodesmodel.h" #include "effectmakernodesmodel.h"
#include "effectmakerview.h" #include "effectmakerview.h"
#include "qmldesignerconstants.h" #include "qmldesignerconstants.h"
#include "qmldesignerplugin.h" #include "qmldesignerplugin.h"
#include "qqmlcontext.h"
#include "theme.h" #include "theme.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -65,6 +67,10 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
{"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())}, {"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())},
{"rootView", QVariant::fromValue(this)}}); {"rootView", QVariant::fromValue(this)}});
auto colorEditorCtx = new ColorEditorContextObject(m_quickWidget->rootContext());
m_quickWidget->rootContext()->setContextObject(colorEditorCtx);
m_quickWidget->rootContext()->setContextProperty("modelNodeBackend", {});
// init the first load of the QML UI elements // init the first load of the QML UI elements
reloadQmlSource(); reloadQmlSource();
} }

View File

@@ -3,6 +3,8 @@
#include "uniform.h" #include "uniform.h"
#include "propertyeditorvalue.h"
#include <QColor> #include <QColor>
#include <QJsonObject> #include <QJsonObject>
#include <QVector2D> #include <QVector2D>
@@ -38,6 +40,9 @@ Uniform::Uniform(const QJsonObject &propObj)
maxValue = propObj.value("maxValue").toString(); maxValue = propObj.value("maxValue").toString();
setValueData(value, defaultValue, minValue, maxValue); setValueData(value, defaultValue, minValue, maxValue);
m_backendValue = new PropertyEditorValue(this);
m_backendValue->setValue(value);
} }
QString Uniform::type() const QString Uniform::type() const
@@ -70,6 +75,11 @@ QVariant Uniform::value() const
return m_value; return m_value;
} }
QVariant Uniform::backendValue() const
{
return QVariant::fromValue(m_backendValue);
}
void Uniform::setValue(const QVariant &newValue) void Uniform::setValue(const QVariant &newValue)
{ {
if (m_value != newValue) { if (m_value != newValue) {

View File

@@ -12,6 +12,8 @@ QT_FORWARD_DECLARE_CLASS(QVector2D)
namespace QmlDesigner { namespace QmlDesigner {
class PropertyEditorValue;
class Uniform : public QObject class Uniform : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -19,6 +21,7 @@ class Uniform : public QObject
Q_PROPERTY(QString uniformName MEMBER m_name CONSTANT) Q_PROPERTY(QString uniformName MEMBER m_name CONSTANT)
Q_PROPERTY(QString uniformType READ type CONSTANT) Q_PROPERTY(QString uniformType READ type CONSTANT)
Q_PROPERTY(QVariant uniformValue READ value WRITE setValue NOTIFY uniformValueChanged) Q_PROPERTY(QVariant uniformValue READ value WRITE setValue NOTIFY uniformValueChanged)
Q_PROPERTY(QVariant uniformBackendValue READ backendValue NOTIFY uniformBackendValueChanged)
Q_PROPERTY(QVariant uniformMinValue MEMBER m_minValue CONSTANT) Q_PROPERTY(QVariant uniformMinValue MEMBER m_minValue CONSTANT)
Q_PROPERTY(QVariant uniformMaxValue MEMBER m_maxValue CONSTANT) Q_PROPERTY(QVariant uniformMaxValue MEMBER m_maxValue CONSTANT)
@@ -43,6 +46,8 @@ public:
QVariant value() const; QVariant value() const;
void setValue(const QVariant &newValue); void setValue(const QVariant &newValue);
QVariant backendValue() const;
QVariant defaultValue() const; QVariant defaultValue() const;
QVariant minValue() const; QVariant minValue() const;
@@ -62,6 +67,7 @@ public:
signals: signals:
void uniformValueChanged(); void uniformValueChanged();
void uniformBackendValueChanged();
private: private:
QString mipmapPropertyName(const QString &name) const; QString mipmapPropertyName(const QString &name) const;
@@ -85,6 +91,7 @@ private:
bool m_useCustomValue = false; bool m_useCustomValue = false;
bool m_enabled = true; bool m_enabled = true;
bool m_enableMipmap = false; bool m_enableMipmap = false;
PropertyEditorValue *m_backendValue = nullptr;
bool operator==(const Uniform &rhs) const noexcept bool operator==(const Uniform &rhs) const noexcept
{ {