forked from qt-creator/qt-creator
QmlDesigner: Implement effect maker view
Initial basic logic for a view and simple functionality to be extended. The view is hidden by default during development and enabled via an env var. Task-number: QDS-10401 Change-Id: I5c2e1e20aca6c53c1ed273136ee6204145f15def Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Amr Elsayed <amr.elsayed@qt.io>
This commit is contained in:
@@ -0,0 +1,106 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import HelperWidgets as HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property var effectMakerModel: EffectMakerBackend.effectMakerModel
|
||||||
|
property var rootView: EffectMakerBackend.rootView
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: col
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: topHeader
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
Row {
|
||||||
|
// TODO: Filter row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: previewHeader
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: StudioTheme.Values.toolbarHeight
|
||||||
|
color: StudioTheme.Values.themeToolbarBackground
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: previewImage
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - y
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Behavior on contentY {
|
||||||
|
id: contentYBehavior
|
||||||
|
PropertyAnimation {
|
||||||
|
id: scrollViewAnim
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Item {
|
||||||
|
width: scrollView.width
|
||||||
|
height: categories.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
Repeater {
|
||||||
|
id: categories
|
||||||
|
width: root.width
|
||||||
|
model: effectMakerModel
|
||||||
|
|
||||||
|
delegate: HelperWidgets.Section {
|
||||||
|
id: effectsSection
|
||||||
|
width: root.width
|
||||||
|
caption: model.categoryName
|
||||||
|
category: "EffectMaker"
|
||||||
|
|
||||||
|
property var effectList: model.effectNames
|
||||||
|
|
||||||
|
onExpandedChanged: {
|
||||||
|
effects.visible = expanded // TODO: update
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: effects
|
||||||
|
model: effectList
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
delegate: EffectNode {
|
||||||
|
width: parent.width
|
||||||
|
//height: StudioTheme.Values.checkIndicatorHeight * 2 // TODO: update or remove
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuickDesignerTheme
|
||||||
|
import HelperWidgets
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
import EffectMakerBackend
|
||||||
|
|
||||||
|
// TODO: this will be redone based on new specs
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
property real margin: StudioTheme.Values.marginTopBottom
|
||||||
|
|
||||||
|
id: root
|
||||||
|
height: col.height + margin * 2
|
||||||
|
|
||||||
|
signal showContextMenu()
|
||||||
|
|
||||||
|
border.width: EffectMakerBackend.effectMakerModel.selectedIndex === index ? 3 : 0
|
||||||
|
border.color: EffectMakerBackend.effectMakerModel.selectedIndex === index
|
||||||
|
? StudioTheme.Values.themeControlOutlineInteraction
|
||||||
|
: "transparent"
|
||||||
|
color: "transparent"
|
||||||
|
visible: true // TODO: from rolename -> effectVisible
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
|
onPressed: (mouse) => {
|
||||||
|
EffectMakerBackend.effectMakerModel.selectEffect(index)
|
||||||
|
EffectMakerBackend.rootView.focusSection(0) // TODO: Set the correct section based on current effect
|
||||||
|
|
||||||
|
if (mouse.button === Qt.LeftButton)
|
||||||
|
// TODO: Start dragging here
|
||||||
|
;
|
||||||
|
else if (mouse.button === Qt.RightButton)
|
||||||
|
root.showContextMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
Layout.topMargin: margin
|
||||||
|
Layout.bottomMargin: margin
|
||||||
|
Row {
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
rightPadding: margin * 3
|
||||||
|
text: '⋮⋮'
|
||||||
|
color: StudioTheme.Values.themeTextColorDisabled
|
||||||
|
font.letterSpacing: -10
|
||||||
|
font.bold: true
|
||||||
|
font.pointSize: StudioTheme.Values.mediumIconFontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
text: modelData
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -457,6 +457,7 @@ add_qtc_plugin(QmlDesigner
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/components/propertyeditor
|
${CMAKE_CURRENT_LIST_DIR}/components/propertyeditor
|
||||||
${CMAKE_CURRENT_LIST_DIR}/components/stateseditor
|
${CMAKE_CURRENT_LIST_DIR}/components/stateseditor
|
||||||
${CMAKE_CURRENT_LIST_DIR}/components/texteditor
|
${CMAKE_CURRENT_LIST_DIR}/components/texteditor
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/components/effectmaker
|
||||||
PUBLIC_INCLUDES
|
PUBLIC_INCLUDES
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore
|
${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore
|
||||||
@@ -705,6 +706,16 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
assetslibraryiconprovider.cpp assetslibraryiconprovider.h
|
assetslibraryiconprovider.cpp assetslibraryiconprovider.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
SOURCES_PREFIX components/effectmaker
|
||||||
|
SOURCES
|
||||||
|
effectmakerwidget.cpp effectmakerwidget.h
|
||||||
|
effectmakerview.cpp effectmakerview.h
|
||||||
|
effectmakermodel.cpp effectmakermodel.h
|
||||||
|
effectnode.cpp effectnode.h
|
||||||
|
effectscategory.cpp effectscategory.h
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
SOURCES_PREFIX components/navigator
|
SOURCES_PREFIX components/navigator
|
||||||
SOURCES
|
SOURCES
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include <designeractionmanagerview.h>
|
#include <designeractionmanagerview.h>
|
||||||
#include <designmodewidget.h>
|
#include <designmodewidget.h>
|
||||||
#include <edit3dview.h>
|
#include <edit3dview.h>
|
||||||
|
#include <effectmakerview.h>
|
||||||
#include <formeditorview.h>
|
#include <formeditorview.h>
|
||||||
#include <itemlibraryview.h>
|
#include <itemlibraryview.h>
|
||||||
#include <materialbrowserview.h>
|
#include <materialbrowserview.h>
|
||||||
@@ -53,6 +54,7 @@ public:
|
|||||||
, contentLibraryView{externalDependencies}
|
, contentLibraryView{externalDependencies}
|
||||||
, componentView{externalDependencies}
|
, componentView{externalDependencies}
|
||||||
, edit3DView{externalDependencies}
|
, edit3DView{externalDependencies}
|
||||||
|
, effectMakerView{externalDependencies}
|
||||||
, formEditorView{externalDependencies}
|
, formEditorView{externalDependencies}
|
||||||
, textEditorView{externalDependencies}
|
, textEditorView{externalDependencies}
|
||||||
, assetsLibraryView{externalDependencies}
|
, assetsLibraryView{externalDependencies}
|
||||||
@@ -74,6 +76,7 @@ public:
|
|||||||
ContentLibraryView contentLibraryView;
|
ContentLibraryView contentLibraryView;
|
||||||
ComponentView componentView;
|
ComponentView componentView;
|
||||||
Edit3DView edit3DView;
|
Edit3DView edit3DView;
|
||||||
|
EffectMakerView effectMakerView;
|
||||||
FormEditorView formEditorView;
|
FormEditorView formEditorView;
|
||||||
TextEditorView textEditorView;
|
TextEditorView textEditorView;
|
||||||
AssetsLibraryView assetsLibraryView;
|
AssetsLibraryView assetsLibraryView;
|
||||||
@@ -206,6 +209,9 @@ QList<AbstractView *> ViewManager::standardViews() const
|
|||||||
.toBool())
|
.toBool())
|
||||||
list.append(&d->debugView);
|
list.append(&d->debugView);
|
||||||
|
|
||||||
|
if (qEnvironmentVariableIsSet("ENABLE_QDS_EFFECTMAKER"))
|
||||||
|
list.append(&d->effectMakerView);
|
||||||
|
|
||||||
#ifdef CHECK_LICENSE
|
#ifdef CHECK_LICENSE
|
||||||
if (checkLicense() == FoundLicense::enterprise)
|
if (checkLicense() == FoundLicense::enterprise)
|
||||||
list.append(&d->contentLibraryView);
|
list.append(&d->contentLibraryView);
|
||||||
@@ -381,6 +387,9 @@ QList<WidgetInfo> ViewManager::widgetInfos() const
|
|||||||
widgetInfoList.append(d->textureEditorView.widgetInfo());
|
widgetInfoList.append(d->textureEditorView.widgetInfo());
|
||||||
widgetInfoList.append(d->statesEditorView.widgetInfo());
|
widgetInfoList.append(d->statesEditorView.widgetInfo());
|
||||||
|
|
||||||
|
if (qEnvironmentVariableIsSet("ENABLE_QDS_EFFECTMAKER"))
|
||||||
|
widgetInfoList.append(d->effectMakerView.widgetInfo());
|
||||||
|
|
||||||
#ifdef CHECK_LICENSE
|
#ifdef CHECK_LICENSE
|
||||||
if (checkLicense() == FoundLicense::enterprise)
|
if (checkLicense() == FoundLicense::enterprise)
|
||||||
widgetInfoList.append(d->contentLibraryView.widgetInfo());
|
widgetInfoList.append(d->contentLibraryView.widgetInfo());
|
||||||
|
@@ -0,0 +1,121 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "effectmakermodel.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/kit.h>
|
||||||
|
#include <projectexplorer/projecttree.h>
|
||||||
|
#include <projectexplorer/target.h>
|
||||||
|
|
||||||
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <utils/filepath.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
EffectMakerModel::EffectMakerModel(QObject *parent)
|
||||||
|
: QAbstractListModel{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> EffectMakerModel::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
roles[CategoryRole] = "categoryName";
|
||||||
|
roles[EffectsRole] = "effectNames";
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EffectMakerModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent)
|
||||||
|
|
||||||
|
return m_categories.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant EffectMakerModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
// TODO: to be updated
|
||||||
|
|
||||||
|
if (index.row() < 0 || index.row() >= m_categories.count())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const EffectsCategory *category = m_categories[index.row()];
|
||||||
|
if (role == CategoryRole)
|
||||||
|
return category->name();
|
||||||
|
|
||||||
|
if (role == EffectsRole) {
|
||||||
|
QStringList effectsNames;
|
||||||
|
const QList<EffectNode *> effects = category->effects();
|
||||||
|
for (const EffectNode *effect : effects)
|
||||||
|
effectsNames << effect->name();
|
||||||
|
|
||||||
|
return effectsNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
Utils::FilePath EffectMakerModel::getQmlEffectsPath()
|
||||||
|
{
|
||||||
|
const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget();
|
||||||
|
if (!target) {
|
||||||
|
qWarning() << __FUNCTION__ << "No project open";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit());
|
||||||
|
return baseQtVersion->qmlPath().pathAppended("QtQuickEffectMaker/defaultnodes");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerModel::loadModel()
|
||||||
|
{
|
||||||
|
const Utils::FilePath effectsPath = getQmlEffectsPath();
|
||||||
|
|
||||||
|
if (!effectsPath.exists()) {
|
||||||
|
qWarning() << __FUNCTION__ << "Effects are not found.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDirIterator itCategories(effectsPath.toString(), QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
while (itCategories.hasNext()) {
|
||||||
|
beginInsertRows(QModelIndex(), rowCount(), rowCount());
|
||||||
|
itCategories.next();
|
||||||
|
if (itCategories.fileName() == "images")
|
||||||
|
continue;
|
||||||
|
QList<EffectNode *> effects = {};
|
||||||
|
Utils::FilePath categoryPath = effectsPath.resolvePath(itCategories.fileName());
|
||||||
|
QDirIterator itEffects(categoryPath.toString(), QDir::Files | QDir::NoDotAndDotDot);
|
||||||
|
while (itEffects.hasNext()) {
|
||||||
|
itEffects.next();
|
||||||
|
effects.push_back(new EffectNode(QFileInfo(itEffects.fileName()).baseName()));
|
||||||
|
}
|
||||||
|
EffectsCategory *category = new EffectsCategory(itCategories.fileName(), effects);
|
||||||
|
m_categories.push_back(category);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerModel::resetModel()
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerModel::selectEffect(int idx, bool force)
|
||||||
|
{
|
||||||
|
Q_UNUSED(idx)
|
||||||
|
Q_UNUSED(force)
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerModel::applyToSelected(qint64 internalId, bool add)
|
||||||
|
{
|
||||||
|
Q_UNUSED(internalId)
|
||||||
|
Q_UNUSED(add)
|
||||||
|
|
||||||
|
// TODO: remove?
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
#include "effectscategory.h"
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class FilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EffectMakerModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
enum Roles {
|
||||||
|
CategoryRole = Qt::UserRole + 1,
|
||||||
|
EffectsRole
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
||||||
|
Q_PROPERTY(int selectedIndex MEMBER m_selectedIndex NOTIFY selectedIndexChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
EffectMakerModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
bool isEmpty() const { return m_isEmpty; }
|
||||||
|
|
||||||
|
void loadModel();
|
||||||
|
void resetModel();
|
||||||
|
|
||||||
|
QList<EffectsCategory *> categories() { return m_categories; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void selectEffect(int idx, bool force = false);
|
||||||
|
Q_INVOKABLE void applyToSelected(qint64 internalId, bool add = false);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void isEmptyChanged();
|
||||||
|
void selectedIndexChanged(int idx);
|
||||||
|
void hasModelSelectionChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isValidIndex(int idx) const;
|
||||||
|
static Utils::FilePath getQmlEffectsPath();
|
||||||
|
|
||||||
|
QList<EffectsCategory *> m_categories;
|
||||||
|
|
||||||
|
int m_selectedIndex = -1;
|
||||||
|
bool m_isEmpty = true;
|
||||||
|
bool m_hasModelSelection = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "effectmakerview.h"
|
||||||
|
|
||||||
|
#include "effectmakerwidget.h"
|
||||||
|
#include "effectmakermodel.h"
|
||||||
|
#include "designmodecontext.h"
|
||||||
|
#include "nodeinstanceview.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <QQmlContext>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
EffectMakerView::EffectMakerView(ExternalDependenciesInterface &externalDependencies)
|
||||||
|
: AbstractView{externalDependencies}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectMakerView::~EffectMakerView()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool EffectMakerView::hasWidget() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetInfo EffectMakerView::widgetInfo()
|
||||||
|
{
|
||||||
|
if (m_widget.isNull()) {
|
||||||
|
m_widget = new EffectMakerWidget{this};
|
||||||
|
|
||||||
|
auto context = new Internal::EffectMakerContext(m_widget.data());
|
||||||
|
Core::ICore::addContextObject(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createWidgetInfo(m_widget.data(), "Effect Maker", WidgetInfo::LeftPane, 0, tr("Effect Maker"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerView::customNotification(const AbstractView * /*view*/,
|
||||||
|
const QString & /*identifier*/,
|
||||||
|
const QList<ModelNode> & /*nodeList*/,
|
||||||
|
const QList<QVariant> & /*data*/)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerView::modelAttached(Model *model)
|
||||||
|
{
|
||||||
|
AbstractView::modelAttached(model);
|
||||||
|
|
||||||
|
// Add some dummy effects data
|
||||||
|
//m_widget->effectMakerModel()->setEffects({"Drop Shadow", "Colorize", "Fast Blue"}); // TODO
|
||||||
|
m_widget->effectMakerModel()->loadModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerView::modelAboutToBeDetached(Model *model)
|
||||||
|
{
|
||||||
|
AbstractView::modelAboutToBeDetached(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "abstractview.h"
|
||||||
|
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EffectMakerWidget;
|
||||||
|
|
||||||
|
class EffectMakerView : public AbstractView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EffectMakerView(ExternalDependenciesInterface &externalDependencies);
|
||||||
|
~EffectMakerView() override;
|
||||||
|
|
||||||
|
bool hasWidget() const override;
|
||||||
|
WidgetInfo widgetInfo() override;
|
||||||
|
|
||||||
|
// AbstractView
|
||||||
|
void modelAttached(Model *model) override;
|
||||||
|
void modelAboutToBeDetached(Model *model) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
|
QPointer<EffectMakerWidget> m_widget;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,115 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "effectmakerwidget.h"
|
||||||
|
|
||||||
|
#include "effectmakermodel.h"
|
||||||
|
#include "effectmakerview.h"
|
||||||
|
#include "qmldesignerconstants.h"
|
||||||
|
#include "qmldesignerplugin.h"
|
||||||
|
#include "theme.h"
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <studioquickwidget.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/environment.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
static QString propertyEditorResourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources";
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
EffectMakerWidget::EffectMakerWidget(EffectMakerView *view)
|
||||||
|
: m_effectMakerModel{new EffectMakerModel(this)}
|
||||||
|
, m_effectMakerView(view)
|
||||||
|
, m_effectMakerWidget{new StudioQuickWidget(this)}
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Effect Maker", "Title of effect maker widget"));
|
||||||
|
setMinimumWidth(250);
|
||||||
|
|
||||||
|
m_effectMakerWidget->quickWidget()->installEventFilter(this);
|
||||||
|
|
||||||
|
// create the inner widget
|
||||||
|
m_effectMakerWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_EFFECT_MAKER);
|
||||||
|
m_effectMakerWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
Theme::setupTheme(m_effectMakerWidget->engine());
|
||||||
|
m_effectMakerWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||||
|
m_effectMakerWidget->setClearColor(Theme::getColor(Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||||
|
|
||||||
|
auto layout = new QHBoxLayout(this);
|
||||||
|
layout->setContentsMargins({});
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->addWidget(m_effectMakerWidget.data());
|
||||||
|
|
||||||
|
setStyleSheet(Theme::replaceCssColors(
|
||||||
|
QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"))));
|
||||||
|
|
||||||
|
QmlDesignerPlugin::trackWidgetFocusTime(this, Constants::EVENT_EFFECTMAKER_TIME);
|
||||||
|
|
||||||
|
auto map = m_effectMakerWidget->registerPropertyMap("EffectMakerBackend");
|
||||||
|
map->setProperties({{"effectMakerModel", QVariant::fromValue(m_effectMakerModel.data())},
|
||||||
|
{"rootView", QVariant::fromValue(this)}});
|
||||||
|
|
||||||
|
// init the first load of the QML UI elements
|
||||||
|
reloadQmlSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EffectMakerWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(obj)
|
||||||
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerWidget::contextHelp(const Core::IContext::HelpCallback &callback) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioQuickWidget *EffectMakerWidget::quickWidget() const
|
||||||
|
{
|
||||||
|
return m_effectMakerWidget.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointer<EffectMakerModel> EffectMakerWidget::effectMakerModel() const
|
||||||
|
{
|
||||||
|
return m_effectMakerModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerWidget::focusSection(int section)
|
||||||
|
{
|
||||||
|
Q_UNUSED(section)
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EffectMakerWidget::qmlSourcesPath()
|
||||||
|
{
|
||||||
|
#ifdef SHARE_QML_PATH
|
||||||
|
if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE"))
|
||||||
|
return QLatin1String(SHARE_QML_PATH) + "/effectMakerQmlSources";
|
||||||
|
#endif
|
||||||
|
return Core::ICore::resourcePath("qmldesigner/effectMakerQmlSources").toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerWidget::reloadQmlSource()
|
||||||
|
{
|
||||||
|
const QString effectMakerQmlPath = qmlSourcesPath() + "/EffectMaker.qml";
|
||||||
|
QTC_ASSERT(QFileInfo::exists(effectMakerQmlPath), return);
|
||||||
|
m_effectMakerWidget->setSource(QUrl::fromLocalFile(effectMakerQmlPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,50 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <coreplugin/icontext.h>
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
class StudioQuickWidget;
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EffectMakerView;
|
||||||
|
class EffectMakerModel;
|
||||||
|
|
||||||
|
class EffectMakerWidget : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
EffectMakerWidget(EffectMakerView *view);
|
||||||
|
~EffectMakerWidget() = default;
|
||||||
|
|
||||||
|
void contextHelp(const Core::IContext::HelpCallback &callback) const;
|
||||||
|
|
||||||
|
static QString qmlSourcesPath();
|
||||||
|
void clearSearchFilter();
|
||||||
|
|
||||||
|
void delayedUpdateModel();
|
||||||
|
void updateModel();
|
||||||
|
|
||||||
|
StudioQuickWidget *quickWidget() const;
|
||||||
|
QPointer<EffectMakerModel> effectMakerModel() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void focusSection(int section);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reloadQmlSource();
|
||||||
|
|
||||||
|
QPointer<EffectMakerModel> m_effectMakerModel;
|
||||||
|
QPointer<EffectMakerView> m_effectMakerView;
|
||||||
|
QPointer<StudioQuickWidget> m_effectMakerWidget;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "effectnode.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
EffectNode::EffectNode(const QString &name)
|
||||||
|
: m_name(name) {}
|
||||||
|
|
||||||
|
QString EffectNode::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
21
src/plugins/qmldesigner/components/effectmaker/effectnode.h
Normal file
21
src/plugins/qmldesigner/components/effectmaker/effectnode.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EffectNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EffectNode(const QString &name);
|
||||||
|
|
||||||
|
QString name() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "effectscategory.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
EffectsCategory::EffectsCategory(const QString &name, const QList<EffectNode *> &subcategories)
|
||||||
|
: m_name(name),
|
||||||
|
m_effects(subcategories) {}
|
||||||
|
|
||||||
|
QString EffectsCategory::name() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<EffectNode *> EffectsCategory::effects() const
|
||||||
|
{
|
||||||
|
return m_effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "effectnode.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class EffectsCategory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EffectsCategory(const QString &name, const QList<EffectNode *> &subcategories);
|
||||||
|
|
||||||
|
QString name() const;
|
||||||
|
QList<EffectNode *> effects() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
QList<EffectNode *> m_effects;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -5,6 +5,7 @@
|
|||||||
#include "assetslibrarywidget.h"
|
#include "assetslibrarywidget.h"
|
||||||
#include "designmodewidget.h"
|
#include "designmodewidget.h"
|
||||||
#include "edit3dwidget.h"
|
#include "edit3dwidget.h"
|
||||||
|
#include "effectmakerwidget.h"
|
||||||
#include "formeditorwidget.h"
|
#include "formeditorwidget.h"
|
||||||
#include "materialbrowserwidget.h"
|
#include "materialbrowserwidget.h"
|
||||||
#include "navigatorwidget.h"
|
#include "navigatorwidget.h"
|
||||||
@@ -98,6 +99,18 @@ void TextEditorContext::contextHelp(const HelpCallback &callback) const
|
|||||||
qobject_cast<TextEditorWidget *>(m_widget)->contextHelp(callback);
|
qobject_cast<TextEditorWidget *>(m_widget)->contextHelp(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EffectMakerContext::EffectMakerContext(QWidget *widget)
|
||||||
|
: IContext(widget)
|
||||||
|
{
|
||||||
|
setWidget(widget);
|
||||||
|
setContext(Core::Context(Constants::C_QMLEFFECTMAKER, Constants::C_QT_QUICK_TOOLS_MENU));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectMakerContext::contextHelp(const HelpCallback &callback) const
|
||||||
|
{
|
||||||
|
qobject_cast<EffectMakerWidget *>(m_widget)->contextHelp(callback);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,5 +74,14 @@ public:
|
|||||||
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EffectMakerContext : public Core::IContext
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
EffectMakerContext(QWidget *widget);
|
||||||
|
void contextHelp(const Core::IContext::HelpCallback &callback) const override;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ const char C_DUPLICATE[] = "QmlDesigner.Duplicate";
|
|||||||
const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain";
|
const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain";
|
||||||
const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor";
|
const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor";
|
||||||
const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D";
|
const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D";
|
||||||
|
const char C_QMLEFFECTMAKER[] = "QmlDesigner::EffectMaker";
|
||||||
const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator";
|
const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator";
|
||||||
const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor";
|
const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor";
|
||||||
const char C_QMLMATERIALBROWSER[] = "QmlDesigner::MaterialBrowser";
|
const char C_QMLMATERIALBROWSER[] = "QmlDesigner::MaterialBrowser";
|
||||||
@@ -122,6 +123,7 @@ const char EVENT_TEXTEDITOR_TIME[] = "textEditor";
|
|||||||
const char EVENT_TEXTUREEDITOR_TIME[] = "textureEditor";
|
const char EVENT_TEXTUREEDITOR_TIME[] = "textureEditor";
|
||||||
const char EVENT_PROPERTYEDITOR_TIME[] = "propertyEditor";
|
const char EVENT_PROPERTYEDITOR_TIME[] = "propertyEditor";
|
||||||
const char EVENT_ASSETSLIBRARY_TIME[] = "assetsLibrary";
|
const char EVENT_ASSETSLIBRARY_TIME[] = "assetsLibrary";
|
||||||
|
const char EVENT_EFFECTMAKER_TIME[] = "effectMaker";
|
||||||
const char EVENT_ITEMLIBRARY_TIME[] = "itemLibrary";
|
const char EVENT_ITEMLIBRARY_TIME[] = "itemLibrary";
|
||||||
const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView";
|
const char EVENT_TRANSLATIONVIEW_TIME[] = "translationView";
|
||||||
const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView";
|
const char EVENT_NAVIGATORVIEW_TIME[] = "navigatorView";
|
||||||
@@ -152,6 +154,7 @@ const char OBJECT_NAME_ASSET_LIBRARY[] = "QQuickWidgetAssetLibrary";
|
|||||||
const char OBJECT_NAME_CONTENT_LIBRARY[] = "QQuickWidgetContentLibrary";
|
const char OBJECT_NAME_CONTENT_LIBRARY[] = "QQuickWidgetContentLibrary";
|
||||||
const char OBJECT_NAME_BUSY_INDICATOR[] = "QQuickWidgetBusyIndicator";
|
const char OBJECT_NAME_BUSY_INDICATOR[] = "QQuickWidgetBusyIndicator";
|
||||||
const char OBJECT_NAME_COMPONENT_LIBRARY[] = "QQuickWidgetComponentLibrary";
|
const char OBJECT_NAME_COMPONENT_LIBRARY[] = "QQuickWidgetComponentLibrary";
|
||||||
|
const char OBJECT_NAME_EFFECT_MAKER[] = "QQuickWidgetEffectMaker";
|
||||||
const char OBJECT_NAME_MATERIAL_BROWSER[] = "QQuickWidgetMaterialBrowser";
|
const char OBJECT_NAME_MATERIAL_BROWSER[] = "QQuickWidgetMaterialBrowser";
|
||||||
const char OBJECT_NAME_MATERIAL_EDITOR[] = "QQuickWidgetMaterialEditor";
|
const char OBJECT_NAME_MATERIAL_EDITOR[] = "QQuickWidgetMaterialEditor";
|
||||||
const char OBJECT_NAME_PROPERTY_EDITOR[] = "QQuickWidgetPropertyEditor";
|
const char OBJECT_NAME_PROPERTY_EDITOR[] = "QQuickWidgetPropertyEditor";
|
||||||
|
Reference in New Issue
Block a user