diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
index ac1871e..948b53b 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj
@@ -104,6 +104,7 @@
+
@@ -200,6 +201,7 @@
+
diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
index f60bea2..c738e52 100644
--- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
+++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters
@@ -240,6 +240,9 @@
Source Files
+
+ Source Files
+
@@ -290,6 +293,9 @@
Header Files
+
+ Header Files
+
diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h
index aca00ea..a8edd67 100644
--- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h
+++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h
@@ -6,7 +6,7 @@ class ColorPicker : public QPushButton
private:
QColor color;
public:
- ColorPicker(const QColor& color, QWidget* parent = nullptr);
+ ColorPicker(const QColor& color = QColor::fromRgb(0, 0, 0), QWidget* parent = nullptr);
QColor getColor() const;
public slots:
void onClicked();
diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.cpp
new file mode 100644
index 0000000..bf78dbc
--- /dev/null
+++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.cpp
@@ -0,0 +1,48 @@
+#include "FillStyleWidget.h"
+#include "ColorPicker.h"
+#include
+#include
+#include
+
+FillStyleWidget::FillStyleWidget(std::shared_ptr fill, QWidget* parent)
+: QWidget(parent), fill(fill)
+{
+ auto* layout = new QGridLayout(this);
+ this->setLayout(layout);
+
+ // 颜色
+ auto* material = &plainFill(fill)->material;
+ auto* colorLabel = new QLabel(QStringLiteral("颜色"), this);
+ layout->addWidget(colorLabel, 0, 0);
+ auto* colorPicker = new ColorPicker(material->color);
+ connect(colorPicker, &ColorPicker::colorChanged,
+ [material](QColor color)
+ {
+ material->color = color;
+ });
+ layout->addWidget(colorPicker, 0, 1);
+
+ // 金属度
+ auto* metallicLabel = new QLabel(QStringLiteral("金属度"), this);
+ layout->addWidget(metallicLabel, 1, 0);
+ auto* metallicInput = new QtMaterialTextField(this);
+ metallicInput->setText(QString::number(material->metallicF(), 'g', 3));
+ connect(metallicInput, &QtMaterialTextField::textChanged,
+ [material](const QString& text)
+ {
+ material->setMetallicF(text.toFloat());
+ });
+ layout->addWidget(metallicInput, 1, 1);
+
+ // 粗糙度
+ auto* roughnessLabel = new QLabel(QStringLiteral("粗糙度"), this);
+ layout->addWidget(roughnessLabel, 2, 0);
+ auto* roughnessInput = new QtMaterialTextField(this);
+ roughnessInput->setText(QString::number(material->roughnessF(), 'g', 3));
+ connect(roughnessInput, &QtMaterialTextField::textChanged,
+ [material](const QString& text)
+ {
+ material->setRoughnessF(text.toFloat());
+ });
+ layout->addWidget(roughnessInput, 2, 1);
+}
diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.h
new file mode 100644
index 0000000..bff2724
--- /dev/null
+++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/FillStyleWidget.h
@@ -0,0 +1,12 @@
+#pragma once
+#include "../Renderer/Painting/MaterialStyleFill.h"
+#include "LayerStyle.h"
+#include
+class FillStyleWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FillStyleWidget(std::shared_ptr fill, QWidget* parent = nullptr);
+ std::shared_ptr fill;
+};
+
diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp
index 670e185..e2c9ce7 100644
--- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp
+++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp
@@ -11,7 +11,7 @@ constexpr int COLUMN_ROUGHNESS = 3;
constexpr int COLUMN_OPERATIONS = 4;
StrokeStyleWidget::StrokeStyleWidget(
- std::shared_ptr stroke,
+ std::shared_ptr stroke,
QWidget* parent
) : QWidget(parent), stroke(stroke)
{
diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp
index 5115658..7240d46 100644
--- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp
+++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp
@@ -1,12 +1,11 @@
#include "LayerStyle.h"
#include "./EditorWidgetComponent/StrokeStyleWidget.h"
+#include "./EditorWidgetComponent/FillStyleWidget.h"
#include "./util/EncodeUtil.hpp"
#include
#include
-#include
#include
#include
-#include
#include
#include
#define _USE_JOIN_VIEW_INPUT_RANGE
@@ -20,21 +19,19 @@ std::vector StrokeElementLayerStyle::toBaseStyles() const
{
if (!radialStroke(strokePair.first)->materialMap.empty())
{
- baseStyles.push_back(Renderer::BaseStyle(std::make_shared(),
- strokePair.first));
+ baseStyles.push_back({ std::make_shared(), strokePair.first });
}
if (!radialStroke(strokePair.second)->materialMap.empty())
{
- baseStyles.push_back(Renderer::BaseStyle(std::make_shared(),
- strokePair.second));
+ baseStyles.push_back({ std::make_shared(), strokePair.second });
}
}
else if (!radialStroke(strokePair.first)->materialMap.empty())
{
const auto material = std::shared_ptr(std::move(strokePair.first->clone()));
- std::dynamic_pointer_cast(material)->strokeType = Renderer::StrokeType::kBothSides;
+ std::static_pointer_cast(material)->strokeType = Renderer::StrokeType::kBothSides;
- baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), material));
+ baseStyles.push_back({ std::make_shared(), material });
}
return baseStyles;
}
@@ -197,18 +194,23 @@ bool LayerStyleContainer::dropStyle(const QString& styleName)
return true;
}
-float LayerStyleContainer::boundingBoxAffectValue() {
+float LayerStyleContainer::boundingBoxAffectValue() const {
float maxLineWidth = 0;
- auto strokeStyle = styles[StrokeElementLayerStyle::displayName()];
- if (strokeStyle != nullptr) {
- auto strokeElementLayerStyle = dynamic_cast(strokeStyle.get());
- if (strokeElementLayerStyle != nullptr) {
- auto leftStyleStroke = strokeElementLayerStyle->strokePair.first;
- auto rightStyleStroke = strokeElementLayerStyle->strokePair.second;
- if (leftStyleStroke != nullptr) {
+ const auto strokeStyle = styles.at(StrokeElementLayerStyle::displayName());
+ if (strokeStyle != nullptr)
+ {
+ if (const auto strokeElementLayerStyle =
+ std::dynamic_pointer_cast(strokeStyle);
+ strokeElementLayerStyle != nullptr)
+ {
+ const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first;
+ const auto& rightStyleStroke = strokeElementLayerStyle->strokePair.second;
+ if (leftStyleStroke != nullptr)
+ {
maxLineWidth = std::max(maxLineWidth, leftStyleStroke->halfWidth);
}
- if (rightStyleStroke != nullptr) {
+ if (rightStyleStroke != nullptr)
+ {
maxLineWidth = std::max(maxLineWidth, rightStyleStroke->halfWidth);
}
}
@@ -216,11 +218,25 @@ float LayerStyleContainer::boundingBoxAffectValue() {
return maxLineWidth;
}
-inline size_t LayerStyleContainer::getHash() const
+size_t LayerStyleContainer::getHash() const
{
return hash;
}
+std::unique_ptr StrokeElementLayerStyle::fromJson(const QJsonObject& json)
+{
+ auto ptr = std::make_unique(
+ std::static_pointer_cast(
+ std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString()))))
+ ),
+ std::static_pointer_cast(
+ std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString()))))
+ )
+ );
+ ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
+ return ptr;
+}
+
StrokeElementLayerStyle::StrokeElementLayerStyle()
{
const auto materialMap = std::map();
@@ -238,7 +254,7 @@ StrokeElementLayerStyle::StrokeElementLayerStyle()
}
-StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right)
+StrokeElementLayerStyle::StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right)
{
this->strokePair.first = left;
this->strokePair.second = right ? right : std::static_pointer_cast(
@@ -259,8 +275,7 @@ StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle&
QJsonObject StrokeElementLayerStyle::toJson() const
{
- QJsonObject json;
- json["type"] = typeName();
+ auto json = LayerStyle::toJson();
json["enableEachSideIndependent"] = enableEachSideIndependent;
json["left"] = EncodeUtil::toBase64(strokePair.first->encoded());
json["right"] = EncodeUtil::toBase64(strokePair.second->encoded());
@@ -272,18 +287,24 @@ std::unique_ptr StrokeElementLayerStyle::clone() const
return std::make_unique(StrokeElementLayerStyle(*this));
}
+std::unique_ptr FillElementLayerStyle::fromJson(const QJsonObject& json)
+{
+ auto ptr = std::make_unique(
+ std::static_pointer_cast(
+ std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["material"].toString()))))
+ )
+ );
+ return ptr;
+}
+
std::vector FillElementLayerStyle::toBaseStyles() const
{
- // TODO: implement
- return std::vector();
+ return { {std::make_shared(), fillMaterialStyle} };
}
QWidget* FillElementLayerStyle::getInputWidget()
{
- // TODO
- auto* name = new QLineEdit;
- name->setText(QStringLiteral("填充"));
- return name;
+ return new FillStyleWidget(fillMaterialStyle);
}
QWidget* FillElementLayerStyle::getListDisplayWidget() const
@@ -297,18 +318,29 @@ QWidget* FillElementLayerStyle::getListDisplayWidget() const
return w;
}
+FillElementLayerStyle::FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle)
+ : fillMaterialStyle(fillMaterialStyle)
+{
+ if (!fillMaterialStyle)
+ {
+ this->fillMaterialStyle = std::make_shared(
+ std::make_shared(Renderer::Material(QColor::fromRgb(0, 0, 0)))
+ );
+ }
+}
+
FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other)
{
- materialStyles = std::vector>(other.materialStyles.size());
- for (size_t i = 0; i < other.materialStyles.size(); i++)
- {
- materialStyles[i] = std::make_shared(*other.materialStyles[i]);
- }
+ this->fillMaterialStyle = std::static_pointer_cast(
+ std::shared_ptr(std::move(other.fillMaterialStyle->clone()))
+ );
}
QJsonObject FillElementLayerStyle::toJson() const
{
- return QJsonObject();
+ auto json = LayerStyle::toJson();
+ json["material"] = EncodeUtil::toBase64(fillMaterialStyle->encoded());
+ return json;
}
std::unique_ptr FillElementLayerStyle::clone() const
@@ -321,23 +353,18 @@ std::unique_ptr LayerStyle::fromJson(const QJsonObject& json)
QString type = json["type"].toString();
if (type == StrokeElementLayerStyle::typeName())
{
- auto ptr = std::make_unique(
- std::static_pointer_cast(
- std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString()))))
- ),
- std::static_pointer_cast(
- std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString()))))
- )
- );
- ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
- return ptr;
+ return StrokeElementLayerStyle::fromJson(json);
}
- else if (type == FillElementLayerStyle::typeName())
+ if (type == FillElementLayerStyle::typeName())
{
- return std::make_unique();
- }
- else
- {
- return nullptr;
+ return FillElementLayerStyle::fromJson(json);
}
+ return nullptr;
+}
+
+QJsonObject LayerStyle::toJson() const
+{
+ QJsonObject json;
+ json["type"] = this->getTypeName();
+ return json;
}
diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h
index ed328bb..3d9b023 100644
--- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h
+++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h
@@ -12,26 +12,35 @@
using Renderer::MaterialStyle;
using Renderer::MaterialStyleStroke;
+using Renderer::MaterialStyleFill;
#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; }
+ static QString typeName() { return type_name; } \
+ QString getTypeName() const override { return type_name; }
#define radialStroke(stroke) std::static_pointer_cast(stroke->materialStroke)
+#define plainFill(fill) std::static_pointer_cast(fill->materialFill)
class LayerStyle : public Renderer::ElementStyle
{
public:
static std::unique_ptr fromJson(const QJsonObject& json);
+ virtual ~LayerStyle() = default;
virtual QString getDisplayName() const = 0;
+ virtual QString getTypeName() const = 0;
+
virtual QWidget* getInputWidget() = 0;
virtual QWidget* getListDisplayWidget() const = 0;
- virtual ~LayerStyle() = default;
- virtual QJsonObject toJson() const = 0;
+
+ virtual QJsonObject toJson() const;
virtual std::unique_ptr clone() const = 0;
};
+/**
+ * LayerStyle的容器,在每次数据变更时需要手动调用computeNewHash()方法,否则哈希值不会更新
+ */
class LayerStyleContainer : public Renderer::ElementStyle
{
using DisplayNameWithSupplier = std::map()>>;
@@ -56,7 +65,7 @@ public:
std::unique_ptr makeUnusedStyle(const QString& styleName) const;
bool useStyle(const std::shared_ptr& style);
bool dropStyle(const QString& styleName);
- float boundingBoxAffectValue();
+ float boundingBoxAffectValue() const;
size_t getHash() const;
/**
@@ -70,10 +79,11 @@ class StrokeElementLayerStyle : public LayerStyle
using PMaterialStyleStroke = std::shared_ptr;
public:
- STYLE_NAME("描边","stroke")
+ STYLE_NAME("描边", "stroke")
+ static std::unique_ptr fromJson(const QJsonObject& json);
StrokeElementLayerStyle();
- StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr);
+ StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right = nullptr);
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
~StrokeElementLayerStyle() override = default;
@@ -89,16 +99,21 @@ public:
class FillElementLayerStyle : public LayerStyle
{
+ using PMaterialStyleFill = std::shared_ptr;
+
public:
- STYLE_NAME("填充","fill")
+ STYLE_NAME("填充", "fill")
+ static std::unique_ptr fromJson(const QJsonObject& json);
+
+ FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle = nullptr);
+ FillElementLayerStyle(const FillElementLayerStyle& other);
+ ~FillElementLayerStyle() override = default;
std::vector toBaseStyles() const override;
QWidget* getInputWidget() override;
QWidget* getListDisplayWidget() const override;
- FillElementLayerStyle() = default;
- FillElementLayerStyle(const FillElementLayerStyle& other);
- ~FillElementLayerStyle() override = default;
- std::vector> materialStyles;
QJsonObject toJson() const override;
std::unique_ptr clone() const override;
+
+ PMaterialStyleFill fillMaterialStyle;
};
\ No newline at end of file
diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp
index ca1e2ca..1db2940 100644
--- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp
+++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp
@@ -102,7 +102,7 @@ void InfoDisplayWidget::generateLayerForm()
else
{
connect(addStyleButton, &QPushButton::clicked, [&, leafP] {
- auto* dialog = new LayerStyleDialog(leafP->styles);
+ auto* dialog = new LayerStyleDialog(leafP->styles, nullptr, this);
dialog->exec();
if (dialog->layerStyle)
{
@@ -113,7 +113,6 @@ void InfoDisplayWidget::generateLayerForm()
emit requireSelfRefresh();
emit requireRefreshElementWidget();
}
- dialog->deleteLater();
});
}
@@ -125,60 +124,7 @@ void InfoDisplayWidget::generateLayerForm()
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()));
- }*/
auto* styles = &leafP->styles;
for (auto styleIterator = styles->begin(); styleIterator != styles->end(); ++styleIterator)
{
@@ -200,7 +146,7 @@ void InfoDisplayWidget::generateLayerForm()
[this, styles, styleIterator]
{
auto* dialog =
- new LayerStyleDialog(*styles, styleIterator->second);
+ new LayerStyleDialog(*styles, styleIterator->second, this);
dialog->exec();
if (dialog->layerStyle)
@@ -212,7 +158,6 @@ void InfoDisplayWidget::generateLayerForm()
emit requireSelfRefresh();
emit requireRefreshElementWidget();
}
- dialog->deleteLater();
});
connect(removeButton, &QPushButton::clicked, this,