diff options
Diffstat (limited to 'src/runtime/api')
-rw-r--r-- | src/runtime/api/q3dsdatainput.cpp | 87 | ||||
-rw-r--r-- | src/runtime/api/q3dsdatainput.h | 1 | ||||
-rw-r--r-- | src/runtime/api/q3dselement.cpp | 138 | ||||
-rw-r--r-- | src/runtime/api/q3dselement.h | 1 | ||||
-rw-r--r-- | src/runtime/api/q3dspresentation.cpp | 356 | ||||
-rw-r--r-- | src/runtime/api/q3dssceneelement.cpp | 214 | ||||
-rw-r--r-- | src/runtime/api/q3dssceneelement.h | 1 | ||||
-rw-r--r-- | src/runtime/api/q3dssurfaceviewer.cpp | 139 | ||||
-rw-r--r-- | src/runtime/api/q3dsviewersettings.cpp | 51 | ||||
-rw-r--r-- | src/runtime/api/q3dswidget.cpp | 53 |
10 files changed, 1014 insertions, 27 deletions
diff --git a/src/runtime/api/q3dsdatainput.cpp b/src/runtime/api/q3dsdatainput.cpp index 9341c04..69cafe3 100644 --- a/src/runtime/api/q3dsdatainput.cpp +++ b/src/runtime/api/q3dsdatainput.cpp @@ -32,18 +32,31 @@ QT_BEGIN_NAMESPACE -Q3DSDataInput::Q3DSDataInput(QObject *parent) - : QObject(*new Q3DSDataInputPrivate, parent) -{ -} +/*! + \class Q3DSDataInput + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Controls a data input entry in a Qt 3D Studio presentation. + + This class is a convenience class for controlling a data input in a presentation. -Q3DSDataInput::Q3DSDataInput(const QString &name, QObject *parent) + \sa Q3DSPresentation +*/ + +/*! + \internal + */ +Q3DSDataInput::Q3DSDataInput(QObject *parent) : QObject(*new Q3DSDataInputPrivate, parent) { - Q_D(Q3DSDataInput); - d->name = name; } +/*! + Constructs a Q3DSDataInput instance and initializes the \a name. The + constructed instance is automatically associated with the specified \a + presentation. An optional \a parent object can be specified. + */ Q3DSDataInput::Q3DSDataInput(Q3DSPresentation *presentation, const QString &name, QObject *parent) : QObject(*new Q3DSDataInputPrivate, parent) { @@ -52,15 +65,29 @@ Q3DSDataInput::Q3DSDataInput(Q3DSPresentation *presentation, const QString &name d->presentation = presentation; } +/*! + \internal + */ Q3DSDataInput::Q3DSDataInput(Q3DSDataInputPrivate &dd, QObject *parent) : QObject(dd, parent) { } +/*! + Destructor. + */ Q3DSDataInput::~Q3DSDataInput() { } +/*! + \property Q3DSDataInput::name + + Specifies the name of the controlled data input element in the + presentation. This property must be set before setting the value property. + The initial value is provided via the constructor in practice, but the name + can also be changed later on, if desired. + */ QString Q3DSDataInput::name() const { Q_D(const Q3DSDataInput); @@ -76,6 +103,19 @@ void Q3DSDataInput::setName(const QString &name) } } +/*! + \property Q3DSDataInput::value + + Specifies the value of the controlled data input element in the + presentation. + + The value of this property only accounts for changes done via the same + Q3DSDataInput instance. If the value of the same data input in the + presentation is changed elsewhere, for example via presentation scripting, + those changes are not reflected in the value of this property. Due to this + uncertainty, this property treats all value sets as changes even if the + newly set value is the same value as the previous value. +*/ QVariant Q3DSDataInput::value() const { Q_D(const Q3DSDataInput); @@ -104,4 +144,37 @@ void Q3DSDataInputPrivate::sendValue() presentation->setDataInputValue(name, value); } +/*! + \qmltype DataInput + \instantiates Q3DSDataInput + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + \brief Control type for data inputs in a Qt 3D Studio presentation. + + This type is a convenience type for controlling a data input in a presentation. + + \sa Studio3D, Presentation +*/ + +/*! + \qmlproperty string DataInput::name + + Specifies the name of the controlled data input element in the presentation. + This property must be set as part of DataInput declaration. +*/ + +/*! + \qmlproperty variant DataInput::value + + Specifies the value of the controlled data input element in the presentation. + The changes to the value property are queued and handled asynchronously before the + next frame is displayed. + + The value of this property only accounts for changes done via the same DataInput instance. + If the value of the same data input in the presentation is changed elsewhere, + for example via presentation scripting, those changes are not reflected in + the value of this property. Due to this uncertainty, this property treats all value sets as + changes even if the newly set value is the same value as the previous value. +*/ + QT_END_NAMESPACE diff --git a/src/runtime/api/q3dsdatainput.h b/src/runtime/api/q3dsdatainput.h index e685f78..c869c9e 100644 --- a/src/runtime/api/q3dsdatainput.h +++ b/src/runtime/api/q3dsdatainput.h @@ -52,7 +52,6 @@ class Q3DSV_EXPORT Q3DSDataInput : public QObject public: explicit Q3DSDataInput(QObject *parent = nullptr); - explicit Q3DSDataInput(const QString &name, QObject *parent = nullptr); Q3DSDataInput(Q3DSPresentation *presentation, const QString &name, QObject *parent = nullptr); ~Q3DSDataInput(); diff --git a/src/runtime/api/q3dselement.cpp b/src/runtime/api/q3dselement.cpp index ae119ae..3e72e83 100644 --- a/src/runtime/api/q3dselement.cpp +++ b/src/runtime/api/q3dselement.cpp @@ -32,18 +32,38 @@ QT_BEGIN_NAMESPACE +/*! + \class Q3DSElement + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Controls a scene object in a Qt 3D Studio presentation. + + This class is a convenience class for controlling the properties of a scene + object (such as, model, material, camera, layer) in a Qt 3D Studio + presentation. + + \note The functionality of Q3DSElement is equivalent to + Q3DSPresentation::setAttribute(), Q3DSPresentation::getAttribute(), and + Q3DSPresentation::fireEvent(). + + \sa Q3DSPresentation, Q3DSWidget, Q3DSSurfaceViewer, Q3DSSceneElement + */ + +/*! + \internal + */ Q3DSElement::Q3DSElement(QObject *parent) : QObject(*new Q3DSElementPrivate, parent) { } -Q3DSElement::Q3DSElement(const QString &elementPath, QObject *parent) - : QObject(*new Q3DSElementPrivate, parent) -{ - Q_D(Q3DSElement); - d->elementPath = elementPath; -} - +/*! + Constructs a Q3DSElement instance controlling the scene object specified by + \a elementPath. An optional \a parent object can be specified. The + constructed instance is automatically associated with the specified \a + presentation. An optional \a parent object can be specified. + */ Q3DSElement::Q3DSElement(Q3DSPresentation *presentation, const QString &elementPath, QObject *parent) : QObject(*new Q3DSElementPrivate, parent) { @@ -52,15 +72,47 @@ Q3DSElement::Q3DSElement(Q3DSPresentation *presentation, const QString &elementP d->presentation = presentation; } +/*! + \internal + */ Q3DSElement::Q3DSElement(Q3DSElementPrivate &dd, QObject *parent) : QObject(dd, parent) { } +/*! + Destructor. + */ Q3DSElement::~Q3DSElement() { } +/*! + \property Q3DSElement::elementPath + + Holds the element path of the presentation element. + + An element path refers to an object in the scene either by name or id. The + latter is rarely used in application code since the unique IDs are not + exposed in the Qt 3D Studio application. To refer to an object by id, + prepend \c{#} to the name. Applications will typically refer to objects by + name. + + Names are not necessarily unique, however. To access an object with a + non-unique name, the path can be specified, for example, + \c{Scene.Layer.Camera}. Here the right camera object gets chosen even if + the scene contains other layers with the default camera names (for instance + \c{Scene.Layer2.Camera}). + + If the object is renamed to a unique name in the Qt 3D Studio application's + Timeline view, the path can be omitted. For example, if the camera in + question was renamed to \c MyCamera, applications can then simply pass \c + MyCamera as the element path. + + To access an object in a sub-presentation, prepend the name of the + sub-presentation followed by a colon, for example, + \c{SubPresentationOne:Scene.Layer.Camera}. + */ QString Q3DSElement::elementPath() const { Q_D(const Q3DSElement); @@ -76,6 +128,12 @@ void Q3DSElement::setElementPath(const QString &elementPath) } } +/*! + Returns the current value of an attribute (property) of the scene + object specified by elementPath. + + The \a attributeName is the \l{Attribute Names}{scripting name} of the attribute. + */ QVariant Q3DSElement::getAttribute(const QString &attributeName) const { Q_D(const Q3DSElement); @@ -85,6 +143,12 @@ QVariant Q3DSElement::getAttribute(const QString &attributeName) const return QVariant(); } +/*! + Sets the \a value of an attribute (property) of the scene object + specified by elementPath. + + The \a attributeName is the \l{Attribute Names}{scripting name} of the attribute. + */ void Q3DSElement::setAttribute(const QString &attributeName, const QVariant &value) { Q_D(Q3DSElement); @@ -92,6 +156,14 @@ void Q3DSElement::setAttribute(const QString &attributeName, const QVariant &val d->presentation->setAttribute(d->elementPath, attributeName, value); } +/*! + Dispatches an event with \a eventName on the scene object + specified by elementPath. + + Appropriate actions created in Qt 3D Studio or callbacks registered using + the registerForEvent() method in attached (behavior) scripts will be + executed in response to the event. + */ void Q3DSElement::fireEvent(const QString &eventName) { Q_D(Q3DSElement); @@ -104,4 +176,56 @@ void Q3DSElementPrivate::setPresentation(Q3DSPresentation *pres) presentation = pres; } +/*! + \qmltype Element + \instantiates Q3DSElement + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + \brief Control type for elements in a Qt 3D Studio presentation. + + This type is a convenience type for managing a presentation element. + + All methods provided by this type are queued and handled asynchronously before the next + frame is displayed. + + \sa Studio3D, Presentation, SceneElement +*/ + +/*! + \qmlproperty string Element::elementPath + + Holds the element path of the presentation element. + This property must be set as part of Element declaration. + You can specify an element of a sub-presentation by adding "SubPresentationId:" + in front of the element path, for example \c{"SubPresentationOne:Scene"}. +*/ + +/*! + \qmlmethod void Element::setAttribute(string attributeName, variant value) + + Sets the \a value of an attribute on an element specified by this instance. + The \a attributeName is the \l{Attribute Names}{scripting name} of the attribute. + + The attribute must be preserved for scripting to be set by this function, or else it will fail. + An attribute is preserved if it is either \e{animated}, or + \e{an attribute on a master element that is unlinked and changed per-slide}. +*/ + +/*! + \qmlmethod void Element::fireEvent(string eventName) + + Dispatches an event with \a eventName on the element specified by this instance. + Appropriate actions created in Qt 3D Studio or callbacks registered using the registerForEvent() + method in attached scripts will be executed in response to the event. +*/ + +/*! + \qmlsignal Element::elementPathChanged(string elementPath) + + This signal is emitted when the element path property changes. + The new value is provided in the \a elementPath parameter. + + The corresponding handler is \c onElementPathChanged. +*/ + QT_END_NAMESPACE diff --git a/src/runtime/api/q3dselement.h b/src/runtime/api/q3dselement.h index ec62590..7e5d0b8 100644 --- a/src/runtime/api/q3dselement.h +++ b/src/runtime/api/q3dselement.h @@ -51,7 +51,6 @@ class Q3DSV_EXPORT Q3DSElement : public QObject public: explicit Q3DSElement(QObject *parent = nullptr); - explicit Q3DSElement(const QString &elementPath, QObject *parent = nullptr); Q3DSElement(Q3DSPresentation *presentation, const QString &elementPath, QObject *parent = nullptr); ~Q3DSElement(); diff --git a/src/runtime/api/q3dspresentation.cpp b/src/runtime/api/q3dspresentation.cpp index 0f0cf89..0a797b2 100644 --- a/src/runtime/api/q3dspresentation.cpp +++ b/src/runtime/api/q3dspresentation.cpp @@ -31,6 +31,40 @@ QT_BEGIN_NAMESPACE +/*! + \class Q3DSPresentation + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Represents a Qt 3D Studio presentation. + + This class provides properties and methods for controlling a + presentation. + + Qt 3D Studio supports multiple presentations in one project. There + is always a main presentation and zero or more + sub-presentations. The sub-presentations are composed into the + main presentations either as contents of Qt 3D Studio layers or as + texture maps. + + In the filesystem each presentation corresponds to one \c{.uip} + file. When present, the \c{.uia} file ties these together by + specifying a name for each of the (sub-)presentations and + specifies which one is the main one. + + From the API point of view Q3DSPresentation corresponds to the + main presentation. The source property can refer either to a + \c{.uia} or \c{.uip} file. When specifying a file with \c{.uip} + extension and a \c{.uia} is present with the same name, the + \c{.uia} is loaded automatically and thus sub-presentation + information is available regardless. + + \note This class should not be instantiated directly when working with the + C++ APIs. Q3DSSurfaceViewer and Q3DSWidget create a Q3DSPresentation + instance implicitly. This can be queried via + Q3DSSurfaceViewer::presentation() or Q3DSWidget::presentation(). + */ + // Unlike in 3DS1, Q3DSPresentation here does not own the engine. This is due // to the delicate lifetime management needs due to Qt 3D under the hood: for // instance the Studio3D element has to carefully manage the underlying @@ -40,20 +74,41 @@ QT_BEGIN_NAMESPACE // Q3DSPresentationController (for common functionality), or individually by // Studio3D, Q3DSWidget, or Q3DSSurfaceViewer. +/*! + Constructs a new Q3DSPresentation with the given \a parent. + */ Q3DSPresentation::Q3DSPresentation(QObject *parent) : QObject(*new Q3DSPresentationPrivate, parent) { } +/*! + \internal + */ Q3DSPresentation::Q3DSPresentation(Q3DSPresentationPrivate &dd, QObject *parent) : QObject(dd, parent) { } +/*! + Destructor. + */ Q3DSPresentation::~Q3DSPresentation() { } +/*! + \property Q3DSPresentation::source + + Holds the name of the main presentation file (\c{*.uia} or + \c{*.uip}). This may be either a local file or qrc URL. + + The names of all further assets (image files for texture maps, qml + behavior scripts, mesh files) will be resolved relative to the + location of the presentation, unless they use absolute paths. This + allows bundling all assets next to the presentation in the Qt + resource system. +*/ QUrl Q3DSPresentation::source() const { Q_D(const Q3DSPresentation); @@ -128,6 +183,9 @@ void Q3DSPresentation::setProfileUiScale(float scale) } } +/*! + Reloads the presentation. + */ void Q3DSPresentation::reload() { Q_D(Q3DSPresentation); @@ -135,6 +193,21 @@ void Q3DSPresentation::reload() d->controller->handlePresentationReload(); } +/*! + Sets the \a value of a data input element \a name in the presentation. + + Data input provides a higher level, designer-driven alternative to + Q3DSElement and setAttribute(). Instead of exposing a large set of + properties with their intenal engine names, data input allows designers to + decide which properties should be writable by the application, and can + assign custom names to these data input entries, thus forming a + well-defined contract between the designer and the developer. + + In addition, data input also allows controlling the time line and the + current slide for time context objects (Scene or Component). Therefore it + is also an alternative to the goToSlide() and goToTime() family of APIs and + to Q3DSSceneElement. + */ void Q3DSPresentation::setDataInputValue(const QString &name, const QVariant &value) { Q_D(Q3DSPresentation); @@ -142,6 +215,14 @@ void Q3DSPresentation::setDataInputValue(const QString &name, const QVariant &va d->controller->handleDataInputValue(name, value); } +/*! + Dispatches an event with \a eventName on a specific element found in \a + elementPath. Appropriate actions created in Qt 3D Studio or callbacks + registered using the registerForEvent() method in attached (behavior) + scripts will be executed in response to the event. + + See setAttribute() for a description of \a elementPath. + */ void Q3DSPresentation::fireEvent(const QString &elementPath, const QString &eventName) { Q_D(Q3DSPresentation); @@ -149,6 +230,32 @@ void Q3DSPresentation::fireEvent(const QString &elementPath, const QString &even d->controller->handleFireEvent(elementPath, eventName); } +/*! + Moves the timeline for a time context (a Scene or a Component element) to a + specific position. The position is given in seconds in \a timeSeconds. + + If \a elementPath points to a time context, that element is + controlled. For all other element types the time context owning + that element is controlled instead. You can target the command to + a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example + \c{"SubPresentationOne:Scene"}. + + The behavior when specifying a time before 0 or after the end time + for the current slide depends on the play mode of the slide: + + \list + \li \c{Stop at End} - values outside the valid time range instead clamp to the boundaries. + For example, going to time -5 is the same as going to time 0. + \li \c{Looping} - values outside the valid time range mod into the valid range. For example, + going to time -4 on a 10 second slide is the same as going to time 6. + \li \c{Ping Pong} - values outside the valid time range bounce off the ends. For example, + going to time -4 is the same as going to time 4 (assuming the time context is at least 4 seconds + long), while going to time 12 on a 10 second slide is the same as going to time 8. + \li \c{Ping} - values less than 0 are treated as time 0, while values greater than the endtime + bounce off the end (eventually hitting 0.) + \endlist + */ void Q3DSPresentation::goToTime(const QString &elementPath, float timeSeconds) { Q_D(Q3DSPresentation); @@ -156,6 +263,17 @@ void Q3DSPresentation::goToTime(const QString &elementPath, float timeSeconds) d->controller->handleGoToTime(elementPath, timeSeconds); } +/*! + Requests a time context (a Scene or a Component object) to change + to a specific slide by \a name. If the context is already on that + slide, playback will start over. + + If \a elementPath points to a time context, that element is + controlled. For all other element types the time context owning + that element is controlled instead. You can target the command to + a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. + */ void Q3DSPresentation::goToSlide(const QString &elementPath, const QString &name) { Q_D(Q3DSPresentation); @@ -163,6 +281,17 @@ void Q3DSPresentation::goToSlide(const QString &elementPath, const QString &name d->controller->handleGoToSlideByName(elementPath, name); } +/*! + Requests a time context (a Scene or a Component object) to change + to a specific slide by \a index. If the context is already on that + slide, playback will start over. + + If \a elementPath points to a time context, that element is + controlled. For all other element types the time context owning + that element is controlled instead. You can target the command to + a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. + */ void Q3DSPresentation::goToSlide(const QString &elementPath, int index) { Q_D(Q3DSPresentation); @@ -170,6 +299,18 @@ void Q3DSPresentation::goToSlide(const QString &elementPath, int index) d->controller->handleGoToSlideByIndex(elementPath, index); } +/*! + Requests a time context (a Scene or a Component object) to change to the + next or previous slide, depending on the value of \a next. If the context + is already at the last or first slide, \a wrap defines if wrapping over to + the first or last slide, respectively, occurs. + + If \a elementPath points to a time context, that element is controlled. For + all other element types the time context owning that element is controlled + instead. You can target the command to a specific sub-presentation by + adding "SubPresentationId:" in front of the element path, for example + \c{"SubPresentationOne:Scene"}. + */ void Q3DSPresentation::goToSlide(const QString &elementPath, bool next, bool wrap) { Q_D(Q3DSPresentation); @@ -177,6 +318,15 @@ void Q3DSPresentation::goToSlide(const QString &elementPath, bool next, bool wra d->controller->handleGoToSlideByDirection(elementPath, next, wrap); } +/*! + Returns the value of an attribute (property) on the object specified by \a + elementPath. The \a attributeName is the \l{Attribute Names}{scripting + name} of the attribute. + + See setAttribute() for a description of \a elementPath. + + \sa setAttribute + */ QVariant Q3DSPresentation::getAttribute(const QString &elementPath, const QString &attributeName) { Q_D(Q3DSPresentation); @@ -186,6 +336,34 @@ QVariant Q3DSPresentation::getAttribute(const QString &elementPath, const QStrin return QVariant(); } +/*! + Sets the \a value of an attribute (property) on the object specified by + \a elementPath. The \a attributeName is the \l{Attribute Names}{scripting + name} of the attribute. + + An element path refers to an object in the scene either by name or id. The + latter is rarely used in application code since the unique IDs are not + exposed in the Qt 3D Studio application. To refer to an object by id, + prepend \c{#} to the name. Applications will typically refer to objects by + name. + + Names are not necessarily unique, however. To access an object with a + non-unique name, the path can be specified, for example, + \c{Scene.Layer.Camera}. Here the right camera object gets chosen even if + the scene contains other layers with the default camera names (for instance + \c{Scene.Layer2.Camera}). + + If the object is renamed to a unique name in the Qt 3D Studio application's + Timeline view, the path can be omitted. For example, if the camera in + question was renamed to \c MyCamera, applications can then simply pass \c + MyCamera as the element path. + + To access an object in a sub-presentation, prepend the name of the + sub-presentation followed by a colon, for example, + \c{SubPresentationOne:Scene.Layer.Camera}. + + \sa getAttribute + */ void Q3DSPresentation::setAttribute(const QString &elementPath, const QString &attributeName, const QVariant &value) { Q_D(Q3DSPresentation); @@ -292,4 +470,182 @@ void Q3DSPresentationPrivate::registerInlineQmlSubPresentations(const QVector<Q3 inlineQmlSubPresentations += list; } +/*! + \qmltype Presentation + \instantiates Q3DSPresentation + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + + \brief Control type for Qt 3D Studio presentations. + + This type provides properties and methods for controlling a presentation. + + All methods provided by this type are queued and handled asynchronously before the next + frame is displayed. + + \sa Studio3D +*/ + +/*! + \qmlproperty url Presentation::source + + Holds the presentation source (\c{*.uia} or \c{*.uip}) file location. + May be either a file URL or a qrc URL. +*/ + +/*! + \qmlproperty SubPresentationSettings Presentation::subPresentationSettings + + Holds the settings for the subpresentations in the Qt 3D Studio presentation. + + This property is read-only. +*/ + +/*! + \qmlmethod void Presentation::goToSlide(string elementPath, string name) + + Requests a time context (a Scene or a Component element) to change to a specific slide + by \a name. If the context is already on that slide playback will start over. + + If \a elementPath points to a time context, that element is controlled. For + all other element types the time context owning that element is controlled instead. + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. +*/ + +/*! + \qmlmethod void Presentation::goToSlide(string elementPath, int index) + + Requests a time context (a Scene or a Component element) to change to a specific slide by + index \a index. If the context is already on that slide playback will start over. + + If \a elementPath points to a time context, that element is controlled. For + all other element types the time context owning that element is controlled instead. + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. +*/ + +/*! + \qmlmethod void Presentation::goToSlide(string elementPath, bool next, bool wrap) + + Requests a time context (a Scene or a Component element) to change to the next or the + previous slide, depending on the value of \a next. If the context is already at the + last or first slide, \a wrap defines if change occurs to the opposite end. + + If \a elementPath points to a time context, that element is controlled. For + all other element types the time context owning that element is controlled instead. + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. +*/ + +/*! + \qmlmethod void Presentation::goToTime(string elementPath, real time) + + Sets a time context (a Scene or a Component element) to a specific playback \a time in seconds. + + If \a elementPath points to a time context, that element is controlled. For + all other element types the time context owning that element is controlled instead. + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene"}. + + The behavior when specifying a time before 0 or after the end time for the current slide depends + on the play mode of the slide: + \list + \li \c{Stop at End} - values outside the valid time range instead clamp to the boundaries. + For example, going to time -5 is the same as going to time 0. + \li \c{Looping} - values outside the valid time range mod into the valid range. For example, + going to time -4 on a 10 second slide is the same as going to time 6. + \li \c{Ping Pong} - values outside the valid time range ‘bounce’ off the ends. For example, + going to time -4 is the same as going to time 4 (assuming the time context is at least 4 seconds + long), while going to time 12 on a 10 second slide is the same as going to time 8. + \li \c{Ping} - values less than 0 are treated as time 0, while values greater than the endtime + bounce off the end (eventually hitting 0.) + \endlist +*/ + +/*! + \qmlmethod void Presentation::setAttribute(string elementPath, string attributeName, + variant value) + + Sets the \a value of an attribute on an element found at \a elementPath. The \a attributeName is + the \l{Attribute Names}{scripting name} of the attribute. + + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene.Mesh.Material"}. + + The attribute must be preserved for scripting to be set by this function, or else it will fail. + An attribute is preserved if it is either \e{animated}, or + \e{an attribute on a master element that is unlinked and changed per-slide}. +*/ + +/*! + \qmlmethod void Presentation::setPresentationActive(string id, bool active) + + Stops or starts updates to a sub-presentation based on the \a active flag. The presentation is + referenced to by the \a id, which is the name of the presentation without the \c{.uip}. + + Making a presentation inactive prevents any elements, behaviors, and animations within it from + updating. It also prevents any events within that presentation from being processed. It does + not, however, prevent the presentation from rendering. An inactive presentation will continue + to render using its last-updated information. + + Explicitly inactivating presentations can provide a significant performance increase, depending + on the number and size of the presentations that are inactive. Inactive presentations are not + ‘paused’. When the presentation is re-activated, animations will resume at the time they should + be had they been running, not where they were when the presentation was made inactive. +*/ + +/*! + \qmlmethod void Presentation::fireEvent(string elementPath, string eventName) + + Dispatches an event with \a eventName on a specific element found in \a elementPath. Appropriate + Appropriate actions created in Qt 3D Studio or callbacks registered using the registerForEvent() + method in attached scripts will be executed in response to the event. + + You can target the command to a specific sub-presentation by adding "SubPresentationId:" in + front of the element path, for example \c{"SubPresentationOne:Scene.Mesh"}. +*/ + +/*! + \qmlmethod void Presentation::setGlobalAnimationTime(int64 milliseconds) + + Sets the global animation time to \a milliseconds. Setting the global animation time to a + non-zero value will disable the automatic animation timer. Setting the value to zero + resumes automatic animation timer. +*/ + +/*! + \qmlmethod void Presentation::setDataInputValue(string name, variant value) + \since QtStudio3D 1.1 + + Sets the \a value of a data input element \a name in the presentation. +*/ + +/*! + \qmlsignal Presentation::slideEntered(string elementPath, int index, string name) + + This signal is emitted when a slide is entered in the presentation. + The \a elementPath specifies the time context (a Scene or a Component element) owning the + entered slide. + The \a index and \a name contain the index and the name of the entered slide. +*/ + +/*! + \qmlsignal Presentation::slideExited(string elementPath, int index, string name) + + This signal is emitted when a slide is exited in the presentation. + The \a elementPath specifies the time context (a Scene or a Component element) owning the + exited slide. + The \a index and \a name contain the index and the name of the exited slide. +*/ + +/*! + \qmlsignal Presentation::sourceChanged(url source) + + This signal is emitted when the source property has changed. + The new value is provided in the \a source parameter. + + The corresponding handler is \c onSourceChanged. +*/ + QT_END_NAMESPACE diff --git a/src/runtime/api/q3dssceneelement.cpp b/src/runtime/api/q3dssceneelement.cpp index f8b3e23..6b3c161 100644 --- a/src/runtime/api/q3dssceneelement.cpp +++ b/src/runtime/api/q3dssceneelement.cpp @@ -32,18 +32,39 @@ QT_BEGIN_NAMESPACE -Q3DSSceneElement::Q3DSSceneElement(QObject *parent) - : Q3DSElement(*new Q3DSSceneElementPrivate, parent) -{ -} +/*! + \class Q3DSSceneElement + \inherits Q3DSElement + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Controls the special Scene or Component scene objects in a Qt 3D + Studio presentation. + + This class is a convenience class for controlling the properties of Scene + and Component objects in the scene. These are special since they have a + time context, meaning they control a timline and a set of associated + slides. + + \note The functionality of Q3DSSceneElement is equivalent to + Q3DSPresentation::goToTime() and Q3DSPresentation::goToSlide(). + + \sa Q3DSPresentation, Q3DSWidget, Q3DSSurfaceViewer, Q3DSElement + */ -Q3DSSceneElement::Q3DSSceneElement(const QString &elementPath, QObject *parent) +/*! + \internal + */ +Q3DSSceneElement::Q3DSSceneElement(QObject *parent) : Q3DSElement(*new Q3DSSceneElementPrivate, parent) { - Q_D(Q3DSSceneElement); - d->elementPath = elementPath; } +/*! + Constructs a Q3DSSceneElement instance and associated it with the object + specified by \a elementPath and the given \a presentation. An optional \a + parent object can be specified. + */ Q3DSSceneElement::Q3DSSceneElement(Q3DSPresentation *presentation, const QString &elementPath, QObject *parent) : Q3DSElement(*new Q3DSSceneElementPrivate, parent) { @@ -52,33 +73,77 @@ Q3DSSceneElement::Q3DSSceneElement(Q3DSPresentation *presentation, const QString d->presentation = presentation; } +/*! + \internal + */ Q3DSSceneElement::Q3DSSceneElement(Q3DSSceneElementPrivate &dd, QObject *parent) : Q3DSElement(dd, parent) { } +/*! + Destructor. + */ Q3DSSceneElement::~Q3DSSceneElement() { } +/*! + \property Q3DSSceneElement::currentSlideIndex + + Holds the index of the currently active slide of the tracked time context. + + \note If this property is set to something else than the default slide for + the scene at the initial declaration of SceneElement, a changed signal for + the default slide may stil be emitted before the slide changes to the + desired one. This happens in order to ensure we end up with the index of + the slide that is actually shown even if the slide specified in the initial + declaration is invalid. +*/ int Q3DSSceneElement::currentSlideIndex() const { Q_D(const Q3DSSceneElement); return d->currentSlideIndex; } +/*! + \property Q3DSSceneElement::previousSlideIndex + + Holds the index of the previously active slide of the tracked time context. + + This property is read-only. +*/ int Q3DSSceneElement::previousSlideIndex() const { Q_D(const Q3DSSceneElement); return d->previousSlideIndex; } +/*! + \property Q3DSSceneElement::currentSlideName + + Holds the name of the currently active slide of the tracked time context. + + \note If this property is set to something else than the default slide for + the scene at the initial declaration of SceneElement, a changed signal for + the default slide may stil be emitted before the slide changes to the + desired one. This happens in order to ensure we end up with the index of + the slide that is actually shown even if the slide specified in the initial + declaration is invalid. +*/ QString Q3DSSceneElement::currentSlideName() const { Q_D(const Q3DSSceneElement); return d->currentSlideName; } +/*! + \property Q3DSSceneElement::previousSlideName + + Holds the name of the previously active slide of the tracked time context. + + This property is read-only. +*/ QString Q3DSSceneElement::previousSlideName() const { Q_D(const Q3DSSceneElement); @@ -105,6 +170,12 @@ void Q3DSSceneElement::setCurrentSlideName(const QString ¤tSlideName) d->pendingSlideSetName = currentSlideName; // defer to sendPendingValues() } +/*! + Requests a time context (a Scene or a Component object) to change to the + next or previous slide, depending on the value of \a next. If the context + is already at the last or first slide, \a wrap defines if wrapping over to + the first or last slide, respectively, occurs. + */ void Q3DSSceneElement::goToSlide(bool next, bool wrap) { Q_D(Q3DSSceneElement); @@ -112,6 +183,10 @@ void Q3DSSceneElement::goToSlide(bool next, bool wrap) d->presentation->goToSlide(d->elementPath, next, wrap); } +/*! + Moves the timeline for a time context (a Scene or a Component element) to a + specific position. The position is given in seconds in \a timeSeconds. + */ void Q3DSSceneElement::goToTime(float timeSeconds) { Q_D(Q3DSSceneElement); @@ -171,6 +246,131 @@ void Q3DSSceneElementPrivate::setPresentation(Q3DSPresentation *pres) q, SLOT(_q_onSlideEntered(QString,int,QString))); } +/*! + \qmltype SceneElement + \instantiates Q3DSSceneElement + \inherits Element + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + \brief Control type for scene and component elements in a Qt 3D Studio presentation. + + This type is a convenience type for managing the slides of a single + time context (a Scene or a Component element) of a presentation. + + All methods provided by this type are queued and handled asynchronously before the next + frame is displayed. + + \sa Studio3D, Presentation, Element +*/ + +/*! + \qmlproperty int SceneElement::currentSlideIndex + + Holds the index of the currently active slide of the tracked time context. + + Changing the current slide via this property is asynchronous. The property + value will not actually change until the next frame has been processed, and + even then only if the new slide was valid. + + \note If this property is set to something else than the default slide for the scene at the + initial declaration of SceneElement, you will still get an extra changed signal for the + default slide before the slide changes to the desired one. This happens in order to ensure + we end up with the index of the slide that is actually shown even if the slide specified in the + initial declaration is invalid. +*/ + +/*! + \qmlproperty int SceneElement::previousSlideIndex + + Holds the index of the previously active slide of the tracked time context. + + This property is read-only. +*/ + +/*! + \qmlproperty string SceneElement::currentSlideName + + Holds the name of the currently active slide of the tracked time context. + + Changing the current slide via this property is asynchronous. The property + value will not actually change until the next frame has been processed, and + even then only if the new slide was valid. + + \note If this property is set to something else than the default slide for the scene at the + initial declaration of SceneElement, you will still get an extra changed signal for the + default slide before the slide changes to the desired one. This happens in order to ensure + we end up with the name of the slide that is actually shown even if the slide specified in the + initial declaration is invalid. +*/ + +/*! + \qmlproperty string SceneElement::previousSlideName + + Holds the name of the previously active slide of the tracked time context. + + This property is read-only. +*/ + +/*! + \qmlsignal SceneElement::currentSlideIndexChanged(int currentSlideIndex) + + This signal is emitted when the current slide changes. + The new value is provided in the \a currentSlideIndex parameter. + + This signal is always emitted with currentSlideNameChanged. + + The corresponding handler is \c onCurrentSlideIndexChanged. +*/ + +/*! + \qmlsignal SceneElement::previousSlideIndexChanged(int previousSlideIndex) + + This signal is emitted when the previous slide changes. + The new value is provided in the \a previousSlideIndex parameter. + + This signal is always emitted with previousSlideNameChanged. + + The corresponding handler is \c onPreviousSlideIndexChanged. +*/ + +/*! + \qmlsignal SceneElement::currentSlideNameChanged(string currentSlideName) + + This signal is emitted when the current slide changes. + The new value is provided in the \a currentSlideName parameter. + + This signal is always emitted with currentSlideIndexChanged. + + The corresponding handler is \c onCurrentSlideNameChanged. +*/ + +/*! + \qmlsignal SceneElement::previousSlideNameChanged(string previousSlideName) + + This signal is emitted when the previous slide changes. + The new value is provided in the \a previousSlideName parameter. + + This signal is always emitted with previousSlideIndexChanged. + + The corresponding handler is \c onPreviousSlideNameChanged. +*/ + +/*! + \qmlmethod void SceneElement::goToSlide(bool next, bool wrap) + + Requests a time context (a Scene or a Component element) to change to the next or the + previous slide, depending on the value of \a next. If the context is already at the + last or first slide, \a wrap defines if change occurs to the opposite end. +*/ + +/*! + \qmlmethod void SceneElement::goToTime(string elementPath, real time) + + Sets a time context (a Scene or a Component element) to a specific playback \a time in seconds. + + For behavior details, see Presentation::goToTime() documentation. +*/ + QT_END_NAMESPACE #include "moc_q3dssceneelement.cpp" diff --git a/src/runtime/api/q3dssceneelement.h b/src/runtime/api/q3dssceneelement.h index d8eba18..b7726d3 100644 --- a/src/runtime/api/q3dssceneelement.h +++ b/src/runtime/api/q3dssceneelement.h @@ -52,7 +52,6 @@ class Q3DSV_EXPORT Q3DSSceneElement : public Q3DSElement public: explicit Q3DSSceneElement(QObject *parent = nullptr); - explicit Q3DSSceneElement(const QString &elementPath, QObject *parent = nullptr); Q3DSSceneElement(Q3DSPresentation *presentation, const QString &elementPath, QObject *parent = nullptr); ~Q3DSSceneElement(); diff --git a/src/runtime/api/q3dssurfaceviewer.cpp b/src/runtime/api/q3dssurfaceviewer.cpp index 853b96b..8ecb6c3 100644 --- a/src/runtime/api/q3dssurfaceviewer.cpp +++ b/src/runtime/api/q3dssurfaceviewer.cpp @@ -45,6 +45,56 @@ QT_BEGIN_NAMESPACE +/*! + \class Q3DSSurfaceViewer + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Renders a Qt 3D Studio presentation on a QWindow or an offscreen + render target using OpenGL. + + Q3DSSurfaceViewer is used to render Qt 3D Studio presentations onto a + QSurface. In practice this means two types of uses: rendering to an + on-screen QWindow, or rendering to an offscreen render target (typically an + OpenGL texture via a framebuffer object and a QOffscreenSurface). + + \section2 Example Usage + + \code + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + + QOpenGLContext context; + context.create(); + + QWindow window; + window.setSurfaceType(QSurface::OpenGLSurface); + window.setFormat(context.format()); + window.create(); + + Q3DSSurfaceViewer viewer; + viewer.presentation()->setSource(QUrl(QStringLiteral("qrc:/my_presentation.uip"))); + viewer.setUpdateInterval(0); // enable automatic updates + + // Register a scene object for slide management (optional) + Q3DSSceneElement scene(viewer.presentation(), QStringLiteral("Scene")); + + // Register an element object for attribute setting (optional) + Q3DSElement element(viewer.presentation(), QStringLiteral("myCarModel")); + + viewer.create(&window, &context); + + w.resize(1024, 768); + w.show(); + + return app.exec(); + } + \endcode + + \sa Q3DSWidget + */ + Q3DSSurfaceViewer::Q3DSSurfaceViewer(QObject *parent) : QObject(*new Q3DSSurfaceViewerPrivate, parent) { @@ -67,12 +117,35 @@ Q3DSSurfaceViewer::~Q3DSSurfaceViewer() // "use this custom FBO as-is". Changing to int would be wrong too since the ID // is a GLuint in practice. +/*! + Initializes Q3DSSurfaceViewer to render the presentation to the given + \a surface using the \a context. + + The source property of the attached presentation must be set before the + viewer can be initialized. + + Returns whether the initialization succeeded. + + \sa running, Q3DSPresentation::source, presentation() +*/ bool Q3DSSurfaceViewer::create(QSurface *surface, QOpenGLContext *context) { Q_D(Q3DSSurfaceViewer); return d->doCreate(surface, context, 0, false); } +/*! + Initializes Q3DSSurfaceViewer to render the presentation to the given + \a surface using the \a context and optional framebuffer id (\a fboId). If + \a fboId is omitted, it defaults to zero. + + The source property of the attached presentation must be set before the + viewer can be initialized. + + Returns whether the initialization succeeded. + + \sa running, Q3DSPresentation::source, presentation() +*/ bool Q3DSSurfaceViewer::create(QSurface *surface, QOpenGLContext *context, uint fboId) { Q_D(Q3DSSurfaceViewer); @@ -114,12 +187,18 @@ void Q3DSSurfaceViewer::destroy() d->fbo = 0; } +/*! + Returns the presentation object used by the Q3DSSurfaceViewer. +*/ Q3DSPresentation *Q3DSSurfaceViewer::presentation() const { Q_D(const Q3DSSurfaceViewer); return d->presentation; } +/*! + Returns the settings object used by the Q3DSSurfaceViewer. +*/ Q3DSViewerSettings *Q3DSSurfaceViewer::settings() const { Q_D(const Q3DSSurfaceViewer); @@ -132,6 +211,14 @@ QString Q3DSSurfaceViewer::error() const return d->error; } +/*! + \property Q3DSSurfaceViewer::running + + The value of this property is \c true when the viewer has been initialized + and the presentation is running. + + This property is read-only. +*/ bool Q3DSSurfaceViewer::isRunning() const { Q_D(const Q3DSSurfaceViewer); @@ -153,6 +240,22 @@ void Q3DSSurfaceViewer::setSize(const QSize &size) } } +/*! + \property Q3DSSurfaceViewer::autoSize + + Specifies whether the viewer should change the size of the presentation + automatically to match the surface size when surface size changes. The + \l{Q3DSSurfaceViewer::size}{size} property is updated automatically + whenever the viewer is \l{Q3DSSurfaceViewer::update()}{updated} if this + property value is \c{true}. + + When rendering offscreen, via a QOffscreenSurface, this property must be + set to \c{false} by the application since it is then up to the application + to provide a QOpenGLFramebufferObject with the desired size. The size of + the Q3DSSurfaceViewer must be set to the same value. + + The default value is \c{true}. +*/ bool Q3DSSurfaceViewer::autoSize() const { Q_D(const Q3DSSurfaceViewer); @@ -168,6 +271,17 @@ void Q3DSSurfaceViewer::setAutoSize(bool autoSize) } } +/*! + \property Q3DSSurfaceViewer::updateInterval + + Holds the viewer update interval in milliseconds. If the value is negative, + the viewer doesn't update the presentation automatically. + + The default value is -1, meaning there are no automatic updates and + update() must be called manually. + + \sa update() +*/ int Q3DSSurfaceViewer::updateInterval() const { Q_D(const Q3DSSurfaceViewer); @@ -190,18 +304,33 @@ void Q3DSSurfaceViewer::setUpdateInterval(int interval) } } +/*! + Returns the framebuffer id given in initialization. + + \sa create() +*/ uint Q3DSSurfaceViewer::fboId() const { Q_D(const Q3DSSurfaceViewer); return d->fbo; } +/*! + Returns the surface given in initialization. + + \sa create() +*/ QSurface *Q3DSSurfaceViewer::surface() const { Q_D(const Q3DSSurfaceViewer); return d->surface; } +/*! + Returns the context given in initialization. + + \sa create() +*/ QOpenGLContext *Q3DSSurfaceViewer::context() const { Q_D(const Q3DSSurfaceViewer); @@ -210,6 +339,9 @@ QOpenGLContext *Q3DSSurfaceViewer::context() const extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); +/*! + Updates the surface viewer with a new frame. +*/ void Q3DSSurfaceViewer::update() { Q_D(Q3DSSurfaceViewer); @@ -272,6 +404,13 @@ void Q3DSSurfaceViewer::update() emit frameUpdate(); } +/*! + Grabs the data rendered to the framebuffer into an image using the given \a + rect. The \a rect parameter is optional. If it is omitted, the whole + framebuffer is captured. + + \note This is a potentially expensive operation. +*/ QImage Q3DSSurfaceViewer::grab(const QRect &rect) { Q_D(Q3DSSurfaceViewer); diff --git a/src/runtime/api/q3dsviewersettings.cpp b/src/runtime/api/q3dsviewersettings.cpp index ba1249a..a0d91ea 100644 --- a/src/runtime/api/q3dsviewersettings.cpp +++ b/src/runtime/api/q3dsviewersettings.cpp @@ -32,6 +32,26 @@ QT_BEGIN_NAMESPACE +/*! + \class Q3DSViewerSettings + \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + + \brief Qt 3D Studio presentation viewer settings. + + Q3DSViewerSettings provides properties to define presentation independent + viewer settings. + + \note As of Qt 3D Studio 2.0 this class is provided mainly for + compatibility reasons. Most functions are not applicable or are not + currently supported and will be silently ignored. + + \note This class should not be instantiated directly when working with the + C++ APIs. Q3DSSurfaceViewer and Q3DSWidget create a Q3DSViewerSettings + instance implicitly. This can be queried via Q3DSSurfaceViewer::settings() + or Q3DSWidget::settings(). + */ + Q3DSViewerSettings::Q3DSViewerSettings(QObject *parent) : QObject(*new Q3DSViewerSettingsPrivate, parent) { @@ -52,6 +72,17 @@ QColor Q3DSViewerSettings::matteColor() const return d->matteColor; } +/*! + \property Q3DSViewerSettings::showRenderStats + + If this property is set to \c{true}, the interactive statistics and profile + view is displayed in-scene, on top of the 3D content. + + \note This feature can be disabled at build time, in which case this + property has no effect. + + Default value is \c{false}. +*/ bool Q3DSViewerSettings::isShowingRenderStats() const { Q_D(const Q3DSViewerSettings); @@ -129,4 +160,24 @@ void Q3DSViewerSettings::load(const QString &group, qWarning() << Q_FUNC_INFO << "not implemented"; } +/*! + \qmltype ViewerSettings + \instantiates Q3DSViewerSettings + \inqmlmodule QtStudio3D + \ingroup 3dstudioruntime2 + \brief Qt 3D Studio presentation viewer settings. + + This type provides properties to define presentation independent viewer settings. + + \sa Studio3D +*/ + +/*! + \qmlproperty bool ViewerSettings::showRenderStats + + If this property is set to \c{true}, render statistics are displayed on the upper part + of the viewer. + Default value is \c{false}. +*/ + QT_END_NAMESPACE diff --git a/src/runtime/api/q3dswidget.cpp b/src/runtime/api/q3dswidget.cpp index 6fb6d3e..8cdd898 100644 --- a/src/runtime/api/q3dswidget.cpp +++ b/src/runtime/api/q3dswidget.cpp @@ -44,12 +44,35 @@ QT_BEGIN_NAMESPACE /*! \class Q3DSWidget - \inmodule 3dstudioruntime2 + \since Qt 3D Studio 2.0 + \inherits QOpenGLWidget + + \brief A widget that renders Qt 3D Studio presentations using OpenGL. + + Q3DSWidget is a widget that can be used to embed Qt 3D Studio presentations + into QWidget-based applications. + + Q3DSWidget is used to specify a render widget for Qt 3D Studio + presentation. It subclasses QOpenGLWidget, which means all considerations + that should be taken when working with QOpenGLWidget apply to Q3DSWidget as + well. Refer to the QOpenGLWidget documentation for details. + + \section2 Example Usage - \brief Widget + \code + Q3DSWidget *viewer = new Q3DSWidget(parentWidget); + viewer->presentation()->setSource(QUrl(QStringLiteral("qrc:/my_presentation.uip"))); + viewer->setUpdateInterval(0); - blah + // Register a scene element object for slide management (optional) + Q3DSSceneElement scene(viewer->presentation(), QStringLiteral("Scene")); + + // Register an element object for attribute setting (optional) + Q3DSElement element(viewer->presentation(), QStringLiteral("myCarModel")); + \endcode + + \sa Q3DSSurfaceViewer */ Q3DSWidget::Q3DSWidget(QWidget *parent) @@ -65,12 +88,18 @@ Q3DSWidget::~Q3DSWidget() delete d_ptr; } +/*! + Returns the presentation object used by the Q3DSWidget. + */ Q3DSPresentation *Q3DSWidget::presentation() const { Q_D(const Q3DSWidget); return d->presentation; } +/*! + Returns the settings object used by the Q3DSWidget. + */ Q3DSViewerSettings *Q3DSWidget::settings() const { Q_D(const Q3DSWidget); @@ -83,12 +112,30 @@ QString Q3DSWidget::error() const return d->error; } +/*! + \property Q3DSWidget::running + + The value of this property is \c true when the viewer has been initialized + and the presentation is running. + + This property is read-only. +*/ bool Q3DSWidget::isRunning() const { Q_D(const Q3DSWidget); return d->engine && d->sourceLoaded; } +/*! + \property Q3DSWidget::updateInterval + + Holds the viewer update interval in milliseconds. If the value is negative, + the viewer doesn't update the presentation automatically. + + The default value is 0, meaning automatic updates are enabled. + + \sa QWidget::update() +*/ int Q3DSWidget::updateInterval() const { Q_D(const Q3DSWidget); |