parent
b465b90195
commit
df71b04e4c
|
@ -110,6 +110,7 @@
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\Editor\Properties\MaterialReplaceDialog.cpp" />
|
||||||
<ClCompile Include="src\Editor\util\JsonMerger.cpp" />
|
<ClCompile Include="src\Editor\util\JsonMerger.cpp" />
|
||||||
<ClCompile Include="src\Editor\Properties\ProjectPropertyWidget.cpp" />
|
<ClCompile Include="src\Editor\Properties\ProjectPropertyWidget.cpp" />
|
||||||
<ClCompile Include="src\Editor\Properties\ProjectPropertyDialog.cpp" />
|
<ClCompile Include="src\Editor\Properties\ProjectPropertyDialog.cpp" />
|
||||||
|
@ -222,6 +223,7 @@
|
||||||
<QtMoc Include="src\Editor\Properties\CanvasPropertyWidget.h" />
|
<QtMoc Include="src\Editor\Properties\CanvasPropertyWidget.h" />
|
||||||
<QtMoc Include="src\Editor\Properties\ProjectPropertyDialog.h" />
|
<QtMoc Include="src\Editor\Properties\ProjectPropertyDialog.h" />
|
||||||
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h" />
|
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h" />
|
||||||
|
<QtMoc Include="src\Editor\Properties\MaterialReplaceDialog.h" />
|
||||||
<ClInclude Include="src\Editor\util\JsonMerger.h" />
|
<ClInclude Include="src\Editor\util\JsonMerger.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="src\Editor\Properties\PropertyWidget.h" />
|
<ClInclude Include="src\Editor\Properties\PropertyWidget.h" />
|
||||||
|
|
|
@ -288,6 +288,9 @@
|
||||||
<ClCompile Include="src\Editor\util\JsonMerger.cpp">
|
<ClCompile Include="src\Editor\util\JsonMerger.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\Editor\Properties\MaterialReplaceDialog.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="src\Renderer\RendererGLWidget.h">
|
<QtMoc Include="src\Renderer\RendererGLWidget.h">
|
||||||
|
@ -359,6 +362,9 @@
|
||||||
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h">
|
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
<QtMoc Include="src\Editor\Properties\MaterialReplaceDialog.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\data.json" />
|
<None Include="..\data.json" />
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "EditorWidget.h"
|
#include "EditorWidget.h"
|
||||||
#include "EditorWidgetItem.h"
|
#include "EditorWidgetItem.h"
|
||||||
#include "Properties/ProjectPropertyDialog.h"
|
#include "Properties/ProjectPropertyDialog.h"
|
||||||
|
#include "Properties/MaterialReplaceDialog.h"
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
@ -22,11 +23,11 @@ EditorWidget::EditorWidget(QWidget* parent) : QWidget(parent)
|
||||||
initProjectMenu();
|
initProjectMenu();
|
||||||
|
|
||||||
connect(this->tabWidget, &QTabWidget::tabCloseRequested, [this](int index) {
|
connect(this->tabWidget, &QTabWidget::tabCloseRequested, [this](int index) {
|
||||||
const int prevCount = this->tabWidget->count();
|
const int prevCount = this->tabWidget->count();
|
||||||
this->tabWidget->removeTab(index);
|
this->tabWidget->removeTab(index);
|
||||||
const int nowCount = this->tabWidget->count();
|
const int nowCount = this->tabWidget->count();
|
||||||
|
|
||||||
emit tabCountChanged(prevCount, nowCount);
|
emit tabCountChanged(prevCount, nowCount);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,8 +150,10 @@ void EditorWidget::initProjectMenu()
|
||||||
projectMenuButton->setDisabled(true);
|
projectMenuButton->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* actionProjectSettings = new QAction(QStringLiteral("ÏîÄ¿ÉèÖÃ"), projectMenuButton);
|
auto actionProjectSettings = new QAction(QStringLiteral("ÏîÄ¿ÉèÖÃ"), projectMenuButton);
|
||||||
|
auto actionMaterialReplace = new QAction(QStringLiteral("²ÄÖÊÌæ»»"), projectMenuButton);
|
||||||
projectMenuButton->addMenuAction(actionProjectSettings);
|
projectMenuButton->addMenuAction(actionProjectSettings);
|
||||||
|
projectMenuButton->addMenuAction(actionMaterialReplace);
|
||||||
|
|
||||||
connect(actionProjectSettings, &QAction::triggered, [this]
|
connect(actionProjectSettings, &QAction::triggered, [this]
|
||||||
{
|
{
|
||||||
|
@ -160,9 +163,9 @@ void EditorWidget::initProjectMenu()
|
||||||
|
|
||||||
connect(dialog, &ProjectPropertyDialog::projectNameChanged,
|
connect(dialog, &ProjectPropertyDialog::projectNameChanged,
|
||||||
currentEditorWidgetItem, &EditorWidgetItem::handleProjectNameChange);
|
currentEditorWidgetItem, &EditorWidgetItem::handleProjectNameChange);
|
||||||
connect(dialog, &ProjectPropertyDialog::backgroundColorChanged,
|
connect(dialog, &ProjectPropertyDialog::backgroundColorChanged,
|
||||||
currentEditorWidgetItem, &EditorWidgetItem::handleBackgroundColorChange);
|
currentEditorWidgetItem, &EditorWidgetItem::handleBackgroundColorChange);
|
||||||
connect(dialog, &ProjectPropertyDialog::canvasSizeChanged,
|
connect(dialog, &ProjectPropertyDialog::canvasSizeChanged,
|
||||||
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasSizeChange);
|
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasSizeChange);
|
||||||
connect(dialog, &ProjectPropertyDialog::canvasRoughnessChanged,
|
connect(dialog, &ProjectPropertyDialog::canvasRoughnessChanged,
|
||||||
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasRoughnessChange);
|
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasRoughnessChange);
|
||||||
|
@ -170,4 +173,10 @@ void EditorWidget::initProjectMenu()
|
||||||
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasMetallicChange);
|
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasMetallicChange);
|
||||||
dialog->exec();
|
dialog->exec();
|
||||||
});
|
});
|
||||||
|
connect(actionMaterialReplace, &QAction::triggered, [this]
|
||||||
|
{
|
||||||
|
auto* currentEditorWidgetItem = static_cast<EditorWidgetItem*>(this->tabWidget->currentWidget());
|
||||||
|
const auto dialog = new MaterialReplaceDialog(currentEditorWidgetItem, this);
|
||||||
|
dialog->exec();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,6 +274,11 @@ void EditorWidgetItem::handleCanvasMetallicChange(const float& metallic)
|
||||||
previewWindow->canvasMetallic = metallic;
|
previewWindow->canvasMetallic = metallic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorWidgetItem::handleMaterialReplace(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QSize EditorWidgetItem::getCanvasReferSize() const
|
QSize EditorWidgetItem::getCanvasReferSize() const
|
||||||
{
|
{
|
||||||
return previewWindow->referSize;
|
return previewWindow->referSize;
|
||||||
|
|
|
@ -50,6 +50,7 @@ class EditorWidgetItem : public QWidget
|
||||||
void handleCanvasSizeChange(const QSize& size);
|
void handleCanvasSizeChange(const QSize& size);
|
||||||
void handleCanvasRoughnessChange(const float& roughness);
|
void handleCanvasRoughnessChange(const float& roughness);
|
||||||
void handleCanvasMetallicChange(const float& metallic);
|
void handleCanvasMetallicChange(const float& metallic);
|
||||||
|
void handleMaterialReplace(const Renderer::Material& origin, const Renderer::Material& target);
|
||||||
QSize getCanvasReferSize() const;
|
QSize getCanvasReferSize() const;
|
||||||
float getCanvasRoughness() const;
|
float getCanvasRoughness() const;
|
||||||
float getCanvasMetallic() const;
|
float getCanvasMetallic() const;
|
||||||
|
|
|
@ -16,421 +16,441 @@
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
|
std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
|
||||||
{
|
{
|
||||||
std::vector<Renderer::BaseStyle> baseStyles;
|
std::vector<Renderer::BaseStyle> baseStyles;
|
||||||
if (enableEachSideIndependent)
|
if (enableEachSideIndependent)
|
||||||
{
|
{
|
||||||
if (!radialStroke(strokePair.first)->materialMap.empty())
|
if (!radialStroke(strokePair.first)->materialMap.empty())
|
||||||
{
|
{
|
||||||
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), strokePair.first });
|
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), strokePair.first });
|
||||||
}
|
}
|
||||||
if (!radialStroke(strokePair.second)->materialMap.empty())
|
if (!radialStroke(strokePair.second)->materialMap.empty())
|
||||||
{
|
{
|
||||||
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), strokePair.second });
|
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), strokePair.second });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!radialStroke(strokePair.first)->materialMap.empty())
|
else if (!radialStroke(strokePair.first)->materialMap.empty())
|
||||||
{
|
{
|
||||||
const auto material = std::shared_ptr(std::move(strokePair.first->clone()));
|
const auto material = std::shared_ptr(std::move(strokePair.first->clone()));
|
||||||
std::static_pointer_cast<MaterialStyleStroke>(material)->strokeType = Renderer::StrokeType::kBothSides;
|
std::static_pointer_cast<MaterialStyleStroke>(material)->strokeType = Renderer::StrokeType::kBothSides;
|
||||||
|
|
||||||
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), material });
|
baseStyles.push_back({ std::make_shared<Renderer::TransformStyle>(), material });
|
||||||
}
|
}
|
||||||
return baseStyles;
|
return baseStyles;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* StrokeElementLayerStyle::getInputWidget()
|
QWidget* StrokeElementLayerStyle::getInputWidget()
|
||||||
{
|
{
|
||||||
auto* w = new QWidget;
|
auto* w = new QWidget;
|
||||||
|
|
||||||
auto* layout = new QVBoxLayout(w);
|
auto* layout = new QVBoxLayout(w);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
|
|
||||||
auto* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w);
|
auto* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w);
|
||||||
layout->addWidget(leftStrokeView);
|
layout->addWidget(leftStrokeView);
|
||||||
|
|
||||||
auto* checkEachSideIndependent = new QtMaterialCheckBox(w);
|
|
||||||
checkEachSideIndependent->setText(QStringLiteral("ÓÒ²à¶ÀÁ¢Ãè±ß"));
|
|
||||||
checkEachSideIndependent->setChecked(enableEachSideIndependent);
|
|
||||||
layout->addWidget(checkEachSideIndependent);
|
|
||||||
|
|
||||||
auto* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w);
|
auto* checkEachSideIndependent = new QtMaterialCheckBox(w);
|
||||||
layout->addWidget(rightStrokeView);
|
checkEachSideIndependent->setText(QStringLiteral("ÓÒ²à¶ÀÁ¢Ãè±ß"));
|
||||||
rightStrokeView->setDisabled(!this->enableEachSideIndependent);
|
checkEachSideIndependent->setChecked(enableEachSideIndependent);
|
||||||
|
layout->addWidget(checkEachSideIndependent);
|
||||||
|
|
||||||
QObject::connect(checkEachSideIndependent, &QtMaterialCheckBox::toggled, [this, rightStrokeView](bool toggled) {
|
auto* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w);
|
||||||
this->enableEachSideIndependent = toggled;
|
layout->addWidget(rightStrokeView);
|
||||||
rightStrokeView->setDisabled(!toggled);
|
rightStrokeView->setDisabled(!this->enableEachSideIndependent);
|
||||||
});
|
|
||||||
return w;
|
QObject::connect(checkEachSideIndependent, &QtMaterialCheckBox::toggled, [this, rightStrokeView](bool toggled) {
|
||||||
|
this->enableEachSideIndependent = toggled;
|
||||||
|
rightStrokeView->setDisabled(!toggled);
|
||||||
|
});
|
||||||
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
|
QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
|
||||||
{
|
{
|
||||||
auto* w = new QWidget;
|
auto* w = new QWidget;
|
||||||
auto* name = new QLabel(w);
|
auto* name = new QLabel(w);
|
||||||
name->setText(QStringLiteral("Ãè±ß"));
|
name->setText(QStringLiteral("Ãè±ß"));
|
||||||
auto* layout = new QHBoxLayout(w);
|
auto* layout = new QHBoxLayout(w);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
layout->addWidget(name);
|
layout->addWidget(name);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerStyleContainer::computeNewHash()
|
void LayerStyleContainer::computeNewHash()
|
||||||
{
|
{
|
||||||
hash = 0;
|
hash = 0;
|
||||||
for (auto& f : styles
|
for (auto& f : styles
|
||||||
| std::views::values
|
| std::views::values
|
||||||
| std::views::transform(&LayerStyle::toBaseStyles)
|
| std::views::transform(&LayerStyle::toBaseStyles)
|
||||||
| std::views::join
|
| std::views::join
|
||||||
| std::views::transform(&Renderer::BaseStyle::material)
|
| std::views::transform(&Renderer::BaseStyle::material)
|
||||||
| std::views::transform(&MaterialStyle::encoded)
|
| std::views::transform(&MaterialStyle::encoded)
|
||||||
| std::views::join)
|
| std::views::join)
|
||||||
{
|
{
|
||||||
const unsigned int u = *reinterpret_cast<unsigned int*>(&f);
|
const unsigned int u = *reinterpret_cast<unsigned int*>(&f);
|
||||||
hash ^= u + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
hash ^= u + 0x9e3779b9 + (hash << 6) + (hash >> 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer LayerStyleContainer::fromJson(ElementType::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)
|
||||||
{
|
{
|
||||||
container.useStyle(LayerStyle::fromJson(style.toObject()));
|
container.useStyle(LayerStyle::fromJson(style.toObject()));
|
||||||
}
|
}
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer::LayerStyleContainer(ElementType::ElementType elementType) : 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 & ElementType::TYPE_UNCLOSED)
|
if (elementType & ElementType::TYPE_UNCLOSED)
|
||||||
{
|
{
|
||||||
for (const auto& style : unclosedOnlyStyles)
|
for (const auto& style : unclosedOnlyStyles)
|
||||||
{
|
{
|
||||||
unusedStyles.insert(style);
|
unusedStyles.insert(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (elementType & ElementType::TYPE_CLOSED)
|
if (elementType & ElementType::TYPE_CLOSED)
|
||||||
{
|
{
|
||||||
for (const auto& style : closedOnlyStyles)
|
for (const auto& style : closedOnlyStyles)
|
||||||
{
|
{
|
||||||
unusedStyles.insert(style);
|
unusedStyles.insert(style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> LayerStyleContainer::toBaseStyles() const
|
std::vector<Renderer::BaseStyle> LayerStyleContainer::toBaseStyles() const
|
||||||
{
|
{
|
||||||
std::vector<Renderer::BaseStyle> result;
|
std::vector<Renderer::BaseStyle> result;
|
||||||
for (const auto& style : styles | std::views::values)
|
for (const auto& style : styles | std::views::values)
|
||||||
{
|
{
|
||||||
auto baseStyles = style->toBaseStyles();
|
auto baseStyles = style->toBaseStyles();
|
||||||
result.insert(result.end(),
|
result.insert(result.end(),
|
||||||
std::make_move_iterator(baseStyles.begin()),
|
std::make_move_iterator(baseStyles.begin()),
|
||||||
std::make_move_iterator(baseStyles.end()));
|
std::make_move_iterator(baseStyles.end()));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray LayerStyleContainer::toJson() const
|
QJsonArray LayerStyleContainer::toJson() const
|
||||||
{
|
{
|
||||||
QJsonArray json;
|
QJsonArray json;
|
||||||
for (const auto& style : styles | std::views::values)
|
for (const auto& style : styles | std::views::values)
|
||||||
{
|
{
|
||||||
json.append(style->toJson());
|
json.append(style->toJson());
|
||||||
}
|
}
|
||||||
return json;
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerStyleContainer::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
for (auto& style : styles | std::views::values)
|
||||||
|
style->replaceMaterial(origin, target);
|
||||||
|
computeNewHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList LayerStyleContainer::unusedStyleNames() const
|
QStringList LayerStyleContainer::unusedStyleNames() const
|
||||||
{
|
{
|
||||||
QStringList result;
|
QStringList result;
|
||||||
for(const auto& name : unusedStyles | std::views::keys)
|
for(const auto& name : unusedStyles | std::views::keys)
|
||||||
{
|
{
|
||||||
result << name;
|
result << name;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LayerStyle> LayerStyleContainer::makeUnusedStyle(const QString& styleName) const
|
std::unique_ptr<LayerStyle> LayerStyleContainer::makeUnusedStyle(const QString& styleName) const
|
||||||
{
|
{
|
||||||
return unusedStyles.at(styleName)();
|
return unusedStyles.at(styleName)();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::empty() const
|
bool LayerStyleContainer::empty() const
|
||||||
{
|
{
|
||||||
return styles.empty();
|
return styles.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::full() const
|
bool LayerStyleContainer::full() const
|
||||||
{
|
{
|
||||||
return unusedStyles.empty();
|
return unusedStyles.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::begin()
|
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::begin()
|
||||||
{
|
{
|
||||||
return styles.begin();
|
return styles.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::end()
|
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::end()
|
||||||
{
|
{
|
||||||
return styles.end();
|
return styles.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cbegin() const
|
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cbegin() const
|
||||||
{
|
{
|
||||||
return styles.cbegin();
|
return styles.cbegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cend() const
|
std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator LayerStyleContainer::cend() const
|
||||||
{
|
{
|
||||||
return styles.cend();
|
return styles.cend();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride)
|
bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride)
|
||||||
{
|
{
|
||||||
const auto styleDisplayName = style->getDisplayName();
|
const auto styleDisplayName = style->getDisplayName();
|
||||||
auto styleNode = unusedStyles.extract(styleDisplayName);
|
auto styleNode = unusedStyles.extract(styleDisplayName);
|
||||||
if (styleNode.empty() && !forceOverride)
|
if (styleNode.empty() && !forceOverride)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto uFittedStyle = style->fitForElementType(this->elementType);
|
auto uFittedStyle = style->fitForElementType(this->elementType);
|
||||||
auto fittedStyle = std::shared_ptr(std::move(uFittedStyle));
|
auto fittedStyle = std::shared_ptr(std::move(uFittedStyle));
|
||||||
if (!fittedStyle)
|
if (!fittedStyle)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!styleNode.empty())
|
if (!styleNode.empty())
|
||||||
{
|
{
|
||||||
usedStyles.insert(std::move(styleNode));
|
usedStyles.insert(std::move(styleNode));
|
||||||
}
|
}
|
||||||
styles[styleDisplayName] = fittedStyle;
|
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)
|
||||||
{
|
{
|
||||||
auto fittedStyle = std::shared_ptr(std::move(style->fitForElementType(this->elementType)));
|
auto fittedStyle = std::shared_ptr(std::move(style->fitForElementType(this->elementType)));
|
||||||
if (!fittedStyle)
|
if (!fittedStyle)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
styles[style->getDisplayName()] = fittedStyle;
|
styles[style->getDisplayName()] = fittedStyle;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::dropStyle(const QString& styleName)
|
bool LayerStyleContainer::dropStyle(const QString& styleName)
|
||||||
{
|
{
|
||||||
auto styleNode = usedStyles.extract(styleName);
|
auto styleNode = usedStyles.extract(styleName);
|
||||||
if (styleNode.empty())
|
if (styleNode.empty())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
styles.erase(styleName);
|
styles.erase(styleName);
|
||||||
unusedStyles.insert(std::move(styleNode));
|
unusedStyles.insert(std::move(styleNode));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<LayerStyle> LayerStyleContainer::getStyle(const QString& styleName) const
|
std::shared_ptr<LayerStyle> LayerStyleContainer::getStyle(const QString& styleName) const
|
||||||
{
|
{
|
||||||
return styles.at(styleName);
|
return styles.at(styleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
float LayerStyleContainer::boundingBoxAffectValue() const {
|
float LayerStyleContainer::boundingBoxAffectValue() const {
|
||||||
float maxLineWidth = 0;
|
float maxLineWidth = 0;
|
||||||
const auto strokeStyle = styles.find(StrokeElementLayerStyle::displayName());
|
const auto strokeStyle = styles.find(StrokeElementLayerStyle::displayName());
|
||||||
if (strokeStyle != styles.end())
|
if (strokeStyle != styles.end())
|
||||||
{
|
{
|
||||||
if (const auto strokeElementLayerStyle =
|
if (const auto strokeElementLayerStyle =
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(strokeStyle->second);
|
std::dynamic_pointer_cast<StrokeElementLayerStyle>(strokeStyle->second);
|
||||||
strokeElementLayerStyle != nullptr)
|
strokeElementLayerStyle != nullptr)
|
||||||
{
|
{
|
||||||
const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first;
|
const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first;
|
||||||
const auto& rightStyleStroke = strokeElementLayerStyle->strokePair.second;
|
const auto& rightStyleStroke = strokeElementLayerStyle->strokePair.second;
|
||||||
if (leftStyleStroke != nullptr)
|
if (leftStyleStroke != nullptr)
|
||||||
{
|
{
|
||||||
maxLineWidth = std::max(maxLineWidth, leftStyleStroke->halfWidth);
|
maxLineWidth = std::max(maxLineWidth, leftStyleStroke->halfWidth);
|
||||||
}
|
}
|
||||||
if (rightStyleStroke != nullptr)
|
if (rightStyleStroke != nullptr)
|
||||||
{
|
{
|
||||||
maxLineWidth = std::max(maxLineWidth, rightStyleStroke->halfWidth);
|
maxLineWidth = std::max(maxLineWidth, rightStyleStroke->halfWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return maxLineWidth;
|
return maxLineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t LayerStyleContainer::getHash() const
|
size_t LayerStyleContainer::getHash() const
|
||||||
{
|
{
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyleContainer::operator==(const LayerStyleContainer& other) const
|
bool LayerStyleContainer::operator==(const LayerStyleContainer& other) const
|
||||||
{
|
{
|
||||||
if (getHash() != other.getHash() || unusedStyleNames() != other.unusedStyleNames())
|
if (getHash() != other.getHash() || unusedStyleNames() != other.unusedStyleNames())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return std::ranges::equal(styles | std::views::values, other.styles | std::views::values);
|
return std::ranges::equal(styles | std::views::values, other.styles | std::views::values);
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer LayerStyleContainer::operator|(const LayerStyleContainer& other) const
|
LayerStyleContainer LayerStyleContainer::operator|(const LayerStyleContainer& other) const
|
||||||
{
|
{
|
||||||
LayerStyleContainer result = other;
|
LayerStyleContainer result = other;
|
||||||
for (const auto& style : std::ranges::subrange(this->cbegin(), this->cend())
|
for (const auto& style : std::ranges::subrange(this->cbegin(), this->cend())
|
||||||
| std::views::values)
|
| std::views::values)
|
||||||
{
|
{
|
||||||
result.useStyle(style);
|
result.useStyle(style);
|
||||||
}
|
}
|
||||||
result.computeNewHash();
|
result.computeNewHash();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerStyleContainer& LayerStyleContainer::operator<<(const LayerStyleContainer& other)
|
LayerStyleContainer& LayerStyleContainer::operator<<(const LayerStyleContainer& other)
|
||||||
{
|
{
|
||||||
for (auto& style : std::ranges::subrange(other.cbegin(), other.cend())
|
for (auto& style : std::ranges::subrange(other.cbegin(), other.cend())
|
||||||
| std::views::values)
|
| std::views::values)
|
||||||
{
|
{
|
||||||
this->useStyle(style, true);
|
this->useStyle(style, true);
|
||||||
}
|
}
|
||||||
computeNewHash();
|
computeNewHash();
|
||||||
return *this;
|
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>(
|
||||||
std::static_pointer_cast<MaterialStyleStroke>(
|
std::static_pointer_cast<MaterialStyleStroke>(
|
||||||
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString()))))
|
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString()))))
|
||||||
),
|
),
|
||||||
std::static_pointer_cast<MaterialStyleStroke>(
|
std::static_pointer_cast<MaterialStyleStroke>(
|
||||||
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["right"].toString()))))
|
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["right"].toString()))))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
|
ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
StrokeElementLayerStyle::StrokeElementLayerStyle(bool isClosed)
|
StrokeElementLayerStyle::StrokeElementLayerStyle(bool isClosed)
|
||||||
{
|
{
|
||||||
const auto materialMap = std::map<float, Renderer::Material>();
|
const auto materialMap = std::map<float, Renderer::Material>();
|
||||||
this->strokePair.first = std::make_shared<MaterialStyleStroke>(
|
this->strokePair.first = std::make_shared<MaterialStyleStroke>(
|
||||||
7,
|
7,
|
||||||
Renderer::StrokeType::kLeftSide, isClosed ? Renderer::StrokeEndType::kClosed : Renderer::StrokeEndType::kFlat,
|
Renderer::StrokeType::kLeftSide, isClosed ? Renderer::StrokeEndType::kClosed : Renderer::StrokeEndType::kFlat,
|
||||||
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
|
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this->strokePair.second = std::make_shared<MaterialStyleStroke>(
|
||||||
|
7,
|
||||||
|
Renderer::StrokeType::kRightSide, isClosed ? Renderer::StrokeEndType::kClosed : Renderer::StrokeEndType::kFlat,
|
||||||
|
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
|
||||||
|
);
|
||||||
|
|
||||||
this->strokePair.second = std::make_shared<MaterialStyleStroke>(
|
|
||||||
7,
|
|
||||||
Renderer::StrokeType::kRightSide, isClosed ? Renderer::StrokeEndType::kClosed : Renderer::StrokeEndType::kFlat,
|
|
||||||
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StrokeElementLayerStyle::StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right)
|
StrokeElementLayerStyle::StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right)
|
||||||
{
|
{
|
||||||
this->strokePair.first = left;
|
this->strokePair.first = left;
|
||||||
this->strokePair.second = right ? right : std::static_pointer_cast<MaterialStyleStroke>(
|
this->strokePair.second = right ? right : std::static_pointer_cast<MaterialStyleStroke>(
|
||||||
std::shared_ptr(std::move(left->clone()))
|
std::shared_ptr(std::move(left->clone()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
|
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
|
||||||
{
|
{
|
||||||
strokePair.first = std::static_pointer_cast<MaterialStyleStroke>(
|
strokePair.first = std::static_pointer_cast<MaterialStyleStroke>(
|
||||||
std::shared_ptr(std::move(other.strokePair.first->clone()))
|
std::shared_ptr(std::move(other.strokePair.first->clone()))
|
||||||
);
|
);
|
||||||
strokePair.second = std::static_pointer_cast<MaterialStyleStroke>(
|
strokePair.second = std::static_pointer_cast<MaterialStyleStroke>(
|
||||||
std::shared_ptr(std::move(other.strokePair.second->clone()))
|
std::shared_ptr(std::move(other.strokePair.second->clone()))
|
||||||
);
|
);
|
||||||
enableEachSideIndependent = other.enableEachSideIndependent;
|
enableEachSideIndependent = other.enableEachSideIndependent;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject StrokeElementLayerStyle::toJson() const
|
QJsonObject StrokeElementLayerStyle::toJson() const
|
||||||
{
|
{
|
||||||
auto json = LayerStyle::toJson();
|
auto json = LayerStyle::toJson();
|
||||||
json["enableEachSideIndependent"] = enableEachSideIndependent;
|
json["enableEachSideIndependent"] = enableEachSideIndependent;
|
||||||
json["left"] = EncodeUtil::toBase64<GLfloat>(strokePair.first->encoded());
|
json["left"] = EncodeUtil::toBase64<GLfloat>(strokePair.first->encoded());
|
||||||
json["right"] = EncodeUtil::toBase64<GLfloat>(strokePair.second->encoded());
|
json["right"] = EncodeUtil::toBase64<GLfloat>(strokePair.second->encoded());
|
||||||
return json;
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StrokeElementLayerStyle::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
auto styles = { strokePair.first, strokePair.second };
|
||||||
|
for (auto& style : styles)
|
||||||
|
{
|
||||||
|
if (!style) continue;
|
||||||
|
|
||||||
|
for (auto& material : std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(style->materialStroke)->materialMap | std::views::values)
|
||||||
|
if (material == origin)
|
||||||
|
material = target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clone() const
|
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
|
std::unique_ptr<LayerStyle> StrokeElementLayerStyle::fitForElementType(ElementType::ElementType type) const
|
||||||
{
|
{
|
||||||
auto result = std::unique_ptr<StrokeElementLayerStyle>(reinterpret_cast<StrokeElementLayerStyle*>(this->clone().release()));
|
auto result = std::unique_ptr<StrokeElementLayerStyle>(reinterpret_cast<StrokeElementLayerStyle*>(this->clone().release()));
|
||||||
const bool isThisClosed = strokePair.first->endType == Renderer::StrokeEndType::kClosed;
|
const bool isThisClosed = strokePair.first->endType == Renderer::StrokeEndType::kClosed;
|
||||||
const bool isRequiredTypeClosed = (type & ElementType::TYPE_CLOSED) == ElementType::TYPE_CLOSED;
|
const bool isRequiredTypeClosed = (type & ElementType::TYPE_CLOSED) == ElementType::TYPE_CLOSED;
|
||||||
if (isThisClosed == isRequiredTypeClosed)
|
if (isThisClosed == isRequiredTypeClosed)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (type == ElementType::TYPE_CLOSED)
|
if (type == ElementType::TYPE_CLOSED)
|
||||||
{
|
{
|
||||||
result->strokePair.first->endType = Renderer::StrokeEndType::kClosed;
|
result->strokePair.first->endType = Renderer::StrokeEndType::kClosed;
|
||||||
result->strokePair.second->endType = Renderer::StrokeEndType::kClosed;
|
result->strokePair.second->endType = Renderer::StrokeEndType::kClosed;
|
||||||
}
|
}
|
||||||
else if (isThisClosed)
|
else if (isThisClosed)
|
||||||
{
|
{
|
||||||
result->strokePair.first->endType = Renderer::StrokeEndType::kFlat;
|
result->strokePair.first->endType = Renderer::StrokeEndType::kFlat;
|
||||||
result->strokePair.second->endType = Renderer::StrokeEndType::kFlat;
|
result->strokePair.second->endType = Renderer::StrokeEndType::kFlat;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StrokeElementLayerStyle::operator==(const LayerStyle& other) const
|
bool StrokeElementLayerStyle::operator==(const LayerStyle& other) const
|
||||||
{
|
{
|
||||||
if (!LayerStyle::operator==(other))
|
if (!LayerStyle::operator==(other))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto otherStyle = dynamic_cast<const StrokeElementLayerStyle*>(&other);
|
const auto otherStyle = dynamic_cast<const StrokeElementLayerStyle*>(&other);
|
||||||
if (!otherStyle)
|
if (!otherStyle)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->strokePair.first == otherStyle->strokePair.first && this->strokePair.second == otherStyle->strokePair.second;
|
return this->strokePair.first == otherStyle->strokePair.first && this->strokePair.second == otherStyle->strokePair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FillElementLayerStyle> FillElementLayerStyle::fromJson(const QJsonObject& json)
|
std::unique_ptr<FillElementLayerStyle> FillElementLayerStyle::fromJson(const QJsonObject& json)
|
||||||
{
|
{
|
||||||
auto ptr = std::make_unique<FillElementLayerStyle>(
|
auto ptr = std::make_unique<FillElementLayerStyle>(
|
||||||
std::static_pointer_cast<MaterialStyleFill>(
|
std::static_pointer_cast<MaterialStyleFill>(
|
||||||
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["material"].toString()))))
|
std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["material"].toString()))))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> FillElementLayerStyle::toBaseStyles() const
|
std::vector<Renderer::BaseStyle> FillElementLayerStyle::toBaseStyles() const
|
||||||
{
|
{
|
||||||
return { {std::make_shared<Renderer::TransformStyle>(), fillMaterialStyle} };
|
return { {std::make_shared<Renderer::TransformStyle>(), fillMaterialStyle} };
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* FillElementLayerStyle::getInputWidget()
|
QWidget* FillElementLayerStyle::getInputWidget()
|
||||||
{
|
{
|
||||||
return new FillStyleWidget(fillMaterialStyle);
|
return new FillStyleWidget(fillMaterialStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget* FillElementLayerStyle::getListDisplayWidget() const
|
QWidget* FillElementLayerStyle::getListDisplayWidget() const
|
||||||
{
|
{
|
||||||
auto* w = new QWidget;
|
auto* w = new QWidget;
|
||||||
auto* name = new QLabel(w);
|
auto* name = new QLabel(w);
|
||||||
name->setText(QStringLiteral("Ìî³ä"));
|
name->setText(QStringLiteral("Ìî³ä"));
|
||||||
auto* layout = new QHBoxLayout(w);
|
auto* layout = new QHBoxLayout(w);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
layout->addWidget(name);
|
layout->addWidget(name);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
FillElementLayerStyle::FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle)
|
FillElementLayerStyle::FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle)
|
||||||
|
@ -438,76 +458,83 @@ FillElementLayerStyle::FillElementLayerStyle(const PMaterialStyleFill& fillMater
|
||||||
{
|
{
|
||||||
if (!fillMaterialStyle)
|
if (!fillMaterialStyle)
|
||||||
{
|
{
|
||||||
this->fillMaterialStyle = std::make_shared<MaterialStyleFill>(
|
this->fillMaterialStyle = std::make_shared<MaterialStyleFill>(
|
||||||
std::make_shared<Renderer::FillPlain>(ColorHelper::instance().getPrimary1())
|
std::make_shared<Renderer::FillPlain>(ColorHelper::instance().getPrimary1())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other)
|
FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other)
|
||||||
{
|
{
|
||||||
this->fillMaterialStyle = std::static_pointer_cast<MaterialStyleFill>(
|
this->fillMaterialStyle = std::static_pointer_cast<MaterialStyleFill>(
|
||||||
std::shared_ptr(std::move(other.fillMaterialStyle->clone()))
|
std::shared_ptr(std::move(other.fillMaterialStyle->clone()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject FillElementLayerStyle::toJson() const
|
QJsonObject FillElementLayerStyle::toJson() const
|
||||||
{
|
{
|
||||||
auto json = LayerStyle::toJson();
|
auto json = LayerStyle::toJson();
|
||||||
json["material"] = EncodeUtil::toBase64<GLfloat>(fillMaterialStyle->encoded());
|
json["material"] = EncodeUtil::toBase64<GLfloat>(fillMaterialStyle->encoded());
|
||||||
return json;
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillElementLayerStyle::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
auto materialFill = std::dynamic_pointer_cast<Renderer::FillPlain>(fillMaterialStyle->materialFill);
|
||||||
|
if (materialFill->material == origin)
|
||||||
|
materialFill->material = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
|
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
|
std::unique_ptr<LayerStyle> FillElementLayerStyle::fitForElementType(ElementType::ElementType type) const
|
||||||
{
|
{
|
||||||
if (type & ElementType::TYPE_CLOSED)
|
if (type & ElementType::TYPE_CLOSED)
|
||||||
{
|
{
|
||||||
return this->clone();
|
return this->clone();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FillElementLayerStyle::operator==(const LayerStyle& other) const
|
bool FillElementLayerStyle::operator==(const LayerStyle& other) const
|
||||||
{
|
{
|
||||||
if (!LayerStyle::operator==(other))
|
if (!LayerStyle::operator==(other))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto otherStyle = dynamic_cast<const FillElementLayerStyle*>(&other);
|
const auto otherStyle = dynamic_cast<const FillElementLayerStyle*>(&other);
|
||||||
if (!otherStyle)
|
if (!otherStyle)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->fillMaterialStyle == otherStyle->fillMaterialStyle;
|
return this->fillMaterialStyle == otherStyle->fillMaterialStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
|
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
|
||||||
{
|
{
|
||||||
QString type = json["type"].toString();
|
QString type = json["type"].toString();
|
||||||
if (type == StrokeElementLayerStyle::typeName())
|
if (type == StrokeElementLayerStyle::typeName())
|
||||||
{
|
{
|
||||||
return StrokeElementLayerStyle::fromJson(json);
|
return StrokeElementLayerStyle::fromJson(json);
|
||||||
}
|
}
|
||||||
if (type == FillElementLayerStyle::typeName())
|
if (type == FillElementLayerStyle::typeName())
|
||||||
{
|
{
|
||||||
return FillElementLayerStyle::fromJson(json);
|
return FillElementLayerStyle::fromJson(json);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject LayerStyle::toJson() const
|
QJsonObject LayerStyle::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json["type"] = this->getTypeName();
|
json["type"] = this->getTypeName();
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LayerStyle::operator==(const LayerStyle& other) const
|
bool LayerStyle::operator==(const LayerStyle& other) const
|
||||||
{
|
{
|
||||||
return this->getTypeName() == other.getTypeName();
|
return this->getTypeName() == other.getTypeName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,79 +23,82 @@ using Renderer::MaterialStyleFill;
|
||||||
|
|
||||||
namespace ElementType
|
namespace ElementType
|
||||||
{
|
{
|
||||||
using ElementType = unsigned short;
|
using ElementType = unsigned short;
|
||||||
constexpr ElementType TYPE_ALL = 0xffff;
|
constexpr ElementType TYPE_ALL = 0xffff;
|
||||||
constexpr ElementType TYPE_CLOSED = 0b01;
|
constexpr ElementType TYPE_CLOSED = 0b01;
|
||||||
constexpr ElementType TYPE_UNCLOSED = 0b10;
|
constexpr ElementType TYPE_UNCLOSED = 0b10;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LayerStyle : public Renderer::ElementStyle
|
class LayerStyle : public Renderer::ElementStyle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<LayerStyle> fromJson(const QJsonObject& json);
|
static std::unique_ptr<LayerStyle> fromJson(const QJsonObject& json);
|
||||||
virtual ~LayerStyle() = default;
|
virtual ~LayerStyle() = default;
|
||||||
|
|
||||||
virtual QString getDisplayName() const = 0;
|
virtual QString getDisplayName() const = 0;
|
||||||
virtual QString getTypeName() const = 0;
|
virtual QString getTypeName() const = 0;
|
||||||
|
|
||||||
virtual QWidget* getInputWidget() = 0;
|
virtual QWidget* getInputWidget() = 0;
|
||||||
virtual QWidget* getListDisplayWidget() const = 0;
|
virtual QWidget* getListDisplayWidget() const = 0;
|
||||||
|
|
||||||
virtual QJsonObject toJson() const;
|
virtual QJsonObject toJson() const;
|
||||||
virtual std::unique_ptr<LayerStyle> clone() const = 0;
|
virtual void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) = 0;
|
||||||
virtual std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StrokeElementLayerStyle : public LayerStyle
|
class StrokeElementLayerStyle : public LayerStyle
|
||||||
{
|
{
|
||||||
using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>;
|
using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STYLE_NAME("描边", "stroke")
|
STYLE_NAME("描边", "stroke")
|
||||||
static std::unique_ptr<StrokeElementLayerStyle> fromJson(const QJsonObject& json);
|
static std::unique_ptr<StrokeElementLayerStyle> fromJson(const QJsonObject& json);
|
||||||
|
|
||||||
StrokeElementLayerStyle(bool isClosed);
|
StrokeElementLayerStyle(bool isClosed);
|
||||||
StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right = nullptr);
|
StrokeElementLayerStyle(const PMaterialStyleStroke& left, const PMaterialStyleStroke& right = nullptr);
|
||||||
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
||||||
~StrokeElementLayerStyle() override = default;
|
~StrokeElementLayerStyle() override = default;
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||||
QWidget* getInputWidget() override;
|
QWidget* getInputWidget() override;
|
||||||
QWidget* getListDisplayWidget() const override;
|
QWidget* getListDisplayWidget() const override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
|
||||||
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) 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;
|
||||||
|
|
||||||
std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
|
std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
|
||||||
bool enableEachSideIndependent = false;
|
bool enableEachSideIndependent = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FillElementLayerStyle : public LayerStyle
|
class FillElementLayerStyle : public LayerStyle
|
||||||
{
|
{
|
||||||
using PMaterialStyleFill = std::shared_ptr<MaterialStyleFill>;
|
using PMaterialStyleFill = std::shared_ptr<MaterialStyleFill>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STYLE_NAME("填充", "fill")
|
STYLE_NAME("填充", "fill")
|
||||||
static std::unique_ptr<FillElementLayerStyle> fromJson(const QJsonObject& json);
|
static std::unique_ptr<FillElementLayerStyle> fromJson(const QJsonObject& json);
|
||||||
|
|
||||||
FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle = nullptr);
|
FillElementLayerStyle(const PMaterialStyleFill& fillMaterialStyle = nullptr);
|
||||||
FillElementLayerStyle(const FillElementLayerStyle& other);
|
FillElementLayerStyle(const FillElementLayerStyle& other);
|
||||||
~FillElementLayerStyle() override = default;
|
~FillElementLayerStyle() override = default;
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||||
QWidget* getInputWidget() override;
|
QWidget* getInputWidget() override;
|
||||||
QWidget* getListDisplayWidget() const override;
|
QWidget* getListDisplayWidget() const override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
|
||||||
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) 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;
|
||||||
|
|
||||||
PMaterialStyleFill fillMaterialStyle;
|
PMaterialStyleFill fillMaterialStyle;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,62 +106,63 @@ public:
|
||||||
*/
|
*/
|
||||||
class LayerStyleContainer : public Renderer::ElementStyle
|
class LayerStyleContainer : public Renderer::ElementStyle
|
||||||
{
|
{
|
||||||
using DisplayNameWithSupplier = std::map<QString, std::function<std::unique_ptr<LayerStyle>()>>;
|
using DisplayNameWithSupplier = std::map<QString, std::function<std::unique_ptr<LayerStyle>()>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline const static DisplayNameWithSupplier commonStyles = { };
|
inline const static DisplayNameWithSupplier commonStyles = { };
|
||||||
inline const static DisplayNameWithSupplier closedOnlyStyles = {
|
inline const static DisplayNameWithSupplier closedOnlyStyles = {
|
||||||
{
|
{
|
||||||
FillElementLayerStyle::displayName(),
|
FillElementLayerStyle::displayName(),
|
||||||
[] { return std::make_unique<FillElementLayerStyle>(); }
|
[] { return std::make_unique<FillElementLayerStyle>(); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
StrokeElementLayerStyle::displayName(),
|
StrokeElementLayerStyle::displayName(),
|
||||||
[] { return std::make_unique<StrokeElementLayerStyle>(true); }
|
[] { return std::make_unique<StrokeElementLayerStyle>(true); }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
inline const static DisplayNameWithSupplier unclosedOnlyStyles = { {
|
inline const static DisplayNameWithSupplier unclosedOnlyStyles = { {
|
||||||
StrokeElementLayerStyle::displayName(),
|
StrokeElementLayerStyle::displayName(),
|
||||||
[] { return std::make_unique<StrokeElementLayerStyle>(false); }
|
[] { return std::make_unique<StrokeElementLayerStyle>(false); }
|
||||||
} };
|
} };
|
||||||
|
|
||||||
ElementType::ElementType elementType;
|
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:
|
||||||
static LayerStyleContainer fromJson(ElementType::ElementType elementType, const QJsonArray& jsonArray);
|
static LayerStyleContainer fromJson(ElementType::ElementType elementType, const QJsonArray& jsonArray);
|
||||||
|
|
||||||
LayerStyleContainer(ElementType::ElementType elementType);
|
LayerStyleContainer(ElementType::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;
|
||||||
|
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target);
|
||||||
|
|
||||||
[[nodiscard]] bool empty() const;
|
[[nodiscard]] bool empty() const;
|
||||||
[[nodiscard]] bool full() const;
|
[[nodiscard]] bool full() const;
|
||||||
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::iterator begin();
|
[[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>>::iterator end();
|
||||||
[[nodiscard]] std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator cbegin() const;
|
[[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]] std::map<QString, std::shared_ptr<LayerStyle>>::const_iterator cend() const;
|
||||||
|
|
||||||
[[nodiscard]] QStringList unusedStyleNames() const;
|
[[nodiscard]] QStringList unusedStyleNames() const;
|
||||||
[[nodiscard]] std::unique_ptr<LayerStyle> makeUnusedStyle(const QString& styleName) const;
|
[[nodiscard]] std::unique_ptr<LayerStyle> makeUnusedStyle(const QString& styleName) const;
|
||||||
bool useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride = false);
|
bool useStyle(const std::shared_ptr<LayerStyle>& style, bool forceOverride = false);
|
||||||
bool overrideStyle(const std::shared_ptr<LayerStyle>& style);
|
bool overrideStyle(const std::shared_ptr<LayerStyle>& style);
|
||||||
bool dropStyle(const QString& styleName);
|
bool dropStyle(const QString& styleName);
|
||||||
[[nodiscard]] std::shared_ptr<LayerStyle> getStyle(const QString& styleName) const;
|
[[nodiscard]] std::shared_ptr<LayerStyle> getStyle(const QString& styleName) const;
|
||||||
[[nodiscard]] float boundingBoxAffectValue() const;
|
[[nodiscard]] float boundingBoxAffectValue() const;
|
||||||
[[nodiscard]] size_t getHash() const;
|
[[nodiscard]] size_t getHash() const;
|
||||||
|
|
||||||
[[nodiscard]] bool operator==(const LayerStyleContainer& other) const;
|
[[nodiscard]] bool operator==(const LayerStyleContainer& other) const;
|
||||||
/**
|
/**
|
||||||
* 类管道操作,后者覆盖前者,会返回一个新的LayerStyleContainer
|
* 类管道操作,后者覆盖前者,会返回一个新的LayerStyleContainer
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] LayerStyleContainer operator|(const LayerStyleContainer& other) const;
|
[[nodiscard]] LayerStyleContainer operator|(const LayerStyleContainer& other) const;
|
||||||
LayerStyleContainer& operator<<(const LayerStyleContainer& other);
|
LayerStyleContainer& operator<<(const LayerStyleContainer& other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要在每次更改后手动调用
|
* 需要在每次更改后手动调用
|
||||||
*/
|
*/
|
||||||
void computeNewHash();
|
void computeNewHash();
|
||||||
};
|
};
|
|
@ -294,6 +294,13 @@ QJsonObject FolderLayerWrapper::toJson() const
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FolderLayerWrapper::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
for (auto& child : children)
|
||||||
|
if (child != nullptr)
|
||||||
|
child->replaceMaterial(origin, target);
|
||||||
|
}
|
||||||
|
|
||||||
QJsonObject LeafLayerWrapper::toJson() const
|
QJsonObject LeafLayerWrapper::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject json = LayerWrapper::toJson();
|
QJsonObject json = LayerWrapper::toJson();
|
||||||
|
@ -303,6 +310,11 @@ QJsonObject LeafLayerWrapper::toJson() const
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LeafLayerWrapper::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
|
||||||
|
{
|
||||||
|
styles->replaceMaterial(origin, target);
|
||||||
|
}
|
||||||
|
|
||||||
int FolderLayerWrapper::getReferencedBy()const
|
int FolderLayerWrapper::getReferencedBy()const
|
||||||
{
|
{
|
||||||
if (this->elementManager != nullptr)
|
if (this->elementManager != nullptr)
|
||||||
|
|
|
@ -71,6 +71,7 @@ class LayerWrapper
|
||||||
virtual void del();
|
virtual void del();
|
||||||
virtual void delSelf();
|
virtual void delSelf();
|
||||||
virtual QJsonObject toJson() const;
|
virtual QJsonObject toJson() const;
|
||||||
|
virtual void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) = 0;
|
||||||
~LayerWrapper() = default;
|
~LayerWrapper() = default;
|
||||||
virtual void collectUpReachable(std::set<LayerWrapper*>& reachable);
|
virtual void collectUpReachable(std::set<LayerWrapper*>& reachable);
|
||||||
virtual void collectDownReachable(std::set<LayerWrapper*>& reachable);
|
virtual void collectDownReachable(std::set<LayerWrapper*>& reachable);
|
||||||
|
@ -105,6 +106,7 @@ class FolderLayerWrapper : public LayerWrapper
|
||||||
void delSelf() override;
|
void delSelf() override;
|
||||||
QTreeWidgetItem* getQTreeItem() override;
|
QTreeWidgetItem* getQTreeItem() override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
|
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
|
||||||
int getReferencedBy()const;
|
int getReferencedBy()const;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::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;
|
||||||
|
@ -125,6 +127,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 replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::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 collectDownUsedElements(std::set<GraphicElement*>& elements, bool deep = true) override;
|
void collectDownUsedElements(std::set<GraphicElement*>& elements, bool deep = true) override;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "MaterialReplaceDialog.h"
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
|
||||||
|
MaterialReplaceDialog::MaterialReplaceDialog(const EditorWidgetItem* editorWidgetItem, QWidget* parent)
|
||||||
|
: QDialog(parent),
|
||||||
|
editorWidgetItem(editorWidgetItem),
|
||||||
|
originColorPicker(new ColorPicker(ColorHelper::instance().getPrimary1(), this)),
|
||||||
|
originRoughnessField(new QtMaterialTextField(this)),
|
||||||
|
originMetallicField(new QtMaterialTextField(this)),
|
||||||
|
targetColorPicker(new ColorPicker(ColorHelper::instance().getPrimary1(), this)),
|
||||||
|
targetRoughnessField(new QtMaterialTextField(this)),
|
||||||
|
targetMetallicField(new QtMaterialTextField(this))
|
||||||
|
{
|
||||||
|
setWindowTitle(QStringLiteral("第窐杸遙"));
|
||||||
|
|
||||||
|
auto* vbox = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
auto gridLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
auto* formLeft = new QFormLayout(this);
|
||||||
|
formLeft->addRow(QStringLiteral("埻價插伎"), originColorPicker);
|
||||||
|
formLeft->addRow(QStringLiteral("埻棉缽僅"), originRoughnessField);
|
||||||
|
formLeft->addRow(QStringLiteral("埻踢扽僅"), originMetallicField);
|
||||||
|
originRoughnessField->setText(QString::number(0.5));
|
||||||
|
originMetallicField->setText(QString::number(0));
|
||||||
|
|
||||||
|
auto* formRight = new QFormLayout(this);
|
||||||
|
formRight->addRow(QStringLiteral("醴梓價插伎"), targetColorPicker);
|
||||||
|
formRight->addRow(QStringLiteral("醴梓棉缽僅"), targetRoughnessField);
|
||||||
|
formRight->addRow(QStringLiteral("醴梓踢扽僅"), targetMetallicField);
|
||||||
|
targetRoughnessField->setText(QString::number(0.5));
|
||||||
|
targetMetallicField->setText(QString::number(0));
|
||||||
|
|
||||||
|
gridLayout->addLayout(formLeft, 0, 0);
|
||||||
|
gridLayout->addLayout(formRight, 0, 1);
|
||||||
|
|
||||||
|
vbox->addLayout(gridLayout);
|
||||||
|
auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||||
|
vbox->addWidget(buttonBox);
|
||||||
|
|
||||||
|
connect(buttonBox, &QDialogButtonBox::accepted, this, &MaterialReplaceDialog::accept);
|
||||||
|
connect(buttonBox, &QDialogButtonBox::rejected, this, &MaterialReplaceDialog::reject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaterialReplaceDialog::accept()
|
||||||
|
{
|
||||||
|
editorWidgetItem->layerManager->getRoot()->replaceMaterial(
|
||||||
|
Renderer::Material(originColorPicker->getColor(), originMetallicField->text().toFloat(), originRoughnessField->text().toFloat()),
|
||||||
|
Renderer::Material(targetColorPicker->getColor(), targetMetallicField->text().toFloat(), targetRoughnessField->text().toFloat())
|
||||||
|
);
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include "EditorWidgetItem.h"
|
||||||
|
#include "EditorWidgetComponent/ColorPicker.h"
|
||||||
|
#include "../Renderer/Painting/BaseStyle.h"
|
||||||
|
|
||||||
|
class MaterialReplaceDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MaterialReplaceDialog(const EditorWidgetItem* editorWidgetItem, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void accept() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EditorWidgetItem* editorWidgetItem;
|
||||||
|
ColorPicker* originColorPicker; QtMaterialTextField* originRoughnessField; QtMaterialTextField* originMetallicField;
|
||||||
|
ColorPicker* targetColorPicker; QtMaterialTextField* targetRoughnessField; QtMaterialTextField* targetMetallicField;
|
||||||
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "BaseStyle.h"
|
#include "BaseStyle.h"
|
||||||
#include "MaterialStyleFill.h"
|
#include "MaterialStyleFill.h"
|
||||||
#include "MaterialStyleStroke.h"
|
#include "MaterialStyleStroke.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
using namespace glm;
|
using namespace glm;
|
||||||
|
@ -107,3 +108,8 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
|
||||||
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke), widthMap);
|
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke), widthMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug d, const Renderer::Material& m)
|
||||||
|
{
|
||||||
|
return d << m.color << " " << m.metallic << " " << m.roughness;
|
||||||
|
}
|
||||||
|
|
|
@ -54,3 +54,5 @@ namespace Renderer
|
||||||
std::pair<glm::vec4, glm::vec2> toVec() const;
|
std::pair<glm::vec4, glm::vec2> toVec() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug, const Renderer::Material&);
|
Loading…
Reference in New Issue