forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/7.0' into 8.0" into 8.0
This commit is contained in:
@@ -28,6 +28,8 @@
|
||||
#include <QSize>
|
||||
#include <QUrl>
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
#include <QColor>
|
||||
#include <qmetatype.h>
|
||||
|
||||
#include "instancecontainer.h"
|
||||
@@ -58,7 +60,8 @@ public:
|
||||
const QString &language,
|
||||
QSize captureImageMinimumSize,
|
||||
QSize captureImageMaximumSize,
|
||||
qint32 stateInstanceId)
|
||||
qint32 stateInstanceId,
|
||||
const QList<QColor> &edit3dBackgroundColor)
|
||||
: instances(instanceContainer)
|
||||
, reparentInstances(reparentContainer)
|
||||
, ids(idVector)
|
||||
@@ -74,6 +77,7 @@ public:
|
||||
, captureImageMinimumSize(captureImageMinimumSize)
|
||||
, captureImageMaximumSize(captureImageMaximumSize)
|
||||
, stateInstanceId{stateInstanceId}
|
||||
, edit3dBackgroundColor{edit3dBackgroundColor}
|
||||
{}
|
||||
|
||||
friend QDataStream &operator<<(QDataStream &out, const CreateSceneCommand &command)
|
||||
@@ -93,6 +97,7 @@ public:
|
||||
out << command.stateInstanceId;
|
||||
out << command.captureImageMinimumSize;
|
||||
out << command.captureImageMaximumSize;
|
||||
out << command.edit3dBackgroundColor;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -114,6 +119,7 @@ public:
|
||||
in >> command.stateInstanceId;
|
||||
in >> command.captureImageMinimumSize;
|
||||
in >> command.captureImageMaximumSize;
|
||||
in >> command.edit3dBackgroundColor;
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -134,6 +140,7 @@ public:
|
||||
QSize captureImageMinimumSize;
|
||||
QSize captureImageMaximumSize;
|
||||
qint32 stateInstanceId = 0;
|
||||
QList<QColor> edit3dBackgroundColor;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, const CreateSceneCommand &command);
|
||||
|
@@ -30,24 +30,27 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
View3DActionCommand::View3DActionCommand(Type type, bool enable)
|
||||
View3DActionCommand::View3DActionCommand(Type type, const QVariant &value)
|
||||
: m_type(type)
|
||||
, m_enabled(enable)
|
||||
, m_position(0)
|
||||
, m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
View3DActionCommand::View3DActionCommand(int pos)
|
||||
: m_type(ParticlesSeek)
|
||||
, m_enabled(true)
|
||||
, m_position(pos)
|
||||
, m_value(pos)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool View3DActionCommand::isEnabled() const
|
||||
{
|
||||
return m_enabled;
|
||||
return m_value.toBool();
|
||||
}
|
||||
|
||||
QVariant View3DActionCommand::value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
View3DActionCommand::Type View3DActionCommand::type() const
|
||||
@@ -57,29 +60,32 @@ View3DActionCommand::Type View3DActionCommand::type() const
|
||||
|
||||
int View3DActionCommand::position() const
|
||||
{
|
||||
return m_position;
|
||||
bool ok = false;
|
||||
int result = m_value.toInt(&ok);
|
||||
if (!ok) {
|
||||
qWarning() << "View3DActionCommand: returning a position that is not int; command type = "
|
||||
<< m_type;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const View3DActionCommand &command)
|
||||
{
|
||||
out << qint32(command.isEnabled());
|
||||
out << command.value();
|
||||
out << qint32(command.type());
|
||||
out << qint32(command.position());
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, View3DActionCommand &command)
|
||||
{
|
||||
qint32 enabled;
|
||||
QVariant value;
|
||||
qint32 type;
|
||||
qint32 pos;
|
||||
in >> enabled;
|
||||
in >> value;
|
||||
in >> type;
|
||||
in >> pos;
|
||||
command.m_enabled = bool(enabled);
|
||||
command.m_value = value;
|
||||
command.m_type = View3DActionCommand::Type(type);
|
||||
command.m_position = pos;
|
||||
|
||||
return in;
|
||||
}
|
||||
@@ -88,7 +94,7 @@ QDebug operator<<(QDebug debug, const View3DActionCommand &command)
|
||||
{
|
||||
return debug.nospace() << "View3DActionCommand(type: "
|
||||
<< command.m_type << ","
|
||||
<< command.m_enabled << ")";
|
||||
<< command.m_value << ")\n";
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QVariant>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
@@ -55,20 +56,22 @@ public:
|
||||
ParticlesPlay,
|
||||
ParticlesRestart,
|
||||
ParticlesSeek,
|
||||
SelectBackgroundColor,
|
||||
ResetBackgroundColor,
|
||||
};
|
||||
|
||||
explicit View3DActionCommand(Type type, bool enable);
|
||||
explicit View3DActionCommand(Type type, const QVariant &value);
|
||||
|
||||
View3DActionCommand() = default;
|
||||
|
||||
bool isEnabled() const;
|
||||
QVariant value() const;
|
||||
Type type() const;
|
||||
int position() const;
|
||||
|
||||
private:
|
||||
Type m_type = Empty;
|
||||
bool m_enabled = false;
|
||||
int m_position = 0;
|
||||
QVariant m_value;
|
||||
|
||||
protected:
|
||||
View3DActionCommand(int pos);
|
||||
|
@@ -32,7 +32,6 @@
|
||||
<file>mockfiles/qt6/FadeHandle.qml</file>
|
||||
<file>mockfiles/qt6/HelperGrid.qml</file>
|
||||
<file>mockfiles/qt6/IconGizmo.qml</file>
|
||||
<file>mockfiles/qt6/IconRenderer3D.qml</file>
|
||||
<file>mockfiles/qt6/LightGizmo.qml</file>
|
||||
<file>mockfiles/qt6/LightIconGizmo.qml</file>
|
||||
<file>mockfiles/qt6/LightModel.qml</file>
|
||||
|
@@ -142,6 +142,7 @@ void NodeInstanceServerInterface::registerCommands()
|
||||
registerCommand<View3DActionCommand>("View3DActionCommand");
|
||||
registerCommand<RequestModelNodePreviewImageCommand>("RequestModelNodePreviewImageCommand");
|
||||
registerCommand<QPair<int, int>>("QPairIntInt");
|
||||
registerCommand<QList<QColor>>("QColorList");
|
||||
registerCommand<ChangeLanguageCommand>("ChangeLanguageCommand");
|
||||
registerCommand<ChangePreviewImageSizeCommand>("ChangePreviewImageSizeCommand");
|
||||
registerCommand<CapturedDataCommand>("CapturedDataCommand");
|
||||
|
@@ -45,6 +45,8 @@ Item {
|
||||
property bool usePerspective: true
|
||||
property bool globalOrientation: false
|
||||
property alias contentItem: contentItem
|
||||
property color backgroundGradientColorStart: "#222222"
|
||||
property color backgroundGradientColorEnd: "#999999"
|
||||
|
||||
enum SelectionMode { Item, Group }
|
||||
enum TransformMode { Move, Rotate, Scale }
|
||||
@@ -212,6 +214,15 @@ Item {
|
||||
cameraControl.alignView(selectedNodes);
|
||||
}
|
||||
|
||||
function updateViewStates(viewStates)
|
||||
{
|
||||
if ("selectBackgroundColor" in viewStates) {
|
||||
var color = viewStates.selectBackgroundColor
|
||||
backgroundGradientColorStart = color[0];
|
||||
backgroundGradientColorEnd = color[1];
|
||||
}
|
||||
}
|
||||
|
||||
// If resetToDefault is true, tool states not specifically set to anything will be reset to
|
||||
// their default state.
|
||||
function updateToolStates(toolStates, resetToDefault)
|
||||
@@ -329,6 +340,15 @@ Item {
|
||||
|
||||
function handleObjectClicked(object, multi)
|
||||
{
|
||||
if (object instanceof View3D) {
|
||||
// View3D can be the resolved pick target in case the 3D editor is showing content
|
||||
// of a component that has View3D as root. In that case locking is resolved on C++ side
|
||||
// and we ignore multiselection.
|
||||
selectObjects([]);
|
||||
selectionChanged([object]);
|
||||
return;
|
||||
}
|
||||
|
||||
var clickedObject;
|
||||
|
||||
// Click on locked object is treated same as click on empty space
|
||||
@@ -721,8 +741,8 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
GradientStop { position: 1.0; color: backgroundGradientColorStart }
|
||||
GradientStop { position: 0.0; color: backgroundGradientColorEnd }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -740,7 +760,7 @@ Item {
|
||||
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
|
||||
mouse.modifiers & Qt.ControlModifier);
|
||||
|
||||
if (pickResult.objectHit) {
|
||||
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
|
||||
if (transformMode === EditView3D.TransformMode.Move)
|
||||
freeDraggerArea = moveGizmo.freeDraggerArea;
|
||||
else if (transformMode === EditView3D.TransformMode.Rotate)
|
||||
|
@@ -32,7 +32,7 @@ View3D {
|
||||
|
||||
property Material previewMaterial
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// No need to zoom this view, this is here just to avoid runtime warnings
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@ Item {
|
||||
property var modelViewComponent
|
||||
property var nodeViewComponent
|
||||
|
||||
property bool closeUp: false
|
||||
|
||||
function destroyView()
|
||||
{
|
||||
previewObject = null;
|
||||
@@ -96,7 +98,15 @@ Item {
|
||||
|
||||
function fitToViewPort()
|
||||
{
|
||||
view.fitToViewPort();
|
||||
view.fitToViewPort(closeUp);
|
||||
}
|
||||
|
||||
// Enables/disables icon mode. When in icon mode, camera is zoomed bit closer to reduce margins
|
||||
// and the background is removed, in order to generate a preview suitable for library icons.
|
||||
function setIconMode(enable)
|
||||
{
|
||||
closeUp = enable;
|
||||
backgroundRect.visible = !enable;
|
||||
}
|
||||
|
||||
View3D {
|
||||
@@ -108,10 +118,15 @@ Item {
|
||||
id: contentItem
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: viewRect
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: backgroundRect
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
|
@@ -34,11 +34,11 @@ View3D {
|
||||
|
||||
property Model sourceModel
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// The magic number is the distance from camera default pos to origin
|
||||
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, importScene, root,
|
||||
1040);
|
||||
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, sourceModel, root,
|
||||
1040, closeUp);
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
|
@@ -32,11 +32,11 @@ View3D {
|
||||
environment: sceneEnv
|
||||
camera: theCamera
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// The magic number is the distance from camera default pos to origin
|
||||
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, importScene, root,
|
||||
1040);
|
||||
1040, closeUp);
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
|
@@ -46,6 +46,8 @@ Item {
|
||||
property bool usePerspective: true
|
||||
property bool globalOrientation: false
|
||||
property alias contentItem: contentItem
|
||||
property color backgroundGradientColorStart: "#222222"
|
||||
property color backgroundGradientColorEnd: "#999999"
|
||||
|
||||
enum SelectionMode { Item, Group }
|
||||
enum TransformMode { Move, Rotate, Scale }
|
||||
@@ -206,6 +208,15 @@ Item {
|
||||
cameraControl.alignView(selectedNodes);
|
||||
}
|
||||
|
||||
function updateViewStates(viewStates)
|
||||
{
|
||||
if ("selectBackgroundColor" in viewStates) {
|
||||
var color = viewStates.selectBackgroundColor
|
||||
backgroundGradientColorStart = color[0];
|
||||
backgroundGradientColorEnd = color[1];
|
||||
}
|
||||
}
|
||||
|
||||
// If resetToDefault is true, tool states not specifically set to anything will be reset to
|
||||
// their default state.
|
||||
function updateToolStates(toolStates, resetToDefault)
|
||||
@@ -329,6 +340,15 @@ Item {
|
||||
|
||||
function handleObjectClicked(object, multi)
|
||||
{
|
||||
if (object instanceof View3D) {
|
||||
// View3D can be the resolved pick target in case the 3D editor is showing content
|
||||
// of a component that has View3D as root. In that case locking is resolved on C++ side
|
||||
// and we ignore multiselection.
|
||||
selectObjects([]);
|
||||
selectionChanged([object]);
|
||||
return;
|
||||
}
|
||||
|
||||
var clickedObject;
|
||||
|
||||
// Click on locked object is treated same as click on empty space
|
||||
@@ -866,8 +886,8 @@ Item {
|
||||
anchors.fill: parent
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
GradientStop { position: 1.0; color: backgroundGradientColorStart }
|
||||
GradientStop { position: 0.0; color: backgroundGradientColorEnd }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -892,7 +912,7 @@ Item {
|
||||
|
||||
handleObjectClicked(resolvedResult, mouse.modifiers & Qt.ControlModifier);
|
||||
|
||||
if (pickResult.objectHit) {
|
||||
if (pickResult.objectHit && pickResult.objectHit instanceof Node) {
|
||||
if (transformMode === EditView3D.TransformMode.Move)
|
||||
freeDraggerArea = moveGizmo.freeDraggerArea;
|
||||
else if (transformMode === EditView3D.TransformMode.Rotate)
|
||||
|
@@ -1,88 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** 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
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: viewRoot
|
||||
width: 1024
|
||||
height: 1024
|
||||
visible: true
|
||||
|
||||
property alias view3D: view3D
|
||||
property alias camPos: viewCamera.position
|
||||
|
||||
function setSceneToBox()
|
||||
{
|
||||
selectionBox.targetNode = view3D.importScene;
|
||||
}
|
||||
|
||||
function fitAndHideBox()
|
||||
{
|
||||
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true, true);
|
||||
if (cameraControl._zoomFactor < 0.1)
|
||||
view3D.importScene.scale = view3D.importScene.scale.times(10);
|
||||
if (cameraControl._zoomFactor > 10)
|
||||
view3D.importScene.scale = view3D.importScene.scale.times(0.1);
|
||||
|
||||
selectionBox.visible = false;
|
||||
}
|
||||
|
||||
View3D {
|
||||
id: view3D
|
||||
camera: viewCamera
|
||||
environment: sceneEnv
|
||||
|
||||
SceneEnvironment {
|
||||
id: sceneEnv
|
||||
antialiasingMode: SceneEnvironment.MSAA
|
||||
antialiasingQuality: SceneEnvironment.VeryHigh
|
||||
}
|
||||
|
||||
PerspectiveCamera {
|
||||
id: viewCamera
|
||||
position: Qt.vector3d(-200, 200, 200)
|
||||
eulerRotation: Qt.vector3d(-45, -45, 0)
|
||||
}
|
||||
|
||||
DirectionalLight {
|
||||
rotation: viewCamera.rotation
|
||||
}
|
||||
|
||||
SelectionBox {
|
||||
id: selectionBox
|
||||
view3D: view3D
|
||||
geometryName: "SB"
|
||||
}
|
||||
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
camera: view3D.camera
|
||||
view3d: view3D
|
||||
ignoreToolState: true
|
||||
}
|
||||
}
|
||||
}
|
@@ -32,7 +32,7 @@ View3D {
|
||||
|
||||
property Material previewMaterial
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// No need to zoom this view, this is here just to avoid runtime warnings
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@ Item {
|
||||
property var modelViewComponent
|
||||
property var nodeViewComponent
|
||||
|
||||
property bool closeUp: false
|
||||
|
||||
function destroyView()
|
||||
{
|
||||
previewObject = null;
|
||||
@@ -96,17 +98,30 @@ Item {
|
||||
|
||||
function fitToViewPort()
|
||||
{
|
||||
view.fitToViewPort();
|
||||
view.fitToViewPort(closeUp);
|
||||
}
|
||||
|
||||
// Enables/disables icon mode. When in icon mode, camera is zoomed bit closer to reduce margins
|
||||
// and the background is removed, in order to generate a preview suitable for library icons.
|
||||
function setIconMode(enable)
|
||||
{
|
||||
closeUp = enable;
|
||||
backgroundRect.visible = !enable;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
Item {
|
||||
id: viewRect
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: backgroundRect
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
|
@@ -34,11 +34,11 @@ View3D {
|
||||
|
||||
property Model sourceModel
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// The magic number is the distance from camera default pos to origin
|
||||
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, sourceModel, root,
|
||||
1040);
|
||||
1040, closeUp);
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
|
@@ -32,11 +32,11 @@ View3D {
|
||||
environment: sceneEnv
|
||||
camera: theCamera
|
||||
|
||||
function fitToViewPort()
|
||||
function fitToViewPort(closeUp)
|
||||
{
|
||||
// The magic number is the distance from camera default pos to origin
|
||||
_generalHelper.calculateNodeBoundsAndFocusCamera(theCamera, importScene, root,
|
||||
1040);
|
||||
1040, closeUp);
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
|
@@ -308,7 +308,7 @@ QVector4D GeneralHelper::focusNodesToCamera(QQuick3DCamera *camera, float defaul
|
||||
// and recalculating bounds for every frame is not a problem.
|
||||
void GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
||||
QQuick3DCamera *camera, QQuick3DNode *node, QQuick3DViewport *viewPort,
|
||||
float defaultLookAtDistance)
|
||||
float defaultLookAtDistance, bool closeUp)
|
||||
{
|
||||
QVector3D minBounds;
|
||||
QVector3D maxBounds;
|
||||
@@ -317,7 +317,9 @@ void GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
||||
|
||||
QVector3D extents = maxBounds - minBounds;
|
||||
QVector3D lookAt = minBounds + (extents / 2.f);
|
||||
float maxExtent = qMax(extents.x(), qMax(extents.y(), extents.z()));
|
||||
float maxExtent = qSqrt(qreal(extents.x()) * qreal(extents.x())
|
||||
+ qreal(extents.y()) * qreal(extents.y())
|
||||
+ qreal(extents.z()) * qreal(extents.z()));
|
||||
|
||||
// Reset camera position to default zoom
|
||||
QMatrix4x4 m = camera->sceneTransform();
|
||||
@@ -328,9 +330,27 @@ void GeneralHelper::calculateNodeBoundsAndFocusCamera(
|
||||
|
||||
camera->setPosition(lookAt + newLookVector);
|
||||
|
||||
float newZoomFactor = maxExtent / 725.f; // Divisor taken from focusNodesToCamera function
|
||||
// CloseUp divisor is used for icon generation, where we can allow some extreme models to go
|
||||
// slightly out of bounds for better results generally. The other divisor is used for other
|
||||
// previews, where the image is larger to begin with and we would also like some margin
|
||||
// between preview edge and the rendered model, so we can be more conservative with the zoom.
|
||||
// The divisor values are empirically selected to provide nice result.
|
||||
float divisor = closeUp ? 1250.f : 1050.f;
|
||||
float newZoomFactor = maxExtent / divisor;
|
||||
|
||||
zoomCamera(viewPort, camera, 0, defaultLookAtDistance, lookAt, newZoomFactor, false);
|
||||
|
||||
if (auto perspectiveCamera = qobject_cast<QQuick3DPerspectiveCamera *>(camera)) {
|
||||
// Fix camera near/far clips in case we are dealing with extreme zooms
|
||||
const float cameraDist = qAbs((camera->position() - lookAt).length());
|
||||
const float minDist = cameraDist - (maxExtent / 2.f);
|
||||
const float maxDist = cameraDist + (maxExtent / 2.f);
|
||||
if (minDist < perspectiveCamera->clipNear() || maxDist > perspectiveCamera->clipFar()) {
|
||||
perspectiveCamera->setClipNear(minDist * 0.99);
|
||||
perspectiveCamera->setClipFar(maxDist * 1.01);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Aligns any cameras found in nodes list to a camera.
|
||||
@@ -418,15 +438,15 @@ QQuick3DPickResult GeneralHelper::pickViewAt(QQuick3DViewport *view, float posX,
|
||||
return QQuick3DPickResult();
|
||||
}
|
||||
|
||||
QQuick3DNode *GeneralHelper::resolvePick(QQuick3DNode *pickNode)
|
||||
QObject *GeneralHelper::resolvePick(QQuick3DNode *pickNode)
|
||||
{
|
||||
if (pickNode) {
|
||||
// Check if the picked node actually specifies another node as the pick target
|
||||
// Check if the picked node actually specifies another object as the pick target
|
||||
QVariant componentVar = pickNode->property("_pickTarget");
|
||||
if (componentVar.isValid()) {
|
||||
auto componentNode = componentVar.value<QQuick3DNode *>();
|
||||
if (componentNode)
|
||||
return componentNode;
|
||||
auto componentObj = componentVar.value<QObject *>();
|
||||
if (componentObj)
|
||||
return componentObj;
|
||||
}
|
||||
}
|
||||
return pickNode;
|
||||
@@ -823,12 +843,13 @@ bool GeneralHelper::getBounds(QQuick3DViewport *view3D, QQuick3DNode *node, QVec
|
||||
if (auto childNode = qobject_cast<QQuick3DNode *>(child)) {
|
||||
QVector3D newMinBounds = minBounds;
|
||||
QVector3D newMaxBounds = maxBounds;
|
||||
hasModel = getBounds(view3D, childNode, newMinBounds, newMaxBounds, true);
|
||||
bool childHasModel = getBounds(view3D, childNode, newMinBounds, newMaxBounds, true);
|
||||
// Ignore any subtrees that do not have Model in them as we don't need those
|
||||
// for visual bounds calculations
|
||||
if (hasModel) {
|
||||
if (childHasModel) {
|
||||
minBoundsVec << newMinBounds;
|
||||
maxBoundsVec << newMaxBounds;
|
||||
hasModel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,7 +77,7 @@ public:
|
||||
bool closeUp = false);
|
||||
Q_INVOKABLE void calculateNodeBoundsAndFocusCamera(QQuick3DCamera *camera, QQuick3DNode *node,
|
||||
QQuick3DViewport *viewPort,
|
||||
float defaultLookAtDistance);
|
||||
float defaultLookAtDistance, bool closeUp);
|
||||
Q_INVOKABLE void alignCameras(QQuick3DCamera *camera, const QVariant &nodes);
|
||||
Q_INVOKABLE QVector3D alignView(QQuick3DCamera *camera, const QVariant &nodes,
|
||||
const QVector3D &lookAtPoint);
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
Q_INVOKABLE void delayedPropertySet(QObject *obj, int delay, const QString &property,
|
||||
const QVariant& value);
|
||||
Q_INVOKABLE QQuick3DPickResult pickViewAt(QQuick3DViewport *view, float posX, float posY);
|
||||
Q_INVOKABLE QQuick3DNode *resolvePick(QQuick3DNode *pickNode);
|
||||
Q_INVOKABLE QObject *resolvePick(QQuick3DNode *pickNode);
|
||||
|
||||
Q_INVOKABLE bool isLocked(QQuick3DNode *node) const;
|
||||
Q_INVOKABLE bool isHidden(QQuick3DNode *node) const;
|
||||
|
@@ -77,9 +77,8 @@ void import3D(const QString &sourceAsset, const QString &outDir, const QString &
|
||||
}
|
||||
}
|
||||
|
||||
// Allow little time for file operations to finish
|
||||
QTimer::singleShot(2000, nullptr, []() {
|
||||
qApp->exit(0);
|
||||
QTimer::singleShot(0, nullptr, []() {
|
||||
qApp->quit();
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1561,6 +1561,10 @@ void NodeInstanceServer::handleInstanceHidden(const ServerNodeInstance &/*instan
|
||||
{
|
||||
}
|
||||
|
||||
void NodeInstanceServer::handlePickTarget(const ServerNodeInstance &/*instance*/)
|
||||
{
|
||||
}
|
||||
|
||||
void NodeInstanceServer::setupState(qint32 stateInstanceId)
|
||||
{
|
||||
if (hasInstanceForId(stateInstanceId)) {
|
||||
|
@@ -226,6 +226,7 @@ public:
|
||||
|
||||
virtual void handleInstanceLocked(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||
virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors);
|
||||
virtual void handlePickTarget(const ServerNodeInstance &instance);
|
||||
|
||||
virtual QImage grabWindow() = 0;
|
||||
virtual QImage grabItem(QQuickItem *item) = 0;
|
||||
|
@@ -553,7 +553,18 @@ void Qt5InformationNodeInstanceServer::handleSelectionChanged(const QVariant &ob
|
||||
auto obj = object.value<QObject *>();
|
||||
if (obj) {
|
||||
ServerNodeInstance instance = instanceForObject(obj);
|
||||
instanceList << instance;
|
||||
// If instance is a View3D, make sure it is not locked
|
||||
bool locked = false;
|
||||
if (instance.isSubclassOf("QQuick3DViewport")) {
|
||||
locked = instance.internalInstance()->isLockedInEditor();
|
||||
auto parentInst = instance.parent();
|
||||
while (!locked && parentInst.isValid()) {
|
||||
locked = parentInst.internalInstance()->isLockedInEditor();
|
||||
parentInst = parentInst.parent();
|
||||
}
|
||||
}
|
||||
if (!locked)
|
||||
instanceList << instance;
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
if (!skipSystemDeselect) {
|
||||
auto particleSystem = parentParticleSystem(instance.internalObject());
|
||||
@@ -1452,8 +1463,9 @@ void Qt5InformationNodeInstanceServer::handleSelectionChangeTimeout()
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handleDynamicAddObjectTimeout()
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
for (auto obj : std::as_const(m_dynamicObjectConstructors)) {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
|
||||
#ifdef QUICK3D_MODULE
|
||||
auto handleHiding = [this](QQuick3DNode *node) -> bool {
|
||||
if (node && hasInstanceForObject(node)) {
|
||||
ServerNodeInstance instance = instanceForObject(node);
|
||||
@@ -1468,8 +1480,22 @@ void Qt5InformationNodeInstanceServer::handleDynamicAddObjectTimeout()
|
||||
if (auto pickTarget = obj->property("_pickTarget").value<QQuick3DNode *>())
|
||||
handleHiding(pickTarget);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
auto handlePicking = [this](QObject *object) -> bool {
|
||||
if (object && hasInstanceForObject(object)) {
|
||||
ServerNodeInstance instance = instanceForObject(object);
|
||||
handlePickTarget(instance);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (!handlePicking(obj)) {
|
||||
if (auto pickTarget = obj->property("_pickTarget").value<QObject *>())
|
||||
handlePicking(pickTarget);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
m_dynamicObjectConstructors.clear();
|
||||
}
|
||||
|
||||
@@ -1932,6 +1958,12 @@ void Qt5InformationNodeInstanceServer::createScene(const CreateSceneCommand &com
|
||||
#ifdef IMPORT_QUICK3D_ASSETS
|
||||
QTimer::singleShot(0, this, &Qt5InformationNodeInstanceServer::resolveImportSupport);
|
||||
#endif
|
||||
|
||||
if (!command.edit3dBackgroundColor.isEmpty()) {
|
||||
View3DActionCommand backgroundColorCommand(View3DActionCommand::SelectBackgroundColor,
|
||||
QVariant::fromValue(command.edit3dBackgroundColor));
|
||||
view3DAction(backgroundColorCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> &childList)
|
||||
@@ -2147,18 +2179,19 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
if (!m_editView3DSetupDone)
|
||||
return;
|
||||
|
||||
QVariantMap updatedState;
|
||||
QVariantMap updatedToolState;
|
||||
QVariantMap updatedViewState;
|
||||
int renderCount = 1;
|
||||
|
||||
switch (command.type()) {
|
||||
case View3DActionCommand::MoveTool:
|
||||
updatedState.insert("transformMode", 0);
|
||||
updatedToolState.insert("transformMode", 0);
|
||||
break;
|
||||
case View3DActionCommand::RotateTool:
|
||||
updatedState.insert("transformMode", 1);
|
||||
updatedToolState.insert("transformMode", 1);
|
||||
break;
|
||||
case View3DActionCommand::ScaleTool:
|
||||
updatedState.insert("transformMode", 2);
|
||||
updatedToolState.insert("transformMode", 2);
|
||||
break;
|
||||
case View3DActionCommand::FitToView:
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "fitToView");
|
||||
@@ -2170,38 +2203,42 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "alignViewToCamera");
|
||||
break;
|
||||
case View3DActionCommand::SelectionModeToggle:
|
||||
updatedState.insert("selectionMode", command.isEnabled() ? 1 : 0);
|
||||
updatedToolState.insert("selectionMode", command.isEnabled() ? 1 : 0);
|
||||
break;
|
||||
case View3DActionCommand::CameraToggle:
|
||||
updatedState.insert("usePerspective", command.isEnabled());
|
||||
updatedToolState.insert("usePerspective", command.isEnabled());
|
||||
// It can take a couple frames to properly update icon gizmo positions
|
||||
renderCount = 2;
|
||||
break;
|
||||
case View3DActionCommand::OrientationToggle:
|
||||
updatedState.insert("globalOrientation", command.isEnabled());
|
||||
updatedToolState.insert("globalOrientation", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::EditLightToggle:
|
||||
updatedState.insert("showEditLight", command.isEnabled());
|
||||
updatedToolState.insert("showEditLight", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ShowGrid:
|
||||
updatedState.insert("showGrid", command.isEnabled());
|
||||
updatedToolState.insert("showGrid", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ShowSelectionBox:
|
||||
updatedState.insert("showSelectionBox", command.isEnabled());
|
||||
updatedToolState.insert("showSelectionBox", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ShowIconGizmo:
|
||||
updatedState.insert("showIconGizmo", command.isEnabled());
|
||||
updatedToolState.insert("showIconGizmo", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ShowCameraFrustum:
|
||||
updatedState.insert("showCameraFrustum", command.isEnabled());
|
||||
updatedToolState.insert("showCameraFrustum", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::SelectBackgroundColor: {
|
||||
updatedViewState.insert("selectBackgroundColor", command.value());
|
||||
break;
|
||||
}
|
||||
#ifdef QUICK3D_PARTICLES_MODULE
|
||||
case View3DActionCommand::ShowParticleEmitter:
|
||||
updatedState.insert("showParticleEmitter", command.isEnabled());
|
||||
updatedToolState.insert("showParticleEmitter", command.isEnabled());
|
||||
break;
|
||||
case View3DActionCommand::ParticlesPlay:
|
||||
m_particleAnimationPlaying = command.isEnabled();
|
||||
updatedState.insert("particlePlay", command.isEnabled());
|
||||
updatedToolState.insert("particlePlay", command.isEnabled());
|
||||
if (m_particleAnimationPlaying) {
|
||||
m_particleAnimationDriver->play();
|
||||
m_particleAnimationDriver->setSeekerEnabled(false);
|
||||
@@ -2227,12 +2264,17 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
break;
|
||||
}
|
||||
|
||||
if (!updatedState.isEmpty()) {
|
||||
if (!updatedToolState.isEmpty()) {
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateToolStates",
|
||||
Q_ARG(QVariant, updatedState),
|
||||
Q_ARG(QVariant, updatedToolState),
|
||||
Q_ARG(QVariant, QVariant::fromValue(false)));
|
||||
}
|
||||
|
||||
if (!updatedViewState.isEmpty()) {
|
||||
QMetaObject::invokeMethod(m_editView3DData.rootItem, "updateViewStates",
|
||||
Q_ARG(QVariant, updatedViewState));
|
||||
}
|
||||
|
||||
render3DEditView(renderCount);
|
||||
}
|
||||
|
||||
@@ -2332,9 +2374,9 @@ void Qt5InformationNodeInstanceServer::handleInstanceLocked(const ServerNodeInst
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(instance);
|
||||
Q_UNUSED(enable);
|
||||
Q_UNUSED(checkAncestors);
|
||||
Q_UNUSED(instance)
|
||||
Q_UNUSED(enable)
|
||||
Q_UNUSED(checkAncestors)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2388,6 +2430,7 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
|
||||
// Don't override explicit hide in children
|
||||
handleInstanceHidden(quick3dInstance, edit3dHidden || isInstanceHidden, false);
|
||||
} else {
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
|
||||
// Children of components do not have instances, but will still need to be pickable
|
||||
std::function<void(QQuick3DNode *)> checkChildren;
|
||||
checkChildren = [&](QQuick3DNode *checkNode) {
|
||||
@@ -2402,9 +2445,7 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
|
||||
value = QVariant::fromValue(node);
|
||||
// Specify the actual pick target with dynamic property
|
||||
checkModel->setProperty("_pickTarget", value);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
|
||||
checkModel->setPickable(!edit3dHidden);
|
||||
#endif
|
||||
} else {
|
||||
auto checkRepeater = qobject_cast<QQuick3DRepeater *>(checkNode);
|
||||
auto checkLoader = qobject_cast<QQuick3DLoader *>(checkNode);
|
||||
@@ -2436,13 +2477,102 @@ void Qt5InformationNodeInstanceServer::handleInstanceHidden(const ServerNodeInst
|
||||
};
|
||||
if (auto childNode = qobject_cast<QQuick3DNode *>(childItem))
|
||||
checkChildren(childNode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(instance);
|
||||
Q_UNUSED(enable);
|
||||
Q_UNUSED(checkAncestors);
|
||||
Q_UNUSED(instance)
|
||||
Q_UNUSED(enable)
|
||||
Q_UNUSED(checkAncestors)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::handlePickTarget(const ServerNodeInstance &instance)
|
||||
{
|
||||
#if defined(QUICK3D_MODULE) && (QT_VERSION >= QT_VERSION_CHECK(6, 2, 1))
|
||||
// Picking is dependent on hidden status prior to global picking support (<6.2.1), so it is
|
||||
// handled in handleInstanceHidden() method in those builds
|
||||
|
||||
if (!ViewConfig::isQuick3DMode())
|
||||
return;
|
||||
|
||||
QObject *obj = instance.internalObject();
|
||||
QList<QQuick3DObject *> childItems;
|
||||
if (auto node = qobject_cast<QQuick3DNode *>(obj)) {
|
||||
childItems = node->childItems();
|
||||
} else if (auto view = qobject_cast<QQuick3DViewport *>(obj)) {
|
||||
// We only need to handle views that are components
|
||||
// View is a component if its scene is not an instance and scene has node children that
|
||||
// have no instances
|
||||
QQuick3DNode *node = view->scene();
|
||||
if (node) {
|
||||
if (hasInstanceForObject(node))
|
||||
return;
|
||||
childItems = node->childItems();
|
||||
bool allHaveInstance = true;
|
||||
for (const auto &childItem : childItems) {
|
||||
if (qobject_cast<QQuick3DNode *>(childItem) && !hasInstanceForObject(childItem)) {
|
||||
allHaveInstance = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allHaveInstance)
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto childItem : qAsConst(childItems)) {
|
||||
if (!hasInstanceForObject(childItem)) {
|
||||
// Children of components do not have instances, but will still need to be pickable
|
||||
// and redirect their pick to the component
|
||||
std::function<void(QQuick3DNode *)> checkChildren;
|
||||
checkChildren = [&](QQuick3DNode *checkNode) {
|
||||
const auto childItems = checkNode->childItems();
|
||||
for (auto child : childItems) {
|
||||
if (auto childNode = qobject_cast<QQuick3DNode *>(child))
|
||||
checkChildren(childNode);
|
||||
}
|
||||
if (auto checkModel = qobject_cast<QQuick3DModel *>(checkNode)) {
|
||||
// Specify the actual pick target with dynamic property
|
||||
checkModel->setProperty("_pickTarget", QVariant::fromValue(obj));
|
||||
} else {
|
||||
auto checkRepeater = qobject_cast<QQuick3DRepeater *>(checkNode);
|
||||
auto checkLoader = qobject_cast<QQuick3DLoader *>(checkNode);
|
||||
#if defined(QUICK3D_ASSET_UTILS_MODULE)
|
||||
auto checkRunLoader = qobject_cast<QQuick3DRuntimeLoader *>(checkNode);
|
||||
if (checkRepeater || checkLoader || checkRunLoader) {
|
||||
#else
|
||||
if (checkRepeater || checkLoader) {
|
||||
#endif
|
||||
// Repeaters/loaders may not yet have created their children, so we set
|
||||
// _pickTarget on them and connect the notifier.
|
||||
if (checkNode->property("_pickTarget").isNull()) {
|
||||
if (checkRepeater) {
|
||||
QObject::connect(checkRepeater, &QQuick3DRepeater::objectAdded,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
#if defined(QUICK3D_ASSET_UTILS_MODULE)
|
||||
} else if (checkRunLoader) {
|
||||
QObject::connect(checkRunLoader, &QQuick3DRuntimeLoader::statusChanged,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
#endif
|
||||
} else {
|
||||
QObject::connect(checkLoader, &QQuick3DLoader::loaded,
|
||||
this, &Qt5InformationNodeInstanceServer::handleDynamicAddObject);
|
||||
}
|
||||
}
|
||||
checkNode->setProperty("_pickTarget", QVariant::fromValue(obj));
|
||||
}
|
||||
}
|
||||
};
|
||||
if (auto childNode = qobject_cast<QQuick3DNode *>(childItem))
|
||||
checkChildren(childNode);
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(instance)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -80,6 +80,7 @@ public:
|
||||
|
||||
void handleInstanceLocked(const ServerNodeInstance &instance, bool enable, bool checkAncestors) override;
|
||||
void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors) override;
|
||||
void handlePickTarget(const ServerNodeInstance &instance) override;
|
||||
|
||||
bool isInformationServer() const override;
|
||||
void handleDynamicAddObject();
|
||||
|
@@ -57,6 +57,9 @@ void Quick3DRenderableNodeInstance::initialize(const ObjectNodeInstance::Pointer
|
||||
// In case this is the scene root, we need to create a dummy View3D for the scene
|
||||
// in preview puppets
|
||||
if (instanceId() == 0 && (!nodeInstanceServer()->isInformationServer())) {
|
||||
nodeInstanceServer()->quickWindow()->setDefaultAlphaBuffer(true);
|
||||
nodeInstanceServer()->quickWindow()->setColor(Qt::transparent);
|
||||
|
||||
auto helper = new QmlDesigner::Internal::GeneralHelper();
|
||||
engine()->rootContext()->setContextProperty("_generalHelper", helper);
|
||||
|
||||
@@ -199,6 +202,14 @@ QQuickItem *Quick3DRenderableNodeInstance::contentItem() const
|
||||
return m_dummyRootView;
|
||||
}
|
||||
|
||||
void Quick3DRenderableNodeInstance::setPropertyVariant(const PropertyName &name,
|
||||
const QVariant &value)
|
||||
{
|
||||
if (m_dummyRootView && name == "isLibraryIcon")
|
||||
QMetaObject::invokeMethod(m_dummyRootView, "setIconMode", Q_ARG(QVariant, value));
|
||||
ObjectNodeInstance::setPropertyVariant(name, value);
|
||||
}
|
||||
|
||||
Qt5NodeInstanceServer *Quick3DRenderableNodeInstance::qt5NodeInstanceServer() const
|
||||
{
|
||||
return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer());
|
||||
|
@@ -52,6 +52,7 @@ public:
|
||||
QList<ServerNodeInstance> stateInstances() const override;
|
||||
|
||||
QQuickItem *contentItem() const override;
|
||||
void setPropertyVariant(const PropertyName &name, const QVariant &value) override;
|
||||
|
||||
protected:
|
||||
explicit Quick3DRenderableNodeInstance(QObject *node);
|
||||
|
@@ -323,8 +323,12 @@ ServerNodeInstance ServerNodeInstance::create(NodeInstanceServer *nodeInstanceSe
|
||||
|
||||
instance.internalInstance()->initialize(instance.m_nodeInstance, instanceContainer.metaFlags());
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 2, 1)
|
||||
// Handle hidden state to initialize pickable state
|
||||
nodeInstanceServer->handleInstanceHidden(instance, false, false);
|
||||
#else
|
||||
nodeInstanceServer->handlePickTarget(instance);
|
||||
#endif
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@ StudioControls.ComboBox {
|
||||
|
||||
onModelChanged: colorLogic.invalidate()
|
||||
|
||||
hasActiveDrag: comboBox.backendValue !== undefined && comboBox.backendValue.hasActiveDrag
|
||||
|
||||
// This is available in all editors.
|
||||
|
||||
onValueTypeChanged: {
|
||||
@@ -83,16 +85,15 @@ StudioControls.ComboBox {
|
||||
|
||||
onEntered: (drag) => {
|
||||
dropArea.assetPath = drag.getDataAsString(drag.keys[0]).split(",")[0]
|
||||
|
||||
drag.accepted = comboBox.backendValue !== undefined && comboBox.backendValue.isSupportedDrop(dropArea.assetPath)
|
||||
comboBox.hasActiveDrag = drag.accepted
|
||||
drag.accepted = comboBox.backendValue !== undefined && comboBox.backendValue.hasActiveDrag
|
||||
comboBox.hasActiveHoverDrag = drag.accepted
|
||||
}
|
||||
|
||||
onExited: comboBox.hasActiveDrag = false
|
||||
onExited: comboBox.hasActiveHoverDrag = false
|
||||
|
||||
onDropped: {
|
||||
comboBox.backendValue.commitDrop(dropArea.assetPath)
|
||||
comboBox.hasActiveDrag = false
|
||||
comboBox.hasActiveHoverDrag = false
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -39,7 +39,8 @@ T.ComboBox {
|
||||
&& myComboBox.enabled
|
||||
property bool edit: myComboBox.activeFocus && myComboBox.editable
|
||||
property bool open: comboBoxPopup.opened
|
||||
property bool hasActiveDrag: false
|
||||
property bool hasActiveDrag: false // an item that can be dropped on the combobox is being dragged
|
||||
property bool hasActiveHoverDrag: false // an item that can be dropped on the combobox is being hovered on the combobox
|
||||
|
||||
property bool dirty: false // user modification flag
|
||||
|
||||
@@ -49,6 +50,9 @@ T.ComboBox {
|
||||
|
||||
property alias textInput: comboBoxInput
|
||||
|
||||
property int borderWidth: myComboBox.hasActiveHoverDrag ? StudioTheme.Values.borderHover
|
||||
: StudioTheme.Values.border
|
||||
|
||||
signal compressedActivated(int index, int reason)
|
||||
|
||||
enum ActivatedReason { EditingFinished, Other }
|
||||
@@ -57,7 +61,7 @@ T.ComboBox {
|
||||
height: StudioTheme.Values.defaultControlHeight
|
||||
|
||||
leftPadding: actionIndicator.width
|
||||
rightPadding: popupIndicator.width + StudioTheme.Values.border
|
||||
rightPadding: popupIndicator.width + myComboBox.borderWidth
|
||||
font.pixelSize: StudioTheme.Values.myFontSize
|
||||
wheelEnabled: false
|
||||
|
||||
@@ -87,6 +91,7 @@ T.ComboBox {
|
||||
|
||||
myControl: myComboBox
|
||||
text: myComboBox.editText
|
||||
borderWidth: myComboBox.borderWidth
|
||||
|
||||
onEditingFinished: {
|
||||
comboBoxInput.deselect()
|
||||
@@ -108,16 +113,16 @@ T.ComboBox {
|
||||
myControl: myComboBox
|
||||
myPopup: myComboBox.popup
|
||||
x: comboBoxInput.x + comboBoxInput.width
|
||||
y: StudioTheme.Values.border
|
||||
width: StudioTheme.Values.checkIndicatorWidth - StudioTheme.Values.border
|
||||
height: StudioTheme.Values.checkIndicatorHeight - (StudioTheme.Values.border * 2)
|
||||
y: myComboBox.borderWidth
|
||||
width: StudioTheme.Values.checkIndicatorWidth - myComboBox.borderWidth
|
||||
height: StudioTheme.Values.checkIndicatorHeight - myComboBox.borderWidth * 2
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
id: comboBoxBackground
|
||||
color: StudioTheme.Values.themeControlBackground
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
border.width: myComboBox.borderWidth
|
||||
x: actionIndicator.width
|
||||
width: myComboBox.width - actionIndicator.width
|
||||
height: myComboBox.height
|
||||
@@ -144,7 +149,7 @@ T.ComboBox {
|
||||
width: comboBoxPopup.width - comboBoxPopup.leftPadding - comboBoxPopup.rightPadding
|
||||
- (comboBoxPopupScrollBar.visible ? comboBoxPopupScrollBar.contentItem.implicitWidth
|
||||
+ 2 : 0) // TODO Magic number
|
||||
height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
|
||||
height: StudioTheme.Values.height - 2 * myComboBox.borderWidth
|
||||
padding: 0
|
||||
enabled: model.enabled === undefined ? true : model.enabled
|
||||
|
||||
@@ -198,9 +203,9 @@ T.ComboBox {
|
||||
|
||||
popup: T.Popup {
|
||||
id: comboBoxPopup
|
||||
x: actionIndicator.width + StudioTheme.Values.border
|
||||
x: actionIndicator.width + myComboBox.borderWidth
|
||||
y: myComboBox.height
|
||||
width: myComboBox.width - actionIndicator.width - (StudioTheme.Values.border * 2)
|
||||
width: myComboBox.width - actionIndicator.width - myComboBox.borderWidth * 2
|
||||
// TODO Setting the height on the popup solved the problem with the popup of height 0,
|
||||
// but it has the problem that it sometimes extend over the border of the actual window
|
||||
// and is then cut off.
|
||||
@@ -208,7 +213,7 @@ T.ComboBox {
|
||||
+ comboBoxPopup.bottomPadding,
|
||||
myComboBox.Window.height - topMargin - bottomMargin,
|
||||
StudioTheme.Values.maxComboBoxPopupHeight)
|
||||
padding: StudioTheme.Values.border
|
||||
padding: myComboBox.borderWidth
|
||||
margins: 0 // If not defined margin will be -1
|
||||
closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent
|
||||
| T.Popup.CloseOnEscape | T.Popup.CloseOnReleaseOutside
|
||||
@@ -252,8 +257,9 @@ T.ComboBox {
|
||||
PropertyChanges {
|
||||
target: comboBoxBackground
|
||||
color: StudioTheme.Values.themeControlBackground
|
||||
border.color: hasActiveDrag ? StudioTheme.Values.themeInteraction
|
||||
: StudioTheme.Values.themeControlOutline
|
||||
border.color: myComboBox.hasActiveDrag ? StudioTheme.Values.themeInteraction
|
||||
: StudioTheme.Values.themeControlOutline
|
||||
border.width: myComboBox.borderWidth
|
||||
}
|
||||
},
|
||||
// This state is intended for ComboBoxes which aren't editable, but have focus e.g. via
|
||||
|
@@ -34,6 +34,7 @@ TextInput {
|
||||
|
||||
property bool edit: textInput.activeFocus
|
||||
property bool hover: mouseArea.containsMouse && textInput.enabled
|
||||
property int borderWidth: StudioTheme.Values.border
|
||||
|
||||
z: 2
|
||||
font: myControl.font
|
||||
@@ -55,11 +56,11 @@ TextInput {
|
||||
|
||||
Rectangle {
|
||||
id: textInputBackground
|
||||
x: StudioTheme.Values.border
|
||||
y: StudioTheme.Values.border
|
||||
x: textInput.borderWidth
|
||||
y: textInput.borderWidth
|
||||
z: -1
|
||||
width: textInput.width
|
||||
height: StudioTheme.Values.height - (StudioTheme.Values.border * 2)
|
||||
height: StudioTheme.Values.height - textInput.borderWidth * 2
|
||||
color: StudioTheme.Values.themeControlBackground
|
||||
border.width: 0
|
||||
}
|
||||
|
@@ -86,6 +86,7 @@ QtObject {
|
||||
|
||||
property real marginTopBottom: 4
|
||||
property real border: 1
|
||||
property real borderHover: 3
|
||||
|
||||
property real maxComboBoxPopupHeight: Math.round(300 * values.scaleFactor)
|
||||
property real maxTextAreaPopupHeight: Math.round(150 * values.scaleFactor)
|
||||
|
@@ -17,21 +17,23 @@
|
||||
{ "key": "ProjectPluginName", "value": "%{ProjectName}plugin" },
|
||||
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
|
||||
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "UIClassName", "value": "Screen01" },
|
||||
{ "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" },
|
||||
{ "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -243,21 +245,24 @@
|
||||
"trKey": "Qt 5",
|
||||
"value":
|
||||
"({
|
||||
'TargetQuickVersion': '2.15'
|
||||
'TargetQuickVersion': '2.15',
|
||||
'TargetQuick3DVersion': '1.15'
|
||||
})"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 6.2",
|
||||
"value":
|
||||
"({
|
||||
'TargetQuickVersion': '6.2'
|
||||
'TargetQuickVersion': '6.2',
|
||||
'TargetQuick3DVersion': '6.2'
|
||||
})"
|
||||
},
|
||||
{
|
||||
"trKey": "Qt 6.3",
|
||||
"value":
|
||||
"({
|
||||
'TargetQuickVersion': '6.3'
|
||||
'TargetQuickVersion': '6.3',
|
||||
'TargetQuick3DVersion': '6.3'
|
||||
})"
|
||||
}
|
||||
]
|
||||
|
@@ -20,20 +20,20 @@
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "UIClassName", "value": "Screen01" },
|
||||
{ "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('QtQuickVersion') === '' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "DefaultStyle", "value": "%{JS: value('QtQuickVersion') === '' ? 'Basic' : 'Default'}" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "DefaultStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? 'Basic' : 'Default'}" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
|
@@ -20,17 +20,19 @@
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "UIClassName", "value": "Screen01" },
|
||||
{ "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
@@ -235,7 +237,6 @@
|
||||
"data":
|
||||
{
|
||||
"index": 1,
|
||||
"items":
|
||||
"items":
|
||||
[
|
||||
{
|
||||
|
@@ -18,19 +18,19 @@
|
||||
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
|
||||
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "UIClassName", "value": "Screen01" },
|
||||
{ "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboard", "value": "%{JS: false}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
|
@@ -18,17 +18,19 @@
|
||||
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
|
||||
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboard", "value": "%{JS: false}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
|
@@ -18,17 +18,19 @@
|
||||
{ "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" },
|
||||
{ "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" },
|
||||
{ "key": "ImportModuleName", "value": "%{ProjectName}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" },
|
||||
{ "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" },
|
||||
{ "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt5", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyle}" },
|
||||
{ "key": "QtQuickControlsStyleInternalQt6", "value": "%{JS: value('QtQuickControlsStyleInternalQt5') === 'Default' ? 'Basic' : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyle", "value": "%{JS: value('IsQt6Project') === 'true' ? value('QtQuickControlsStyleInternalQt6') : value('QtQuickControlsStyleInternalQt5')}" },
|
||||
{ "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('QtQuickVersion') === '' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" },
|
||||
{ "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" },
|
||||
{ "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" },
|
||||
{ "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" },
|
||||
{ "key": "UseVirtualKeyboard", "value": "%{JS: false}" },
|
||||
{ "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') === '' }" },
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('QtQuickVersion') === '' ? '' : '1.0'}" }
|
||||
{ "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" }
|
||||
],
|
||||
|
||||
"pages":
|
||||
|
@@ -67,10 +67,7 @@ public:
|
||||
, m_stdErr(stdErr) {}
|
||||
QByteArray stdOut() const { return m_stdOut; }
|
||||
QByteArray stdErr() const { return m_stdErr; }
|
||||
void mergeWith(LauncherReadyReadSignal *newSignal) {
|
||||
m_stdOut += newSignal->stdOut();
|
||||
m_stdErr += newSignal->stdErr();
|
||||
}
|
||||
|
||||
private:
|
||||
QByteArray m_stdOut;
|
||||
QByteArray m_stdErr;
|
||||
@@ -203,31 +200,6 @@ void CallerHandle::appendSignal(LauncherSignal *newSignal)
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
QTC_ASSERT(isCalledFromLaunchersThread(), return);
|
||||
|
||||
// TODO: we might assert if the caller's state is proper, e.g.
|
||||
// start signal can't appear if we are in Running or NotRunning state,
|
||||
// or finish signal can't appear if we are in NotRunning or Starting state,
|
||||
// or readyRead signal can't appear if we are in NotRunning or Starting state,
|
||||
// or error signal can't appear if we are in NotRunning state
|
||||
// or FailedToStart error signal can't appear if we are in Running state
|
||||
// or other than FailedToStart error signal can't appear if we are in Starting state.
|
||||
if (!m_signals.isEmpty()) {
|
||||
LauncherSignal *lastSignal = m_signals.last();
|
||||
|
||||
QTC_ASSERT(lastSignal->signalType() != SignalType::Done,
|
||||
qWarning() << "Buffering new signal for process" << m_command
|
||||
<< "while the last done() signal wasn't flushed yet.");
|
||||
|
||||
// Merge ReadyRead signals into one.
|
||||
if (lastSignal->signalType() == SignalType::ReadyRead
|
||||
&& newSignal->signalType() == SignalType::ReadyRead) {
|
||||
LauncherReadyReadSignal *lastRead = static_cast<LauncherReadyReadSignal *>(lastSignal);
|
||||
LauncherReadyReadSignal *newRead = static_cast<LauncherReadyReadSignal *>(newSignal);
|
||||
lastRead->mergeWith(newRead);
|
||||
delete newRead;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_signals.append(newSignal);
|
||||
}
|
||||
|
||||
|
@@ -103,6 +103,7 @@ IAssistProposal *FunctionHintProcessor::perform(const AssistInterface *interface
|
||||
|
||||
void FunctionHintProcessor::cancel()
|
||||
{
|
||||
QTC_ASSERT(m_client, return);
|
||||
if (running()) {
|
||||
m_client->cancelRequest(*m_currentRequest);
|
||||
m_client->removeAssistProcessor(this);
|
||||
@@ -112,6 +113,7 @@ void FunctionHintProcessor::cancel()
|
||||
|
||||
void FunctionHintProcessor::handleSignatureResponse(const SignatureHelpRequest::Response &response)
|
||||
{
|
||||
QTC_ASSERT(m_client, setAsyncProposalAvailable(nullptr); return);
|
||||
m_currentRequest.reset();
|
||||
if (auto error = response.error())
|
||||
m_client->log(*error);
|
||||
|
@@ -165,6 +165,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
edit3dcanvas.cpp edit3dcanvas.h
|
||||
edit3dactions.cpp edit3dactions.h
|
||||
edit3dvisibilitytogglesmenu.cpp edit3dvisibilitytogglesmenu.h
|
||||
backgroundcolorselection.cpp backgroundcolorselection.h
|
||||
edit3d.qrc
|
||||
)
|
||||
|
||||
|
@@ -81,30 +81,20 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
if (obj == m_assetsWidget.data())
|
||||
QMetaObject::invokeMethod(m_assetsWidget->rootObject(), "handleViewFocusOut");
|
||||
} else if (event->type() == QMouseEvent::MouseMove) {
|
||||
if (!m_assetsToDrag.isEmpty()) {
|
||||
if (!m_assetsToDrag.isEmpty() && !m_model.isNull()) {
|
||||
QMouseEvent *me = static_cast<QMouseEvent *>(event);
|
||||
if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 10) {
|
||||
auto drag = new QDrag(this);
|
||||
drag->setPixmap(m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], nullptr, {128, 128}));
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8());
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
drag->deleteLater();
|
||||
|
||||
m_model->startDrag(mimeData,
|
||||
m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], nullptr, {128, 128}));
|
||||
m_assetsToDrag.clear();
|
||||
}
|
||||
}
|
||||
} else if (event->type() == QMouseEvent::MouseButtonRelease) {
|
||||
m_assetsToDrag.clear();
|
||||
QWidget *view = QmlDesignerPlugin::instance()->viewManager().widget("Navigator");
|
||||
if (view) {
|
||||
NavigatorWidget *navView = qobject_cast<NavigatorWidget *>(view);
|
||||
if (navView) {
|
||||
navView->setDragType("");
|
||||
navView->update();
|
||||
}
|
||||
}
|
||||
if (m_model)
|
||||
m_model->endDrag();
|
||||
}
|
||||
|
||||
return QObject::eventFilter(obj, event);
|
||||
|
@@ -0,0 +1,107 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** 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
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "backgroundcolorselection.h"
|
||||
|
||||
#include <nodeinstanceview.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <view3dactioncommand.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
using namespace QmlDesigner;
|
||||
|
||||
namespace {
|
||||
QList<QColor> readBackgroundColorConfiguration()
|
||||
{
|
||||
QVariant var = QmlDesigner::DesignerSettings::getValue(
|
||||
QmlDesigner::DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR);
|
||||
|
||||
if (!var.isValid())
|
||||
return {};
|
||||
|
||||
auto colorNameList = var.value<QList<QString>>();
|
||||
QTC_ASSERT(colorNameList.size() == 2, return {});
|
||||
|
||||
return {colorNameList[0], colorNameList[1]};
|
||||
}
|
||||
|
||||
void setBackgroundColorConfiguration(const QList<QColor> &colorConfig)
|
||||
{
|
||||
auto view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView();
|
||||
View3DActionCommand cmd(View3DActionCommand::SelectBackgroundColor,
|
||||
QVariant::fromValue(colorConfig));
|
||||
view->view3DAction(cmd);
|
||||
}
|
||||
|
||||
void saveBackgroundColorConfiguration(const QList<QColor> &colorConfig)
|
||||
{
|
||||
QList<QString> colorsSaved = {colorConfig[0].name(), colorConfig[1].name()};
|
||||
QmlDesigner::DesignerSettings::setValue(
|
||||
QmlDesigner::DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR,
|
||||
QVariant::fromValue(colorsSaved));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
QColorDialog *BackgroundColorSelection::createDialog(QWidget *parent)
|
||||
{
|
||||
auto dialog = new QColorDialog(parent);
|
||||
|
||||
dialog->setModal(true);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
const QList<QColor> oldColorConfig = readBackgroundColorConfiguration();
|
||||
|
||||
dialog->show();
|
||||
|
||||
QObject::connect(dialog, &QColorDialog::currentColorChanged, dialog, [](const QColor &color) {
|
||||
setBackgroundColorConfiguration({color, color});
|
||||
});
|
||||
|
||||
QObject::connect(dialog, &QColorDialog::colorSelected, dialog, [](const QColor &color) {
|
||||
saveBackgroundColorConfiguration({color, color});
|
||||
});
|
||||
|
||||
if (!oldColorConfig.isEmpty()) {
|
||||
QObject::connect(dialog, &QColorDialog::rejected, dialog, [oldColorConfig]() {
|
||||
setBackgroundColorConfiguration(oldColorConfig);
|
||||
});
|
||||
}
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
void BackgroundColorSelection::showBackgroundColorSelectionWidget(QWidget *parent)
|
||||
{
|
||||
if (m_dialog)
|
||||
return;
|
||||
|
||||
m_dialog = BackgroundColorSelection::createDialog(parent);
|
||||
QTC_ASSERT(m_dialog, return);
|
||||
|
||||
QObject::connect(m_dialog, &QWidget::destroyed, m_dialog, [&]() {
|
||||
m_dialog = nullptr;
|
||||
});
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** 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
|
||||
** 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.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QColorDialog>
|
||||
|
||||
namespace QmlDesigner {
|
||||
class BackgroundColorSelection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BackgroundColorSelection(QObject *parent = nullptr)
|
||||
: QObject{parent}
|
||||
{}
|
||||
|
||||
static void showBackgroundColorSelectionWidget(QWidget *parent);
|
||||
|
||||
private:
|
||||
static QColorDialog *createDialog(QWidget *parent);
|
||||
inline static QColorDialog *m_dialog = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
@@ -44,5 +44,7 @@
|
||||
<file>images/align_camera_on@2x.png</file>
|
||||
<file>images/align_view_on.png</file>
|
||||
<file>images/align_view_on@2x.png</file>
|
||||
<file>images/color_palette.png</file>
|
||||
<file>images/color_palette@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -48,9 +48,10 @@ Edit3DActionTemplate::Edit3DActionTemplate(const QString &description,
|
||||
|
||||
void Edit3DActionTemplate::actionTriggered(bool b)
|
||||
{
|
||||
if (m_type != View3DActionCommand::Empty) {
|
||||
QmlDesignerPlugin::instance()->viewManager().nodeInstanceView()
|
||||
->view3DAction(View3DActionCommand(m_type, b));
|
||||
if (m_type != View3DActionCommand::Empty && m_type != View3DActionCommand::SelectBackgroundColor) {
|
||||
auto view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView();
|
||||
View3DActionCommand cmd(m_type, b);
|
||||
view->view3DAction(cmd);
|
||||
}
|
||||
|
||||
if (m_action)
|
||||
|
@@ -42,6 +42,8 @@
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <backgroundcolorselection.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QToolButton>
|
||||
|
||||
@@ -336,6 +338,32 @@ void Edit3DView::createEdit3DActions()
|
||||
QKeySequence(Qt::Key_G), true, true, {}, {}, nullptr,
|
||||
QCoreApplication::translate("ShowGridAction", "Toggle the visibility of the helper grid."));
|
||||
|
||||
SelectionContextOperation showBackgroundColorSelection = [this](const SelectionContext &) {
|
||||
BackgroundColorSelection::showBackgroundColorSelectionWidget(edit3DWidget());
|
||||
};
|
||||
|
||||
m_backgroundColorSelectionAction = new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_SELECT_BACKGROUND_COLOR, View3DActionCommand::SelectBackgroundColor,
|
||||
QCoreApplication::translate("SelectBackgroundColorAction", "Select Background color"),
|
||||
{}, false, false, {}, {}, showBackgroundColorSelection,
|
||||
QCoreApplication::translate("SelectBackgroundColorAction", "Choose a color for the background."));
|
||||
|
||||
m_resetBackgroundColorAction = new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_RESET_BACKGROUND_COLOR, View3DActionCommand::ResetBackgroundColor,
|
||||
QCoreApplication::translate("ResetBackgroundColorAction", "Reset Background color"),
|
||||
{}, false, false, {}, {}, [](const SelectionContext &) {
|
||||
QList<QColor> colors = {QRgb(0x222222), QRgb(0x999999)};
|
||||
auto view = QmlDesignerPlugin::instance()->viewManager().nodeInstanceView();
|
||||
View3DActionCommand cmd(View3DActionCommand::SelectBackgroundColor, QVariant::fromValue(colors));
|
||||
view->view3DAction(cmd);
|
||||
|
||||
QList<QString> colorsToSave = {colors[0].name(), colors[1].name()};
|
||||
QmlDesigner::DesignerSettings::setValue(
|
||||
QmlDesigner::DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR,
|
||||
QVariant::fromValue(colorsToSave));
|
||||
},
|
||||
QCoreApplication::translate("ResetBackgroundColorAction", "Reset Background color to the default value."));
|
||||
|
||||
m_showSelectionBoxAction = new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_EDIT_SHOW_SELECTION_BOX, View3DActionCommand::ShowSelectionBox,
|
||||
QCoreApplication::translate("ShowSelectionBoxAction", "Show Selection Boxes"),
|
||||
@@ -438,6 +466,29 @@ void Edit3DView::createEdit3DActions()
|
||||
QKeySequence(), false, false, Utils::Icons::EYE_OPEN_TOOLBAR.icon(),
|
||||
{}, visibilityTogglesTrigger);
|
||||
|
||||
SelectionContextOperation backgroundColorActionsTrigger = [this](const SelectionContext &) {
|
||||
if (!edit3DWidget()->backgroundColorMenu())
|
||||
return;
|
||||
|
||||
QPoint pos;
|
||||
const auto &actionWidgets = m_backgrondColorMenuAction->action()->associatedWidgets();
|
||||
for (auto actionWidget : actionWidgets) {
|
||||
if (auto button = qobject_cast<QToolButton *>(actionWidget)) {
|
||||
pos = button->mapToGlobal(QPoint(0, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
edit3DWidget()->showBackgroundColorMenu(!edit3DWidget()->backgroundColorMenu()->isVisible(),
|
||||
pos);
|
||||
};
|
||||
|
||||
m_backgrondColorMenuAction = new Edit3DAction(
|
||||
QmlDesigner::Constants::EDIT3D_BACKGROUND_COLOR_ACTIONS, View3DActionCommand::Empty,
|
||||
QCoreApplication::translate("BackgroundColorMenuActions", "Background Color Actions"),
|
||||
QKeySequence(), false, false, Icons::COLOR_PALETTE.icon(),
|
||||
{}, backgroundColorActionsTrigger);
|
||||
|
||||
m_leftActions << m_selectionModeAction;
|
||||
m_leftActions << nullptr; // Null indicates separator
|
||||
m_leftActions << nullptr; // Second null after separator indicates an exclusive group
|
||||
@@ -455,6 +506,8 @@ void Edit3DView::createEdit3DActions()
|
||||
m_leftActions << m_alignViewAction;
|
||||
m_leftActions << nullptr;
|
||||
m_leftActions << m_visibilityTogglesAction;
|
||||
m_leftActions << nullptr;
|
||||
m_leftActions << m_backgrondColorMenuAction;
|
||||
|
||||
m_rightActions << m_particleViewModeAction;
|
||||
m_rightActions << m_particlesPlayAction;
|
||||
@@ -467,6 +520,9 @@ void Edit3DView::createEdit3DActions()
|
||||
m_visibilityToggleActions << m_showIconGizmoAction;
|
||||
m_visibilityToggleActions << m_showCameraFrustumAction;
|
||||
m_visibilityToggleActions << m_showParticleEmitterAction;
|
||||
|
||||
m_backgroundColorActions << m_backgroundColorSelectionAction;
|
||||
m_backgroundColorActions << m_resetBackgroundColorAction;
|
||||
}
|
||||
|
||||
QVector<Edit3DAction *> Edit3DView::leftActions() const
|
||||
@@ -484,6 +540,11 @@ QVector<Edit3DAction *> Edit3DView::visibilityToggleActions() const
|
||||
return m_visibilityToggleActions;
|
||||
}
|
||||
|
||||
QVector<Edit3DAction *> Edit3DView::backgroundColorActions() const
|
||||
{
|
||||
return m_backgroundColorActions;
|
||||
}
|
||||
|
||||
void Edit3DView::addQuick3DImport()
|
||||
{
|
||||
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||
|
@@ -74,6 +74,7 @@ public:
|
||||
QVector<Edit3DAction *> leftActions() const;
|
||||
QVector<Edit3DAction *> rightActions() const;
|
||||
QVector<Edit3DAction *> visibilityToggleActions() const;
|
||||
QVector<Edit3DAction *> backgroundColorActions() const;
|
||||
void setSeeker(SeekerSlider *slider);
|
||||
|
||||
void addQuick3DImport();
|
||||
@@ -88,6 +89,7 @@ private:
|
||||
QVector<Edit3DAction *> m_leftActions;
|
||||
QVector<Edit3DAction *> m_rightActions;
|
||||
QVector<Edit3DAction *> m_visibilityToggleActions;
|
||||
QVector<Edit3DAction *> m_backgroundColorActions;
|
||||
Edit3DAction *m_selectionModeAction = nullptr;
|
||||
Edit3DAction *m_moveToolAction = nullptr;
|
||||
Edit3DAction *m_rotateToolAction = nullptr;
|
||||
@@ -99,6 +101,8 @@ private:
|
||||
Edit3DAction *m_orientationModeAction = nullptr;
|
||||
Edit3DAction *m_editLightAction = nullptr;
|
||||
Edit3DAction *m_showGridAction = nullptr;
|
||||
Edit3DAction *m_backgroundColorSelectionAction = nullptr;
|
||||
Edit3DAction *m_resetBackgroundColorAction = nullptr;
|
||||
Edit3DAction *m_showSelectionBoxAction = nullptr;
|
||||
Edit3DAction *m_showIconGizmoAction = nullptr;
|
||||
Edit3DAction *m_showCameraFrustumAction = nullptr;
|
||||
@@ -108,6 +112,7 @@ private:
|
||||
Edit3DAction *m_particlesPlayAction = nullptr;
|
||||
Edit3DAction *m_particlesRestartAction = nullptr;
|
||||
Edit3DAction *m_visibilityTogglesAction = nullptr;
|
||||
Edit3DAction *m_backgrondColorMenuAction = nullptr;
|
||||
SeekerSlider *m_seeker = nullptr;
|
||||
int particlemode;
|
||||
ModelCache<QImage> m_canvasCache;
|
||||
|
@@ -141,6 +141,9 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) :
|
||||
m_visibilityTogglesMenu = new Edit3DVisibilityTogglesMenu(this);
|
||||
handleActions(view->visibilityToggleActions(), m_visibilityTogglesMenu, false);
|
||||
|
||||
m_backgroundColorMenu = new Edit3DVisibilityTogglesMenu(this);
|
||||
handleActions(view->backgroundColorActions(), m_backgroundColorMenu, false);
|
||||
|
||||
view->setSeeker(seeker);
|
||||
seeker->setToolTip(QLatin1String("Seek particle system time when paused."));
|
||||
|
||||
@@ -201,6 +204,21 @@ void Edit3DWidget::showVisibilityTogglesMenu(bool show, const QPoint &pos)
|
||||
m_visibilityTogglesMenu->close();
|
||||
}
|
||||
|
||||
QMenu *Edit3DWidget::backgroundColorMenu() const
|
||||
{
|
||||
return m_backgroundColorMenu.data();
|
||||
}
|
||||
|
||||
void Edit3DWidget::showBackgroundColorMenu(bool show, const QPoint &pos)
|
||||
{
|
||||
if (m_backgroundColorMenu.isNull())
|
||||
return;
|
||||
if (show)
|
||||
m_backgroundColorMenu->popup(pos);
|
||||
else
|
||||
m_backgroundColorMenu->close();
|
||||
}
|
||||
|
||||
void Edit3DWidget::linkActivated(const QString &link)
|
||||
{
|
||||
Q_UNUSED(link)
|
||||
|
@@ -51,6 +51,9 @@ public:
|
||||
QMenu *visibilityTogglesMenu() const;
|
||||
void showVisibilityTogglesMenu(bool show, const QPoint &pos);
|
||||
|
||||
QMenu *backgroundColorMenu() const;
|
||||
void showBackgroundColorMenu(bool show, const QPoint &pos);
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override;
|
||||
void dropEvent(QDropEvent *dropEvent) override;
|
||||
@@ -65,6 +68,7 @@ private:
|
||||
QPointer<ToolBox> m_toolBox;
|
||||
Core::IContext *m_context = nullptr;
|
||||
QPointer<QMenu> m_visibilityTogglesMenu;
|
||||
QPointer<QMenu> m_backgroundColorMenu;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 363 B |
Binary file not shown.
After Width: | Height: | Size: 713 B |
@@ -401,7 +401,6 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
||||
qmlInfo.append(outDir.relativeFilePath(qmlIt.filePath()));
|
||||
qmlInfo.append('\n');
|
||||
|
||||
// Generate item library icon for qml file based on root component
|
||||
QFile qmlFile(qmlIt.filePath());
|
||||
if (qmlFile.open(QIODevice::ReadOnly)) {
|
||||
QString iconFileName = outDir.path() + '/'
|
||||
@@ -410,6 +409,8 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
||||
QString iconFileName2x = iconFileName + "@2x";
|
||||
QByteArray content = qmlFile.readAll();
|
||||
int braceIdx = content.indexOf('{');
|
||||
QString impVersionStr;
|
||||
int impVersionMajor = -1;
|
||||
if (braceIdx != -1) {
|
||||
int nlIdx = content.lastIndexOf('\n', braceIdx);
|
||||
QByteArray rootItem = content.mid(nlIdx, braceIdx - nlIdx).trimmed();
|
||||
@@ -423,8 +424,9 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
||||
out << "canBeDroppedInView3D: true" << Qt::endl;
|
||||
file.close();
|
||||
|
||||
// Add quick3D import unless it is already added
|
||||
if (m_requiredImports.first().url() != "QtQuick3D") {
|
||||
// Assume that all assets import the same QtQuick3D version,
|
||||
// since they are being imported with same kit
|
||||
if (impVersionMajor == -1) {
|
||||
QByteArray import3dStr{"import QtQuick3D"};
|
||||
int importIdx = content.indexOf(import3dStr);
|
||||
if (importIdx != -1 && importIdx < braceIdx) {
|
||||
@@ -433,15 +435,25 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
||||
QByteArray versionStr = content.mid(importIdx, nlIdx - importIdx).trimmed();
|
||||
// There could be 'as abc' after version, so just take first part
|
||||
QList<QByteArray> parts = versionStr.split(' ');
|
||||
QString impVersion;
|
||||
if (parts.size() >= 1)
|
||||
impVersion = QString::fromUtf8(parts[0]);
|
||||
m_requiredImports.prepend(Import::createLibraryImport(
|
||||
"QtQuick3D", impVersion));
|
||||
if (parts.size() >= 1) {
|
||||
impVersionStr = QString::fromUtf8(parts[0]);
|
||||
if (impVersionStr.isEmpty())
|
||||
impVersionMajor = 6;
|
||||
else
|
||||
impVersionMajor = impVersionStr.left(1).toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add quick3D import unless it is already added
|
||||
if (impVersionMajor > 0
|
||||
&& m_requiredImports.first().url() != "QtQuick3D") {
|
||||
m_requiredImports.prepend(Import::createLibraryImport(
|
||||
"QtQuick3D", impVersionStr));
|
||||
}
|
||||
}
|
||||
if (startIconProcess(24, iconFileName, qmlIt.filePath())) {
|
||||
if (impVersionMajor > 0 && impVersionMajor < 6
|
||||
&& startIconProcess(24, iconFileName, qmlIt.filePath())) {
|
||||
// Since icon is generated by external process, the file won't be
|
||||
// ready for asset gathering below, so assume its generation succeeds
|
||||
// and add it now.
|
||||
|
@@ -92,7 +92,9 @@ QQuickImageResponse *ItemLibraryIconImageProvider::requestImageResponse(const QS
|
||||
}
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
});
|
||||
},
|
||||
"libIcon",
|
||||
ImageCache::LibraryIconAuxiliaryData{true});
|
||||
|
||||
return response.release();
|
||||
}
|
||||
|
@@ -30,12 +30,6 @@
|
||||
#include <asynchronousimagecache.h>
|
||||
#include <bindingproperty.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <imagecache/imagecachecollector.h>
|
||||
#include <imagecache/imagecacheconnectionmanager.h>
|
||||
#include <imagecache/imagecachefontcollector.h>
|
||||
#include <imagecache/imagecachegenerator.h>
|
||||
#include <imagecache/imagecachestorage.h>
|
||||
#include <imagecache/timestampprovider.h>
|
||||
#include <import.h>
|
||||
#include <nodelistproperty.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
@@ -44,7 +38,6 @@
|
||||
#include <projectexplorer/target.h>
|
||||
#include <rewriterview.h>
|
||||
#include <sqlitedatabase.h>
|
||||
#include <synchronousimagecache.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
#include <qmlitemnode.h>
|
||||
@@ -52,38 +45,9 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
namespace {
|
||||
ProjectExplorer::Target *activeTarget(ProjectExplorer::Project *project)
|
||||
{
|
||||
if (project)
|
||||
return project->activeTarget();
|
||||
|
||||
return {};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class ItemLibraryView::ImageCacheData
|
||||
{
|
||||
public:
|
||||
Sqlite::Database database{Utils::PathString{
|
||||
Core::ICore::cacheResourcePath("imagecache-v2.db").toString()},
|
||||
Sqlite::JournalMode::Wal,
|
||||
Sqlite::LockingMode::Normal};
|
||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||
ImageCacheConnectionManager connectionManager;
|
||||
ImageCacheCollector collector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||
ImageCacheFontCollector fontCollector;
|
||||
ImageCacheGenerator generator{collector, storage};
|
||||
ImageCacheGenerator fontGenerator{fontCollector, storage};
|
||||
TimeStampProvider timeStampProvider;
|
||||
AsynchronousImageCache cache{storage, generator, timeStampProvider};
|
||||
AsynchronousImageCache asynchronousFontImageCache{storage, fontGenerator, timeStampProvider};
|
||||
SynchronousImageCache synchronousFontImageCache{storage, timeStampProvider, fontCollector};
|
||||
};
|
||||
|
||||
ItemLibraryView::ItemLibraryView(QObject* parent)
|
||||
: AbstractView(parent)
|
||||
|
||||
ItemLibraryView::ItemLibraryView(AsynchronousImageCache &imageCache)
|
||||
: AbstractView()
|
||||
, m_imageCache(imageCache)
|
||||
{}
|
||||
|
||||
ItemLibraryView::~ItemLibraryView()
|
||||
@@ -97,11 +61,8 @@ bool ItemLibraryView::hasWidget() const
|
||||
|
||||
WidgetInfo ItemLibraryView::widgetInfo()
|
||||
{
|
||||
if (m_widget.isNull()) {
|
||||
m_widget = new ItemLibraryWidget{imageCacheData()->cache,
|
||||
imageCacheData()->asynchronousFontImageCache,
|
||||
imageCacheData()->synchronousFontImageCache};
|
||||
}
|
||||
if (m_widget.isNull())
|
||||
m_widget = new ItemLibraryWidget{m_imageCache};
|
||||
|
||||
return createWidgetInfo(m_widget.data(), "Components", WidgetInfo::LeftPane, 0, tr("Components"));
|
||||
}
|
||||
@@ -177,43 +138,6 @@ void ItemLibraryView::usedImportsChanged(const QList<Import> &usedImports)
|
||||
m_widget->updateUsedImports(usedImports);
|
||||
}
|
||||
|
||||
ItemLibraryView::ImageCacheData *ItemLibraryView::imageCacheData()
|
||||
{
|
||||
std::call_once(imageCacheFlag, [this]() {
|
||||
m_imageCacheData = std::make_unique<ImageCacheData>();
|
||||
auto setTargetInImageCache =
|
||||
[imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) {
|
||||
if (target == imageCacheData->collector.target())
|
||||
return;
|
||||
|
||||
if (target)
|
||||
imageCacheData->cache.clean();
|
||||
|
||||
imageCacheData->collector.setTarget(target);
|
||||
};
|
||||
|
||||
if (auto project = ProjectExplorer::SessionManager::startupProject(); project) {
|
||||
m_imageCacheData->collector.setTarget(project->activeTarget());
|
||||
connect(project,
|
||||
&ProjectExplorer::Project::activeTargetChanged,
|
||||
this,
|
||||
setTargetInImageCache);
|
||||
}
|
||||
connect(ProjectExplorer::SessionManager::instance(),
|
||||
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||
this,
|
||||
[=](ProjectExplorer::Project *project) {
|
||||
setTargetInImageCache(activeTarget(project));
|
||||
});
|
||||
});
|
||||
return m_imageCacheData.get();
|
||||
}
|
||||
|
||||
AsynchronousImageCache &ItemLibraryView::imageCache()
|
||||
{
|
||||
return imageCacheData()->cache;
|
||||
}
|
||||
|
||||
void ItemLibraryView::documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &)
|
||||
{
|
||||
if (m_hasErrors && errors.isEmpty())
|
||||
|
@@ -29,19 +29,16 @@
|
||||
|
||||
#include <QPointer>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class ItemLibraryWidget;
|
||||
class AsynchronousImageCache;
|
||||
|
||||
class ItemLibraryView : public AbstractView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ItemLibraryView(QObject* parent = nullptr);
|
||||
ItemLibraryView(class AsynchronousImageCache &imageCache);
|
||||
~ItemLibraryView() override;
|
||||
|
||||
bool hasWidget() const override;
|
||||
@@ -58,17 +55,11 @@ public:
|
||||
void customNotification(const AbstractView *view, const QString &identifier,
|
||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||
|
||||
AsynchronousImageCache &imageCache();
|
||||
|
||||
protected:
|
||||
void updateImports();
|
||||
|
||||
private:
|
||||
class ImageCacheData;
|
||||
ImageCacheData *imageCacheData();
|
||||
|
||||
std::once_flag imageCacheFlag;
|
||||
std::unique_ptr<ImageCacheData> m_imageCacheData;
|
||||
AsynchronousImageCache &m_imageCache;
|
||||
QPointer<ItemLibraryWidget> m_widget;
|
||||
bool m_hasErrors = false;
|
||||
QVariantMap m_importableExtensions3DMap;
|
||||
|
@@ -140,18 +140,13 @@ void ItemLibraryWidget::resizeEvent(QResizeEvent *event)
|
||||
isHorizontalLayout = event->size().width() >= HORIZONTAL_LAYOUT_WIDTH_LIMIT;
|
||||
}
|
||||
|
||||
ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
AsynchronousImageCache &asynchronousFontImageCache,
|
||||
SynchronousImageCache &synchronousFontImageCache)
|
||||
ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache)
|
||||
: m_itemIconSize(24, 24)
|
||||
, m_fontImageCache(synchronousFontImageCache)
|
||||
, m_itemLibraryModel(new ItemLibraryModel(this))
|
||||
, m_addModuleModel(new ItemLibraryAddImportModel(this))
|
||||
, m_itemsWidget(new QQuickWidget(this))
|
||||
, m_imageCache{imageCache}
|
||||
{
|
||||
Q_UNUSED(asynchronousFontImageCache)
|
||||
|
||||
m_compressionTimer.setInterval(200);
|
||||
m_compressionTimer.setSingleShot(true);
|
||||
ItemLibraryModel::registerQmlTypes();
|
||||
|
@@ -56,7 +56,6 @@ class Model;
|
||||
class ItemLibraryModel;
|
||||
class ItemLibraryAddImportModel;
|
||||
class ItemLibraryResourceView;
|
||||
class SynchronousImageCache;
|
||||
class AsynchronousImageCache;
|
||||
class ImageCacheCollector;
|
||||
|
||||
@@ -67,9 +66,7 @@ class ItemLibraryWidget : public QFrame
|
||||
public:
|
||||
Q_PROPERTY(bool subCompEditMode READ subCompEditMode NOTIFY subCompEditModeChanged)
|
||||
|
||||
ItemLibraryWidget(AsynchronousImageCache &imageCache,
|
||||
AsynchronousImageCache &asynchronousFontImageCache,
|
||||
SynchronousImageCache &synchronousFontImageCache);
|
||||
ItemLibraryWidget(AsynchronousImageCache &imageCache);
|
||||
~ItemLibraryWidget();
|
||||
|
||||
void setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo);
|
||||
@@ -115,7 +112,6 @@ private:
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
||||
SynchronousImageCache &m_fontImageCache;
|
||||
QPointer<ItemLibraryInfo> m_itemLibraryInfo;
|
||||
|
||||
QPointer<ItemLibraryModel> m_itemLibraryModel;
|
||||
|
@@ -29,6 +29,7 @@
|
||||
#include "materialeditorcontextobject.h"
|
||||
#include "propertyeditorvalue.h"
|
||||
#include "materialeditortransaction.h"
|
||||
#include "assetslibrarywidget.h"
|
||||
|
||||
#include <qmldesignerconstants.h>
|
||||
#include <qmltimeline.h>
|
||||
@@ -809,6 +810,39 @@ void MaterialEditorView::customNotification(const AbstractView *view, const QStr
|
||||
}
|
||||
}
|
||||
|
||||
void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highlight)
|
||||
{
|
||||
DesignerPropertyMap &propMap = m_qmlBackEnd->backendValuesPropertyMap();
|
||||
const QStringList propNames = propMap.keys();
|
||||
|
||||
for (const QString &propName : propNames) {
|
||||
if (propName.endsWith("Map")) {
|
||||
QObject *propEditorValObj = propMap.value(propName).value<QObject *>();
|
||||
PropertyEditorValue *propEditorVal = qobject_cast<PropertyEditorValue *>(propEditorValObj);
|
||||
propEditorVal->setHasActiveDrag(highlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MaterialEditorView::dragStarted(QMimeData *mimeData)
|
||||
{
|
||||
if (!mimeData->hasFormat(Constants::MIME_TYPE_ASSETS))
|
||||
return;
|
||||
|
||||
const QString assetPath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',')[0];
|
||||
QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first;
|
||||
|
||||
if (assetType != Constants::MIME_TYPE_ASSET_IMAGE) // currently only image assets have dnd-supported properties
|
||||
return;
|
||||
|
||||
highlightSupportedProperties();
|
||||
}
|
||||
|
||||
void MaterialEditorView::dragEnded()
|
||||
{
|
||||
highlightSupportedProperties(false);
|
||||
}
|
||||
|
||||
// from model to material editor
|
||||
void MaterialEditorView::setValue(const QmlObjectNode &qmlObjectNode, const PropertyName &name, const QVariant &value)
|
||||
{
|
||||
|
@@ -73,6 +73,9 @@ public:
|
||||
void customNotification(const AbstractView *view, const QString &identifier,
|
||||
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||
|
||||
void dragStarted(QMimeData *mimeData) override;
|
||||
void dragEnded() override;
|
||||
|
||||
void changeValue(const QString &name);
|
||||
void changeExpression(const QString &name);
|
||||
void exportPropertyAsAlias(const QString &name);
|
||||
@@ -93,6 +96,7 @@ private:
|
||||
static QString materialEditorResourcesPath();
|
||||
|
||||
void reloadQml();
|
||||
void highlightSupportedProperties(bool highlight = true);
|
||||
QString generateIdFromName(const QString &name);
|
||||
|
||||
void ensureMaterialLibraryNode();
|
||||
|
@@ -274,6 +274,19 @@ bool PropertyEditorValue::isTranslated() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PropertyEditorValue::hasActiveDrag() const
|
||||
{
|
||||
return m_hasActiveDrag;
|
||||
}
|
||||
|
||||
void PropertyEditorValue::setHasActiveDrag(bool val)
|
||||
{
|
||||
if (m_hasActiveDrag != val) {
|
||||
m_hasActiveDrag = val;
|
||||
emit hasActiveDragChanged();
|
||||
}
|
||||
}
|
||||
|
||||
static bool isAllowedSubclassType(const QString &type, const QmlDesigner::NodeMetaInfo &metaInfo)
|
||||
{
|
||||
if (!metaInfo.isValid())
|
||||
@@ -371,18 +384,6 @@ void PropertyEditorValue::setEnumeration(const QString &scope, const QString &na
|
||||
setValueWithEmit(QVariant::fromValue(newEnumeration));
|
||||
}
|
||||
|
||||
bool PropertyEditorValue::isSupportedDrop(const QString &path)
|
||||
{
|
||||
QString suffix = "*." + QFileInfo(path).suffix().toLower();
|
||||
|
||||
if (m_modelNode.isSubclassOf("QtQuick3D.Material") && nameAsQString().endsWith("Map"))
|
||||
return QmlDesigner::AssetsLibraryModel::supportedImageSuffixes().contains(suffix);
|
||||
|
||||
// TODO: handle support for other object properties dnd here (like image source)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void PropertyEditorValue::exportPropertyAsAlias()
|
||||
{
|
||||
emit exportPropertyAsAliasRequested(nameAsQString());
|
||||
|
@@ -82,6 +82,7 @@ class PropertyEditorValue : public QObject
|
||||
Q_PROPERTY(bool isBound READ isBound NOTIFY isBoundChanged FINAL)
|
||||
Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged FINAL)
|
||||
Q_PROPERTY(bool isTranslated READ isTranslated NOTIFY expressionChanged FINAL)
|
||||
Q_PROPERTY(bool hasActiveDrag READ hasActiveDrag WRITE setHasActiveDrag NOTIFY hasActiveDragChanged FINAL)
|
||||
|
||||
Q_PROPERTY(bool isIdList READ isIdList NOTIFY expressionChanged FINAL)
|
||||
Q_PROPERTY(QStringList expressionAsList READ getExpressionAsList NOTIFY expressionChanged FINAL)
|
||||
@@ -117,6 +118,9 @@ public:
|
||||
|
||||
bool isTranslated() const;
|
||||
|
||||
bool hasActiveDrag() const;
|
||||
void setHasActiveDrag(bool val);
|
||||
|
||||
bool isAvailable() const;
|
||||
|
||||
QmlDesigner::PropertyName name() const;
|
||||
@@ -148,7 +152,6 @@ public:
|
||||
public slots:
|
||||
void resetValue();
|
||||
void setEnumeration(const QString &scope, const QString &name);
|
||||
bool isSupportedDrop(const QString &path);
|
||||
|
||||
signals:
|
||||
void valueChanged(const QString &name, const QVariant&);
|
||||
@@ -164,6 +167,7 @@ signals:
|
||||
void isBoundChanged();
|
||||
void isValidChanged();
|
||||
void isExplicitChanged();
|
||||
void hasActiveDragChanged();
|
||||
|
||||
private:
|
||||
QStringList generateStringList(const QString &string) const;
|
||||
@@ -176,6 +180,7 @@ private:
|
||||
bool m_isInSubState;
|
||||
bool m_isInModel;
|
||||
bool m_isBound;
|
||||
bool m_hasActiveDrag = false;
|
||||
bool m_isValid; // if the property value belongs to a non-existing complexProperty it is invalid
|
||||
PropertyEditorNodeWrapper *m_complexNode;
|
||||
};
|
||||
|
@@ -74,7 +74,7 @@ ImageCacheCollector::~ImageCacheCollector() = default;
|
||||
|
||||
void ImageCacheCollector::start(Utils::SmallStringView name,
|
||||
Utils::SmallStringView state,
|
||||
const ImageCache::AuxiliaryData &,
|
||||
const ImageCache::AuxiliaryData &auxiliaryData,
|
||||
CaptureCallback captureCallback,
|
||||
AbortCallback abortCallback)
|
||||
{
|
||||
@@ -96,13 +96,22 @@ void ImageCacheCollector::start(Utils::SmallStringView name,
|
||||
|
||||
model->setRewriterView(&rewriterView);
|
||||
|
||||
bool is3DRoot = !rewriterView.inErrorState()
|
||||
&& (rewriterView.rootModelNode().isSubclassOf("Quick3D.Node")
|
||||
|| rewriterView.rootModelNode().isSubclassOf("Quick3D.Material"));
|
||||
|
||||
if (rewriterView.inErrorState() || (!rewriterView.rootModelNode().metaInfo().isGraphicalItem()
|
||||
&& !rewriterView.rootModelNode().isSubclassOf("Quick3D.Node") )) {
|
||||
&& !is3DRoot)) {
|
||||
if (abortCallback)
|
||||
abortCallback(ImageCache::AbortReason::Failed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is3DRoot) {
|
||||
if (auto libIcon = Utils::get_if<ImageCache::LibraryIconAuxiliaryData>(&auxiliaryData))
|
||||
rewriterView.rootModelNode().setAuxiliaryData("isLibraryIcon@NodeInstance", libIcon->enable);
|
||||
}
|
||||
|
||||
ModelNode stateNode = rewriterView.modelNodeForId(QString{state});
|
||||
|
||||
if (stateNode.isValid())
|
||||
|
@@ -54,7 +54,16 @@ public:
|
||||
QString text;
|
||||
};
|
||||
|
||||
using AuxiliaryData = Utils::variant<Utils::monostate, FontCollectorSizeAuxiliaryData, FontCollectorSizesAuxiliaryData>;
|
||||
class LibraryIconAuxiliaryData
|
||||
{
|
||||
public:
|
||||
bool enable;
|
||||
};
|
||||
|
||||
using AuxiliaryData = Utils::variant<Utils::monostate,
|
||||
LibraryIconAuxiliaryData,
|
||||
FontCollectorSizeAuxiliaryData,
|
||||
FontCollectorSizesAuxiliaryData>;
|
||||
|
||||
enum class AbortReason : char { Abort, Failed };
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <import.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPixmap;
|
||||
class QUrl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -44,7 +45,7 @@ namespace Internal {
|
||||
class ModelPrivate;
|
||||
class WriteLocker;
|
||||
class NodeMetaInfoPrivate;
|
||||
} //Internal
|
||||
} // namespace Internal
|
||||
|
||||
class AnchorLine;
|
||||
class ModelNode;
|
||||
@@ -130,7 +131,7 @@ public:
|
||||
QString generateNewId(const QString &prefixName) const;
|
||||
QString generateNewId(const QString &prefixName, const QString &fallbackPrefix) const;
|
||||
|
||||
void startDrag(QMimeData *mimeData, const QString iconPath = {});
|
||||
void startDrag(QMimeData *mimeData, const QPixmap &icon);
|
||||
void endDrag();
|
||||
|
||||
protected:
|
||||
@@ -140,4 +141,4 @@ private:
|
||||
Internal::ModelPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -47,12 +47,11 @@ class Edit3DView;
|
||||
namespace Internal { class DesignModeWidget; }
|
||||
|
||||
class ViewManagerData;
|
||||
class AsynchronousImageCache;
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT ViewManager
|
||||
{
|
||||
public:
|
||||
ViewManager();
|
||||
ViewManager(class AsynchronousImageCache &imageCache);
|
||||
~ViewManager();
|
||||
|
||||
void attachRewriterView();
|
||||
@@ -107,8 +106,6 @@ public:
|
||||
void disableStandardViews();
|
||||
void enableStandardViews();
|
||||
|
||||
AsynchronousImageCache &imageCache();
|
||||
|
||||
private: // functions
|
||||
Q_DISABLE_COPY(ViewManager)
|
||||
|
||||
|
@@ -600,11 +600,9 @@ void NodeInstanceView::nodeReparented(const ModelNode &node, const NodeAbstractP
|
||||
|
||||
// Reset puppet when particle emitter/affector is reparented to work around issue in
|
||||
// autodetecting the particle system it belongs to. QTBUG-101157
|
||||
// Reset is also needed when particle shapes are reparented. QTBUG-101882
|
||||
if (((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
||||
if ((node.isSubclassOf("QtQuick.Particles3D.ParticleEmitter3D")
|
||||
|| node.isSubclassOf("QtQuick.Particles3D.Affector3D"))
|
||||
&& node.property("system").toBindingProperty().expression().isEmpty())
|
||||
|| node.isSubclassOf("QQuick3DParticleAbstractShape")) {
|
||||
&& node.property("system").toBindingProperty().expression().isEmpty()) {
|
||||
resetPuppet();
|
||||
}
|
||||
}
|
||||
@@ -987,6 +985,17 @@ QList<ModelNode> filterNodesForSkipItems(const QList<ModelNode> &nodeList)
|
||||
return filteredNodeList;
|
||||
}
|
||||
|
||||
QList<QColor> readBackgroundColorConfiguration(const QVariant &var)
|
||||
{
|
||||
if (!var.isValid())
|
||||
return {};
|
||||
|
||||
auto colorNameList = var.value<QList<QString>>();
|
||||
QTC_ASSERT(colorNameList.size() == 2, return {});
|
||||
|
||||
return {colorNameList[0], colorNameList[1]};
|
||||
}
|
||||
|
||||
CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
||||
{
|
||||
QList<ModelNode> nodeList = allModelNodes();
|
||||
@@ -1141,6 +1150,17 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
||||
if (stateNode.isValid() && stateNode.metaInfo().isSubclassOf("QtQuick.State", 1, 0))
|
||||
stateInstanceId = stateNode.internalId();
|
||||
|
||||
auto value
|
||||
#ifndef QMLDESIGNER_TEST
|
||||
= QmlDesigner::DesignerSettings::getValue(
|
||||
QmlDesigner::DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR);
|
||||
#else
|
||||
= QColor();
|
||||
#endif
|
||||
QList<QColor> edit3dBackgroundColor;
|
||||
if (value.isValid())
|
||||
edit3dBackgroundColor = readBackgroundColorConfiguration(value);
|
||||
|
||||
return CreateSceneCommand(
|
||||
instanceContainerList,
|
||||
reparentContainerList,
|
||||
@@ -1161,7 +1181,8 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand()
|
||||
lastUsedLanguage,
|
||||
m_captureImageMinimumSize,
|
||||
m_captureImageMaximumSize,
|
||||
stateInstanceId);
|
||||
stateInstanceId,
|
||||
edit3dBackgroundColor);
|
||||
}
|
||||
|
||||
ClearSceneCommand NodeInstanceView::createClearSceneCommand() const
|
||||
@@ -2190,9 +2211,8 @@ void NodeInstanceView::maybeResetOnPropertyChange(const PropertyName &name, cons
|
||||
{
|
||||
bool reset = false;
|
||||
if (flags & AbstractView::PropertiesAdded
|
||||
&& name == "model" && (node.isSubclassOf("QtQuick.Repeater")
|
||||
|| node.isSubclassOf("QtQuick3D.Repeater3D"))) {
|
||||
// TODO: This is a workaround for QTBUG-97583 (2D) and QTBUG-97586 (3D):
|
||||
&& name == "model" && node.isSubclassOf("QtQuick.Repeater")) {
|
||||
// TODO: This is a workaround for QTBUG-97583:
|
||||
// Reset puppet when repeater model is first added, if there is already a delegate
|
||||
if (node.hasProperty("delegate"))
|
||||
reset = true;
|
||||
|
@@ -452,10 +452,9 @@ void SubComponentManager::parseQuick3DAssetsItem(const QString &importUrl, const
|
||||
QString iconPath = qmlIt.fileInfo().absolutePath() + '/'
|
||||
+ Constants::QUICK_3D_ASSET_ICON_DIR + '/' + name
|
||||
+ Constants::QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX;
|
||||
if (!QFileInfo::exists(iconPath))
|
||||
iconPath = defaultIconPath;
|
||||
itemLibraryEntry.setLibraryEntryIconPath(iconPath);
|
||||
itemLibraryEntry.setTypeIcon(QIcon(iconPath));
|
||||
if (QFileInfo::exists(iconPath))
|
||||
itemLibraryEntry.setLibraryEntryIconPath(iconPath);
|
||||
itemLibraryEntry.setTypeIcon(QIcon(defaultIconPath));
|
||||
|
||||
// load hints file if exists
|
||||
QFile hintsFile(qmlIt.fileInfo().absolutePath() + '/' + name + ".hints");
|
||||
|
@@ -1510,12 +1510,12 @@ QString Model::generateNewId(const QString &prefixName, const QString &fallbackP
|
||||
return newId;
|
||||
}
|
||||
|
||||
void Model::startDrag(QMimeData *mimeData, const QString iconPath)
|
||||
void Model::startDrag(QMimeData *mimeData, const QPixmap &icon)
|
||||
{
|
||||
d->notifyDragStarted(mimeData);
|
||||
|
||||
auto drag = new QDrag(this);
|
||||
drag->setPixmap(iconPath);
|
||||
drag->setPixmap(icon);
|
||||
drag->setMimeData(mimeData);
|
||||
drag->exec();
|
||||
drag->deleteLater();
|
||||
|
@@ -62,6 +62,10 @@ static Q_LOGGING_CATEGORY(viewBenchmark, "qtc.viewmanager.attach", QtWarningMsg)
|
||||
class ViewManagerData
|
||||
{
|
||||
public:
|
||||
ViewManagerData(AsynchronousImageCache &imageCache)
|
||||
: itemLibraryView(imageCache)
|
||||
{}
|
||||
|
||||
InteractiveConnectionManager connectionManager;
|
||||
CapturingConnectionManager capturingConnectionManager;
|
||||
QmlModelState savedState;
|
||||
@@ -90,12 +94,13 @@ static CrumbleBar *crumbleBar() {
|
||||
return QmlDesignerPlugin::instance()->mainWidget()->crumbleBar();
|
||||
}
|
||||
|
||||
ViewManager::ViewManager()
|
||||
: d(std::make_unique<ViewManagerData>())
|
||||
ViewManager::ViewManager(AsynchronousImageCache &imageCache)
|
||||
: d(std::make_unique<ViewManagerData>(imageCache))
|
||||
{
|
||||
d->formEditorView.setGotoErrorCallback([this](int line, int column) {
|
||||
d->textEditorView.gotoCursorPosition(line, column);
|
||||
if (Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance()->mainWidget())
|
||||
if (Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance()
|
||||
->mainWidget())
|
||||
designModeWidget->showDockWidget("TextEditor");
|
||||
});
|
||||
}
|
||||
@@ -439,11 +444,6 @@ void ViewManager::enableStandardViews()
|
||||
attachViewsExceptRewriterAndComponetView();
|
||||
}
|
||||
|
||||
AsynchronousImageCache &ViewManager::imageCache()
|
||||
{
|
||||
return d->itemLibraryView.imageCache();
|
||||
}
|
||||
|
||||
void ViewManager::addView(std::unique_ptr<AbstractView> &&view)
|
||||
{
|
||||
d->additionalViews.push_back(std::move(view));
|
||||
|
@@ -80,6 +80,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
|
||||
restoreValue(settings, DesignerSettingsKey::ALWAYS_DESIGN_MODE, true);
|
||||
restoreValue(settings, DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER, false);
|
||||
restoreValue(settings, DesignerSettingsKey::ASK_BEFORE_DELETING_ASSET, true);
|
||||
restoreValue(settings, DesignerSettingsKey::EDIT3DVIEW_BACKGROUND_COLOR, QList<QString>{"#222222", "#999999"});
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
|
@@ -49,6 +49,7 @@ const char WARNING_FOR_QML_FILES_INSTEAD_OF_UIQML_FILES[] = "WarnAboutQmlFilesIn
|
||||
const char WARNING_FOR_DESIGNER_FEATURES_IN_EDITOR[] = "WarnAboutQtQuickDesignerFeaturesInCodeEditor";
|
||||
const char SHOW_DEBUGVIEW[] = "ShowQtQuickDesignerDebugView";
|
||||
const char ENABLE_DEBUGVIEW[] = "EnableQtQuickDesignerDebugView";
|
||||
const char EDIT3DVIEW_BACKGROUND_COLOR[] = "Edit3DViewBackgroundColor";
|
||||
const char ALWAYS_SAVE_IN_CRUMBLEBAR[] = "AlwaysSaveInCrumbleBar";
|
||||
const char USE_DEFAULT_PUPPET[] = "UseDefaultQml2Puppet";
|
||||
const char PUPPET_TOPLEVEL_BUILD_DIRECTORY[] = "PuppetToplevelBuildDirectory";
|
||||
|
@@ -65,6 +65,8 @@ const char EDIT3D_EDIT_CAMERA[] = "QmlDesigner.Editor3D.EditCameraToggle";
|
||||
const char EDIT3D_ORIENTATION[] = "QmlDesigner.Editor3D.OrientationToggle";
|
||||
const char EDIT3D_EDIT_LIGHT[] = "QmlDesigner.Editor3D.EditLightToggle";
|
||||
const char EDIT3D_EDIT_SHOW_GRID[] = "QmlDesigner.Editor3D.ToggleGrid";
|
||||
const char EDIT3D_EDIT_SELECT_BACKGROUND_COLOR[] = "QmlDesigner.Editor3D.SelectBackgroundColor";
|
||||
const char EDIT3D_EDIT_RESET_BACKGROUND_COLOR[] = "QmlDesigner.Editor3D.ResetBackgroundColor";
|
||||
const char EDIT3D_EDIT_SHOW_SELECTION_BOX[] = "QmlDesigner.Editor3D.ToggleSelectionBox";
|
||||
const char EDIT3D_EDIT_SHOW_ICON_GIZMO[] = "QmlDesigner.Editor3D.ToggleIconGizmo";
|
||||
const char EDIT3D_EDIT_SHOW_CAMERA_FRUSTUM[] = "QmlDesigner.Editor3D.ToggleCameraFrustum";
|
||||
@@ -74,6 +76,7 @@ const char EDIT3D_PARTICLE_MODE[] = "QmlDesigner.Editor3D.ParticleViewModeTo
|
||||
const char EDIT3D_PARTICLES_PLAY[] = "QmlDesigner.Editor3D.ParticlesPlay";
|
||||
const char EDIT3D_PARTICLES_RESTART[] = "QmlDesigner.Editor3D.ParticlesRestart";
|
||||
const char EDIT3D_VISIBILITY_TOGGLES[] = "QmlDesigner.Editor3D.VisibilityToggles";
|
||||
const char EDIT3D_BACKGROUND_COLOR_ACTIONS[] = "QmlDesigner.Editor3D.BackgroundColorActions";
|
||||
|
||||
|
||||
const char QML_DESIGNER_SUBFOLDER[] = "/designer/";
|
||||
|
@@ -91,6 +91,8 @@ const Utils::Icon EDIT3D_ALIGN_CAMERA_ON({
|
||||
{":/edit3d/images/align_camera_on.png", Utils::Theme::IconsBaseColor}});
|
||||
const Utils::Icon EDIT3D_ALIGN_VIEW_ON({
|
||||
{":/edit3d/images/align_view_on.png", Utils::Theme::IconsBaseColor}});
|
||||
const Utils::Icon COLOR_PALETTE({
|
||||
{":/edit3d/images/color_palette.png", Utils::Theme::IconsBaseColor}});
|
||||
|
||||
} // Icons
|
||||
} // QmlDesigner
|
||||
|
@@ -135,7 +135,7 @@ class QmlDesignerPluginPrivate
|
||||
{
|
||||
public:
|
||||
QmlDesignerProjectManager projectManager;
|
||||
ViewManager viewManager;
|
||||
ViewManager viewManager{projectManager.asynchronousImageCache()};
|
||||
DocumentManager documentManager;
|
||||
ShortCutManager shortCutManager;
|
||||
SettingsPage settingsPage;
|
||||
@@ -666,7 +666,7 @@ void QmlDesignerPlugin::emitUsageStatisticsHelpRequested(const QString &identifi
|
||||
|
||||
AsynchronousImageCache &QmlDesignerPlugin::imageCache()
|
||||
{
|
||||
return m_instance->d->viewManager.imageCache();
|
||||
return m_instance->d->projectManager.asynchronousImageCache();
|
||||
}
|
||||
|
||||
void QmlDesignerPlugin::registerPreviewImageProvider(QQmlEngine *engine)
|
||||
|
@@ -526,6 +526,8 @@ Project {
|
||||
"debugview/debugviewwidget.ui",
|
||||
"edit3d/edit3dview.cpp",
|
||||
"edit3d/edit3dview.h",
|
||||
"edit3d/backgroundcolorselection.cpp",
|
||||
"edit3d/backgroundcolorselection.h",
|
||||
"edit3d/edit3dwidget.cpp",
|
||||
"edit3d/edit3dwidget.h",
|
||||
"edit3d/edit3dcanvas.cpp",
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
#include <asynchronousexplicitimagecache.h>
|
||||
#include <asynchronousimagecache.h>
|
||||
#include <imagecache/asynchronousimagefactory.h>
|
||||
#include <imagecache/explicitimagecacheimageprovider.h>
|
||||
#include <imagecache/imagecachecollector.h>
|
||||
@@ -60,6 +61,14 @@ namespace QmlDesigner {
|
||||
|
||||
namespace {
|
||||
|
||||
ProjectExplorer::Target *activeTarget(ProjectExplorer::Project *project)
|
||||
{
|
||||
if (project)
|
||||
return project->activeTarget();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QString defaultImagePath()
|
||||
{
|
||||
return Core::ICore::resourcePath("qmldesigner/welcomepage/images/newThumbnail.png").toString();
|
||||
@@ -89,7 +98,22 @@ public:
|
||||
|
||||
} // namespace
|
||||
|
||||
class PreviewImageCacheData
|
||||
class QmlDesignerProjectManager::ImageCacheData
|
||||
{
|
||||
public:
|
||||
Sqlite::Database database{Utils::PathString{
|
||||
Core::ICore::cacheResourcePath("imagecache-v2.db").toString()},
|
||||
Sqlite::JournalMode::Wal,
|
||||
Sqlite::LockingMode::Normal};
|
||||
ImageCacheStorage<Sqlite::Database> storage{database};
|
||||
ImageCacheConnectionManager connectionManager;
|
||||
ImageCacheCollector collector{connectionManager, QSize{300, 300}, QSize{600, 600}};
|
||||
ImageCacheGenerator generator{collector, storage};
|
||||
TimeStampProvider timeStampProvider;
|
||||
AsynchronousImageCache asynchronousImageCache{storage, generator, timeStampProvider};
|
||||
};
|
||||
|
||||
class QmlDesignerProjectManager::PreviewImageCacheData
|
||||
{
|
||||
public:
|
||||
Sqlite::Database database{Utils::PathString{
|
||||
@@ -100,7 +124,7 @@ public:
|
||||
AsynchronousExplicitImageCache cache{storage};
|
||||
};
|
||||
|
||||
class QmlDesignerProjectManagerProjectData
|
||||
class QmlDesignerProjectManager::QmlDesignerProjectManagerProjectData
|
||||
{
|
||||
public:
|
||||
QmlDesignerProjectManagerProjectData(ImageCacheStorage<Sqlite::Database> &storage)
|
||||
@@ -117,7 +141,7 @@ public:
|
||||
};
|
||||
|
||||
QmlDesignerProjectManager::QmlDesignerProjectManager()
|
||||
: m_imageCacheData{std::make_unique<PreviewImageCacheData>()}
|
||||
: m_previewImageCacheData{std::make_unique<PreviewImageCacheData>()}
|
||||
{
|
||||
auto editorManager = ::Core::EditorManager::instance();
|
||||
QObject::connect(editorManager, &::Core::EditorManager::editorOpened, [&](auto *editor) {
|
||||
@@ -145,12 +169,17 @@ QmlDesignerProjectManager::~QmlDesignerProjectManager() = default;
|
||||
|
||||
void QmlDesignerProjectManager::registerPreviewImageProvider(QQmlEngine *engine) const
|
||||
{
|
||||
auto imageProvider = std::make_unique<ExplicitImageCacheImageProvider>(m_imageCacheData->cache,
|
||||
auto imageProvider = std::make_unique<ExplicitImageCacheImageProvider>(m_previewImageCacheData->cache,
|
||||
QImage{defaultImagePath()});
|
||||
|
||||
engine->addImageProvider("project_preview", imageProvider.release());
|
||||
}
|
||||
|
||||
AsynchronousImageCache &QmlDesignerProjectManager::asynchronousImageCache()
|
||||
{
|
||||
return imageCacheData()->asynchronousImageCache;
|
||||
}
|
||||
|
||||
void QmlDesignerProjectManager::editorOpened(::Core::IEditor *) {}
|
||||
|
||||
void QmlDesignerProjectManager::currentEditorChanged(::Core::IEditor *)
|
||||
@@ -171,7 +200,7 @@ void QmlDesignerProjectManager::editorsClosed(const QList<::Core::IEditor *> &)
|
||||
|
||||
void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project)
|
||||
{
|
||||
m_projectData = std::make_unique<QmlDesignerProjectManagerProjectData>(m_imageCacheData->storage);
|
||||
m_projectData = std::make_unique<QmlDesignerProjectManagerProjectData>(m_previewImageCacheData->storage);
|
||||
m_projectData->activeTarget = project->activeTarget();
|
||||
}
|
||||
|
||||
@@ -183,4 +212,36 @@ void QmlDesignerProjectManager::aboutToRemoveProject(::ProjectExplorer::Project
|
||||
|
||||
void QmlDesignerProjectManager::projectRemoved(::ProjectExplorer::Project *) {}
|
||||
|
||||
QmlDesignerProjectManager::ImageCacheData *QmlDesignerProjectManager::imageCacheData()
|
||||
{
|
||||
std::call_once(imageCacheFlag, [this]() {
|
||||
m_imageCacheData = std::make_unique<ImageCacheData>();
|
||||
auto setTargetInImageCache =
|
||||
[imageCacheData = m_imageCacheData.get()](ProjectExplorer::Target *target) {
|
||||
if (target == imageCacheData->collector.target())
|
||||
return;
|
||||
|
||||
if (target)
|
||||
imageCacheData->asynchronousImageCache.clean();
|
||||
|
||||
imageCacheData->collector.setTarget(target);
|
||||
};
|
||||
|
||||
if (auto project = ProjectExplorer::SessionManager::startupProject(); project) {
|
||||
m_imageCacheData->collector.setTarget(project->activeTarget());
|
||||
QObject::connect(project,
|
||||
&ProjectExplorer::Project::activeTargetChanged,
|
||||
this,
|
||||
setTargetInImageCache);
|
||||
}
|
||||
QObject::connect(ProjectExplorer::SessionManager::instance(),
|
||||
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||
this,
|
||||
[=](ProjectExplorer::Project *project) {
|
||||
setTargetInImageCache(activeTarget(project));
|
||||
});
|
||||
});
|
||||
return m_imageCacheData.get();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -26,8 +26,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QQmlEngine)
|
||||
|
||||
@@ -42,17 +44,22 @@ class Target;
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class QmlDesignerProjectManagerProjectData;
|
||||
class PreviewImageCacheData;
|
||||
|
||||
class QmlDesignerProjectManager
|
||||
class QmlDesignerProjectManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class QmlDesignerProjectManagerProjectData;
|
||||
class PreviewImageCacheData;
|
||||
class ImageCacheData;
|
||||
|
||||
public:
|
||||
QmlDesignerProjectManager();
|
||||
~QmlDesignerProjectManager();
|
||||
|
||||
void registerPreviewImageProvider(QQmlEngine *engine) const;
|
||||
|
||||
class AsynchronousImageCache &asynchronousImageCache();
|
||||
|
||||
private:
|
||||
void editorOpened(::Core::IEditor *editor);
|
||||
void currentEditorChanged(::Core::IEditor *);
|
||||
@@ -60,9 +67,12 @@ private:
|
||||
void projectAdded(::ProjectExplorer::Project *project);
|
||||
void aboutToRemoveProject(::ProjectExplorer::Project *project);
|
||||
void projectRemoved(::ProjectExplorer::Project *project);
|
||||
ImageCacheData *imageCacheData();
|
||||
|
||||
private:
|
||||
std::unique_ptr<PreviewImageCacheData> m_imageCacheData;
|
||||
std::once_flag imageCacheFlag;
|
||||
std::unique_ptr<ImageCacheData> m_imageCacheData;
|
||||
std::unique_ptr<PreviewImageCacheData> m_previewImageCacheData;
|
||||
std::unique_ptr<QmlDesignerProjectManagerProjectData> m_projectData;
|
||||
};
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -57,6 +57,12 @@
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
static bool enableDownload()
|
||||
{
|
||||
const QString lastQDSVersionEntry = "QML/Designer/EnableWelcomePageDownload";
|
||||
return Core::ICore::settings()->value(lastQDSVersionEntry, false).toBool();
|
||||
}
|
||||
|
||||
void ExampleCheckout::registerTypes()
|
||||
{
|
||||
static bool once = []() {
|
||||
@@ -186,6 +192,12 @@ bool FileDownloader::available() const
|
||||
|
||||
void FileDownloader::probeUrl()
|
||||
{
|
||||
if (!enableDownload()) {
|
||||
m_available = false;
|
||||
emit availableChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
auto request = QNetworkRequest(m_url);
|
||||
request.setAttribute(QNetworkRequest::RedirectPolicyAttribute,
|
||||
QNetworkRequest::UserVerifiedRedirectPolicy);
|
||||
@@ -448,6 +460,13 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */)
|
||||
|
||||
void DataModelDownloader::start()
|
||||
{
|
||||
|
||||
if (!enableDownload()) {
|
||||
m_available = false;
|
||||
emit availableChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
m_fileDownloader.setUrl(QUrl::fromUserInput(
|
||||
"https://download.qt.io/learning/examples/qtdesignstudio/dataImports.zip"));
|
||||
|
||||
|
Reference in New Issue
Block a user