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"
else if (uniformType === "bool")
valueLoader.source = "ValueBool.qml"
// else if (uniformType === "color") // TODO
// valueLoader.sourceComponent = colorValue
else if (uniformType === "color")
valueLoader.source = "ValueColor.qml"
// else if (uniformType === "image") // TODO
// valueLoader.sourceComponent = imageValue
// valueLoader.source = valueImage
else
valueLoader.source = "ValueFloat.qml"
}

View File

@@ -4,13 +4,18 @@
import QtQuick
import QtQuickDesignerTheme
import HelperWidgets as HelperWidgets
import StudioControls as StudioControls
import StudioTheme 1.0 as StudioTheme
import EffectMakerBackend
Row {
id: itemPane
width: parent.width
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
uniform.cpp uniform.h
effectutils.cpp effectutils.h
coloreditorcontextobject.cpp coloreditorcontextobject.h
)
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[DescriptionRole] = "uniformDescription";
roles[ValueRole] = "uniformValue";
roles[BackendValueRole] = "uniformBackendValue";
roles[DefaultValueRole] = "uniformDefaultValue";
roles[MinValueRole] = "uniformMinValue";
roles[MaxValueRole] = "uniformMaxValue";

View File

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

View File

@@ -3,11 +3,13 @@
#include "effectmakerwidget.h"
#include "coloreditorcontextobject.h"
#include "effectmakermodel.h"
#include "effectmakernodesmodel.h"
#include "effectmakerview.h"
#include "qmldesignerconstants.h"
#include "qmldesignerplugin.h"
#include "qqmlcontext.h"
#include "theme.h"
#include <coreplugin/icore.h>
@@ -65,6 +67,10 @@ EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
{"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())},
{"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
reloadQmlSource();
}

View File

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

View File

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