diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index 91c9f62..6b49ff0 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -197,6 +197,7 @@ + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index 71f1e04..d32b61b 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -480,6 +480,9 @@ Header Files\Editor\util + + Header Files\Editor\util + diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp index 00283ca..7e014db 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp @@ -10,7 +10,6 @@ constexpr int COLUMN_METALLIC = 2; constexpr int COLUMN_ROUGHNESS = 3; constexpr int COLUMN_OPERATIONS = 4; -// FIXME: Material的控件有显示bug StrokeStyleWidget::StrokeStyleWidget( std::shared_ptr stroke, QWidget* parent @@ -122,7 +121,7 @@ void StrokeStyleWidget::initTable(std::shared_ptrrbegin(); newWidth = lastPair->first + 0.01; } - Renderer::Material newMaterial = { QColor::fromRgb(0,0,0), 0.f, .8f }; + Renderer::Material newMaterial(QColor::fromRgb(0, 0, 0)); (*materialMap)[newWidth] = newMaterial; int newRow = this->strokeTable->rowCount() - 1; this->strokeTable->insertRow(newRow); @@ -153,18 +152,17 @@ void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& ma }); QTableWidgetItem* metallicItem = new QTableWidgetItem; - metallicItem->setData(Qt::EditRole, material.metallic); + metallicItem->setData(Qt::EditRole, material.metallicF()); strokeTable->setItem(row, COLUMN_METALLIC, metallicItem); QTableWidgetItem* roughnessItem = new QTableWidgetItem; - roughnessItem->setData(Qt::EditRole, material.roughness); + roughnessItem->setData(Qt::EditRole, material.roughnessF()); strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem); QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable); removeButton->setFixedSize(20, 20); strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton); connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() { - if (this->strokeTable->rowCount() <= 1) return; radialStroke(this->stroke)->materialMap.erase(this->strokeTable->item(row, COLUMN_WIDTH)->text().toFloat()); this->strokeTable->removeRow(row); }); @@ -204,12 +202,12 @@ void StrokeStyleWidget::onCellChanged(int row, int column) } case COLUMN_METALLIC: { - radialStroke(stroke)->materialMap[changedWidth].metallic = changedItemValue; + radialStroke(stroke)->materialMap[changedWidth].setMetallicF(changedItemValue); break; } case COLUMN_ROUGHNESS: { - radialStroke(stroke)->materialMap[changedWidth].roughness = changedItemValue; + radialStroke(stroke)->materialMap[changedWidth].setRoughnessF(changedItemValue); break; } } diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 9b65355..215ec15 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -1,6 +1,6 @@ #include "LayerStyle.h" #include "./EditorWidgetComponent/StrokeStyleWidget.h" -#include "./util/JsonUtil.hpp" +#include "./util/EncodeUtil.hpp" #include #include #include @@ -51,7 +51,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget() if (this->strokePair.first == nullptr) { auto materialMap = std::map(); - materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f }; this->strokePair.first = std::shared_ptr(new Renderer::MaterialStyleStroke( 15, Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, @@ -63,7 +62,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget() if (this->strokePair.second == nullptr) { auto materialMap = std::map(); - materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f }; this->strokePair.second = std::shared_ptr(new Renderer::MaterialStyleStroke( 15, Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, @@ -108,6 +106,14 @@ QWidget* StrokeElementLayerStyle::getListDisplayWidget() const return w; } +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())) + ); +} + StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) { strokePair.first = std::dynamic_pointer_cast( @@ -121,11 +127,12 @@ StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& QJsonObject StrokeElementLayerStyle::toJson() const { + // todo: 修改打开逻辑 QJsonObject json; - json.insert("type", "stroke"); - json.insert("enableEachSideIndependent", enableEachSideIndependent); - json.insert("left", JsonUtil::toQJsonArray(strokePair.first->encoded())); - json.insert("right", JsonUtil::toQJsonArray(strokePair.second->encoded())); + json["type"] = getTypeName(); + json["enableEachSideIndependent"] = enableEachSideIndependent; + json["left"] = EncodeUtil::toBase64(strokePair.first->encoded()); + json["right"] = EncodeUtil::toBase64(strokePair.second->encoded()); return json; } @@ -184,5 +191,26 @@ std::unique_ptr FillElementLayerStyle::clone() const std::unique_ptr LayerStyle::fromJson(const QJsonObject& json) { - return std::unique_ptr(); + QString type = json["type"].toString(); + if (type == StrokeElementLayerStyle::getTypeName()) + { + auto ptr = std::make_unique( + std::dynamic_pointer_cast( + std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString())))) + ), + std::dynamic_pointer_cast( + std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString())))) + ) + ); + ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool(); + return ptr; + } + else if (type == FillElementLayerStyle::getTypeName()) + { + return std::make_unique(); + } + else + { + return nullptr; + } } diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h index 6717299..636201d 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h @@ -13,6 +13,8 @@ using Renderer::MaterialStyle; using Renderer::MaterialStyleStroke; +#define STYLE_TYPENAME(name) static QString getTypeName() { return name; } + /** * 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法 * 在进行Style的修改时,直接调用getInputWidget()方法 @@ -36,17 +38,22 @@ public: class StrokeElementLayerStyle : public LayerStyle { + using PMaterialStyleStroke = std::shared_ptr; private: - std::pair, std::shared_ptr> strokePair; + std::pair strokePair; public: + STYLE_TYPENAME("stroke") + + StrokeElementLayerStyle() = default; + StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr); + StrokeElementLayerStyle(const StrokeElementLayerStyle& other); + ~StrokeElementLayerStyle() = default; + std::vector toBaseStyles() const override; QString getStyleName() const override; QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; - StrokeElementLayerStyle() = default; - StrokeElementLayerStyle(const StrokeElementLayerStyle& other); - ~StrokeElementLayerStyle() = default; QJsonObject toJson() const override; std::unique_ptr clone() const override; @@ -56,6 +63,7 @@ public: class FillElementLayerStyle : public LayerStyle { public: + STYLE_TYPENAME("fill") std::vector toBaseStyles() const override; QString getStyleName() const override; QWidget* getInputWidget() override; diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index d5229e9..febc24a 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -79,6 +79,11 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana qDebug() << json.value("name").toString() << " " << this; 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())); + } } void LayerWrapper::SimpleProperty::apply(PixelPath&cache) diff --git a/ArchitectureColoredPainting/src/Editor/util/EncodeUtil.hpp b/ArchitectureColoredPainting/src/Editor/util/EncodeUtil.hpp new file mode 100644 index 0000000..d9a5d01 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/util/EncodeUtil.hpp @@ -0,0 +1,25 @@ +#pragma once +#include + +namespace EncodeUtil +{ +#include + template + QString toBase64(const std::vector& vec) + { + QByteArray ba; + ba.resize(vec.size() * sizeof(S)); + memcpy_s(ba.data(), ba.size(), vec.data(), vec.size() * sizeof(S)); + return ba.toBase64(); + } + + template + std::vector fromBase64(const QString& str) + { + QByteArray ba = QByteArray::fromBase64(str.toUtf8()); + std::vector vec; + vec.resize(ba.size() / sizeof(T)); + memcpy_s(vec.data(), vec.size() * sizeof(T), ba.data(), ba.size()); + return vec; + } +}