From 652fa483ba7c745d598171558e30376db7b62c68 Mon Sep 17 00:00:00 2001 From: ArgonarioD Date: Thu, 9 Mar 2023 16:35:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86LayerStyle=E7=9A=84?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E6=9E=84=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchitectureColoredPainting.vcxproj | 2 + ...rchitectureColoredPainting.vcxproj.filters | 12 +- .../src/Editor/GraphicElement.cpp | 4 +- .../src/Editor/GraphicElement.h | 7 +- .../src/Editor/LayerStyle.cpp | 64 +++++++- .../src/Editor/LayerStyle.h | 51 ++++-- .../src/Editor/LayerStyleDialog.cpp | 53 ++++++ .../src/Editor/LayerStyleDialog.h | 18 +++ .../src/Editor/LayerWrapper.cpp | 2 +- .../src/Editor/LayerWrapper.h | 3 +- .../src/Editor/RightBar/InfoDisplayWidget.cpp | 152 +++++++++++++----- 11 files changed, 303 insertions(+), 65 deletions(-) create mode 100644 ArchitectureColoredPainting/src/Editor/LayerStyleDialog.cpp create mode 100644 ArchitectureColoredPainting/src/Editor/LayerStyleDialog.h diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 1b99be6..eb014e5 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -104,6 +104,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index b433451..11b36fe 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -213,6 +213,9 @@ Source Files\Editor + + Source Files + @@ -248,6 +251,9 @@ Header Files + + Header Files + @@ -381,9 +387,6 @@ Header Files\Editor - - Header Files\Editor - Header Files\Editor @@ -441,6 +444,9 @@ Header Files\Renderer + + Header Files\Editor + diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 9381eee..2bfc5aa 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -43,7 +43,7 @@ PixelPath GroupElement::getPaintObject() const } //TODO: apply styles and send back -PixelPath SimpleElement::getPaintObject(std::vector styles) const { +PixelPath SimpleElement::getPaintObject(std::vector>* styles) const { PixelPath result; Renderer::ElementStyleStrokeDemo demo(2); auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0, false); @@ -59,7 +59,7 @@ PixelPath SimpleElement::getPaintObject(std::vector styles) const { +PixelPath GroupElement::getPaintObject(std::vector>* styles) const { return getPaintObject(); } diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index a34d56f..b1a968a 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -1,6 +1,7 @@ #pragma once #include "LayerWrapper.h" +#include "LayerStyle.h" #include #include #include @@ -24,7 +25,7 @@ public: QString name = ""; // TODO: 改为BitmapPath virtual PixelPath getPaintObject() const = 0; - virtual PixelPath getPaintObject(std::vector) const = 0; + virtual PixelPath getPaintObject(std::vector>*) const = 0; }; class SimpleElement : public GraphicElement @@ -39,7 +40,7 @@ public: SimpleElement(QJsonObject jsonSource); ~SimpleElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector) const override; + PixelPath getPaintObject(std::vector>*) const override; }; class GroupElement : public GraphicElement @@ -52,7 +53,7 @@ public: GroupElement(FolderLayerWrapper* mSourceLayer); ~GroupElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector) const override; + PixelPath getPaintObject(std::vector>*) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); }; diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 34c0cf3..5938023 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -1,6 +1,68 @@ #include "LayerStyle.h" +#include +#include +#include +#include +#include -std::vector StrokeElementStyle::toBaseStyles() const +const std::vector()>>> LayerStyle::types = { + { + QStringLiteral("描边"), + []() { return std::make_shared(); } + }, + { + QStringLiteral("填充"), + []() { return std::make_shared(); } + } +}; + +//const std::vector>> LayerStyle::types = { +// { +// QStringLiteral("描边"), +// []() { return new StrokeElementLayerStyle; } +// }, +// { +// QStringLiteral("填充"), +// []() { return new FillElementLayerStyle; } +// } +//}; + +std::vector StrokeElementLayerStyle::toBaseStyles() const { return std::vector(); } + +QWidget* StrokeElementLayerStyle::getInputWidget() const +{ + QLabel* le = new QLabel; + le->setText(QStringLiteral("描边")); + return le; +} + +QWidget* StrokeElementLayerStyle::getListDisplayWidget() const +{ + QWidget* w = new QWidget; + QLabel* name = new QLabel(w); + name->setText(QStringLiteral("描边")); + QHBoxLayout* layout = new QHBoxLayout(w); + layout->setMargin(0); + layout->addWidget(name); + return w; +} + +std::vector FillElementLayerStyle::toBaseStyles() const +{ + return std::vector(); +} + +QWidget* FillElementLayerStyle::getInputWidget() const +{ + QLineEdit* name = new QLineEdit; + name->setText(QStringLiteral("填充")); + return name; +} + +QWidget* FillElementLayerStyle::getListDisplayWidget() const +{ + return nullptr; +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h index 52f208b..43b9d04 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h @@ -1,24 +1,49 @@ #pragma once +#include +#include +#include +#include +#include +#include #include "../Renderer/Painting/ElementStyle.h" #include "../Renderer/Painting/MaterialStyleStroke.h" +#include "../Renderer/Painting/MaterialStyleFill.h" +/** + * 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法 + * 在进行Style的修改时,直接调用getInputWidget()方法 + * + * 对于LayerStyle的实现类,应该同时实现ElementStyle,并将相同种类的(如描边或填充)的style整合成一个类, + * 对于相同的类,一个图层应该只拥有一个 + */ class LayerStyle { - public: - virtual void apply() = 0; +public: + const static std::vector()>>> types; + //const static std::vector>> types; + virtual QWidget* getInputWidget() const = 0; + virtual QWidget* getListDisplayWidget() const = 0; + virtual ~LayerStyle() {}; }; -struct EditorStrokeMaterialStyle -{ - float applyWidth; - Renderer::StrokeType strokeType; - Renderer::StrokeEndType endType; - std::shared_ptr materialStroke; -}; - -class StrokeElementStyle : Renderer::ElementStyle +class StrokeElementLayerStyle : public Renderer::ElementStyle, public LayerStyle { public: - virtual std::vector toBaseStyles() const override; - std::vector materialStyles; + std::vector toBaseStyles() const override; + QWidget* getInputWidget() const override; + QWidget* getListDisplayWidget() const override; + StrokeElementLayerStyle() = default; + ~StrokeElementLayerStyle() = default; + std::vector> materialStyles; +}; + +class FillElementLayerStyle : public Renderer::ElementStyle, public LayerStyle +{ +public: + std::vector toBaseStyles() const override; + QWidget* getInputWidget() const override; + QWidget* getListDisplayWidget() const override; + FillElementLayerStyle() = default; + ~FillElementLayerStyle() = default; + std::vector> materialStyles; }; \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.cpp new file mode 100644 index 0000000..53c6b49 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.cpp @@ -0,0 +1,53 @@ +#include "LayerStyleDialog.h" +#include +#include +#include +#include + +LayerStyleDialog::LayerStyleDialog(QWidget* parent, std::shared_ptr existedStyle) : QDialog(parent) +{ + QVBoxLayout* dialogLayout = new QVBoxLayout(this); + dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); + this->setLayout(dialogLayout); + + if (existedStyle) + { + this->layerStyle = existedStyle; + + QWidget* styleWidget = layerStyle->getInputWidget(); + styleWidget->setParent(this); + dialogLayout->addWidget(styleWidget); + // do something + } + else + { + this->layerStyle = LayerStyle::types[0].second(); + + QComboBox* typeSelector = new QComboBox(this); + for (auto& pair : LayerStyle::types) { + typeSelector->addItem(pair.first); + } + dialogLayout->addWidget(typeSelector); + this->styleContainer = new QGridLayout(this); + dialogLayout->addLayout(styleContainer); + + this->styleWidget = this->layerStyle->getInputWidget(); + this->styleWidget->setParent(this); + this->styleContainer->addWidget(styleWidget); + connect(typeSelector, QOverload::of(&QComboBox::currentIndexChanged), this, &LayerStyleDialog::onStyleTypeSelectorChanged); + } +} + +void LayerStyleDialog::onStyleTypeSelectorChanged(int index) +{ + if (this->styleWidget) + { + this->styleContainer->removeWidget(this->styleWidget); + this->styleWidget->setParent(nullptr); + delete styleWidget; + } + this->layerStyle = std::move(LayerStyle::types[index].second()); + this->styleWidget = this->layerStyle->getInputWidget(); + this->styleWidget->setParent(this); + this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1); +} diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.h b/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.h new file mode 100644 index 0000000..7f73672 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/LayerStyleDialog.h @@ -0,0 +1,18 @@ +#pragma once +#include "LayerStyle.h" +#include +#include + +class LayerStyleDialog : public QDialog +{ + Q_OBJECT +private: + QWidget* styleWidget; + QGridLayout* styleContainer; +public: + LayerStyleDialog(QWidget* parent = nullptr, std::shared_ptr existedStyle = nullptr); + std::shared_ptr layerStyle; +private slots: + void onStyleTypeSelectorChanged(int index); +}; + diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index a8f0a07..3f0f6a5 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -106,7 +106,7 @@ void LeafLayerWrapper::refresh() cache.clear(); if (wrappedElement != nullptr) { - cache.addPath(wrappedElement->getPaintObject(this->styles)); + cache.addPath(wrappedElement->getPaintObject(&(this->styles))); } LayerWrapper::refresh(); } diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index 8d0284f..bbce701 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -86,7 +86,8 @@ class LeafLayerWrapper : public LayerWrapper { public: GraphicElement *wrappedElement; - const vector styles; + //const vector styles; + vector> styles; public: ~LeafLayerWrapper() = default; diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp index d069285..30c46ee 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp @@ -1,9 +1,11 @@ #include "InfoDisplayWidget.h" +#include "LayerStyleDialog.h" #include #include #include #include #include +#include #include void InfoDisplayWidget::setLayer(LayerWrapper *layer) @@ -78,63 +80,131 @@ void InfoDisplayWidget::generateLayerForm() layout->addRow("scale-Y:", scaleY); layout->setRowWrapPolicy(QFormLayout::DontWrapRows); - bool styleEnabled = true; - if (styleEnabled) { + LeafLayerWrapper* leafP = dynamic_cast(this->displayLayer); + if (leafP) { QListWidget* styleList = new QListWidget(this); - QListWidgetItem* item = new QListWidgetItem("鏍峰紡鍒楄〃"); - item->setFlags(Qt::NoItemFlags); - styleList->addItem(item); - static vector styleNames = { "鏍蜂緥1", "鏍蜂緥2", "鏍蜂緥3" }; - auto createStyleItem = [this, styleList](int index) { + + QListWidgetItem* header = new QListWidgetItem; + QWidget* headerWidget = new QWidget(styleList); + QHBoxLayout* headerLayout = new QHBoxLayout; + + QLabel* headerLabel = new QLabel(headerWidget); + headerLabel->setText("鏍峰紡鍒楄〃"); + headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + + QPushButton* addStyleButton = new QPushButton("+", headerWidget); + addStyleButton->setFixedSize(QSize(20, 20)); + connect(addStyleButton, &QPushButton::clicked, [this]() { + QDialog* dialog = new LayerStyleDialog(this); + dialog->exec(); + }); + + headerLayout->addWidget(headerLabel); + headerLayout->addWidget(addStyleButton); + headerLayout->setContentsMargins(5, 0, 5, 0); + headerWidget->setLayout(headerLayout); + + header->setFlags(Qt::NoItemFlags); + styleList->addItem(header); + styleList->setItemWidget(header, headerWidget); + //static vector styleNames = { "鏍蜂緥1", "鏍蜂緥2", "鏍蜂緥3" }; + // auto createStyleItem = [this, styleList](int index) { + // QListWidgetItem* item = new QListWidgetItem; + // QWidget* w = new QWidget; + // item->setSizeHint(QSize(50, 40)); + // QHBoxLayout* layout = new QHBoxLayout; + // QPushButton* deleteButton = new QPushButton(w); + // QPushButton* detailButton = new QPushButton(w); + // QLabel* name = new QLabel(w); + // name->setText(styleNames[index]); + // detailButton->setText("..."); + // detailButton->setFixedSize(QSize(20, 20)); + // deleteButton->setText("脳"); + // deleteButton->setFixedSize(QSize(20, 20)); + // connect(detailButton, &QPushButton::clicked, [styleList, item, this, index]() { + // QDialog dlg(this); + // dlg.setWindowTitle("鏍峰紡璇︽儏"); + // dlg.resize(400, 200); + // QGridLayout *contentLayout = new QGridLayout(&dlg); + // QLineEdit* name = new QLineEdit(styleNames[index], &dlg); + // auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel); + // contentLayout->addWidget(buttonBox); + // connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); + // connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); + // bool updateStyle = dlg.exec(); + // if (updateStyle) { + // styleNames[index] = name->text(); + // qDebug() << name->text(); + // // 鍦ㄦ澶勪慨鏀规柊鏍峰紡淇℃伅鑷冲唴瀛 + // emit requireRefreshPreview(); + // emit requireSelfRefresh(); + // } + // }); + // connect(deleteButton, &QPushButton::clicked, [styleList,item,this]() { + // styleList->removeItemWidget(item); + // delete item; + // // 鍒犻櫎layer瀵瑰簲鏍峰紡 + // emit requireRefreshPreview(); + // emit requireSelfRefresh(); + // }); + // layout->addWidget(name); + // layout->addWidget(detailButton); + // layout->addWidget(deleteButton); + // w->setLayout(layout); + // styleList->addItem(item); + // styleList->setItemWidget(item, w); + // }; + // for (int i = 0; i < styleNames.size(); i++) + // createStyleItem(i); + + if (leafP->styles.empty()) + { + leafP->styles.push_back(std::shared_ptr(new StrokeElementLayerStyle())); + } + for (auto& style : leafP->styles) + { QListWidgetItem* item = new QListWidgetItem; QWidget* w = new QWidget; item->setSizeHint(QSize(50, 40)); QHBoxLayout* layout = new QHBoxLayout; - QPushButton* deleteButton = new QPushButton(w); + layout->setAlignment(Qt::AlignmentFlag::AlignRight); QPushButton* detailButton = new QPushButton(w); - QLabel* name = new QLabel(w); - name->setText(styleNames[index]); - detailButton->setText("..."); + QPushButton* deleteButton = new QPushButton(w); + detailButton->setText("..."); detailButton->setFixedSize(QSize(20, 20)); deleteButton->setText("脳"); deleteButton->setFixedSize(QSize(20, 20)); - connect(detailButton, &QPushButton::clicked, [styleList, item, this, index]() { - QDialog dlg(this); - dlg.setWindowTitle("鏍峰紡璇︽儏"); - dlg.resize(400, 200); - QGridLayout *contentLayout = new QGridLayout(&dlg); - QLineEdit* name = new QLineEdit(styleNames[index], &dlg); - auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel); - contentLayout->addWidget(buttonBox); - connect(buttonBox, &QDialogButtonBox::accepted, &dlg, &QDialog::accept); - connect(buttonBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject); - bool updateStyle = dlg.exec(); - if (updateStyle) { - styleNames[index] = name->text(); - qDebug() << name->text(); - // 鍦ㄦ澶勪慨鏀规柊鏍峰紡淇℃伅鑷冲唴瀛 - emit requireRefreshPreview(); - emit requireSelfRefresh(); + + connect(detailButton, &QPushButton::clicked, [this, &style]() { + LayerStyleDialog* dialog = new LayerStyleDialog(this, style); + /*dialog->setAttribute(Qt::WA_DeleteOnClose); + QVBoxLayout* layout = new QVBoxLayout(dialog); + + QComboBox* typeSelector = new QComboBox(dialog); + for (auto &pair : LayerStyle::types) { + typeSelector->addItem(pair.first); } + + layout->addWidget(typeSelector); + QWidget* styleWidget = style->getInputWidget(); + styleWidget->setParent(dialog); + layout->addWidget(styleWidget);*/ + dialog->exec(); }); - connect(deleteButton, &QPushButton::clicked, [styleList,item,this]() { - styleList->removeItemWidget(item); - delete item; - // 鍒犻櫎layer瀵瑰簲鏍峰紡 - emit requireRefreshPreview(); - emit requireSelfRefresh(); - }); - layout->addWidget(name); + + QWidget* styleDisplayWidget = style->getListDisplayWidget(); + styleDisplayWidget->setParent(w); + styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); + + layout->addWidget(styleDisplayWidget); layout->addWidget(detailButton); layout->addWidget(deleteButton); w->setLayout(layout); + styleList->addItem(item); styleList->setItemWidget(item, w); - }; - for (int i = 0; i < styleNames.size(); i++) - createStyleItem(i); - - + //style->addListItem(styleList); + } layout->addRow(styleList); } }