添加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'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>$(SolutionDir)QGoodWindow;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)ArchitectureColoredPainting\src\Editor\RightBar;$(SolutionDir)ArchitectureColoredPainting\src\Editor\;$(SolutionDir)QGoodWindow;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
@ -105,6 +105,7 @@
<ClCompile Include="src\Editor\LayerManager.cpp" /> <ClCompile Include="src\Editor\LayerManager.cpp" />
<ClCompile Include="src\Editor\LayerWrapper.cpp" /> <ClCompile Include="src\Editor\LayerWrapper.cpp" />
<ClCompile Include="src\Editor\PreviewWindow.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\qquick\qquicksvgparser.cpp" />
<ClCompile Include="src\Editor\third-party modules\util\SvgFileLoader.cpp" /> <ClCompile Include="src\Editor\third-party modules\util\SvgFileLoader.cpp" />
<ClCompile Include="src\IconWidget.cpp" /> <ClCompile Include="src\IconWidget.cpp" />
@ -161,6 +162,7 @@
<None Include="Shaders\ssgi.comp" /> <None Include="Shaders\ssgi.comp" />
</ItemGroup> </ItemGroup>
<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.h" />
<ClInclude Include="src\Editor\third-party modules\qquick\qtquickglobal_p.h" /> <ClInclude Include="src\Editor\third-party modules\qquick\qtquickglobal_p.h" />
<ClInclude Include="src\Editor\third-party modules\qquick\qquicksvgparser_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"> <ClCompile Include="src\Editor\third-party modules\SvgHelper.cpp">
<Filter>Source Files\Editor\third-party modules</Filter> <Filter>Source Files\Editor\third-party modules</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Editor\RightBar\LayerTreeWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h"> <QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -203,6 +206,9 @@
<QtMoc Include="src\Editor\PreviewWindow.h"> <QtMoc Include="src\Editor\PreviewWindow.h">
<Filter>Header Files\Editor</Filter> <Filter>Header Files\Editor</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="src\Editor\RightBar\LayerTreeWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Shaders\shader.frag"> <None Include="Shaders\shader.frag">
@ -330,9 +336,6 @@
<ClInclude Include="src\Editor\ElementManager.h"> <ClInclude Include="src\Editor\ElementManager.h">
<Filter>Header Files\Editor</Filter> <Filter>Header Files\Editor</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\Editor\LayerWrapper.h">
<Filter>Header Files\Editor</Filter>
</ClInclude>
<ClInclude Include="src\Renderer\Painting\LineTree.h"> <ClInclude Include="src\Renderer\Painting\LineTree.h">
<Filter>Header Files\Renderer\Painting</Filter> <Filter>Header Files\Renderer\Painting</Filter>
</ClInclude> </ClInclude>
@ -354,6 +357,9 @@
<ClInclude Include="src\Editor\third-party modules\util\SvgFileLoader.h"> <ClInclude Include="src\Editor\third-party modules\util\SvgFileLoader.h">
<Filter>Header Files\Editor\util</Filter> <Filter>Header Files\Editor\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\Editor\LayerWrapper.h">
<Filter>Header Files\Editor</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtRcc Include="MainWindow.qrc"> <QtRcc Include="MainWindow.qrc">

View File

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

View File

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

View File

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

View File

@ -7,6 +7,10 @@ LayerManager::LayerManager(QJsonObject source, ElementManager *elementManager)
else else
root = new LeafLayerWrapper(rootJson, elementManager, nullptr); root = new LeafLayerWrapper(rootJson, elementManager, nullptr);
} }
LayerWrapper *LayerManager::getRoot() const
{
return root;
}
void LayerManager::paint(QPainter *painter) const void LayerManager::paint(QPainter *painter) const
{ {
painter->drawPath(root->getCache()); painter->drawPath(root->getCache());
@ -57,3 +61,11 @@ bool LayerManager::changeParent(FolderLayerWrapper *newParent) const
selectedLayers[0]->setParent(newParent); selectedLayers[0]->setParent(newParent);
return true; 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 "LayerWrapper.h"
#include <QJsonArray> #include <QJsonArray>
#include <QPainter> #include <QPainter>
#include <set>
#include <utility> #include <utility>
#include <vector> #include <vector>
using std::pair; using std::pair;
using std::set;
using std::vector; using std::vector;
class ElementManager; class ElementManager;
class LayerWrapper; class LayerWrapper;
@ -21,8 +23,13 @@ class LayerManager
LayerPtrs involvedLeafLayersCache; LayerPtrs involvedLeafLayersCache;
bool singleSelectedCheck() const; bool singleSelectedCheck() const;
bool multipleSelectedCheck() const; bool multipleSelectedCheck() const;
set<LayerWrapper *> layerSet;
public: public:
void addLayer(LayerWrapper *layer);
void removeLayer(LayerWrapper *layer);
LayerWrapper *getRoot() const;
LayerManager() = default;
LayerManager(QJsonObject source, ElementManager *elementManager); LayerManager(QJsonObject source, ElementManager *elementManager);
void paint(QPainter *painter) const; void paint(QPainter *painter) const;
bool rename(QString newName) const; bool rename(QString newName) const;

View File

@ -33,15 +33,23 @@ LayerWrapper::LayerWrapper(QJsonObject json, LayerWrapper *parent)
{ {
this->parent = shared_ptr<LayerWrapper>(parent); this->parent = shared_ptr<LayerWrapper>(parent);
auto transformJson = json.value("transform").toObject(); auto transformJson = json.value("transform").toObject();
property.offset = { transformJson.value("offset").toObject().value("x").toDouble(), transformJson.value("offset").toObject().value("y").toDouble() }; property.name = json.value("name").toString();
property.scale = { transformJson.value("scale").toObject().value("x").toDouble(), transformJson.value("scale").toObject().value("y").toDouble() }; property.offset = {transformJson.value("offset").toObject().value("x").toDouble(),
property.rotation = { transformJson.value("rotation").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) FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, LayerWrapper *parent)
: LayerWrapper(json, parent) : LayerWrapper(json, parent)
{ {
qDebug() << json.value("name").toString()<<" "<<this; qDebug() << json.value("name").toString() << " " << this;
QJsonArray childrenJson = json.value("children").toArray(); QJsonArray childrenJson = json.value("children").toArray();
QJsonValue referencedJson = json.value("referenced-by"); QJsonValue referencedJson = json.value("referenced-by");
if (!referencedJson.isNull()) if (!referencedJson.isNull())
@ -73,12 +81,12 @@ void LayerWrapper::SimpleProperty::apply(QPainterPath &cache) const
QTransform trans; QTransform trans;
double delX = cache.boundingRect().width(); double delX = cache.boundingRect().width();
double delY = cache.boundingRect().height(); double delY = cache.boundingRect().height();
trans.translate(-delX,-delY); trans.translate(-delX, -delY);
trans.scale(scale.x(), scale.y()); trans.scale(scale.x(), scale.y());
trans.rotate(rotation); trans.rotate(rotation);
cache = trans.map(cache); cache = trans.map(cache);
trans.reset(); trans.reset();
trans.translate(delX+offset.x(), delY+offset.y()); trans.translate(delX + offset.x(), delY + offset.y());
cache = trans.map(cache); cache = trans.map(cache);
// cache.translate(offset); // cache.translate(offset);
} }
@ -98,7 +106,8 @@ void FolderLayerWrapper::refresh()
void LeafLayerWrapper::refresh() void LeafLayerWrapper::refresh()
{ {
cache.clear(); cache.clear();
if (wrappedElement != nullptr) { if (wrappedElement != nullptr)
{
cache.addPath(wrappedElement->getPaintObject()); cache.addPath(wrappedElement->getPaintObject());
} }
LayerWrapper::refresh(); LayerWrapper::refresh();
@ -113,3 +122,12 @@ void FolderLayerWrapper::removeAllChild()
{ {
children.clear(); children.clear();
} }
namespace LayerEvent
{
static void onDoubleClick(QTreeWidgetItem *qItem, LayerWrapper *layerWrapper)
{
}
} // namespace LayerEvent

View File

@ -7,7 +7,9 @@
#include <QGraphicsScene> #include <QGraphicsScene>
#include <QJSonObject> #include <QJSonObject>
#include <QLine> #include <QLine>
#include <QObject>
#include <QPoint> #include <QPoint>
#include <QTreeWidget>
#include <memory> #include <memory>
#include <vector> #include <vector>
using std::shared_ptr; using std::shared_ptr;
@ -19,6 +21,7 @@ class ElementManager;
class LayerWrapper class LayerWrapper
{ {
protected: protected:
shared_ptr<LayerWrapper> parent; shared_ptr<LayerWrapper> parent;
QPointF referencePoint; QPointF referencePoint;
@ -26,6 +29,7 @@ class LayerWrapper
QPainterPath cache; QPainterPath cache;
public: public:
QTreeWidgetItem *qTreeItem;
struct SimpleProperty struct SimpleProperty
{ {
QString name = ""; QString name = "";
@ -42,6 +46,11 @@ class LayerWrapper
LayerWrapper *getParent() const; // invoke by manager, then invoke parent's applyStyles LayerWrapper *getParent() const; // invoke by manager, then invoke parent's applyStyles
LayerWrapper(QJsonObject json, LayerWrapper *parent); LayerWrapper(QJsonObject json, LayerWrapper *parent);
LayerWrapper() = default; 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 class FolderLayerWrapper : public LayerWrapper
@ -68,3 +77,5 @@ class LeafLayerWrapper : public LayerWrapper
LeafLayerWrapper() = default; LeafLayerWrapper() = default;
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, LayerWrapper *parent); 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);
};