From 6acd398536789583a2a4e131a9bdbd375591fc3b Mon Sep 17 00:00:00 2001 From: Massimo Callegari Date: Sun, 5 Nov 2023 18:18:45 +0100 Subject: [PATCH] qmlui: add support for 2D view background picture --- qmlui/contextmanager.cpp | 10 + qmlui/contextmanager.h | 3 + qmlui/mainview2d.cpp | 18 ++ qmlui/mainview2d.h | 6 + qmlui/qml/fixturesfunctions/2DView.qml | 15 +- .../qml/fixturesfunctions/SettingsView2D.qml | 270 +++++++++++------- qmlui/tardis/tardis.cpp | 6 + qmlui/tardis/tardis.h | 1 + 8 files changed, 218 insertions(+), 111 deletions(-) diff --git a/qmlui/contextmanager.cpp b/qmlui/contextmanager.cpp index eba8c66659..f2d1b49f3b 100644 --- a/qmlui/contextmanager.cpp +++ b/qmlui/contextmanager.cpp @@ -222,6 +222,16 @@ QString ContextManager::currentContext() const return m_view->rootObject()->property("currentContext").toString(); } +MainView2D *ContextManager::get2DView() +{ + return m_2DView; +} + +MainView3D *ContextManager::get3DView() +{ + return m_3DView; +} + QVector3D ContextManager::environmentSize() const { return m_monProps->gridSize(); diff --git a/qmlui/contextmanager.h b/qmlui/contextmanager.h index ebb1bf2d5d..01151871de 100644 --- a/qmlui/contextmanager.h +++ b/qmlui/contextmanager.h @@ -79,6 +79,9 @@ class ContextManager : public QObject /** Return the currently active context */ QString currentContext() const; + MainView2D *get2DView(); + MainView3D *get3DView(); + /** Get/Set the environment width/height/depth size */ QVector3D environmentSize() const; void setEnvironmentSize(QVector3D environmentSize); diff --git a/qmlui/mainview2d.cpp b/qmlui/mainview2d.cpp index 48f6ada0a6..fca8e34fca 100644 --- a/qmlui/mainview2d.cpp +++ b/qmlui/mainview2d.cpp @@ -760,6 +760,24 @@ void MainView2D::setPointOfView(int pointOfView) slotRefreshView(); } +QString MainView2D::backgroundImage() +{ + return m_monProps->commonBackgroundImage(); +} + +void MainView2D::setBackgroundImage(QString image) +{ + QString strippedPath = image.replace("file://", ""); + QString currentImage = m_monProps->commonBackgroundImage(); + + if (strippedPath == currentImage) + return; + + Tardis::instance()->enqueueAction(Tardis::EnvironmentBackgroundImage, 0, QVariant(currentImage), QVariant(strippedPath)); + m_monProps->setCommonBackgroundImage(strippedPath); + emit backgroundImageChanged(); +} + diff --git a/qmlui/mainview2d.h b/qmlui/mainview2d.h index d1e8864aac..06ce869662 100644 --- a/qmlui/mainview2d.h +++ b/qmlui/mainview2d.h @@ -40,6 +40,7 @@ class MainView2D : public PreviewContext Q_PROPERTY(qreal gridScale READ gridScale WRITE setGridScale NOTIFY gridScaleChanged) Q_PROPERTY(qreal cellPixels READ cellPixels WRITE setCellPixels NOTIFY cellPixelsChanged) Q_PROPERTY(int pointOfView READ pointOfView WRITE setPointOfView NOTIFY pointOfViewChanged) + Q_PROPERTY(QString backgroundImage READ backgroundImage WRITE setBackgroundImage NOTIFY backgroundImageChanged) public: explicit MainView2D(QQuickView *view, Doc *doc, QObject *parent = 0); @@ -114,6 +115,10 @@ class MainView2D : public PreviewContext int pointOfView() const; void setPointOfView(int pointOfView); + /** Get/Set the main background image */ + QString backgroundImage(); + void setBackgroundImage(QString image); + protected: /** First time 2D view variables initializations */ bool initialize2DProperties(); @@ -128,6 +133,7 @@ class MainView2D : public PreviewContext void gridScaleChanged(qreal gridScale); void cellPixelsChanged(qreal cellPixels); void pointOfViewChanged(int pointOfView); + void backgroundImageChanged(); public slots: /** @reimp */ diff --git a/qmlui/qml/fixturesfunctions/2DView.qml b/qmlui/qml/fixturesfunctions/2DView.qml index f76c88bcbf..491c91ae81 100644 --- a/qmlui/qml/fixturesfunctions/2DView.qml +++ b/qmlui/qml/fixturesfunctions/2DView.qml @@ -80,6 +80,7 @@ Rectangle * The stacking order of this view is very important and delicate * From bottom to top: * Flickable (z = 1): main scrollable area + * Image (z = 0): Main background image * Canvas (z = 0): The actual grid graphics view * DropArea (z = 0): allow to drop items from fixture browser * Rectangle (z = 1): multiple drag layer as big as the Canvas layer @@ -142,6 +143,17 @@ Rectangle twoDContents.requestPaint() } + Image + { + x: twoDContents.xOffset + y: twoDContents.yOffset + width: twoDView.contentWidth - (x * 2) + height: twoDView.contentHeight - (y * 2) + source: View2D.backgroundImage ? "file://" + View2D.backgroundImage : "" + sourceSize: Qt.size(width, height) + fillMode: Image.PreserveAspectFit + } + Canvas { id: twoDContents @@ -175,7 +187,7 @@ Rectangle var context = getContext("2d") context.globalAlpha = 1.0 context.strokeStyle = "#5F5F5F" - context.fillStyle = "black" + context.fillStyle = "transparent" context.lineWidth = 1 context.beginPath() @@ -183,6 +195,7 @@ Rectangle context.fillRect(0, 0, width, height) context.rect(xOffset, yOffset, width - (xOffset * 2), height - (yOffset * 2)) + // draw the view grid for (var vl = 1; vl < twoDView.gridSize.width; vl++) { var xPos = (cellSize * vl) + xOffset diff --git a/qmlui/qml/fixturesfunctions/SettingsView2D.qml b/qmlui/qml/fixturesfunctions/SettingsView2D.qml index a501f20df9..e801e2f318 100644 --- a/qmlui/qml/fixturesfunctions/SettingsView2D.qml +++ b/qmlui/qml/fixturesfunctions/SettingsView2D.qml @@ -19,6 +19,7 @@ import QtQuick 2.0 import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.3 import org.qlcplus.classes 1.0 import "." @@ -203,140 +204,189 @@ Rectangle } } } // GridLayout - } // SectionBox + } // SectionBox - SectionBox - { - visible: fxPropsVisible - width: parent.width - isExpanded: fxPropsVisible - sectionLabel: qsTr("Selected fixtures") - - sectionContents: - GridLayout + SectionBox + { + width: parent.width + sectionLabel: qsTr("Custom Background") + sectionContents: + GridLayout + { + IconButton { - width: parent.width - columns: 2 - columnSpacing: 5 - rowSpacing: 2 + id: imgButton + width: UISettings.iconSizeMedium + height: width + imgSource: "qrc:/background.svg" - // row 1 - RobotoText - { - height: UISettings.listItemHeight - label: qsTr("Gel color") - } - Rectangle + onClicked: fileDialog.open() + + FileDialog { - Layout.fillWidth: true - height: UISettings.listItemHeight - color: gelColorTool.currentRGB + id: fileDialog + visible: false + title: qsTr("Select an image") + nameFilters: [ "Image files (*.png *.bmp *.jpg *.jpeg *.gif *.svg)", "All files (*)" ] - MouseArea + onAccepted: { - anchors.fill: parent - onClicked: gelColorTool.visible = !gelColorTool.visible + View2D.backgroundImage = fileDialog.fileUrl } } + } + + CustomTextEdit + { + Layout.fillWidth: true + height: UISettings.iconSizeMedium + text: View2D.backgroundImage + } + + IconButton + { + z: 2 + width: UISettings.iconSizeMedium + height: width + faSource: FontAwesome.fa_times + tooltip: qsTr("Reset background") + onClicked: View2D.backgroundImage = "" + } + } + } + + SectionBox + { + visible: fxPropsVisible + width: parent.width + isExpanded: fxPropsVisible + sectionLabel: qsTr("Selected fixtures") + + sectionContents: + GridLayout + { + width: parent.width + columns: 2 + columnSpacing: 5 + rowSpacing: 2 + + // row 1 + RobotoText + { + height: UISettings.listItemHeight + label: qsTr("Gel color") + } + Rectangle + { + Layout.fillWidth: true + height: UISettings.listItemHeight + color: gelColorTool.currentRGB - // row 2 - RobotoText + MouseArea { - height: UISettings.listItemHeight - label: qsTr("Rotation") + anchors.fill: parent + onClicked: gelColorTool.visible = !gelColorTool.visible } - CustomSpinBox + } + + // row 2 + RobotoText + { + height: UISettings.listItemHeight + label: qsTr("Rotation") + } + CustomSpinBox + { + id: fxRotSpin + Layout.fillWidth: true + height: UISettings.listItemHeight + from: -359 + to: 359 + suffix: "°" + value: { - id: fxRotSpin - Layout.fillWidth: true - height: UISettings.listItemHeight - from: -359 - to: 359 - suffix: "°" - value: + switch (View2D.pointOfView) { - switch (View2D.pointOfView) - { - case MonitorProperties.LeftSideView: - case MonitorProperties.RightSideView: - return fxRotation.x - - case MonitorProperties.FrontView: - return fxRotation.z - - default: - return fxRotation.y - } + case MonitorProperties.LeftSideView: + case MonitorProperties.RightSideView: + return fxRotation.x + + case MonitorProperties.FrontView: + return fxRotation.z + + default: + return fxRotation.y } - onValueModified: updateRotation(value) } + onValueModified: updateRotation(value) + } - // row 3 - RobotoText + // row 3 + RobotoText + { + height: UISettings.listItemHeight; + label: qsTr("Alignment") + } + + Row + { + Layout.fillWidth: true + + IconButton { - height: UISettings.listItemHeight; - label: qsTr("Alignment") + id: alignLeftBtn + width: UISettings.iconSizeDefault + height: width + bgColor: UISettings.bgLighter + imgSource: "qrc:/align-left.svg" + tooltip: qsTr("Align the selected items to the left") + onClicked: contextManager.setFixturesAlignment(Qt.AlignLeft) } - - Row + IconButton { - Layout.fillWidth: true - - IconButton - { - id: alignLeftBtn - width: UISettings.iconSizeDefault - height: width - bgColor: UISettings.bgLighter - imgSource: "qrc:/align-left.svg" - tooltip: qsTr("Align the selected items to the left") - onClicked: contextManager.setFixturesAlignment(Qt.AlignLeft) - } - IconButton - { - id: alignTopBtn - width: UISettings.iconSizeDefault - height: width - bgColor: UISettings.bgLighter - imgSource: "qrc:/align-top.svg" - tooltip: qsTr("Align the selected items to the top") - onClicked: contextManager.setFixturesAlignment(Qt.AlignTop) - } + id: alignTopBtn + width: UISettings.iconSizeDefault + height: width + bgColor: UISettings.bgLighter + imgSource: "qrc:/align-top.svg" + tooltip: qsTr("Align the selected items to the top") + onClicked: contextManager.setFixturesAlignment(Qt.AlignTop) } + } + + // row 3 + RobotoText + { + height: UISettings.listItemHeight; + label: qsTr("Distribution") + } - // row 3 - RobotoText + Row + { + Layout.fillWidth: true + + IconButton { - height: UISettings.listItemHeight; - label: qsTr("Distribution") + id: distributeXBtn + width: UISettings.iconSizeDefault + height: width + bgColor: UISettings.bgLighter + imgSource: "qrc:/distribute-x.svg" + tooltip: qsTr("Equally distribute horizontally the selected items") + onClicked: contextManager.setFixturesDistribution(Qt.Horizontal) } - - Row + IconButton { - Layout.fillWidth: true - - IconButton - { - id: distributeXBtn - width: UISettings.iconSizeDefault - height: width - bgColor: UISettings.bgLighter - imgSource: "qrc:/distribute-x.svg" - tooltip: qsTr("Equally distribute horizontally the selected items") - onClicked: contextManager.setFixturesDistribution(Qt.Horizontal) - } - IconButton - { - id: distributeYBtn - width: UISettings.iconSizeDefault - height: width - bgColor: UISettings.bgLighter - imgSource: "qrc:/distribute-y.svg" - tooltip: qsTr("Equally distribute vertically the selected items") - onClicked: contextManager.setFixturesDistribution(Qt.Vertical) - } + id: distributeYBtn + width: UISettings.iconSizeDefault + height: width + bgColor: UISettings.bgLighter + imgSource: "qrc:/distribute-y.svg" + tooltip: qsTr("Equally distribute vertically the selected items") + onClicked: contextManager.setFixturesDistribution(Qt.Vertical) } - } // GridLayout - } // SectionBox + } + } // GridLayout + } // SectionBox } // Column } diff --git a/qmlui/tardis/tardis.cpp b/qmlui/tardis/tardis.cpp index 2608863ba4..5ec24f0719 100644 --- a/qmlui/tardis/tardis.cpp +++ b/qmlui/tardis/tardis.cpp @@ -28,6 +28,7 @@ #include "fixturemanager.h" #include "functionmanager.h" #include "contextmanager.h" +#include "mainview2d.h" #include "simpledesk.h" #include "collection.h" #include "rgbmatrix.h" @@ -543,6 +544,11 @@ int Tardis::processAction(TardisAction &action, bool undo) m_contextManager->setEnvironmentSize(value->value()); } break; + case EnvironmentBackgroundImage: + { + m_contextManager->get2DView()->setBackgroundImage(value->toString()); + } + break; case FixtureSetPosition: { QVector3D pos = value->value(); diff --git a/qmlui/tardis/tardis.h b/qmlui/tardis/tardis.h index 8309c03037..ae87a29e44 100644 --- a/qmlui/tardis/tardis.h +++ b/qmlui/tardis/tardis.h @@ -66,6 +66,7 @@ class Tardis : public QThread { /* Preview settings */ EnvironmentSetSize = 0x0000, + EnvironmentBackgroundImage, FixtureSetPosition, FixtureSetRotation, GenericItemSetPosition,