diff options
author | Janne Kangas <janne.kangas@qt.io> | 2018-11-14 13:40:38 +0200 |
---|---|---|
committer | Janne Kangas <janne.kangas@qt.io> | 2019-02-06 06:13:26 +0000 |
commit | 9a5714c4051f6e0c9a16ba1ff6f27eb471994496 (patch) | |
tree | 1e9c7d5645e08330f024ea2d82c8125565e5bedb | |
parent | e3529c59f265c3cd4834c9c2ebddaff839b0bd8a (diff) |
Implement datainput getter API in Q3DSPresentation
Returns QVariantList containing Q3DSDataInput* allowing both QML
and C++ iterate through datainputs defined in the presentation. Also
implement isValid() that checks that datainput name is valid and datainput
is associated with a presentation. Modify qmldatainput example and provide
"cppdatainput" example for C++ side.
Change-Id: I83afda1b03326390f4cf4f23c68219248a9d3ae2
Task-id: QT3DS-2204
Reviewed-by: Pasi Keränen <pasi.keranen@qt.io>
21 files changed, 392 insertions, 22 deletions
diff --git a/examples/3dstudioruntime2/3dstudioruntime2.pro b/examples/3dstudioruntime2/3dstudioruntime2.pro index d30bbc0..b1b2946 100644 --- a/examples/3dstudioruntime2/3dstudioruntime2.pro +++ b/examples/3dstudioruntime2/3dstudioruntime2.pro @@ -2,7 +2,8 @@ TEMPLATE = subdirs SUBDIRS += \ simplewindow \ - simpleoffscreen + simpleoffscreen \ + cppdatainput qtHaveModule(quick) { SUBDIRS += simpleqml \ diff --git a/examples/3dstudioruntime2/cppdatainput/cppdatainput.pro b/examples/3dstudioruntime2/cppdatainput/cppdatainput.pro new file mode 100644 index 0000000..d8753c0 --- /dev/null +++ b/examples/3dstudioruntime2/cppdatainput/cppdatainput.pro @@ -0,0 +1,11 @@ +CONFIG += c++11 +QT += widgets qml quick 3dstudioruntime2 + +target.path = $$[QT_INSTALL_EXAMPLES]/3dstudioruntime2/$$TARGET +INSTALLS += target + +SOURCES += \ + main.cpp + +RESOURCES += \ + res.qrc diff --git a/examples/3dstudioruntime2/cppdatainput/main.cpp b/examples/3dstudioruntime2/cppdatainput/main.cpp new file mode 100644 index 0000000..0ae25fb --- /dev/null +++ b/examples/3dstudioruntime2/cppdatainput/main.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt 3D Studio. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQmlApplicationEngine> +#include <Q3DSSurfaceViewer> +#include <QWindow> +#include <QSurface> +#include <Q3DSPresentation> +#include <QOpenGLContext> +#include <Q3DSDataInput> +#include <QVector3D> +#include <QTimer> +// Required for Ubuntu build +#include <cmath> + +int main(int argc, char *argv[]) +{ + float colorRed = 0.0f; + int range = 0; + + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + + QGuiApplication app(argc, argv); + QSurfaceFormat::setDefaultFormat(Q3DS::surfaceFormat()); + + QOpenGLContext context; + if (!context.create()) + qFatal("Failed to create OpenGL context"); + + QWindow window; + window.setSurfaceType(QSurface::OpenGLSurface); + window.setFormat(context.format()); + window.create(); + + Q3DSSurfaceViewer viewer; + + QObject::connect(&viewer, &Q3DSSurfaceViewer:: presentationLoaded, &viewer, [&] { + const QVariantList diList = viewer.presentation()->getDataInputs(); + for (const auto &it : diList) { + Q3DSDataInput *dynDi = qvariant_cast<Q3DSDataInput *>(it); + if (dynDi->name().contains(QLatin1String("color"))) { + if (dynDi->isValid()) { + QObject::connect(&viewer, &Q3DSSurfaceViewer::frameUpdate, + [&colorRed, dynDi] { + dynDi->setValue(QVector3D(colorRed, 0.5, 0.5)); + colorRed = std::fmod(colorRed + 0.001f, 1.0f); + }); + } + } else if (dynDi->name().contains(QLatin1String("range"))) { + if (dynDi->isValid()) { + QObject::connect(&viewer, &Q3DSSurfaceViewer::frameUpdate, [&range, dynDi] { + dynDi->setValue(range); + range = (range + 1) % 360; + }); + } + } + } + }); + + viewer.presentation()->setSource(QUrl(QStringLiteral("qrc:presentation/datainput.uia"))); + viewer.setUpdateInterval(0); // enable automatic updates + + viewer.create(&window, &context); + + window.setTitle(QStringLiteral("Qt 3D Studio Example")); + window.resize(800, 480); + window.show(); + + return app.exec(); +} diff --git a/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uia b/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uia new file mode 100644 index 0000000..cbe778f --- /dev/null +++ b/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uia @@ -0,0 +1,17 @@ +<?xml version='1.0' encoding='UTF-8'?> +<application> + <assets initial="datainput"> + <presentation id="datainput" src="datainput.uip"/> + <dataInput name="colorInput" type="Vector3"/> + <dataInput name="rangeInput" type="Ranged Number" min="0" max="360"/> + </assets> + <statemachine ref="#logic"> + <visual-states> + <state ref="Initial"> + <enter> + <goto-slide element="main:Scene" rel="next"/> + </enter> + </state> + </visual-states> + </statemachine> +</application> diff --git a/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uip b/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uip new file mode 100644 index 0000000..d54f210 --- /dev/null +++ b/examples/3dstudioruntime2/cppdatainput/presentation/datainput.uip @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<UIP version="5" > + <Project > + <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" preferKtx="False" > + <CustomColors count="16" >#ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors> + </ProjectSettings> + <Graph > + <Scene id="Scene" controlledproperty="$rangeInput @timeline" > + <Layer id="Layer" > + <Camera id="Camera" /> + <Light id="Light" /> + <Text id="Text" /> + <Text id="Text2" /> + <Model id="Cylinder" > + <Material id="Default_002" name="Default" /> + </Model> + <Text id="Text4" /> + <Model id="Rectangle" > + <Material id="Default_001" name="Default" /> + </Model> + </Layer> + </Scene> + </Graph> + <Logic > + <State name="Master Slide" component="#Scene" > + <Add ref="#Layer" multisampleaa="SSAA" progressiveaa="8x" /> + <Add ref="#Camera" controlledproperty="" pivot="0 0 0" position="0 0 -800" rotation="0 0 0" /> + <Add ref="#Light" castshadow="True" controlledproperty="$colorInput lightdiffuse" lightdiffuse="1 0 0" lighttype="Point" position="-300.444 70.829 -30" shdwfactor="11.89" shdwfilter="6.94" shdwmapres="11" /> + <State id="Scene-Slide1" name="Slide1" initialplaystate="Pause" > + <Add ref="#Text" name="Text" controlledproperty="$rangeInput textstring" font="TitilliumWeb-Regular" position="216.513 76.6172 -113.498" scale="1 1 1" size="24" textstring="0" > + <AnimationTrack property="rotation.x" type="EaseInOut" >0 0 0 0 10 0 0 0</AnimationTrack> + <AnimationTrack property="rotation.y" type="EaseInOut" >0 0 0 0 10 0 0 0</AnimationTrack> + <AnimationTrack property="rotation.z" type="EaseInOut" >0 0 0 0 10 -360 0 0</AnimationTrack> + </Add> + <Add ref="#Text2" name="Text2" controlledproperty="" font="TitilliumWeb-Regular" position="259.808 217.95 0" scale="1 1 1" size="16" textstring="Text control Rotation animation control via datainput timeline control" /> + <Add ref="#Cylinder" name="Cylinder" controlledproperty="" position="15.877 -141.932 0" sourcepath="#Cylinder" /> + <Add ref="#Default_002" diffuse="0.666667 1 0.498039" /> + <Add ref="#Text4" name="Text4" font="TitilliumWeb-Regular" position="-373.353 201.004 0" size="18" textstring="Directional light color control" /> + <Add ref="#Rectangle" name="Rectangle" position="0 -400 20" rotation="90.5 0 0" scale="11.0468 7.99191 9.12813" sourcepath="#Rectangle" /> + <Add ref="#Default_001" diffuse="0.623529 0.623529 0.623529" /> + </State> + </State> + </Logic> + </Project> +</UIP> diff --git a/examples/3dstudioruntime2/cppdatainput/res.qrc b/examples/3dstudioruntime2/cppdatainput/res.qrc new file mode 100644 index 0000000..9beb456 --- /dev/null +++ b/examples/3dstudioruntime2/cppdatainput/res.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>presentation/datainput.uia</file> + <file>presentation/datainput.uip</file> + </qresource> +</RCC> diff --git a/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uia b/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uia index 66b1518..67014ae 100644 --- a/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uia +++ b/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uia @@ -1,21 +1,22 @@ -<?xml version="1.0" encoding="UTF-8" ?> +<?xml version='1.0' encoding='UTF-8'?> <application> - <assets initial="datainput"> - <presentation id="datainput" src="datainput.uip"/> - <dataInput name="cameraRotInput" type="Vector3"/> - <dataInput name="colorInput" type="Vector3"/> - <dataInput name="rangeInput" type="Ranged Number" min="0" max="360"/> - <dataInput name="scaleInput" type="Vector3"/> - <dataInput name="stringInput" type="String"/> - <dataInput name="variantInput" type="Variant"/> - </assets> - <statemachine ref="#logic"> - <visual-states> - <state ref="Initial"> - <enter> - <goto-slide element="main:Scene" rel="next"/> - </enter> - </state> - </visual-states> - </statemachine> + <assets initial="datainput"> + <presentation id="datainput" src="datainput.uip"/> + <dataInput name="cameraRotInput" type="Vector3"/> + <dataInput name="colorInput" type="Vector3"/> + <dataInput name="queriedInput" type="String"/> + <dataInput name="rangeInput" type="Ranged Number" min="0" max="360"/> + <dataInput name="scaleInput" type="Vector3"/> + <dataInput name="stringInput" type="String"/> + <dataInput name="variantInput" type="Variant"/> + </assets> + <statemachine ref="#logic"> + <visual-states> + <state ref="Initial"> + <enter> + <goto-slide rel="next" element="main:Scene"/> + </enter> + </state> + </visual-states> + </statemachine> </application> diff --git a/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uip b/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uip index e4e6ba1..7475629 100644 --- a/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uip +++ b/examples/3dstudioruntime2/qmldatainput/presentation/datainput.uip @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<UIP version="4" > +<UIP version="5" > <Project > - <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" > + <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" preferKtx="False" > <CustomColors count="16" >#ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff #ffffff</CustomColors> </ProjectSettings> <Graph > @@ -29,6 +29,7 @@ <Image id="Default_001_diffusemap" /> </Material> </Model> + <Text id="Text5" /> </Layer> </Scene> </Graph> @@ -57,6 +58,7 @@ <Add ref="#Rectangle" name="Rectangle" position="0 -400 20" rotation="90.5 0 0" scale="11.0468 7.99191 9.12813" sourcepath="#Rectangle" /> <Add ref="#Default_001" diffuse="0.623529 0.623529 0.623529" diffusemap="#Default_001_diffusemap" /> <Add ref="#Default_001_diffusemap" sourcepath="Paper05.png" /> + <Add ref="#Text5" name="Text5" controlledproperty="$queriedInput textstring" font="TitilliumWeb-Regular" position="-57.7348 3.84888 0" textstring="Text from queried QML Datainput" /> </State> </State> </Logic> diff --git a/examples/3dstudioruntime2/qmldatainput/qml/qmldatainput/main.qml b/examples/3dstudioruntime2/qmldatainput/qml/qmldatainput/main.qml index c0757e2..696c3d7 100644 --- a/examples/3dstudioruntime2/qmldatainput/qml/qmldatainput/main.qml +++ b/examples/3dstudioruntime2/qmldatainput/qml/qmldatainput/main.qml @@ -57,9 +57,44 @@ Item { height: 768 visible: true + // Show the list of datainputs queried by Q3DSPresentation queried from Presentation + Column { + id : diColumn + opacity: 50 + z: 1 + + Text { text: "Datainputs"; color: "red"; bottomPadding: 5; } + + Repeater { + id: diList + height: childrenRect.height + + function updateModel() { + // Datainput list is accessible from QML as JS array + var diList = studio3D.presentation.getDataInputs(); + model = diList; + for (var i = 0; i < count; ++i) { + // Use dynamically queried datainput to set value. + if (itemAt(i).text === "queriedInput") { + console.log("Updating " + diList[i].name); + diList[i].value = "This text is controlled by " + diList[i].name; + } + } + } + + Text { + id: diItem + color: "red" + text: modelData.name + } + } + } + Studio3D { id: studio3D anchors.fill: parent + height: 900 + width: 1280 property real inputNumber: 0 property vector3d inputColorVec3: Qt.vector3d(0, 0, 0) @@ -68,6 +103,10 @@ Item { property string inputString: "" property variant inputVariant: 0 + onPresentationLoaded: { + diList.updateModel(); + } + // A changing property to demonstrate DataInput NumberAnimation { target: studio3D @@ -127,6 +166,8 @@ Item { // Presentation item is used to control the presentation. //![1] Presentation { + id: presentation + source: "qrc:/presentation/datainput.uia" DataInput { // Name must match the data input name specified in the presentation diff --git a/src/runtime/api/q3dsdatainput.cpp b/src/runtime/api/q3dsdatainput.cpp index 77b999a..6d6150e 100644 --- a/src/runtime/api/q3dsdatainput.cpp +++ b/src/runtime/api/q3dsdatainput.cpp @@ -29,6 +29,7 @@ #include "q3dsdatainput_p.h" #include "q3dspresentation.h" +#include "q3dspresentation_p.h" QT_BEGIN_NAMESPACE @@ -123,6 +124,23 @@ QVariant Q3DSDataInput::value() const return d->value; } +/*! + Returns true if presentation (or its subpresentation) associated with + this datainput has a datainput definition with a matching name. Returns + false if the datainput has no associated presentation, or if a match is not found. + */ +bool Q3DSDataInput::isValid() const +{ + Q_D(const Q3DSDataInput); + // Fast exit if name or presentation is null + if (name().isEmpty() || !d->presentation) { + return false; + } else { + return Q3DSPresentationPrivate::get(d->presentation) + ->controller->handleIsValidDataInput(this); + } +} + void Q3DSDataInput::setValue(const QVariant &value) { Q_D(Q3DSDataInput); diff --git a/src/runtime/api/q3dsdatainput.h b/src/runtime/api/q3dsdatainput.h index c869c9e..7d5b710 100644 --- a/src/runtime/api/q3dsdatainput.h +++ b/src/runtime/api/q3dsdatainput.h @@ -57,6 +57,7 @@ public: QString name() const; QVariant value() const; + bool isValid() const; public Q_SLOTS: void setName(const QString &name); @@ -76,4 +77,6 @@ private: QT_END_NAMESPACE +Q_DECLARE_METATYPE(Q3DSDataInput*) + #endif // Q3DSDATAINPUT_H diff --git a/src/runtime/api/q3dspresentation.cpp b/src/runtime/api/q3dspresentation.cpp index 102f714..0fa84a7 100644 --- a/src/runtime/api/q3dspresentation.cpp +++ b/src/runtime/api/q3dspresentation.cpp @@ -28,6 +28,8 @@ ****************************************************************************/ #include "q3dspresentation_p.h" +#include "q3dsdatainput.h" +#include "q3dsdatainput_p.h" QT_BEGIN_NAMESPACE @@ -415,6 +417,39 @@ void Q3DSPresentation::setAttribute(const QString &elementPath, const QString &a } /*! + Returns a list of datainputs defined for this presentation. Use setDataInputValue() + interface to set a datainput value using datainput name, or call Q3DSDataInput::setValue + directly for a specific datainput. + + \sa setDataInputValue + \sa Q3DSDataInput + */ +QVariantList Q3DSPresentation::getDataInputs() +{ + Q_D(Q3DSPresentation); + QVariantList ret; + if (d->controller) { + const auto diList = d->controller->handleGetDataInputs(); + for (auto it : diList) { + // Assign "this" as presentation associated with this datainput, + // as the query from Q3DSUipPresentation does not return + // actual datainput object references with presentation associations. + // Instead we get datainput metadata stored in DataInput entry map. + // Actual datainput object is therefore created on the fly based on this metadata and + // handed out to API client. + // Here we associate DI with the presentation object that is now available + // in order for setValue calls to be correctly routed. + Q3DSDataInputPrivate::get(it)->presentation = this; + QVariant var(QVariant::fromValue(it)); + ret.append(var); + } + return ret; + } else { + return QVariantList(); + } +} + +/*! \fn void Q3DSPresentation::customSignalEmitted(const QString &elementPath, const QString &name) This signal is emitted when an action with the \c{Emit Signal} diff --git a/src/runtime/api/q3dspresentation.h b/src/runtime/api/q3dspresentation.h index a04a226..8144091 100644 --- a/src/runtime/api/q3dspresentation.h +++ b/src/runtime/api/q3dspresentation.h @@ -44,6 +44,7 @@ class QWheelEvent; class QTouchEvent; class QTabletEvent; class Q3DSEngine; +class Q3DSDataInput; // hack. no clue why Cpp.ignoretokens does not work. #ifdef Q_CLANG_QDOC @@ -88,6 +89,8 @@ public: Q_INVOKABLE QVariant getAttribute(const QString &elementPath, const QString &attributeName); Q_INVOKABLE void setAttribute(const QString &elementPath, const QString &attributeName, const QVariant &value); + Q_INVOKABLE QVariantList getDataInputs(); + void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); void mousePressEvent(QMouseEvent *e); diff --git a/src/runtime/api/q3dspresentation_p.h b/src/runtime/api/q3dspresentation_p.h index eab60dd..b04b874 100644 --- a/src/runtime/api/q3dspresentation_p.h +++ b/src/runtime/api/q3dspresentation_p.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class Q3DSEngine; +class Q3DSDataInput; class Q3DSInlineQmlSubPresentation; class Q3DSV_PRIVATE_EXPORT Q3DSPresentationController @@ -83,6 +84,8 @@ public: #endif virtual void handleDataInputValue(const QString &name, const QVariant &value); + virtual QVector<Q3DSDataInput *> handleGetDataInputs() const; + virtual bool handleIsValidDataInput(const Q3DSDataInput *di) const; virtual void handleFireEvent(const QString &elementPath, const QString &eventName); virtual void handleGoToTime(const QString &elementPath, float timeSeconds); virtual void handleGoToSlideByName(const QString &elementPath, const QString &name); diff --git a/src/runtime/api/q3dspresentationcontroller.cpp b/src/runtime/api/q3dspresentationcontroller.cpp index e7e6d33..a46b64e 100644 --- a/src/runtime/api/q3dspresentationcontroller.cpp +++ b/src/runtime/api/q3dspresentationcontroller.cpp @@ -128,6 +128,22 @@ void Q3DSPresentationController::handleDataInputValue(const QString &name, const m_pendingDataInputSets.append({ name, value }); // defer to initializePresentationController } +QVector<Q3DSDataInput *> Q3DSPresentationController::handleGetDataInputs() const +{ + if (m_pcEngine) + return m_pcEngine->dataInputs(); + else + return QVector<Q3DSDataInput *>(); +} + +bool Q3DSPresentationController::handleIsValidDataInput(const Q3DSDataInput *di) const +{ + if (m_pcEngine) + return m_pcEngine->isValidDataInput(di); + else + return false; +} + void Q3DSPresentationController::handleFireEvent(const QString &elementPath, const QString &eventName) { if (!m_pcEngine) diff --git a/src/runtime/q3dsengine.cpp b/src/runtime/q3dsengine.cpp index 875e422..034d26f 100644 --- a/src/runtime/q3dsengine.cpp +++ b/src/runtime/q3dsengine.cpp @@ -35,6 +35,7 @@ #include "q3dsinputmanager_p.h" #include "q3dsinlineqmlsubpresentation_p.h" #include "q3dsviewportsettings_p.h" +#include "q3dsdatainput.h" #include <QCoreApplication> #include <QLoggingCategory> @@ -1534,6 +1535,29 @@ void Q3DSEngine::setDataInputValue(const QString &name, const QVariant &value) } } +QVector<Q3DSDataInput *> Q3DSEngine::dataInputs() const +{ + QVector<Q3DSDataInput *> dataInputs; + for (const UipPresentation &pres : qAsConst(m_uipPresentations)) { + if (pres.sceneManager) + dataInputs.append(pres.sceneManager->dataInputs()); + } + + return dataInputs; +} + +bool Q3DSEngine::isValidDataInput(const Q3DSDataInput *di) const +{ + if (m_uipPresentations.isEmpty()) + return false; + + for (const UipPresentation &pres : qAsConst(m_uipPresentations)) { + if (pres.presentation->isValidDataInput(di)) + return true; + } + return false; +} + void Q3DSEngine::fireEvent(Q3DSGraphObject *target, Q3DSUipPresentation *presentation, const QString &event) { for (const UipPresentation &pres : qAsConst(m_uipPresentations)) { diff --git a/src/runtime/q3dsengine_p.h b/src/runtime/q3dsengine_p.h index 162c205..1729a94 100644 --- a/src/runtime/q3dsengine_p.h +++ b/src/runtime/q3dsengine_p.h @@ -47,6 +47,7 @@ #include <Qt3DCore/QAspectEngine> #include "q3dsuipdocument_p.h" #include "q3dsuiadocument_p.h" +#include "q3dsdatainput.h" #include "q3dsuiaparser_p.h" #include "q3dsscenemanager_p.h" #include "private/q3dsbehaviorobject_p.h" @@ -164,6 +165,8 @@ public: void resize(const QSize &size, qreal dpr = qreal(1.0), bool forceSynchronous = false); void setDataInputValue(const QString &name, const QVariant &value); + QVector<Q3DSDataInput *> dataInputs() const; + bool isValidDataInput(const Q3DSDataInput *di) const; void fireEvent(Q3DSGraphObject *target, Q3DSUipPresentation *presentation, const QString &event); void goToTime(Q3DSGraphObject *context, Q3DSUipPresentation *presentation, float milliseconds); void goToSlideByName(Q3DSGraphObject *context, Q3DSUipPresentation *presentation, const QString &name); diff --git a/src/runtime/q3dsscenemanager.cpp b/src/runtime/q3dsscenemanager.cpp index 563b2b4..6adb13f 100644 --- a/src/runtime/q3dsscenemanager.cpp +++ b/src/runtime/q3dsscenemanager.cpp @@ -8757,6 +8757,18 @@ void Q3DSSceneManager::setDataInputValue(const QString &dataInputName, const QVa } } +QVector<Q3DSDataInput *> Q3DSSceneManager::dataInputs() const +{ + const auto dataInputEntries = m_presentation->dataInputEntries(); + + QVector<Q3DSDataInput *> outVec; + + for (auto &it : *dataInputEntries) + outVec.append(new Q3DSDataInput(nullptr, it.name)); + + return outVec; +} + void Q3DSSceneManager::handleEvent(const Q3DSGraphObject::Event &e) { Q3DSSlide *slide = currentSlide(); diff --git a/src/runtime/q3dsscenemanager_p.h b/src/runtime/q3dsscenemanager_p.h index 944718d..5d7996d 100644 --- a/src/runtime/q3dsscenemanager_p.h +++ b/src/runtime/q3dsscenemanager_p.h @@ -68,6 +68,7 @@ class Q3DSAbstractSlidePlayer; class Q3DSConsoleCommands; class Q3DSScenePicker; struct Q3DSAnimator; +class Q3DSDataInput; namespace Qt3DCore { class QEntity; @@ -802,6 +803,7 @@ public: Qt3DCore::QEntity *getRootEntity() const { return m_rootEntity; } void setDataInputValue(const QString &dataInputName, const QVariant &value); + QVector<Q3DSDataInput *> dataInputs() const; void changeSlideByName(Q3DSGraphObject *sceneOrComponent, const QString &name); void changeSlideByIndex(Q3DSGraphObject *sceneOrComponent, int index); void changeSlideByDirection(Q3DSGraphObject *sceneOrComponent, bool next, bool wrap); diff --git a/src/runtime/q3dsuippresentation.cpp b/src/runtime/q3dsuippresentation.cpp index 4213e20..a7db195 100644 --- a/src/runtime/q3dsuippresentation.cpp +++ b/src/runtime/q3dsuippresentation.cpp @@ -4395,6 +4395,13 @@ const Q3DSDataInputEntry::Map *Q3DSUipPresentation::dataInputEntries() const return d->dataInputEntries; } +bool Q3DSUipPresentation::isValidDataInput(const Q3DSDataInput *di) const +{ + // Only check for name validity here. Q3DSUipPresentation is not concerned + // about the presentation object that Q3DSDataInput belongs to. + return d->dataInputEntries->contains(di->name()); +} + // Each Q3DSGraphObject has a table of the properties that are controlled // by data input. However, walking the scene graph on every data input // value change is not ideal. Therefore we maintain a central map in the diff --git a/src/runtime/q3dsuippresentation_p.h b/src/runtime/q3dsuippresentation_p.h index 55d88e8..f760e1a 100644 --- a/src/runtime/q3dsuippresentation_p.h +++ b/src/runtime/q3dsuippresentation_p.h @@ -47,6 +47,7 @@ #include "q3dsbehavior_p.h" #include "q3dsmeshloader_p.h" #include "q3dsdatainputentry_p.h" +#include "q3dsdatainput.h" #include <QString> #include <QVector> #include <QSet> @@ -2169,6 +2170,7 @@ public: void setDataInputEntries(const Q3DSDataInputEntry::Map *entries); const Q3DSDataInputEntry::Map *dataInputEntries() const; + bool isValidDataInput(const Q3DSDataInput *di) const; typedef QMultiHash<QString, Q3DSGraphObject *> DataInputMap; // data input entry name - target object const DataInputMap *dataInputMap() const; |