[editor/style] 完成StrokeStyle的序列化和反序列化

[stroke] 取消创建StrokeStyle时的初值
dev-LayerStyle
ArgonarioD 2023-03-16 20:22:03 +08:00
parent 4ff5406acc
commit 81bb1b4b86
7 changed files with 87 additions and 19 deletions

View File

@ -197,6 +197,7 @@
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" />
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" />
<QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" />
<ClInclude Include="src\Editor\util\EncodeUtil.hpp" />
<ClInclude Include="src\Editor\util\JsonUtil.hpp" /> <ClInclude Include="src\Editor\util\JsonUtil.hpp" />
<ClInclude Include="src\Editor\ElementManager.h" /> <ClInclude Include="src\Editor\ElementManager.h" />
<QtMoc Include="src\Editor\ElementPoolWidget.h" /> <QtMoc Include="src\Editor\ElementPoolWidget.h" />

View File

@ -480,6 +480,9 @@
<ClInclude Include="src\Editor\util\JsonUtil.hpp"> <ClInclude Include="src\Editor\util\JsonUtil.hpp">
<Filter>Header Files\Editor\util</Filter> <Filter>Header Files\Editor\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\Editor\util\EncodeUtil.hpp">
<Filter>Header Files\Editor\util</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtRcc Include="res\MainWindow.qrc"> <QtRcc Include="res\MainWindow.qrc">

View File

@ -10,7 +10,6 @@ constexpr int COLUMN_METALLIC = 2;
constexpr int COLUMN_ROUGHNESS = 3; constexpr int COLUMN_ROUGHNESS = 3;
constexpr int COLUMN_OPERATIONS = 4; constexpr int COLUMN_OPERATIONS = 4;
// FIXME: Material的控件有显示bug
StrokeStyleWidget::StrokeStyleWidget( StrokeStyleWidget::StrokeStyleWidget(
std::shared_ptr<Renderer::MaterialStyleStroke> stroke, std::shared_ptr<Renderer::MaterialStyleStroke> stroke,
QWidget* parent QWidget* parent
@ -122,7 +121,7 @@ void StrokeStyleWidget::initTable(std::shared_ptr<Renderer::StrokeRadialGradient
auto lastPair = materialMap->rbegin(); auto lastPair = materialMap->rbegin();
newWidth = lastPair->first + 0.01; 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; (*materialMap)[newWidth] = newMaterial;
int newRow = this->strokeTable->rowCount() - 1; int newRow = this->strokeTable->rowCount() - 1;
this->strokeTable->insertRow(newRow); this->strokeTable->insertRow(newRow);
@ -153,18 +152,17 @@ void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& ma
}); });
QTableWidgetItem* metallicItem = new QTableWidgetItem; QTableWidgetItem* metallicItem = new QTableWidgetItem;
metallicItem->setData(Qt::EditRole, material.metallic); metallicItem->setData(Qt::EditRole, material.metallicF());
strokeTable->setItem(row, COLUMN_METALLIC, metallicItem); strokeTable->setItem(row, COLUMN_METALLIC, metallicItem);
QTableWidgetItem* roughnessItem = new QTableWidgetItem; QTableWidgetItem* roughnessItem = new QTableWidgetItem;
roughnessItem->setData(Qt::EditRole, material.roughness); roughnessItem->setData(Qt::EditRole, material.roughnessF());
strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem); strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem);
QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable); QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable);
removeButton->setFixedSize(20, 20); removeButton->setFixedSize(20, 20);
strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton); strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton);
connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() { 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()); radialStroke(this->stroke)->materialMap.erase(this->strokeTable->item(row, COLUMN_WIDTH)->text().toFloat());
this->strokeTable->removeRow(row); this->strokeTable->removeRow(row);
}); });
@ -204,12 +202,12 @@ void StrokeStyleWidget::onCellChanged(int row, int column)
} }
case COLUMN_METALLIC: case COLUMN_METALLIC:
{ {
radialStroke(stroke)->materialMap[changedWidth].metallic = changedItemValue; radialStroke(stroke)->materialMap[changedWidth].setMetallicF(changedItemValue);
break; break;
} }
case COLUMN_ROUGHNESS: case COLUMN_ROUGHNESS:
{ {
radialStroke(stroke)->materialMap[changedWidth].roughness = changedItemValue; radialStroke(stroke)->materialMap[changedWidth].setRoughnessF(changedItemValue);
break; break;
} }
} }

View File

@ -1,6 +1,6 @@
#include "LayerStyle.h" #include "LayerStyle.h"
#include "./EditorWidgetComponent/StrokeStyleWidget.h" #include "./EditorWidgetComponent/StrokeStyleWidget.h"
#include "./util/JsonUtil.hpp" #include "./util/EncodeUtil.hpp"
#include <qtmaterialcheckbox.h> #include <qtmaterialcheckbox.h>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QDialogButtonBox> #include <QDialogButtonBox>
@ -51,7 +51,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
if (this->strokePair.first == nullptr) if (this->strokePair.first == nullptr)
{ {
auto materialMap = std::map<float, Renderer::Material>(); auto materialMap = std::map<float, Renderer::Material>();
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
this->strokePair.first = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke( this->strokePair.first = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
15, 15,
Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat,
@ -63,7 +62,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
if (this->strokePair.second == nullptr) if (this->strokePair.second == nullptr)
{ {
auto materialMap = std::map<float, Renderer::Material>(); auto materialMap = std::map<float, Renderer::Material>();
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
this->strokePair.second = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke( this->strokePair.second = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
15, 15,
Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat,
@ -108,6 +106,14 @@ QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
return w; return w;
} }
StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right)
{
this->strokePair.first = left;
this->strokePair.second = right ? right : std::dynamic_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(left->clone()))
);
}
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
{ {
strokePair.first = std::dynamic_pointer_cast<MaterialStyleStroke>( strokePair.first = std::dynamic_pointer_cast<MaterialStyleStroke>(
@ -121,11 +127,12 @@ StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle&
QJsonObject StrokeElementLayerStyle::toJson() const QJsonObject StrokeElementLayerStyle::toJson() const
{ {
// todo: Ð޸Ĵò¿ªÂß¼­
QJsonObject json; QJsonObject json;
json.insert("type", "stroke"); json["type"] = getTypeName();
json.insert("enableEachSideIndependent", enableEachSideIndependent); json["enableEachSideIndependent"] = enableEachSideIndependent;
json.insert("left", JsonUtil::toQJsonArray<GLfloat>(strokePair.first->encoded())); json["left"] = EncodeUtil::toBase64<GLfloat>(strokePair.first->encoded());
json.insert("right", JsonUtil::toQJsonArray<GLfloat>(strokePair.second->encoded())); json["right"] = EncodeUtil::toBase64<GLfloat>(strokePair.second->encoded());
return json; return json;
} }
@ -184,5 +191,26 @@ std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json) std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
{ {
return std::unique_ptr<LayerStyle>(); QString type = json["type"].toString();
if (type == StrokeElementLayerStyle::getTypeName())
{
auto ptr = std::make_unique<StrokeElementLayerStyle>(
std::dynamic_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString()))))
),
std::dynamic_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["right"].toString()))))
)
);
ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
return ptr;
}
else if (type == FillElementLayerStyle::getTypeName())
{
return std::make_unique<FillElementLayerStyle>();
}
else
{
return nullptr;
}
} }

View File

@ -13,6 +13,8 @@
using Renderer::MaterialStyle; using Renderer::MaterialStyle;
using Renderer::MaterialStyleStroke; using Renderer::MaterialStyleStroke;
#define STYLE_TYPENAME(name) static QString getTypeName() { return name; }
/** /**
* StylegetInputWidget() * StylegetInputWidget()
* StylegetInputWidget() * StylegetInputWidget()
@ -36,17 +38,22 @@ public:
class StrokeElementLayerStyle : public LayerStyle class StrokeElementLayerStyle : public LayerStyle
{ {
using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>;
private: private:
std::pair<std::shared_ptr<MaterialStyleStroke>, std::shared_ptr<MaterialStyleStroke>> strokePair; std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
public: public:
STYLE_TYPENAME("stroke")
StrokeElementLayerStyle() = default;
StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr);
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
~StrokeElementLayerStyle() = default;
std::vector<Renderer::BaseStyle> toBaseStyles() const override; std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QString getStyleName() const override; QString getStyleName() const override;
QWidget* getInputWidget() override; QWidget* getInputWidget() override;
QWidget* getListDisplayWidget() const override; QWidget* getListDisplayWidget() const override;
StrokeElementLayerStyle() = default;
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
~StrokeElementLayerStyle() = default;
QJsonObject toJson() const override; QJsonObject toJson() const override;
std::unique_ptr<LayerStyle> clone() const override; std::unique_ptr<LayerStyle> clone() const override;
@ -56,6 +63,7 @@ public:
class FillElementLayerStyle : public LayerStyle class FillElementLayerStyle : public LayerStyle
{ {
public: public:
STYLE_TYPENAME("fill")
std::vector<Renderer::BaseStyle> toBaseStyles() const override; std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QString getStyleName() const override; QString getStyleName() const override;
QWidget* getInputWidget() override; QWidget* getInputWidget() override;

View File

@ -79,6 +79,11 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
qDebug() << json.value("name").toString() << " " << this; qDebug() << json.value("name").toString() << " " << this;
int elementIndex = json.value("element").toInt(); int elementIndex = json.value("element").toInt();
wrappedElement = elementManager->getElementById(elementIndex); 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) void LayerWrapper::SimpleProperty::apply(PixelPath&cache)

View File

@ -0,0 +1,25 @@
#pragma once
#include <QByteArray>
namespace EncodeUtil
{
#include <vector>
template<typename S>
QString toBase64(const std::vector<S>& 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<typename T>
std::vector<T> fromBase64(const QString& str)
{
QByteArray ba = QByteArray::fromBase64(str.toUtf8());
std::vector<T> vec;
vec.resize(ba.size() / sizeof(T));
memcpy_s(vec.data(), vec.size() * sizeof(T), ba.data(), ba.size());
return vec;
}
}