forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/8.0'
Reverts/comments out parts of 45f93a817a
,
which needs to be resolved in a follow-up commit.
Conflicts:
cmake/QtCreatorIDEBranding.cmake
qbs/modules/qtc/qtc.qbs
qtcreator_ide_branding.pri
share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp
src/plugins/clangcodemodel/clangmodelmanagersupport.cpp
src/plugins/cmakeprojectmanager/cmakesettingspage.cpp
src/plugins/python/pythoneditor.cpp
src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp
src/plugins/scxmleditor/common/colorsettings.cpp
Change-Id: I7f0f7b7120e75a9fc3a8886bc57c17345cbb501b
This commit is contained in:
23
dist/changes-8.0.1.md
vendored
23
dist/changes-8.0.1.md
vendored
@@ -13,8 +13,14 @@ the public Git repository. For example:
|
|||||||
Editing
|
Editing
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
* Delayed context menu tooltip action creation
|
||||||
|
* Cached the last QIcon created from a Utils::Icon
|
||||||
|
|
||||||
### C++
|
### C++
|
||||||
|
|
||||||
|
* Prevent opening unneeded generated ui header files in clangd
|
||||||
|
* Fixed documents getting opened in wrong clangd
|
||||||
|
|
||||||
Projects
|
Projects
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -42,17 +48,34 @@ Platforms
|
|||||||
### Baremetal
|
### Baremetal
|
||||||
|
|
||||||
* Fixed running and debugging applications (QTCREATORBUG-27972)
|
* Fixed running and debugging applications (QTCREATORBUG-27972)
|
||||||
|
* Fixed bug when cloning jLink gdb server provider
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
---------
|
||||||
|
|
||||||
|
* Fixed bitfield display with Python 3
|
||||||
|
|
||||||
|
|
||||||
Credits for these changes go to:
|
Credits for these changes go to:
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
Alexander Akulich
|
||||||
Alibek Omarov
|
Alibek Omarov
|
||||||
André Pönitz
|
André Pönitz
|
||||||
Christian Kandeler
|
Christian Kandeler
|
||||||
|
Christian Stenger
|
||||||
Cristian Adam
|
Cristian Adam
|
||||||
|
David Schulz
|
||||||
|
Dmitry Kovalev
|
||||||
Eike Ziller
|
Eike Ziller
|
||||||
Ivan Komissarov
|
Ivan Komissarov
|
||||||
Jaroslaw Kobus
|
Jaroslaw Kobus
|
||||||
|
Knud Dollereder
|
||||||
Mahmoud Badri
|
Mahmoud Badri
|
||||||
|
Marcus Tillmanns
|
||||||
Mats Honkamaa
|
Mats Honkamaa
|
||||||
|
Miikka Heikkinen
|
||||||
|
Orgad Shaneh
|
||||||
Oswald Buddenhagen
|
Oswald Buddenhagen
|
||||||
|
Samuel Ghinet
|
||||||
Thomas Hartmann
|
Thomas Hartmann
|
||||||
|
Vikas Pachdha
|
||||||
|
@@ -165,6 +165,16 @@
|
|||||||
To disable the Python language server, deselect
|
To disable the Python language server, deselect
|
||||||
\uicontrol {Use Python Language Server}.
|
\uicontrol {Use Python Language Server}.
|
||||||
|
|
||||||
|
\section2 Qml Language Server
|
||||||
|
|
||||||
|
Qt 6.4 ships with the qmlls language server that provides completions and warnings for QML.
|
||||||
|
It can be set up as a \l {Generic StdIO Language Server}, selecting \c {text/x-qml} and
|
||||||
|
\c {application/x-qt.ui+qml} as MIME Types, and \c {<Qt Installation>/bin/qmlls} as executable.
|
||||||
|
|
||||||
|
If the language server is used together with the QmlJSEditor plugin duplicate suggestions and
|
||||||
|
warnings might be shown. To avoid this you might want to disable it as described in
|
||||||
|
\l {Enabling and Disabling Plugins}.
|
||||||
|
|
||||||
\section1 Supported Locator Filters
|
\section1 Supported Locator Filters
|
||||||
|
|
||||||
The locator enables you to browse not only files, but any items defined by
|
The locator enables you to browse not only files, but any items defined by
|
||||||
|
@@ -43,10 +43,8 @@
|
|||||||
|
|
||||||
\section1 2D Assets
|
\section1 2D Assets
|
||||||
|
|
||||||
You can use the Qt Installer to install \QB if you have a commercial
|
You can use the Qt Installer to install \QB if you have a
|
||||||
\QDS license. You can also purchase a \QB license separately from the
|
\QDS enterprise license.
|
||||||
\l{https://marketplace.qt.io/}{Qt Marketplace} and then install \QB using
|
|
||||||
the Qt Installer.
|
|
||||||
|
|
||||||
\table
|
\table
|
||||||
\row
|
\row
|
||||||
|
@@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
\title Setting Up \QBPS
|
\title Setting Up \QBPS
|
||||||
|
|
||||||
You can purchase a \QBPS license from the \l{https://marketplace.qt.io/}
|
\QBPS is included in the
|
||||||
{Qt Marketplace}, and then use the Qt Installer to have the \QBPS
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
installation package copied to the following path in your Qt installation
|
You can use the Qt Installer to have the \QBPS plugin package copied to the
|
||||||
folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li On Windows: \c {Tools\QtDesignStudio\photoshop_bridge}
|
\li On Windows: \c {Tools\QtDesignStudio\photoshop_bridge}
|
||||||
|
@@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
\title Setting Up \QBSK
|
\title Setting Up \QBSK
|
||||||
|
|
||||||
You can purchase a \QBSK license from the \l{https://marketplace.qt.io/}
|
\QBSK is included in the
|
||||||
{Qt Marketplace}, and then use the Qt Installer to have the \QBSK
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
plugin package copied to the following path in your Qt installation
|
You can use the Qt Installer to have the \QBSK plugin package copied to the
|
||||||
folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li On Windows:
|
\li On Windows:
|
||||||
|
@@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
\title Setting Up \QBXD
|
\title Setting Up \QBXD
|
||||||
|
|
||||||
You can purchase a \QBXD license from the \l{https://marketplace.qt.io/}
|
\QBXD is included in the
|
||||||
{Qt Marketplace}, and then use the Qt Installer to have the \QBXD
|
\l{https://www.qt.io/pricing}{Qt Design Studio Enterprise license}.
|
||||||
plugin package copied to the following path in your Qt installation
|
You can use the Qt Installer to have the \QBXD plugin package copied to the
|
||||||
folder:
|
following path in your Qt installation folder:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li On Windows:
|
\li On Windows:
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
Model {
|
PerspectiveCamera {
|
||||||
id: model
|
id: studioCamera
|
||||||
|
y: 232
|
||||||
|
z: 85
|
||||||
|
eulerRotation.x: -64.98
|
||||||
|
clipNear: 1
|
||||||
|
clipFar: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
Node {
|
||||||
|
rotation: root.camera.rotation
|
||||||
y: 50
|
y: 50
|
||||||
source: "#Sphere"
|
Node {
|
||||||
materials: previewMaterial
|
y: modelSrc === "#Cone" ? -40 : 10
|
||||||
|
eulerRotation.x: 35
|
||||||
|
Model {
|
||||||
|
id: model
|
||||||
|
source: modelSrc ? modelSrc : "#Sphere"
|
||||||
|
eulerRotation.y: 45
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
Model {
|
PerspectiveCamera {
|
||||||
id: model
|
id: studioCamera
|
||||||
readonly property bool _edit3dLocked: true // Make this non-pickable
|
y: 232
|
||||||
|
z: 85
|
||||||
y: 50
|
eulerRotation.x: -64.98
|
||||||
source: "#Sphere"
|
clipNear: 1
|
||||||
materials: previewMaterial
|
clipFar: 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node {
|
||||||
|
rotation: root.camera.rotation
|
||||||
|
y: 50
|
||||||
|
Node {
|
||||||
|
y: modelSrc === "#Cone" ? -40 : 10
|
||||||
|
eulerRotation.x: 35
|
||||||
|
Model {
|
||||||
|
id: model
|
||||||
|
readonly property bool _edit3dLocked: true // Make this non-pickable
|
||||||
|
source: modelSrc ? modelSrc : "#Sphere"
|
||||||
|
eulerRotation.y: 45
|
||||||
|
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,22 @@ void Qt5InformationNodeInstanceServer::resolveImportSupport()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Qt5InformationNodeInstanceServer::updateMaterialPreviewData(
|
||||||
|
const QVector<PropertyValueContainer> &valueChanges)
|
||||||
|
{
|
||||||
|
const PropertyName matPrevPrefix("matPrev");
|
||||||
|
for (const auto &container : valueChanges) {
|
||||||
|
if (container.instanceId() == 0) {
|
||||||
|
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(
|
void Qt5InformationNodeInstanceServer::updateRotationBlocks(
|
||||||
[[maybe_unused]] const QVector<PropertyValueContainer> &valueChanges)
|
[[maybe_unused]] const QVector<PropertyValueContainer> &valueChanges)
|
||||||
{
|
{
|
||||||
@@ -1176,7 +1192,10 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView(
|
|||||||
} 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
|
||||||
@@ -2010,6 +2029,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,
|
||||||
@@ -2414,6 +2434,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
|
||||||
|
@@ -39,6 +39,8 @@ Item {
|
|||||||
property var currentMaterial: null
|
property var currentMaterial: null
|
||||||
property int currentMaterialIdx: 0
|
property int currentMaterialIdx: 0
|
||||||
|
|
||||||
|
property var matSectionsModel: []
|
||||||
|
|
||||||
// Called also from C++ to close context menu on focus out
|
// Called also from C++ to close context menu on focus out
|
||||||
function closeContextMenu()
|
function closeContextMenu()
|
||||||
{
|
{
|
||||||
@@ -67,8 +69,10 @@ Item {
|
|||||||
acceptedButtons: Qt.RightButton
|
acceptedButtons: Qt.RightButton
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentMaterial = null
|
if (!materialBrowserModel.hasMaterialRoot) {
|
||||||
contextMenu.popup()
|
root.currentMaterial = null
|
||||||
|
contextMenu.popup()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,27 +96,77 @@ Item {
|
|||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Apply to selected (replace)")
|
text: qsTr("Apply to selected (replace)")
|
||||||
enabled: currentMaterial && materialBrowserModel.hasModelSelection
|
enabled: root.currentMaterial && materialBrowserModel.hasModelSelection
|
||||||
onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, false)
|
onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Apply to selected (add)")
|
text: qsTr("Apply to selected (add)")
|
||||||
enabled: currentMaterial && materialBrowserModel.hasModelSelection
|
enabled: root.currentMaterial && materialBrowserModel.hasModelSelection
|
||||||
onTriggered: materialBrowserModel.applyToSelected(currentMaterial.materialInternalId, true)
|
onTriggered: materialBrowserModel.applyToSelected(root.currentMaterial.materialInternalId, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuSeparator {
|
||||||
|
height: StudioTheme.Values.border
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.Menu {
|
||||||
|
title: qsTr("Copy properties")
|
||||||
|
enabled: root.currentMaterial
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
onAboutToShow: {
|
||||||
|
root.matSectionsModel = ["All"];
|
||||||
|
|
||||||
|
switch (root.currentMaterial.materialType) {
|
||||||
|
case "DefaultMaterial":
|
||||||
|
root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.defaultMaterialSections);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "PrincipledMaterial":
|
||||||
|
root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.principledMaterialSections);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "CustomMaterial":
|
||||||
|
root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.customMaterialSections);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: root.matSectionsModel
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
text: modelData
|
||||||
|
enabled: root.currentMaterial
|
||||||
|
onTriggered: materialBrowserModel.copyMaterialProperties(root.currentMaterialIdx, modelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuItem {
|
||||||
|
text: qsTr("Paste properties")
|
||||||
|
enabled: root.currentMaterial && root.currentMaterial.materialType
|
||||||
|
=== materialBrowserModel.copiedMaterialType
|
||||||
|
onTriggered: materialBrowserModel.pasteMaterialProperties(root.currentMaterialIdx)
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.MenuSeparator {
|
||||||
|
height: StudioTheme.Values.border
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Duplicate")
|
text: qsTr("Duplicate")
|
||||||
enabled: currentMaterial
|
enabled: root.currentMaterial
|
||||||
onTriggered: materialBrowserModel.duplicateMaterial(currentMaterialIdx)
|
onTriggered: materialBrowserModel.duplicateMaterial(root.currentMaterialIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Rename")
|
text: qsTr("Rename")
|
||||||
enabled: currentMaterial
|
enabled: root.currentMaterial
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
var item = gridRepeater.itemAt(currentMaterialIdx);
|
var item = gridRepeater.itemAt(root.currentMaterialIdx);
|
||||||
if (item)
|
if (item)
|
||||||
item.startRename();
|
item.startRename();
|
||||||
}
|
}
|
||||||
@@ -120,9 +174,9 @@ Item {
|
|||||||
|
|
||||||
StudioControls.MenuItem {
|
StudioControls.MenuItem {
|
||||||
text: qsTr("Delete")
|
text: qsTr("Delete")
|
||||||
enabled: currentMaterial
|
enabled: root.currentMaterial
|
||||||
|
|
||||||
onTriggered: materialBrowserModel.deleteMaterial(currentMaterialIdx)
|
onTriggered: materialBrowserModel.deleteMaterial(root.currentMaterialIdx)
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.MenuSeparator {}
|
StudioControls.MenuSeparator {}
|
||||||
@@ -141,6 +195,7 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: root.width
|
width: root.width
|
||||||
|
enabled: !materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport
|
||||||
|
|
||||||
SearchBox {
|
SearchBox {
|
||||||
id: searchBox
|
id: searchBox
|
||||||
@@ -165,22 +220,22 @@ Item {
|
|||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
font.pixelSize: StudioTheme.Values.baseFontSize
|
font.pixelSize: StudioTheme.Values.baseFontSize
|
||||||
leftPadding: 10
|
leftPadding: 10
|
||||||
visible: materialBrowserModel.hasQuick3DImport && materialBrowserModel.isEmpty && !searchBox.isEmpty()
|
visible: materialBrowserModel.hasQuick3DImport && materialBrowserModel.isEmpty
|
||||||
|
&& !searchBox.isEmpty() && !materialBrowserModel.hasMaterialRoot
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
text: qsTr("There are no materials in this project.<br>Select '<b>+</b>' to create one.")
|
text: {
|
||||||
textFormat: Text.RichText
|
if (materialBrowserModel.hasMaterialRoot)
|
||||||
color: StudioTheme.Values.themeTextColor
|
qsTr("<b>Material Browser</b> is disabled inside a material component.")
|
||||||
font.pixelSize: StudioTheme.Values.mediumFontSize
|
else if (!materialBrowserModel.hasQuick3DImport)
|
||||||
horizontalAlignment: Text.AlignHCenter
|
qsTr("To use <b>Material Browser</b>, first add the QtQuick3D module in the <b>Components</b> view.")
|
||||||
topPadding: 30
|
else if (materialBrowserModel.isEmpty && searchBox.isEmpty())
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
qsTr("There are no materials in this project.<br>Select '<b>+</b>' to create one.")
|
||||||
visible: materialBrowserModel.hasQuick3DImport && materialBrowserModel.isEmpty && searchBox.isEmpty()
|
else
|
||||||
}
|
""
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
|
||||||
text: qsTr("To use <b>Material Browser</b>, first add the QtQuick3D module in the <b>Components</b> view.");
|
|
||||||
textFormat: Text.RichText
|
textFormat: Text.RichText
|
||||||
color: StudioTheme.Values.themeTextColor
|
color: StudioTheme.Values.themeTextColor
|
||||||
font.pixelSize: StudioTheme.Values.mediumFontSize
|
font.pixelSize: StudioTheme.Values.mediumFontSize
|
||||||
@@ -188,8 +243,7 @@ Item {
|
|||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
width: root.width
|
width: root.width
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
visible: text !== ""
|
||||||
visible: !materialBrowserModel.hasQuick3DImport
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
|
@@ -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,43 @@ 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 }
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: specificsTwo
|
||||||
|
|
||||||
|
property string theSource: specificQmlData
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
visible: theSource !== ""
|
||||||
|
sourceComponent: specificQmlComponent
|
||||||
|
|
||||||
|
onTheSourceChanged: {
|
||||||
|
active = false
|
||||||
|
active = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item { width: 1; height: 10 }
|
Item { width: 1; height: 10 }
|
||||||
|
@@ -47,10 +47,10 @@ Rectangle {
|
|||||||
IconButton {
|
IconButton {
|
||||||
icon: StudioTheme.Constants.applyMaterialToSelected
|
icon: StudioTheme.Constants.applyMaterialToSelected
|
||||||
|
|
||||||
normalColor: "transparent"
|
normalColor: StudioTheme.Values.themeSectionHeadBackground
|
||||||
iconSize: StudioTheme.Values.bigIconFontSize
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
buttonSize: root.height
|
buttonSize: root.height
|
||||||
enabled: hasMaterial && hasModelSelection && hasQuick3DImport
|
enabled: hasMaterial && hasModelSelection && hasQuick3DImport && !hasMaterialRoot
|
||||||
onClicked: root.toolBarAction(ToolBarAction.ApplyToSelected)
|
onClicked: root.toolBarAction(ToolBarAction.ApplyToSelected)
|
||||||
tooltip: qsTr("Apply material to selected model.")
|
tooltip: qsTr("Apply material to selected model.")
|
||||||
}
|
}
|
||||||
@@ -58,10 +58,10 @@ Rectangle {
|
|||||||
IconButton {
|
IconButton {
|
||||||
icon: StudioTheme.Constants.newMaterial
|
icon: StudioTheme.Constants.newMaterial
|
||||||
|
|
||||||
normalColor: "transparent"
|
normalColor: StudioTheme.Values.themeSectionHeadBackground
|
||||||
iconSize: StudioTheme.Values.bigIconFontSize
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
buttonSize: root.height
|
buttonSize: root.height
|
||||||
enabled: hasQuick3DImport
|
enabled: hasQuick3DImport && !hasMaterialRoot
|
||||||
onClicked: root.toolBarAction(ToolBarAction.AddNewMaterial)
|
onClicked: root.toolBarAction(ToolBarAction.AddNewMaterial)
|
||||||
tooltip: qsTr("Create new material.")
|
tooltip: qsTr("Create new material.")
|
||||||
}
|
}
|
||||||
@@ -69,10 +69,10 @@ Rectangle {
|
|||||||
IconButton {
|
IconButton {
|
||||||
icon: StudioTheme.Constants.deleteMaterial
|
icon: StudioTheme.Constants.deleteMaterial
|
||||||
|
|
||||||
normalColor: "transparent"
|
normalColor: StudioTheme.Values.themeSectionHeadBackground
|
||||||
iconSize: StudioTheme.Values.bigIconFontSize
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
buttonSize: root.height
|
buttonSize: root.height
|
||||||
enabled: hasMaterial && hasQuick3DImport
|
enabled: hasMaterial && hasQuick3DImport && !hasMaterialRoot
|
||||||
onClicked: root.toolBarAction(ToolBarAction.DeleteCurrentMaterial)
|
onClicked: root.toolBarAction(ToolBarAction.DeleteCurrentMaterial)
|
||||||
tooltip: qsTr("Delete current material.")
|
tooltip: qsTr("Delete current material.")
|
||||||
}
|
}
|
||||||
@@ -80,10 +80,10 @@ Rectangle {
|
|||||||
IconButton {
|
IconButton {
|
||||||
icon: StudioTheme.Constants.openMaterialBrowser
|
icon: StudioTheme.Constants.openMaterialBrowser
|
||||||
|
|
||||||
normalColor: "transparent"
|
normalColor: StudioTheme.Values.themeSectionHeadBackground
|
||||||
iconSize: StudioTheme.Values.bigIconFontSize
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
buttonSize: root.height
|
buttonSize: root.height
|
||||||
enabled: hasMaterial && hasQuick3DImport
|
enabled: hasMaterial && hasQuick3DImport && !hasMaterialRoot
|
||||||
onClicked: root.toolBarAction(ToolBarAction.OpenMaterialBrowser)
|
onClicked: root.toolBarAction(ToolBarAction.OpenMaterialBrowser)
|
||||||
tooltip: qsTr("Open material browser.")
|
tooltip: qsTr("Open material browser.")
|
||||||
}
|
}
|
||||||
|
@@ -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,20 +64,133 @@ Column {
|
|||||||
|
|
||||||
Item { width: 1; height: 10 } // spacer
|
Item { width: 1; height: 10 } // spacer
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 152
|
|
||||||
height: 152
|
|
||||||
color: "#000000"
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Image {
|
StudioControls.Menu {
|
||||||
id: materialPreview
|
id: modelMenu
|
||||||
width: 150
|
closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside
|
||||||
height: 150
|
|
||||||
anchors.centerIn: parent
|
ListModel {
|
||||||
source: "image://materialEditor/preview"
|
id: modelMenuModel
|
||||||
cache: false
|
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 {
|
||||||
|
id: previewRect
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: 152
|
||||||
|
height: 152
|
||||||
|
color: "#000000"
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: materialPreview
|
||||||
|
width: 150
|
||||||
|
height: 150
|
||||||
|
anchors.centerIn: parent
|
||||||
|
source: "image://materialEditor/preview"
|
||||||
|
cache: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
|
buttonSize: previewOptions.width
|
||||||
|
tooltip: qsTr("Select preview environment.")
|
||||||
|
onClicked: envMenu.popup()
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
icon: StudioTheme.Constants.materialPreviewModel
|
||||||
|
iconSize: StudioTheme.Values.bigIconFontSize
|
||||||
|
buttonSize: previewOptions.width
|
||||||
|
tooltip: qsTr("Select preview model.")
|
||||||
|
onClicked: modelMenu.popup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
@@ -103,17 +227,8 @@ Column {
|
|||||||
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
currentIndex: {
|
currentIndex: possibleTypeIndex
|
||||||
if (backendValues.__classNamePrivateInternal.value === "CustomMaterial")
|
model: possibleTypes
|
||||||
return 2
|
|
||||||
|
|
||||||
if (backendValues.__classNamePrivateInternal.value === "PrincipledMaterial")
|
|
||||||
return 1
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
model: ["DefaultMaterial", "PrincipledMaterial", "CustomMaterial"]
|
|
||||||
showExtendedFunctionButton: false
|
showExtendedFunctionButton: false
|
||||||
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
implicitWidth: StudioTheme.Values.singleControlColumnWidth
|
||||||
|
|
||||||
|
@@ -51,13 +51,6 @@ Rectangle {
|
|||||||
: mouseArea.containsMouse ? hoverColor
|
: mouseArea.containsMouse ? hoverColor
|
||||||
: normalColor
|
: normalColor
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation {
|
|
||||||
duration: 300
|
|
||||||
easing.type: Easing.OutQuad
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: icon
|
id: icon
|
||||||
|
|
||||||
|
@@ -136,7 +136,7 @@ Item {
|
|||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "hover"
|
name: "hover"
|
||||||
when: searchFilterText.hovered && !searchFilterText.activeFocus
|
when: root.enabled && searchFilterText.hovered && !searchFilterText.activeFocus
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: textFieldBackground
|
target: textFieldBackground
|
||||||
color: StudioTheme.Values.themeControlBackgroundHover
|
color: StudioTheme.Values.themeControlBackgroundHover
|
||||||
|
@@ -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.
@@ -318,8 +318,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "Screen01.ui.qml.tpl",
|
"source": "Screen01.ui.qml.tpl",
|
||||||
"target": "%{ProjectDirectory}/content/Screen01.ui.qml",
|
"target": "%{ProjectDirectory}/content/Screen01.ui.qml"
|
||||||
"openInEditor": true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "../common/fonts.txt",
|
"source": "../common/fonts.txt",
|
||||||
|
@@ -421,6 +421,7 @@ namespace ADS {
|
|||||||
d->m_lastLocation = InvalidDockWidgetArea;
|
d->m_lastLocation = InvalidDockWidgetArea;
|
||||||
|
|
||||||
// Move it over the target.
|
// Move it over the target.
|
||||||
|
hide();
|
||||||
resize(target->size());
|
resize(target->size());
|
||||||
QPoint topLeft = target->mapToGlobal(target->rect().topLeft());
|
QPoint topLeft = target->mapToGlobal(target->rect().topLeft());
|
||||||
move(topLeft);
|
move(topLeft);
|
||||||
|
@@ -612,7 +612,7 @@ class UnsupportedTypesByVisualDesigner : public QStringList
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UnsupportedTypesByVisualDesigner()
|
UnsupportedTypesByVisualDesigner()
|
||||||
: QStringList({"Timer", "Package", "Particles", "ApplicationWindow"})
|
: QStringList({"Package", "Particles", "ApplicationWindow"})
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -175,6 +175,11 @@ bool JLinkGdbServerProvider::operator==(const IDebugServerProvider &other) const
|
|||||||
|
|
||||||
const auto p = static_cast<const JLinkGdbServerProvider *>(&other);
|
const auto p = static_cast<const JLinkGdbServerProvider *>(&other);
|
||||||
return m_executableFile == p->m_executableFile
|
return m_executableFile == p->m_executableFile
|
||||||
|
&& m_jlinkDevice == p->m_jlinkDevice
|
||||||
|
&& m_jlinkHost == p->m_jlinkHost
|
||||||
|
&& m_jlinkHostAddr == p->m_jlinkHostAddr
|
||||||
|
&& m_jlinkTargetIface == p->m_jlinkTargetIface
|
||||||
|
&& m_jlinkTargetIfaceSpeed == p->m_jlinkTargetIfaceSpeed
|
||||||
&& m_additionalArguments == p->m_additionalArguments;
|
&& m_additionalArguments == p->m_additionalArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -157,6 +157,20 @@ static void checkSystemForClangdSuitability()
|
|||||||
Core::ICore::infoBar()->addInfo(info);
|
Core::ICore::infoBar()->addInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void updateParserConfig(ClangdClient *client)
|
||||||
|
{
|
||||||
|
if (!client->reachable())
|
||||||
|
return;
|
||||||
|
if (const auto editor = TextEditor::BaseTextEditor::currentTextEditor()) {
|
||||||
|
if (!client->documentOpen(editor->textDocument()))
|
||||||
|
return;
|
||||||
|
const Utils::FilePath filePath = editor->textDocument()->filePath();
|
||||||
|
if (const auto processor = ClangEditorDocumentProcessor::get(filePath.toString()))
|
||||||
|
client->updateParserConfig(filePath, processor->parserConfig());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ClangModelManagerSupport::ClangModelManagerSupport()
|
ClangModelManagerSupport::ClangModelManagerSupport()
|
||||||
{
|
{
|
||||||
watchForExternalChanges();
|
watchForExternalChanges();
|
||||||
@@ -382,6 +396,13 @@ void ClangModelManagerSupport::updateLanguageClient(
|
|||||||
if (Client * const oldClient = clientForProject(project))
|
if (Client * const oldClient = clientForProject(project))
|
||||||
LanguageClientManager::shutdownClient(oldClient);
|
LanguageClientManager::shutdownClient(oldClient);
|
||||||
ClangdClient * const client = new ClangdClient(project, jsonDbDir);
|
ClangdClient * const client = new ClangdClient(project, jsonDbDir);
|
||||||
|
connect(client, &Client::shadowDocumentSwitched, this, [](const Utils::FilePath &fp) {
|
||||||
|
ClangdClient::handleUiHeaderChange(fp.fileName());
|
||||||
|
});
|
||||||
|
connect(CppModelManager::instance(),
|
||||||
|
&CppModelManager::projectPartsUpdated,
|
||||||
|
client,
|
||||||
|
[client] { updateParserConfig(client); });
|
||||||
connect(client, &Client::initialized, this, [this, client, project, projectInfo, jsonDbDir] {
|
connect(client, &Client::initialized, this, [this, client, project, projectInfo, jsonDbDir] {
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
if (!SessionManager::hasProject(project))
|
if (!SessionManager::hasProject(project))
|
||||||
@@ -393,25 +414,15 @@ void ClangModelManagerSupport::updateLanguageClient(
|
|||||||
if (!newProjectInfo || *newProjectInfo != *projectInfo)
|
if (!newProjectInfo || *newProjectInfo != *projectInfo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto updateParserConfig = [client] {
|
|
||||||
if (const auto editor = TextEditor::BaseTextEditor::currentTextEditor()) {
|
|
||||||
if (!client->documentOpen(editor->textDocument()))
|
|
||||||
return;
|
|
||||||
const Utils::FilePath filePath = editor->textDocument()->filePath();
|
|
||||||
if (const auto processor = ClangEditorDocumentProcessor::get(
|
|
||||||
filePath.toString())) {
|
|
||||||
const CppEditor::BaseEditorDocumentParser::Configuration config
|
|
||||||
= processor->parserConfig();
|
|
||||||
client->updateParserConfig(filePath, config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Acquaint the client with all open C++ documents for this project.
|
// Acquaint the client with all open C++ documents for this project.
|
||||||
bool hasDocuments = false;
|
bool hasDocuments = false;
|
||||||
const ClangdSettings settings(ClangdProjectSettings(project).settings());
|
const ClangdSettings settings(ClangdProjectSettings(project).settings());
|
||||||
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
for (TextEditor::TextDocument * const doc : allCppDocuments()) {
|
||||||
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
Client * const currentClient = LanguageClientManager::clientForDocument(doc);
|
||||||
|
if (currentClient == client) {
|
||||||
|
hasDocuments = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!settings.sizeIsOkay(doc->filePath()))
|
if (!settings.sizeIsOkay(doc->filePath()))
|
||||||
continue;
|
continue;
|
||||||
const Project * const docProject = SessionManager::projectForFile(doc->filePath());
|
const Project * const docProject = SessionManager::projectForFile(doc->filePath());
|
||||||
@@ -440,17 +451,8 @@ void ClangModelManagerSupport::updateLanguageClient(
|
|||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connect(client, &Client::shadowDocumentSwitched, this,
|
|
||||||
[](const Utils::FilePath &fp) {
|
|
||||||
ClangdClient::handleUiHeaderChange(fp.fileName());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (client->state() == Client::Initialized)
|
updateParserConfig(client);
|
||||||
updateParserConfig();
|
|
||||||
else
|
|
||||||
connect(client, &Client::initialized, client, updateParserConfig);
|
|
||||||
connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
|
|
||||||
client, updateParserConfig);
|
|
||||||
|
|
||||||
if (hasDocuments)
|
if (hasDocuments)
|
||||||
return;
|
return;
|
||||||
|
@@ -66,7 +66,6 @@ void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style,
|
|||||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
style.DisableFormat = false;
|
|
||||||
style.ColumnLimit = 0;
|
style.ColumnLimit = 0;
|
||||||
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
|
#ifdef KEEP_LINE_BREAKS_FOR_NON_EMPTY_LINES_BACKPORTED
|
||||||
style.KeepLineBreaksForNonEmptyLines = true;
|
style.KeepLineBreaksForNonEmptyLines = true;
|
||||||
|
@@ -435,7 +435,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
void onBinaryPathEditingFinished();
|
void onBinaryPathEditingFinished();
|
||||||
void updateQchFilePath();
|
void updateQchFilePath();
|
||||||
void reload();
|
|
||||||
|
|
||||||
CMakeToolItemModel *m_model;
|
CMakeToolItemModel *m_model;
|
||||||
QLineEdit *m_displayNameLineEdit;
|
QLineEdit *m_displayNameLineEdit;
|
||||||
@@ -501,7 +500,6 @@ void CMakeToolItemConfigWidget::onBinaryPathEditingFinished()
|
|||||||
{
|
{
|
||||||
updateQchFilePath();
|
updateQchFilePath();
|
||||||
store();
|
store();
|
||||||
reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeToolItemConfigWidget::updateQchFilePath()
|
void CMakeToolItemConfigWidget::updateQchFilePath()
|
||||||
@@ -510,18 +508,6 @@ void CMakeToolItemConfigWidget::updateQchFilePath()
|
|||||||
m_qchFileChooser->setFilePath(CMakeTool::searchQchFile(m_binaryChooser->filePath()));
|
m_qchFileChooser->setFilePath(CMakeTool::searchQchFile(m_binaryChooser->filePath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMakeToolItemConfigWidget::reload()
|
|
||||||
{
|
|
||||||
if (!m_id.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const CMakeToolTreeItem *item = m_model->cmakeToolItem(m_id);
|
|
||||||
if (!item)
|
|
||||||
return;
|
|
||||||
|
|
||||||
load(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
|
void CMakeToolItemConfigWidget::load(const CMakeToolTreeItem *item)
|
||||||
{
|
{
|
||||||
m_loadingItem = true; // avoid intermediate signal handling
|
m_loadingItem = true; // avoid intermediate signal handling
|
||||||
|
@@ -473,16 +473,16 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions()
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case LanguageVersion::CXX14:
|
case LanguageVersion::CXX14:
|
||||||
option = "-clang:std=c++14";
|
option = "-clang:-std=c++14";
|
||||||
break;
|
break;
|
||||||
case LanguageVersion::CXX17:
|
case LanguageVersion::CXX17:
|
||||||
option = "-clang:std=c++17";
|
option = "-clang:-std=c++17";
|
||||||
break;
|
break;
|
||||||
case LanguageVersion::CXX20:
|
case LanguageVersion::CXX20:
|
||||||
option = "-clang:std=c++20";
|
option = "-clang:-std=c++20";
|
||||||
break;
|
break;
|
||||||
case LanguageVersion::CXX2b:
|
case LanguageVersion::CXX2b:
|
||||||
option = "-clang:std=c++2b";
|
option = "-clang:-std=c++2b";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -192,7 +192,7 @@ void CompilerOptionsBuilderTest::testLanguageVersionIsExplicitlySetIfNotProvided
|
|||||||
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
|
UseTweakedHeaderPaths::No, UseLanguageDefines::Yes};
|
||||||
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
|
compilerOptionsBuilder.build(ProjectFile::CXXSource, UsePrecompiledHeaders::No);
|
||||||
|
|
||||||
QVERIFY(compilerOptionsBuilder.options().contains("-clang:std=c++17"));
|
QVERIFY(compilerOptionsBuilder.options().contains("-clang:-std=c++17"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOptionsBuilderTest::testAddWordWidth()
|
void CompilerOptionsBuilderTest::testAddWordWidth()
|
||||||
@@ -633,7 +633,7 @@ void CompilerOptionsBuilderTest::testBuildAllOptionsMsvc()
|
|||||||
[&t](const QString &o) { return o.contains(t.toNative("wrappedQtHeaders/QtCore")); });
|
[&t](const QString &o) { return o.contains(t.toNative("wrappedQtHeaders/QtCore")); });
|
||||||
QCOMPARE(compilerOptionsBuilder.options(),
|
QCOMPARE(compilerOptionsBuilder.options(),
|
||||||
(QStringList{"-nostdinc", "-nostdinc++", "--driver-mode=cl", "/Zs", "-m64",
|
(QStringList{"-nostdinc", "-nostdinc++", "--driver-mode=cl", "/Zs", "-m64",
|
||||||
"--target=x86_64-apple-darwin10", "/TP", "-clang:std=c++17",
|
"--target=x86_64-apple-darwin10", "/TP", "-clang:-std=c++17",
|
||||||
"-fms-compatibility-version=19.00", "-DprojectFoo=projectBar",
|
"-fms-compatibility-version=19.00", "-DprojectFoo=projectBar",
|
||||||
"-D__FUNCSIG__=\"void __cdecl someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580(void)\"",
|
"-D__FUNCSIG__=\"void __cdecl someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580(void)\"",
|
||||||
"-D__FUNCTION__=\"someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580\"",
|
"-D__FUNCTION__=\"someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580\"",
|
||||||
@@ -662,7 +662,7 @@ void CompilerOptionsBuilderTest::testBuildAllOptionsMsvcWithExceptions()
|
|||||||
[&t](const QString &o) { return o.contains(t.toNative("wrappedQtHeaders/QtCore")); });
|
[&t](const QString &o) { return o.contains(t.toNative("wrappedQtHeaders/QtCore")); });
|
||||||
QCOMPARE(compilerOptionsBuilder.options(),
|
QCOMPARE(compilerOptionsBuilder.options(),
|
||||||
(QStringList{"-nostdinc", "-nostdinc++", "--driver-mode=cl", "/Zs", "-m64",
|
(QStringList{"-nostdinc", "-nostdinc++", "--driver-mode=cl", "/Zs", "-m64",
|
||||||
"--target=x86_64-apple-darwin10", "/TP", "-clang:std=c++17", "-fcxx-exceptions",
|
"--target=x86_64-apple-darwin10", "/TP", "-clang:-std=c++17", "-fcxx-exceptions",
|
||||||
"-fexceptions", "-fms-compatibility-version=19.00",
|
"-fexceptions", "-fms-compatibility-version=19.00",
|
||||||
"-DprojectFoo=projectBar",
|
"-DprojectFoo=projectBar",
|
||||||
"-D__FUNCSIG__=\"void __cdecl someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580(void)\"",
|
"-D__FUNCSIG__=\"void __cdecl someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580(void)\"",
|
||||||
|
@@ -378,7 +378,6 @@ SignalSlotType CppModelManager::getSignalSlotType(const FilePath &filePath,
|
|||||||
QTextCursor cursor(&textDocument);
|
QTextCursor cursor(&textDocument);
|
||||||
cursor.setPosition(position);
|
cursor.setPosition(position);
|
||||||
|
|
||||||
// Are we at the second argument of a function call?
|
|
||||||
const QList<AST *> path = ASTPath(document)(cursor);
|
const QList<AST *> path = ASTPath(document)(cursor);
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return SignalSlotType::None;
|
return SignalSlotType::None;
|
||||||
@@ -388,9 +387,27 @@ SignalSlotType CppModelManager::getSignalSlotType(const FilePath &filePath,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the function called "connect" or "disconnect"?
|
|
||||||
if (!callAst || !callAst->base_expression)
|
if (!callAst || !callAst->base_expression)
|
||||||
return SignalSlotType::None;
|
return SignalSlotType::None;
|
||||||
|
|
||||||
|
const int argumentPosition = argumentPositionOf(path.last(), callAst);
|
||||||
|
if (argumentPosition != 2 && argumentPosition != 4)
|
||||||
|
return SignalSlotType::None;
|
||||||
|
|
||||||
|
const NameAST *nameAst = nullptr;
|
||||||
|
if (const IdExpressionAST * const idAst = callAst->base_expression->asIdExpression())
|
||||||
|
nameAst = idAst->name;
|
||||||
|
else if (const MemberAccessAST * const ast = callAst->base_expression->asMemberAccess())
|
||||||
|
nameAst = ast->member_name;
|
||||||
|
if (!nameAst || !nameAst->name)
|
||||||
|
return SignalSlotType::None;
|
||||||
|
const Identifier * const id = nameAst->name->identifier();
|
||||||
|
if (!id)
|
||||||
|
return SignalSlotType::None;
|
||||||
|
const QString funcName = QString::fromUtf8(id->chars(), id->size());
|
||||||
|
if (funcName != "connect" && funcName != "disconnect")
|
||||||
|
return SignalSlotType::None;
|
||||||
|
|
||||||
Scope *scope = document->globalNamespace();
|
Scope *scope = document->globalNamespace();
|
||||||
for (auto it = path.crbegin(); it != path.crend(); ++it) {
|
for (auto it = path.crbegin(); it != path.crend(); ++it) {
|
||||||
if (const CompoundStatementAST * const stmtAst = (*it)->asCompoundStatement()) {
|
if (const CompoundStatementAST * const stmtAst = (*it)->asCompoundStatement()) {
|
||||||
@@ -398,12 +415,8 @@ SignalSlotType CppModelManager::getSignalSlotType(const FilePath &filePath,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const NameAST *nameAst = nullptr;
|
|
||||||
const LookupContext context(document, snapshot);
|
const LookupContext context(document, snapshot);
|
||||||
if (const IdExpressionAST * const idAst = callAst->base_expression->asIdExpression()) {
|
if (const MemberAccessAST * const ast = callAst->base_expression->asMemberAccess()) {
|
||||||
nameAst = idAst->name;
|
|
||||||
} else if (const MemberAccessAST * const ast = callAst->base_expression->asMemberAccess()) {
|
|
||||||
nameAst = ast->member_name;
|
|
||||||
TypeOfExpression exprType;
|
TypeOfExpression exprType;
|
||||||
exprType.setExpandTemplates(true);
|
exprType.setExpandTemplates(true);
|
||||||
exprType.init(document, snapshot);
|
exprType.init(document, snapshot);
|
||||||
@@ -433,14 +446,6 @@ SignalSlotType CppModelManager::getSignalSlotType(const FilePath &filePath,
|
|||||||
if (!scope)
|
if (!scope)
|
||||||
return SignalSlotType::None;
|
return SignalSlotType::None;
|
||||||
}
|
}
|
||||||
if (!nameAst || !nameAst->name)
|
|
||||||
return SignalSlotType::None;
|
|
||||||
const Identifier * const id = nameAst->name->identifier();
|
|
||||||
if (!id)
|
|
||||||
return SignalSlotType::None;
|
|
||||||
const QString funcName = QString::fromUtf8(id->chars(), id->size());
|
|
||||||
if (funcName != "connect" && funcName != "disconnect")
|
|
||||||
return SignalSlotType::None;
|
|
||||||
|
|
||||||
// Is the function a member function of QObject?
|
// Is the function a member function of QObject?
|
||||||
const QList<LookupItem> matches = context.lookup(nameAst->name, scope);
|
const QList<LookupItem> matches = context.lookup(nameAst->name, scope);
|
||||||
@@ -463,10 +468,8 @@ SignalSlotType CppModelManager::getSignalSlotType(const FilePath &filePath,
|
|||||||
|
|
||||||
expression = expressionUnderCursor(cursor);
|
expression = expressionUnderCursor(cursor);
|
||||||
|
|
||||||
const int argumentPosition = argumentPositionOf(path.last(), callAst);
|
if (expression.endsWith(QLatin1String("SIGNAL"))
|
||||||
if ((expression.endsWith(QLatin1String("SIGNAL"))
|
|| (expression.endsWith(QLatin1String("SLOT")) && argumentPosition == 4))
|
||||||
&& (argumentPosition == 2 || argumentPosition == 4))
|
|
||||||
|| (expression.endsWith(QLatin1String("SLOT")) && argumentPosition == 4))
|
|
||||||
return SignalSlotType::OldStyleSignal;
|
return SignalSlotType::OldStyleSignal;
|
||||||
|
|
||||||
if (argumentPosition == 2)
|
if (argumentPosition == 2)
|
||||||
|
@@ -5247,10 +5247,12 @@ ExtractFunction::ExtractFunction(FunctionNameGetter functionNameGetter)
|
|||||||
void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
|
void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOperations &result)
|
||||||
{
|
{
|
||||||
const CppRefactoringFilePtr file = interface.currentFile();
|
const CppRefactoringFilePtr file = interface.currentFile();
|
||||||
if (CppModelManager::usesClangd(file->editor()->textDocument())
|
|
||||||
&& file->cppDocument()->languageFeatures().cxxEnabled) {
|
// TODO: Fix upstream and uncomment; see QTCREATORBUG-28030.
|
||||||
return;
|
// if (CppModelManager::usesClangd(file->editor()->textDocument())
|
||||||
}
|
// && file->cppDocument()->languageFeatures().cxxEnabled) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
QTextCursor cursor = file->cursor();
|
QTextCursor cursor = file->cursor();
|
||||||
if (!cursor.hasSelection())
|
if (!cursor.hasSelection())
|
||||||
|
@@ -283,7 +283,17 @@ public:
|
|||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
LanguageFilter m_languagFilter;
|
LanguageFilter m_languagFilter;
|
||||||
QJsonObject m_initializationOptions;
|
QJsonObject m_initializationOptions;
|
||||||
QMap<TextEditor::TextDocument *, QString> m_openedDocument;
|
class OpenedDocument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~OpenedDocument()
|
||||||
|
{
|
||||||
|
QObject::disconnect(contentsChangedConnection);
|
||||||
|
}
|
||||||
|
QMetaObject::Connection contentsChangedConnection;
|
||||||
|
QString documentContents;
|
||||||
|
};
|
||||||
|
QMap<TextEditor::TextDocument *, OpenedDocument> m_openedDocument;
|
||||||
|
|
||||||
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
|
// Used for build system artifacts (e.g. UI headers) that Qt Creator "live-generates" ahead of
|
||||||
// the build.
|
// the build.
|
||||||
@@ -618,11 +628,14 @@ void Client::openDocument(TextEditor::TextDocument *document)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->m_openedDocument[document] = document->plainText();
|
d->m_openedDocument[document].documentContents = document->plainText();
|
||||||
connect(document, &TextDocument::contentsChangedWithPosition, this,
|
d->m_openedDocument[document].contentsChangedConnection
|
||||||
[this, document](int position, int charsRemoved, int charsAdded) {
|
= connect(document,
|
||||||
documentContentsChanged(document, position, charsRemoved, charsAdded);
|
&TextDocument::contentsChangedWithPosition,
|
||||||
});
|
this,
|
||||||
|
[this, document](int position, int charsRemoved, int charsAdded) {
|
||||||
|
documentContentsChanged(document, position, charsRemoved, charsAdded);
|
||||||
|
});
|
||||||
if (!d->m_documentVersions.contains(filePath))
|
if (!d->m_documentVersions.contains(filePath))
|
||||||
d->m_documentVersions[filePath] = 0;
|
d->m_documentVersions[filePath] = 0;
|
||||||
d->sendOpenNotification(filePath, document->mimeType(), document->plainText(),
|
d->sendOpenNotification(filePath, document->mimeType(), document->plainText(),
|
||||||
@@ -1083,7 +1096,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (append) {
|
if (append) {
|
||||||
QTextDocument oldDoc(d->m_openedDocument[document]);
|
QTextDocument oldDoc(d->m_openedDocument[document].documentContents);
|
||||||
QTextCursor cursor(&oldDoc);
|
QTextCursor cursor(&oldDoc);
|
||||||
// Workaround https://bugreports.qt.io/browse/QTBUG-80662
|
// Workaround https://bugreports.qt.io/browse/QTBUG-80662
|
||||||
// The contentsChanged gives a character count that can be wrong for QTextCursor
|
// The contentsChanged gives a character count that can be wrong for QTextCursor
|
||||||
@@ -1104,7 +1117,7 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
|||||||
d->m_documentsToUpdate[document] = {
|
d->m_documentsToUpdate[document] = {
|
||||||
DidChangeTextDocumentParams::TextDocumentContentChangeEvent(document->plainText())};
|
DidChangeTextDocumentParams::TextDocumentContentChangeEvent(document->plainText())};
|
||||||
}
|
}
|
||||||
d->m_openedDocument[document] = document->plainText();
|
d->m_openedDocument[document].documentContents = document->plainText();
|
||||||
}
|
}
|
||||||
|
|
||||||
++d->m_documentVersions[document->filePath()];
|
++d->m_documentVersions[document->filePath()];
|
||||||
@@ -1532,8 +1545,6 @@ bool ClientPrivate::reset()
|
|||||||
m_dynamicCapabilities.reset();
|
m_dynamicCapabilities.reset();
|
||||||
if (m_diagnosticManager)
|
if (m_diagnosticManager)
|
||||||
m_diagnosticManager->clearDiagnostics();
|
m_diagnosticManager->clearDiagnostics();
|
||||||
for (auto it = m_openedDocument.cbegin(); it != m_openedDocument.cend(); ++it)
|
|
||||||
it.key()->disconnect(this);
|
|
||||||
m_openedDocument.clear();
|
m_openedDocument.clear();
|
||||||
// temporary container needed since m_resetAssistProvider is changed in resetAssistProviders
|
// temporary container needed since m_resetAssistProvider is changed in resetAssistProviders
|
||||||
for (TextEditor::TextDocument *document : m_resetAssistProvider.keys())
|
for (TextEditor::TextDocument *document : m_resetAssistProvider.keys())
|
||||||
@@ -1544,7 +1555,8 @@ bool ClientPrivate::reset()
|
|||||||
qDeleteAll(m_documentHighlightsTimer);
|
qDeleteAll(m_documentHighlightsTimer);
|
||||||
m_documentHighlightsTimer.clear();
|
m_documentHighlightsTimer.clear();
|
||||||
m_progressManager.reset();
|
m_progressManager.reset();
|
||||||
m_shadowDocuments.clear();
|
for (auto &doc : m_shadowDocuments)
|
||||||
|
doc.second.clear();
|
||||||
m_documentVersions.clear();
|
m_documentVersions.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -117,13 +117,13 @@ public:
|
|||||||
if (python.exists())
|
if (python.exists())
|
||||||
PyLSConfigureAssistant::openDocumentWithPython(python, this);
|
PyLSConfigureAssistant::openDocumentWithPython(python, this);
|
||||||
});
|
});
|
||||||
|
connect(this, &PythonDocument::openFinishedSuccessfully,
|
||||||
|
this, &PythonDocument::checkForPyls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFilePath(const FilePath &filePath) override
|
void checkForPyls()
|
||||||
{
|
{
|
||||||
TextEditor::TextDocument::setFilePath(filePath);
|
const FilePath &python = detectPython(filePath());
|
||||||
|
|
||||||
const FilePath &python = detectPython(filePath);
|
|
||||||
if (!python.exists())
|
if (!python.exists())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -595,7 +595,7 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
easingcurve.cpp easingcurve.h
|
easingcurve.cpp easingcurve.h
|
||||||
easingcurvedialog.cpp easingcurvedialog.h
|
easingcurvedialog.cpp easingcurvedialog.h
|
||||||
preseteditor.cpp preseteditor.h
|
preseteditor.cpp preseteditor.h
|
||||||
setframevaluedialog.cpp setframevaluedialog.h setframevaluedialog.ui
|
setframevaluedialog.cpp setframevaluedialog.h
|
||||||
splineeditor.cpp splineeditor.h
|
splineeditor.cpp splineeditor.h
|
||||||
timeline.qrc
|
timeline.qrc
|
||||||
timelineabstracttool.cpp timelineabstracttool.h
|
timelineabstracttool.cpp timelineabstracttool.h
|
||||||
|
@@ -129,11 +129,13 @@ void DesignerActionManager::polishActions() const
|
|||||||
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
|
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
|
||||||
Core::Context qmlDesignerEditor3DContext(Constants::C_QMLEDITOR3D);
|
Core::Context qmlDesignerEditor3DContext(Constants::C_QMLEDITOR3D);
|
||||||
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
|
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
|
||||||
|
Core::Context qmlDesignerMaterialBrowserContext(Constants::C_QMLMATERIALBROWSER);
|
||||||
|
|
||||||
Core::Context qmlDesignerUIContext;
|
Core::Context qmlDesignerUIContext;
|
||||||
qmlDesignerUIContext.add(qmlDesignerFormEditorContext);
|
qmlDesignerUIContext.add(qmlDesignerFormEditorContext);
|
||||||
qmlDesignerUIContext.add(qmlDesignerEditor3DContext);
|
qmlDesignerUIContext.add(qmlDesignerEditor3DContext);
|
||||||
qmlDesignerUIContext.add(qmlDesignerNavigatorContext);
|
qmlDesignerUIContext.add(qmlDesignerNavigatorContext);
|
||||||
|
qmlDesignerUIContext.add(qmlDesignerMaterialBrowserContext);
|
||||||
|
|
||||||
for (auto *action : actions) {
|
for (auto *action : actions) {
|
||||||
if (!action->menuId().isEmpty()) {
|
if (!action->menuId().isEmpty()) {
|
||||||
|
@@ -130,6 +130,8 @@ public:
|
|||||||
listView,
|
listView,
|
||||||
lockOff,
|
lockOff,
|
||||||
lockOn,
|
lockOn,
|
||||||
|
materialPreviewEnvironment,
|
||||||
|
materialPreviewModel,
|
||||||
mergeCells,
|
mergeCells,
|
||||||
minus,
|
minus,
|
||||||
mirror,
|
mirror,
|
||||||
|
@@ -85,7 +85,7 @@ void ColorControl::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
if (color != m_color) {
|
if (color.isValid() && color != m_color) {
|
||||||
m_color = color;
|
m_color = color;
|
||||||
update();
|
update();
|
||||||
emit valueChanged();
|
emit valueChanged();
|
||||||
|
@@ -27,7 +27,10 @@
|
|||||||
#include "curveitem.h"
|
#include "curveitem.h"
|
||||||
#include "handleitem.h"
|
#include "handleitem.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <QGraphicsSceneMouseEvent>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
@@ -452,10 +455,22 @@ QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons
|
|||||||
lseg.moveRightTo(position);
|
lseg.moveRightTo(position);
|
||||||
rseg.moveLeftTo(position);
|
rseg.moveLeftTo(position);
|
||||||
|
|
||||||
if (legalLeft() && legalRight())
|
if (legalLeft() && legalRight()) {
|
||||||
m_validPos = position;
|
if (qApp->keyboardModifiers().testFlag(Qt::ShiftModifier) && m_validPos.has_value()) {
|
||||||
|
if (m_firstPos) {
|
||||||
|
auto firstToNow = QLineF(*m_firstPos, position);
|
||||||
|
if (std::abs(firstToNow.dx()) > std::abs(firstToNow.dy()))
|
||||||
|
m_validPos = QPointF(position.x(), m_firstPos->y());
|
||||||
|
else
|
||||||
|
m_validPos = QPointF(m_firstPos->x(), position.y());
|
||||||
|
}
|
||||||
|
|
||||||
return QVariant(m_transform.map(m_validPos));
|
} else {
|
||||||
|
m_validPos = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant(m_transform.map(*m_validPos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -465,6 +480,11 @@ QVariant KeyframeItem::itemChange(QGraphicsItem::GraphicsItemChange change, cons
|
|||||||
|
|
||||||
void KeyframeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
void KeyframeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
|
bool ok;
|
||||||
|
m_firstPos = m_transform.inverted(&ok).map(event->scenePos());
|
||||||
|
if (!ok)
|
||||||
|
m_firstPos = Utils::nullopt;
|
||||||
|
|
||||||
SelectableItem::mousePressEvent(event);
|
SelectableItem::mousePressEvent(event);
|
||||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(parentItem()))
|
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(parentItem()))
|
||||||
curveItem->setHandleVisibility(false);
|
curveItem->setHandleVisibility(false);
|
||||||
@@ -472,6 +492,7 @@ void KeyframeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
void KeyframeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
void KeyframeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||||
{
|
{
|
||||||
|
m_firstPos = Utils::nullopt;
|
||||||
SelectableItem::mouseReleaseEvent(event);
|
SelectableItem::mouseReleaseEvent(event);
|
||||||
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(parentItem()))
|
if (auto *curveItem = qgraphicsitem_cast<CurveItem *>(parentItem()))
|
||||||
curveItem->setHandleVisibility(true);
|
curveItem->setHandleVisibility(true);
|
||||||
|
@@ -30,6 +30,8 @@
|
|||||||
#include "keyframe.h"
|
#include "keyframe.h"
|
||||||
#include "selectableitem.h"
|
#include "selectableitem.h"
|
||||||
|
|
||||||
|
#include <utils/optional.h>
|
||||||
|
|
||||||
#include <QGraphicsObject>
|
#include <QGraphicsObject>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
@@ -133,7 +135,8 @@ private:
|
|||||||
|
|
||||||
HandleItem *m_right;
|
HandleItem *m_right;
|
||||||
|
|
||||||
QPointF m_validPos;
|
Utils::optional< QPointF > m_firstPos;
|
||||||
|
Utils::optional< QPointF > m_validPos;
|
||||||
|
|
||||||
bool m_visibleOverride = true;
|
bool m_visibleOverride = true;
|
||||||
|
|
||||||
|
@@ -24,9 +24,13 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "materialbrowsermodel.h"
|
#include "materialbrowsermodel.h"
|
||||||
#include "variantproperty.h"
|
|
||||||
|
#include <bindingproperty.h>
|
||||||
#include <designmodewidget.h>
|
#include <designmodewidget.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <qmlobjectnode.h>
|
||||||
|
#include "variantproperty.h"
|
||||||
|
#include "utils/qtcassert.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -46,24 +50,27 @@ int MaterialBrowserModel::rowCount(const QModelIndex &) const
|
|||||||
|
|
||||||
QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const
|
QVariant MaterialBrowserModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
if (!index.isValid() || index.row() >= m_materialList.count()) {
|
QTC_ASSERT(index.isValid() && index.row() < m_materialList.count(), return {});
|
||||||
qWarning() << Q_FUNC_INFO << "invalid index requested";
|
QTC_ASSERT(roleNames().contains(role), return {});
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (roleNames().value(role) == "materialName") {
|
QByteArray roleName = roleNames().value(role);
|
||||||
|
if (roleName == "materialName") {
|
||||||
QVariant objName = m_materialList.at(index.row()).variantProperty("objectName").value();
|
QVariant objName = m_materialList.at(index.row()).variantProperty("objectName").value();
|
||||||
return objName.isValid() ? objName : "";
|
return objName.isValid() ? objName : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roleNames().value(role) == "materialInternalId")
|
if (roleName == "materialInternalId")
|
||||||
return m_materialList.at(index.row()).internalId();
|
return m_materialList.at(index.row()).internalId();
|
||||||
|
|
||||||
if (roleNames().value(role) == "materialVisible")
|
if (roleName == "materialVisible")
|
||||||
return isMaterialVisible(index.row());
|
return isMaterialVisible(index.row());
|
||||||
|
|
||||||
if (!roleNames().contains(role))
|
if (roleName == "materialType") {
|
||||||
qWarning() << Q_FUNC_INFO << "invalid role requested";
|
QString matType = QString::fromLatin1(m_materialList.at(index.row()).type());
|
||||||
|
if (matType.startsWith("QtQuick3D."))
|
||||||
|
matType.remove("QtQuick3D.");
|
||||||
|
return matType;
|
||||||
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -82,12 +89,57 @@ bool MaterialBrowserModel::isValidIndex(int idx) const
|
|||||||
return idx > -1 && idx < rowCount();
|
return idx > -1 && idx < rowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Loads and parses propertyGroups.json from QtQuick3D module's designer folder
|
||||||
|
*
|
||||||
|
* propertyGroups.json contains lists of QtQuick3D objects' properties grouped by sections
|
||||||
|
*
|
||||||
|
* @param path path to propertyGroups.json file
|
||||||
|
*/
|
||||||
|
void MaterialBrowserModel::loadPropertyGroups(const QString &path)
|
||||||
|
{
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if (m_propertyGroupsObj.isEmpty()) {
|
||||||
|
QFile matPropsFile(path);
|
||||||
|
|
||||||
|
if (!matPropsFile.open(QIODevice::ReadOnly)) {
|
||||||
|
qWarning("Couldn't open propertyGroups.json");
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
QJsonDocument matPropsJsonDoc = QJsonDocument::fromJson(matPropsFile.readAll());
|
||||||
|
if (matPropsJsonDoc.isNull()) {
|
||||||
|
qWarning("Invalid propertyGroups.json file");
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
m_propertyGroupsObj = matPropsJsonDoc.object();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_defaultMaterialSections.clear();
|
||||||
|
m_principledMaterialSections.clear();
|
||||||
|
m_customMaterialSections.clear();
|
||||||
|
if (ok) {
|
||||||
|
m_defaultMaterialSections.append(m_propertyGroupsObj.value("DefaultMaterial").toObject().keys());
|
||||||
|
m_principledMaterialSections.append(m_propertyGroupsObj.value("PrincipledMaterial").toObject().keys());
|
||||||
|
|
||||||
|
QStringList customMatSections = m_propertyGroupsObj.value("CustomMaterial").toObject().keys();
|
||||||
|
if (customMatSections.size() > 1) // as of now custom material has only 1 section, so we don't add it
|
||||||
|
m_customMaterialSections.append(customMatSections);
|
||||||
|
}
|
||||||
|
emit materialSectionsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> MaterialBrowserModel::roleNames() const
|
QHash<int, QByteArray> MaterialBrowserModel::roleNames() const
|
||||||
{
|
{
|
||||||
static const QHash<int, QByteArray> roles {
|
static const QHash<int, QByteArray> roles {
|
||||||
{Qt::UserRole + 1, "materialName"},
|
{Qt::UserRole + 1, "materialName"},
|
||||||
{Qt::UserRole + 2, "materialInternalId"},
|
{Qt::UserRole + 2, "materialInternalId"},
|
||||||
{Qt::UserRole + 3, "materialVisible"},
|
{Qt::UserRole + 3, "materialVisible"},
|
||||||
|
{Qt::UserRole + 4, "materialType"}
|
||||||
};
|
};
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@@ -120,6 +172,34 @@ void MaterialBrowserModel::setHasModelSelection(bool b)
|
|||||||
emit hasModelSelectionChanged();
|
emit hasModelSelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MaterialBrowserModel::hasMaterialRoot() const
|
||||||
|
{
|
||||||
|
return m_hasMaterialRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserModel::setHasMaterialRoot(bool b)
|
||||||
|
{
|
||||||
|
if (m_hasMaterialRoot == b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hasMaterialRoot = b;
|
||||||
|
emit hasMaterialRootChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MaterialBrowserModel::copiedMaterialType() const
|
||||||
|
{
|
||||||
|
return m_copiedMaterialType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserModel::setCopiedMaterialType(const QString &matType)
|
||||||
|
{
|
||||||
|
if (matType == m_copiedMaterialType)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_copiedMaterialType = matType;
|
||||||
|
emit copiedMaterialTypeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QList<ModelNode> MaterialBrowserModel::materials() const
|
QList<ModelNode> MaterialBrowserModel::materials() const
|
||||||
{
|
{
|
||||||
return m_materialList;
|
return m_materialList;
|
||||||
@@ -201,6 +281,12 @@ void MaterialBrowserModel::removeMaterial(const ModelNode &material)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserModel::deleteSelectedMaterial()
|
||||||
|
{
|
||||||
|
if (isValidIndex(m_selectedIndex))
|
||||||
|
m_materialList[m_selectedIndex].destroy();
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialBrowserModel::updateSelectedMaterial()
|
void MaterialBrowserModel::updateSelectedMaterial()
|
||||||
{
|
{
|
||||||
selectMaterial(m_selectedIndex, true);
|
selectMaterial(m_selectedIndex, true);
|
||||||
@@ -256,6 +342,42 @@ void MaterialBrowserModel::duplicateMaterial(int idx)
|
|||||||
emit duplicateMaterialTriggered(m_materialList.at(idx));
|
emit duplicateMaterialTriggered(m_materialList.at(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §ion)
|
||||||
|
{
|
||||||
|
ModelNode mat = m_materialList.at(idx);
|
||||||
|
QString matType = QString::fromLatin1(mat.type());
|
||||||
|
|
||||||
|
if (matType.startsWith("QtQuick3D."))
|
||||||
|
matType.remove("QtQuick3D.");
|
||||||
|
|
||||||
|
setCopiedMaterialType(matType);
|
||||||
|
m_allPropsCopied = section == "All";
|
||||||
|
|
||||||
|
if (m_allPropsCopied || m_propertyGroupsObj.empty()) {
|
||||||
|
m_copiedMaterialProps = mat.properties();
|
||||||
|
} else {
|
||||||
|
QJsonObject propsSpecObj = m_propertyGroupsObj.value(m_copiedMaterialType).toObject();
|
||||||
|
if (propsSpecObj.contains(section)) { // should always be true
|
||||||
|
m_copiedMaterialProps.clear();
|
||||||
|
const QJsonArray propNames = propsSpecObj.value(section).toArray();
|
||||||
|
for (const QJsonValueRef &propName : propNames)
|
||||||
|
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
|
||||||
|
|
||||||
|
if (section == "Base") { // add QtQuick3D.Material base props as well
|
||||||
|
QJsonObject propsMatObj = m_propertyGroupsObj.value("Material").toObject();
|
||||||
|
const QJsonArray propNames = propsMatObj.value("Base").toArray();
|
||||||
|
for (const QJsonValueRef &propName : propNames)
|
||||||
|
m_copiedMaterialProps.append(mat.property(propName.toString().toLatin1()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserModel::pasteMaterialProperties(int idx)
|
||||||
|
{
|
||||||
|
emit pasteMaterialPropertiesTriggered(m_materialList.at(idx), m_copiedMaterialProps, m_allPropsCopied);
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialBrowserModel::deleteMaterial(int idx)
|
void MaterialBrowserModel::deleteMaterial(int idx)
|
||||||
{
|
{
|
||||||
m_materialList[idx].destroy();
|
m_materialList[idx].destroy();
|
||||||
|
@@ -25,7 +25,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qjsonobject.h"
|
||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
|
#include <qmlobjectnode.h>
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@@ -41,6 +43,11 @@ class MaterialBrowserModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
|
Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
|
||||||
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
||||||
Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
|
Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
|
||||||
|
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
|
||||||
|
Q_PROPERTY(QString copiedMaterialType READ copiedMaterialType WRITE setCopiedMaterialType NOTIFY copiedMaterialTypeChanged)
|
||||||
|
Q_PROPERTY(QStringList defaultMaterialSections MEMBER m_defaultMaterialSections NOTIFY materialSectionsChanged)
|
||||||
|
Q_PROPERTY(QStringList principledMaterialSections MEMBER m_principledMaterialSections NOTIFY materialSectionsChanged)
|
||||||
|
Q_PROPERTY(QStringList customMaterialSections MEMBER m_customMaterialSections NOTIFY materialSectionsChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialBrowserModel(QObject *parent = nullptr);
|
MaterialBrowserModel(QObject *parent = nullptr);
|
||||||
@@ -58,18 +65,28 @@ public:
|
|||||||
bool hasModelSelection() const;
|
bool hasModelSelection() const;
|
||||||
void setHasModelSelection(bool b);
|
void setHasModelSelection(bool b);
|
||||||
|
|
||||||
|
bool hasMaterialRoot() const;
|
||||||
|
void setHasMaterialRoot(bool b);
|
||||||
|
|
||||||
|
QString copiedMaterialType() const;
|
||||||
|
void setCopiedMaterialType(const QString &matType);
|
||||||
|
|
||||||
QList<ModelNode> materials() const;
|
QList<ModelNode> materials() const;
|
||||||
void setMaterials(const QList<ModelNode> &materials, bool hasQuick3DImport);
|
void setMaterials(const QList<ModelNode> &materials, bool hasQuick3DImport);
|
||||||
void removeMaterial(const ModelNode &material);
|
void removeMaterial(const ModelNode &material);
|
||||||
|
void deleteSelectedMaterial();
|
||||||
void updateMaterialName(const ModelNode &material);
|
void updateMaterialName(const ModelNode &material);
|
||||||
void updateSelectedMaterial();
|
void updateSelectedMaterial();
|
||||||
int materialIndex(const ModelNode &material) const;
|
int materialIndex(const ModelNode &material) const;
|
||||||
ModelNode materialAt(int idx) const;
|
ModelNode materialAt(int idx) const;
|
||||||
|
void loadPropertyGroups(const QString &path);
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
|
|
||||||
Q_INVOKABLE void selectMaterial(int idx, bool force = false);
|
Q_INVOKABLE void selectMaterial(int idx, bool force = false);
|
||||||
Q_INVOKABLE void duplicateMaterial(int idx);
|
Q_INVOKABLE void duplicateMaterial(int idx);
|
||||||
|
Q_INVOKABLE void copyMaterialProperties(int idx, const QString §ion);
|
||||||
|
Q_INVOKABLE void pasteMaterialProperties(int idx);
|
||||||
Q_INVOKABLE void deleteMaterial(int idx);
|
Q_INVOKABLE void deleteMaterial(int idx);
|
||||||
Q_INVOKABLE void renameMaterial(int idx, const QString &newName);
|
Q_INVOKABLE void renameMaterial(int idx, const QString &newName);
|
||||||
Q_INVOKABLE void addNewMaterial();
|
Q_INVOKABLE void addNewMaterial();
|
||||||
@@ -80,11 +97,17 @@ signals:
|
|||||||
void isEmptyChanged();
|
void isEmptyChanged();
|
||||||
void hasQuick3DImportChanged();
|
void hasQuick3DImportChanged();
|
||||||
void hasModelSelectionChanged();
|
void hasModelSelectionChanged();
|
||||||
|
void hasMaterialRootChanged();
|
||||||
|
void copiedMaterialTypeChanged();
|
||||||
|
void materialSectionsChanged();
|
||||||
void selectedIndexChanged(int idx);
|
void selectedIndexChanged(int idx);
|
||||||
void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName);
|
void renameMaterialTriggered(const QmlDesigner::ModelNode &material, const QString &newName);
|
||||||
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
|
void applyToSelectedTriggered(const QmlDesigner::ModelNode &material, bool add = false);
|
||||||
void addNewMaterialTriggered();
|
void addNewMaterialTriggered();
|
||||||
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
|
void duplicateMaterialTriggered(const QmlDesigner::ModelNode &material);
|
||||||
|
void pasteMaterialPropertiesTriggered(const QmlDesigner::ModelNode &material,
|
||||||
|
const QList<QmlDesigner::AbstractProperty> &props,
|
||||||
|
bool all);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isMaterialVisible(int idx) const;
|
bool isMaterialVisible(int idx) const;
|
||||||
@@ -92,12 +115,20 @@ private:
|
|||||||
|
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
QList<ModelNode> m_materialList;
|
QList<ModelNode> m_materialList;
|
||||||
|
QStringList m_defaultMaterialSections;
|
||||||
|
QStringList m_principledMaterialSections;
|
||||||
|
QStringList m_customMaterialSections;
|
||||||
|
QList<AbstractProperty> m_copiedMaterialProps;
|
||||||
QHash<qint32, int> m_materialIndexHash; // internalId -> index
|
QHash<qint32, int> m_materialIndexHash; // internalId -> index
|
||||||
|
QJsonObject m_propertyGroupsObj;
|
||||||
|
|
||||||
int m_selectedIndex = 0;
|
int m_selectedIndex = 0;
|
||||||
bool m_isEmpty = true;
|
bool m_isEmpty = true;
|
||||||
bool m_hasQuick3DImport = false;
|
bool m_hasQuick3DImport = false;
|
||||||
bool m_hasModelSelection = false;
|
bool m_hasModelSelection = false;
|
||||||
|
bool m_hasMaterialRoot = false;
|
||||||
|
bool m_allPropsCopied = true;
|
||||||
|
QString m_copiedMaterialType;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -24,12 +24,17 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "materialbrowserview.h"
|
#include "materialbrowserview.h"
|
||||||
|
|
||||||
|
#include "bindingproperty.h"
|
||||||
#include "materialbrowserwidget.h"
|
#include "materialbrowserwidget.h"
|
||||||
#include "materialbrowsermodel.h"
|
#include "materialbrowsermodel.h"
|
||||||
#include "nodeabstractproperty.h"
|
#include "nodeabstractproperty.h"
|
||||||
|
#include "nodemetainfo.h"
|
||||||
#include "qmlobjectnode.h"
|
#include "qmlobjectnode.h"
|
||||||
#include "variantproperty.h"
|
#include "variantproperty.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <designmodecontext.h>
|
||||||
#include <nodeinstanceview.h>
|
#include <nodeinstanceview.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
|
|
||||||
@@ -39,7 +44,6 @@ namespace QmlDesigner {
|
|||||||
|
|
||||||
MaterialBrowserView::MaterialBrowserView(QObject *parent)
|
MaterialBrowserView::MaterialBrowserView(QObject *parent)
|
||||||
: AbstractView(parent)
|
: AbstractView(parent)
|
||||||
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
MaterialBrowserView::~MaterialBrowserView()
|
MaterialBrowserView::~MaterialBrowserView()
|
||||||
@@ -53,7 +57,11 @@ bool MaterialBrowserView::hasWidget() const
|
|||||||
WidgetInfo MaterialBrowserView::widgetInfo()
|
WidgetInfo MaterialBrowserView::widgetInfo()
|
||||||
{
|
{
|
||||||
if (m_widget.isNull()) {
|
if (m_widget.isNull()) {
|
||||||
m_widget = new MaterialBrowserWidget;
|
m_widget = new MaterialBrowserWidget(this);
|
||||||
|
|
||||||
|
auto matEditorContext = new Internal::MaterialBrowserContext(m_widget.data());
|
||||||
|
Core::ICore::addContextObject(matEditorContext);
|
||||||
|
|
||||||
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
|
MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data();
|
||||||
|
|
||||||
// custom notifications below are sent to the MaterialEditor
|
// custom notifications below are sent to the MaterialEditor
|
||||||
@@ -81,6 +89,32 @@ WidgetInfo MaterialBrowserView::widgetInfo()
|
|||||||
[&] (const ModelNode &material) {
|
[&] (const ModelNode &material) {
|
||||||
emitCustomNotification("duplicate_material", {material});
|
emitCustomNotification("duplicate_material", {material});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(matBrowserModel, &MaterialBrowserModel::pasteMaterialPropertiesTriggered, this,
|
||||||
|
[&] (const ModelNode &material, const QList<AbstractProperty> &props, bool all) {
|
||||||
|
QmlObjectNode mat(material);
|
||||||
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
|
if (all) { // all material properties copied
|
||||||
|
// remove current properties
|
||||||
|
const PropertyNameList propNames = material.propertyNames();
|
||||||
|
for (const PropertyName &propName : propNames) {
|
||||||
|
if (propName != "objectName")
|
||||||
|
mat.removeProperty(propName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply pasted properties
|
||||||
|
for (const AbstractProperty &prop : props) {
|
||||||
|
if (prop.name() == "objectName")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (prop.isVariantProperty())
|
||||||
|
mat.setVariantProperty(prop.name(), prop.toVariantProperty().value());
|
||||||
|
else if (prop.isBindingProperty())
|
||||||
|
mat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return createWidgetInfo(m_widget.data(),
|
return createWidgetInfo(m_widget.data(),
|
||||||
@@ -94,7 +128,12 @@ void MaterialBrowserView::modelAttached(Model *model)
|
|||||||
{
|
{
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
|
|
||||||
|
QString matPropsPath = model->metaInfo("QtQuick3D.Material").importDirectoryPath()
|
||||||
|
+ "/designer/propertyGroups.json";
|
||||||
|
m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
|
||||||
|
|
||||||
m_widget->clearSearchFilter();
|
m_widget->clearSearchFilter();
|
||||||
|
m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material"));
|
||||||
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
||||||
|
|
||||||
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
|
// Project load is already very busy and may even trigger puppet reset, so let's wait a moment
|
||||||
@@ -130,7 +169,7 @@ void MaterialBrowserView::refreshModel(bool updateImages)
|
|||||||
|
|
||||||
bool MaterialBrowserView::isMaterial(const ModelNode &node) const
|
bool MaterialBrowserView::isMaterial(const ModelNode &node) const
|
||||||
{
|
{
|
||||||
if (!node.isValid() || node.isComponent())
|
if (!node.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return node.isSubclassOf("QtQuick3D.Material");
|
return node.isSubclassOf("QtQuick3D.Material");
|
||||||
@@ -273,6 +312,12 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
|
|||||||
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);
|
||||||
|
});
|
||||||
|
} else if (identifier == "delete_selected_material") {
|
||||||
|
m_widget->materialBrowserModel()->deleteSelectedMaterial();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "materialbrowserwidget.h"
|
#include "materialbrowserwidget.h"
|
||||||
#include "materialbrowsermodel.h"
|
#include "materialbrowsermodel.h"
|
||||||
|
#include "materialbrowserview.h"
|
||||||
|
|
||||||
#include <theme.h>
|
#include <theme.h>
|
||||||
|
|
||||||
@@ -130,14 +131,20 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialBrowserWidget::MaterialBrowserWidget()
|
MaterialBrowserWidget::MaterialBrowserWidget(MaterialBrowserView *view)
|
||||||
: m_materialBrowserModel(new MaterialBrowserModel(this))
|
: m_materialBrowserView(view)
|
||||||
|
, m_materialBrowserModel(new MaterialBrowserModel(this))
|
||||||
, m_quickWidget(new QQuickWidget(this))
|
, m_quickWidget(new QQuickWidget(this))
|
||||||
, m_previewImageProvider(new PreviewImageProvider())
|
, m_previewImageProvider(new PreviewImageProvider())
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Material Browser", "Title of material browser widget"));
|
setWindowTitle(tr("Material Browser", "Title of material browser widget"));
|
||||||
setMinimumWidth(120);
|
setMinimumWidth(120);
|
||||||
|
|
||||||
|
Core::Context context(Constants::C_QMLMATERIALBROWSER);
|
||||||
|
m_context = new Core::IContext(this);
|
||||||
|
m_context->setContext(context);
|
||||||
|
m_context->setWidget(this);
|
||||||
|
|
||||||
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
m_quickWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||||
m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground));
|
m_quickWidget->setClearColor(Theme::getColor(Theme::Color::DSpanelBackground));
|
||||||
@@ -182,6 +189,14 @@ QList<QToolButton *> MaterialBrowserWidget::createToolBarWidgets()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
|
||||||
|
{
|
||||||
|
if (m_materialBrowserView)
|
||||||
|
m_materialBrowserView->contextHelp(callback);
|
||||||
|
else
|
||||||
|
callback({});
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialBrowserWidget::handleSearchfilterChanged(const QString &filterText)
|
void MaterialBrowserWidget::handleSearchfilterChanged(const QString &filterText)
|
||||||
{
|
{
|
||||||
if (filterText != m_filterText) {
|
if (filterText != m_filterText) {
|
||||||
|
@@ -25,20 +25,19 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "itemlibraryinfo.h"
|
|
||||||
#include "import.h"
|
|
||||||
#include "modelnode.h"
|
#include "modelnode.h"
|
||||||
|
|
||||||
#include <utils/fancylineedit.h>
|
#include <coreplugin/icontext.h>
|
||||||
#include <utils/dropsupport.h>
|
#include <utils/dropsupport.h>
|
||||||
|
#include <utils/fancylineedit.h>
|
||||||
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QToolButton>
|
|
||||||
#include <QFileIconProvider>
|
#include <QFileIconProvider>
|
||||||
#include <QQuickWidget>
|
#include <QFrame>
|
||||||
#include <QQmlPropertyMap>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
|
#include <QQmlPropertyMap>
|
||||||
|
#include <QQuickWidget>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -49,6 +48,7 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class MaterialBrowserView;
|
||||||
class MaterialBrowserModel;
|
class MaterialBrowserModel;
|
||||||
class PreviewImageProvider;
|
class PreviewImageProvider;
|
||||||
|
|
||||||
@@ -57,10 +57,11 @@ class MaterialBrowserWidget : public QFrame
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialBrowserWidget();
|
MaterialBrowserWidget(MaterialBrowserView *view);
|
||||||
~MaterialBrowserWidget() = default;
|
~MaterialBrowserWidget() = default;
|
||||||
|
|
||||||
QList<QToolButton *> createToolBarWidgets();
|
QList<QToolButton *> createToolBarWidgets();
|
||||||
|
void contextHelp(const Core::IContext::HelpCallback &callback) const;
|
||||||
|
|
||||||
static QString qmlSourcesPath();
|
static QString qmlSourcesPath();
|
||||||
void clearSearchFilter();
|
void clearSearchFilter();
|
||||||
@@ -80,11 +81,13 @@ private:
|
|||||||
void reloadQmlSource();
|
void reloadQmlSource();
|
||||||
void updateSearch();
|
void updateSearch();
|
||||||
|
|
||||||
|
QPointer<MaterialBrowserView> m_materialBrowserView;
|
||||||
QPointer<MaterialBrowserModel> m_materialBrowserModel;
|
QPointer<MaterialBrowserModel> m_materialBrowserModel;
|
||||||
QScopedPointer<QQuickWidget> m_quickWidget;
|
QScopedPointer<QQuickWidget> m_quickWidget;
|
||||||
|
|
||||||
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
|
QShortcut *m_qmlSourceUpdateShortcut = nullptr;
|
||||||
PreviewImageProvider *m_previewImageProvider = nullptr;
|
PreviewImageProvider *m_previewImageProvider = nullptr;
|
||||||
|
Core::IContext *m_context = nullptr;
|
||||||
|
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <qmlmodelnodeproxy.h>
|
#include <qmlmodelnodeproxy.h>
|
||||||
#include <qmlobjectnode.h>
|
#include <qmlobjectnode.h>
|
||||||
#include <qmltimeline.h>
|
#include <qmltimeline.h>
|
||||||
|
#include <documentmanager.h>
|
||||||
|
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -47,12 +48,24 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
MaterialEditorContextObject::MaterialEditorContextObject(QObject *parent)
|
MaterialEditorContextObject::MaterialEditorContextObject(QQmlContext *context, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, m_qmlContext(context)
|
||||||
{
|
{
|
||||||
qmlRegisterUncreatableType<MaterialEditorContextObject>("ToolBarAction", 1, 0, "ToolBarAction", "Enum type");
|
qmlRegisterUncreatableType<MaterialEditorContextObject>("ToolBarAction", 1, 0, "ToolBarAction", "Enum type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QQmlComponent *MaterialEditorContextObject::specificQmlComponent()
|
||||||
|
{
|
||||||
|
if (m_specificQmlComponent)
|
||||||
|
return m_specificQmlComponent;
|
||||||
|
|
||||||
|
m_specificQmlComponent = new QQmlComponent(m_qmlContext->engine(), this);
|
||||||
|
m_specificQmlComponent->setData(m_specificQmlData.toUtf8(), QUrl::fromLocalFile("specifics.qml"));
|
||||||
|
|
||||||
|
return m_specificQmlComponent;
|
||||||
|
}
|
||||||
|
|
||||||
QString MaterialEditorContextObject::convertColorToString(const QVariant &color)
|
QString MaterialEditorContextObject::convertColorToString(const QVariant &color)
|
||||||
{
|
{
|
||||||
QString colorString;
|
QString colorString;
|
||||||
@@ -159,8 +172,10 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName)
|
|||||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||||
|
|
||||||
if (msgBox.exec() == QMessageBox::Cancel)
|
if (msgBox.exec() == QMessageBox::Cancel) {
|
||||||
|
updatePossibleTypeIndex();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &p : std::as_const(incompatibleProperties))
|
for (const auto &p : std::as_const(incompatibleProperties))
|
||||||
m_selectedMaterial.removeProperty(p);
|
m_selectedMaterial.removeProperty(p);
|
||||||
@@ -234,6 +249,20 @@ void MaterialEditorContextObject::setHasQuick3DImport(bool b)
|
|||||||
emit hasQuick3DImportChanged();
|
emit hasQuick3DImportChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MaterialEditorContextObject::hasMaterialRoot() const
|
||||||
|
{
|
||||||
|
return m_hasMaterialRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::setHasMaterialRoot(bool b)
|
||||||
|
{
|
||||||
|
if (b == m_hasMaterialRoot)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hasMaterialRoot = b;
|
||||||
|
emit hasMaterialRootChanged();
|
||||||
|
}
|
||||||
|
|
||||||
bool MaterialEditorContextObject::hasModelSelection() const
|
bool MaterialEditorContextObject::hasModelSelection() const
|
||||||
{
|
{
|
||||||
return m_hasModelSelection;
|
return m_hasModelSelection;
|
||||||
@@ -262,6 +291,20 @@ void MaterialEditorContextObject::setSpecificsUrl(const QUrl &newSpecificsUrl)
|
|||||||
emit specificsUrlChanged();
|
emit specificsUrlChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::setSpecificQmlData(const QString &newSpecificQmlData)
|
||||||
|
{
|
||||||
|
if (newSpecificQmlData == m_specificQmlData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_specificQmlData = newSpecificQmlData;
|
||||||
|
|
||||||
|
delete m_specificQmlComponent;
|
||||||
|
m_specificQmlComponent = nullptr;
|
||||||
|
|
||||||
|
emit specificQmlComponentChanged();
|
||||||
|
emit specificQmlDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorContextObject::setStateName(const QString &newStateName)
|
void MaterialEditorContextObject::setStateName(const QString &newStateName)
|
||||||
{
|
{
|
||||||
if (newStateName == m_stateName)
|
if (newStateName == m_stateName)
|
||||||
@@ -280,6 +323,23 @@ void MaterialEditorContextObject::setAllStateNames(const QStringList &allStates)
|
|||||||
emit allStateNamesChanged();
|
emit allStateNamesChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::setPossibleTypes(const QStringList &types)
|
||||||
|
{
|
||||||
|
if (types == m_possibleTypes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_possibleTypes = types;
|
||||||
|
emit possibleTypesChanged();
|
||||||
|
|
||||||
|
updatePossibleTypeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::setCurrentType(const QString &type)
|
||||||
|
{
|
||||||
|
m_currentType = type.split('.').last();
|
||||||
|
updatePossibleTypeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorContextObject::setIsBaseState(bool newIsBaseState)
|
void MaterialEditorContextObject::setIsBaseState(bool newIsBaseState)
|
||||||
{
|
{
|
||||||
if (newIsBaseState == m_isBaseState)
|
if (newIsBaseState == m_isBaseState)
|
||||||
@@ -326,6 +386,20 @@ void MaterialEditorContextObject::setHasAliasExport(bool hasAliasExport)
|
|||||||
emit hasAliasExportChanged();
|
emit hasAliasExportChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::updatePossibleTypeIndex()
|
||||||
|
{
|
||||||
|
int newIndex = -1;
|
||||||
|
if (!m_currentType.isEmpty())
|
||||||
|
newIndex = m_possibleTypes.indexOf(m_currentType);
|
||||||
|
|
||||||
|
// Emit valid possible type index change even if the index doesn't change, as currentIndex on
|
||||||
|
// QML side will change to default internally if model is updated
|
||||||
|
if (m_possibleTypeIndex != -1 || m_possibleTypeIndex != newIndex) {
|
||||||
|
m_possibleTypeIndex = newIndex;
|
||||||
|
emit possibleTypeIndexChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorContextObject::hideCursor()
|
void MaterialEditorContextObject::hideCursor()
|
||||||
{
|
{
|
||||||
if (QApplication::overrideCursor())
|
if (QApplication::overrideCursor())
|
||||||
@@ -390,4 +464,10 @@ bool MaterialEditorContextObject::isBlocked(const QString &propName) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorContextObject::goIntoComponent()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_model, return);
|
||||||
|
DocumentManager::goIntoComponent(m_selectedMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
} // QmlDesigner
|
} // QmlDesigner
|
||||||
|
@@ -43,9 +43,13 @@ class MaterialEditorContextObject : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QUrl specificsUrl READ specificsUrl WRITE setSpecificsUrl NOTIFY specificsUrlChanged)
|
Q_PROPERTY(QUrl specificsUrl READ specificsUrl WRITE setSpecificsUrl NOTIFY specificsUrlChanged)
|
||||||
|
Q_PROPERTY(QString specificQmlData READ specificQmlData WRITE setSpecificQmlData NOTIFY specificQmlDataChanged)
|
||||||
|
Q_PROPERTY(QQmlComponent *specificQmlComponent READ specificQmlComponent NOTIFY specificQmlComponentChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString stateName READ stateName WRITE setStateName NOTIFY stateNameChanged)
|
Q_PROPERTY(QString stateName READ stateName WRITE setStateName NOTIFY stateNameChanged)
|
||||||
Q_PROPERTY(QStringList allStateNames READ allStateNames WRITE setAllStateNames NOTIFY allStateNamesChanged)
|
Q_PROPERTY(QStringList allStateNames READ allStateNames WRITE setAllStateNames NOTIFY allStateNamesChanged)
|
||||||
|
Q_PROPERTY(QStringList possibleTypes READ possibleTypes WRITE setPossibleTypes NOTIFY possibleTypesChanged)
|
||||||
|
Q_PROPERTY(int possibleTypeIndex READ possibleTypeIndex NOTIFY possibleTypeIndexChanged)
|
||||||
|
|
||||||
Q_PROPERTY(bool isBaseState READ isBaseState WRITE setIsBaseState NOTIFY isBaseStateChanged)
|
Q_PROPERTY(bool isBaseState READ isBaseState WRITE setIsBaseState NOTIFY isBaseStateChanged)
|
||||||
Q_PROPERTY(bool selectionChanged READ selectionChanged WRITE setSelectionChanged NOTIFY selectionChangedChanged)
|
Q_PROPERTY(bool selectionChanged READ selectionChanged WRITE setSelectionChanged NOTIFY selectionChangedChanged)
|
||||||
@@ -56,15 +60,20 @@ class MaterialEditorContextObject : public QObject
|
|||||||
Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged)
|
Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged)
|
||||||
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
||||||
Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
|
Q_PROPERTY(bool hasModelSelection READ hasModelSelection WRITE setHasModelSelection NOTIFY hasModelSelectionChanged)
|
||||||
|
Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
|
Q_PROPERTY(QQmlPropertyMap *backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialEditorContextObject(QObject *parent = nullptr);
|
MaterialEditorContextObject(QQmlContext *context, QObject *parent = nullptr);
|
||||||
|
|
||||||
QUrl specificsUrl() const { return m_specificsUrl; }
|
QUrl specificsUrl() const { return m_specificsUrl; }
|
||||||
|
QString specificQmlData() const {return m_specificQmlData; }
|
||||||
|
QQmlComponent *specificQmlComponent();
|
||||||
QString stateName() const { return m_stateName; }
|
QString stateName() const { return m_stateName; }
|
||||||
QStringList allStateNames() const { return m_allStateNames; }
|
QStringList allStateNames() const { return m_allStateNames; }
|
||||||
|
QStringList possibleTypes() const { return m_possibleTypes; }
|
||||||
|
int possibleTypeIndex() const { return m_possibleTypeIndex; }
|
||||||
|
|
||||||
bool isBaseState() const { return m_isBaseState; }
|
bool isBaseState() const { return m_isBaseState; }
|
||||||
bool selectionChanged() const { return m_selectionChanged; }
|
bool selectionChanged() const { return m_selectionChanged; }
|
||||||
@@ -86,6 +95,7 @@ public:
|
|||||||
Q_INVOKABLE QStringList allStatesForId(const QString &id);
|
Q_INVOKABLE QStringList allStatesForId(const QString &id);
|
||||||
|
|
||||||
Q_INVOKABLE bool isBlocked(const QString &propName) const;
|
Q_INVOKABLE bool isBlocked(const QString &propName) const;
|
||||||
|
Q_INVOKABLE void goIntoComponent();
|
||||||
|
|
||||||
enum ToolBarAction {
|
enum ToolBarAction {
|
||||||
ApplyToSelected = 0,
|
ApplyToSelected = 0,
|
||||||
@@ -105,6 +115,9 @@ public:
|
|||||||
bool hasQuick3DImport() const;
|
bool hasQuick3DImport() const;
|
||||||
void setHasQuick3DImport(bool b);
|
void setHasQuick3DImport(bool b);
|
||||||
|
|
||||||
|
bool hasMaterialRoot() const;
|
||||||
|
void setHasMaterialRoot(bool b);
|
||||||
|
|
||||||
bool hasModelSelection() const;
|
bool hasModelSelection() const;
|
||||||
void setHasModelSelection(bool b);
|
void setHasModelSelection(bool b);
|
||||||
|
|
||||||
@@ -113,8 +126,11 @@ public:
|
|||||||
void setSelectedMaterial(const ModelNode &matNode);
|
void setSelectedMaterial(const ModelNode &matNode);
|
||||||
|
|
||||||
void setSpecificsUrl(const QUrl &newSpecificsUrl);
|
void setSpecificsUrl(const QUrl &newSpecificsUrl);
|
||||||
|
void setSpecificQmlData(const QString &newSpecificQmlData);
|
||||||
void setStateName(const QString &newStateName);
|
void setStateName(const QString &newStateName);
|
||||||
void setAllStateNames(const QStringList &allStates);
|
void setAllStateNames(const QStringList &allStates);
|
||||||
|
void setPossibleTypes(const QStringList &types);
|
||||||
|
void setCurrentType(const QString &type);
|
||||||
void setIsBaseState(bool newIsBaseState);
|
void setIsBaseState(bool newIsBaseState);
|
||||||
void setSelectionChanged(bool newSelectionChanged);
|
void setSelectionChanged(bool newSelectionChanged);
|
||||||
void setBackendValues(QQmlPropertyMap *newBackendValues);
|
void setBackendValues(QQmlPropertyMap *newBackendValues);
|
||||||
@@ -125,8 +141,12 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void specificsUrlChanged();
|
void specificsUrlChanged();
|
||||||
|
void specificQmlDataChanged();
|
||||||
|
void specificQmlComponentChanged();
|
||||||
void stateNameChanged();
|
void stateNameChanged();
|
||||||
void allStateNamesChanged();
|
void allStateNamesChanged();
|
||||||
|
void possibleTypesChanged();
|
||||||
|
void possibleTypeIndexChanged();
|
||||||
void isBaseStateChanged();
|
void isBaseStateChanged();
|
||||||
void selectionChangedChanged();
|
void selectionChangedChanged();
|
||||||
void backendValuesChanged();
|
void backendValuesChanged();
|
||||||
@@ -134,18 +154,26 @@ signals:
|
|||||||
void hasAliasExportChanged();
|
void hasAliasExportChanged();
|
||||||
void hasActiveTimelineChanged();
|
void hasActiveTimelineChanged();
|
||||||
void hasQuick3DImportChanged();
|
void hasQuick3DImportChanged();
|
||||||
|
void hasMaterialRootChanged();
|
||||||
void hasModelSelectionChanged();
|
void hasModelSelectionChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updatePossibleTypeIndex();
|
||||||
|
|
||||||
QUrl m_specificsUrl;
|
QUrl m_specificsUrl;
|
||||||
|
QString m_specificQmlData;
|
||||||
|
QQmlComponent *m_specificQmlComponent = nullptr;
|
||||||
|
QQmlContext *m_qmlContext = nullptr;
|
||||||
|
|
||||||
QString m_stateName;
|
QString m_stateName;
|
||||||
QStringList m_allStateNames;
|
QStringList m_allStateNames;
|
||||||
|
QStringList m_possibleTypes;
|
||||||
|
int m_possibleTypeIndex = -1;
|
||||||
|
QString m_currentType;
|
||||||
|
|
||||||
int m_majorVersion = 1;
|
int m_majorVersion = 1;
|
||||||
|
|
||||||
QQmlPropertyMap *m_backendValues = nullptr;
|
QQmlPropertyMap *m_backendValues = nullptr;
|
||||||
QQmlComponent *m_qmlComponent = nullptr;
|
|
||||||
Model *m_model = nullptr;
|
Model *m_model = nullptr;
|
||||||
|
|
||||||
QPoint m_lastPos;
|
QPoint m_lastPos;
|
||||||
@@ -155,6 +183,7 @@ private:
|
|||||||
bool m_aliasExport = false;
|
bool m_aliasExport = false;
|
||||||
bool m_hasActiveTimeline = false;
|
bool m_hasActiveTimeline = false;
|
||||||
bool m_hasQuick3DImport = false;
|
bool m_hasQuick3DImport = false;
|
||||||
|
bool m_hasMaterialRoot = false;
|
||||||
bool m_hasModelSelection = false;
|
bool m_hasModelSelection = false;
|
||||||
|
|
||||||
ModelNode m_selectedMaterial;
|
ModelNode m_selectedMaterial;
|
||||||
|
@@ -102,7 +102,7 @@ public:
|
|||||||
MaterialEditorQmlBackend::MaterialEditorQmlBackend(MaterialEditorView *materialEditor)
|
MaterialEditorQmlBackend::MaterialEditorQmlBackend(MaterialEditorView *materialEditor)
|
||||||
: m_view(new QQuickWidget)
|
: m_view(new QQuickWidget)
|
||||||
, m_materialEditorTransaction(new MaterialEditorTransaction(materialEditor))
|
, m_materialEditorTransaction(new MaterialEditorTransaction(materialEditor))
|
||||||
, m_contextObject(new MaterialEditorContextObject())
|
, m_contextObject(new MaterialEditorContextObject(m_view->rootContext()))
|
||||||
, m_materialEditorImageProvider(new MaterialEditorImageProvider())
|
, m_materialEditorImageProvider(new MaterialEditorImageProvider())
|
||||||
{
|
{
|
||||||
m_view->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
m_view->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
@@ -51,6 +51,7 @@
|
|||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <propertyeditorqmlbackend.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -62,6 +63,7 @@
|
|||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QColorDialog>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -82,6 +84,10 @@ MaterialEditorView::MaterialEditorView(QWidget *parent)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_typeUpdateTimer.setSingleShot(true);
|
||||||
|
m_typeUpdateTimer.setInterval(500);
|
||||||
|
connect(&m_typeUpdateTimer, &QTimer::timeout, this, &MaterialEditorView::updatePossibleTypes);
|
||||||
|
|
||||||
m_stackedWidget->setStyleSheet(Theme::replaceCssColors(
|
m_stackedWidget->setStyleSheet(Theme::replaceCssColors(
|
||||||
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||||
m_stackedWidget->setMinimumWidth(250);
|
m_stackedWidget->setMinimumWidth(250);
|
||||||
@@ -420,12 +426,15 @@ void MaterialEditorView::handleToolBarAction(int action)
|
|||||||
if (!model())
|
if (!model())
|
||||||
break;
|
break;
|
||||||
executeInTransaction("MaterialEditorView:handleToolBarAction", [&] {
|
executeInTransaction("MaterialEditorView:handleToolBarAction", [&] {
|
||||||
|
ModelNode matLib = materialLibraryNode();
|
||||||
|
if (!matLib.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.DefaultMaterial");
|
NodeMetaInfo metaInfo = model()->metaInfo("QtQuick3D.DefaultMaterial");
|
||||||
ModelNode newMatNode = createModelNode("QtQuick3D.DefaultMaterial", metaInfo.majorVersion(),
|
ModelNode newMatNode = createModelNode("QtQuick3D.DefaultMaterial", metaInfo.majorVersion(),
|
||||||
metaInfo.minorVersion());
|
metaInfo.minorVersion());
|
||||||
renameMaterial(newMatNode, "New Material");
|
renameMaterial(newMatNode, "New Material");
|
||||||
|
matLib.defaultNodeListProperty().reparentHere(newMatNode);
|
||||||
materialLibraryNode().defaultNodeListProperty().reparentHere(newMatNode);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -443,18 +452,110 @@ void MaterialEditorView::handleToolBarAction(int action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::handlePreviewEnvChanged(const QString &envAndValue)
|
||||||
|
{
|
||||||
|
// if (envAndValue.isEmpty() || m_initializingPreviewData)
|
||||||
|
// 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) {
|
||||||
|
// rootModelNode().setAuxiliaryData(matPrevEnvAuxProp, auxEnv);
|
||||||
|
// rootModelNode().setAuxiliaryData(matPrevEnvValueAuxProp, auxValue);
|
||||||
|
// QTimer::singleShot(0, this, &MaterialEditorView::requestPreviewRender);
|
||||||
|
// emitCustomNotification("refresh_material_browser", {});
|
||||||
|
// };
|
||||||
|
|
||||||
|
// if (env == "Color") {
|
||||||
|
// m_colorDialog.clear();
|
||||||
|
|
||||||
|
// // Store color to separate property to persist selection over non-color env changes
|
||||||
|
// PropertyName colorAuxProp("matPrevColor");
|
||||||
|
// QString oldColor = rootModelNode().auxiliaryData(colorAuxProp).toString();
|
||||||
|
// QString oldEnv = rootModelNode().auxiliaryData(matPrevEnvAuxProp).toString();
|
||||||
|
// QString oldValue = rootModelNode().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());
|
||||||
|
// rootModelNode().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() || m_initializingPreviewData)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// QTC_ASSERT(m_hasQuick3DImport, return);
|
||||||
|
// QTC_ASSERT(model(), return);
|
||||||
|
// QTC_ASSERT(model()->nodeInstanceView(), return);
|
||||||
|
|
||||||
|
// rootModelNode().setAuxiliaryData("matPrevModel", modelStr);
|
||||||
|
|
||||||
|
// QTimer::singleShot(0, this, &MaterialEditorView::requestPreviewRender);
|
||||||
|
// emitCustomNotification("refresh_material_browser", {});
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorView::setupQmlBackend()
|
void MaterialEditorView::setupQmlBackend()
|
||||||
{
|
{
|
||||||
QUrl qmlPaneUrl;
|
QUrl qmlPaneUrl;
|
||||||
QUrl qmlSpecificsUrl;
|
QUrl qmlSpecificsUrl;
|
||||||
|
QString specificQmlData;
|
||||||
|
QString currentTypeName;
|
||||||
|
|
||||||
if (m_selectedMaterial.isValid() && m_hasQuick3DImport) {
|
if (m_selectedMaterial.isValid() && m_hasQuick3DImport) {
|
||||||
qmlPaneUrl = QUrl::fromLocalFile(materialEditorResourcesPath() + "/MaterialEditorPane.qml");
|
qmlPaneUrl = QUrl::fromLocalFile(materialEditorResourcesPath() + "/MaterialEditorPane.qml");
|
||||||
|
|
||||||
|
TypeName diffClassName;
|
||||||
NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo();
|
NodeMetaInfo metaInfo = m_selectedMaterial.metaInfo();
|
||||||
QDir importDir(metaInfo.importDirectoryPath() + Constants::QML_DESIGNER_SUBFOLDER);
|
if (metaInfo.isValid()) {
|
||||||
QString typeName = QString::fromUtf8(metaInfo.typeName().split('.').constLast());
|
diffClassName = metaInfo.typeName();
|
||||||
qmlSpecificsUrl = QUrl::fromLocalFile(importDir.absoluteFilePath(typeName + "Specifics.qml"));
|
const QList<NodeMetaInfo> hierarchy = metaInfo.classHierarchy();
|
||||||
|
for (const NodeMetaInfo &metaInfo : hierarchy) {
|
||||||
|
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsUrl))
|
||||||
|
break;
|
||||||
|
qmlSpecificsUrl = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName()
|
||||||
|
+ "Specifics", metaInfo);
|
||||||
|
diffClassName = metaInfo.typeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (metaInfo.isValid() && diffClassName != m_selectedMaterial.type()) {
|
||||||
|
specificQmlData = PropertyEditorQmlBackend::templateGeneration(
|
||||||
|
metaInfo, model()->metaInfo(diffClassName), m_selectedMaterial);
|
||||||
|
}
|
||||||
|
currentTypeName = QString::fromLatin1(m_selectedMaterial.type());
|
||||||
} else {
|
} else {
|
||||||
qmlPaneUrl = QUrl::fromLocalFile(materialEditorResourcesPath() + "/EmptyMaterialEditorPane.qml");
|
qmlPaneUrl = QUrl::fromLocalFile(materialEditorResourcesPath() + "/EmptyMaterialEditorPane.qml");
|
||||||
}
|
}
|
||||||
@@ -473,17 +574,29 @@ 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);
|
||||||
|
currentQmlBackend->contextObject()->setHasMaterialRoot(m_hasMaterialRoot);
|
||||||
m_stackedWidget->setCurrentWidget(currentQmlBackend->widget());
|
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
|
||||||
|
currentQmlBackend->contextObject()->setCurrentType(currentTypeName);
|
||||||
|
|
||||||
m_qmlBackEnd = currentQmlBackend;
|
m_qmlBackEnd = currentQmlBackend;
|
||||||
|
|
||||||
|
delayedTypeUpdate();
|
||||||
|
initPreviewData();
|
||||||
|
|
||||||
|
m_stackedWidget->setCurrentWidget(m_qmlBackEnd->widget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
|
void MaterialEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
|
||||||
@@ -529,6 +642,75 @@ bool MaterialEditorView::noValidSelection() const
|
|||||||
return !QmlObjectNode::isValidQmlObjectNode(m_selectedMaterial);
|
return !QmlObjectNode::isValidQmlObjectNode(m_selectedMaterial);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::initPreviewData()
|
||||||
|
{
|
||||||
|
// if (model() && m_qmlBackEnd) {
|
||||||
|
// QString env = rootModelNode().auxiliaryData("matPrevEnv").toString();
|
||||||
|
// QString envValue = rootModelNode().auxiliaryData("matPrevEnvValue").toString();
|
||||||
|
// QString modelStr = rootModelNode().auxiliaryData("matPrevModel").toString();
|
||||||
|
// if (!envValue.isEmpty() && env != "Color" && env != "Default") {
|
||||||
|
// env += '=';
|
||||||
|
// env += envValue;
|
||||||
|
// }
|
||||||
|
// if (env.isEmpty())
|
||||||
|
// env = "Default";
|
||||||
|
// if (modelStr.isEmpty())
|
||||||
|
// modelStr = "#Sphere";
|
||||||
|
// m_initializingPreviewData = true;
|
||||||
|
// QMetaObject::invokeMethod(m_qmlBackEnd->widget()->rootObject(),
|
||||||
|
// "initPreviewData",
|
||||||
|
// Q_ARG(QVariant, env), Q_ARG(QVariant, modelStr));
|
||||||
|
// m_initializingPreviewData = false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::delayedTypeUpdate()
|
||||||
|
{
|
||||||
|
m_typeUpdateTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Import entryToImport(const ItemLibraryEntry &entry)
|
||||||
|
{
|
||||||
|
if (entry.majorVersion() == -1 && entry.minorVersion() == -1)
|
||||||
|
return Import::createFileImport(entry.requiredImport());
|
||||||
|
return Import::createLibraryImport(entry.requiredImport(),
|
||||||
|
QString::number(entry.majorVersion()) + QLatin1Char('.') +
|
||||||
|
QString::number(entry.minorVersion()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::updatePossibleTypes()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(model(), return);
|
||||||
|
|
||||||
|
if (!m_qmlBackEnd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ensure basic types are always first
|
||||||
|
static const QStringList basicTypes {"DefaultMaterial", "PrincipledMaterial", "CustomMaterial"};
|
||||||
|
QStringList allTypes = basicTypes;
|
||||||
|
|
||||||
|
const QList<ItemLibraryEntry> itemLibEntries = m_itemLibraryInfo->entries();
|
||||||
|
for (const ItemLibraryEntry &entry : itemLibEntries) {
|
||||||
|
NodeMetaInfo metaInfo = model()->metaInfo(entry.typeName());
|
||||||
|
bool valid = metaInfo.isValid()
|
||||||
|
&& (metaInfo.majorVersion() >= entry.majorVersion()
|
||||||
|
|| metaInfo.majorVersion() < 0);
|
||||||
|
if (valid && metaInfo.isSubclassOf("QtQuick3D.Material")) {
|
||||||
|
bool addImport = entry.requiredImport().isEmpty();
|
||||||
|
if (!addImport) {
|
||||||
|
Import import = entryToImport(entry);
|
||||||
|
addImport = model()->hasImport(import, true, true);
|
||||||
|
}
|
||||||
|
if (addImport) {
|
||||||
|
QString typeName = QString::fromLatin1(entry.typeName().split('.').last());
|
||||||
|
if (!allTypes.contains(typeName))
|
||||||
|
allTypes.append(typeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_qmlBackEnd->contextObject()->setPossibleTypes(allTypes);
|
||||||
|
}
|
||||||
|
|
||||||
void MaterialEditorView::modelAttached(Model *model)
|
void MaterialEditorView::modelAttached(Model *model)
|
||||||
{
|
{
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
@@ -536,11 +718,27 @@ void MaterialEditorView::modelAttached(Model *model)
|
|||||||
m_locked = true;
|
m_locked = true;
|
||||||
|
|
||||||
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
m_hasQuick3DImport = model->hasImport("QtQuick3D");
|
||||||
|
m_hasMaterialRoot = rootModelNode().isSubclassOf("QtQuick3D.Material");
|
||||||
|
|
||||||
// Creating the material library node on model attach causes errors as long as the type information
|
if (m_hasMaterialRoot) {
|
||||||
// not complete yet, so we keep checking until type info is complete.
|
m_selectedMaterial = rootModelNode();
|
||||||
if (m_hasQuick3DImport)
|
} else if (m_hasQuick3DImport) {
|
||||||
|
// Creating the material library node on model attach causes errors as long as the type
|
||||||
|
// information is not complete yet, so we keep checking until type info is complete.
|
||||||
m_ensureMatLibTimer.start(500);
|
m_ensureMatLibTimer.start(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_itemLibraryInfo.data() != model->metaInfo().itemLibraryInfo()) {
|
||||||
|
if (m_itemLibraryInfo) {
|
||||||
|
disconnect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
||||||
|
this, &MaterialEditorView::delayedTypeUpdate);
|
||||||
|
}
|
||||||
|
m_itemLibraryInfo = model->metaInfo().itemLibraryInfo();
|
||||||
|
if (m_itemLibraryInfo) {
|
||||||
|
connect(m_itemLibraryInfo.data(), &ItemLibraryInfo::entriesChanged,
|
||||||
|
this, &MaterialEditorView::delayedTypeUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_setupCompleted) {
|
if (!m_setupCompleted) {
|
||||||
reloadQml();
|
reloadQml();
|
||||||
@@ -705,10 +903,20 @@ void MaterialEditorView::instancePropertyChanged(const QList<QPair<ModelNode, Pr
|
|||||||
m_locked = false;
|
m_locked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::nodeTypeChanged(const ModelNode &node, const TypeName &, int, int)
|
void MaterialEditorView::nodeTypeChanged(const ModelNode &node, const TypeName &typeName, int, int)
|
||||||
{
|
{
|
||||||
if (node == m_selectedMaterial)
|
if (node == m_selectedMaterial) {
|
||||||
|
m_qmlBackEnd->contextObject()->setCurrentType(QString::fromLatin1(typeName));
|
||||||
delayedResetView();
|
delayedResetView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialEditorView::rootNodeTypeChanged(const QString &type, int, int)
|
||||||
|
{
|
||||||
|
if (rootModelNode() == m_selectedMaterial) {
|
||||||
|
m_qmlBackEnd->contextObject()->setCurrentType(type);
|
||||||
|
delayedResetView();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap)
|
void MaterialEditorView::modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap)
|
||||||
@@ -752,6 +960,10 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material)
|
|||||||
QmlObjectNode sourceMat(material);
|
QmlObjectNode sourceMat(material);
|
||||||
|
|
||||||
executeInTransaction(__FUNCTION__, [&] {
|
executeInTransaction(__FUNCTION__, [&] {
|
||||||
|
ModelNode matLib = materialLibraryNode();
|
||||||
|
if (!matLib.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
// create the duplicate material
|
// create the duplicate material
|
||||||
NodeMetaInfo metaInfo = model()->metaInfo(matType);
|
NodeMetaInfo metaInfo = model()->metaInfo(matType);
|
||||||
QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion());
|
QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion());
|
||||||
@@ -773,7 +985,7 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material)
|
|||||||
duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
|
duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
|
||||||
}
|
}
|
||||||
|
|
||||||
materialLibraryNode().defaultNodeListProperty().reparentHere(duplicateMat);
|
matLib.defaultNodeListProperty().reparentHere(duplicateMat);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,8 +995,10 @@ void MaterialEditorView::customNotification([[maybe_unused]] const AbstractView
|
|||||||
const QList<QVariant> &data)
|
const QList<QVariant> &data)
|
||||||
{
|
{
|
||||||
if (identifier == "selected_material_changed") {
|
if (identifier == "selected_material_changed") {
|
||||||
m_selectedMaterial = nodeList.first();
|
if (!m_hasMaterialRoot) {
|
||||||
QTimer::singleShot(0, this, &MaterialEditorView::resetView);
|
m_selectedMaterial = nodeList.first();
|
||||||
|
QTimer::singleShot(0, this, &MaterialEditorView::resetView);
|
||||||
|
}
|
||||||
} else if (identifier == "apply_to_selected_triggered") {
|
} else if (identifier == "apply_to_selected_triggered") {
|
||||||
applyMaterialToSelectedModels(nodeList.first(), data.first().toBool());
|
applyMaterialToSelectedModels(nodeList.first(), data.first().toBool());
|
||||||
} else if (identifier == "rename_material") {
|
} else if (identifier == "rename_material") {
|
||||||
@@ -843,6 +1057,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();
|
||||||
|
@@ -26,13 +26,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <abstractview.h>
|
#include <abstractview.h>
|
||||||
|
#include <itemlibraryinfo.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 {
|
||||||
@@ -70,6 +74,7 @@ public:
|
|||||||
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
void instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &propertyList) override;
|
||||||
|
|
||||||
void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override;
|
void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override;
|
||||||
|
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
|
||||||
void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override;
|
void modelNodePreviewPixmapChanged(const ModelNode &node, const QPixmap &pixmap) override;
|
||||||
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override;
|
||||||
void customNotification(const AbstractView *view, const QString &identifier,
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
@@ -89,10 +94,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();
|
||||||
@@ -115,8 +123,13 @@ private:
|
|||||||
|
|
||||||
bool noValidSelection() const;
|
bool noValidSelection() const;
|
||||||
|
|
||||||
|
void initPreviewData();
|
||||||
|
void delayedTypeUpdate();
|
||||||
|
void updatePossibleTypes();
|
||||||
|
|
||||||
ModelNode m_selectedMaterial;
|
ModelNode m_selectedMaterial;
|
||||||
QTimer m_ensureMatLibTimer;
|
QTimer m_ensureMatLibTimer;
|
||||||
|
QTimer m_typeUpdateTimer;
|
||||||
QShortcut *m_updateShortcut = nullptr;
|
QShortcut *m_updateShortcut = nullptr;
|
||||||
int m_timerId = 0;
|
int m_timerId = 0;
|
||||||
QStackedWidget *m_stackedWidget = nullptr;
|
QStackedWidget *m_stackedWidget = nullptr;
|
||||||
@@ -126,6 +139,11 @@ 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;
|
||||||
|
bool m_hasMaterialRoot = false;
|
||||||
|
bool m_initializingPreviewData = false;
|
||||||
|
|
||||||
|
QPointer<QColorDialog> m_colorDialog;
|
||||||
|
QPointer<ItemLibraryInfo> m_itemLibraryInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -65,7 +65,7 @@ QModelIndex StatesEditorModel::index(int row, int column, const QModelIndex &par
|
|||||||
|
|
||||||
int internalNodeId = 0;
|
int internalNodeId = 0;
|
||||||
if (row > 0 && row < rowCount() - 1) // first and last rows are base state, add state
|
if (row > 0 && row < rowCount() - 1) // first and last rows are base state, add state
|
||||||
internalNodeId = m_statesEditorView->rootModelNode().nodeListProperty("states").at(row - 1).internalId();
|
internalNodeId = m_statesEditorView->acitveStatesGroupNode().nodeListProperty("states").at(row - 1).internalId();
|
||||||
|
|
||||||
return hasIndex(row, column, parent) ? createIndex(row, column, internalNodeId) : QModelIndex();
|
return hasIndex(row, column, parent) ? createIndex(row, column, internalNodeId) : QModelIndex();
|
||||||
}
|
}
|
||||||
@@ -75,10 +75,10 @@ int StatesEditorModel::rowCount(const QModelIndex &parent) const
|
|||||||
if (parent.isValid() || m_statesEditorView.isNull() || !m_statesEditorView->model())
|
if (parent.isValid() || m_statesEditorView.isNull() || !m_statesEditorView->model())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!m_statesEditorView->rootModelNode().hasNodeListProperty("states"))
|
if (!m_statesEditorView->acitveStatesGroupNode().hasNodeListProperty("states"))
|
||||||
return 2; // base state + add new state
|
return 2; // base state + add new state
|
||||||
|
|
||||||
return m_statesEditorView->rootModelNode().nodeListProperty("states").count() + 2; // 2 = base state + add new state
|
return m_statesEditorView->acitveStatesGroupNode().nodeListProperty("states").count() + 2; // 2 = base state + add new state
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorModel::reset()
|
void StatesEditorModel::reset()
|
||||||
|
@@ -85,6 +85,20 @@ void StatesEditorView::rootNodeTypeChanged(const QString &/*type*/, int /*majorV
|
|||||||
checkForStatesAvailability();
|
checkForStatesAvailability();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelNode StatesEditorView::acitveStatesGroupNode() const
|
||||||
|
{
|
||||||
|
return m_activeStatesGroupNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatesEditorView::setAcitveStatesGroupNode(const ModelNode &modelNode)
|
||||||
|
{
|
||||||
|
if (m_activeStatesGroupNode == modelNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_activeStatesGroupNode = modelNode;
|
||||||
|
resetModel();
|
||||||
|
}
|
||||||
|
|
||||||
void StatesEditorView::removeState(int nodeId)
|
void StatesEditorView::removeState(int nodeId)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -193,12 +207,12 @@ void StatesEditorView::createNewState()
|
|||||||
void StatesEditorView::addState()
|
void StatesEditorView::addState()
|
||||||
{
|
{
|
||||||
// can happen when root node is e.g. a ListModel
|
// can happen when root node is e.g. a ListModel
|
||||||
if (!QmlVisualNode::isValidQmlVisualNode(rootModelNode()))
|
if (!QmlVisualNode::isValidQmlVisualNode(acitveStatesGroupNode()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_STATE_ADDED);
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_STATE_ADDED);
|
||||||
|
|
||||||
QStringList modelStateNames = rootStateGroup().names();
|
QStringList modelStateNames = activeStateGroup().names();
|
||||||
|
|
||||||
QString newStateName;
|
QString newStateName;
|
||||||
int index = 1;
|
int index = 1;
|
||||||
@@ -209,9 +223,9 @@ void StatesEditorView::addState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
executeInTransaction("addState", [this, newStateName]() {
|
executeInTransaction("addState", [this, newStateName]() {
|
||||||
rootModelNode().validId();
|
acitveStatesGroupNode().validId();
|
||||||
|
|
||||||
ModelNode newState = rootStateGroup().addState(newStateName);
|
ModelNode newState = activeStateGroup().addState(newStateName);
|
||||||
setCurrentState(newState);
|
setCurrentState(newState);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -244,7 +258,7 @@ void StatesEditorView::duplicateCurrentState()
|
|||||||
newName = newName.left(match.capturedStart());
|
newName = newName.left(match.capturedStart());
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
QStringList stateNames = rootStateGroup().names();
|
QStringList stateNames = activeStateGroup().names();
|
||||||
while (stateNames.contains(newName + QString::number(i)))
|
while (stateNames.contains(newName + QString::number(i)))
|
||||||
i++;
|
i++;
|
||||||
const QString newStateName = newName + QString::number(i);
|
const QString newStateName = newName + QString::number(i);
|
||||||
@@ -258,7 +272,7 @@ void StatesEditorView::duplicateCurrentState()
|
|||||||
void StatesEditorView::checkForStatesAvailability()
|
void StatesEditorView::checkForStatesAvailability()
|
||||||
{
|
{
|
||||||
if (m_statesEditorWidget) {
|
if (m_statesEditorWidget) {
|
||||||
const bool isVisual = QmlVisualNode::isValidQmlVisualNode(rootModelNode());
|
const bool isVisual = QmlVisualNode::isValidQmlVisualNode(acitveStatesGroupNode());
|
||||||
m_statesEditorWidget->showAddNewStatesButton(isVisual);
|
m_statesEditorWidget->showAddNewStatesButton(isVisual);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,16 +291,16 @@ QmlModelState StatesEditorView::baseState() const
|
|||||||
return QmlModelState::createBaseState(this);
|
return QmlModelState::createBaseState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlModelStateGroup StatesEditorView::rootStateGroup() const
|
QmlModelStateGroup StatesEditorView::activeStateGroup() const
|
||||||
{
|
{
|
||||||
return QmlModelStateGroup(rootModelNode());
|
return QmlModelStateGroup(acitveStatesGroupNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StatesEditorView::validStateName(const QString &name) const
|
bool StatesEditorView::validStateName(const QString &name) const
|
||||||
{
|
{
|
||||||
if (name == tr("base state"))
|
if (name == tr("base state"))
|
||||||
return false;
|
return false;
|
||||||
const QList<QmlModelState> modelStates = rootStateGroup().allStates();
|
const QList<QmlModelState> modelStates = activeStateGroup().allStates();
|
||||||
for (const QmlModelState &state : modelStates) {
|
for (const QmlModelState &state : modelStates) {
|
||||||
if (state.name() == name)
|
if (state.name() == name)
|
||||||
return false;
|
return false;
|
||||||
@@ -392,8 +406,8 @@ void StatesEditorView::resetDefaultState()
|
|||||||
auto guard = qScopeGuard([&]() { m_block = false; });
|
auto guard = qScopeGuard([&]() { m_block = false; });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (rootModelNode().hasProperty("state"))
|
if (acitveStatesGroupNode().hasProperty("state"))
|
||||||
rootModelNode().removeProperty("state");
|
acitveStatesGroupNode().removeProperty("state");
|
||||||
|
|
||||||
} catch (const RewritingException &e) {
|
} catch (const RewritingException &e) {
|
||||||
e.showException();
|
e.showException();
|
||||||
@@ -402,7 +416,7 @@ void StatesEditorView::resetDefaultState()
|
|||||||
|
|
||||||
bool StatesEditorView::hasDefaultState() const
|
bool StatesEditorView::hasDefaultState() const
|
||||||
{
|
{
|
||||||
return rootModelNode().hasProperty("state");
|
return acitveStatesGroupNode().hasProperty("state");
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatesEditorView::setAnnotation(int internalNodeId)
|
void StatesEditorView::setAnnotation(int internalNodeId)
|
||||||
@@ -475,6 +489,8 @@ void StatesEditorView::modelAttached(Model *model)
|
|||||||
Q_ASSERT(model);
|
Q_ASSERT(model);
|
||||||
AbstractView::modelAttached(model);
|
AbstractView::modelAttached(model);
|
||||||
|
|
||||||
|
m_activeStatesGroupNode = rootModelNode();
|
||||||
|
|
||||||
if (m_statesEditorWidget)
|
if (m_statesEditorWidget)
|
||||||
m_statesEditorWidget->setNodeInstanceView(nodeInstanceView());
|
m_statesEditorWidget->setNodeInstanceView(nodeInstanceView());
|
||||||
|
|
||||||
@@ -593,7 +609,7 @@ void StatesEditorView::instancesPreviewImageChanged(const QVector<ModelNode> &no
|
|||||||
minimumIndex = qMin(minimumIndex, 0);
|
minimumIndex = qMin(minimumIndex, 0);
|
||||||
maximumIndex = qMax(maximumIndex, 0);
|
maximumIndex = qMax(maximumIndex, 0);
|
||||||
} else {
|
} else {
|
||||||
int index = rootStateGroup().allStates().indexOf(QmlModelState(node)) + 1;
|
int index = activeStateGroup().allStates().indexOf(QmlModelState(node)) + 1;
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
minimumIndex = qMin(minimumIndex, index);
|
minimumIndex = qMin(minimumIndex, index);
|
||||||
maximumIndex = qMax(maximumIndex, index);
|
maximumIndex = qMax(maximumIndex, index);
|
||||||
|
@@ -55,7 +55,7 @@ public:
|
|||||||
QString currentStateName() const;
|
QString currentStateName() const;
|
||||||
void setCurrentState(const QmlModelState &state);
|
void setCurrentState(const QmlModelState &state);
|
||||||
QmlModelState baseState() const;
|
QmlModelState baseState() const;
|
||||||
QmlModelStateGroup rootStateGroup() const;
|
QmlModelStateGroup activeStateGroup() const;
|
||||||
|
|
||||||
// AbstractView
|
// AbstractView
|
||||||
void modelAttached(Model *model) override;
|
void modelAttached(Model *model) override;
|
||||||
@@ -87,6 +87,10 @@ public:
|
|||||||
|
|
||||||
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
|
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override;
|
||||||
|
|
||||||
|
ModelNode acitveStatesGroupNode() const;
|
||||||
|
void setAcitveStatesGroupNode(const ModelNode &modelNode);
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void synchonizeCurrentStateFromWidget();
|
void synchonizeCurrentStateFromWidget();
|
||||||
void createNewState();
|
void createNewState();
|
||||||
@@ -105,6 +109,7 @@ private:
|
|||||||
int m_lastIndex;
|
int m_lastIndex;
|
||||||
bool m_block = false;
|
bool m_block = false;
|
||||||
QPointer<AnnotationEditor> m_editor;
|
QPointer<AnnotationEditor> m_editor;
|
||||||
|
ModelNode m_activeStatesGroupNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -24,47 +24,147 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "setframevaluedialog.h"
|
#include "setframevaluedialog.h"
|
||||||
#include "ui_setframevaluedialog.h"
|
#include "timelinecontrols.h"
|
||||||
|
|
||||||
#include <QtGui/qvalidator.h>
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value,
|
SetFrameValueDialog::SetFrameValueDialog(qreal frame, const QVariant &value,
|
||||||
const QString &propertyName, QWidget *parent)
|
const QString &propertyName, QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent, Qt::Tool)
|
||||||
, ui(new Ui::SetFrameValueDialog)
|
, m_valueGetter()
|
||||||
|
, m_valueType(value.metaType())
|
||||||
|
, m_frameControl(new QSpinBox)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
|
||||||
setWindowTitle(tr("Edit Keyframe"));
|
setWindowTitle(tr("Edit Keyframe"));
|
||||||
setFixedSize(size());
|
|
||||||
|
|
||||||
ui->lineEditFrame->setValidator(new QIntValidator(0, 99999, this));
|
auto frameLabelString = QString(tr("Frame"));
|
||||||
auto dv = new QDoubleValidator(this);
|
auto labelWidth = fontMetrics().boundingRect(frameLabelString).width();
|
||||||
dv->setDecimals(2);
|
if (auto tmp = fontMetrics().boundingRect(propertyName).width(); tmp > labelWidth)
|
||||||
ui->lineEditValue->setValidator(dv);
|
labelWidth = tmp;
|
||||||
|
|
||||||
QLocale l;
|
auto *frameLabel = new QLabel(frameLabelString);
|
||||||
ui->lineEditFrame->setText(l.toString(qRound(frame)));
|
frameLabel->setAlignment(Qt::AlignRight);
|
||||||
ui->lineEditValue->setText(l.toString(value.toDouble(), 'f', 2));
|
frameLabel->setFixedWidth(labelWidth);
|
||||||
ui->labelValue->setText(propertyName);
|
|
||||||
|
auto *valueLabel = new QLabel(propertyName);
|
||||||
|
valueLabel->setAlignment(Qt::AlignRight);
|
||||||
|
valueLabel->setFixedWidth(labelWidth);
|
||||||
|
|
||||||
|
m_frameControl->setRange(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
|
||||||
|
m_frameControl->setValue(static_cast<int>(frame));
|
||||||
|
m_frameControl->setAlignment(Qt::AlignRight);
|
||||||
|
|
||||||
|
auto* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||||
|
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||||
|
|
||||||
|
auto* frameRow = new QHBoxLayout;
|
||||||
|
frameRow->addWidget(frameLabel);
|
||||||
|
frameRow->addWidget(m_frameControl);
|
||||||
|
|
||||||
|
auto* valueRow = new QHBoxLayout;
|
||||||
|
valueRow->addWidget(valueLabel);
|
||||||
|
valueRow->addWidget(createValueControl(value));
|
||||||
|
|
||||||
|
auto* hbox = new QVBoxLayout;
|
||||||
|
hbox->addLayout(frameRow);
|
||||||
|
hbox->addLayout(valueRow);
|
||||||
|
hbox->addStretch();
|
||||||
|
hbox->addWidget(buttons);
|
||||||
|
|
||||||
|
setLayout(hbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFrameValueDialog::~SetFrameValueDialog()
|
SetFrameValueDialog::~SetFrameValueDialog()
|
||||||
{
|
{ }
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal SetFrameValueDialog::frame() const
|
qreal SetFrameValueDialog::frame() const
|
||||||
{
|
{
|
||||||
QLocale l;
|
return static_cast<qreal>(m_frameControl->value());
|
||||||
return l.toDouble(ui->lineEditFrame->text());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SetFrameValueDialog::value() const
|
QVariant SetFrameValueDialog::value() const
|
||||||
{
|
{
|
||||||
QLocale l;
|
if (m_valueGetter)
|
||||||
return QVariant(l.toDouble(ui->lineEditValue->text()));
|
return m_valueGetter();
|
||||||
|
return QVariant(m_valueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* SetFrameValueDialog::createValueControl(const QVariant& value)
|
||||||
|
{
|
||||||
|
m_valueType = value.metaType();
|
||||||
|
|
||||||
|
switch (value.metaType().id())
|
||||||
|
{
|
||||||
|
|
||||||
|
case QMetaType::QColor: {
|
||||||
|
auto* widget = new ColorControl(value.value<QColor>());
|
||||||
|
m_valueGetter = [widget]() { return widget->value(); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::Bool: {
|
||||||
|
auto* widget = new QCheckBox;
|
||||||
|
widget->setChecked(value.toBool());
|
||||||
|
m_valueGetter = [widget]() { return widget->isChecked(); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::Int: {
|
||||||
|
auto* widget = new QSpinBox;
|
||||||
|
widget->setRange(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
|
||||||
|
widget->setAlignment(Qt::AlignRight);
|
||||||
|
widget->setValue(value.toInt());
|
||||||
|
m_valueGetter = [widget]() { return widget->value(); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::UInt: {
|
||||||
|
auto* widget = new QSpinBox;
|
||||||
|
widget->setRange(0, std::numeric_limits<int>::max());
|
||||||
|
widget->setAlignment(Qt::AlignRight);
|
||||||
|
widget->setValue(value.toUInt());
|
||||||
|
m_valueGetter = [widget]() { return static_cast<unsigned int>(widget->value()); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::Float: {
|
||||||
|
auto* widget = new QDoubleSpinBox;
|
||||||
|
widget->setRange(std::numeric_limits<float>::min(), std::numeric_limits<float>::max());
|
||||||
|
widget->setAlignment(Qt::AlignRight);
|
||||||
|
widget->setValue(value.toFloat());
|
||||||
|
m_valueGetter = [widget]() { return static_cast<float>(widget->value()); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::Double:
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
|
default: {
|
||||||
|
auto* widget = new QDoubleSpinBox;
|
||||||
|
widget->setRange(std::numeric_limits<double>::min(), std::numeric_limits<double>::max());
|
||||||
|
widget->setAlignment(Qt::AlignRight);
|
||||||
|
widget->setValue(value.toDouble());
|
||||||
|
m_valueGetter = [widget]() { return widget->value(); };
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
m_valueGetter = nullptr;
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -27,14 +27,10 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QLineEdit)
|
QT_FORWARD_DECLARE_CLASS(QSpinBox)
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class SetFrameValueDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SetFrameValueDialog : public QDialog
|
class SetFrameValueDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -48,7 +44,12 @@ public:
|
|||||||
QVariant value() const;
|
QVariant value() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::SetFrameValueDialog *ui;
|
QWidget* createValueControl(const QVariant& value);
|
||||||
|
|
||||||
|
std::function<QVariant(void)> m_valueGetter;
|
||||||
|
|
||||||
|
QMetaType m_valueType;
|
||||||
|
QSpinBox *m_frameControl;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -1,84 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>QmlDesigner::SetFrameValueDialog</class>
|
|
||||||
<widget class="QDialog" name="QmlDesigner::SetFrameValueDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>212</width>
|
|
||||||
<height>148</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Dialog</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="labelFrame">
|
|
||||||
<property name="text">
|
|
||||||
<string>Frame</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditFrame"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="lineEditValue"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="labelValue">
|
|
||||||
<property name="text">
|
|
||||||
<string>Value</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>accepted()</signal>
|
|
||||||
<receiver>QmlDesigner::SetFrameValueDialog</receiver>
|
|
||||||
<slot>accept()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>248</x>
|
|
||||||
<y>254</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>157</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
<connection>
|
|
||||||
<sender>buttonBox</sender>
|
|
||||||
<signal>rejected()</signal>
|
|
||||||
<receiver>QmlDesigner::SetFrameValueDialog</receiver>
|
|
||||||
<slot>reject()</slot>
|
|
||||||
<hints>
|
|
||||||
<hint type="sourcelabel">
|
|
||||||
<x>316</x>
|
|
||||||
<y>260</y>
|
|
||||||
</hint>
|
|
||||||
<hint type="destinationlabel">
|
|
||||||
<x>286</x>
|
|
||||||
<y>274</y>
|
|
||||||
</hint>
|
|
||||||
</hints>
|
|
||||||
</connection>
|
|
||||||
</connections>
|
|
||||||
</ui>
|
|
@@ -191,7 +191,7 @@ void ColorControl::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
if (color != m_color) {
|
if (color.isValid() && color != m_color) {
|
||||||
m_color = color;
|
m_color = color;
|
||||||
update();
|
update();
|
||||||
emit valueChanged();
|
emit valueChanged();
|
||||||
|
@@ -1044,6 +1044,18 @@ bool shouldSendAuxiliary(const AuxiliaryDataKey &key)
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
bool parentIsBehavior(ModelNode node)
|
||||||
|
{
|
||||||
|
while (node.isValid() && !node.isRootNode()) {
|
||||||
|
if (!node.behaviorPropertyName().isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
node = node.parentProperty().parentModelNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
||||||
{
|
{
|
||||||
QList<ModelNode> nodeList = allModelNodes();
|
QList<ModelNode> nodeList = allModelNodes();
|
||||||
@@ -1103,7 +1115,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
|||||||
nodeMetaType,
|
nodeMetaType,
|
||||||
nodeFlags);
|
nodeFlags);
|
||||||
|
|
||||||
if (instance.modelNode().behaviorPropertyName().isEmpty())
|
if (!parentIsBehavior(instance.modelNode()))
|
||||||
instanceContainerList.append(container);
|
instanceContainerList.append(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -836,7 +836,7 @@ void AbstractView::changeRootNodeType(const TypeName &type, int majorVersion, in
|
|||||||
void AbstractView::ensureMaterialLibraryNode()
|
void AbstractView::ensureMaterialLibraryNode()
|
||||||
{
|
{
|
||||||
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
if (matLib.isValid())
|
if (matLib.isValid() || rootModelNode().isSubclassOf("QtQuick3D.Material"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create material library node
|
// Create material library node
|
||||||
@@ -865,13 +865,11 @@ void AbstractView::ensureMaterialLibraryNode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns ModelNode for project's material library.
|
// Returns ModelNode for project's material library.
|
||||||
|
// Since this calls ensureMaterialLibraryNode(), it should only be called within a transaction.
|
||||||
ModelNode AbstractView::materialLibraryNode()
|
ModelNode AbstractView::materialLibraryNode()
|
||||||
{
|
{
|
||||||
ensureMaterialLibraryNode();
|
ensureMaterialLibraryNode();
|
||||||
|
|
||||||
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID);
|
||||||
QTC_ASSERT(matLib.isValid(), return {});
|
|
||||||
|
|
||||||
return matLib;
|
return matLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -408,8 +408,12 @@ void ModelPrivate::notifyNodeInstanceViewLast(Callable call)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const QPointer<AbstractView> &view : enabledViews()) {
|
for (const QPointer<AbstractView> &view : enabledViews()) {
|
||||||
if (!view->isBlockingNotifications())
|
try {
|
||||||
call(view.data());
|
if (!view->isBlockingNotifications())
|
||||||
|
call(view.data());
|
||||||
|
} catch (const Exception &e) {
|
||||||
|
e.showException(tr("Exception thrown by view %1.").arg(view->widgetInfo().tabName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications())
|
if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications())
|
||||||
|
@@ -88,6 +88,7 @@ RewriterView::RewriterView(DifferenceHandling differenceHandling, QObject *paren
|
|||||||
m_textToModelMerger(new Internal::TextToModelMerger(this))
|
m_textToModelMerger(new Internal::TextToModelMerger(this))
|
||||||
{
|
{
|
||||||
m_amendTimer.setSingleShot(true);
|
m_amendTimer.setSingleShot(true);
|
||||||
|
|
||||||
m_amendTimer.setInterval(800);
|
m_amendTimer.setInterval(800);
|
||||||
connect(&m_amendTimer, &QTimer::timeout, this, &RewriterView::amendQmlText);
|
connect(&m_amendTimer, &QTimer::timeout, this, &RewriterView::amendQmlText);
|
||||||
|
|
||||||
@@ -524,6 +525,10 @@ void RewriterView::applyChanges()
|
|||||||
|
|
||||||
void RewriterView::amendQmlText()
|
void RewriterView::amendQmlText()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!model()->rewriterView())
|
||||||
|
return;
|
||||||
|
|
||||||
emitCustomNotification(StartRewriterAmend);
|
emitCustomNotification(StartRewriterAmend);
|
||||||
|
|
||||||
const QString newQmlText = m_textModifier->text();
|
const QString newQmlText = m_textModifier->text();
|
||||||
|
@@ -525,13 +525,15 @@ public:
|
|||||||
&& metaInfo.majorVersion() == majorVersion
|
&& metaInfo.majorVersion() == majorVersion
|
||||||
&& metaInfo.minorVersion() == minorVersion;
|
&& metaInfo.minorVersion() == minorVersion;
|
||||||
|
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
qDebug() << astTypeNode->name.toString() << typeName;
|
qDebug() << astTypeNode->name.toString() << typeName;
|
||||||
qDebug() << metaInfo.isValid() << metaInfo.typeName();
|
qDebug() << metaInfo.isValid() << metaInfo.typeName();
|
||||||
qDebug() << metaInfo.directSuperClass().typeName();
|
qDebug() << metaInfo.directSuperClass().typeName();
|
||||||
|
|
||||||
if (!typeName.startsWith("..."))
|
if (!typeName.startsWith("...") && m_model == m_model->metaInfoProxyModel()
|
||||||
|
&& metaInfo.isValid())
|
||||||
throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "test", "test");
|
throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "test", "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1715,7 +1717,7 @@ void TextToModelMerger::syncSignalDeclarationProperty(AbstractProperty &modelPro
|
|||||||
const QString &signature,
|
const QString &signature,
|
||||||
DifferenceHandler &differenceHandler)
|
DifferenceHandler &differenceHandler)
|
||||||
{
|
{
|
||||||
if (modelProperty.isSignalHandlerProperty()) {
|
if (modelProperty.isSignalDeclarationProperty()) {
|
||||||
SignalDeclarationProperty signalHandlerProperty = modelProperty.toSignalDeclarationProperty();
|
SignalDeclarationProperty signalHandlerProperty = modelProperty.toSignalDeclarationProperty();
|
||||||
if (signalHandlerProperty.signature() != signature)
|
if (signalHandlerProperty.signature() != signature)
|
||||||
differenceHandler.signalDeclarationSignatureDiffer(signalHandlerProperty, signature);
|
differenceHandler.signalDeclarationSignatureDiffer(signalHandlerProperty, signature);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "designmodewidget.h"
|
#include "designmodewidget.h"
|
||||||
#include "formeditorwidget.h"
|
#include "formeditorwidget.h"
|
||||||
#include "edit3dwidget.h"
|
#include "edit3dwidget.h"
|
||||||
|
#include "materialbrowserwidget.h"
|
||||||
#include "navigatorwidget.h"
|
#include "navigatorwidget.h"
|
||||||
#include "texteditorwidget.h"
|
#include "texteditorwidget.h"
|
||||||
|
|
||||||
@@ -70,6 +71,18 @@ void Editor3DContext::contextHelp(const HelpCallback &callback) const
|
|||||||
qobject_cast<Edit3DWidget *>(m_widget)->contextHelp(callback);
|
qobject_cast<Edit3DWidget *>(m_widget)->contextHelp(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaterialBrowserContext::MaterialBrowserContext(QWidget *widget)
|
||||||
|
: IContext(widget)
|
||||||
|
{
|
||||||
|
setWidget(widget);
|
||||||
|
setContext(Core::Context(Constants::C_QMLMATERIALBROWSER, Constants::C_QT_QUICK_TOOLS_MENU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialBrowserContext::contextHelp(const HelpCallback &callback) const
|
||||||
|
{
|
||||||
|
qobject_cast<MaterialBrowserWidget *>(m_widget)->contextHelp(callback);
|
||||||
|
}
|
||||||
|
|
||||||
NavigatorContext::NavigatorContext(QWidget *widget)
|
NavigatorContext::NavigatorContext(QWidget *widget)
|
||||||
: IContext(widget)
|
: IContext(widget)
|
||||||
{
|
{
|
||||||
|
@@ -60,6 +60,15 @@ public:
|
|||||||
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MaterialBrowserContext : public Core::IContext
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MaterialBrowserContext(QWidget *widget);
|
||||||
|
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class NavigatorContext : public Core::IContext
|
class NavigatorContext : public Core::IContext
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@@ -390,19 +390,26 @@ void DesignModeWidget::setup()
|
|||||||
|
|
||||||
m_dockManager->initialize();
|
m_dockManager->initialize();
|
||||||
|
|
||||||
|
// Hide all floating widgets if the initial mode isn't design mode
|
||||||
|
if (Core::ModeManager::instance()->currentModeId() != Core::Constants::MODE_DESIGN) {
|
||||||
|
for (auto &floatingWidget : m_dockManager->floatingWidgets())
|
||||||
|
floatingWidget->hide();
|
||||||
|
}
|
||||||
|
|
||||||
connect(Core::ModeManager::instance(),
|
connect(Core::ModeManager::instance(),
|
||||||
&Core::ModeManager::currentModeChanged,
|
&Core::ModeManager::currentModeChanged,
|
||||||
this,
|
this,
|
||||||
[this](Utils::Id mode, Utils::Id oldMode) {
|
[this](Utils::Id mode, Utils::Id previousMode) {
|
||||||
if (mode == Core::Constants::MODE_DESIGN) {
|
if (mode == Core::Constants::MODE_DESIGN) {
|
||||||
m_dockManager->reloadActiveWorkspace();
|
m_dockManager->reloadActiveWorkspace();
|
||||||
m_dockManager->setModeChangeState(false);
|
m_dockManager->setModeChangeState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldMode == Core::Constants::MODE_DESIGN && mode != Core::Constants::MODE_DESIGN) {
|
if (previousMode == Core::Constants::MODE_DESIGN
|
||||||
|
&& mode != Core::Constants::MODE_DESIGN) {
|
||||||
m_dockManager->save();
|
m_dockManager->save();
|
||||||
m_dockManager->setModeChangeState(true);
|
m_dockManager->setModeChangeState(true);
|
||||||
for (auto floatingWidget : m_dockManager->floatingWidgets())
|
for (auto &floatingWidget : m_dockManager->floatingWidgets())
|
||||||
floatingWidget->hide();
|
floatingWidget->hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -32,11 +32,12 @@ const char C_BACKSPACE[] = "QmlDesigner.Backspace";
|
|||||||
const char C_DELETE[] = "QmlDesigner.Delete";
|
const char C_DELETE[] = "QmlDesigner.Delete";
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain";
|
const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain";
|
||||||
const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor";
|
const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor";
|
||||||
const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D";
|
const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D";
|
||||||
const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator";
|
const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator";
|
||||||
const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor";
|
const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor";
|
||||||
|
const char C_QMLMATERIALBROWSER[] = "QmlDesigner::MaterialBrowser";
|
||||||
|
|
||||||
// Special context for preview menu, shared b/w designer and text editor
|
// Special context for preview menu, shared b/w designer and text editor
|
||||||
const char C_QT_QUICK_TOOLS_MENU[] = "QmlDesigner::ToolsMenu";
|
const char C_QT_QUICK_TOOLS_MENU[] = "QmlDesigner::ToolsMenu";
|
||||||
|
@@ -399,15 +399,18 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget)
|
|||||||
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
|
Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR);
|
||||||
Core::Context qmlDesignerEditor3dContext(Constants::C_QMLEDITOR3D);
|
Core::Context qmlDesignerEditor3dContext(Constants::C_QMLEDITOR3D);
|
||||||
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
|
Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR);
|
||||||
|
Core::Context qmlDesignerMaterialBrowserContext(Constants::C_QMLMATERIALBROWSER);
|
||||||
|
|
||||||
context->context().add(qmlDesignerMainContext);
|
context->context().add(qmlDesignerMainContext);
|
||||||
context->context().add(qmlDesignerFormEditorContext);
|
context->context().add(qmlDesignerFormEditorContext);
|
||||||
context->context().add(qmlDesignerEditor3dContext);
|
context->context().add(qmlDesignerEditor3dContext);
|
||||||
context->context().add(qmlDesignerNavigatorContext);
|
context->context().add(qmlDesignerNavigatorContext);
|
||||||
|
context->context().add(qmlDesignerMaterialBrowserContext);
|
||||||
context->context().add(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
|
context->context().add(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID);
|
||||||
|
|
||||||
d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext,
|
d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext,
|
||||||
qmlDesignerEditor3dContext, qmlDesignerNavigatorContext);
|
qmlDesignerEditor3dContext, qmlDesignerNavigatorContext,
|
||||||
|
qmlDesignerMaterialBrowserContext);
|
||||||
|
|
||||||
const QStringList mimeTypes = { QmlJSTools::Constants::QML_MIMETYPE,
|
const QStringList mimeTypes = { QmlJSTools::Constants::QML_MIMETYPE,
|
||||||
QmlJSTools::Constants::QMLUI_MIMETYPE };
|
QmlJSTools::Constants::QMLUI_MIMETYPE };
|
||||||
|
@@ -1011,7 +1011,6 @@ Project {
|
|||||||
"timelineeditor/preseteditor.h",
|
"timelineeditor/preseteditor.h",
|
||||||
"timelineeditor/setframevaluedialog.cpp",
|
"timelineeditor/setframevaluedialog.cpp",
|
||||||
"timelineeditor/setframevaluedialog.h",
|
"timelineeditor/setframevaluedialog.h",
|
||||||
"timelineeditor/setframevaluedialog.ui",
|
|
||||||
"timelineeditor/splineeditor.cpp",
|
"timelineeditor/splineeditor.cpp",
|
||||||
"timelineeditor/splineeditor.h",
|
"timelineeditor/splineeditor.h",
|
||||||
"timelineeditor/timeline.qrc",
|
"timelineeditor/timeline.qrc",
|
||||||
|
@@ -77,8 +77,11 @@ ShortCutManager::ShortCutManager()
|
|||||||
void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContext,
|
void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContext,
|
||||||
const Core::Context &qmlDesignerFormEditorContext,
|
const Core::Context &qmlDesignerFormEditorContext,
|
||||||
const Core::Context &qmlDesignerEditor3DContext,
|
const Core::Context &qmlDesignerEditor3DContext,
|
||||||
const Core::Context &qmlDesignerNavigatorContext)
|
const Core::Context &qmlDesignerNavigatorContext,
|
||||||
|
const Core::Context &qmlDesignerMaterialBrowserContext)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(qmlDesignerMaterialBrowserContext)
|
||||||
|
|
||||||
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
|
Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT);
|
||||||
Core::ActionContainer *fileMenu = Core::ActionManager::actionContainer(Core::Constants::M_FILE);
|
Core::ActionContainer *fileMenu = Core::ActionManager::actionContainer(Core::Constants::M_FILE);
|
||||||
|
|
||||||
@@ -195,9 +198,12 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex
|
|||||||
m_pasteAction.setEnabled(true);
|
m_pasteAction.setEnabled(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(Core::ICore::instance(), &Core::ICore::contextChanged, this, [&designerActionManager, this](const Core::Context &context){
|
connect(Core::ICore::instance(), &Core::ICore::contextChanged, this, [&](const Core::Context &context) {
|
||||||
if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLEDITOR3D) && !context.contains(Constants::C_QMLNAVIGATOR)) {
|
isMatBrowserActive = context.contains(Constants::C_QMLMATERIALBROWSER);
|
||||||
m_deleteAction.setEnabled(false);
|
|
||||||
|
if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLEDITOR3D)
|
||||||
|
&& !context.contains(Constants::C_QMLNAVIGATOR)) {
|
||||||
|
m_deleteAction.setEnabled(isMatBrowserActive);
|
||||||
m_cutAction.setEnabled(false);
|
m_cutAction.setEnabled(false);
|
||||||
m_copyAction.setEnabled(false);
|
m_copyAction.setEnabled(false);
|
||||||
m_pasteAction.setEnabled(false);
|
m_pasteAction.setEnabled(false);
|
||||||
@@ -249,8 +255,12 @@ void ShortCutManager::redo()
|
|||||||
|
|
||||||
void ShortCutManager::deleteSelected()
|
void ShortCutManager::deleteSelected()
|
||||||
{
|
{
|
||||||
if (currentDesignDocument())
|
if (isMatBrowserActive) {
|
||||||
|
DesignerActionManager &designerActionManager = QmlDesignerPlugin::instance()->viewManager().designerActionManager();
|
||||||
|
designerActionManager.view()->emitCustomNotification("delete_selected_material");
|
||||||
|
} else if (currentDesignDocument()) {
|
||||||
currentDesignDocument()->deleteSelected();
|
currentDesignDocument()->deleteSelected();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShortCutManager::cutSelected()
|
void ShortCutManager::cutSelected()
|
||||||
|
@@ -47,7 +47,8 @@ public:
|
|||||||
void registerActions(const Core::Context &qmlDesignerMainContext,
|
void registerActions(const Core::Context &qmlDesignerMainContext,
|
||||||
const Core::Context &qmlDesignerFormEditorContext,
|
const Core::Context &qmlDesignerFormEditorContext,
|
||||||
const Core::Context &qmlDesignerEditor3DContext,
|
const Core::Context &qmlDesignerEditor3DContext,
|
||||||
const Core::Context &qmlDesignerNavigatorContext);
|
const Core::Context &qmlDesignerNavigatorContext,
|
||||||
|
const Core::Context &qmlDesignerMaterialBrowserContext);
|
||||||
|
|
||||||
void connectUndoActions(DesignDocument *designDocument);
|
void connectUndoActions(DesignDocument *designDocument);
|
||||||
void disconnectUndoActions(DesignDocument *designDocument);
|
void disconnectUndoActions(DesignDocument *designDocument);
|
||||||
@@ -84,6 +85,8 @@ private:
|
|||||||
QAction m_pasteAction;
|
QAction m_pasteAction;
|
||||||
QAction m_selectAllAction;
|
QAction m_selectAllAction;
|
||||||
QAction m_escapeAction;
|
QAction m_escapeAction;
|
||||||
|
|
||||||
|
bool isMatBrowserActive = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -1,18 +1,25 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2017 The Qt Company Ltd
|
** Copyright (C) 2017 The Qt Company Ltd.
|
||||||
** All rights reserved.
|
** Contact: https://www.qt.io/licensing/
|
||||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Enterprise QML Live Preview Add-on.
|
** This file is part of Qt Creator.
|
||||||
**
|
**
|
||||||
** Licensees holding valid Qt Enterprise licenses may use this file in
|
** Commercial License Usage
|
||||||
** accordance with the Qt Enterprise License Agreement provided with the
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
** a written agreement between you and The Qt Company.
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
**
|
**
|
||||||
** If you have questions regarding the use of this file, please use
|
** GNU General Public License Usage
|
||||||
** contact form at http://www.qt.io/contact-us
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
@@ -1,18 +1,25 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2017 The Qt Company Ltd
|
** Copyright (C) 2017 The Qt Company Ltd.
|
||||||
** All rights reserved.
|
** Contact: https://www.qt.io/licensing/
|
||||||
** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
|
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Enterprise QML Live Preview Add-on.
|
** This file is part of Qt Creator.
|
||||||
**
|
**
|
||||||
** Licensees holding valid Qt Enterprise licenses may use this file in
|
** Commercial License Usage
|
||||||
** accordance with the Qt Enterprise License Agreement provided with the
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
** Software or, alternatively, in accordance with the terms contained in
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
** a written agreement between you and The Qt Company.
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
**
|
**
|
||||||
** If you have questions regarding the use of this file, please use
|
** GNU General Public License Usage
|
||||||
** contact form at http://www.qt.io/contact-us
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
@@ -39,12 +39,6 @@ ColorSettings::ColorSettings(QWidget *parent)
|
|||||||
m_ui.setupUi(this);
|
m_ui.setupUi(this);
|
||||||
|
|
||||||
m_ui.m_colorThemeView->setEnabled(false);
|
m_ui.m_colorThemeView->setEnabled(false);
|
||||||
connect(m_ui.m_comboColorThemes, &QComboBox::currentIndexChanged,
|
|
||||||
this, &ColorSettings::selectTheme);
|
|
||||||
connect(m_ui.m_colorThemeView, &ColorThemeView::colorChanged,
|
|
||||||
this, &ColorSettings::updateCurrentColors);
|
|
||||||
connect(m_ui.m_addColorTheme, &QToolButton::clicked, this, &ColorSettings::createTheme);
|
|
||||||
connect(m_ui.m_removeColorTheme, &QToolButton::clicked, this, &ColorSettings::removeTheme);
|
|
||||||
|
|
||||||
const QSettings *s = Core::ICore::settings();
|
const QSettings *s = Core::ICore::settings();
|
||||||
|
|
||||||
@@ -54,6 +48,14 @@ ColorSettings::ColorSettings(QWidget *parent)
|
|||||||
for (auto it = m_colorThemes.cbegin(); it != m_colorThemes.cend(); ++it)
|
for (auto it = m_colorThemes.cbegin(); it != m_colorThemes.cend(); ++it)
|
||||||
m_ui.m_comboColorThemes->addItem(it.key());
|
m_ui.m_comboColorThemes->addItem(it.key());
|
||||||
m_ui.m_comboColorThemes->setCurrentText(s->value(Constants::C_SETTINGS_COLORSETTINGS_CURRENTCOLORTHEME).toString());
|
m_ui.m_comboColorThemes->setCurrentText(s->value(Constants::C_SETTINGS_COLORSETTINGS_CURRENTCOLORTHEME).toString());
|
||||||
|
|
||||||
|
connect(m_ui.m_comboColorThemes,
|
||||||
|
&QComboBox::currentIndexChanged,
|
||||||
|
this,
|
||||||
|
&ColorSettings::selectTheme);
|
||||||
|
connect(m_ui.m_colorThemeView, &ColorThemeView::colorChanged, this, &ColorSettings::updateCurrentColors);
|
||||||
|
connect(m_ui.m_addColorTheme, &QToolButton::clicked, this, &ColorSettings::createTheme);
|
||||||
|
connect(m_ui.m_removeColorTheme, &QToolButton::clicked, this, &ColorSettings::removeTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorSettings::save()
|
void ColorSettings::save()
|
||||||
|
@@ -456,21 +456,28 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */)
|
|||||||
&FileDownloader::progressChanged,
|
&FileDownloader::progressChanged,
|
||||||
this,
|
this,
|
||||||
&DataModelDownloader::progressChanged);
|
&DataModelDownloader::progressChanged);
|
||||||
|
|
||||||
|
connect(&m_fileDownloader,
|
||||||
|
&FileDownloader::downloadFailed,
|
||||||
|
this,
|
||||||
|
&DataModelDownloader::downloadFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataModelDownloader::start()
|
bool DataModelDownloader::start()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!enableDownload()) {
|
if (!enableDownload()) {
|
||||||
m_available = false;
|
m_available = false;
|
||||||
emit availableChanged();
|
emit availableChanged();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fileDownloader.setUrl(QUrl::fromUserInput(
|
m_fileDownloader.setUrl(QUrl::fromUserInput(
|
||||||
"https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip"));
|
"https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip"));
|
||||||
|
|
||||||
connect(&m_fileDownloader, &FileDownloader::availableChanged, this, [this]() {
|
bool started = false;
|
||||||
|
|
||||||
|
connect(&m_fileDownloader, &FileDownloader::availableChanged, this, [this, &started]() {
|
||||||
|
|
||||||
m_available = m_fileDownloader.available();
|
m_available = m_fileDownloader.available();
|
||||||
|
|
||||||
@@ -484,6 +491,8 @@ void DataModelDownloader::start()
|
|||||||
if (!m_forceDownload && (m_fileDownloader.lastModified() <= m_birthTime))
|
if (!m_forceDownload && (m_fileDownloader.lastModified() <= m_birthTime))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
m_fileDownloader.start();
|
m_fileDownloader.start();
|
||||||
connect(&m_fileDownloader, &FileDownloader::finishedChanged, this, [this]() {
|
connect(&m_fileDownloader, &FileDownloader::finishedChanged, this, [this]() {
|
||||||
if (m_fileDownloader.finished()) {
|
if (m_fileDownloader.finished()) {
|
||||||
@@ -501,6 +510,7 @@ void DataModelDownloader::start()
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return started;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataModelDownloader::exists() const
|
bool DataModelDownloader::exists() const
|
||||||
|
@@ -163,7 +163,7 @@ class DataModelDownloader : public QObject
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DataModelDownloader(QObject *parent = nullptr);
|
explicit DataModelDownloader(QObject *parent = nullptr);
|
||||||
void start();
|
bool start();
|
||||||
bool exists() const;
|
bool exists() const;
|
||||||
bool available() const;
|
bool available() const;
|
||||||
Utils::FilePath targetFolder() const;
|
Utils::FilePath targetFolder() const;
|
||||||
@@ -174,6 +174,7 @@ signals:
|
|||||||
void finished();
|
void finished();
|
||||||
void availableChanged();
|
void availableChanged();
|
||||||
void progressChanged();
|
void progressChanged();
|
||||||
|
void downloadFailed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileDownloader m_fileDownloader;
|
FileDownloader m_fileDownloader;
|
||||||
|
@@ -453,7 +453,11 @@ public:
|
|||||||
~WelcomeMode() override;
|
~WelcomeMode() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickWidget *m_modeWidget = nullptr;
|
void setupQuickWidget(const QString &welcomePagePath);
|
||||||
|
void createQuickWidget();
|
||||||
|
|
||||||
|
QQuickWidget *m_quickWidget = nullptr;
|
||||||
|
QWidget *m_modeWidget = nullptr;
|
||||||
DataModelDownloader *m_dataModelDownloader = nullptr;
|
DataModelDownloader *m_dataModelDownloader = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -637,31 +641,31 @@ WelcomeMode::WelcomeMode()
|
|||||||
QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf");
|
QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf");
|
||||||
ExampleCheckout::registerTypes();
|
ExampleCheckout::registerTypes();
|
||||||
|
|
||||||
m_modeWidget = new QQuickWidget;
|
createQuickWidget();
|
||||||
m_modeWidget->setMinimumSize(640, 480);
|
|
||||||
m_modeWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
|
||||||
QmlDesigner::Theme::setupTheme(m_modeWidget->engine());
|
|
||||||
m_modeWidget->engine()->addImportPath("qrc:/studiofonts");
|
|
||||||
|
|
||||||
QmlDesigner::QmlDesignerPlugin::registerPreviewImageProvider(m_modeWidget->engine());
|
|
||||||
|
|
||||||
m_modeWidget->engine()->setOutputWarningsToStandardError(false);
|
|
||||||
|
|
||||||
if (forceDownLoad() || !readme.exists()) // Only downloads contain the readme
|
if (forceDownLoad() || !readme.exists()) // Only downloads contain the readme
|
||||||
m_dataModelDownloader->setForceDownload(true);
|
m_dataModelDownloader->setForceDownload(true);
|
||||||
|
|
||||||
connect(m_dataModelDownloader, &DataModelDownloader::progressChanged, this, [this](){
|
connect(m_dataModelDownloader, &DataModelDownloader::progressChanged, this, [this](){
|
||||||
m_modeWidget->rootObject()->setProperty("loadingProgress", m_dataModelDownloader->progress());
|
m_quickWidget->rootObject()->setProperty("loadingProgress", m_dataModelDownloader->progress());
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_dataModelDownloader, &DataModelDownloader::finished, this, [this](){
|
m_quickWidget->setEnabled(false);
|
||||||
auto source = m_modeWidget->source();
|
|
||||||
m_modeWidget->engine()->clearComponentCache();
|
connect(m_dataModelDownloader, &DataModelDownloader::finished, this, [this, welcomePagePath]() {
|
||||||
m_modeWidget->setSource(source);
|
delete m_quickWidget;
|
||||||
m_modeWidget->rootObject()->setProperty("loadingProgress", 100);
|
createQuickWidget();
|
||||||
|
setupQuickWidget(welcomePagePath);
|
||||||
|
m_modeWidget->layout()->addWidget(m_quickWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
m_dataModelDownloader->start();
|
connect(m_dataModelDownloader, &DataModelDownloader::downloadFailed, this, [this]() {
|
||||||
|
m_quickWidget->setEnabled(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (m_dataModelDownloader->start())
|
||||||
|
m_quickWidget->setEnabled(false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, this, [this](Utils::Id mode){
|
connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged, this, [this](Utils::Id mode){
|
||||||
@@ -669,36 +673,14 @@ WelcomeMode::WelcomeMode()
|
|||||||
m_modeWidget->rootObject()->setProperty("active", active);
|
m_modeWidget->rootObject()->setProperty("active", active);
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
setupQuickWidget(welcomePagePath);
|
||||||
|
|
||||||
if (!useNewWelcomePage()) {
|
QVBoxLayout *boxLayout = new QVBoxLayout();
|
||||||
|
boxLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
#ifdef QT_DEBUG
|
|
||||||
m_modeWidget->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH)
|
|
||||||
+ "welcomepage/imports");
|
|
||||||
m_modeWidget->setSource(QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH)
|
|
||||||
+ "welcomepage/main.qml"));
|
|
||||||
#else
|
|
||||||
m_modeWidget->engine()->addImportPath("qrc:/qml/welcomepage/imports");
|
|
||||||
m_modeWidget->setSource(QUrl("qrc:/qml/welcomepage/main.qml"));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
|
|
||||||
m_modeWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
|
||||||
|
|
||||||
m_modeWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
|
||||||
m_modeWidget->engine()->addImportPath(m_dataModelDownloader->targetFolder().toString());
|
|
||||||
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
|
||||||
|
|
||||||
QShortcut *updateShortcut = nullptr;
|
|
||||||
if (Utils::HostOsInfo::isMacHost())
|
|
||||||
updateShortcut = new QShortcut(QKeySequence(Qt::ALT | Qt::Key_F5), m_modeWidget);
|
|
||||||
else
|
|
||||||
updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F5), m_modeWidget);
|
|
||||||
connect(updateShortcut, &QShortcut::activated, this, [this, welcomePagePath](){
|
|
||||||
m_modeWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
m_modeWidget = new QWidget;
|
||||||
|
m_modeWidget->setLayout(boxLayout);
|
||||||
|
boxLayout->addWidget(m_quickWidget);
|
||||||
setWidget(m_modeWidget);
|
setWidget(m_modeWidget);
|
||||||
|
|
||||||
QStringList designStudioQchPathes
|
QStringList designStudioQchPathes
|
||||||
@@ -749,6 +731,51 @@ WelcomeMode::~WelcomeMode()
|
|||||||
delete m_modeWidget;
|
delete m_modeWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WelcomeMode::setupQuickWidget(const QString &welcomePagePath)
|
||||||
|
{
|
||||||
|
if (!useNewWelcomePage()) {
|
||||||
|
|
||||||
|
#ifdef QT_DEBUG
|
||||||
|
m_quickWidget->engine()->addImportPath(QLatin1String(STUDIO_QML_PATH)
|
||||||
|
+ "welcomepage/imports");
|
||||||
|
m_quickWidget->setSource(
|
||||||
|
QUrl::fromLocalFile(QLatin1String(STUDIO_QML_PATH) + "welcomepage/main.qml"));
|
||||||
|
#else
|
||||||
|
m_quickWidget->engine()->addImportPath("qrc:/qml/welcomepage/imports");
|
||||||
|
m_quickWidget->setSource(QUrl("qrc:/qml/welcomepage/main.qml"));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
|
||||||
|
m_quickWidget->engine()->addImportPath(Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources/imports").toString());
|
||||||
|
|
||||||
|
m_quickWidget->engine()->addImportPath(welcomePagePath + "/imports");
|
||||||
|
m_quickWidget->engine()->addImportPath(m_dataModelDownloader->targetFolder().toString());
|
||||||
|
m_quickWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
||||||
|
|
||||||
|
QShortcut *updateShortcut = nullptr;
|
||||||
|
if (Utils::HostOsInfo::isMacHost())
|
||||||
|
updateShortcut = new QShortcut(QKeySequence(Qt::ALT | Qt::Key_F5), m_quickWidget);
|
||||||
|
else
|
||||||
|
updateShortcut = new QShortcut(QKeySequence(Qt::CTRL | Qt::Key_F5), m_quickWidget);
|
||||||
|
connect(updateShortcut, &QShortcut::activated, this, [this, welcomePagePath](){
|
||||||
|
m_quickWidget->setSource(QUrl::fromLocalFile(welcomePagePath + "/main.qml"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WelcomeMode::createQuickWidget()
|
||||||
|
{
|
||||||
|
m_quickWidget = new QQuickWidget;
|
||||||
|
m_quickWidget->setMinimumSize(640, 480);
|
||||||
|
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
QmlDesigner::Theme::setupTheme(m_quickWidget->engine());
|
||||||
|
m_quickWidget->engine()->addImportPath("qrc:/studiofonts");
|
||||||
|
|
||||||
|
QmlDesigner::QmlDesignerPlugin::registerPreviewImageProvider(m_quickWidget->engine());
|
||||||
|
|
||||||
|
m_quickWidget->engine()->setOutputWarningsToStandardError(false);
|
||||||
|
}
|
||||||
|
|
||||||
StudioSettingsPage::StudioSettingsPage()
|
StudioSettingsPage::StudioSettingsPage()
|
||||||
: m_buildCheckBox(new QCheckBox(tr("Build")))
|
: m_buildCheckBox(new QCheckBox(tr("Build")))
|
||||||
, m_debugCheckBox(new QCheckBox(tr("Debug")))
|
, m_debugCheckBox(new QCheckBox(tr("Debug")))
|
||||||
|
Submodule src/shared/qbs updated: faac35b5b3...3e0553e465
Reference in New Issue
Block a user