添加layer树形展示和右键菜单

dev-VirtualTexture
白封羽 2023-01-16 21:19:35 +08:00
parent fa086ddf8b
commit 3d770ea92f
12 changed files with 189 additions and 24 deletions

View File

@ -68,7 +68,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)QGoodWindow;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)QGoodWindow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
@ -105,6 +105,7 @@
<ClCompile Include="src\Editor\LayerManager.cpp" />
<ClCompile Include="src\Editor\LayerWrapper.cpp" />
<ClCompile Include="src\Editor\PreviewWindow.cpp" />
<ClCompile Include="src\Editor\RightBar\LayerTreeWidget.cpp" />
<ClCompile Include="src\Editor\third-party modules\qquick\qquicksvgparser.cpp" />
<ClCompile Include="src\Editor\third-party modules\util\SvgFileLoader.cpp" />
<ClCompile Include="src\IconWidget.cpp" />
@ -161,6 +162,7 @@
<None Include="Shaders\ssgi.comp" />
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\Editor\RightBar\LayerTreeWidget.h" />
<ClInclude Include="src\Editor\third-party modules\qquick\qtquickglobal.h" />
<ClInclude Include="src\Editor\third-party modules\qquick\qtquickglobal_p.h" />
<ClInclude Include="src\Editor\third-party modules\qquick\qquicksvgparser_p.h" />

View File

@ -174,6 +174,9 @@
<ClCompile Include="src\Editor\third-party modules\SvgHelper.cpp">
<Filter>Source Files\Editor\third-party modules</Filter>
</ClCompile>
<ClCompile Include="src\Editor\RightBar\LayerTreeWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -203,6 +206,9 @@
<QtMoc Include="src\Editor\PreviewWindow.h">
<Filter>Header Files\Editor</Filter>
</QtMoc>
<QtMoc Include="src\Editor\RightBar\LayerTreeWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<None Include="Shaders\shader.frag">
@ -330,9 +336,6 @@
<ClInclude Include="src\Editor\ElementManager.h">
<Filter>Header Files\Editor</Filter>
</ClInclude>
<ClInclude Include="src\Editor\LayerWrapper.h">
<Filter>Header Files\Editor</Filter>
</ClInclude>
<ClInclude Include="src\Renderer\Painting\LineTree.h">
<Filter>Header Files\Renderer\Painting</Filter>
</ClInclude>
@ -354,6 +357,9 @@
<ClInclude Include="src\Editor\third-party modules\util\SvgFileLoader.h">
<Filter>Header Files\Editor\util</Filter>
</ClInclude>
<ClInclude Include="src\Editor\LayerWrapper.h">
<Filter>Header Files\Editor</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtRcc Include="MainWindow.qrc">

View File

@ -27,18 +27,43 @@
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="1,30">
<widget class="QWidget" name="MainWindow" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,30">
<item>
<widget class="QLabel" name="title">
<widget class="QLabel" name="Title">
<property name="text">
<string>纹理编辑</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,18,5">
<item>
<widget class="QWidget" name="LeftBar" native="true"/>
</item>
<item>
<widget class="PreviewWindow" name="Preview"/>
</item>
<item>
<widget class="QWidget" name="RightBar" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="LayerTreeWidget" name="LayerTree">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
@ -49,6 +74,11 @@
<extends>QOpenGLWidget</extends>
<header>PreviewWindow.h</header>
</customwidget>
<customwidget>
<class>LayerTreeWidget</class>
<extends>QTreeWidget</extends>
<header location="global">LayerTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -4,6 +4,7 @@ EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent)
{
ui.setupUi(this);
previewWindow = ui.Preview;
treeWidget = ui.LayerTree;
qDebug() << "123";
// test
QFile settingFile;
@ -19,6 +20,10 @@ EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent)
elementManager = new ElementManager(source);
layerManager = new LayerManager(source, elementManager);
previewWindow->initialize(layerManager);
if (layerManager->getRoot() != nullptr)
{
treeWidget->addTopLevelItem(layerManager->getRoot()->qTreeItem);
}
}
EditorWidget::~EditorWidget()

View File

@ -2,11 +2,12 @@
#include "ElementManager.h"
#include "LayerManager.h"
#include "LayerTreeWidget.h"
#include "PreviewWindow.h"
#include "ui_EditorWidget.h"
#include <QPainter>
#include <QTreeWidget>
#include <QWidget>
class EditorWidget : public QWidget
{
Q_OBJECT
@ -16,6 +17,7 @@ class EditorWidget : public QWidget
PreviewWindow *previewWindow;
ElementManager *elementManager;
LayerManager *layerManager;
LayerTreeWidget *treeWidget;
public:
EditorWidget(QWidget *parent = nullptr);

View File

@ -7,6 +7,10 @@ LayerManager::LayerManager(QJsonObject source, ElementManager *elementManager)
else
root = new LeafLayerWrapper(rootJson, elementManager, nullptr);
}
LayerWrapper *LayerManager::getRoot() const
{
return root;
}
void LayerManager::paint(QPainter *painter) const
{
painter->drawPath(root->getCache());
@ -57,3 +61,11 @@ bool LayerManager::changeParent(FolderLayerWrapper *newParent) const
selectedLayers[0]->setParent(newParent);
return true;
}
void LayerManager::addLayer(LayerWrapper *layer)
{
layerSet.insert(layer);
}
void LayerManager::removeLayer(LayerWrapper *layer)
{
layerSet.erase(layer);
}

View File

@ -3,9 +3,11 @@
#include "LayerWrapper.h"
#include <QJsonArray>
#include <QPainter>
#include <set>
#include <utility>
#include <vector>
using std::pair;
using std::set;
using std::vector;
class ElementManager;
class LayerWrapper;
@ -21,8 +23,13 @@ class LayerManager
LayerPtrs involvedLeafLayersCache;
bool singleSelectedCheck() const;
bool multipleSelectedCheck() const;
set<LayerWrapper *> layerSet;
public:
void addLayer(LayerWrapper *layer);
void removeLayer(LayerWrapper *layer);
LayerWrapper *getRoot() const;
LayerManager() = default;
LayerManager(QJsonObject source, ElementManager *elementManager);
void paint(QPainter *painter) const;
bool rename(QString newName) const;

View File

@ -33,9 +33,17 @@ LayerWrapper::LayerWrapper(QJsonObject json, LayerWrapper *parent)
{
this->parent = shared_ptr<LayerWrapper>(parent);
auto transformJson = json.value("transform").toObject();
property.offset = { transformJson.value("offset").toObject().value("x").toDouble(), transformJson.value("offset").toObject().value("y").toDouble() };
property.scale = { transformJson.value("scale").toObject().value("x").toDouble(), transformJson.value("scale").toObject().value("y").toDouble() };
property.name = json.value("name").toString();
property.offset = {transformJson.value("offset").toObject().value("x").toDouble(),
transformJson.value("offset").toObject().value("y").toDouble()};
property.scale = {transformJson.value("scale").toObject().value("x").toDouble(),
transformJson.value("scale").toObject().value("y").toDouble()};
property.rotation = {transformJson.value("rotation").toDouble()};
qTreeItem = new QTreeWidgetItem();
qTreeItem->setText(0, property.name);
if (parent != nullptr)
parent->qTreeItem->addChild(qTreeItem);
qTreeItem->setData(0, Qt::UserRole, QVariant::fromValue(this));
}
FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, LayerWrapper *parent)
@ -98,7 +106,8 @@ void FolderLayerWrapper::refresh()
void LeafLayerWrapper::refresh()
{
cache.clear();
if (wrappedElement != nullptr) {
if (wrappedElement != nullptr)
{
cache.addPath(wrappedElement->getPaintObject());
}
LayerWrapper::refresh();
@ -113,3 +122,12 @@ void FolderLayerWrapper::removeAllChild()
{
children.clear();
}
namespace LayerEvent
{
static void onDoubleClick(QTreeWidgetItem *qItem, LayerWrapper *layerWrapper)
{
}
} // namespace LayerEvent

View File

@ -7,7 +7,9 @@
#include <QGraphicsScene>
#include <QJSonObject>
#include <QLine>
#include <QObject>
#include <QPoint>
#include <QTreeWidget>
#include <memory>
#include <vector>
using std::shared_ptr;
@ -19,6 +21,7 @@ class ElementManager;
class LayerWrapper
{
protected:
shared_ptr<LayerWrapper> parent;
QPointF referencePoint;
@ -26,6 +29,7 @@ class LayerWrapper
QPainterPath cache;
public:
QTreeWidgetItem *qTreeItem;
struct SimpleProperty
{
QString name = "";
@ -42,6 +46,11 @@ class LayerWrapper
LayerWrapper *getParent() const; // invoke by manager, then invoke parent's applyStyles
LayerWrapper(QJsonObject json, LayerWrapper *parent);
LayerWrapper() = default;
// TODO : export Function
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
// virtual void deleteSelf() const = 0;
// virtual void deleteAll() const = 0;
};
class FolderLayerWrapper : public LayerWrapper
@ -68,3 +77,5 @@ class LeafLayerWrapper : public LayerWrapper
LeafLayerWrapper() = default;
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, LayerWrapper *parent);
};
Q_DECLARE_METATYPE(LayerWrapper *)

View File

@ -0,0 +1 @@
#pragma once

View File

@ -0,0 +1,53 @@
#include "LayerTreeWidget.h"
#include <QInputDialog>
#include <QMenu>
LayerTreeWidget::LayerTreeWidget(QWidget *parent)
{
this->selectedItem = nullptr;
this->copiedItem = nullptr;
this->setContextMenuPolicy(Qt::CustomContextMenu);
this->setHeaderLabel("Layer Content");
connect(this, &QTreeWidget::customContextMenuRequested, this, &LayerTreeWidget::popMenu);
// connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked);
}
// void LayerTreeWidget::mouseDoubleClickEvent(QMouseEvent *event)
//{
// // stay empty to avoid the default behavior
// }
//
// void LayerTreeWidget::onItemDoubleClicked(QTreeWidgetItem *item, int column)
//{
// this->selectedItem = item;
// // TODO
// }
void LayerTreeWidget::popMenu(const QPoint &pos)
{
QMenu menu;
QTreeWidgetItem *item = itemAt(pos);
this->selectedItem = item;
// TODO
menu.addAction("Add Child", this, &LayerTreeWidget::onRenameEvent);
menu.addAction("Rename", this, &LayerTreeWidget::onRenameEvent);
menu.addAction("Copy", this, &LayerTreeWidget::onRenameEvent);
if (item != nullptr && item->childCount() > 0)
menu.addAction("Delete (Self Only)", this, &LayerTreeWidget::onRenameEvent);
menu.addAction("Delete", this, &LayerTreeWidget::onRenameEvent);
menu.exec(mapToGlobal(pos));
}
void LayerTreeWidget::onRenameEvent()
{
if (this->selectedItem == nullptr)
return;
qDebug() << this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper *>()->property.name;
bool bOk = false;
QString sName =
QInputDialog::getText(this, "Rename", "New Name:", QLineEdit::Normal, this->selectedItem->text(0), &bOk);
if (bOk && !sName.isEmpty())
{
this->selectedItem->setText(0, sName);
this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper *>()->property.name = sName;
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "LayerWrapper.h"
#include <QPoint>
#include <QTreeWidget>
class LayerTreeWidget : public QTreeWidget
{
Q_OBJECT
private:
QTreeWidgetItem *selectedItem;
LayerWrapper *copiedItem;
public:
LayerTreeWidget(QWidget *parent = nullptr);
void onRenameEvent();
void popMenu(const QPoint &pos);
// void mouseDoubleClickEvent(QMouseEvent *event) override;
// void onItemDoubleClicked(QTreeWidgetItem *item, int column = 0);
};