diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp index 478301a..33a3568 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp @@ -3,20 +3,18 @@ #include #include #include -#include -#include LayerStyleDialog::LayerStyleDialog( - QWidget* parent, - std::shared_ptr existedStyle, - std::vector>* excludeStyles -) : QDialog(parent) + LayerStyleContainer& styles, + std::shared_ptr existedStyle, + QWidget* parent +) : QDialog(parent), styles(&styles) { - QVBoxLayout* dialogLayout = new QVBoxLayout(this); + auto* dialogLayout = new QVBoxLayout(this); dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); this->setLayout(dialogLayout); - if (existedStyle) + if (existedStyle) { this->modifyingStyle = existedStyle->clone(); @@ -28,28 +26,14 @@ LayerStyleDialog::LayerStyleDialog( } else { - std::unordered_set excludeStyleNames; - for(auto &style : *excludeStyles) - { - excludeStyleNames.insert(style->getStyleName()); - } + QStringList unusedStyleNames = styles.unusedStyleNames(); + auto* typeSelector = new QComboBox(this); - QComboBox* typeSelector = new QComboBox(this); - - for (auto& pair : LayerStyle::types) + if (!unusedStyleNames.empty()) { - if (!excludeStyleNames.contains(pair.first)) - { - typeSelector->addItem(pair.first); - if (!this->modifyingStyle) - { - this->modifyingStyle = std::move(pair.second()); - } - } - } + typeSelector->addItems(unusedStyleNames); + this->modifyingStyle = std::move(styles.makeUnusedStyle(unusedStyleNames[0])); - if (typeSelector->count() > 0) - { dialogLayout->addWidget(typeSelector); this->styleContainer = new QGridLayout(this); dialogLayout->addLayout(styleContainer); @@ -57,11 +41,11 @@ LayerStyleDialog::LayerStyleDialog( this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget->setParent(this); this->styleContainer->addWidget(styleWidget); - connect(typeSelector, QOverload::of(&QComboBox::currentIndexChanged), + connect(typeSelector, &QComboBox::currentTextChanged, this, &LayerStyleDialog::onStyleTypeSelectorChanged); } } - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject); dialogLayout->addWidget(buttonBox); @@ -73,7 +57,7 @@ void LayerStyleDialog::accept() QDialog::accept(); } -void LayerStyleDialog::onStyleTypeSelectorChanged(int index) +void LayerStyleDialog::onStyleTypeSelectorChanged(const QString& current) { if (this->styleWidget) { @@ -81,8 +65,10 @@ void LayerStyleDialog::onStyleTypeSelectorChanged(int index) this->styleWidget->setParent(nullptr); delete styleWidget; } - this->modifyingStyle = std::move(LayerStyle::types[index].second()); + this->modifyingStyle = std::move(styles->makeUnusedStyle(current)); this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget->setParent(this); this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1); + this->styleWidget->adjustSize(); + this->adjustSize(); } diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h index 8246cca..b703e80 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h @@ -9,15 +9,17 @@ class LayerStyleDialog : public QDialog private: QWidget* styleWidget; QGridLayout* styleContainer; + LayerStyleContainer* styles; std::unique_ptr modifyingStyle; public: LayerStyleDialog( - QWidget* parent = nullptr, - std::shared_ptr existedStyle = nullptr, - std::vector>* excludeStyles = nullptr); + LayerStyleContainer& styles, + std::shared_ptr existedStyle = nullptr, + QWidget* parent = nullptr + ); std::shared_ptr layerStyle; private slots: - void onStyleTypeSelectorChanged(int index); + void onStyleTypeSelectorChanged(const QString& current); void accept() override; }; diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp index f924e9c..fabcf6a 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp @@ -110,6 +110,7 @@ void StrokeStyleWidget::initTable(std::shared_ptrsetSpan(row, 0, 1, 5); strokeTable->setCellWidget(row, 0, addButton); strokeTable->setMinimumHeight(strokeTable->rowHeight(row) * 5); + strokeTable->setMinimumWidth(strokeTable->sizeHint().width()); addButton->setFixedHeight(strokeTable->rowHeight(row)); connect(addButton, &QtMaterialRaisedButton::clicked, [this]() { handlingRowInsert = true; @@ -132,7 +133,6 @@ void StrokeStyleWidget::initTable(std::shared_ptrstrokeTable->update(); handlingRowInsert = false; }); - connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged); connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged); } diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index f515210..8896f9e 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -48,11 +48,11 @@ PixelPath GroupElement::getPaintObject() const } //TODO: apply styles and send back -PixelPath SimpleElement::getPaintObject(std::vector>* styles) const { +PixelPath SimpleElement::getPaintObject(const LayerStyleContainer& styles) const { return this->getPaintObject(); } -PixelPath GroupElement::getPaintObject(std::vector>* styles) const { +PixelPath GroupElement::getPaintObject(const LayerStyleContainer& styles) const { return getPaintObject(); } @@ -92,7 +92,7 @@ QJsonObject GroupElement::toJson() const return result; } -void SimpleElement::paint(QPainter* painter, QTransform transform, const vector>& styles) +void SimpleElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) { painter->save(); painter->setTransform(transform); @@ -102,9 +102,6 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< } else { - std::shared_ptr style; - style = styles[0]; - double angle = atan(transform.m12() / transform.m11()); double maxScale; if (fabs(cos(angle))>1e-5) @@ -112,7 +109,7 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< else maxScale = std::max(fabs(transform.m12() / sin(angle)), fabs(transform.m21() / sin(angle))); double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio(); - auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, *style, pixelRatio); + auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, styles, pixelRatio); transform.translate(mov.x(), mov.y()); painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio)); painter->drawImage(0, 0, img); @@ -120,7 +117,7 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< painter->restore(); } -void GroupElement::paint(QPainter* painter, QTransform transform, const vector>& styles) +void GroupElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) { sourceLayer->paint(painter, transform); } diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index d417e7e..12e2cfa 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -2,7 +2,6 @@ #include "LayerWrapper.h" #include "LayerStyle.h" -#include #include #include #include @@ -27,8 +26,8 @@ public: // TODO: 改为BitmapPath virtual QJsonObject toJson() const = 0; virtual PixelPath getPaintObject() const = 0; - virtual PixelPath getPaintObject(std::vector>*) const = 0; - virtual void paint(QPainter* painter, QTransform transform, const std::vector> &styles) = 0; + virtual PixelPath getPaintObject(const LayerStyleContainer& styles) const = 0; + virtual void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) = 0; virtual QPixmap getPreview(QSize size) = 0; }; @@ -47,8 +46,8 @@ public: SimpleElement(QString filePath); ~SimpleElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector>*) const override; - void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; + PixelPath getPaintObject(const LayerStyleContainer& styles) const override; + void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override; QPixmap getPreview(QSize size) override; }; @@ -63,9 +62,9 @@ public: GroupElement(FolderLayerWrapper* mSourceLayer); ~GroupElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector>*) const override; + PixelPath getPaintObject(const LayerStyleContainer& styles) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); - void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; + void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override; QPixmap getPreview(QSize size) override; }; diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 4c9b6b1..47856be 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -9,37 +9,29 @@ #include #include #include - -const std::vector()>>> LayerStyle::types = { - { - QStringLiteral("描边"), - []() { return std::make_unique(); } - }, - { - QStringLiteral("填充"), - []() { return std::make_unique(); } - } -}; +#define _USE_JOIN_VIEW_INPUT_RANGE +#include +#include std::vector StrokeElementLayerStyle::toBaseStyles() const { std::vector baseStyles; if (enableEachSideIndependent) { - if (radialStroke(strokePair.first)->materialMap.size()) + if (!radialStroke(strokePair.first)->materialMap.empty()) { baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), strokePair.first)); } - if (radialStroke(strokePair.second)->materialMap.size()) + if (!radialStroke(strokePair.second)->materialMap.empty()) { baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), strokePair.second)); } } - else if (radialStroke(strokePair.first)->materialMap.size()) + else if (!radialStroke(strokePair.first)->materialMap.empty()) { - auto material = std::shared_ptr(std::move(strokePair.first->clone())); + const auto material = std::shared_ptr(std::move(strokePair.first->clone())); std::dynamic_pointer_cast(material)->strokeType = Renderer::StrokeType::kBothSides; baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), material)); @@ -47,35 +39,8 @@ std::vector StrokeElementLayerStyle::toBaseStyles() const return baseStyles; } -QString StrokeElementLayerStyle::getStyleName() const -{ - return QStringLiteral("描边"); -} - QWidget* StrokeElementLayerStyle::getInputWidget() { - if (this->strokePair.first == nullptr) - { - auto materialMap = std::map(); - this->strokePair.first = std::shared_ptr(new Renderer::MaterialStyleStroke( - 15, - Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, - std::shared_ptr(new Renderer::StrokeRadialGradient( - materialMap, false - )) - )); - } - if (this->strokePair.second == nullptr) - { - auto materialMap = std::map(); - this->strokePair.second = std::shared_ptr(new Renderer::MaterialStyleStroke( - 15, - Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, - std::shared_ptr(new Renderer::StrokeRadialGradient( - materialMap, false - )) - )); - } QWidget* w = new QWidget; QListView* materialList = new QListView; @@ -103,39 +68,180 @@ QWidget* StrokeElementLayerStyle::getInputWidget() QWidget* StrokeElementLayerStyle::getListDisplayWidget() const { - QWidget* w = new QWidget; - QLabel* name = new QLabel(w); + auto* w = new QWidget; + auto* name = new QLabel(w); name->setText(QStringLiteral("描边")); - QHBoxLayout* layout = new QHBoxLayout(w); + auto* layout = new QHBoxLayout(w); layout->setMargin(0); layout->addWidget(name); return w; } +void LayerStyleContainer::computeNewHash() +{ + hash = 0; + for (auto& f : styles + | std::views::values + | std::views::transform(&LayerStyle::toBaseStyles) + | std::views::join + | std::views::transform(&Renderer::BaseStyle::material) + | std::views::transform(&MaterialStyle::encoded) + | std::views::join) + { + const unsigned int u = *reinterpret_cast(&f); + hash ^= u + 0x9e3779b9 + (hash << 6) + (hash >> 2); + } +} + +LayerStyleContainer LayerStyleContainer::fromJson(const QJsonArray& jsonArray) +{ + LayerStyleContainer container; + for (const auto& style : jsonArray) + { + container.useStyle(LayerStyle::fromJson(style.toObject())); + } + return container; +} + +LayerStyleContainer::LayerStyleContainer() : hash(0) +{ + unusedStyles = { { + StrokeElementLayerStyle::displayName(), + [] { return std::make_unique(); } + }, + { + FillElementLayerStyle::displayName(), + [] { return std::make_unique(); } + } }; +} + +std::vector LayerStyleContainer::toBaseStyles() const +{ + std::vector result; + for (const auto& style : styles | std::views::values) + { + auto baseStyles = style->toBaseStyles(); + result.insert(result.end(), + std::make_move_iterator(baseStyles.begin()), + std::make_move_iterator(baseStyles.end())); + } + return result; +} + +QJsonArray LayerStyleContainer::toJson() const +{ + QJsonArray json; + for (const auto& style : styles | std::views::values) + { + json.append(style->toJson()); + } + return json; +} + +QStringList LayerStyleContainer::unusedStyleNames() const +{ + QStringList result; + for(const auto& name : unusedStyles | std::views::keys) + { + result << name; + } + return result; +} + +std::unique_ptr LayerStyleContainer::makeUnusedStyle(const QString& styleName) const +{ + return unusedStyles.at(styleName)(); +} + +bool LayerStyleContainer::empty() const +{ + return styles.empty(); +} + +bool LayerStyleContainer::full() const +{ + return unusedStyles.empty(); +} + +std::map>::iterator LayerStyleContainer::begin() +{ + return styles.begin(); +} + +std::map>::iterator LayerStyleContainer::end() +{ + return styles.end(); +} + +bool LayerStyleContainer::useStyle(const std::shared_ptr& style) +{ + auto styleNode = unusedStyles.extract(style->getDisplayName()); + if (styleNode.empty()) + { + return false; + } + styles[styleNode.key()] = style; + usedStyles.insert(std::move(styleNode)); + return true; +} + +bool LayerStyleContainer::dropStyle(const QString& styleName) +{ + auto styleNode = usedStyles.extract(styleName); + if (styleNode.empty()) + { + return false; + } + styles.erase(styleName); + unusedStyles.insert(std::move(styleNode)); + return true; +} + +inline size_t LayerStyleContainer::getHash() const +{ + return hash; +} + +StrokeElementLayerStyle::StrokeElementLayerStyle() +{ + const auto materialMap = std::map(); + this->strokePair.first = std::make_shared( + 7, + Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, + std::make_shared(materialMap, false) + ); + + this->strokePair.second = std::make_shared( + 7, + Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, + std::make_shared(materialMap, false) + ); + +} + StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right) { this->strokePair.first = left; - this->strokePair.second = right ? right : std::dynamic_pointer_cast( - std::shared_ptr(std::move(left->clone())) + this->strokePair.second = right ? right : std::static_pointer_cast( + std::shared_ptr(std::move(left->clone())) ); } StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) { - strokePair.first = std::dynamic_pointer_cast( - std::shared_ptr(std::move(other.strokePair.first->clone())) + strokePair.first = std::static_pointer_cast( + std::shared_ptr(std::move(other.strokePair.first->clone())) ); - strokePair.second = std::dynamic_pointer_cast( - std::shared_ptr(std::move(other.strokePair.second->clone())) + strokePair.second = std::static_pointer_cast( + std::shared_ptr(std::move(other.strokePair.second->clone())) ); enableEachSideIndependent = other.enableEachSideIndependent; } QJsonObject StrokeElementLayerStyle::toJson() const { - // todo: 修改打开逻辑 QJsonObject json; - json["type"] = getTypeName(); + json["type"] = typeName(); json["enableEachSideIndependent"] = enableEachSideIndependent; json["left"] = EncodeUtil::toBase64(strokePair.first->encoded()); json["right"] = EncodeUtil::toBase64(strokePair.second->encoded()); @@ -149,14 +255,10 @@ std::unique_ptr StrokeElementLayerStyle::clone() const std::vector FillElementLayerStyle::toBaseStyles() const { + // TODO: implement return std::vector(); } -QString FillElementLayerStyle::getStyleName() const -{ - return QStringLiteral("填充"); -} - QWidget* FillElementLayerStyle::getInputWidget() { // TODO @@ -198,20 +300,20 @@ std::unique_ptr FillElementLayerStyle::clone() const std::unique_ptr LayerStyle::fromJson(const QJsonObject& json) { QString type = json["type"].toString(); - if (type == StrokeElementLayerStyle::getTypeName()) + if (type == StrokeElementLayerStyle::typeName()) { auto ptr = std::make_unique( - std::dynamic_pointer_cast( - std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString())))) + std::static_pointer_cast( + std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString())))) ), - std::dynamic_pointer_cast( - std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString())))) + std::static_pointer_cast( + std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString())))) ) ); ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool(); return ptr; } - else if (type == FillElementLayerStyle::getTypeName()) + else if (type == FillElementLayerStyle::typeName()) { return std::make_unique(); } diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h index 8edd10c..a310b6e 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h @@ -1,11 +1,11 @@ #pragma once -#include #include #include -#include -#include +#include +#include #include #include +#include #include "../Renderer/Painting/ElementStyle.h" #include "../Renderer/Painting/MaterialStyleStroke.h" #include "../Renderer/Painting/MaterialStyleFill.h" @@ -13,64 +13,90 @@ using Renderer::MaterialStyle; using Renderer::MaterialStyleStroke; -#define STYLE_TYPENAME(name) static QString getTypeName() { return name; } -#define radialStroke(stroke) std::dynamic_pointer_cast(stroke->materialStroke) +#define STYLE_NAME(display_name, type_name) \ + static QString displayName() { return QStringLiteral(display_name); } \ + QString getDisplayName() const override { return QStringLiteral(display_name); } \ + static QString typeName() { return type_name; } +#define radialStroke(stroke) std::static_pointer_cast(stroke->materialStroke) -/** - * 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法 - * 在进行Style的修改时,直接调用getInputWidget()方法 - * - * 对于LayerStyle的实现类,应该同时实现ElementStyle,并将相同种类的(如描边或填充)的style整合成一个类, - * 对于相同的类,一个图层应该只拥有一个 - */ class LayerStyle : public Renderer::ElementStyle { public: - const static std::vector()>>> types; static std::unique_ptr fromJson(const QJsonObject& json); - virtual QString getStyleName() const = 0; + virtual QString getDisplayName() const = 0; virtual QWidget* getInputWidget() = 0; virtual QWidget* getListDisplayWidget() const = 0; - virtual ~LayerStyle() {}; + virtual ~LayerStyle() = default; virtual QJsonObject toJson() const = 0; virtual std::unique_ptr clone() const = 0; }; +class LayerStyleContainer : public Renderer::ElementStyle +{ + using DisplayNameWithSupplier = std::map()>>; +private: + DisplayNameWithSupplier unusedStyles; + DisplayNameWithSupplier usedStyles; + std::map> styles; + size_t hash; +public: + static LayerStyleContainer fromJson(const QJsonArray& jsonArray); + + LayerStyleContainer(); + std::vector toBaseStyles() const override; + QJsonArray toJson() const; + + bool empty() const; + bool full() const; + std::map>::iterator begin(); + std::map>::iterator end(); + + QStringList unusedStyleNames() const; + std::unique_ptr makeUnusedStyle(const QString& styleName) const; + bool useStyle(const std::shared_ptr& style); + bool dropStyle(const QString& styleName); + size_t getHash() const; + + /** + * 需要在每次更改后手动调用 + */ + void computeNewHash(); +}; + class StrokeElementLayerStyle : public LayerStyle { using PMaterialStyleStroke = std::shared_ptr; public: - STYLE_TYPENAME("stroke") + STYLE_NAME("描边","stroke") - StrokeElementLayerStyle() = default; + StrokeElementLayerStyle(); StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr); StrokeElementLayerStyle(const StrokeElementLayerStyle& other); - ~StrokeElementLayerStyle() = default; + ~StrokeElementLayerStyle() override = default; std::vector toBaseStyles() const override; - QString getStyleName() const override; QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; QJsonObject toJson() const override; std::unique_ptr clone() const override; - std::pair strokePair; + std::pair strokePair; bool enableEachSideIndependent = false; }; class FillElementLayerStyle : public LayerStyle { public: - STYLE_TYPENAME("fill") + STYLE_NAME("填充","fill") + std::vector toBaseStyles() const override; - QString getStyleName() const override; QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; FillElementLayerStyle() = default; FillElementLayerStyle(const FillElementLayerStyle& other); - ~FillElementLayerStyle() = default; + ~FillElementLayerStyle() override = default; std::vector> materialStyles; QJsonObject toJson() const override; std::unique_ptr clone() const override; diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index febc24a..9281248 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -80,10 +80,7 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana int elementIndex = json.value("element").toInt(); wrappedElement = elementManager->getElementById(elementIndex); QJsonArray stylesArray = json.value("styles").toArray(); - for (const auto& style : stylesArray) - { - styles.push_back(LayerStyle::fromJson(style.toObject())); - } + styles = LayerStyleContainer::fromJson(stylesArray); } void LayerWrapper::SimpleProperty::apply(PixelPath&cache) @@ -135,7 +132,7 @@ void LeafLayerWrapper::refresh(LayerWrapper* layer) cache.clear(); if (wrappedElement != nullptr) { - cache.addPath(wrappedElement->getPaintObject(&(this->styles))); + cache.addPath(wrappedElement->getPaintObject(this->styles)); } LayerWrapper::refresh(); } @@ -245,10 +242,7 @@ QJsonObject LeafLayerWrapper::toJson() const QJsonObject json = LayerWrapper::toJson(); json.insert("element", wrappedElement->index); json.insert("is-folder", false); - QJsonArray stylesJson; - for (auto& style : styles) - stylesJson.push_back(style->toJson()); - json.insert("styles", stylesJson); + json.insert("styles", styles.toJson()); return json; } diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index 9a76c3b..dd87c4f 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -98,8 +98,7 @@ class LeafLayerWrapper : public LayerWrapper { public: GraphicElement *wrappedElement; - //const vector styles; - vector> styles; + LayerStyleContainer styles; public: ~LeafLayerWrapper() = default; diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp index d41d374..6e84bd7 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -81,39 +80,40 @@ void InfoDisplayWidget::generateLayerForm() layout->addRow("scale-X:", scaleX); layout->addRow("scale-Y:", scaleY); layout->setRowWrapPolicy(QFormLayout::DontWrapRows); - - LeafLayerWrapper* leafP = dynamic_cast(this->displayLayer); - if (leafP) { - QListWidget* styleList = new QListWidget(this); - QListWidgetItem* header = new QListWidgetItem; - QWidget* headerWidget = new QWidget(styleList); - QHBoxLayout* headerLayout = new QHBoxLayout; + if (auto* leafP = dynamic_cast(this->displayLayer); leafP) { + auto* styleList = new QListWidget(this); - QLabel* headerLabel = new QLabel(headerWidget); + auto* header = new QListWidgetItem; + auto* headerWidget = new QWidget(styleList); + auto* headerLayout = new QHBoxLayout; + + auto* headerLabel = new QLabel(headerWidget); headerLabel->setText("鏍峰紡鍒楄〃"); headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); //QtMaterialRaisedButton* addStyleButton = new QtMaterialRaisedButton("+", headerWidget); - QPushButton* addStyleButton = new QPushButton("+", headerWidget); + auto* addStyleButton = new QPushButton("+", headerWidget); addStyleButton->setFixedSize(QSize(20, 20)); - if (leafP->styles.size() >= LayerStyle::types.size()) + if (leafP->styles.full()) { addStyleButton->setDisabled(true); } else { - connect(addStyleButton, &QPushButton::clicked, [&, leafP]() { - LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, nullptr, &(leafP->styles)); - dialog->exec(); - if (dialog->layerStyle) - { - leafP->styles.push_back(dialog->layerStyle); - emit requireRefreshPreview(); - emit requireSelfRefresh(); - emit requireRefreshElementWidget(); - } - dialog->deleteLater(); + connect(addStyleButton, &QPushButton::clicked, [&, leafP] { + auto* dialog = new LayerStyleDialog(leafP->styles); + dialog->exec(); + if (dialog->layerStyle) + { + leafP->styles.useStyle(dialog->layerStyle); + leafP->styles.computeNewHash(); + + emit requireRefreshPreview(); + emit requireSelfRefresh(); + emit requireRefreshElementWidget(); + } + dialog->deleteLater(); }); } @@ -179,32 +179,35 @@ void InfoDisplayWidget::generateLayerForm() { leafP->styles.push_back(std::shared_ptr(new StrokeElementLayerStyle())); }*/ - std::vector>* styles = &(leafP->styles); - for (auto styleIterator = styles->begin(); styleIterator != styles->end(); styleIterator++) + auto* styles = &leafP->styles; + for (auto styleIterator = styles->begin(); styleIterator != styles->end(); ++styleIterator) { - QListWidgetItem* item = new QListWidgetItem; - QWidget* w = new QWidget; + auto* item = new QListWidgetItem; + auto* w = new QWidget(this); item->setSizeHint(QSize(50, 40)); - QHBoxLayout* layout = new QHBoxLayout; + auto* layout = new QHBoxLayout(w); layout->setAlignment(Qt::AlignmentFlag::AlignRight); //QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w); //QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w); - QPushButton* detailButton = new QPushButton(w); - QPushButton* removeButton = new QPushButton(w); + auto* detailButton = new QPushButton(w); + auto* removeButton = new QPushButton(w); detailButton->setText("..."); detailButton->setFixedSize(QSize(20, 20)); removeButton->setText("脳"); removeButton->setFixedSize(QSize(20, 20)); connect(detailButton, &QPushButton::clicked, this, - [this, styleIterator]() + [this, styles, styleIterator] { - LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, *styleIterator); + auto* dialog = + new LayerStyleDialog(*styles, styleIterator->second); dialog->exec(); if (dialog->layerStyle) { - (*styleIterator) = dialog->layerStyle; + styleIterator->second = dialog->layerStyle; + styles->computeNewHash(); + emit requireRefreshPreview(); emit requireSelfRefresh(); emit requireRefreshElementWidget(); @@ -213,15 +216,17 @@ void InfoDisplayWidget::generateLayerForm() }); connect(removeButton, &QPushButton::clicked, this, - [this, styleIterator, styles]() + [this, styleIterator, styles] { - styles->erase(styleIterator); + styles->dropStyle(styleIterator->first); + styles->computeNewHash(); + emit requireRefreshPreview(); emit requireSelfRefresh(); emit requireRefreshElementWidget(); }); - QWidget* styleDisplayWidget = (*styleIterator)->getListDisplayWidget(); + QWidget* styleDisplayWidget = styleIterator->second->getListDisplayWidget(); styleDisplayWidget->setParent(w); styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));