summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2019-03-08 16:23:03 +0200
committerMahmoud Badri <mahmoud.badri@qt.io>2019-03-12 13:29:07 +0000
commit4f6db42ce61e5a712ed196e96e0d90a1780c73fd (patch)
treeee90500be87525adca7285aad6155bd9bed509c1
parent52730ddc3a94acc32cd2b28fc49b45dd5f19e3c5 (diff)
Implement variants filtering dialog
Implement variants filtering toolbar action, when clicked it shows the filtering dialog where the user can choose the tags to be used by the viewer. Also update the 'preview on remote device' icon. Task-number: QT3DS-3115 Change-Id: I4d93c8cefe94726f1f04aa6fc7e6f9f07fb8a8b2 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp14
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.h1
-rw-r--r--src/Authoring/Studio/Application/FilterVariantsDlg.cpp101
-rw-r--r--src/Authoring/Studio/Application/FilterVariantsDlg.h62
-rw-r--r--src/Authoring/Studio/Application/FilterVariantsDlg.qml191
-rw-r--r--src/Authoring/Studio/Application/FilterVariantsModel.cpp165
-rw-r--r--src/Authoring/Studio/Application/FilterVariantsModel.h77
-rw-r--r--src/Authoring/Studio/Application/StudioApp.cpp1
-rw-r--r--src/Authoring/Studio/MainFrm.cpp68
-rw-r--r--src/Authoring/Studio/MainFrm.h10
-rw-r--r--src/Authoring/Studio/MainFrm.ui28
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp4
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp5
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h18
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml14
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/VariantsGroupModel.cpp38
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.cpp8
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.h4
-rw-r--r--src/Authoring/Studio/PreviewHelper.cpp10
-rw-r--r--src/Authoring/Studio/Qt3DStudio.pro8
-rw-r--r--src/Authoring/Studio/images.qrc6
-rw-r--r--src/Authoring/Studio/images/filter-disabled.pngbin0 -> 250 bytes
-rw-r--r--src/Authoring/Studio/images/filter-disabled@2x.pngbin0 -> 402 bytes
-rw-r--r--src/Authoring/Studio/images/filter.pngbin0 -> 236 bytes
-rw-r--r--src/Authoring/Studio/images/filter@2x.pngbin0 -> 369 bytes
-rw-r--r--src/Authoring/Studio/images/playback-variant@2x.pngbin0 -> 712 bytes
-rw-r--r--src/Authoring/Studio/images/playback_tools_low-02.pngbin519 -> 239 bytes
-rw-r--r--src/Authoring/Studio/images/playback_tools_low-02@2x.pngbin567 -> 366 bytes
-rw-r--r--src/Authoring/Studio/images/playback_tools_low-03.pngbin578 -> 243 bytes
-rw-r--r--src/Authoring/Studio/images/playback_tools_low-03@2x.pngbin693 -> 369 bytes
-rw-r--r--src/Authoring/Studio/images/playplayback-variant.pngbin0 -> 369 bytes
-rw-r--r--src/Authoring/Studio/images/remote-disabled.pngbin660 -> 316 bytes
-rw-r--r--src/Authoring/Studio/images/remote-disabled@2x.pngbin974 -> 578 bytes
-rw-r--r--src/Authoring/Studio/images/remote.pngbin660 -> 331 bytes
-rw-r--r--src/Authoring/Studio/images/remote@2x.pngbin965 -> 559 bytes
-rw-r--r--src/Authoring/Studio/qml.qrc1
-rw-r--r--src/Authoring/Studio/style.qss13
37 files changed, 799 insertions, 48 deletions
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
index 16003177..3749e25f 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
@@ -49,6 +49,7 @@ static ::CColor s_DisabledTextColor;
static QColor s_studioColor1;
static QColor s_studioColor2;
static QColor s_studioColor3;
+static QColor s_studioColor4;
static QColor s_backgroundColor;
static QColor s_guideColor;
static QColor s_selectionColor;
@@ -61,6 +62,7 @@ static QColor s_projectReferencedColor;
static QColor s_xAxisColor;
static QColor s_yAxisColor;
static QColor s_zAxisColor;
+static QColor s_inspectorGroupHeaderColor;
static QLinearGradient s_welcomeBackgroundGradient;
static QColor s_timelineRowColorNormal;
@@ -143,18 +145,20 @@ void CStudioPreferences::loadPreferences(const QString &filePath)
s_studioColor1 = QColor("#262829");
s_studioColor2 = QColor("#404244");
s_studioColor3 = QColor("#727476");
+ s_studioColor4 = QColor("#959596");
s_backgroundColor = QColor("#2e2f30");
s_guideColor = QColor("#f4be04");
s_selectionColor = QColor("#23516D");
s_textColor = QColor("#ffffff");
s_masterColor = QColor("#5caa15");
- s_disabledColor = QColor("#727476");
+ s_disabledColor = s_studioColor3;
s_dataInputColor = QColor("#ff5102");
s_matteColor = QColor("#222222");
s_projectReferencedColor = QColor("#aaaa00");
s_xAxisColor = QColor("#ca2f2e");
s_yAxisColor = QColor("#64cd35");
s_zAxisColor = QColor("#1e9fcd");
+ s_inspectorGroupHeaderColor = QColor("#111111");
s_welcomeBackgroundGradient = QLinearGradient(0.0, 0.0, 1.0, 0.0);
s_welcomeBackgroundGradient.setColorAt(0.0, QColor("#343E55"));
@@ -852,6 +856,7 @@ void CStudioPreferences::setQmlContextProperties(QQmlContext *qml)
qml->setContextProperty(QStringLiteral("_studioColor1"), s_studioColor1);
qml->setContextProperty(QStringLiteral("_studioColor2"), s_studioColor2);
qml->setContextProperty(QStringLiteral("_studioColor3"), s_studioColor3);
+ qml->setContextProperty(QStringLiteral("_studioColor4"), s_studioColor4);
qml->setContextProperty(QStringLiteral("_backgroundColor"), s_backgroundColor);
qml->setContextProperty(QStringLiteral("_buttonDownColor"), s_ButtonDownColor.getQColor());
qml->setContextProperty(QStringLiteral("_guideColor"), s_guideColor);
@@ -868,6 +873,8 @@ void CStudioPreferences::setQmlContextProperties(QQmlContext *qml)
qml->setContextProperty(QStringLiteral("_controlBaseHeight"), s_controlBaseHeight);
qml->setContextProperty(QStringLiteral("_idWidth"), s_idWidth);
qml->setContextProperty(QStringLiteral("_valueWidth"), s_valueWidth);
+ qml->setContextProperty(QStringLiteral("_inspectorGroupHeaderColor"),
+ s_inspectorGroupHeaderColor);
}
QColor CStudioPreferences::studioColor1()
@@ -885,6 +892,11 @@ QColor CStudioPreferences::studioColor3()
return s_studioColor3;
}
+QColor CStudioPreferences::studioColor4()
+{
+ return s_studioColor4;
+}
+
QColor CStudioPreferences::backgroundColor()
{
return s_backgroundColor;
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
index 59fc4b5c..4ef185ed 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
@@ -165,6 +165,7 @@ public:
static QColor studioColor1();
static QColor studioColor2();
static QColor studioColor3();
+ static QColor studioColor4();
static QColor backgroundColor();
static QColor guideColor();
static QColor selectionColor();
diff --git a/src/Authoring/Studio/Application/FilterVariantsDlg.cpp b/src/Authoring/Studio/Application/FilterVariantsDlg.cpp
new file mode 100644
index 00000000..b6213c4a
--- /dev/null
+++ b/src/Authoring/Studio/Application/FilterVariantsDlg.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 "FilterVariantsDlg.h"
+#include "StudioPreferences.h"
+#include "StudioUtils.h"
+#include "FilterVariantsModel.h"
+
+#include <QAction>
+#include <QtCore/qtimer.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlengine.h>
+
+FilterVariantsDlg::FilterVariantsDlg(QWidget *parent, QAction *action, int actionSize)
+ : QQuickWidget(parent)
+ , m_model(new FilterVariantsModel(m_variantsFilter, this))
+ , m_action(action)
+ , m_actionSize(actionSize)
+{
+ setWindowTitle(tr("Filter variants"));
+ QTimer::singleShot(0, this, &FilterVariantsDlg::initialize);
+}
+
+void FilterVariantsDlg::initialize()
+{
+ CStudioPreferences::setQmlContextProperties(rootContext());
+ rootContext()->setContextProperty(QStringLiteral("_view"), this);
+ rootContext()->setContextProperty(QStringLiteral("_model"), m_model);
+ setSource(QUrl(QStringLiteral("qrc:/Application/FilterVariantsDlg.qml")));
+}
+
+QString FilterVariantsDlg::filterStr() const
+{
+ QString ret;
+ if (!m_variantsFilter.isEmpty()) {
+ const auto groups = m_variantsFilter.keys();
+ for (auto &g : groups) {
+ const auto group = m_variantsFilter[g];
+ for (auto &tag : group)
+ ret.append(g + QLatin1Char(':') + tag + QLatin1Char(','));
+ }
+
+ if (!m_variantsFilter.isEmpty())
+ ret.chop(1);
+ }
+
+ return ret;
+}
+
+int FilterVariantsDlg::actionSize() const
+{
+ return m_actionSize;
+}
+
+void FilterVariantsDlg::showEvent(QShowEvent *event)
+{
+ m_model->refresh();
+ QQuickWidget::showEvent(event);
+}
+
+void FilterVariantsDlg::focusOutEvent(QFocusEvent *e)
+{
+ QQuickWidget::focusOutEvent(e);
+ m_action->setChecked(false);
+ QTimer::singleShot(0, this, &QQuickWidget::close);
+}
+
+void FilterVariantsDlg::keyPressEvent(QKeyEvent *e)
+{
+ if (e->key() == Qt::Key_Escape) {
+ m_action->setChecked(false);
+ QTimer::singleShot(0, this, &FilterVariantsDlg::close);
+ }
+
+ QQuickWidget::keyPressEvent(e);
+}
diff --git a/src/Authoring/Studio/Application/FilterVariantsDlg.h b/src/Authoring/Studio/Application/FilterVariantsDlg.h
new file mode 100644
index 00000000..ed2fd8a4
--- /dev/null
+++ b/src/Authoring/Studio/Application/FilterVariantsDlg.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 FILTER_VARIANTS_DLG_H
+#define FILTER_VARIANTS_DLG_H
+
+#include <QtQuickWidgets/qquickwidget.h>
+
+class FilterVariantsModel;
+
+class FilterVariantsDlg : public QQuickWidget
+{
+ Q_OBJECT
+
+public:
+ explicit FilterVariantsDlg(QWidget *parent, QAction *action, int actionSize);
+
+ Q_INVOKABLE int actionSize() const;
+
+ QString filterStr() const;
+
+protected:
+ void focusOutEvent(QFocusEvent *e) override;
+ void keyPressEvent(QKeyEvent *e) override;
+
+private:
+ void showEvent(QShowEvent *event) override;
+
+ void initialize();
+
+ QHash<QString, QSet<QString> > m_variantsFilter; // key: group, value: tags
+ FilterVariantsModel *m_model = nullptr;
+ QAction *m_action = nullptr;
+ int m_actionSize = 0; // width/height of the action icon
+};
+
+#endif // FILTER_VARIANTS_DLG_H
diff --git a/src/Authoring/Studio/Application/FilterVariantsDlg.qml b/src/Authoring/Studio/Application/FilterVariantsDlg.qml
new file mode 100644
index 00000000..1f971509
--- /dev/null
+++ b/src/Authoring/Studio/Application/FilterVariantsDlg.qml
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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.2
+import QtQuick.Layouts 1.3
+
+Rectangle {
+ id: root
+ width: 400
+ height: 280
+ color: _backgroundColor
+ border.color: _studioColor3
+
+ // hider for the border segment between the icon and the dialog
+ Rectangle {
+ color: _backgroundColor
+ x: 1
+ width: _view.actionSize() - 2 // -1px from each side
+ height: 1
+ }
+
+ Item {
+ height: 25
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: 10
+
+ Text {
+ text: qsTr("Select filtering")
+ color: _studioColor4
+ font.pointSize: 10
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ Rectangle { // clear button
+ width: 60
+ height: 25
+ color: _backgroundColor
+ border.color: _studioColor4
+ anchors.right: parent.right
+
+ Text {
+ anchors.centerIn: parent
+ text: qsTr("Clear")
+ font.pointSize: 10
+ color: _studioColor4
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: _model.clearAll();
+ }
+ }
+ }
+
+ Flickable {
+ anchors.top: parent.top
+ anchors.topMargin: 35
+ anchors.fill: parent
+ contentWidth: variantsColumn.width
+ contentHeight: variantsColumn.height
+ flickableDirection: Flickable.VerticalFlick
+ clip: true
+
+ ScrollBar.vertical: ScrollBar {}
+
+ Column {
+ id: variantsColumn
+ spacing: 10
+ padding: 10
+
+ Repeater { // groups
+ id: tagsRepeater
+ model: _model
+ property int maxGroupLabelWidth;
+
+ onItemAdded: {
+ // make all group labels have equal width as the widest one
+ if (index == 0)
+ maxGroupLabelWidth = 20; // min group label width
+
+ if (item.groupLabelWidth > maxGroupLabelWidth) {
+ maxGroupLabelWidth = item.groupLabelWidth;
+
+ if (maxGroupLabelWidth > 150) // max group label width
+ maxGroupLabelWidth = 150;
+ }
+ }
+
+ Row { // a row of a group and its tags
+ spacing: 5
+
+ readonly property var tagsModel: model.tags
+ readonly property var groupModel: model
+ readonly property int groupLabelWidth: tLabel.implicitWidth + 10
+
+ Rectangle { // group button
+ width: tagsRepeater.maxGroupLabelWidth;
+ height: 25
+ color: _backgroundColor
+ border.color: model.color
+
+ Text {
+ id: tLabel
+ text: model.group
+ color: model.color
+ elide: Text.ElideRight
+ anchors.centerIn: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent;
+ onClicked: _model.toggleGroupState(model.group);
+ }
+ }
+
+ Flow { // group tags
+ width: root.width - tagsRepeater.maxGroupLabelWidth - 15
+ spacing: 5
+
+ Repeater {
+ model: tagsModel
+
+ Loader {
+ readonly property var tagsModel: model
+ readonly property var grpModel: groupModel
+ sourceComponent: tagComponent
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Component {
+ id: tagComponent
+
+ Rectangle {
+ property bool toggled: tagsModel ? tagsModel.selected : false
+ property string grpColor: grpModel ? grpModel.color : ""
+
+ width: Math.max(tLabel.width + 10, 60)
+ height: 25
+ color: toggled ? grpColor : _backgroundColor
+ border.color: toggled ? _studioColor4 : grpColor;
+
+ Text {
+ id: tLabel
+ anchors.centerIn: parent
+ text: tagsModel ? tagsModel.tag : ""
+ color: toggled ? _textColor : _studioColor4
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ toggled = !toggled;
+ _model.setTagState(grpModel.group, tagsModel.tag, toggled);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Authoring/Studio/Application/FilterVariantsModel.cpp b/src/Authoring/Studio/Application/FilterVariantsModel.cpp
new file mode 100644
index 00000000..e7badfd0
--- /dev/null
+++ b/src/Authoring/Studio/Application/FilterVariantsModel.cpp
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 "FilterVariantsModel.h"
+#include "VariantsTagModel.h"
+#include "StudioApp.h"
+#include "Views.h"
+#include "MainFrm.h"
+#include "Core.h"
+#include "VariantTagDialog.h"
+
+FilterVariantsModel::FilterVariantsModel(VariantsFilterT &variantsFilter, QObject *parent)
+ : QAbstractListModel(parent)
+ , m_variantsFilter(variantsFilter)
+{
+
+}
+
+void FilterVariantsModel::refresh()
+{
+ beginResetModel();
+
+ // delete tag models
+ for (auto &g : qAsConst(m_data))
+ delete g.m_tagsModel;
+
+ m_data.clear();
+
+ // build the variants data model
+ const auto variantsDef = g_StudioApp.GetCore()->getProjectFile().variantsDef();
+ const auto keys = variantsDef.keys();
+ for (auto &group : keys) {
+ VariantsGroupData g;
+ g.m_title = group;
+ g.m_color = variantsDef[group].m_color;
+ QVector<std::pair<QString, bool> > tags;
+ for (int i = 0; i < variantsDef[group].m_tags.length(); ++i) {
+ QString tag = variantsDef[group].m_tags[i];
+ bool state = m_variantsFilter.contains(group) && m_variantsFilter[group].contains(tag);
+ tags.append({tag, state});
+ }
+ g.m_tagsModel = new VariantsTagModel(tags);
+ m_data.push_back(g);
+ }
+
+ endResetModel();
+}
+
+int FilterVariantsModel::rowCount(const QModelIndex &parent) const
+{
+ // For list models only the root node (an invalid parent) should return the list's size. For all
+ // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
+ if (parent.isValid())
+ return 0;
+
+ return m_data.size();
+}
+
+QVariant FilterVariantsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ if (role == GroupTitleRole)
+ return m_data.at(index.row()).m_title;
+ else if (role == GroupColorRole)
+ return m_data.at(index.row()).m_color;
+ else if (role == TagsRole)
+ return QVariant::fromValue(m_data.at(index.row()).m_tagsModel);
+
+ return QVariant();
+}
+
+void FilterVariantsModel::setTagState(const QString &group, const QString &tag, bool selected)
+{
+ if (selected)
+ m_variantsFilter[group].insert(tag);
+ else
+ m_variantsFilter[group].remove(tag);
+
+ bool filtered = false;
+ for (auto &g : qAsConst(m_variantsFilter)) {
+ if (!g.isEmpty()) {
+ filtered = true;
+ break;
+ }
+ }
+
+ g_StudioApp.GetViews()->getMainFrame()->updateActionPreviewVariantsState(filtered);
+}
+
+void FilterVariantsModel::toggleGroupState(const QString &group)
+{
+ const auto variantsDef = g_StudioApp.GetCore()->getProjectFile().variantsDef();
+
+ if (m_variantsFilter[group].size() < variantsDef[group].m_tags.size()) {
+ // not all tags selected, select all
+ const auto tags = variantsDef[group].m_tags;
+ for (auto &t : tags)
+ m_variantsFilter[group].insert(t);
+ } else {
+ // all tags selected, select none
+ m_variantsFilter[group].clear();
+ }
+ refresh();
+
+ bool filtered = false;
+ for (auto &g : qAsConst(m_variantsFilter)) {
+ if (!g.isEmpty()) {
+ filtered = true;
+ break;
+ }
+ }
+
+ g_StudioApp.GetViews()->getMainFrame()->updateActionPreviewVariantsState(filtered);
+}
+
+void FilterVariantsModel::clearAll()
+{
+ m_variantsFilter.clear();
+ refresh();
+ g_StudioApp.GetViews()->getMainFrame()->updateActionPreviewVariantsState(false);
+}
+
+QHash<int, QByteArray> FilterVariantsModel::roleNames() const
+{
+ auto names = QAbstractListModel::roleNames();
+ names.insert(GroupTitleRole, "group");
+ names.insert(GroupColorRole, "color");
+ names.insert(TagsRole, "tags");
+ return names;
+}
+
+Qt::ItemFlags FilterVariantsModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ return Qt::ItemIsEditable;
+}
diff --git a/src/Authoring/Studio/Application/FilterVariantsModel.h b/src/Authoring/Studio/Application/FilterVariantsModel.h
new file mode 100644
index 00000000..86df5377
--- /dev/null
+++ b/src/Authoring/Studio/Application/FilterVariantsModel.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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 VARIANTSGROUPMODEL_H
+#define VARIANTSGROUPMODEL_H
+
+#include <QtCore/qabstractitemmodel.h>
+
+class VariantsTagModel;
+
+using VariantsFilterT = QHash<QString, QSet<QString> >;
+
+class FilterVariantsModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ explicit FilterVariantsModel(VariantsFilterT &variantsFilter, QObject *parent = nullptr);
+
+ enum Roles {
+ GroupTitleRole = Qt::UserRole + 1,
+ GroupColorRole,
+ TagsRole
+ };
+
+ struct VariantsGroupData
+ {
+ QString m_title;
+ QString m_color;
+ VariantsTagModel *m_tagsModel = nullptr;
+ };
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = GroupTitleRole) const override;
+
+ Qt::ItemFlags flags(const QModelIndex& index) const override;
+
+ void refresh();
+
+ Q_INVOKABLE void setTagState(const QString &group, const QString &tag, bool selected);
+ Q_INVOKABLE void toggleGroupState(const QString &group);
+ Q_INVOKABLE void clearAll();
+
+protected:
+ QHash<int, QByteArray> roleNames() const override;
+
+private:
+ VariantsFilterT &m_variantsFilter;
+ QVector<VariantsGroupData> m_data;
+};
+
+#endif // VARIANTSGROUPMODEL_H
diff --git a/src/Authoring/Studio/Application/StudioApp.cpp b/src/Authoring/Studio/Application/StudioApp.cpp
index 1bd847e7..b444b2d9 100644
--- a/src/Authoring/Studio/Application/StudioApp.cpp
+++ b/src/Authoring/Studio/Application/StudioApp.cpp
@@ -1730,6 +1730,7 @@ bool CStudioApp::OnLoadDocument(const QString &inDocument, bool inShowStartupDia
m_core->getProjectFile().loadSubpresentationsAndDatainputs(m_subpresentations,
m_dataInputDialogItems);
m_core->getProjectFile().loadVariants();
+ GetViews()->getMainFrame()->updateActionFilterEnableState();
GetViews()->getMainFrame()->getSlideView()->refreshVariants();
getRenderer().RegisterSubpresentations(m_subpresentations);
diff --git a/src/Authoring/Studio/MainFrm.cpp b/src/Authoring/Studio/MainFrm.cpp
index 0acd00e8..3069304e 100644
--- a/src/Authoring/Studio/MainFrm.cpp
+++ b/src/Authoring/Studio/MainFrm.cpp
@@ -61,6 +61,7 @@
#include "RowTree.h"
#include "WidgetControl.h"
#include "SlideView.h"
+#include "FilterVariantsDlg.h"
#include <QtGui/qevent.h>
#include <QtGui/qdesktopservices.h>
@@ -91,6 +92,10 @@ CMainFrame::CMainFrame()
{
m_ui->setupUi(this);
+ // allow styling this action
+ m_ui->m_PlaybackToolbar->widgetForAction(m_ui->actionFilterVariants)
+ ->setObjectName("actionFilterVariants");
+
// Register TitilliumWeb as application font in case user doesn't have it already installed
QFontDatabase::addApplicationFont(QStringLiteral(":/TitilliumWeb-Light.ttf"));
QFontDatabase::addApplicationFont(QStringLiteral(":/TitilliumWeb-Regular.ttf"));
@@ -219,8 +224,8 @@ CMainFrame::CMainFrame()
m_sceneView.data(), &CSceneView::onToolGroupSelection);
// Playback toolbar
- connect(m_ui->actionPreview, &QAction::triggered,
- this, &CMainFrame::OnPlaybackPreviewRuntime2);
+ connect(m_ui->actionPreview, &QAction::triggered, this, &CMainFrame::OnPlaybackPreviewRuntime2);
+ connect(m_ui->actionFilterVariants, &QAction::triggered, this, &CMainFrame::onFilterVariants);
connect(m_ui->actionRemote_Preview, &QAction::triggered,
this, &CMainFrame::OnPlaybackPreviewRemote);
@@ -1040,6 +1045,58 @@ void CMainFrame::OnPlaybackPreviewRuntime2()
OnPlaybackPreview(QStringLiteral("q3dsviewer"));
}
+void CMainFrame::onFilterVariants()
+{
+ if (m_ui->actionFilterVariants->isChecked()) {
+ QTimer::singleShot(0, [&] {
+ QRect actionGeom = m_ui->m_PlaybackToolbar->actionGeometry(m_ui->actionFilterVariants);
+ if (!m_filterVariantsDlg) {
+ m_filterVariantsDlg = new FilterVariantsDlg(this, m_ui->actionFilterVariants,
+ actionGeom.width());
+ }
+
+ m_filterVariantsDlg->activateWindow();
+ m_filterVariantsDlg->raise();
+ m_filterVariantsDlg->move(m_ui->m_PlaybackToolbar->pos()
+ + QPoint(actionGeom.x(), actionGeom.bottom()));
+ m_filterVariantsDlg->setFocus();
+ m_filterVariantsDlg->show();
+ });
+ } else {
+ m_filterVariantsDlg->close();
+ }
+}
+
+QString CMainFrame::getVariantsFilterStr() const
+{
+ if (m_filterVariantsDlg)
+ return m_filterVariantsDlg->filterStr();
+
+ return {};
+}
+
+void CMainFrame::updateActionFilterEnableState()
+{
+ bool enable = false;
+ const auto variantsDef = g_StudioApp.GetCore()->getProjectFile().variantsDef();
+ const auto keys = variantsDef.keys();
+ for (auto &group : keys) {
+ if (!variantsDef[group].m_tags.isEmpty()) {
+ enable = true;
+ break;
+ }
+ }
+
+ m_ui->actionFilterVariants->setEnabled(enable);
+}
+
+void CMainFrame::updateActionPreviewVariantsState(bool isFiltered)
+{
+ m_ui->actionPreview->setIcon(QIcon(isFiltered
+ ? QStringLiteral(":/images/playplayback-variant.png")
+ : QStringLiteral(":/images/playback_tools_low-03.png")));
+}
+
void CMainFrame::OnPlaybackPreviewRemote()
{
OnPlaybackPreview(QStringLiteral("q3dsviewer"), true);
@@ -1927,6 +1984,13 @@ SlideView *CMainFrame::getSlideView() const
->widget());
}
+InspectorControlView *CMainFrame::getInspectorView() const
+{
+ return static_cast<InspectorControlView *>(m_paletteManager
+ ->GetControl(CPaletteManager::CONTROLTYPE_INSPECTOR)
+ ->widget());
+}
+
CRecentItems *CMainFrame::GetRecentItems()
{
return m_recentItems.data();
diff --git a/src/Authoring/Studio/MainFrm.h b/src/Authoring/Studio/MainFrm.h
index 6c3a2ce7..5f7cd0d0 100644
--- a/src/Authoring/Studio/MainFrm.h
+++ b/src/Authoring/Studio/MainFrm.h
@@ -57,6 +57,8 @@ class RemoteDeploymentSender;
class TimelineWidget;
class CStudioPreferencesPropSheet;
class SlideView;
+class InspectorControlView;
+class FilterVariantsDlg;
#ifdef QT_NAMESPACE
using namespace QT_NAMESPACE;
@@ -158,6 +160,7 @@ public:
void OnPlaybackPreviewRuntime1();
void OnPlaybackPreviewRuntime2();
void OnPlaybackPreviewRemote();
+ void onFilterVariants();
void OnUpdatePlaybackPreview();
void OnUpdateToolMove();
void OnUpdateToolRotate();
@@ -237,6 +240,7 @@ public:
TimelineWidget *getTimelineWidget() const;
SlideView *getSlideView() const;
+ InspectorControlView *getInspectorView() const;
void EditPreferences(short inPageIndex);
@@ -250,6 +254,9 @@ public:
void toggleSelectMode();
void showScene();
+ QString getVariantsFilterStr() const;
+ void updateActionFilterEnableState();
+ void updateActionPreviewVariantsState(bool isFiltered);
Q_SIGNALS:
void playStateChanged(bool started);
@@ -270,6 +277,9 @@ protected:
bool m_playbackFlag = false;
bool m_resettingLayout = false;
+
+private:
+ FilterVariantsDlg *m_filterVariantsDlg = nullptr;
};
#endif // INCLUDED_MAIN_FRAME
diff --git a/src/Authoring/Studio/MainFrm.ui b/src/Authoring/Studio/MainFrm.ui
index 7c15e262..3a19a548 100644
--- a/src/Authoring/Studio/MainFrm.ui
+++ b/src/Authoring/Studio/MainFrm.ui
@@ -235,6 +235,9 @@ Project palette using Import functionality.</string>
<addaction name="actionWireframe"/>
</widget>
<widget class="QToolBar" name="m_PlaybackToolbar">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
<property name="windowTitle">
<string>Playback</string>
</property>
@@ -252,6 +255,7 @@ Project palette using Import functionality.</string>
</attribute>
<addaction name="actionPreview"/>
<addaction name="actionRemote_Preview"/>
+ <addaction name="actionFilterVariants"/>
</widget>
<action name="action_Reference_Manual">
<property name="text">
@@ -771,6 +775,28 @@ Project palette using Import functionality.</string>
<string>F5</string>
</property>
</action>
+ <action name="actionFilterVariants">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="icon">
+ <iconset resource="images.qrc">
+ <normaloff>:/images/filter.png</normaloff>
+ <disabledoff>:/images/filter-disabled.png</disabledoff>:/images/filter.png</iconset>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="toolTip">
+ <string>Filter variants (F7)</string>
+ </property>
+ <property name="shortcut">
+ <string>F7</string>
+ </property>
+ </action>
<action name="actionSubpresentations">
<property name="text">
<string>Sub-presentations...</string>
@@ -842,6 +868,8 @@ Project palette using Import functionality.</string>
<property name="icon">
<iconset>
<normalon>:/images/remote.png</normalon>
+ <disabledoff>:/images/remote-disabled.png</disabledoff>
+ <disabledon>:/images/remote-disabled.png</disabledon>
</iconset>
</property>
<property name="text">
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
index 5cf47d1f..8b993c75 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
@@ -109,9 +109,9 @@ static std::pair<bool, bool> getSlideCharacteristics(qt3dsdm::Qt3DSDMInstanceHan
}
InspectorControlModel::InspectorControlModel(VariantsGroupModel *variantsModel, QObject *parent)
- : m_variantsModel(variantsModel)
- , QAbstractListModel(parent)
+ : QAbstractListModel(parent)
, m_UpdatableEditor(*g_StudioApp.GetCore()->GetDoc())
+ , m_variantsModel(variantsModel)
{
m_modifiedProperty.first = 0;
m_modifiedProperty.second = 0;
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
index be8cdbcf..5b4996a1 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
@@ -78,8 +78,6 @@ InspectorControlView::InspectorControlView(const QSize &preferredSize, QWidget *
m_variantsGroupModel(new VariantsGroupModel(this)),
m_inspectorControlModel(new InspectorControlModel(m_variantsGroupModel, this)),
m_meshChooserView(new MeshChooserView(this)),
- m_instance(0),
- m_handle(0),
m_preferredSize(preferredSize)
{
setResizeMode(QQuickWidget::SizeRootObjectToView);
@@ -484,6 +482,8 @@ void InspectorControlView::showTagContextMenu(int x, int y, const QString &group
g_StudioApp.GetViews()->getMainFrame()->getTimelineWidget()->refreshVariants();
g_StudioApp.GetViews()->getMainFrame()->getSlideView()->refreshVariants();
m_variantsGroupModel->refresh();
+ if (g_StudioApp.GetCore()->getProjectFile().variantsDef()[group].m_tags.size() == 0)
+ g_StudioApp.GetViews()->getMainFrame()->updateActionFilterEnableState();
});
theContextMenu.exec(mapToGlobal({x, y}));
@@ -522,6 +522,7 @@ void InspectorControlView::showGroupContextMenu(int x, int y, const QString &gro
projectFile.deleteVariantGroup(group);
g_StudioApp.GetViews()->getMainFrame()->getTimelineWidget()->refreshVariants();
g_StudioApp.GetViews()->getMainFrame()->getSlideView()->refreshVariants();
+ g_StudioApp.GetViews()->getMainFrame()->updateActionFilterEnableState();
m_variantsGroupModel->refresh();
});
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
index 14936b57..c997721a 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.h
@@ -61,6 +61,7 @@ class InspectorControlView : public QQuickWidget,
Q_OBJECT
Q_PROPERTY(QString titleText READ titleText NOTIFY titleChanged FINAL)
Q_PROPERTY(QString titleIcon READ titleIcon NOTIFY titleChanged FINAL)
+
public:
explicit InspectorControlView(const QSize &preferredSize, QWidget *parent = nullptr);
~InspectorControlView() override;
@@ -69,11 +70,14 @@ public:
QAbstractItemModel *inspectorControlModel() const;
QString titleText() const;
- Q_INVOKABLE QColor titleColor(int instance = 0, int handle = 0) const;
QString titleIcon() const;
+ VariantsGroupModel *variantsModel() const { return m_variantsGroupModel; }
+ Q_INVOKABLE QColor titleColor(int instance = 0, int handle = 0) const;
+ Q_INVOKABLE QColor showColorDialog(const QColor &color);
Q_INVOKABLE void showContextMenu(int x, int y, int handle, int instance);
Q_INVOKABLE void showTagContextMenu(int x, int y, const QString &group, const QString &tag);
+ Q_INVOKABLE void showDataInputChooser(int handle, int instance, const QPoint &point);
Q_INVOKABLE void showGroupContextMenu(int x, int y, const QString &group);
Q_INVOKABLE QObject *showImageChooser(int handle, int instance, const QPoint &point);
Q_INVOKABLE QObject *showFilesChooser(int handle, int instance, const QPoint &point);
@@ -81,20 +85,18 @@ public:
Q_INVOKABLE QObject *showObjectReference(int handle, int instance, const QPoint &point);
Q_INVOKABLE QObject *showMaterialReference(int handle, int instance, const QPoint &point);
Q_INVOKABLE QObject *showTextureChooser(int handle, int instance, const QPoint &point);
- Q_INVOKABLE void showDataInputChooser(int handle, int instance, const QPoint &point);
- Q_INVOKABLE QColor showColorDialog(const QColor &color);
Q_INVOKABLE bool toolTipsEnabled();
- Q_INVOKABLE QString convertPathToProjectRoot(const QString &presentationPath);
Q_INVOKABLE bool isRefMaterial(int instance) const;
- Q_INVOKABLE QString noneString() const;
Q_INVOKABLE bool isEditable(int handle) const;
+ Q_INVOKABLE QString convertPathToProjectRoot(const QString &presentationPath);
+ Q_INVOKABLE QString noneString() const;
// IDataModelListener
void OnBeginDataModelNotifications() override;
void OnEndDataModelNotifications() override;
void OnImmediateRefreshInstanceSingle(qt3dsdm::Qt3DSDMInstanceHandle inInstance) override;
void OnImmediateRefreshInstanceMultiple(qt3dsdm::Qt3DSDMInstanceHandle *inInstance,
- long inInstanceCount) override;
+ long inInstanceCount) override;
Q_SIGNALS:
void titleChanged();
@@ -143,8 +145,8 @@ private:
std::vector<Q3DStudio::CFilePath> m_fileList;
MouseHelper m_mouseHelper;
- int m_instance;
- int m_handle;
+ int m_instance = 0;
+ int m_handle = 0;
QSize m_preferredSize;
QColor m_currentColor;
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
index ab0b8db3..6c806aa2 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.qml
@@ -211,7 +211,7 @@ Rectangle {
x: -10
width: delegateItem.width
height: 25
- color: "#111111"
+ color: _inspectorGroupHeaderColor
StyledLabel {
x: 30
@@ -1143,7 +1143,7 @@ Rectangle {
Text {
text: qsTr("There are no variant tags yet. Click [+ Group] to add a new tags group and start adding tags.")
- color: "#ffffff"
+ color: _textColor
visible: _variantsGroupModel.variantsEmpty
}
@@ -1242,19 +1242,19 @@ Rectangle {
id: tagComponent
Rectangle {
- property bool toggled: tagsModel.selected
+ property bool toggled: tagsModel ? tagsModel.selected : false
property string grpColor: grpModel ? grpModel.color : ""
width: Math.max(tLabel.width + 10, 60)
height: 25
- color: toggled ? grpColor : "#2e2f30"
- border.color: "#959596"
+ color: toggled ? grpColor : _backgroundColor
+ border.color: _studioColor4
Text {
id: tLabel
anchors.centerIn: parent
- text: tagsModel.tag
- color: toggled ? "#ffffff" : "#959596"
+ text: tagsModel ? tagsModel.tag : ""
+ color: toggled ? _textColor : _studioColor4
}
MouseArea {
diff --git a/src/Authoring/Studio/Palettes/Inspector/VariantsGroupModel.cpp b/src/Authoring/Studio/Palettes/Inspector/VariantsGroupModel.cpp
index e31a5876..b98aeae0 100644
--- a/src/Authoring/Studio/Palettes/Inspector/VariantsGroupModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/VariantsGroupModel.cpp
@@ -30,6 +30,8 @@
#include "VariantsTagModel.h"
#include "StudioApp.h"
#include "Core.h"
+#include "Views.h"
+#include "MainFrm.h"
#include "Qt3DSDMStudioSystem.h"
#include "ClientDataModelBridge.h"
#include "IDocumentEditor.h"
@@ -63,6 +65,11 @@ void VariantsGroupModel::refresh()
qt3dsdm::SValue sValue;
if (propertySystem->GetInstancePropertyValue(m_instance, m_property, sValue)) {
beginResetModel();
+
+ // delete tag models
+ for (auto &g : qAsConst(m_data))
+ delete g.m_tagsModel;
+
m_data.clear();
QString propVal = qt3dsdm::get<qt3dsdm::TDataStrPtr>(sValue)->toQString();
@@ -83,15 +90,13 @@ void VariantsGroupModel::refresh()
g.m_title = group;
g.m_color = variantsDef[group].m_color;
- VariantsTagModel *m = new VariantsTagModel(this);
QVector<std::pair<QString, bool> > tags;
- for (int i = 0; i < variantsDef[group].m_tags.length(); ++i)
+ for (int i = 0; i < variantsDef[group].m_tags.length(); ++i) {
tags.append({variantsDef[group].m_tags[i],
propTags[group].contains(variantsDef[group].m_tags[i])});
+ }
- m->init(tags);
- g.m_tagsModel = m;
-
+ g.m_tagsModel = new VariantsTagModel(tags);
m_data.push_back(g);
}
@@ -160,6 +165,19 @@ void VariantsGroupModel::addNewTag(const QString &group)
if (dlg.exec() == QDialog::Accepted) {
g_StudioApp.GetCore()->getProjectFile().addVariantTag(group, dlg.getNames().second);
refresh();
+
+ if (g_StudioApp.GetCore()->getProjectFile().variantsDef()[group].m_tags.size() == 1)
+ g_StudioApp.GetViews()->getMainFrame()->updateActionFilterEnableState();
+ }
+}
+
+void VariantsGroupModel::addNewGroup()
+{
+ VariantTagDialog dlg(VariantTagDialog::AddGroup);
+
+ if (dlg.exec() == QDialog::Accepted) {
+ g_StudioApp.GetCore()->getProjectFile().addVariantGroup(dlg.getNames().second);
+ refresh();
}
}
@@ -208,16 +226,6 @@ void VariantsGroupModel::exportVariants()
StudioUtils::commitDomDocumentSave(file, domDoc);
}
-void VariantsGroupModel::addNewGroup()
-{
- VariantTagDialog dlg(VariantTagDialog::AddGroup);
-
- if (dlg.exec() == QDialog::Accepted) {
- g_StudioApp.GetCore()->getProjectFile().addVariantGroup(dlg.getNames().second);
- refresh();
- }
-}
-
QHash<int, QByteArray> VariantsGroupModel::roleNames() const
{
auto names = QAbstractListModel::roleNames();
diff --git a/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.cpp b/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.cpp
index 910b4f09..30f33635 100644
--- a/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.cpp
@@ -28,17 +28,13 @@
#include "VariantsTagModel.h"
-VariantsTagModel::VariantsTagModel(QObject *parent)
+VariantsTagModel::VariantsTagModel(const QVector<std::pair<QString, bool> > &data, QObject *parent)
: QAbstractListModel(parent)
+ , m_data(data)
{
}
-void VariantsTagModel::init(const QVector<std::pair<QString, bool> > &data)
-{
- m_data = data;
-}
-
void VariantsTagModel::updateTagState(const QString &tag, bool selected)
{
for (auto &t : m_data) {
diff --git a/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.h b/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.h
index 01bb4e73..392de760 100644
--- a/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.h
+++ b/src/Authoring/Studio/Palettes/Inspector/VariantsTagModel.h
@@ -36,7 +36,8 @@ class VariantsTagModel : public QAbstractListModel
Q_OBJECT
public:
- explicit VariantsTagModel(QObject *parent = nullptr);
+ explicit VariantsTagModel(const QVector<std::pair<QString, bool> > &data,
+ QObject *parent = nullptr);
enum Roles {
TagRole = Qt::UserRole + 1,
@@ -48,7 +49,6 @@ public:
Qt::ItemFlags flags(const QModelIndex& index) const override;
- void init(const QVector<std::pair<QString, bool> > &data);
void updateTagState(const QString &tag, bool selected);
QString serialize(const QString &groupName) const;
diff --git a/src/Authoring/Studio/PreviewHelper.cpp b/src/Authoring/Studio/PreviewHelper.cpp
index 18bc6223..ef029ca7 100644
--- a/src/Authoring/Studio/PreviewHelper.cpp
+++ b/src/Authoring/Studio/PreviewHelper.cpp
@@ -36,6 +36,8 @@
#include "StudioPreferences.h"
#include "StudioProjectSettings.h"
#include "Core.h"
+#include "Views.h"
+#include "MainFrm.h"
#include "Qt3DSFileTools.h"
#include <QtWidgets/qinputdialog.h>
@@ -203,7 +205,13 @@ void CPreviewHelper::DoPreviewViaConfig(Q3DStudio::CBuildConfiguration * /*inSel
delete connection;
cleanupProcess(p, pDocStr);
});
- p->start(theCommandStr, { *pDocStr });
+
+ QStringList args {*pDocStr};
+ QString variantsArg = g_StudioApp.GetViews()->getMainFrame()->getVariantsFilterStr();
+ if (!variantsArg.isEmpty())
+ args << "-v" << variantsArg;
+
+ p->start(theCommandStr, args);
if (!p->waitForStarted()) {
QMessageBox::critical(nullptr, QObject::tr("Error Launching Viewer"),
diff --git a/src/Authoring/Studio/Qt3DStudio.pro b/src/Authoring/Studio/Qt3DStudio.pro
index 86103a2c..3d35ad58 100644
--- a/src/Authoring/Studio/Qt3DStudio.pro
+++ b/src/Authoring/Studio/Qt3DStudio.pro
@@ -229,7 +229,9 @@ HEADERS += \
Palettes/TimelineGraphicsView/ui/RowTimelineCommentItem.h \
Palettes/Inspector/VariantsGroupModel.h \
Palettes/Inspector/VariantsTagModel.h \
- Palettes/Inspector/VariantTagDialog.h
+ Palettes/Inspector/VariantTagDialog.h \
+ Application/FilterVariantsDlg.h \
+ Application/FilterVariantsModel.h
FORMS += \
MainFrm.ui \
@@ -409,7 +411,9 @@ SOURCES += \
Palettes/TimelineGraphicsView/ui/RowTimelineCommentItem.cpp \
Palettes/Inspector/VariantsGroupModel.cpp \
Palettes/Inspector/VariantsTagModel.cpp \
- Palettes/Inspector/VariantTagDialog.cpp
+ Palettes/Inspector/VariantTagDialog.cpp \
+ Application/FilterVariantsDlg.cpp \
+ Application/FilterVariantsModel.cpp
RESOURCES += \
MainFrm.qrc \
diff --git a/src/Authoring/Studio/images.qrc b/src/Authoring/Studio/images.qrc
index 0c6e16f5..3e1e4192 100644
--- a/src/Authoring/Studio/images.qrc
+++ b/src/Authoring/Studio/images.qrc
@@ -309,6 +309,12 @@
<file>images/Keyframe-Property-Selected@2x.png</file>
<file>images/Keyframe-Property-Normal@2x.png</file>
<file>images/Keyframe-Property-Disabled@2x.png</file>
+ <file>images/filter.png</file>
+ <file>images/filter@2x.png</file>
+ <file>images/filter-disabled.png</file>
+ <file>images/filter-disabled@2x.png</file>
+ <file>images/playback-variant@2x.png</file>
+ <file>images/playplayback-variant.png</file>
</qresource>
<qresource prefix="/startup">
<file alias="open_dialog.png">images/open_dialog.png</file>
diff --git a/src/Authoring/Studio/images/filter-disabled.png b/src/Authoring/Studio/images/filter-disabled.png
new file mode 100644
index 00000000..019184cd
--- /dev/null
+++ b/src/Authoring/Studio/images/filter-disabled.png
Binary files differ
diff --git a/src/Authoring/Studio/images/filter-disabled@2x.png b/src/Authoring/Studio/images/filter-disabled@2x.png
new file mode 100644
index 00000000..00a5040a
--- /dev/null
+++ b/src/Authoring/Studio/images/filter-disabled@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/filter.png b/src/Authoring/Studio/images/filter.png
new file mode 100644
index 00000000..e1c04006
--- /dev/null
+++ b/src/Authoring/Studio/images/filter.png
Binary files differ
diff --git a/src/Authoring/Studio/images/filter@2x.png b/src/Authoring/Studio/images/filter@2x.png
new file mode 100644
index 00000000..f01cbab7
--- /dev/null
+++ b/src/Authoring/Studio/images/filter@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playback-variant@2x.png b/src/Authoring/Studio/images/playback-variant@2x.png
new file mode 100644
index 00000000..ae5a9534
--- /dev/null
+++ b/src/Authoring/Studio/images/playback-variant@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playback_tools_low-02.png b/src/Authoring/Studio/images/playback_tools_low-02.png
index 471b2573..c4effffc 100644
--- a/src/Authoring/Studio/images/playback_tools_low-02.png
+++ b/src/Authoring/Studio/images/playback_tools_low-02.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playback_tools_low-02@2x.png b/src/Authoring/Studio/images/playback_tools_low-02@2x.png
index 02370d25..7713f19f 100644
--- a/src/Authoring/Studio/images/playback_tools_low-02@2x.png
+++ b/src/Authoring/Studio/images/playback_tools_low-02@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playback_tools_low-03.png b/src/Authoring/Studio/images/playback_tools_low-03.png
index 5c5f9018..9c647a4e 100644
--- a/src/Authoring/Studio/images/playback_tools_low-03.png
+++ b/src/Authoring/Studio/images/playback_tools_low-03.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playback_tools_low-03@2x.png b/src/Authoring/Studio/images/playback_tools_low-03@2x.png
index e6fe8e10..d2a02f2a 100644
--- a/src/Authoring/Studio/images/playback_tools_low-03@2x.png
+++ b/src/Authoring/Studio/images/playback_tools_low-03@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/playplayback-variant.png b/src/Authoring/Studio/images/playplayback-variant.png
new file mode 100644
index 00000000..62c3e2ff
--- /dev/null
+++ b/src/Authoring/Studio/images/playplayback-variant.png
Binary files differ
diff --git a/src/Authoring/Studio/images/remote-disabled.png b/src/Authoring/Studio/images/remote-disabled.png
index a5d7553c..0da8dac9 100644
--- a/src/Authoring/Studio/images/remote-disabled.png
+++ b/src/Authoring/Studio/images/remote-disabled.png
Binary files differ
diff --git a/src/Authoring/Studio/images/remote-disabled@2x.png b/src/Authoring/Studio/images/remote-disabled@2x.png
index b7d95c41..dba26e55 100644
--- a/src/Authoring/Studio/images/remote-disabled@2x.png
+++ b/src/Authoring/Studio/images/remote-disabled@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/images/remote.png b/src/Authoring/Studio/images/remote.png
index 83b44b84..70e10906 100644
--- a/src/Authoring/Studio/images/remote.png
+++ b/src/Authoring/Studio/images/remote.png
Binary files differ
diff --git a/src/Authoring/Studio/images/remote@2x.png b/src/Authoring/Studio/images/remote@2x.png
index fd06be49..21f48873 100644
--- a/src/Authoring/Studio/images/remote@2x.png
+++ b/src/Authoring/Studio/images/remote@2x.png
Binary files differ
diff --git a/src/Authoring/Studio/qml.qrc b/src/Authoring/Studio/qml.qrc
index ac1348f0..09d5451f 100644
--- a/src/Authoring/Studio/qml.qrc
+++ b/src/Authoring/Studio/qml.qrc
@@ -42,5 +42,6 @@
<file>Palettes/Action/HandlerBaseMultilineText.qml</file>
<file>Palettes/Action/HandlerGenericFloat.qml</file>
<file>Palettes/Inspector/MaterialDropDown.qml</file>
+ <file>Application/FilterVariantsDlg.qml</file>
</qresource>
</RCC>
diff --git a/src/Authoring/Studio/style.qss b/src/Authoring/Studio/style.qss
index e26785c0..3fd39920 100644
--- a/src/Authoring/Studio/style.qss
+++ b/src/Authoring/Studio/style.qss
@@ -150,6 +150,19 @@ QToolButton:checked, QToolButton:hover {
background-color: #262829;
}
+QToolButton#actionFilterVariants:checked {
+ min-width: 22px;
+ max-width: 22px;
+ min-height: 22px;
+ max-height: 22px;
+ background-color: #2e2f30;
+ border-color: #727476;
+ border-width: 1px;
+ border-top-style: solid;
+ border-right-style: solid;
+ border-left-style: solid;
+}
+
QToolButton:pressed:!checked {
min-width: 22px;
max-width: 22px;