forked from qt-creator/qt-creator
EffectComposer: Move code editor tabs to Qml side
Task-number: QDS-14141 Change-Id: I8edb70f7773723e4f87cbed7ed0e766362917a7d Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
// Copyright (C) 2024 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 StudioTheme as StudioTheme
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property var rootEditor: shaderEditor
|
||||
property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle
|
||||
|
||||
color: StudioTheme.Values.themeToolbarBackground
|
||||
height: rowLayout.height
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
|
||||
width: parent.width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Fragment Shader")
|
||||
tabId: "FRAGMENT"
|
||||
}
|
||||
|
||||
TabButton {
|
||||
text: qsTr("Vertex Shader")
|
||||
tabId: "VERTEX"
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
}
|
||||
}
|
||||
|
||||
component TabButton: Label {
|
||||
id: tabButton
|
||||
|
||||
required property string tabId
|
||||
readonly property bool selected: rootEditor.selectedShader === tabId
|
||||
|
||||
Layout.preferredHeight: 40
|
||||
Layout.preferredWidth: 120
|
||||
|
||||
font.pixelSize: StudioTheme.Values.mediumFont
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
padding: 10
|
||||
|
||||
color: {
|
||||
if (!tabButton.enabled)
|
||||
return root.style.text.disabled
|
||||
|
||||
if (tabButton.selected)
|
||||
return root.style.text.selectedText
|
||||
|
||||
return root.style.text.idle
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: {
|
||||
if (!tabButton.enabled)
|
||||
return "transparent"
|
||||
|
||||
if (tabItemMouseArea.containsMouse && tabButton.selected)
|
||||
return root.style.interactionHover
|
||||
|
||||
if (tabButton.selected)
|
||||
return root.style.interaction
|
||||
|
||||
if (tabItemMouseArea.containsMouse)
|
||||
return root.style.background.hover
|
||||
|
||||
return root.style.background.idle
|
||||
}
|
||||
|
||||
border.width: 1
|
||||
border.color: {
|
||||
if (!tabButton.enabled)
|
||||
return "transparent"
|
||||
|
||||
if (tabButton.selected)
|
||||
return root.style.border.interaction
|
||||
|
||||
if (tabItemMouseArea.containsMouse)
|
||||
return root.style.border.hover
|
||||
|
||||
return root.style.border.idle
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: tabItemMouseArea
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
onClicked: rootEditor.selectedShader = tabButton.tabId
|
||||
}
|
||||
}
|
||||
}
|
@@ -28,7 +28,7 @@
|
||||
#include <QPlainTextEdit>
|
||||
#include <QSettings>
|
||||
#include <QSplitter>
|
||||
#include <QTabWidget>
|
||||
#include <QStackedWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
@@ -36,6 +36,11 @@ namespace {
|
||||
inline constexpr char EFFECTCOMPOSER_LIVE_UPDATE_KEY[] = "EffectComposer/CodeEditor/LiveUpdate";
|
||||
inline constexpr char OBJECT_NAME_EFFECTCOMPOSER_SHADER_HEADER[]
|
||||
= "QQuickWidgetEffectComposerCodeEditorHeader";
|
||||
inline constexpr char OBJECT_NAME_EFFECTCOMPOSER_SHADER_EDITOR_TABS[]
|
||||
= "QQuickWidgetEffectComposerCodeEditorTabs";
|
||||
|
||||
inline constexpr char EFFECTCOMPOSER_VERTEX_ID[] = "VERTEX";
|
||||
inline constexpr char EFFECTCOMPOSER_FRAGMENT_ID[] = "FRAGMENT";
|
||||
|
||||
QString propertyEditorResourcesPath()
|
||||
{
|
||||
@@ -71,6 +76,7 @@ EffectShadersCodeEditor::~EffectShadersCodeEditor()
|
||||
close();
|
||||
|
||||
m_headerWidget->setSource({});
|
||||
m_qmlTabWidget->setSource({});
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::showWidget()
|
||||
@@ -121,12 +127,12 @@ void EffectShadersCodeEditor::setupShader(ShaderEditorData *data)
|
||||
if (m_currentEditorData == data)
|
||||
return;
|
||||
|
||||
while (m_tabWidget->count())
|
||||
m_tabWidget->removeTab(0);
|
||||
auto oldEditorData = m_currentEditorData;
|
||||
m_currentEditorData = data;
|
||||
|
||||
if (data) {
|
||||
m_tabWidget->addTab(data->fragmentEditor.get(), tr("Fragment Shader"));
|
||||
m_tabWidget->addTab(data->vertexEditor.get(), tr("Vertex Shader"));
|
||||
m_stackedWidget->addWidget(data->fragmentEditor.get());
|
||||
m_stackedWidget->addWidget(data->vertexEditor.get());
|
||||
|
||||
selectNonEmptyShader(data);
|
||||
setUniformsModel(data->tableModel);
|
||||
@@ -134,7 +140,10 @@ void EffectShadersCodeEditor::setupShader(ShaderEditorData *data)
|
||||
setUniformsModel(nullptr);
|
||||
}
|
||||
|
||||
m_currentEditorData = data;
|
||||
if (oldEditorData) {
|
||||
m_stackedWidget->removeWidget(oldEditorData->fragmentEditor.get());
|
||||
m_stackedWidget->removeWidget(oldEditorData->vertexEditor.get());
|
||||
}
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::cleanFromData(ShaderEditorData *data)
|
||||
@@ -143,6 +152,20 @@ void EffectShadersCodeEditor::cleanFromData(ShaderEditorData *data)
|
||||
setupShader(nullptr);
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::selectShader(const QString &shaderName)
|
||||
{
|
||||
using namespace Qt::StringLiterals;
|
||||
if (!m_currentEditorData)
|
||||
return;
|
||||
EffectCodeEditorWidget *editor = nullptr;
|
||||
if (shaderName == EFFECTCOMPOSER_FRAGMENT_ID)
|
||||
editor = m_currentEditorData->fragmentEditor.get();
|
||||
else if (shaderName == EFFECTCOMPOSER_VERTEX_ID)
|
||||
editor = m_currentEditorData->vertexEditor.get();
|
||||
|
||||
m_stackedWidget->setCurrentWidget(editor);
|
||||
}
|
||||
|
||||
ShaderEditorData *EffectShadersCodeEditor::createEditorData(
|
||||
const QString &fragmentDocument,
|
||||
const QString &vertexDocument,
|
||||
@@ -229,20 +252,32 @@ void EffectShadersCodeEditor::setupUIComponents()
|
||||
{
|
||||
QVBoxLayout *verticalLayout = new QVBoxLayout(this);
|
||||
QSplitter *splitter = new QSplitter(this);
|
||||
m_tabWidget = new QTabWidget(this);
|
||||
QWidget *tabComplexWidget = new QWidget(this);
|
||||
QVBoxLayout *tabsLayout = new QVBoxLayout(tabComplexWidget);
|
||||
m_stackedWidget = new QStackedWidget(tabComplexWidget);
|
||||
|
||||
splitter->setOrientation(Qt::Vertical);
|
||||
|
||||
createHeader();
|
||||
createQmlTabs();
|
||||
|
||||
verticalLayout->setContentsMargins(0, 0, 0, 0);
|
||||
verticalLayout->addWidget(splitter);
|
||||
tabsLayout->addWidget(m_qmlTabWidget);
|
||||
tabsLayout->addWidget(m_stackedWidget);
|
||||
|
||||
splitter->addWidget(m_headerWidget.get());
|
||||
splitter->addWidget(m_tabWidget);
|
||||
splitter->addWidget(tabComplexWidget);
|
||||
|
||||
splitter->setCollapsible(0, false);
|
||||
splitter->setCollapsible(1, false);
|
||||
|
||||
connect(
|
||||
m_stackedWidget.get(),
|
||||
&QStackedWidget::currentChanged,
|
||||
this,
|
||||
&EffectShadersCodeEditor::onEditorWidgetChanged);
|
||||
|
||||
this->resize(660, 240);
|
||||
}
|
||||
|
||||
@@ -291,11 +326,30 @@ void EffectShadersCodeEditor::createHeader()
|
||||
"editableCompositionsModel", QVariant::fromValue(m_editableNodesModel.get()));
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::createQmlTabs()
|
||||
{
|
||||
m_qmlTabWidget = new StudioQuickWidget(this);
|
||||
m_qmlTabWidget->quickWidget()->setObjectName(OBJECT_NAME_EFFECTCOMPOSER_SHADER_EDITOR_TABS);
|
||||
m_qmlTabWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
QmlDesigner::Theme::setupTheme(m_qmlTabWidget->engine());
|
||||
m_qmlTabWidget->engine()->addImportPath(propertyEditorResourcesPath() + "/imports");
|
||||
m_qmlTabWidget->engine()->addImportPath(EffectUtils::nodesSourcesPath() + "/common");
|
||||
m_qmlTabWidget->setClearColor(QmlDesigner::Theme::getColor(
|
||||
QmlDesigner::Theme::Color::QmlDesigner_BackgroundColorDarkAlternate));
|
||||
m_qmlTabWidget->rootContext()->setContextProperty("shaderEditor", QVariant::fromValue(this));
|
||||
m_qmlTabWidget->setFixedHeight(43);
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::loadQml()
|
||||
{
|
||||
const QString headerQmlPath = EffectComposerWidget::qmlSourcesPath() + "/CodeEditorHeader.qml";
|
||||
QTC_ASSERT(QFileInfo::exists(headerQmlPath), return);
|
||||
m_headerWidget->setSource(QUrl::fromLocalFile(headerQmlPath));
|
||||
|
||||
const QString editorTabsQmlPath = EffectComposerWidget::qmlSourcesPath()
|
||||
+ "/CodeEditorTabs.qml";
|
||||
QTC_ASSERT(QFileInfo::exists(editorTabsQmlPath), return);
|
||||
m_qmlTabWidget->setSource(QUrl::fromLocalFile(editorTabsQmlPath));
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::setUniformsModel(EffectComposerUniformsTableModel *uniformsTable)
|
||||
@@ -316,13 +370,37 @@ void EffectShadersCodeEditor::selectNonEmptyShader(ShaderEditorData *data)
|
||||
? data->fragmentEditor.get()
|
||||
: data->vertexEditor.get();
|
||||
|
||||
m_tabWidget->setCurrentWidget(widgetToSelect);
|
||||
m_stackedWidget->setCurrentWidget(widgetToSelect);
|
||||
widgetToSelect->setFocus();
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::setSelectedShaderName(const QString &shaderName)
|
||||
{
|
||||
if (m_selectedShaderName == shaderName)
|
||||
return;
|
||||
m_selectedShaderName = shaderName;
|
||||
emit selectedShaderChanged(m_selectedShaderName);
|
||||
}
|
||||
|
||||
void EffectShadersCodeEditor::onEditorWidgetChanged()
|
||||
{
|
||||
QWidget *currentWidget = m_stackedWidget->currentWidget();
|
||||
if (!m_currentEditorData || !currentWidget) {
|
||||
setSelectedShaderName({});
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentWidget == m_currentEditorData->fragmentEditor.get())
|
||||
setSelectedShaderName(EFFECTCOMPOSER_FRAGMENT_ID);
|
||||
else if (currentWidget == m_currentEditorData->vertexEditor.get())
|
||||
setSelectedShaderName(EFFECTCOMPOSER_VERTEX_ID);
|
||||
else
|
||||
setSelectedShaderName({});
|
||||
}
|
||||
|
||||
EffectCodeEditorWidget *EffectShadersCodeEditor::currentEditor() const
|
||||
{
|
||||
QWidget *currentTab = m_tabWidget->currentWidget();
|
||||
QWidget *currentTab = m_stackedWidget->currentWidget();
|
||||
if (!m_currentEditorData || !currentTab)
|
||||
return nullptr;
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include <utils/uniqueobjectptr.h>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QSettings)
|
||||
QT_FORWARD_DECLARE_CLASS(QTabWidget)
|
||||
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
|
||||
|
||||
class StudioQuickWidget;
|
||||
|
||||
@@ -42,6 +42,12 @@ class EffectShadersCodeEditor : public QWidget
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool liveUpdate READ liveUpdate WRITE setLiveUpdate NOTIFY liveUpdateChanged)
|
||||
|
||||
Q_PROPERTY(
|
||||
QString selectedShader
|
||||
MEMBER m_selectedShaderName
|
||||
WRITE selectShader
|
||||
NOTIFY selectedShaderChanged)
|
||||
|
||||
public:
|
||||
EffectShadersCodeEditor(const QString &title = tr("Untitled Editor"), QWidget *parent = nullptr);
|
||||
~EffectShadersCodeEditor() override;
|
||||
@@ -59,6 +65,8 @@ public:
|
||||
void setupShader(ShaderEditorData *data);
|
||||
void cleanFromData(ShaderEditorData *data);
|
||||
|
||||
void selectShader(const QString &shaderName);
|
||||
|
||||
ShaderEditorData *createEditorData(
|
||||
const QString &fragmentDocument,
|
||||
const QString &vertexDocument,
|
||||
@@ -73,6 +81,7 @@ signals:
|
||||
void liveUpdateChanged(bool);
|
||||
void rebakeRequested();
|
||||
void openedChanged(bool);
|
||||
void selectedShaderChanged(const QString &);
|
||||
|
||||
protected:
|
||||
using QWidget::show;
|
||||
@@ -86,21 +95,26 @@ private:
|
||||
void writeLiveUpdateSettings();
|
||||
void readAndApplyLiveUpdateSettings();
|
||||
void createHeader();
|
||||
void createQmlTabs();
|
||||
void loadQml();
|
||||
void setUniformsModel(EffectComposerUniformsTableModel *uniforms);
|
||||
void selectNonEmptyShader(ShaderEditorData *data);
|
||||
void setSelectedShaderName(const QString &shaderName);
|
||||
void onEditorWidgetChanged();
|
||||
|
||||
EffectCodeEditorWidget *currentEditor() const;
|
||||
|
||||
QSettings *m_settings = nullptr;
|
||||
QPointer<StudioQuickWidget> m_headerWidget;
|
||||
QPointer<QTabWidget> m_tabWidget;
|
||||
QPointer<StudioQuickWidget> m_qmlTabWidget;
|
||||
QPointer<QStackedWidget> m_stackedWidget;
|
||||
QPointer<EffectComposerUniformsTableModel> m_defaultTableModel;
|
||||
QPointer<EffectComposerEditableNodesModel> m_editableNodesModel;
|
||||
ShaderEditorData *m_currentEditorData = nullptr;
|
||||
|
||||
bool m_liveUpdate = false;
|
||||
bool m_opened = false;
|
||||
QString m_selectedShaderName;
|
||||
};
|
||||
|
||||
} // namespace EffectComposer
|
||||
|
Reference in New Issue
Block a user