summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanne Kangas <janne.kangas@qt.io>2017-12-15 11:53:56 +0200
committerJanne Kangas <janne.kangas@qt.io>2018-01-19 10:17:42 +0000
commit337aaa465ac78ac72ca748f0c2d4c3b6257829b8 (patch)
tree538354b89f2a96d220f1137e8fba867400fcfa9d
parent849b12c5df97ec268c5efce27ea96daa7676e525 (diff)
[DataInput] Add UI enablers for linking DataInput and Text
Add popup for text property that allows choosing a datainput in scene to be controller for the property. DataInput toggle icon and other functionality can be enabled by adding 'Controllable="True"' parameter to textstring property in MetaData.xml Task-Id: QT3DS-337 Change-Id: I5ab25566866cb45134d36e025e21e94f98944eaf Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp2
-rw-r--r--src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp317
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h4
-rw-r--r--src/Authoring/Client/Code/Core/Doc/RelativePathTools.cpp4
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/DataInputBrowser.qml153
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.cpp124
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.h90
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp38
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.h5
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp55
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h3
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml23
-rw-r--r--src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp10
-rw-r--r--src/Authoring/Studio/Qt3DStudio.pro2
-rw-r--r--src/Authoring/Studio/qml.qrc1
15 files changed, 784 insertions, 47 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp b/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp
index b48cd318..b1e3c8c3 100644
--- a/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/ClientDataModelBridge/ClientDataModelBridge.cpp
@@ -1343,7 +1343,7 @@ bool CClientDataModelBridge::IsDuplicateable(qt3dsdm::Qt3DSDMInstanceHandle inIn
EStudioObjectType theObjectType = GetObjectType(inInstance);
if (theObjectType == OBJTYPE_SCENE || theObjectType == OBJTYPE_MATERIAL
- || theObjectType == OBJTYPE_IMAGE)
+ || theObjectType == OBJTYPE_IMAGE ||theObjectType == OBJTYPE_DATAINPUT)
return false;
// If we are delving inside component and selecting the component itself (the component is root
// in timeline palette)
diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
index 87662d5b..3ac72680 100644
--- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
@@ -32,6 +32,7 @@
#include "Doc.h"
#include "Qt3DSFileTools.h"
#include "StudioFullSystem.h"
+#include "IObjectReferenceHelper.h"
#include "foundation/Qt3DS.h"
#include "foundation/Qt3DSAssert.h"
#include "StudioCoreSystem.h"
@@ -658,6 +659,40 @@ public:
}
}
+ // Resolve all instances that are controlled by datainput instance
+ void GetControlledInstancesAndProperties(TInstanceHandle dataInput,
+ TInstancePropertyPairList &ctrldInstsProps)
+ {
+ Q_ASSERT(m_Bridge.IsDataInputInstance(dataInput));
+ IObjectReferenceHelper *objReferenceHelper = m_Doc.GetDataModelObjectReferenceHelper();
+
+ Option<SValue> controlledElemProp
+ = GetInstancePropertyValue(
+ dataInput,
+ m_Bridge.GetObjectDefinitions().m_DataInput.m_ControlledElemProp);
+ CString controlledElemPropStr = get<TDataStrPtr>(*controlledElemProp)->GetData();
+
+ std::string::size_type thePos = 0;
+ bool fullResolved = false;
+ CRelativePathTools::EPathType type;
+ // Controlled instance and property names are stored in "controlledelemprop"
+ // property as a single string, each item separated by whitespace. Parse
+ // names and get corresponding handles.
+ while (thePos < controlledElemPropStr.size()) {
+ CString theCurrentElemStr = controlledElemPropStr.substr(
+ thePos, controlledElemPropStr.find(' ', thePos) - thePos);
+ thePos += theCurrentElemStr.size() + 1;
+ CString theCurrentPropStr = controlledElemPropStr.substr(
+ thePos, controlledElemPropStr.find(' ', thePos) - thePos);
+ thePos += theCurrentPropStr.size() + 1;
+ TInstanceHandle currElement = CRelativePathTools::FindAssetInstanceByObjectPath(
+ &m_Doc, m_Doc.GetActiveRootInstance(), theCurrentElemStr,
+ type, fullResolved, objReferenceHelper);
+ TPropertyHandle currProp = FindProperty(currElement, theCurrentPropStr);
+ ctrldInstsProps.push_back(TInstancePropertyPair(currElement, currProp));
+ }
+ }
+
bool IsInSceneGraph(TInstanceHandle child) const override { return m_AssetGraph.IsExist(child); }
// If the path has any sub-path children, then yes it is externalizeable.
@@ -729,7 +764,20 @@ public:
return false;
return m_AnimationCore.IsArtistEdited(animHandle);
}
-
+ bool IsControlled(TInstanceHandle instance)
+ {
+ // TODO This is Text element specific code
+ if (!m_Bridge.IsTextInstance(instance))
+ return false;
+ Option<SValue> currentControlledProperty = GetInstancePropertyValue(
+ instance, m_Bridge.GetObjectDefinitions().m_Text.m_ControlledProperty);
+ if (!currentControlledProperty.hasValue())
+ return false;
+ CString propStr = (get<TDataStrPtr>(*currentControlledProperty))->GetData();
+ if (!propStr.IsEmpty())
+ return true;
+ return false;
+ }
pair<std::shared_ptr<qt3dsdm::IDOMWriter>, CFilePath>
DoCopySceneGraphObject(const TInstanceHandleList &inInstances)
{
@@ -1049,6 +1097,7 @@ public:
void DoDeleteInstance(Qt3DSDMInstanceHandle instance)
{
+ IObjectReferenceHelper *objReferenceHelper = m_Doc.GetDataModelObjectReferenceHelper();
// For delete, the metadata needs to participate in the undo/redo system.
m_MetaData.SetConsumer(m_StudioSystem.GetFullSystem()->GetConsumer());
TInstanceHandleList theDeleteDependentInstances;
@@ -1167,16 +1216,40 @@ public:
&& theInstanceChildren[0] == instance));
theDeleteDependentInstances.push_back(theInstanceParent);
}
+ } else if (m_Bridge.IsDataInputInstance(instance)) {
+ // When DataInput is deleted, we must set properties controlled by it
+ // in target instances to uncontrolled
+ TInstancePropertyPairList instPropPairList;
+ GetControlledInstancesAndProperties(instance, instPropPairList);
+ // Iterate through instance-property pairs and set to uncontrolled
+ for (size_t idx = 0, end = instPropPairList.size(); idx < end; ++idx) {
+ CString controlledElemStr = objReferenceHelper->GetObjectReferenceString(
+ m_Doc.GetSceneInstance(), CRelativePathTools::EPATHTYPE_GUID,
+ instPropPairList[idx].first);
+ SetInstancePropertyControlled(instPropPairList[idx].first,
+ controlledElemStr,
+ instPropPairList[idx].second,
+ 0, false);
+ }
}
// Note that the instance and its parents are still valid.
// we delete from the bottom of the asset graph upwards.
+ // If any instance properties are controlled by a datainput,
+ // remove control first
+ if (IsControlled(instance))
+ RemoveAllControlForInstance(instance);
+
m_DataCore.DeleteInstance(instance);
+
if (m_AssetGraph.IsExist(instance))
m_AssetGraph.RemoveNode(instance);
for (size_t idx = 0; idx < theDeleteDependentInstances.size(); ++idx) {
QT3DS_ASSERT(!m_AssetGraph.IsExist(theDeleteDependentInstances[idx]));
+ if (IsControlled(theDeleteDependentInstances[idx]))
+ RemoveAllControlForInstance(theDeleteDependentInstances[idx]);
+
m_DataCore.DeleteInstance(theDeleteDependentInstances[idx]);
}
}
@@ -1372,54 +1445,175 @@ public:
}
SetName(theMaterial, materialName);
}
-
+ // Set a property in an instance to be controlled by datainput.
+ // We build two strings here. "Controlled element - controlled property" -string
+ // goes to controlling datainput and details all elements and their properties
+ // that a specified datainput should control. "Controlling datanode - controlled
+ // property" -string is specific for this (=controlled) instance and contains
+ // the path of controlling datanode and the controlled property(/-ies).
void SetInstancePropertyControlled(TInstanceHandle instance, CString instancepath,
TPropertyHandle propName, TInstanceHandle controller,
bool controlled) override
{
SComposerObjectDefinitions &theDefinitions(m_Bridge.GetObjectDefinitions());
+ IObjectReferenceHelper* objReferenceHelper = m_Doc.GetDataModelObjectReferenceHelper();
// get the name of controlled property
auto metadataHandle = m_MetaData.GetMetaDataProperty(instance, propName);
auto metadata = m_MetaData.GetMetaDataPropertyInfo(metadataHandle);
const wchar_t *propname = metadata->m_Name.wide_str();
- qt3dsdm::SValue controlledProperty = std::make_shared<CDataStr>(propname);
- // get existing string of controlled elements and properties from controlling
- // datainput
- qt3dsdm::SValue controlledElemProp;
- m_DataCore.GetInstancePropertyValue(
- controller, theDefinitions.m_DataInput.m_ControlledElemProp, controlledElemProp);
- QString controlledElemPropStr = controlledElemProp.toQVariant().toString();
-
- // build the controlled element - controlled property string specific for this element
- instancepath.append(" ");
- instancepath.append(propname);
- instancepath.append(" ");
-
- // If property was set to controlled, append element - property string to the list
- // held by the controlling datainput. Otherwise, remove this element-property -pair from it.
- if (controlled)
- controlledElemPropStr.append(instancepath.toQString());
- else
- controlledElemPropStr.remove(instancepath.toQString());
+ SValue controlledProperty;
+ Option<SValue> controlledElemProp;
+ CString controlledElemPropStr;
+ SValue controllerName;
+
+ // Get the name of controller instance and build controller - controlled property
+ // string.
+ // If we are setting control on, we have incoming controller handle from
+ // dialog.
+ // If control is simply being set off from UI toggle, we need to get the current
+ // controlling instance from a property string held by this instance, for the purposes
+ // of removing the control target from the controller datainput
+ if (controlled) {
+ // controller instance must be valid when setting control to true
+ Q_ASSERT(controller != 0);
+ // get existing string of controlled elements and properties from controlling
+ // datainput
+ controlledElemProp = GetInstancePropertyValue(
+ controller, theDefinitions.m_DataInput.m_ControlledElemProp);
+ controlledElemPropStr = get<TDataStrPtr>(*controlledElemProp)->GetData();
+
+ // build the controlled element - controlled property string specific for this element
+ instancepath.append(" ");
+ instancepath.append(propname);
+ instancepath.append(" ");
+
+ // append this element - property pair to existing items that datainput already controls
+ controlledElemPropStr.append(instancepath);
+
+ // build the controller datainput - controlled property string
+ CString controlledElemStr = objReferenceHelper->GetObjectReferenceString(
+ m_Doc.GetSceneInstance(), CRelativePathTools::EPATHTYPE_GUID, controller);
+ controlledElemStr.append(" ");
+ controlledElemStr.append(metadata->m_Name.c_str());
+
+ controlledProperty = std::make_shared<CDataStr>(controlledElemStr);
+ // Text element -specific: show controlling datainput name in brackets
+ // as the textstring contents for clarity
+ controllerName = std::make_shared<CDataStr>("[" + m_Bridge.GetName(controller) + "]");
+ } else {
+ // TODO: this is Text element-specific at the moment
+ // Get controller - property -pair for this element
+ Option<SValue> currentControlledProperty = GetInstancePropertyValue(
+ instance, theDefinitions.m_Text.m_ControlledProperty);
+
+ TDataStrPtr theNamePtr(get<TDataStrPtr>(*currentControlledProperty));
+ CString controllerNameStr = theNamePtr->GetData();
+
+ // Check if this property has a controlling datainput before trying
+ // to delete it from the list of controlled properties
+ if (controllerNameStr.size()) {
+ // get the controlling datainput name only
+ controllerNameStr = controllerNameStr.substr(0, controllerNameStr.find(" "));
+
+ bool theFullResolvedFlag;
+ CRelativePathTools::EPathType type;
+ controller = CRelativePathTools::FindAssetInstanceByObjectPath(
+ &m_Doc, m_Doc.GetActiveRootInstance(), controllerNameStr,
+ type, theFullResolvedFlag, objReferenceHelper);
+
+ // get existing string of controlled elements and properties from controlling
+ // datainput
+ controlledElemProp = GetInstancePropertyValue(
+ controller, theDefinitions.m_DataInput.m_ControlledElemProp);
+ controlledElemPropStr = get<TDataStrPtr>(*controlledElemProp)->GetData();
+ // build the string for this element-property -pair and remove it
+ // from items that datanode controls
+ instancepath.append(" ");
+ instancepath.append(metadata->m_Name.c_str());
+ instancepath.append(" ");
+ controlledElemPropStr.Replace(instancepath, "");
+
+ // Set controller - property -string empty for this element.
+ // We need to explicitly set controlledProperty with an empty string initializer,
+ // otherwise it will have type "None" instead of "String".
+ // TODO: for now only a single textstring property can be controlled. For
+ // control of several properties in a single element, we must only remove
+ // a specific controller - property pair from controlledProperty string, not all.
+ controlledProperty = std::make_shared<CDataStr>(CString());
+
+ // Set the textstring content to default when disabling datainput control
+ // TODO: restore the previous text content prior to setting it to controlled
+ controllerName = theDefinitions.m_Text.m_TextString.m_DefaultValue.getValue();
+ } else {
+ // We are trying to turn control off for property that had no existing control.
+ // This might happen when user toggles control on and off without setting
+ // the controller from the selection dialog.
+ // Nothing to do except to make sure that we set the textstring to default and
+ // controlledProperty to an empty string.
+ controlledProperty = std::make_shared<CDataStr>(CString());
+ controllerName = theDefinitions.m_Text.m_TextString.m_DefaultValue.getValue();
+
+ m_DataCore.SetInstancePropertyValue(instance,
+ theDefinitions.m_Text.m_ControlledProperty,
+ controlledProperty);
+ SetInstancePropertyValue(instance,
+ theDefinitions.m_Text.m_TextString,
+ controllerName);
+ // early return to avoid trying to set property in the non-existent
+ // controller instance
+ return;
+ }
+ }
- qCDebug(qt3ds::TRACE_INFO) << "SetInstance datainput controlledelemprop: instance "
- << controller
- << " property " << theDefinitions.m_DataInput.m_ControlledElemProp.m_Property
- << " value " << controlledElemPropStr;
+ // Set properties both in the controller and the controlled instance
+ SValue finalControlledElemProp = std::make_shared<CDataStr>(controlledElemPropStr);
- controlledElemProp = std::make_shared<CDataStr>(controlledElemPropStr.toStdWString().c_str());
// For DataInput and Alias, property values are set through datacore.
// Set the newly built controlledelemprop string for the controlling datainput
m_DataCore.SetInstancePropertyValue(controller,
theDefinitions.m_DataInput.m_ControlledElemProp,
- controlledElemProp);
+ finalControlledElemProp);
// Set the controlledproperty string in the controlled element
// TODO: For the moment this is Text element -specific only
m_DataCore.SetInstancePropertyValue(instance,
theDefinitions.m_Text.m_ControlledProperty,
controlledProperty);
+
+ // Show the controller name also in Inspector Text field as visual reminder.
+ // DataInput does not set any values to target in Editor; we need to show something
+ // to indicate where the values will be coming from during animation so we use
+ // controller name in brackets.
+ // Do not set this value directly via datacore so that the value updates in Studio UI.
+ if (m_Bridge.IsTextInstance(instance)) {
+ SetInstancePropertyValue(instance,
+ theDefinitions.m_Text.m_TextString,
+ controllerName);
+ }
+ }
+
+ // Remove datainput control of all properties of this instance,
+ // for example when deleting the entire instance
+ void RemoveAllControlForInstance(TInstanceHandle instance)
+ {
+ SComposerObjectDefinitions &theDefinitions(m_Bridge.GetObjectDefinitions());
+ IObjectReferenceHelper* objReferenceHelper = m_Doc.GetDataModelObjectReferenceHelper();
+
+ // TODO: text element-specific. Also, only removes a single controller-property
+ // pair as currently only textstring can be controlled. For generic
+ // implementation we need to iterate through all controller-property pairs
+ // and remove control for each of them separately (a single instance can have
+ // several different datainputs each controlling a single or multiple properties
+ // i.e. one-to-many mapping).
+ SetInstancePropertyControlled(instance,
+ objReferenceHelper->GetObjectReferenceString(
+ m_Doc.GetSceneInstance(),
+ CRelativePathTools::EPATHTYPE_GUID,
+ instance),
+ theDefinitions.m_Text.m_TextString,
+ 0,
+ false);
}
// Normal way in to the system.
@@ -2385,9 +2579,18 @@ public:
// messages.
// The timeline, for instance, requires that before a create operation happens all remove
// operations have happened.
-
+ QList<CString> instancePaths;
qt3dsdm::TInstanceHandleList sortableList(ToGraphOrdering(inInstances));
for (size_t idx = 0, end = sortableList.size(); idx < end; ++idx) {
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance(sortableList[idx]);
+ instancePaths.push_back(
+ m_Doc.GetDataModelObjectReferenceHelper()->GetObjectReferenceString(
+ m_Doc.GetSceneInstance(),
+ CRelativePathTools::EPATHTYPE_GUID,
+ theInstance));
+ }
+
+ for (size_t idx = 0, end = sortableList.size(); idx < end; ++idx) {
m_AssetGraph.RemoveChild(sortableList[idx], false);
}
@@ -2415,13 +2618,71 @@ public:
else if (inInsertType == DocumentEditorInsertType::LastChild)
m_AssetGraph.MoveTo(theInstance, inDest, COpaquePosition::LAST);
}
+
+ for (size_t idx = 0, end = sortableList.size(); idx < end; ++idx) {
+ qt3dsdm::Qt3DSDMInstanceHandle theInstance(sortableList[idx]);
+ if (inInsertType == DocumentEditorInsertType::NextSibling)
+ theInstance = sortableList[end - idx - 1];
+ if (IsControlled(theInstance))
+ UpdateDataInputTarget(theInstance, instancePaths[idx]);
+ }
}
+ // Called when controlled instance is moved inside scene graph and
+ // controlling datanode must update the instance path
+ void UpdateDataInputTarget(TInstanceHandle instance, CString oldPath)
+ {
+ SComposerObjectDefinitions &objDefinitions(m_Bridge.GetObjectDefinitions());
+ // TODO: Text-element specific code
+ Option<SValue> currentControlledProperty = GetInstancePropertyValue(
+ instance, objDefinitions.m_Text.m_ControlledProperty);
+ CString controllerNameStr
+ = (get<TDataStrPtr>(*currentControlledProperty))->GetData();
+
+ Q_ASSERT(controllerNameStr.size());
+
+ // get the controlling datainput name only
+ controllerNameStr = controllerNameStr.substr(0, controllerNameStr.find(" "));
+
+ bool theFullResolvedFlag;
+ CRelativePathTools::EPathType type;
+ TInstanceHandle controller = CRelativePathTools::FindAssetInstanceByObjectPath(
+ &m_Doc, m_Doc.GetActiveRootInstance(), controllerNameStr,
+ type, theFullResolvedFlag, m_Doc.GetDataModelObjectReferenceHelper());
+
+ // get existing string of controlled elements and properties from controlling
+ // datainput and replace old path with new
+ Option<SValue> controlledElemProp = GetInstancePropertyValue(
+ controller, objDefinitions.m_DataInput.m_ControlledElemProp);
+ CString controlledElemPropStr = get<TDataStrPtr>(*controlledElemProp)->GetData();
+
+ CString currentInstancePath = m_Doc.GetDataModelObjectReferenceHelper()
+ ->GetObjectReferenceString(m_Doc.GetSceneInstance(),
+ CRelativePathTools::EPATHTYPE_GUID,
+ instance);
+ controlledElemPropStr.Replace(oldPath, currentInstancePath);
+
+ // Set the new controlled properties string to controlling datainput
+ SValue finalControlledElemProp = std::make_shared<CDataStr>(controlledElemPropStr);
+
+ m_DataCore.SetInstancePropertyValue(controller,
+ objDefinitions.m_DataInput.m_ControlledElemProp,
+ finalControlledElemProp);
+ }
Qt3DSDMInstanceHandle MakeComponent(const qt3dsdm::TInstanceHandleList &inInstances) override
{
if (inInstances.empty())
return Qt3DSDMInstanceHandle();
+ // TODO: For now, we need to break control relationship for instances that are
+ // included in the newly made component as the binding goes wrong during
+ // instance "copy to mem - delete - insert" sequence needed for component creation.
+ // This means that at the moment, datainput cannot control a property
+ // within a component instance.
+ for (size_t idx = 0; idx < inInstances.size(); idx++) {
+ if (IsControlled(inInstances[idx]))
+ RemoveAllControlForInstance(inInstances[idx]);
+ }
qt3dsdm::TInstanceHandleList theInstances = ToGraphOrdering(inInstances);
// Do this in reverse order.
// first add new component.
diff --git a/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h b/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
index 765c5b4c..500bf2a2 100644
--- a/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
+++ b/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
@@ -196,6 +196,10 @@ public:
SetInstancePropertyValueAsRenderable(TInstanceHandle instance, TPropertyHandle propName,
const Q3DStudio::CString &inSourcePath) = 0;
+ // Sets/unsets "instance" property "propName" to be controlled by datainput "controller"
+ // and adds element - property pair to controlling datainput control list. "Instancepath"
+ // must correspond to controlled instance path as it is the data used by controller to
+ // locate element when controlling the property value
virtual void SetInstancePropertyControlled(TInstanceHandle instance, CString instancepath,
TPropertyHandle propName,
TInstanceHandle controller,
diff --git a/src/Authoring/Client/Code/Core/Doc/RelativePathTools.cpp b/src/Authoring/Client/Code/Core/Doc/RelativePathTools.cpp
index 6ea23673..03998b29 100644
--- a/src/Authoring/Client/Code/Core/Doc/RelativePathTools.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/RelativePathTools.cpp
@@ -190,6 +190,10 @@ qt3dsdm::Qt3DSDMInstanceHandle CRelativePathTools::FindAssetInstanceByObjectPath
outIsResolved = true;
theFoundInstance = inRootInstance;
outPathType = EPATHTYPE_RELATIVE;
+ } else if (theCurrentToken.Compare(CPathConstructionHelper::GetSceneString(), false)) {
+ outIsResolved = true;
+ theFoundInstance = inRootInstance;
+ outPathType = EPATHTYPE_RELATIVE;
} else if (theCurrentToken.Compare(CPathConstructionHelper::GetParentString(), false)) {
outIsResolved = true;
theFoundInstance = theBridge->GetParentInstance(inRootInstance);
diff --git a/src/Authoring/Studio/Palettes/Inspector/DataInputBrowser.qml b/src/Authoring/Studio/Palettes/Inspector/DataInputBrowser.qml
new file mode 100644
index 00000000..d92a5b2d
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/Inspector/DataInputBrowser.qml
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Controls 2.1
+import QtQuick.Layouts 1.3
+import Qt3DStudio 1.0
+import "../controls"
+
+Rectangle {
+ id: root
+
+ color: _backgroundColor
+ border.color: _studioColor3
+
+ ColumnLayout {
+ anchors.fill: parent
+
+ spacing: 10
+
+ ListView {
+ id: browserList
+
+ Layout.margins: 10
+ Layout.columnSpan: 2
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.minimumHeight: 80
+ Layout.preferredHeight: count * 20
+ Layout.preferredWidth: root.width
+
+ ScrollBar.vertical: ScrollBar {}
+
+ model: _dataInputChooserView.model
+ boundsBehavior: Flickable.StopAtBounds
+ clip: true
+ currentIndex: _dataInputChooserView.selection
+
+ delegate: Item {
+ id: delegateItem
+
+ x: model.depth * 20
+ width: parent.width
+ height: model.parentExpanded ? typeIcon.height + 10 : 0
+
+ visible: height > 0
+
+ Behavior on height {
+ NumberAnimation {
+ duration: 100
+ easing.type: Easing.OutQuad
+ }
+ }
+
+ Row {
+ id: row
+
+ height: typeIcon.height
+ spacing: 5
+
+ Image {
+ source: {
+ if (!model.hasChildren)
+ return "";
+ model.expanded ? _resDir + "arrow_down.png"
+ : _resDir + "arrow.png";
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: model.expanded = !model.expanded
+ }
+ }
+
+ Rectangle {
+ height: typeIcon.height
+ width: typeIcon.width + name.width + 10
+
+ color: model.index === browserList.currentIndex ? _selectionColor
+ : "transparent"
+
+ Row {
+ spacing: 10
+ Image {
+ id: typeIcon
+
+ source: model.icon
+ }
+
+ StyledLabel {
+ id: name
+ anchors.verticalCenter: typeIcon.verticalCenter
+ color: model.textColor
+ text: model.name
+ }
+ }
+
+ MouseArea {
+ id: delegateArea
+
+ anchors.fill: parent
+ onClicked: {
+ if (_dataInputChooserView.selectable(model.index))
+ browserList.currentIndex = model.index;
+ }
+ onDoubleClicked: {
+ if (_dataInputChooserView.selectable(model.index)) {
+ browserList.currentIndex = model.index;
+ _dataInputChooserView.close();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ onCurrentIndexChanged: _dataInputChooserView.selection = currentIndex
+
+ Connections {
+ target: _dataInputChooserView
+ onSelectionChanged: {
+ if (browserList.currentIndex !== _dataInputChooserView.selection)
+ browserList.currentIndex = _dataInputChooserView.selection;
+ }
+ }
+ }
+ }
+}
diff --git a/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.cpp b/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.cpp
new file mode 100644
index 00000000..142c39c4
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "DataInputChooserView.h"
+
+#include "CColor.h"
+#include "Literals.h"
+#include "ObjectListModel.h"
+#include "StudioPreferences.h"
+#include "StudioUtils.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qtimer.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+
+DataInputChooserView::DataInputChooserView(QWidget *parent)
+ : QQuickWidget(parent)
+{
+ setWindowFlags(Qt::Tool | Qt::FramelessWindowHint);
+ setResizeMode(QQuickWidget::SizeRootObjectToView);
+ QTimer::singleShot(0, this, &DataInputChooserView::initialize);
+}
+
+QAbstractItemModel *DataInputChooserView::model() const
+{
+ return m_model;
+}
+
+void DataInputChooserView::setModel(ObjectListModel *model)
+{
+ if (!m_model)
+ m_model = new FlatObjectListModel(model, this);
+
+ m_model->setSourceModel(model);
+
+ Q_EMIT modelChanged();
+}
+
+
+QSize DataInputChooserView::sizeHint() const
+{
+ return {500, 500};
+}
+
+QString DataInputChooserView::name(int index) const
+{
+ return m_model->index(index, 0).data(ObjectListModel::NameRole).toString();
+}
+
+QString DataInputChooserView::path(int index) const
+{
+ return m_model->index(index, 0).data(ObjectListModel::PathReferenceRole).toString();
+}
+
+bool DataInputChooserView::selectable(int index) const
+{
+ auto handleId = m_model->index(index, 0).data(ObjectListModel::HandleRole).toInt();
+ auto handle = qt3dsdm::Qt3DSDMInstanceHandle(handleId);
+ return m_model->sourceModel()->selectable(handle);
+}
+
+void DataInputChooserView::selectAndExpand(const qt3dsdm::Qt3DSDMInstanceHandle &handle)
+{
+ QModelIndex index = m_model->sourceModel()->indexForHandle(handle);
+ m_model->expandTo(QModelIndex(), index);
+ setSelection(m_model->rowForSourceIndex(index));
+}
+
+void DataInputChooserView::setSelection(int index)
+{
+ if (m_selection != index) {
+ m_selection = index;
+ Q_EMIT selectionChanged();
+ }
+}
+
+qt3dsdm::Qt3DSDMInstanceHandle DataInputChooserView::selectedHandle() const
+{
+ auto handleId = m_model->index(m_selection, 0).data(ObjectListModel::HandleRole).toInt();
+ return qt3dsdm::Qt3DSDMInstanceHandle(handleId);
+}
+
+void DataInputChooserView::focusOutEvent(QFocusEvent *event)
+{
+ QQuickWidget::focusOutEvent(event);
+ QTimer::singleShot(0, this, &DataInputChooserView::close);
+}
+
+void DataInputChooserView::initialize()
+{
+ CStudioPreferences::setQmlContextProperties(rootContext());
+ rootContext()->setContextProperty("_dataInputChooserView"_L1, this);
+ rootContext()->setContextProperty("_resDir"_L1, resourceImageUrl());
+ qmlRegisterUncreatableType<DataInputChooserView>(
+ "Qt3DStudio", 1, 0, "DataInputChooserView",
+ tr("Creation of DataInputChooserView not allowed from QML"));
+ engine()->addImportPath(qmlImportPath());
+ setSource(QUrl("qrc:/Palettes/Inspector/DataInputBrowser.qml"_L1));
+}
diff --git a/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.h b/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.h
new file mode 100644
index 00000000..ce8ded82
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/Inspector/DataInputChooserView.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef DATAINPUTCHOOSERVIEW_H
+#define DATAINPUTCHOOSERVIEW_H
+
+#include <QQuickWidget>
+
+#include "RelativePathTools.h"
+#include "Qt3DSDMHandles.h"
+
+#include <QColor>
+
+class ObjectListModel;
+class FlatObjectListModel;
+
+QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
+
+class DataInputChooserView : public QQuickWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractItemModel *model READ model NOTIFY modelChanged FINAL)
+ Q_PROPERTY(int selection READ selection WRITE setSelection NOTIFY selectionChanged FINAL)
+
+public:
+ DataInputChooserView(QWidget *parent = nullptr);
+
+ enum PathType {
+ Name = CRelativePathTools::EPATHTYPE_GUID,
+ Relative = CRelativePathTools::EPATHTYPE_RELATIVE,
+ };
+ Q_ENUM(PathType)
+
+ QAbstractItemModel *model() const;
+ void setModel(ObjectListModel *model);
+ QSize sizeHint() const override;
+
+ Q_INVOKABLE QString name(int index) const;
+ Q_INVOKABLE QString path(int index) const;
+ Q_INVOKABLE bool selectable(int index) const;
+
+ void selectAndExpand(const qt3dsdm::Qt3DSDMInstanceHandle &handle);
+
+ int selection() const { return m_selection; }
+ void setSelection(int index);
+
+ qt3dsdm::Qt3DSDMInstanceHandle selectedHandle() const;
+
+Q_SIGNALS:
+ void modelChanged();
+ void selectionChanged();
+
+protected:
+ void focusOutEvent(QFocusEvent *event) override;
+
+private:
+ void initialize();
+
+ FlatObjectListModel *m_model = nullptr;
+ QHash<int, ObjectListModel *> m_subModels;
+ QColor m_baseColor = QColor::fromRgb(75, 75, 75);
+ QColor m_selectColor;
+ int m_selection = -1;
+};
+
+#endif // DATAINPUTCHOOSERVIEW_H
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
index 53a16861..7ebb42ba 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
@@ -375,6 +375,8 @@ InspectorControlBase* InspectorControlModel::createItem(Qt3DSDMInspectable *insp
Q3DStudio::CString propertyNameStr = metaProperty.m_Name.c_str();
// is this property controlled in this element?
item->m_controlled = currPropValStr.contains(propertyNameStr.toQString());
+ // This works for now because Text element textstring is only controllable property so far.
+ item->m_controlled = currPropValStr.contains(propertyNameStr.toQString());
m_controlledToggleConnection = signalProvider->ConnectControlledToggled(
std::bind(&InspectorControlModel::updateControlledToggleState,
@@ -916,7 +918,8 @@ void InspectorControlModel::setSlideSelection(long instance, int handle, int ind
->SetInstancePropertyValue(instance, handle, newSelectedData);
}
-void InspectorControlModel::setPropertyControlled(long instance, int property, bool controlled)
+void InspectorControlModel::setPropertyControllerInstance(long instance, int property,
+ long controllerInstance, bool controlled)
{
CDoc *doc = g_StudioApp.GetCore()->GetDoc();
const auto studio = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem();
@@ -926,25 +929,34 @@ void InspectorControlModel::setPropertyControlled(long instance, int property, b
Q3DStudio::CString instancepath = Q3DStudio::CString(
objRefHelper->GetObjectReferenceString(doc->GetSceneInstance(),
CRelativePathTools::EPATHTYPE_GUID, instance));
- // TODO this is test code, hardwired for item named DataInput
- // We need to have the datainput handle or name as input to this
- // function, coming from dialog
- Q3DStudio::CString controller = Q3DStudio::CString("this.DataInput");
-
- bool theFullResolvedFlag;
- CRelativePathTools::EPathType type;
- qt3dsdm::Qt3DSDMInstanceHandle controllerhandle
- = CRelativePathTools::FindAssetInstanceByObjectPath(
- doc, doc->GetActiveRootInstance(), controller,
- type, theFullResolvedFlag, objRefHelper);
+ Q_ASSERT(instancepath.size());
Q3DStudio::SCOPED_DOCUMENT_EDITOR(*doc, QObject::tr("Set Property Controlled"))
->SetInstancePropertyControlled(instance, instancepath, property,
- controllerhandle, controlled);
+ controllerInstance, controlled);
+}
+void InspectorControlModel::setPropertyControlled(long instance, int property, bool controlled)
+{
+ const auto studio = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem();
const auto signalSender
= g_StudioApp.GetCore()->GetDoc()->GetStudioSystem()->GetFullSystemSignalSender();
signalSender->SendControlledToggled(instance, property);
+ // If control is toggled on, we do not need to do anything here except toggle the UI icon,
+ // and set the controller to "None" as DataInput selector dialog will later call
+ // setPropertyControllerInstance() and set the correct controller handle and name.
+ // If we are setting control off, no need to find out the datainput that controls this pair.
+ // SetInstancePropertyControlled() will get the current controller from controlledProperty
+ // of this item and removes control.
+ if (controlled) {
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(
+ *g_StudioApp.GetCore()->GetDoc(), QObject::tr("Set Property"))
+ ->SetInstancePropertyValue(
+ instance, property, std::make_shared<qt3dsdm::CDataStr>(
+ Q3DStudio::CString::fromQString(tr("[None]"))));
+ } else {
+ setPropertyControllerInstance(instance, property, 0, controlled);
+ }
}
void InspectorControlModel::setPropertyAnimated(long instance, int handle, bool animated)
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.h b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.h
index 36bfef06..bafe9753 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.h
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.h
@@ -124,13 +124,16 @@ public:
QVariant getPropertyValue(long instance, int handle);
qt3dsdm::SValue currentPropertyValue(long instance, int handle);
+ void setPropertyControllerInstance(long instance, int handle,
+ long controllerInstance, bool controlled);
+
Q_INVOKABLE void setMaterialTypeValue(long instance, int handle, const QVariant &value);
Q_INVOKABLE void setRenderableValue(long instance, int handle, const QVariant &value);
Q_INVOKABLE void setPropertyValue(long instance, int handle, const QVariant &value, bool commit = true);
Q_INVOKABLE void setSlideSelection(long instance, int handle, int index,
const QStringList &list);
Q_INVOKABLE void setPropertyAnimated(long instance, int handle, bool animated);
- Q_INVOKABLE void setPropertyControlled(long instance, int handle, bool controlled);
+ Q_INVOKABLE void setPropertyControlled(long instance, int property, bool controlled);
private:
void onSlideRearranged(const qt3dsdm::Qt3DSDMSlideHandle &inMaster, int inOldIndex,
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
index 99197d4f..c93c0539 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
@@ -42,6 +42,7 @@
#include "IDocumentEditor.h"
#include "ImageChooserModel.h"
#include "ImageChooserView.h"
+#include "DataInputChooserView.h"
#include "MeshChooserView.h"
#include "TextureChooserView.h"
#include "InspectableBase.h"
@@ -460,6 +461,60 @@ QObject *InspectorControlView::showObjectReference(int handle, int instance, con
return m_objectReferenceView;
}
+QObject *InspectorControlView::showDataInputChooser(int handle, int instance, const QPoint &point)
+{
+ CDoc *doc = g_StudioApp.GetCore()->GetDoc();
+ if (!m_objectReferenceModel) {
+ m_objectReferenceModel
+ = new ObjectListModel(g_StudioApp.GetCore(), doc->GetActiveRootInstance(), this);
+ }
+ if (!m_dataInputChooserView)
+ m_dataInputChooserView = new DataInputChooserView(this);
+ m_dataInputChooserView->setModel(m_objectReferenceModel);
+
+ // TODO: for now datainput chooser can only be evoked from text element.
+ // Remove this restriction when other element types can also be controlled
+ if (doc->GetStudioSystem()->GetClientDataModelBridge()
+ ->GetObjectType(instance) == OBJTYPE_TEXT) {
+ QVector<EStudioObjectType> exclude;
+ exclude << OBJTYPE_ALIAS << OBJTYPE_BEHAVIOR << OBJTYPE_MODEL
+ << OBJTYPE_EFFECT << OBJTYPE_GUIDE << OBJTYPE_IMAGE << OBJTYPE_LAYER
+ << OBJTYPE_MATERIAL << OBJTYPE_REFERENCEDMATERIAL << OBJTYPE_CAMERA
+ << OBJTYPE_LIGHT << OBJTYPE_GROUP << OBJTYPE_TEXT
+ << OBJTYPE_COMPONENT << OBJTYPE_SLIDE << OBJTYPE_RENDERPLUGIN
+ << OBJTYPE_CUSTOMMATERIAL << OBJTYPE_PATH << OBJTYPE_PATHANCHORPOINT
+ << OBJTYPE_SUBPATH << OBJTYPE_SOUND << OBJTYPE_LIGHTMAPS;
+ m_objectReferenceModel->excludeObjectTypes(exclude);
+ } else {
+ m_objectReferenceModel->excludeObjectTypes(QVector<EStudioObjectType>());
+ }
+
+ disconnect(m_dataInputChooserView, nullptr, nullptr, nullptr);
+
+ IObjectReferenceHelper *objRefHelper = doc->GetDataModelObjectReferenceHelper();
+ if (objRefHelper) {
+ qt3dsdm::SValue value = m_inspectorControlModel->currentPropertyValue(instance, handle);
+ qt3dsdm::Qt3DSDMInstanceHandle refInstance = objRefHelper->Resolve(value, instance);
+ m_dataInputChooserView->selectAndExpand(refInstance);
+ }
+
+ showBrowser(m_dataInputChooserView, point);
+
+ connect(m_dataInputChooserView, &DataInputChooserView::selectionChanged,
+ this, [this, doc, handle, instance] {
+ auto selectedItem = m_dataInputChooserView->selectedHandle();
+ qt3dsdm::SValue value = m_inspectorControlModel->currentPropertyValue(instance, handle);
+
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(*doc, QObject::tr("Set Property"))
+ ->SetInstancePropertyValue(instance, handle, value);
+
+ m_inspectorControlModel->setPropertyControllerInstance(instance, handle,
+ selectedItem, true);
+ });
+
+ return m_dataInputChooserView;
+}
+
void InspectorControlView::showBrowser(QQuickWidget *browser, const QPoint &point)
{
QSize popupSize = CStudioPreferences::browserPopupSize();
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
index 564f71c8..bccd2e91 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
@@ -41,6 +41,7 @@ class InspectorControlModel;
QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
class CInspectableBase;
class ImageChooserView;
+class DataInputChooserView;
class ImageChooserModel;
class MeshChooserView;
class ObjectBrowserView;
@@ -74,6 +75,7 @@ public:
Q_INVOKABLE QObject *showMeshChooser(int handle, int instance, const QPoint &point);
Q_INVOKABLE QObject *showObjectReference(int handle, int instance, const QPoint &point);
Q_INVOKABLE QObject *showTextureChooser(int handle, int instance, const QPoint &point);
+ Q_INVOKABLE QObject *showDataInputChooser(int handle, int instance, const QPoint &point);
Q_INVOKABLE void showDataInputDialog();
// IDataModelListener
@@ -120,6 +122,7 @@ private:
QPointer<MeshChooserView> m_meshChooserView;
QPointer<FileChooserView> m_fileChooserView;
QPointer<TextureChooserView> m_textureChooserView;
+ QPointer<DataInputChooserView> m_dataInputChooserView;
QPointer<ObjectBrowserView> m_objectReferenceView;
QPointer<ObjectListModel> m_objectReferenceModel;
std::vector<Q3DStudio::CFilePath> m_fileList;
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
index 758572e2..e59577c3 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
@@ -207,7 +207,7 @@ Rectangle {
_inspectorModel.setPropertyControlled(
model.modelData.instance,
model.modelData.handle,
- !model.modelData.controlled)
+ !model.modelData.controlled);
} else {
const coords = mapToItem(root, mouse.x, mouse.y);
groupDelegateItem.showContextMenu(coords);
@@ -298,8 +298,12 @@ Rectangle {
return renderableDropDown;
if (modelData.propertyType === AdditionalMetaDataType.Mesh)
return meshChooser;
+ // Show DataInput selector if this item is controlled
if (modelData.propertyType === AdditionalMetaDataType.MultiLine)
- return multiLine;
+ if (modelData.controlled)
+ return datainputChooser;
+ else
+ return multiLine;
if (modelData.propertyType === AdditionalMetaDataType.Font)
return comboDropDown;
if (modelData.propertyType === AdditionalMetaDataType.Texture)
@@ -801,6 +805,21 @@ Rectangle {
}
Component {
+ id: datainputChooser
+
+ HandlerGenericChooser {
+ property int instance: parent.modelData.instance
+ property int handle: parent.modelData.handle
+ property variant values: parent.modelData.values
+ value: parent.modelData.value
+ onShowBrowser: {
+ activeBrowser = _inspectorView.showDataInputChooser(handle, instance,
+ mapToGlobal(width, 0))
+ }
+ }
+ }
+
+ Component {
id: intSliderComponent
HandlerPropertyBaseSlider {
diff --git a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
index 612dd32c..609fb1d3 100644
--- a/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
+++ b/src/Authoring/Studio/Palettes/Timeline/Bindings/Qt3DSDMTimelineItemBinding.cpp
@@ -557,7 +557,11 @@ bool Qt3DSDMTimelineItemBinding::IsValidTransaction(EUserTransaction inTransacti
qt3dsdm::Qt3DSDMInstanceHandle theInstance = GetInstance();
switch (inTransaction) {
case EUserTransaction_Rename:
- return (GetObjectType() != OBJTYPE_SCENE && GetObjectType() != OBJTYPE_IMAGE);
+ // DataInput renaming is forbidden by convention. DataInput name is
+ // permanently assigned when it is added to the scene from a fixed list of
+ // available datainputs
+ return (GetObjectType() != OBJTYPE_SCENE && GetObjectType() != OBJTYPE_IMAGE
+ && GetObjectType() != OBJTYPE_DATAINPUT);
case EUserTransaction_Duplicate:
if (theInstance.Valid())
@@ -589,11 +593,13 @@ bool Qt3DSDMTimelineItemBinding::IsValidTransaction(EUserTransaction inTransacti
// component.
// This may include behavior assets which may be directly attached to the Scene.
// This is because by principal, components cannot exist on the Scene directly.
+ // DataInputs cannot reside inside component as they must be direct children
+ // of scene
qt3dsdm::Qt3DSDMInstanceHandle theParentInstance =
theBridge->GetParentInstance(theInstance);
if (theObjectType != OBJTYPE_LAYER && theObjectType != OBJTYPE_SCENE
&& theObjectType != OBJTYPE_MATERIAL && theObjectType != OBJTYPE_IMAGE
- && theObjectType != OBJTYPE_EFFECT
+ && theObjectType != OBJTYPE_EFFECT && theObjectType != OBJTYPE_DATAINPUT
&& (theParentInstance.Valid()
&& theBridge->GetObjectType(theParentInstance)
!= OBJTYPE_SCENE)) // This checks if the object is
diff --git a/src/Authoring/Studio/Qt3DStudio.pro b/src/Authoring/Studio/Qt3DStudio.pro
index f3c3b379..cb617aa8 100644
--- a/src/Authoring/Studio/Qt3DStudio.pro
+++ b/src/Authoring/Studio/Qt3DStudio.pro
@@ -277,6 +277,7 @@ SOURCES += \
Palettes/Inspector/InspectorControlModel.cpp \
Palettes/Inspector/ObjectListModel.cpp \
Palettes/Inspector/ObjectBrowserView.cpp \
+ Palettes/Inspector/DataInputChooserView.cpp \
Palettes/Inspector/TabOrderHandler.cpp \
Palettes/Inspector/MouseHelper.cpp \
Palettes/Project/ProjectView.cpp \
@@ -409,6 +410,7 @@ HEADERS += \
Palettes/Inspector/FileChooserView.h \
Palettes/Inspector/FileChooserModel.h \
Palettes/Inspector/TextureChooserView.h \
+ Palettes/Inspector/DataInputChooserView.h \
Palettes/Inspector/TabOrderHandler.h \
Palettes/Inspector/MouseHelper.h \
Palettes/Project/ProjectView.h \
diff --git a/src/Authoring/Studio/qml.qrc b/src/Authoring/Studio/qml.qrc
index fa0cc143..4a2ecb68 100644
--- a/src/Authoring/Studio/qml.qrc
+++ b/src/Authoring/Studio/qml.qrc
@@ -38,5 +38,6 @@
<file>Palettes/controls/StyledTooltip.qml</file>
<file>Palettes/controls/StyledToolButton.qml</file>
<file>Palettes/controls/StyledMenuSeparator.qml</file>
+ <file>Palettes/Inspector/DataInputBrowser.qml</file>
</qresource>
</RCC>