[style] 修改了LayerStyle相关的很多东西
* 实现了复制和粘贴 * 实现了LayerStyleContainer的<<运算符 * 重构了LayerContainerListWidget的信号结构 * 使LayerStyleContainer的一些接口的表现更符合新需求 * 让style继承的基本覆盖逻辑变得正确了 * Fix: LayerContainerListWidget的操作对象不及时改变main
parent
dc4de8823e
commit
7667525287
|
@ -1,7 +1,12 @@
|
||||||
#include "LayerContainerListWidget.h"
|
#include "LayerContainerListWidget.h"
|
||||||
|
|
||||||
#include "LayerStyleDialog.h"
|
#include "LayerStyleDialog.h"
|
||||||
#include "../ColorHelper.hpp"
|
#include "../ColorHelper.hpp"
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
inline void initMaterialButton(QtMaterialRaisedButton* button)
|
inline void initMaterialButton(QtMaterialRaisedButton* button)
|
||||||
|
@ -13,11 +18,6 @@ inline void initMaterialButton(QtMaterialRaisedButton* button)
|
||||||
LayerContainerListWidget::LayerContainerListWidget(QWidget* parent, const PLayerStyleContainer& styleContainer)
|
LayerContainerListWidget::LayerContainerListWidget(QWidget* parent, const PLayerStyleContainer& styleContainer)
|
||||||
: QWidget(parent), headerWidget(new QWidget(this)), styleList(new QListWidget(this)), styleContainer(styleContainer)
|
: QWidget(parent), headerWidget(new QWidget(this)), styleList(new QListWidget(this)), styleContainer(styleContainer)
|
||||||
{
|
{
|
||||||
connect(this, &LayerContainerListWidget::addLayerStyle,
|
|
||||||
this, &LayerContainerListWidget::onAddLayerStyle);
|
|
||||||
connect(this, &LayerContainerListWidget::removeLayerStyle,
|
|
||||||
this, &LayerContainerListWidget::onRemoveLayerStyle);
|
|
||||||
|
|
||||||
auto* widgetLayout = new QVBoxLayout(this);
|
auto* widgetLayout = new QVBoxLayout(this);
|
||||||
initHeader();
|
initHeader();
|
||||||
widgetLayout->addWidget(this->headerWidget);
|
widgetLayout->addWidget(this->headerWidget);
|
||||||
|
@ -43,6 +43,7 @@ void LayerContainerListWidget::setStyleContainer(const PLayerStyleContainer& sty
|
||||||
{
|
{
|
||||||
if (!forceRefresh && comparePStyleContainersEquality(this->styleContainer, styleContainer))
|
if (!forceRefresh && comparePStyleContainersEquality(this->styleContainer, styleContainer))
|
||||||
{
|
{
|
||||||
|
this->styleContainer = styleContainer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +53,6 @@ void LayerContainerListWidget::setStyleContainer(const PLayerStyleContainer& sty
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->styleContainer = styleContainer;
|
this->styleContainer = styleContainer;
|
||||||
|
|
||||||
for (const auto& style : *styleContainer | std::views::values)
|
for (const auto& style : *styleContainer | std::views::values)
|
||||||
|
@ -60,6 +60,7 @@ void LayerContainerListWidget::setStyleContainer(const PLayerStyleContainer& sty
|
||||||
auto* item = new QListWidgetItem(styleList);
|
auto* item = new QListWidgetItem(styleList);
|
||||||
item->setSizeHint(QSize(50, 40));
|
item->setSizeHint(QSize(50, 40));
|
||||||
styleList->setItemWidget(item, buildStyleListWidget(style));
|
styleList->setItemWidget(item, buildStyleListWidget(style));
|
||||||
|
styleItemMap[style->getDisplayName()] = item;
|
||||||
}
|
}
|
||||||
resetAddButton();
|
resetAddButton();
|
||||||
}
|
}
|
||||||
|
@ -75,11 +76,10 @@ void LayerContainerListWidget::resetAddButton()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "resetAddButton" << styleContainer->full();
|
|
||||||
addButton->setDisabled(styleContainer->full());
|
addButton->setDisabled(styleContainer->full());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerContainerListWidget::onAddLayerStyle(const std::shared_ptr<LayerStyle>& style)
|
void LayerContainerListWidget::addLayerStyle(const std::shared_ptr<LayerStyle>& style)
|
||||||
{
|
{
|
||||||
if (const bool ok = styleContainer->useStyle(style))
|
if (const bool ok = styleContainer->useStyle(style))
|
||||||
{
|
{
|
||||||
|
@ -89,10 +89,18 @@ void LayerContainerListWidget::onAddLayerStyle(const std::shared_ptr<LayerStyle>
|
||||||
styleItemMap[style->getDisplayName()] = newItem;
|
styleItemMap[style->getDisplayName()] = newItem;
|
||||||
newItem->setSizeHint(QSize(50, 40));
|
newItem->setSizeHint(QSize(50, 40));
|
||||||
styleList->setItemWidget(newItem, buildStyleListWidget(style));
|
styleList->setItemWidget(newItem, buildStyleListWidget(style));
|
||||||
|
emit refreshStylePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerContainerListWidget::onRemoveLayerStyle(const QString& styleName)
|
void LayerContainerListWidget::editLayerStyle(const std::shared_ptr<LayerStyle>& style)
|
||||||
|
{
|
||||||
|
this->styleContainer->overrideStyle(style);
|
||||||
|
this->styleContainer->computeNewHash();
|
||||||
|
emit refreshStylePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerContainerListWidget::removeLayerStyle(const QString& styleName)
|
||||||
{
|
{
|
||||||
if (const bool ok = styleContainer->dropStyle(styleName))
|
if (const bool ok = styleContainer->dropStyle(styleName))
|
||||||
{
|
{
|
||||||
|
@ -100,9 +108,35 @@ void LayerContainerListWidget::onRemoveLayerStyle(const QString& styleName)
|
||||||
auto* removedItem = styleItemMap.extract(styleName).mapped();
|
auto* removedItem = styleItemMap.extract(styleName).mapped();
|
||||||
resetAddButton();
|
resetAddButton();
|
||||||
delete styleList->takeItem(styleList->row(removedItem));
|
delete styleList->takeItem(styleList->row(removedItem));
|
||||||
|
emit refreshStylePreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LayerContainerListWidget::copyStyles() const
|
||||||
|
{
|
||||||
|
QApplication::clipboard()->setText(QJsonDocument(styleContainer->toJson()).toJson());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerContainerListWidget::pasteStyles()
|
||||||
|
{
|
||||||
|
QJsonParseError jsonError;
|
||||||
|
const auto& document = QJsonDocument::fromJson(QApplication::clipboard()->text().toUtf8(), &jsonError);
|
||||||
|
if (jsonError.error || !document.isArray())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, QStringLiteral("错误!"), QStringLiteral("剪贴板中的文本无法被识别为样式。"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto& jsonArray = document.array();
|
||||||
|
if (jsonArray.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto& container = LayerStyleContainer::fromJson(ElementType::TYPE_ALL, jsonArray);
|
||||||
|
*this->styleContainer << container;
|
||||||
|
setStyleContainer(this->styleContainer, true);
|
||||||
|
emit refreshStylePreview();
|
||||||
|
}
|
||||||
|
|
||||||
void LayerContainerListWidget::initHeader()
|
void LayerContainerListWidget::initHeader()
|
||||||
{
|
{
|
||||||
auto* headerLayout = new QHBoxLayout;
|
auto* headerLayout = new QHBoxLayout;
|
||||||
|
@ -118,16 +152,17 @@ void LayerContainerListWidget::initHeader()
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
if (dialog->layerStyle)
|
if (dialog->layerStyle)
|
||||||
{
|
{
|
||||||
emit addLayerStyle(dialog->layerStyle);
|
addLayerStyle(dialog->layerStyle);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this->copyButton = new QtMaterialRaisedButton(QStringLiteral("复制所有样式"), headerWidget);
|
this->copyButton = new QtMaterialRaisedButton(QStringLiteral("复制所有样式"), headerWidget);
|
||||||
initMaterialButton(copyButton);
|
initMaterialButton(copyButton);
|
||||||
// TODO: ʵÏÖ¸´ÖÆ
|
connect(copyButton, &QtMaterialRaisedButton::clicked, this, &LayerContainerListWidget::copyStyles);
|
||||||
|
|
||||||
this->pasteButton = new QtMaterialRaisedButton(QStringLiteral("从剪贴板粘贴"), headerWidget);
|
this->pasteButton = new QtMaterialRaisedButton(QStringLiteral("从剪贴板粘贴"), headerWidget);
|
||||||
initMaterialButton(pasteButton);
|
initMaterialButton(pasteButton);
|
||||||
|
connect(pasteButton, &QtMaterialRaisedButton::clicked, this, &LayerContainerListWidget::pasteStyles);
|
||||||
|
|
||||||
headerLayout->addWidget(headerLabel);
|
headerLayout->addWidget(headerLabel);
|
||||||
headerLayout->addWidget(addButton);
|
headerLayout->addWidget(addButton);
|
||||||
|
@ -135,11 +170,6 @@ void LayerContainerListWidget::initHeader()
|
||||||
headerLayout->addWidget(pasteButton);
|
headerLayout->addWidget(pasteButton);
|
||||||
headerLayout->setContentsMargins(5, 0, 5, 0);
|
headerLayout->setContentsMargins(5, 0, 5, 0);
|
||||||
headerWidget->setLayout(headerLayout);
|
headerWidget->setLayout(headerLayout);
|
||||||
|
|
||||||
/*auto* headerItem = new QListWidgetItem(this);
|
|
||||||
headerItem->setFlags(Qt::NoItemFlags);
|
|
||||||
this->addItem(headerItem);
|
|
||||||
this->setItemWidget(headerItem, headerWidget);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,17 +197,12 @@ QWidget* LayerContainerListWidget::buildStyleListWidget(std::shared_ptr<LayerSty
|
||||||
|
|
||||||
if (dialog->layerStyle)
|
if (dialog->layerStyle)
|
||||||
{
|
{
|
||||||
this->styleContainer->overrideStyle(dialog->layerStyle);
|
editLayerStyle(dialog->layerStyle);
|
||||||
this->styleContainer->computeNewHash();
|
|
||||||
emit editLayerStyle(targetStyle);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(removeButton, &QPushButton::clicked,
|
connect(removeButton, &QPushButton::clicked,
|
||||||
[this, styleDisplayName]
|
[this, styleDisplayName] { removeLayerStyle(styleDisplayName); });
|
||||||
{
|
|
||||||
emit removeLayerStyle(styleDisplayName);
|
|
||||||
});
|
|
||||||
|
|
||||||
QWidget* styleDisplayWidget = style->getListDisplayWidget();
|
QWidget* styleDisplayWidget = style->getListDisplayWidget();
|
||||||
styleDisplayWidget->setParent(w);
|
styleDisplayWidget->setParent(w);
|
||||||
|
|
|
@ -26,13 +26,15 @@ public:
|
||||||
void setStyleContainer(const PLayerStyleContainer& styleContainer, bool forceRefresh = false);
|
void setStyleContainer(const PLayerStyleContainer& styleContainer, bool forceRefresh = false);
|
||||||
PLayerStyleContainer getStyleContainer() const;
|
PLayerStyleContainer getStyleContainer() const;
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void onAddLayerStyle(const std::shared_ptr<LayerStyle>& style);
|
|
||||||
void onRemoveLayerStyle(const QString& styleName);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void addLayerStyle(const std::shared_ptr<LayerStyle>& style);
|
void addLayerStyle(const std::shared_ptr<LayerStyle>& style);
|
||||||
void editLayerStyle(const std::shared_ptr<LayerStyle>& style);
|
void editLayerStyle(const std::shared_ptr<LayerStyle>& style);
|
||||||
void removeLayerStyle(const QString& styleName);
|
void removeLayerStyle(const QString& styleName);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void copyStyles() const;
|
||||||
|
void pasteStyles();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void refreshStylePreview();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ void LayerStyleContainer::computeNewHash()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer LayerStyleContainer::fromJson(ElementType elementType, const QJsonArray& jsonArray)
|
LayerStyleContainer LayerStyleContainer::fromJson(ElementType::ElementType elementType, const QJsonArray& jsonArray)
|
||||||
{
|
{
|
||||||
LayerStyleContainer container(elementType);
|
LayerStyleContainer container(elementType);
|
||||||
for (const auto& style : jsonArray)
|
for (const auto& style : jsonArray)
|
||||||
|
@ -102,26 +102,26 @@ LayerStyleContainer LayerStyleContainer::fromJson(ElementType elementType, const
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer::LayerStyleContainer(ElementType elementType) : hash(0)
|
LayerStyleContainer::LayerStyleContainer(ElementType::ElementType elementType) : elementType(elementType), hash(0)
|
||||||
{
|
{
|
||||||
for (const auto& style : commonStyles)
|
for (const auto& style : commonStyles)
|
||||||
{
|
{
|
||||||
unusedStyles.insert(style);
|
unusedStyles.insert(style);
|
||||||
}
|
}
|
||||||
if (elementType & LayerStyleContainer::TYPE_CLOSED)
|
if (elementType & ElementType::TYPE_UNCLOSED)
|
||||||
|
{
|
||||||
|
for (const auto& style : unclosedOnlyStyles)
|
||||||
|
{
|
||||||
|
unusedStyles.insert(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (elementType & ElementType::TYPE_CLOSED)
|
||||||
{
|
{
|
||||||
for (const auto& style : closedOnlyStyles)
|
for (const auto& style : closedOnlyStyles)
|
||||||
{
|
{
|
||||||
unusedStyles.insert(style);
|
unusedStyles.insert(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (elementType & LayerStyleContainer::TYPE_UNCLOSED)
|
|
||||||
{
|
|
||||||
for (const auto& style : unclosedOnlyStyles)
|
|
||||||
{
|
|
||||||
unusedStyles.insert(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> LayerStyleContainer::toBaseStyles() const
|
std::vector<Renderer::BaseStyle> LayerStyleContainer::toBaseStyles() const
|
||||||
|
@ -196,27 +196,32 @@ bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style, boo
|
||||||
{
|
{
|
||||||
const auto styleDisplayName = style->getDisplayName();
|
const auto styleDisplayName = style->getDisplayName();
|
||||||
auto styleNode = unusedStyles.extract(styleDisplayName);
|
auto styleNode = unusedStyles.extract(styleDisplayName);
|
||||||
if (styleNode.empty())
|
if (styleNode.empty() && !forceOverride)
|
||||||
{
|
{
|
||||||
if (!forceOverride || !styles.contains(styleDisplayName))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
styles[styleDisplayName] = style;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
styles[styleNode.key()] = style;
|
auto uFittedStyle = style->fitForElementType(this->elementType);
|
||||||
usedStyles.insert(std::move(styleNode));
|
auto fittedStyle = std::shared_ptr(std::move(uFittedStyle));
|
||||||
|
if (!fittedStyle)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!styleNode.empty())
|
||||||
|
{
|
||||||
|
usedStyles.insert(std::move(styleNode));
|
||||||
|
}
|
||||||
|
styles[styleDisplayName] = fittedStyle;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::overrideStyle(const std::shared_ptr<LayerStyle>& style)
|
bool LayerStyleContainer::overrideStyle(const std::shared_ptr<LayerStyle>& style)
|
||||||
{
|
{
|
||||||
if (!styles.contains(style->getDisplayName()))
|
auto fittedStyle = std::shared_ptr(std::move(style->fitForElementType(this->elementType)));
|
||||||
|
if (!fittedStyle)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
styles[style->getDisplayName()] = style;
|
styles[style->getDisplayName()] = fittedStyle;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +292,17 @@ LayerStyleContainer LayerStyleContainer::operator|(const LayerStyleContainer& ot
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerStyleContainer& LayerStyleContainer::operator<<(const LayerStyleContainer& other)
|
||||||
|
{
|
||||||
|
for (auto& style : std::ranges::subrange(other.cbegin(), other.cend())
|
||||||
|
| std::views::values)
|
||||||
|
{
|
||||||
|
this->useStyle(style, true);
|
||||||
|
}
|
||||||
|
computeNewHash();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<StrokeElementLayerStyle> StrokeElementLayerStyle::fromJson(const QJsonObject& json)
|
std::unique_ptr<StrokeElementLayerStyle> StrokeElementLayerStyle::fromJson(const QJsonObject& json)
|
||||||
{
|
{
|
||||||
auto ptr = std::make_unique<StrokeElementLayerStyle>(
|
auto ptr = std::make_unique<StrokeElementLayerStyle>(
|
||||||
|
@ -351,6 +367,28 @@ std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clone() const
|
||||||
return std::make_unique<StrokeElementLayerStyle>(StrokeElementLayerStyle(*this));
|
return std::make_unique<StrokeElementLayerStyle>(StrokeElementLayerStyle(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<LayerStyle> StrokeElementLayerStyle::fitForElementType(ElementType::ElementType type) const
|
||||||
|
{
|
||||||
|
auto result = std::unique_ptr<StrokeElementLayerStyle>(reinterpret_cast<StrokeElementLayerStyle*>(this->clone().release()));
|
||||||
|
const bool isThisClosed = strokePair.first->endType == Renderer::StrokeEndType::kClosed;
|
||||||
|
const bool isRequiredTypeClosed = (type & ElementType::TYPE_CLOSED) == ElementType::TYPE_CLOSED;
|
||||||
|
if (isThisClosed == isRequiredTypeClosed)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (type == ElementType::TYPE_CLOSED)
|
||||||
|
{
|
||||||
|
result->strokePair.first->endType = Renderer::StrokeEndType::kClosed;
|
||||||
|
result->strokePair.second->endType = Renderer::StrokeEndType::kClosed;
|
||||||
|
}
|
||||||
|
else if (isThisClosed)
|
||||||
|
{
|
||||||
|
result->strokePair.first->endType = Renderer::StrokeEndType::kFlat;
|
||||||
|
result->strokePair.second->endType = Renderer::StrokeEndType::kFlat;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool StrokeElementLayerStyle::operator==(const LayerStyle& other) const
|
bool StrokeElementLayerStyle::operator==(const LayerStyle& other) const
|
||||||
{
|
{
|
||||||
if (!LayerStyle::operator==(other))
|
if (!LayerStyle::operator==(other))
|
||||||
|
@ -426,6 +464,15 @@ std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
|
||||||
return std::make_unique<FillElementLayerStyle>(FillElementLayerStyle(*this));
|
return std::make_unique<FillElementLayerStyle>(FillElementLayerStyle(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<LayerStyle> FillElementLayerStyle::fitForElementType(ElementType::ElementType type) const
|
||||||
|
{
|
||||||
|
if (type & ElementType::TYPE_CLOSED)
|
||||||
|
{
|
||||||
|
return this->clone();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool FillElementLayerStyle::operator==(const LayerStyle& other) const
|
bool FillElementLayerStyle::operator==(const LayerStyle& other) const
|
||||||
{
|
{
|
||||||
if (!LayerStyle::operator==(other))
|
if (!LayerStyle::operator==(other))
|
||||||
|
|
|
@ -21,6 +21,14 @@ using Renderer::MaterialStyleFill;
|
||||||
#define radialStroke(stroke) std::static_pointer_cast<Renderer::StrokeRadialGradient>((stroke)->materialStroke)
|
#define radialStroke(stroke) std::static_pointer_cast<Renderer::StrokeRadialGradient>((stroke)->materialStroke)
|
||||||
#define plainFill(fill) std::static_pointer_cast<Renderer::FillPlain>((fill)->materialFill)
|
#define plainFill(fill) std::static_pointer_cast<Renderer::FillPlain>((fill)->materialFill)
|
||||||
|
|
||||||
|
namespace ElementType
|
||||||
|
{
|
||||||
|
using ElementType = unsigned short;
|
||||||
|
constexpr ElementType TYPE_ALL = 0xffff;
|
||||||
|
constexpr ElementType TYPE_CLOSED = 0b01;
|
||||||
|
constexpr ElementType TYPE_UNCLOSED = 0b10;
|
||||||
|
};
|
||||||
|
|
||||||
class LayerStyle : public Renderer::ElementStyle
|
class LayerStyle : public Renderer::ElementStyle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -35,6 +43,7 @@ public:
|
||||||
|
|
||||||
virtual QJsonObject toJson() const;
|
virtual QJsonObject toJson() const;
|
||||||
virtual std::unique_ptr<LayerStyle> clone() const = 0;
|
virtual std::unique_ptr<LayerStyle> clone() const = 0;
|
||||||
|
virtual std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const = 0;
|
||||||
|
|
||||||
virtual bool operator==(const LayerStyle& other) const;
|
virtual bool operator==(const LayerStyle& other) const;
|
||||||
};
|
};
|
||||||
|
@ -57,6 +66,7 @@ public:
|
||||||
QWidget* getListDisplayWidget() const override;
|
QWidget* getListDisplayWidget() const override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
std::unique_ptr<LayerStyle> clone() const override;
|
||||||
|
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override;
|
||||||
|
|
||||||
bool operator==(const LayerStyle& other) const override;
|
bool operator==(const LayerStyle& other) const override;
|
||||||
|
|
||||||
|
@ -81,6 +91,7 @@ public:
|
||||||
QWidget* getListDisplayWidget() const override;
|
QWidget* getListDisplayWidget() const override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
std::unique_ptr<LayerStyle> clone() const override;
|
||||||
|
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override;
|
||||||
|
|
||||||
bool operator==(const LayerStyle& other) const override;
|
bool operator==(const LayerStyle& other) const override;
|
||||||
|
|
||||||
|
@ -111,19 +122,15 @@ private:
|
||||||
[] { return std::make_unique<StrokeElementLayerStyle>(false); }
|
[] { return std::make_unique<StrokeElementLayerStyle>(false); }
|
||||||
} };
|
} };
|
||||||
|
|
||||||
|
ElementType::ElementType elementType;
|
||||||
DisplayNameWithSupplier unusedStyles;
|
DisplayNameWithSupplier unusedStyles;
|
||||||
DisplayNameWithSupplier usedStyles;
|
DisplayNameWithSupplier usedStyles;
|
||||||
std::map<QString, std::shared_ptr<LayerStyle>> styles;
|
std::map<QString, std::shared_ptr<LayerStyle>> styles;
|
||||||
size_t hash;
|
size_t hash;
|
||||||
public:
|
public:
|
||||||
using ElementType = unsigned short;
|
static LayerStyleContainer fromJson(ElementType::ElementType elementType, const QJsonArray& jsonArray);
|
||||||
constexpr static ElementType TYPE_ALL = 0xffff;
|
|
||||||
constexpr static ElementType TYPE_CLOSED = 0b01;
|
|
||||||
constexpr static ElementType TYPE_UNCLOSED = 0b10;
|
|
||||||
|
|
||||||
static LayerStyleContainer fromJson(ElementType elementType, const QJsonArray& jsonArray);
|
LayerStyleContainer(ElementType::ElementType elementType);
|
||||||
|
|
||||||
LayerStyleContainer(ElementType elementType);
|
|
||||||
[[nodiscard]] std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
[[nodiscard]] std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||||
[[nodiscard]] QJsonArray toJson() const;
|
[[nodiscard]] QJsonArray toJson() const;
|
||||||
|
|
||||||
|
@ -148,6 +155,7 @@ public:
|
||||||
* 类管道操作,后者覆盖前者,会返回一个新的LayerStyleContainer
|
* 类管道操作,后者覆盖前者,会返回一个新的LayerStyleContainer
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] LayerStyleContainer operator|(const LayerStyleContainer& other) const;
|
[[nodiscard]] LayerStyleContainer operator|(const LayerStyleContainer& other) const;
|
||||||
|
LayerStyleContainer& operator<<(const LayerStyleContainer& other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要在每次更改后手动调用
|
* 需要在每次更改后手动调用
|
||||||
|
|
|
@ -59,7 +59,7 @@ FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *element
|
||||||
qDebug() << json.value("name").toString() << " " << this;
|
qDebug() << json.value("name").toString() << " " << this;
|
||||||
QJsonArray childrenJson = json.value("children").toArray();
|
QJsonArray childrenJson = json.value("children").toArray();
|
||||||
QJsonValue referencedJson = json.value("referenced-by");
|
QJsonValue referencedJson = json.value("referenced-by");
|
||||||
styles = new LayerStyleContainer(LayerStyleContainer::TYPE_ALL);
|
styles = new LayerStyleContainer(ElementType::TYPE_ALL);
|
||||||
if (!referencedJson.isNull())
|
if (!referencedJson.isNull())
|
||||||
{
|
{
|
||||||
auto p = reinterpret_cast<GroupElement *>(elementManager->getElementById(referencedJson.toInt()));
|
auto p = reinterpret_cast<GroupElement *>(elementManager->getElementById(referencedJson.toInt()));
|
||||||
|
@ -83,7 +83,7 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager* elementMana
|
||||||
wrappedElement(elementManager->getElementById(json.value("element").toInt()))
|
wrappedElement(elementManager->getElementById(json.value("element").toInt()))
|
||||||
{
|
{
|
||||||
styles = new LayerStyleContainer(LayerStyleContainer::fromJson(
|
styles = new LayerStyleContainer(LayerStyleContainer::fromJson(
|
||||||
wrappedElement->isClosed() ? LayerStyleContainer::TYPE_CLOSED : LayerStyleContainer::TYPE_UNCLOSED,
|
wrappedElement->isClosed() ? ElementType::TYPE_CLOSED : ElementType::TYPE_UNCLOSED,
|
||||||
json.value("styles").toArray()));
|
json.value("styles").toArray()));
|
||||||
qDebug() << json.value("name").toString() << " " << this;
|
qDebug() << json.value("name").toString() << " " << this;
|
||||||
if(wrappedElement != nullptr)
|
if(wrappedElement != nullptr)
|
||||||
|
|
|
@ -62,7 +62,7 @@ class LayerWrapper
|
||||||
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
||||||
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
||||||
LayerWrapper() = default;
|
LayerWrapper() = default;
|
||||||
virtual void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(LayerStyleContainer::TYPE_ALL));
|
virtual void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL));
|
||||||
// TODO : export Function
|
// TODO : export Function
|
||||||
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
||||||
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
||||||
|
@ -103,7 +103,7 @@ class FolderLayerWrapper : public LayerWrapper
|
||||||
QTreeWidgetItem* getQTreeItem() override;
|
QTreeWidgetItem* getQTreeItem() override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
int getReferencedBy()const;
|
int getReferencedBy()const;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(LayerStyleContainer::TYPE_ALL)) override;
|
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override;
|
||||||
void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
|
void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
|
||||||
void refreshTreeItem() override;
|
void refreshTreeItem() override;
|
||||||
size_t referencedCount(bool excludeSelf = false) const override;
|
size_t referencedCount(bool excludeSelf = false) const override;
|
||||||
|
@ -121,7 +121,7 @@ class LeafLayerWrapper : public LayerWrapper
|
||||||
void refresh(LayerWrapper* layer = nullptr) override;
|
void refresh(LayerWrapper* layer = nullptr) override;
|
||||||
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(LayerStyleContainer::TYPE_ALL)) override;
|
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override;
|
||||||
void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
|
void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
|
||||||
QTreeWidgetItem* getQTreeItem() override;
|
QTreeWidgetItem* getQTreeItem() override;
|
||||||
void refreshTreeItem() override;
|
void refreshTreeItem() override;
|
||||||
|
|
|
@ -23,7 +23,7 @@ InfoDisplayWidget::InfoDisplayWidget(QWidget* parent) :QWidget(parent)
|
||||||
ui.scaleX->setLabel(("水平缩放"));
|
ui.scaleX->setLabel(("水平缩放"));
|
||||||
ui.scaleY->setLabel(("垂直缩放"));
|
ui.scaleY->setLabel(("垂直缩放"));
|
||||||
ui.rotation->setValidator(new QIntValidator(-360, 360, this));
|
ui.rotation->setValidator(new QIntValidator(-360, 360, this));
|
||||||
ui.styleList->setDisabled(true);
|
//ui.styleList->setDisabled(true);
|
||||||
connect(ui.rotation, &QLineEdit::textChanged, [=](const QString& content) {
|
connect(ui.rotation, &QLineEdit::textChanged, [=](const QString& content) {
|
||||||
if (fabs(content.toDouble() - this->displayLayer->property.rotation) < 1e-6)
|
if (fabs(content.toDouble() - this->displayLayer->property.rotation) < 1e-6)
|
||||||
return;
|
return;
|
||||||
|
@ -70,13 +70,7 @@ InfoDisplayWidget::InfoDisplayWidget(QWidget* parent) :QWidget(parent)
|
||||||
this->displayLayer->property.flipY = state;
|
this->displayLayer->property.flipY = state;
|
||||||
emit triggerCentralRefresh();
|
emit triggerCentralRefresh();
|
||||||
});
|
});
|
||||||
connect(ui.styleList, &LayerContainerListWidget::addLayerStyle, [this](const std::shared_ptr<LayerStyle>& style) {
|
connect(ui.styleList, &LayerContainerListWidget::refreshStylePreview, [this] {
|
||||||
emit triggerCentralRefresh();
|
|
||||||
});
|
|
||||||
connect(ui.styleList, &LayerContainerListWidget::editLayerStyle, [this](const std::shared_ptr<LayerStyle>& style) {
|
|
||||||
emit triggerCentralRefresh();
|
|
||||||
});
|
|
||||||
connect(ui.styleList, &LayerContainerListWidget::removeLayerStyle, [this](const QString& styleName) {
|
|
||||||
emit triggerCentralRefresh();
|
emit triggerCentralRefresh();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -99,14 +93,15 @@ void InfoDisplayWidget::refresh()
|
||||||
ui.scaleY->setText(QString::number(this->displayLayer->property.scale.y()));
|
ui.scaleY->setText(QString::number(this->displayLayer->property.scale.y()));
|
||||||
ui.flipX->setChecked(this->displayLayer->property.flipX);
|
ui.flipX->setChecked(this->displayLayer->property.flipX);
|
||||||
ui.flipY->setChecked(this->displayLayer->property.flipY);
|
ui.flipY->setChecked(this->displayLayer->property.flipY);
|
||||||
if (this->displayLayer->canApplyStyles())
|
/*if (this->displayLayer->canApplyStyles())
|
||||||
{
|
{
|
||||||
ui.styleList->setDisabled(false);
|
ui.styleList->setDisabled(false);
|
||||||
ui.styleList->setStyleContainer(static_cast<LayerWrapper*>(this->displayLayer)->styles);
|
ui.styleList->setStyleContainer(this->displayLayer->styles);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ui.styleList->setDisabled(true);
|
ui.styleList->setDisabled(true);
|
||||||
}
|
}*/
|
||||||
|
ui.styleList->setStyleContainer(this->displayLayer->styles);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,8 +16,8 @@ namespace UnitTest
|
||||||
public:
|
public:
|
||||||
LayerStyleContainerTest() :
|
LayerStyleContainerTest() :
|
||||||
argv{ const_cast<char*>("") }, argc(1),
|
argv{ const_cast<char*>("") }, argc(1),
|
||||||
containerParent(LayerStyleContainer::TYPE_ALL),
|
containerParent(ElementType::TYPE_ALL),
|
||||||
containerChild(LayerStyleContainer::TYPE_UNCLOSED)
|
containerChild(ElementType::TYPE_UNCLOSED)
|
||||||
{
|
{
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
Assert::IsTrue(containerParent.empty());
|
Assert::IsTrue(containerParent.empty());
|
||||||
|
|
Loading…
Reference in New Issue