[editor] 为LayerStyleContainer重载了<<运算符 | #30

dev-wuyize
ArgonarioD 2023-03-23 01:44:28 +08:00
parent ba4be72918
commit 2f9b988dac
7 changed files with 122 additions and 31 deletions

View File

@ -92,9 +92,9 @@ void LayerStyleContainer::computeNewHash()
}
}
LayerStyleContainer LayerStyleContainer::fromJson(bool isClosedElement, const QJsonArray& jsonArray)
LayerStyleContainer LayerStyleContainer::fromJson(ElementType elementType, const QJsonArray& jsonArray)
{
LayerStyleContainer container(isClosedElement);
LayerStyleContainer container(elementType);
for (const auto& style : jsonArray)
{
container.useStyle(LayerStyle::fromJson(style.toObject()));
@ -102,20 +102,20 @@ LayerStyleContainer LayerStyleContainer::fromJson(bool isClosedElement, const QJ
return container;
}
LayerStyleContainer::LayerStyleContainer(bool isClosedElement) : hash(0)
LayerStyleContainer::LayerStyleContainer(ElementType elementType) : hash(0)
{
for (const auto& style : commonStyles)
{
unusedStyles.insert(style);
}
if (isClosedElement)
if (elementType & LayerStyleContainer::TYPE_CLOSED)
{
for (const auto& style : closedOnlyStyles)
{
unusedStyles.insert(style);
}
}
else
if (elementType & LayerStyleContainer::TYPE_UNCLOSED)
{
for (const auto& style : unclosedOnlyStyles)
{
@ -182,13 +182,29 @@ std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::en
return styles.end();
}
bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style)
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cbegin() const
{
auto styleNode = unusedStyles.extract(style->getDisplayName());
return styles.cbegin();
}
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cend() const
{
return styles.cend();
}
bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride)
{
const auto styleDisplayName = style->getDisplayName();
auto styleNode = unusedStyles.extract(styleDisplayName);
if (styleNode.empty())
{
if (!forceOverride || !styles.contains(styleDisplayName))
{
return false;
}
styles[styleDisplayName] = style;
return true;
}
styles[styleNode.key()] = style;
usedStyles.insert(std::move(styleNode));
return true;
@ -259,6 +275,18 @@ bool LayerStyleContainer::operator==(const LayerStyleContainer& other) const
return std::ranges::equal(styles | std::views::values, other.styles | std::views::values);
}
LayerStyleContainer LayerStyleContainer::operator<<(const LayerStyleContainer& other) const
{
LayerStyleContainer result = other;
for (const auto& style : std::ranges::subrange(this->cbegin(), this->cend())
| std::views::values)
{
result.useStyle(style);
}
result.computeNewHash();
return result;
}
std::unique_ptr<StrokeElementLayerStyle> StrokeElementLayerStyle::fromJson(const QJsonObject& json)
{
auto ptr = std::make_unique<StrokeElementLayerStyle>(

View File

@ -116,27 +116,35 @@ private:
std::map<QString, std::shared_ptr<LayerStyle>> styles;
size_t hash;
public:
static LayerStyleContainer fromJson(bool isClosedElement, const QJsonArray& jsonArray);
using ElementType = unsigned short;
constexpr static ElementType TYPE_ALL = 0xffff;
constexpr static ElementType TYPE_CLOSED = 0b01;
constexpr static ElementType TYPE_UNCLOSED = 0b10;
LayerStyleContainer(bool isClosedElement);
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QJsonArray toJson() const;
static LayerStyleContainer fromJson(ElementType elementType, const QJsonArray& jsonArray);
bool empty() const;
bool full() const;
std::map<QString, std::shared_ptr<LayerStyle>>::iterator begin();
std::map<QString, std::shared_ptr<LayerStyle>>::iterator end();
LayerStyleContainer(ElementType elementType);
[[nodiscard]] std::vector<Renderer::BaseStyle> toBaseStyles() const override;
[[nodiscard]] QJsonArray toJson() const;
QStringList unusedStyleNames() const;
std::unique_ptr<LayerStyle> makeUnusedStyle(const QString& styleName) const;
bool useStyle(const std::shared_ptr<LayerStyle>& style);
[[nodiscard]] bool empty() const;
[[nodiscard]] bool full() const;
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::iterator begin();
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::iterator end();
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator cbegin() const;
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator cend() const;
[[nodiscard]] QStringList unusedStyleNames() const;
[[nodiscard]] std::unique_ptr<LayerStyle> makeUnusedStyle(const QString& styleName) const;
bool useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride = false);
bool overrideStyle(const std::shared_ptr<LayerStyle>& style);
bool dropStyle(const QString& styleName);
std::shared_ptr<LayerStyle> getStyle(const QString& styleName) const;
float boundingBoxAffectValue() const;
size_t getHash() const;
[[nodiscard]] std::shared_ptr<LayerStyle> getStyle(const QString& styleName) const;
[[nodiscard]] float boundingBoxAffectValue() const;
[[nodiscard]] size_t getHash() const;
bool operator==(const LayerStyleContainer& other) const;
[[nodiscard]] bool operator==(const LayerStyleContainer& other) const;
[[nodiscard]] LayerStyleContainer operator<<(const LayerStyleContainer& other) const;
/**
*

View File

@ -79,7 +79,9 @@ FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *element
LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager* elementManager, FolderLayerWrapper* parent)
: LayerWrapper(json, parent, elementManager),
wrappedElement(elementManager->getElementById(json.value("element").toInt())),
styles(LayerStyleContainer::fromJson(wrappedElement->isClosed(), json.value("styles").toArray()))
styles(LayerStyleContainer::fromJson(
wrappedElement->isClosed() ? LayerStyleContainer::TYPE_CLOSED : LayerStyleContainer::TYPE_UNCLOSED,
json.value("styles").toArray()))
{
qDebug() << json.value("name").toString() << " " << this;
if(wrappedElement != nullptr)

View File

@ -21,37 +21,37 @@ InfoDisplayWidget::InfoDisplayWidget(QWidget* parent) :QWidget(parent)
ui.rotation->setLabel(("旋转角度"));
ui.scaleX->setLabel(("水平缩放"));
ui.scaleY->setLabel(("垂直缩放"));
ui.rotation->setValidator(new QDoubleValidator(-10000, 10000, 6, this));
ui.rotation->setValidator(new QIntValidator(-360, 360, this));
ui.styleList->setDisabled(true);
connect(ui.rotation, &QLineEdit::textChanged, [=](QString content) {
connect(ui.rotation, &QLineEdit::textChanged, [=](const QString& content) {
if (fabs(content.toDouble() - this->displayLayer->property.rotation) < 1e-6)
return;
this->displayLayer->property.rotation = content.toDouble();
this->displayLayer->property.setRotation(content.toDouble());
emit triggerCentralRefresh();
});
ui.offsetX->setValidator(new QDoubleValidator(-10000, 10000, 2, this));
connect(ui.offsetX, &QLineEdit::textChanged, [=](QString content) {
connect(ui.offsetX, &QLineEdit::textChanged, [=](const QString& content) {
if (fabs(content.toDouble() - this->displayLayer->property.offset.x()) < 1e-6)
return;
this->displayLayer->property.offset = { content.toDouble(), this->displayLayer->property.offset.y() };
emit triggerCentralRefresh();
});
ui.offsetY->setValidator(new QDoubleValidator(-10000, 10000, 2, this));
connect(ui.offsetY, &QLineEdit::textChanged, [=](QString content) {
connect(ui.offsetY, &QLineEdit::textChanged, [=](const QString& content) {
if (fabs(content.toDouble() - this->displayLayer->property.offset.y()) < 1e-6)
return;
this->displayLayer->property.offset = { this->displayLayer->property.offset.x(), content.toDouble() };
emit triggerCentralRefresh();
});
ui.scaleX->setValidator(new QDoubleValidator(0, 10000, 6, this));
connect(ui.scaleX, &QLineEdit::textChanged, [=](QString content) {
connect(ui.scaleX, &QLineEdit::textChanged, [=](const QString& content) {
if (fabs(content.toDouble() - this->displayLayer->property.scale.x()) < 1e-6)
return;
this->displayLayer->property.scale = { content.toDouble(), this->displayLayer->property.scale.y() };
emit triggerCentralRefresh();
});
ui.scaleY->setValidator(new QDoubleValidator(0, 10000, 6, this));
connect(ui.scaleY, &QLineEdit::textChanged, [=](QString content) {
connect(ui.scaleY, &QLineEdit::textChanged, [=](const QString& content) {
if (fabs(content.toDouble() - this->displayLayer->property.scale.y()) < 1e-6)
return;
this->displayLayer->property.scale = { this->displayLayer->property.scale.x(), content.toDouble() };

View File

@ -0,0 +1,49 @@
#include "CppUnitTest.h"
#include "Editor/LayerStyle.h"
#include <QGuiApplication>
#include <QtWidgets/QApplication>
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace UnitTest
{
TEST_CLASS(LayerStyleContainerTest)
{
private:
char* argv[1];
int argc;
LayerStyleContainer containerParent, containerChild;
public:
LayerStyleContainerTest() :
argv{ const_cast<char*>("") }, argc(1),
containerParent(LayerStyleContainer::TYPE_ALL),
containerChild(LayerStyleContainer::TYPE_UNCLOSED)
{
QApplication app(argc, argv);
Assert::IsTrue(containerParent.empty());
Assert::IsTrue(containerChild.empty());
auto fillStyle = containerParent.makeUnusedStyle(FillElementLayerStyle::displayName());
Assert::IsTrue(containerParent.useStyle(std::shared_ptr(std::move(fillStyle))));
Assert::IsFalse(containerParent.empty());
Assert::IsFalse(containerParent.full());
auto strokeStyle = containerParent.makeUnusedStyle(StrokeElementLayerStyle::displayName());
containerParent.useStyle(std::shared_ptr(std::move(strokeStyle)));
auto childStrokeStyle = containerChild.makeUnusedStyle(StrokeElementLayerStyle::displayName());
containerChild.useStyle(std::shared_ptr(std::move(childStrokeStyle)));
Assert::IsTrue(containerChild.full());
containerParent.computeNewHash();
containerChild.computeNewHash();
}
TEST_METHOD(ContainerCoverTest)
{
const auto newContainer = containerParent << containerChild;
Assert::IsTrue(newContainer.full());
Assert::AreEqual(newContainer.getHash(), containerChild.getHash());
}
};
}

View File

@ -111,6 +111,7 @@
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
</ClCompile>
<ClCompile Include="LayerStyleTest.cpp" />
<ClCompile Include="PaintingTest.cpp">
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">input</DynamicSource>
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).moc</QtMocFileName>

View File

@ -51,5 +51,8 @@
<ClCompile Include="StyleTest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LayerStyleTest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>