forked from qt-creator/qt-creator
QmlDesigner: Add environment and model selectors to material preview
The model and the scene environment used to render material previews can now be selected via buttons next to the preview in material editor. Task-number: QDS-7347 Change-Id: I03089029e8420f80ed65be1c7b7a1ce4581f2fd4 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
<file>mockfiles/images/static_floor.png</file>
|
<file>mockfiles/images/static_floor.png</file>
|
||||||
<file>mockfiles/images/spot.png</file>
|
<file>mockfiles/images/spot.png</file>
|
||||||
<file>mockfiles/images/spot@2x.png</file>
|
<file>mockfiles/images/spot@2x.png</file>
|
||||||
|
<file>mockfiles/images/preview_landscape.hdr</file>
|
||||||
|
<file>mockfiles/images/preview_studio.hdr</file>
|
||||||
<file>mockfiles/qt5/AdjustableArrow.qml</file>
|
<file>mockfiles/qt5/AdjustableArrow.qml</file>
|
||||||
<file>mockfiles/qt5/AreaLightHandle.qml</file>
|
<file>mockfiles/qt5/AreaLightHandle.qml</file>
|
||||||
<file>mockfiles/qt5/Arrow.qml</file>
|
<file>mockfiles/qt5/Arrow.qml</file>
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
<file>mockfiles/images/floor_tex.png</file>
|
<file>mockfiles/images/floor_tex.png</file>
|
||||||
<file>mockfiles/images/spot.png</file>
|
<file>mockfiles/images/spot.png</file>
|
||||||
<file>mockfiles/images/spot@2x.png</file>
|
<file>mockfiles/images/spot@2x.png</file>
|
||||||
|
<file>mockfiles/images/preview_landscape.hdr</file>
|
||||||
|
<file>mockfiles/images/preview_studio.hdr</file>
|
||||||
<file>mockfiles/qt6/AdjustableArrow.qml</file>
|
<file>mockfiles/qt6/AdjustableArrow.qml</file>
|
||||||
<file>mockfiles/qt6/AreaLightHandle.qml</file>
|
<file>mockfiles/qt6/AreaLightHandle.qml</file>
|
||||||
<file>mockfiles/qt6/Arrow.qml</file>
|
<file>mockfiles/qt6/Arrow.qml</file>
|
||||||
|
Binary file not shown.
Binary file not shown.
@@ -29,8 +29,12 @@ View3D {
|
|||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
environment: sceneEnv
|
environment: sceneEnv
|
||||||
|
camera: envMode === "SkyBox" && envValue === "preview_studio" ? studioCamera : defaultCamera
|
||||||
|
|
||||||
property Material previewMaterial
|
property Material previewMaterial
|
||||||
|
property string envMode
|
||||||
|
property string envValue
|
||||||
|
property string modelSrc: "#Sphere"
|
||||||
|
|
||||||
function fitToViewPort(closeUp)
|
function fitToViewPort(closeUp)
|
||||||
{
|
{
|
||||||
@@ -41,28 +45,59 @@ View3D {
|
|||||||
id: sceneEnv
|
id: sceneEnv
|
||||||
antialiasingMode: SceneEnvironment.MSAA
|
antialiasingMode: SceneEnvironment.MSAA
|
||||||
antialiasingQuality: SceneEnvironment.High
|
antialiasingQuality: SceneEnvironment.High
|
||||||
|
backgroundMode: envMode === "Color" ? SceneEnvironment.Color
|
||||||
|
: envMode === "SkyBox" ? SceneEnvironment.SkyBox
|
||||||
|
: SceneEnvironment.Transparent
|
||||||
|
clearColor: envMode === "Color" ? envValue : "#000000"
|
||||||
|
lightProbe: envMode === "SkyBox" ? skyBoxTex : null
|
||||||
|
|
||||||
|
Texture {
|
||||||
|
id: skyBoxTex
|
||||||
|
source: envMode === "SkyBox" ? "../images/" + envValue + ".hdr"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
DirectionalLight {
|
DirectionalLight {
|
||||||
eulerRotation.x: -26
|
eulerRotation.x: -26
|
||||||
eulerRotation.y: -57
|
eulerRotation.y: modelSrc === "#Cube" ? -10 : -50
|
||||||
|
brightness: envMode !== "SkyBox" ? 100 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
PerspectiveCamera {
|
PerspectiveCamera {
|
||||||
y: 125.331
|
id: defaultCamera
|
||||||
z: 120
|
y: 70
|
||||||
eulerRotation.x: -31
|
z: 200
|
||||||
|
eulerRotation.x: -5.71
|
||||||
clipNear: 1
|
clipNear: 1
|
||||||
clipFar: 1000
|
clipFar: 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PerspectiveCamera {
|
||||||
|
id: studioCamera
|
||||||
|
y: 232
|
||||||
|
z: 85
|
||||||
|
eulerRotation.x: -64.98
|
||||||
|
clipNear: 1
|
||||||
|
clipFar: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Node {
|
||||||
|
rotation: root.camera.rotation
|
||||||
|
y: 50
|
||||||
|
Node {
|
||||||
|
y: modelSrc === "#Cone" ? -40 : 10
|
||||||
|
eulerRotation.x: 35
|
||||||
Model {
|
Model {
|
||||||
id: model
|
id: model
|
||||||
|
source: modelSrc ? modelSrc : "#Sphere"
|
||||||
y: 50
|
eulerRotation.y: 45
|
||||||
source: "#Sphere"
|
|
||||||
materials: previewMaterial
|
materials: previewMaterial
|
||||||
|
scale: !modelSrc || modelSrc === "#Sphere"
|
||||||
|
? Qt.vector3d(1.7, 1.7, 1.7) : Qt.vector3d(1.2, 1.2, 1.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,25 +50,28 @@ Item {
|
|||||||
view.destroy();
|
view.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewForObject(obj)
|
function createViewForObject(obj, env, envValue, model)
|
||||||
{
|
{
|
||||||
if (obj instanceof Material)
|
if (obj instanceof Material)
|
||||||
createViewForMaterial(obj);
|
createViewForMaterial(obj, env, envValue, model);
|
||||||
else if (obj instanceof Model)
|
else if (obj instanceof Model)
|
||||||
createViewForModel(obj);
|
createViewForModel(obj);
|
||||||
else if (obj instanceof Node)
|
else if (obj instanceof Node)
|
||||||
createViewForNode(obj);
|
createViewForNode(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewForMaterial(material)
|
function createViewForMaterial(material, env, envValue, model)
|
||||||
{
|
{
|
||||||
if (!materialViewComponent)
|
if (!materialViewComponent)
|
||||||
materialViewComponent = Qt.createComponent("MaterialNodeView.qml");
|
materialViewComponent = Qt.createComponent("MaterialNodeView.qml");
|
||||||
|
|
||||||
// Always recreate the view to ensure material is up to date
|
// Always recreate the view to ensure material is up to date
|
||||||
if (materialViewComponent.status === Component.Ready)
|
if (materialViewComponent.status === Component.Ready) {
|
||||||
view = materialViewComponent.createObject(viewRect, {"previewMaterial": material});
|
view = materialViewComponent.createObject(viewRect, {"previewMaterial": material,
|
||||||
|
"envMode": env,
|
||||||
|
"envValue": envValue,
|
||||||
|
"modelSrc": model});
|
||||||
|
}
|
||||||
previewObject = material;
|
previewObject = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -29,8 +29,12 @@ View3D {
|
|||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
environment: sceneEnv
|
environment: sceneEnv
|
||||||
|
camera: envMode === "SkyBox" && envValue === "preview_studio" ? studioCamera : defaultCamera
|
||||||
|
|
||||||
property Material previewMaterial
|
property Material previewMaterial
|
||||||
|
property string envMode
|
||||||
|
property string envValue
|
||||||
|
property string modelSrc: "#Sphere"
|
||||||
|
|
||||||
function fitToViewPort(closeUp)
|
function fitToViewPort(closeUp)
|
||||||
{
|
{
|
||||||
@@ -41,30 +45,79 @@ View3D {
|
|||||||
id: sceneEnv
|
id: sceneEnv
|
||||||
antialiasingMode: SceneEnvironment.MSAA
|
antialiasingMode: SceneEnvironment.MSAA
|
||||||
antialiasingQuality: SceneEnvironment.High
|
antialiasingQuality: SceneEnvironment.High
|
||||||
|
backgroundMode: envMode === "Color" ? SceneEnvironment.Color
|
||||||
|
: envMode === "SkyBox" ? SceneEnvironment.SkyBox
|
||||||
|
: SceneEnvironment.Transparent
|
||||||
|
clearColor: envMode === "Color" ? envValue : "#000000"
|
||||||
|
lightProbe: envMode === "SkyBox" ? skyBoxTex : null
|
||||||
|
|
||||||
|
Texture {
|
||||||
|
id: skyBoxTex
|
||||||
|
source: envMode === "SkyBox" ? "../images/" + envValue + ".hdr"
|
||||||
|
: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node {
|
Node {
|
||||||
DirectionalLight {
|
DirectionalLight {
|
||||||
eulerRotation.x: -26
|
eulerRotation.x: -26
|
||||||
eulerRotation.y: -57
|
eulerRotation.y: modelSrc === "#Cube" ? -10 : -50
|
||||||
|
brightness: envMode !== "SkyBox" ? 1 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
PerspectiveCamera {
|
PerspectiveCamera {
|
||||||
y: 125.331
|
id: defaultCamera
|
||||||
z: 120
|
y: 70
|
||||||
eulerRotation.x: -31
|
z: 200
|
||||||
|
eulerRotation.x: -5.71
|
||||||
clipNear: 1
|
clipNear: 1
|
||||||
clipFar: 1000
|
clipFar: 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PerspectiveCamera {
|
||||||
|
id: studioCamera
|
||||||
|
y: 232
|
||||||
|
z: 85
|
||||||
|
eulerRotation.x: -64.98
|
||||||
|
clipNear: 1
|
||||||
|
clipFar: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Node {
|
||||||
|
rotation: root.camera.rotation
|
||||||
|
y: 50
|
||||||
|
Node {
|
||||||
|
y: modelSrc === "#Cone" ? -40 : 10
|
||||||
|
eulerRotation.x: 35
|
||||||
Model {
|
Model {
|
||||||
id: model
|
id: model
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
source: modelSrc ? modelSrc : "#Sphere"
|
||||||
y: 50
|
eulerRotation.y: 45
|
||||||
source: "#Sphere"
|
|
||||||
materials: previewMaterial
|
materials: previewMaterial
|
||||||
|
scale: !modelSrc || modelSrc === "#Sphere"
|
||||||
|
? Qt.vector3d(1.7, 1.7, 1.7) : Qt.vector3d(1.2, 1.2, 1.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Model {
|
||||||
|
id: floorModel
|
||||||
|
source: "#Rectangle"
|
||||||
|
scale.y: 8
|
||||||
|
scale.x: 8
|
||||||
|
eulerRotation.x: -60
|
||||||
|
visible: !envMode || envMode === "Default"
|
||||||
|
materials: floorMaterial
|
||||||
|
DefaultMaterial {
|
||||||
|
id: floorMaterial
|
||||||
|
diffuseMap: floorTex
|
||||||
|
Texture {
|
||||||
|
id: floorTex
|
||||||
|
source: "../images/floor_tex.png"
|
||||||
|
scaleU: floorModel.scale.x
|
||||||
|
scaleV: floorModel.scale.y
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -50,25 +50,31 @@ Item {
|
|||||||
view.destroy();
|
view.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewForObject(obj)
|
function createViewForObject(obj, env, envValue, model)
|
||||||
{
|
{
|
||||||
|
backgroundView3d.visible = true;
|
||||||
if (obj instanceof Material)
|
if (obj instanceof Material)
|
||||||
createViewForMaterial(obj);
|
createViewForMaterial(obj, env, envValue, model);
|
||||||
else if (obj instanceof Model)
|
else if (obj instanceof Model)
|
||||||
createViewForModel(obj);
|
createViewForModel(obj);
|
||||||
else if (obj instanceof Node)
|
else if (obj instanceof Node)
|
||||||
createViewForNode(obj);
|
createViewForNode(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createViewForMaterial(material)
|
function createViewForMaterial(material, env, envValue, model)
|
||||||
{
|
{
|
||||||
if (!materialViewComponent)
|
if (!materialViewComponent)
|
||||||
materialViewComponent = Qt.createComponent("MaterialNodeView.qml");
|
materialViewComponent = Qt.createComponent("MaterialNodeView.qml");
|
||||||
|
|
||||||
// Always recreate the view to ensure material is up to date
|
// Always recreate the view to ensure material is up to date
|
||||||
if (materialViewComponent.status === Component.Ready)
|
if (materialViewComponent.status === Component.Ready) {
|
||||||
view = materialViewComponent.createObject(viewRect, {"previewMaterial": material});
|
view = materialViewComponent.createObject(viewRect, {"previewMaterial": material,
|
||||||
|
"envMode": env,
|
||||||
|
"envValue": envValue,
|
||||||
|
"modelSrc": model});
|
||||||
|
}
|
||||||
|
// Floor must be in same view as material so material can reflect it, so hide it in this one
|
||||||
|
backgroundView3d.visible = false;
|
||||||
previewObject = material;
|
previewObject = material;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +135,7 @@ Item {
|
|||||||
|
|
||||||
// Use View3D instead of static image to make background look good on all resolutions
|
// Use View3D instead of static image to make background look good on all resolutions
|
||||||
View3D {
|
View3D {
|
||||||
|
id: backgroundView3d
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
environment: sceneEnv
|
environment: sceneEnv
|
||||||
|
|
||||||
|
@@ -339,6 +339,31 @@ void Qt5InformationNodeInstanceServer::resolveImportSupport()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::updateMaterialPreviewData(const QVector<PropertyValueContainer> &valueChanges)
|
||||||
|
{
|
||||||
|
const PropertyName matPrevPrefix("matPrev");
|
||||||
|
qint32 materialLibraryId = -1;
|
||||||
|
for (const auto &container : valueChanges) {
|
||||||
|
if (container.name().startsWith(matPrevPrefix)) {
|
||||||
|
if (!hasInstanceForId(container.instanceId()))
|
||||||
|
continue;
|
||||||
|
if (materialLibraryId < 0) {
|
||||||
|
ServerNodeInstance instance = instanceForId(container.instanceId());
|
||||||
|
if (instance.id() == "__materialLibrary__")
|
||||||
|
materialLibraryId = container.instanceId();
|
||||||
|
}
|
||||||
|
if (container.instanceId() == materialLibraryId) {
|
||||||
|
if (container.name() == "matPrevEnv")
|
||||||
|
m_materialPreviewData.env = container.value().toString();
|
||||||
|
else if (container.name() == "matPrevEnvValue")
|
||||||
|
m_materialPreviewData.envValue = container.value().toString();
|
||||||
|
else if (container.name() == "matPrevModel")
|
||||||
|
m_materialPreviewData.model = container.value().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Qt5InformationNodeInstanceServer::updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges)
|
void Qt5InformationNodeInstanceServer::updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges)
|
||||||
{
|
{
|
||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
@@ -1184,7 +1209,10 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView(const Reques
|
|||||||
} else {
|
} else {
|
||||||
QMetaObject::invokeMethod(
|
QMetaObject::invokeMethod(
|
||||||
m_modelNode3DImageViewData.rootItem, "createViewForObject",
|
m_modelNode3DImageViewData.rootItem, "createViewForObject",
|
||||||
Q_ARG(QVariant, objectToVariant(instanceObj)));
|
Q_ARG(QVariant, objectToVariant(instanceObj)),
|
||||||
|
Q_ARG(QVariant, m_materialPreviewData.env),
|
||||||
|
Q_ARG(QVariant, m_materialPreviewData.envValue),
|
||||||
|
Q_ARG(QVariant, m_materialPreviewData.model));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to render twice, first render updates spatial nodes
|
// Need to render twice, first render updates spatial nodes
|
||||||
@@ -2027,6 +2055,7 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
|||||||
if (ViewConfig::isQuick3DMode()) {
|
if (ViewConfig::isQuick3DMode()) {
|
||||||
setup3DEditView(instanceList, command);
|
setup3DEditView(instanceList, command);
|
||||||
updateRotationBlocks(command.auxiliaryChanges);
|
updateRotationBlocks(command.auxiliaryChanges);
|
||||||
|
updateMaterialPreviewData(command.auxiliaryChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
|
QObject::connect(&m_renderModelNodeImageViewTimer, &QTimer::timeout,
|
||||||
@@ -2431,6 +2460,7 @@ void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const Reques
|
|||||||
void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
|
void Qt5InformationNodeInstanceServer::changeAuxiliaryValues(const ChangeAuxiliaryCommand &command)
|
||||||
{
|
{
|
||||||
updateRotationBlocks(command.auxiliaryChanges);
|
updateRotationBlocks(command.auxiliaryChanges);
|
||||||
|
updateMaterialPreviewData(command.auxiliaryChanges);
|
||||||
Qt5NodeInstanceServer::changeAuxiliaryValues(command);
|
Qt5NodeInstanceServer::changeAuxiliaryValues(command);
|
||||||
render3DEditView();
|
render3DEditView();
|
||||||
}
|
}
|
||||||
|
@@ -145,6 +145,7 @@ private:
|
|||||||
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
||||||
void handleInputEvents();
|
void handleInputEvents();
|
||||||
void resolveImportSupport();
|
void resolveImportSupport();
|
||||||
|
void updateMaterialPreviewData(const QVector<PropertyValueContainer> &valueChanges);
|
||||||
void updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges);
|
void updateRotationBlocks(const QVector<PropertyValueContainer> &valueChanges);
|
||||||
void removeRotationBlocks(const QVector<qint32> &instanceIds);
|
void removeRotationBlocks(const QVector<qint32> &instanceIds);
|
||||||
|
|
||||||
@@ -191,6 +192,13 @@ private:
|
|||||||
QObject *m_3dHelper = nullptr;
|
QObject *m_3dHelper = nullptr;
|
||||||
int m_need3DEditViewRender = 0;
|
int m_need3DEditViewRender = 0;
|
||||||
QSet<QObject *> m_dynamicObjectConstructors;
|
QSet<QObject *> m_dynamicObjectConstructors;
|
||||||
|
|
||||||
|
struct PreviewData {
|
||||||
|
QString env;
|
||||||
|
QString envValue;
|
||||||
|
QString model;
|
||||||
|
};
|
||||||
|
PreviewData m_materialPreviewData;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -33,6 +33,12 @@ PropertyEditorPane {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
signal toolBarAction(int action)
|
signal toolBarAction(int action)
|
||||||
|
signal previewEnvChanged(string env)
|
||||||
|
signal previewModelChanged(string model)
|
||||||
|
|
||||||
|
// Called from C++, dummy methods to avoid warnings
|
||||||
|
function closeContextMenu() {}
|
||||||
|
function initPreviewData(env, model) {}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: col
|
id: col
|
||||||
|
@@ -31,6 +31,8 @@ PropertyEditorPane {
|
|||||||
id: itemPane
|
id: itemPane
|
||||||
|
|
||||||
signal toolBarAction(int action)
|
signal toolBarAction(int action)
|
||||||
|
signal previewEnvChanged(string env)
|
||||||
|
signal previewModelChanged(string model)
|
||||||
|
|
||||||
// invoked from C++ to refresh material preview image
|
// invoked from C++ to refresh material preview image
|
||||||
function refreshPreview()
|
function refreshPreview()
|
||||||
@@ -38,10 +40,25 @@ PropertyEditorPane {
|
|||||||
topSection.refreshPreview()
|
topSection.refreshPreview()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called also from C++ to close context menu on focus out
|
||||||
|
function closeContextMenu()
|
||||||
|
{
|
||||||
|
topSection.closeContextMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from C++ to initialize preview menu checkmarks
|
||||||
|
function initPreviewData(env, model)
|
||||||
|
{
|
||||||
|
topSection.previewEnv = env;
|
||||||
|
topSection.previewModel = model
|
||||||
|
}
|
||||||
|
|
||||||
MaterialEditorTopSection {
|
MaterialEditorTopSection {
|
||||||
id: topSection
|
id: topSection
|
||||||
|
|
||||||
onToolBarAction: (action) => itemPane.toolBarAction(action)
|
onToolBarAction: (action) => itemPane.toolBarAction(action)
|
||||||
|
onPreviewEnvChanged: itemPane.previewEnvChanged(previewEnv)
|
||||||
|
onPreviewModelChanged: itemPane.previewModelChanged(previewModel)
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { width: 1; height: 10 }
|
Item { width: 1; height: 10 }
|
||||||
|
@@ -29,6 +29,7 @@ import QtQuick.Layouts 1.15
|
|||||||
import QtQuickDesignerTheme 1.0
|
import QtQuickDesignerTheme 1.0
|
||||||
import QtQuick.Templates 2.15 as T
|
import QtQuick.Templates 2.15 as T
|
||||||
import HelperWidgets 2.0
|
import HelperWidgets 2.0
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
import StudioTheme 1.0 as StudioTheme
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -36,12 +37,22 @@ Column {
|
|||||||
|
|
||||||
signal toolBarAction(int action)
|
signal toolBarAction(int action)
|
||||||
|
|
||||||
|
property string previewEnv
|
||||||
|
property string previewModel
|
||||||
|
|
||||||
function refreshPreview()
|
function refreshPreview()
|
||||||
{
|
{
|
||||||
materialPreview.source = ""
|
materialPreview.source = ""
|
||||||
materialPreview.source = "image://materialEditor/preview"
|
materialPreview.source = "image://materialEditor/preview"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called from C++ to close context menu on focus out
|
||||||
|
function closeContextMenu()
|
||||||
|
{
|
||||||
|
modelMenu.close()
|
||||||
|
envMenu.close()
|
||||||
|
}
|
||||||
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
@@ -53,11 +64,96 @@ Column {
|
|||||||
|
|
||||||
Item { width: 1; height: 10 } // spacer
|
Item { width: 1; height: 10 } // spacer
|
||||||
|
|
||||||
|
|
||||||
|
StudioControls.Menu {
|
||||||
|
id: modelMenu
|
||||||
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: modelMenuModel
|
||||||
|
ListElement {
|
||||||
|
modelName: qsTr("Cone")
|
||||||
|
modelStr: "#Cone"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
modelName: qsTr("Cube")
|
||||||
|
modelStr: "#Cube"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
modelName: qsTr("Cylinder")
|
||||||
|
modelStr: "#Cylinder"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
modelName: qsTr("Sphere")
|
||||||
|
modelStr: "#Sphere"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: modelMenuModel
|
||||||
|
StudioControls.MenuItemWithIcon {
|
||||||
|
text: modelName
|
||||||
|
onClicked: {
|
||||||
|
// Force property change notifications to keep check mark when reselected
|
||||||
|
root.previewModel = ""
|
||||||
|
root.previewModel = modelStr
|
||||||
|
}
|
||||||
|
checkable: true
|
||||||
|
checked: root.previewModel === modelStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.Menu {
|
||||||
|
id: envMenu
|
||||||
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: envMenuModel
|
||||||
|
ListElement {
|
||||||
|
envName: qsTr("Default")
|
||||||
|
envStr: "Default"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
envName: qsTr("Color")
|
||||||
|
envStr: "Color"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
envName: qsTr("Studio")
|
||||||
|
envStr: "SkyBox=preview_studio"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
envName: qsTr("Landscape")
|
||||||
|
envStr: "SkyBox=preview_landscape"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: envMenuModel
|
||||||
|
StudioControls.MenuItemWithIcon {
|
||||||
|
text: envName
|
||||||
|
onClicked: {
|
||||||
|
// Force property change notifications to keep check mark when reselected
|
||||||
|
root.previewEnv = ""
|
||||||
|
root.previewEnv = envStr
|
||||||
|
}
|
||||||
|
checkable: true
|
||||||
|
checked: root.previewEnv === envStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: parent.width
|
||||||
|
height: previewRect.height
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: previewRect
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
width: 152
|
width: 152
|
||||||
height: 152
|
height: 152
|
||||||
color: "#000000"
|
color: "#000000"
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: materialPreview
|
id: materialPreview
|
||||||
@@ -69,6 +165,36 @@ Column {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: previewOptions
|
||||||
|
width: 40
|
||||||
|
height: previewRect.height
|
||||||
|
anchors.top: previewRect.top
|
||||||
|
anchors.left: previewRect.right
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
IconButton {
|
||||||
|
icon: StudioTheme.Constants.materialPreviewEnvironment
|
||||||
|
normalColor: "transparent"
|
||||||
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
|
buttonSize: previewOptions.width
|
||||||
|
tooltip: qsTr("Select preview environment.")
|
||||||
|
onClicked: envMenu.popup()
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
icon: StudioTheme.Constants.materialPreviewModel
|
||||||
|
normalColor: "transparent"
|
||||||
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
|
buttonSize: previewOptions.width
|
||||||
|
tooltip: qsTr("Select preview model.")
|
||||||
|
onClicked: modelMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
// Section with hidden header is used so properties are aligned with the other sections' properties
|
// Section with hidden header is used so properties are aligned with the other sections' properties
|
||||||
hideHeader: true
|
hideHeader: true
|
||||||
|
@@ -122,72 +122,74 @@ QtObject {
|
|||||||
readonly property string listView: "\u0075"
|
readonly property string listView: "\u0075"
|
||||||
readonly property string lockOff: "\u0076"
|
readonly property string lockOff: "\u0076"
|
||||||
readonly property string lockOn: "\u0077"
|
readonly property string lockOn: "\u0077"
|
||||||
readonly property string mergeCells: "\u0078"
|
readonly property string materialPreviewEnvironment: "\u0078"
|
||||||
readonly property string minus: "\u0079"
|
readonly property string materialPreviewModel: "\u0079"
|
||||||
readonly property string mirror: "\u007A"
|
readonly property string mergeCells: "\u007A"
|
||||||
readonly property string newMaterial: "\u007B"
|
readonly property string minus: "\u007B"
|
||||||
readonly property string openMaterialBrowser: "\u007C"
|
readonly property string mirror: "\u007C"
|
||||||
readonly property string orientation: "\u007D"
|
readonly property string newMaterial: "\u007D"
|
||||||
readonly property string paddingEdge: "\u007E"
|
readonly property string openMaterialBrowser: "\u007E"
|
||||||
readonly property string paddingFrame: "\u007F"
|
readonly property string orientation: "\u007F"
|
||||||
readonly property string pasteStyle: "\u0080"
|
readonly property string paddingEdge: "\u0080"
|
||||||
readonly property string pause: "\u0081"
|
readonly property string paddingFrame: "\u0081"
|
||||||
readonly property string pin: "\u0082"
|
readonly property string pasteStyle: "\u0082"
|
||||||
readonly property string play: "\u0083"
|
readonly property string pause: "\u0083"
|
||||||
readonly property string plus: "\u0084"
|
readonly property string pin: "\u0084"
|
||||||
readonly property string promote: "\u0085"
|
readonly property string play: "\u0085"
|
||||||
readonly property string readOnly: "\u0086"
|
readonly property string plus: "\u0086"
|
||||||
readonly property string redo: "\u0087"
|
readonly property string promote: "\u0087"
|
||||||
readonly property string rotationFill: "\u0088"
|
readonly property string readOnly: "\u0088"
|
||||||
readonly property string rotationOutline: "\u0089"
|
readonly property string redo: "\u0089"
|
||||||
readonly property string search: "\u008A"
|
readonly property string rotationFill: "\u008A"
|
||||||
readonly property string sectionToggle: "\u008B"
|
readonly property string rotationOutline: "\u008B"
|
||||||
readonly property string splitColumns: "\u008C"
|
readonly property string search: "\u008C"
|
||||||
readonly property string splitRows: "\u008D"
|
readonly property string sectionToggle: "\u008D"
|
||||||
readonly property string startNode: "\u008E"
|
readonly property string splitColumns: "\u008E"
|
||||||
readonly property string testIcon: "\u008F"
|
readonly property string splitRows: "\u008F"
|
||||||
readonly property string textAlignBottom: "\u0090"
|
readonly property string startNode: "\u0090"
|
||||||
readonly property string textAlignCenter: "\u0091"
|
readonly property string testIcon: "\u0091"
|
||||||
readonly property string textAlignJustified: "\u0092"
|
readonly property string textAlignBottom: "\u0092"
|
||||||
readonly property string textAlignLeft: "\u0093"
|
readonly property string textAlignCenter: "\u0093"
|
||||||
readonly property string textAlignMiddle: "\u0094"
|
readonly property string textAlignJustified: "\u0094"
|
||||||
readonly property string textAlignRight: "\u0095"
|
readonly property string textAlignLeft: "\u0095"
|
||||||
readonly property string textAlignTop: "\u0096"
|
readonly property string textAlignMiddle: "\u0096"
|
||||||
readonly property string textBulletList: "\u0097"
|
readonly property string textAlignRight: "\u0097"
|
||||||
readonly property string textFullJustification: "\u0098"
|
readonly property string textAlignTop: "\u0098"
|
||||||
readonly property string textNumberedList: "\u0099"
|
readonly property string textBulletList: "\u0099"
|
||||||
readonly property string tickIcon: "\u009A"
|
readonly property string textFullJustification: "\u009A"
|
||||||
readonly property string translationCreateFiles: "\u009B"
|
readonly property string textNumberedList: "\u009B"
|
||||||
readonly property string translationCreateReport: "\u009D"
|
readonly property string tickIcon: "\u009D"
|
||||||
readonly property string translationExport: "\u009E"
|
readonly property string translationCreateFiles: "\u009E"
|
||||||
readonly property string translationImport: "\u009F"
|
readonly property string translationCreateReport: "\u009F"
|
||||||
readonly property string translationSelectLanguages: "\u00A0"
|
readonly property string translationExport: "\u00A0"
|
||||||
readonly property string translationTest: "\u00A1"
|
readonly property string translationImport: "\u00A1"
|
||||||
readonly property string transparent: "\u00A2"
|
readonly property string translationSelectLanguages: "\u00A2"
|
||||||
readonly property string triState: "\u00A3"
|
readonly property string translationTest: "\u00A3"
|
||||||
readonly property string triangleArcA: "\u00A4"
|
readonly property string transparent: "\u00A4"
|
||||||
readonly property string triangleArcB: "\u00A5"
|
readonly property string triState: "\u00A5"
|
||||||
readonly property string triangleCornerA: "\u00A6"
|
readonly property string triangleArcA: "\u00A6"
|
||||||
readonly property string triangleCornerB: "\u00A7"
|
readonly property string triangleArcB: "\u00A7"
|
||||||
readonly property string unLinked: "\u00A8"
|
readonly property string triangleCornerA: "\u00A8"
|
||||||
readonly property string undo: "\u00A9"
|
readonly property string triangleCornerB: "\u00A9"
|
||||||
readonly property string unpin: "\u00AA"
|
readonly property string unLinked: "\u00AA"
|
||||||
readonly property string upDownIcon: "\u00AB"
|
readonly property string undo: "\u00AB"
|
||||||
readonly property string upDownSquare2: "\u00AC"
|
readonly property string unpin: "\u00AC"
|
||||||
readonly property string visibilityOff: "\u00AE"
|
readonly property string upDownIcon: "\u00AE"
|
||||||
readonly property string visibilityOn: "\u00AF"
|
readonly property string upDownSquare2: "\u00AF"
|
||||||
readonly property string wildcard: "\u00B0"
|
readonly property string visibilityOff: "\u00B0"
|
||||||
readonly property string wizardsAutomotive: "\u00B1"
|
readonly property string visibilityOn: "\u00B1"
|
||||||
readonly property string wizardsDesktop: "\u00B2"
|
readonly property string wildcard: "\u00B2"
|
||||||
readonly property string wizardsGeneric: "\u00B3"
|
readonly property string wizardsAutomotive: "\u00B3"
|
||||||
readonly property string wizardsMcuEmpty: "\u00B4"
|
readonly property string wizardsDesktop: "\u00B4"
|
||||||
readonly property string wizardsMcuGraph: "\u00B5"
|
readonly property string wizardsGeneric: "\u00B5"
|
||||||
readonly property string wizardsMobile: "\u00B6"
|
readonly property string wizardsMcuEmpty: "\u00B6"
|
||||||
readonly property string wizardsUnknown: "\u00B7"
|
readonly property string wizardsMcuGraph: "\u00B7"
|
||||||
readonly property string zoomAll: "\u00B8"
|
readonly property string wizardsMobile: "\u00B8"
|
||||||
readonly property string zoomIn: "\u00B9"
|
readonly property string wizardsUnknown: "\u00B9"
|
||||||
readonly property string zoomOut: "\u00BA"
|
readonly property string zoomAll: "\u00BA"
|
||||||
readonly property string zoomSelection: "\u00BB"
|
readonly property string zoomIn: "\u00BB"
|
||||||
|
readonly property string zoomOut: "\u00BC"
|
||||||
|
readonly property string zoomSelection: "\u00BD"
|
||||||
|
|
||||||
readonly property font iconFont: Qt.font({
|
readonly property font iconFont: Qt.font({
|
||||||
"family": controlIcons.name,
|
"family": controlIcons.name,
|
||||||
|
Binary file not shown.
@@ -130,6 +130,8 @@ public:
|
|||||||
listView,
|
listView,
|
||||||
lockOff,
|
lockOff,
|
||||||
lockOn,
|
lockOn,
|
||||||
|
materialPreviewEnvironment,
|
||||||
|
materialPreviewModel,
|
||||||
mergeCells,
|
mergeCells,
|
||||||
minus,
|
minus,
|
||||||
mirror,
|
mirror,
|
||||||
|
@@ -284,6 +284,10 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt
|
|||||||
int idx = m_widget->materialBrowserModel()->materialIndex(nodeList.first());
|
int idx = m_widget->materialBrowserModel()->materialIndex(nodeList.first());
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
m_widget->materialBrowserModel()->selectMaterial(idx);
|
m_widget->materialBrowserModel()->selectMaterial(idx);
|
||||||
|
} else if (identifier == "refresh_material_browser") {
|
||||||
|
QTimer::singleShot(0, this, [this]() {
|
||||||
|
refreshModel(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -62,6 +62,7 @@
|
|||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QColorDialog>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -442,6 +443,90 @@ void MaterialEditorView::handleToolBarAction(int action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::handlePreviewEnvChanged(const QString &envAndValue)
|
||||||
|
{
|
||||||
|
if (envAndValue.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTC_ASSERT(m_hasQuick3DImport, return);
|
||||||
|
QTC_ASSERT(model(), return);
|
||||||
|
QTC_ASSERT(model()->nodeInstanceView(), return);
|
||||||
|
|
||||||
|
QStringList parts = envAndValue.split('=');
|
||||||
|
QString env = parts[0];
|
||||||
|
QString value;
|
||||||
|
if (parts.size() > 1)
|
||||||
|
value = parts[1];
|
||||||
|
|
||||||
|
PropertyName matPrevEnvAuxProp("matPrevEnv");
|
||||||
|
PropertyName matPrevEnvValueAuxProp("matPrevEnvValue");
|
||||||
|
|
||||||
|
auto renderPreviews = [=](const QString &auxEnv, const QString &auxValue) {
|
||||||
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
|
QTC_ASSERT(matLib.isValid(), return);
|
||||||
|
matLib.setAuxiliaryData(matPrevEnvAuxProp, auxEnv);
|
||||||
|
matLib.setAuxiliaryData(matPrevEnvValueAuxProp, auxValue);
|
||||||
|
QTimer::singleShot(0, this, &MaterialEditorView::requestPreviewRender);
|
||||||
|
emitCustomNotification("refresh_material_browser", {});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (env == "Color") {
|
||||||
|
m_colorDialog.clear();
|
||||||
|
|
||||||
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
|
QTC_ASSERT(matLib.isValid(), return);
|
||||||
|
// Store color to separate property to persist selection over non-color env changes
|
||||||
|
PropertyName colorAuxProp("matPrevColor");
|
||||||
|
QString oldColor = matLib.auxiliaryData(colorAuxProp).toString();
|
||||||
|
QString oldEnv = matLib.auxiliaryData(matPrevEnvAuxProp).toString();
|
||||||
|
QString oldValue = matLib.auxiliaryData(matPrevEnvValueAuxProp).toString();
|
||||||
|
|
||||||
|
m_colorDialog = new QColorDialog(Core::ICore::dialogParent());
|
||||||
|
m_colorDialog->setModal(true);
|
||||||
|
m_colorDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
m_colorDialog->setCurrentColor(QColor(oldColor));
|
||||||
|
m_colorDialog->show();
|
||||||
|
|
||||||
|
QObject::connect(m_colorDialog, &QColorDialog::currentColorChanged,
|
||||||
|
m_colorDialog, [=](const QColor &color) {
|
||||||
|
renderPreviews(env, color.name());
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(m_colorDialog, &QColorDialog::colorSelected,
|
||||||
|
m_colorDialog, [=](const QColor &color) {
|
||||||
|
renderPreviews(env, color.name());
|
||||||
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
|
QTC_ASSERT(matLib.isValid(), return);
|
||||||
|
matLib.setAuxiliaryData(colorAuxProp, color.name());
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(m_colorDialog, &QColorDialog::rejected,
|
||||||
|
m_colorDialog, [=]() {
|
||||||
|
renderPreviews(oldEnv, oldValue);
|
||||||
|
initPreviewData();
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
renderPreviews(env, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::handlePreviewModelChanged(const QString &modelStr)
|
||||||
|
{
|
||||||
|
if (modelStr.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QTC_ASSERT(m_hasQuick3DImport, return);
|
||||||
|
QTC_ASSERT(model(), return);
|
||||||
|
QTC_ASSERT(model()->nodeInstanceView(), return);
|
||||||
|
|
||||||
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
|
QTC_ASSERT(matLib.isValid(), return);
|
||||||
|
matLib.setAuxiliaryData("matPrevModel", modelStr);
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, &MaterialEditorView::requestPreviewRender);
|
||||||
|
emitCustomNotification("refresh_material_browser", {});
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorView::setupQmlBackend()
|
void MaterialEditorView::setupQmlBackend()
|
||||||
{
|
{
|
||||||
QUrl qmlPaneUrl;
|
QUrl qmlPaneUrl;
|
||||||
@@ -472,17 +557,24 @@ void MaterialEditorView::setupQmlBackend()
|
|||||||
|
|
||||||
currentQmlBackend->setSource(qmlPaneUrl);
|
currentQmlBackend->setSource(qmlPaneUrl);
|
||||||
|
|
||||||
QObject::connect(currentQmlBackend->widget()->rootObject(), SIGNAL(toolBarAction(int)),
|
QObject *rootObj = currentQmlBackend->widget()->rootObject();
|
||||||
|
QObject::connect(rootObj, SIGNAL(toolBarAction(int)),
|
||||||
this, SLOT(handleToolBarAction(int)));
|
this, SLOT(handleToolBarAction(int)));
|
||||||
|
QObject::connect(rootObj, SIGNAL(previewEnvChanged(QString)),
|
||||||
|
this, SLOT(handlePreviewEnvChanged(QString)));
|
||||||
|
QObject::connect(rootObj, SIGNAL(previewModelChanged(QString)),
|
||||||
|
this, SLOT(handlePreviewModelChanged(QString)));
|
||||||
} else {
|
} else {
|
||||||
currentQmlBackend->setup(m_selectedMaterial, currentStateName, qmlSpecificsUrl, this);
|
currentQmlBackend->setup(m_selectedMaterial, currentStateName, qmlSpecificsUrl, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentQmlBackend->widget()->installEventFilter(this);
|
||||||
currentQmlBackend->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
currentQmlBackend->contextObject()->setHasQuick3DImport(m_hasQuick3DImport);
|
||||||
|
|
||||||
m_stackedWidget->setCurrentWidget(currentQmlBackend->widget());
|
m_stackedWidget->setCurrentWidget(currentQmlBackend->widget());
|
||||||
|
|
||||||
m_qmlBackEnd = currentQmlBackend;
|
m_qmlBackEnd = currentQmlBackend;
|
||||||
|
initPreviewData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
|
void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
|
||||||
@@ -528,6 +620,29 @@ bool MaterialEditorView::noValidSelection() const
|
|||||||
return !QmlObjectNode::isValidQmlObjectNode(m_selectedMaterial);
|
return !QmlObjectNode::isValidQmlObjectNode(m_selectedMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::initPreviewData()
|
||||||
|
{
|
||||||
|
if (model() && m_qmlBackEnd) {
|
||||||
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
|
if (matLib.isValid()) {
|
||||||
|
QString env = matLib.auxiliaryData("matPrevEnv").toString();
|
||||||
|
QString envValue = matLib.auxiliaryData("matPrevEnvValue").toString();
|
||||||
|
QString modelStr = matLib.auxiliaryData("matPrevModel").toString();
|
||||||
|
if (!envValue.isEmpty() && env != "Color" && env != "Default") {
|
||||||
|
env += '=';
|
||||||
|
env += envValue;
|
||||||
|
}
|
||||||
|
if (env.isEmpty())
|
||||||
|
env = "Default";
|
||||||
|
if (modelStr.isEmpty())
|
||||||
|
modelStr = "#Sphere";
|
||||||
|
QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(),
|
||||||
|
"initPreviewData",
|
||||||
|
Q_ARG(QVariant, env), Q_ARG(QVariant, modelStr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorView::modelAttached(Model *model)
|
void MaterialEditorView::modelAttached(Model *model)
|
||||||
{
|
{
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
@@ -844,6 +959,15 @@ void MaterialEditorView::setValue(const QmlObjectNode &qmlObjectNode, const Prop
|
|||||||
m_locked = false;
|
m_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MaterialEditorView::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::FocusOut) {
|
||||||
|
if (m_qmlBackEnd && m_qmlBackEnd->widget() == obj)
|
||||||
|
QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(), "closeContextMenu");
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorView::reloadQml()
|
void MaterialEditorView::reloadQml()
|
||||||
{
|
{
|
||||||
m_qmlBackendHash.clear();
|
m_qmlBackendHash.clear();
|
||||||
|
@@ -27,12 +27,14 @@
|
|||||||
|
|
||||||
#include <abstractview.h>
|
#include <abstractview.h>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QPointer>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QShortcut;
|
class QShortcut;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
class QTimer;
|
class QTimer;
|
||||||
|
class QColorDialog;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -87,10 +89,13 @@ public:
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void handleToolBarAction(int action);
|
void handleToolBarAction(int action);
|
||||||
|
void handlePreviewEnvChanged(const QString &envAndValue);
|
||||||
|
void handlePreviewModelChanged(const QString &modelStr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value);
|
void setValue(const QmlObjectNode &fxObjectNode, const PropertyName &name, const QVariant &value);
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QString materialEditorResourcesPath();
|
static QString materialEditorResourcesPath();
|
||||||
@@ -113,6 +118,8 @@ private:
|
|||||||
|
|
||||||
bool noValidSelection() const;
|
bool noValidSelection() const;
|
||||||
|
|
||||||
|
void initPreviewData();
|
||||||
|
|
||||||
ModelNode m_selectedMaterial;
|
ModelNode m_selectedMaterial;
|
||||||
QTimer m_ensureMatLibTimer;
|
QTimer m_ensureMatLibTimer;
|
||||||
QShortcut *m_updateShortcut = nullptr;
|
QShortcut *m_updateShortcut = nullptr;
|
||||||
@@ -124,6 +131,8 @@ private:
|
|||||||
bool m_locked = false;
|
bool m_locked = false;
|
||||||
bool m_setupCompleted = false;
|
bool m_setupCompleted = false;
|
||||||
bool m_hasQuick3DImport = false;
|
bool m_hasQuick3DImport = false;
|
||||||
|
|
||||||
|
QPointer<QColorDialog> m_colorDialog;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -660,7 +660,8 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node,
|
|||||||
const QVariant &value)
|
const QVariant &value)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_nodeInstanceServer, return);
|
QTC_ASSERT(m_nodeInstanceServer, return);
|
||||||
const bool forceAuxChange = name == "invisible" || name == "locked" || name == "rotBlocked@Internal";
|
const bool forceAuxChange = name == "invisible" || name == "locked"
|
||||||
|
|| name == "rotBlocked@Internal" || name.startsWith("matPrev");
|
||||||
if (((node.isRootNode() && (name == "width" || name == "height")) || forceAuxChange)
|
if (((node.isRootNode() && (name == "width" || name == "height")) || forceAuxChange)
|
||||||
|| name.endsWith(PropertyName("@NodeInstance"))) {
|
|| name.endsWith(PropertyName("@NodeInstance"))) {
|
||||||
if (hasInstanceForModelNode(node)) {
|
if (hasInstanceForModelNode(node)) {
|
||||||
|
Reference in New Issue
Block a user