Compare commits

..

8 Commits

31 changed files with 588 additions and 227 deletions

View File

@ -104,6 +104,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Editor\RightBar\EditorSettingWidget.cpp" />
<ClCompile Include="src\Editor\EditorWidgetComponent\ColorPicker.cpp" /> <ClCompile Include="src\Editor\EditorWidgetComponent\ColorPicker.cpp" />
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.cpp" /> <ClCompile Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.cpp" />
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp" /> <ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp" />
@ -154,6 +155,7 @@
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" /> <ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
<ClCompile Include="src\SvgParser.cpp" /> <ClCompile Include="src\SvgParser.cpp" />
<ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.cpp" /> <ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.cpp" />
<QtUic Include="EditorSettingWidget.ui" />
<QtUic Include="EditorWidget.ui" /> <QtUic Include="EditorWidget.ui" />
<QtUic Include="EditorWidgetItem.ui" /> <QtUic Include="EditorWidgetItem.ui" />
<QtUic Include="MainWindow.ui" /> <QtUic Include="MainWindow.ui" />
@ -197,6 +199,7 @@
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" />
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" />
<QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" /> <QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" />
<QtMoc Include="src\Editor\RightBar\EditorSettingWidget.h" />
<ClInclude Include="src\Editor\util\EncodeUtil.hpp" /> <ClInclude Include="src\Editor\util\EncodeUtil.hpp" />
<ClInclude Include="src\Editor\util\JsonUtil.hpp" /> <ClInclude Include="src\Editor\util\JsonUtil.hpp" />
<ClInclude Include="src\Editor\ElementManager.h" /> <ClInclude Include="src\Editor\ElementManager.h" />

View File

@ -82,6 +82,9 @@
<QtUic Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui"> <QtUic Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.ui">
<Filter>Form Files</Filter> <Filter>Form Files</Filter>
</QtUic> </QtUic>
<QtUic Include="EditorSettingWidget.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Editor\EditorWidgetItem.cpp"> <ClCompile Include="src\Editor\EditorWidgetItem.cpp">
@ -234,6 +237,9 @@
<ClCompile Include="src\Editor\EditorWidgetComponent\ColorPicker.cpp"> <ClCompile Include="src\Editor\EditorWidgetComponent\ColorPicker.cpp">
<Filter>Source Files\Editor</Filter> <Filter>Source Files\Editor</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Editor\RightBar\EditorSettingWidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h"> <QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -281,6 +287,9 @@
<QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h"> <QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h">
<Filter>Header Files\Editor</Filter> <Filter>Header Files\Editor</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="src\Editor\RightBar\EditorSettingWidget.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\data.json" /> <None Include="..\data.json" />

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EditorSettingWidget</class>
<widget class="QWidget" name="EditorSettingWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="backgroundColorButton">
<property name="text">
<string>设置背景颜色</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EditorSettingWidget</class>
<widget class="QWidget" name="EditorSettingWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="backgroundColorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>120</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>设置背景颜色</string>
</property>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QPushButton" name="renameButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>120</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>设置项目名称</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -147,7 +147,7 @@
</size> </size>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>2</number>
</property> </property>
<widget class="InfoDisplayWidget" name="LayerDisplay"> <widget class="InfoDisplayWidget" name="LayerDisplay">
<attribute name="title"> <attribute name="title">
@ -159,6 +159,11 @@
<string>图元池</string> <string>图元池</string>
</attribute> </attribute>
</widget> </widget>
<widget class="EditorSettingWidget" name="EditorSetting">
<attribute name="title">
<string>设置</string>
</attribute>
</widget>
</widget> </widget>
</item> </item>
<item> <item>
@ -229,6 +234,12 @@
<header>ElementPoolWidget.h</header> <header>ElementPoolWidget.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>EditorSettingWidget</class>
<extends>QWidget</extends>
<header location="global">EditorSettingWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>

View File

@ -4,6 +4,11 @@ layout(local_size_x = 8, local_size_y = 8) in;
layout(location = 0) uniform ivec2 pixelOffset; layout(location = 0) uniform ivec2 pixelOffset;
layout(std140, binding = 1) uniform ubo
{
vec3 backgroundColor;
};
layout(rgba8, binding = 0) uniform image2D gBaseColor; layout(rgba8, binding = 0) uniform image2D gBaseColor;
layout(rg8, binding = 1) uniform image2D gMetallicRoughness; layout(rg8, binding = 1) uniform image2D gMetallicRoughness;
@ -1353,7 +1358,7 @@ void main()
vec3 debugBVH = vec3(0); vec3 debugBVH = vec3(0);
// bool debugHit = false; // bool debugHit = false;
//vec4 color = vec4(0.76, 0.33, 0.15, -1); //vec4 color = vec4(0.76, 0.33, 0.15, -1);
vec4 color = vec4(1,1,1, -1); vec4 color = vec4(backgroundColor, -1);
vec2 metallicRoughness = vec2(0, 0.8); vec2 metallicRoughness = vec2(0, 0.8);
stack.top = 0; stack.top = 0;
uint index = 0, visitTime = 0; uint index = 0, visitTime = 0;

View File

@ -47,3 +47,11 @@ EditorWidget::EditorWidget(QWidget* parent) : QWidget(parent)
}); });
} }
void EditorWidget::renameTab(QWidget* target, QString name)
{
int index = this->tabWidget->indexOf(target);
if (index != -1)
{
this->tabWidget->setTabText(index, name);
}
}

View File

@ -18,6 +18,6 @@ private:
public: public:
EditorWidget(QWidget* parent = nullptr); EditorWidget(QWidget* parent = nullptr);
~EditorWidget()=default; ~EditorWidget()=default;
void renameTab(QWidget* target, QString name);
}; };

View File

@ -3,16 +3,14 @@
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QGridLayout> #include <QGridLayout>
#include <QDebug>
#include <unordered_set>
LayerStyleDialog::LayerStyleDialog( LayerStyleDialog::LayerStyleDialog(
QWidget* parent, LayerStyleContainer& styles,
std::shared_ptr<LayerStyle> existedStyle, std::shared_ptr<LayerStyle> existedStyle,
std::vector<std::shared_ptr<LayerStyle>>* excludeStyles QWidget* parent
) : QDialog(parent) ) : QDialog(parent), styles(&styles)
{ {
QVBoxLayout* dialogLayout = new QVBoxLayout(this); auto* dialogLayout = new QVBoxLayout(this);
dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter);
this->setLayout(dialogLayout); this->setLayout(dialogLayout);
@ -28,28 +26,14 @@ LayerStyleDialog::LayerStyleDialog(
} }
else else
{ {
std::unordered_set<QString> excludeStyleNames; QStringList unusedStyleNames = styles.unusedStyleNames();
for(auto &style : *excludeStyles) auto* typeSelector = new QComboBox(this);
{
excludeStyleNames.insert(style->getStyleName());
}
QComboBox* typeSelector = new QComboBox(this); if (!unusedStyleNames.empty())
for (auto& pair : LayerStyle::types)
{ {
if (!excludeStyleNames.contains(pair.first)) typeSelector->addItems(unusedStyleNames);
{ this->modifyingStyle = std::move(styles.makeUnusedStyle(unusedStyleNames[0]));
typeSelector->addItem(pair.first);
if (!this->modifyingStyle)
{
this->modifyingStyle = std::move(pair.second());
}
}
}
if (typeSelector->count() > 0)
{
dialogLayout->addWidget(typeSelector); dialogLayout->addWidget(typeSelector);
this->styleContainer = new QGridLayout(this); this->styleContainer = new QGridLayout(this);
dialogLayout->addLayout(styleContainer); dialogLayout->addLayout(styleContainer);
@ -57,11 +41,11 @@ LayerStyleDialog::LayerStyleDialog(
this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget = this->modifyingStyle->getInputWidget();
this->styleWidget->setParent(this); this->styleWidget->setParent(this);
this->styleContainer->addWidget(styleWidget); this->styleContainer->addWidget(styleWidget);
connect(typeSelector, QOverload<int>::of(&QComboBox::currentIndexChanged), connect(typeSelector, &QComboBox::currentTextChanged,
this, &LayerStyleDialog::onStyleTypeSelectorChanged); this, &LayerStyleDialog::onStyleTypeSelectorChanged);
} }
} }
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept); connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject); connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject);
dialogLayout->addWidget(buttonBox); dialogLayout->addWidget(buttonBox);
@ -73,7 +57,7 @@ void LayerStyleDialog::accept()
QDialog::accept(); QDialog::accept();
} }
void LayerStyleDialog::onStyleTypeSelectorChanged(int index) void LayerStyleDialog::onStyleTypeSelectorChanged(const QString& current)
{ {
if (this->styleWidget) if (this->styleWidget)
{ {
@ -81,8 +65,10 @@ void LayerStyleDialog::onStyleTypeSelectorChanged(int index)
this->styleWidget->setParent(nullptr); this->styleWidget->setParent(nullptr);
delete styleWidget; delete styleWidget;
} }
this->modifyingStyle = std::move(LayerStyle::types[index].second()); this->modifyingStyle = std::move(styles->makeUnusedStyle(current));
this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget = this->modifyingStyle->getInputWidget();
this->styleWidget->setParent(this); this->styleWidget->setParent(this);
this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1); this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1);
this->styleWidget->adjustSize();
this->adjustSize();
} }

View File

@ -9,15 +9,17 @@ class LayerStyleDialog : public QDialog
private: private:
QWidget* styleWidget; QWidget* styleWidget;
QGridLayout* styleContainer; QGridLayout* styleContainer;
LayerStyleContainer* styles;
std::unique_ptr<LayerStyle> modifyingStyle; std::unique_ptr<LayerStyle> modifyingStyle;
public: public:
LayerStyleDialog( LayerStyleDialog(
QWidget* parent = nullptr, LayerStyleContainer& styles,
std::shared_ptr<LayerStyle> existedStyle = nullptr, std::shared_ptr<LayerStyle> existedStyle = nullptr,
std::vector<std::shared_ptr<LayerStyle>>* excludeStyles = nullptr); QWidget* parent = nullptr
);
std::shared_ptr<LayerStyle> layerStyle; std::shared_ptr<LayerStyle> layerStyle;
private slots: private slots:
void onStyleTypeSelectorChanged(int index); void onStyleTypeSelectorChanged(const QString& current);
void accept() override; void accept() override;
}; };

View File

@ -2,8 +2,8 @@
#include "ColorPicker.h" #include "ColorPicker.h"
#include <qtmaterialraisedbutton.h> #include <qtmaterialraisedbutton.h>
#include <limits> #include <limits>
#include <lib/qtmaterialstyle.h>
#define radialStroke(stroke) std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(stroke->materialStroke)
constexpr int COLUMN_WIDTH = 0; constexpr int COLUMN_WIDTH = 0;
constexpr int COLUMN_COLOR = 1; constexpr int COLUMN_COLOR = 1;
constexpr int COLUMN_METALLIC = 2; constexpr int COLUMN_METALLIC = 2;
@ -15,12 +15,12 @@ StrokeStyleWidget::StrokeStyleWidget(
QWidget* parent QWidget* parent
) : QWidget(parent), stroke(stroke) ) : QWidget(parent), stroke(stroke)
{ {
QVBoxLayout* viewLayout = new QVBoxLayout(this); auto* viewLayout = new QVBoxLayout(this);
this->setLayout(viewLayout); this->setLayout(viewLayout);
initStrokeSettings(); initStrokeSettings();
QWidget* strokeProperties = new QWidget(this); auto* strokeProperties = new QWidget(this);
QHBoxLayout* strokePropertiesLayout = new QHBoxLayout(strokeProperties); auto* strokePropertiesLayout = new QHBoxLayout(strokeProperties);
strokePropertiesLayout->setMargin(0); strokePropertiesLayout->setMargin(0);
strokeProperties->setLayout(strokePropertiesLayout); strokeProperties->setLayout(strokePropertiesLayout);
@ -38,7 +38,7 @@ StrokeStyleWidget::StrokeStyleWidget(
void StrokeStyleWidget::initStrokeSettings() void StrokeStyleWidget::initStrokeSettings()
{ {
this->enableGradual = new QtMaterialCheckBox(this); this->enableGradual = new QtMaterialCheckBox(this);
enableGradual->setText(QStringLiteral("ÆôÓý¥±ä")); enableGradual->setText(QStringLiteral("½¥±ä"));
enableGradual->setChecked(radialStroke(stroke)->gradual); enableGradual->setChecked(radialStroke(stroke)->gradual);
connect(enableGradual, &QtMaterialCheckBox::toggled, [this](bool checked) { connect(enableGradual, &QtMaterialCheckBox::toggled, [this](bool checked) {
radialStroke(this->stroke)->gradual = checked; radialStroke(this->stroke)->gradual = checked;
@ -72,7 +72,7 @@ void StrokeStyleWidget::initStrokeSettings()
this->widthField = new QtMaterialTextField(this); this->widthField = new QtMaterialTextField(this);
widthField->setLabel(QStringLiteral("±¾²àÃè±ß¿í¶È")); widthField->setLabel(QStringLiteral("±¾²àÃè±ß¿í¶È"));
widthField->setText(QString::number(stroke->halfWidth)); widthField->setText(QString::number(stroke->halfWidth));
QDoubleValidator* widthValidator = new QDoubleValidator(0.1, std::numeric_limits<float>::max(), 3, widthField); auto* widthValidator = new QDoubleValidator(0.1, std::numeric_limits<float>::max(), 3, widthField);
widthValidator->setNotation(QDoubleValidator::StandardNotation); widthValidator->setNotation(QDoubleValidator::StandardNotation);
widthField->setValidator(widthValidator); widthField->setValidator(widthValidator);
connect(widthField, &QtMaterialTextField::textChanged, [this](const QString& changed) { connect(widthField, &QtMaterialTextField::textChanged, [this](const QString& changed) {
@ -106,8 +106,12 @@ void StrokeStyleWidget::initTable(std::shared_ptr<Renderer::StrokeRadialGradient
} }
// ÐÂÔö°´Å¥ // ÐÂÔö°´Å¥
QtMaterialRaisedButton* addButton = new QtMaterialRaisedButton("+", strokeTable); QtMaterialRaisedButton* addButton = new QtMaterialRaisedButton("+", strokeTable);
addButton->setBackgroundColor(QtMaterialStyle::instance().themeColor("primary1"));
strokeTable->setSpan(row, 0, 1, 5); strokeTable->setSpan(row, 0, 1, 5);
strokeTable->setCellWidget(row, 0, addButton); strokeTable->setCellWidget(row, 0, addButton);
strokeTable->setMinimumHeight(strokeTable->rowHeight(row) * 5);
strokeTable->setMinimumWidth(strokeTable->sizeHint().width());
addButton->setFixedHeight(strokeTable->rowHeight(row));
connect(addButton, &QtMaterialRaisedButton::clicked, [this]() { connect(addButton, &QtMaterialRaisedButton::clicked, [this]() {
handlingRowInsert = true; handlingRowInsert = true;
auto materialMap = &(radialStroke(this->stroke)->materialMap); auto materialMap = &(radialStroke(this->stroke)->materialMap);
@ -129,37 +133,37 @@ void StrokeStyleWidget::initTable(std::shared_ptr<Renderer::StrokeRadialGradient
this->strokeTable->update(); this->strokeTable->update();
handlingRowInsert = false; handlingRowInsert = false;
}); });
connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged); connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged);
connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged); connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged);
} }
void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& material) void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& material)
{ {
QTableWidgetItem* widthItem = new QTableWidgetItem; auto* widthItem = new QTableWidgetItem;
widthItem->setData(Qt::EditRole, width); widthItem->setData(Qt::EditRole, width);
strokeTable->setItem(row, COLUMN_WIDTH, widthItem); strokeTable->setItem(row, COLUMN_WIDTH, widthItem);
QColor* colorPtr = &(material.color); QColor* colorPtr = &(material.color);
QTableWidgetItem* colorItem = new QTableWidgetItem; auto* colorItem = new QTableWidgetItem;
colorItem->setData(Qt::DisplayRole, *colorPtr); colorItem->setData(Qt::DisplayRole, *colorPtr);
strokeTable->setItem(row, COLUMN_COLOR, colorItem); strokeTable->setItem(row, COLUMN_COLOR, colorItem);
ColorPicker* colorPicker = new ColorPicker(*colorPtr, strokeTable); auto* colorPicker = new ColorPicker(*colorPtr, strokeTable);
strokeTable->setCellWidget(row, COLUMN_COLOR, colorPicker); strokeTable->setCellWidget(row, COLUMN_COLOR, colorPicker);
connect(colorPicker, &ColorPicker::colorChanged, [this, colorPtr](QColor color) { connect(colorPicker, &ColorPicker::colorChanged, [this, colorPtr](QColor color) {
*colorPtr = color; *colorPtr = color;
this->strokeTable->update(); this->strokeTable->update();
}); });
QTableWidgetItem* metallicItem = new QTableWidgetItem; auto* metallicItem = new QTableWidgetItem;
metallicItem->setData(Qt::EditRole, material.metallicF()); metallicItem->setData(Qt::EditRole, material.metallicF());
strokeTable->setItem(row, COLUMN_METALLIC, metallicItem); strokeTable->setItem(row, COLUMN_METALLIC, metallicItem);
QTableWidgetItem* roughnessItem = new QTableWidgetItem; auto* roughnessItem = new QTableWidgetItem;
roughnessItem->setData(Qt::EditRole, material.roughnessF()); roughnessItem->setData(Qt::EditRole, material.roughnessF());
strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem); strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem);
QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable); auto* removeButton = new QtMaterialRaisedButton("-", strokeTable);
removeButton->setBackgroundColor(QtMaterialStyle::instance().themeColor("primary1"));
removeButton->setFixedSize(20, 20); removeButton->setFixedSize(20, 20);
strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton); strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton);
connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() { connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() {

View File

@ -1,8 +1,11 @@
#include "EditorWidgetItem.h" #include "EditorWidgetItem.h"
#include "EditorWidget.h"
#include <QTimer>
EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(parent) EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(parent)
{ {
QImage x; QImage x;
this->parent = parent;
displayLayer = nullptr; displayLayer = nullptr;
displayElement = nullptr; displayElement = nullptr;
ui.setupUi(this); ui.setupUi(this);
@ -12,9 +15,12 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
this->filePath = filePath; this->filePath = filePath;
layerInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(0)); layerInfoDisplayWidget = dynamic_cast<InfoDisplayWidget *>(tabWidget->widget(0));
elementInfoDisplayWidget = dynamic_cast<ElementPoolWidget *>(tabWidget->widget(1)); elementInfoDisplayWidget = dynamic_cast<ElementPoolWidget *>(tabWidget->widget(1));
editorSettingWidget = dynamic_cast<EditorSettingWidget*>(tabWidget->widget(2));
elementInfoDisplayWidget->enableEdit(); elementInfoDisplayWidget->enableEdit();
qDebug() << layerInfoDisplayWidget; qDebug() << layerInfoDisplayWidget;
qDebug() << elementInfoDisplayWidget; qDebug() << elementInfoDisplayWidget;
connect(editorSettingWidget, &EditorSettingWidget::backgroundColorChanged, this, &EditorWidgetItem::handleBackgroundColorChange);
connect(editorSettingWidget, &EditorSettingWidget::projectNameChanged, this, &EditorWidgetItem::handleProjectNameChange);
connect(previewWindow, &PreviewWindow::refreshElementPreviewByIndex, elementInfoDisplayWidget, &ElementPoolWidget::refreshPictureByIndex); connect(previewWindow, &PreviewWindow::refreshElementPreviewByIndex, elementInfoDisplayWidget, &ElementPoolWidget::refreshPictureByIndex);
connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh); connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh);
connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged); connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged);
@ -53,6 +59,15 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
treeWidget->refresh(); treeWidget->refresh();
treeWidget->addTopLevelItem(treeWidget->root->getQTreeItem()); treeWidget->addTopLevelItem(treeWidget->root->getQTreeItem());
} }
this->backgroundColor = source.value("background-color").toVariant().value<QColor>();
this->projectName = source.value("project-name").toString();
qDebug() << this->backgroundColor;
qDebug() << this->projectName;
QTimer::singleShot(300, this, [this]() {
handleBackgroundColorChange(this->backgroundColor);
handleProjectNameChange(this->projectName);
});
} }
EditorWidgetItem::~EditorWidgetItem() EditorWidgetItem::~EditorWidgetItem()
@ -100,9 +115,28 @@ void EditorWidgetItem::saveImpl(QString filePath) const
json.insert("height", 1080); json.insert("height", 1080);
json.insert("root-layer", source1.value("root-layer")); json.insert("root-layer", source1.value("root-layer"));
json.insert("elements", source2.value("elements")); json.insert("elements", source2.value("elements"));
json.insert("project-name", this->projectName);
json.insert("background-color", QJsonValue::fromVariant(QVariant::fromValue(this->backgroundColor)));
QJsonDocument doc(json); QJsonDocument doc(json);
QFile file(filePath); QFile file(filePath);
file.open(QIODevice::WriteOnly); file.open(QIODevice::WriteOnly);
file.write(doc.toJson()); file.write(doc.toJson());
file.close(); file.close();
} }
void EditorWidgetItem::handleBackgroundColorChange(QColor color)
{
this->backgroundColor = color;
previewWindow->setBackgroundColor(color);
}
void EditorWidgetItem::handleProjectNameChange(QString name)
{
this->projectName = name;
auto parent = dynamic_cast<EditorWidget*>(this->parent);
qDebug() << name << " " << parent<<" "<<this;
if (parent != nullptr)
{
parent->renameTab(this, name);
}
}

View File

@ -6,6 +6,7 @@
#include "LayerManager.h" #include "LayerManager.h"
#include "LayerTreeWidget.h" #include "LayerTreeWidget.h"
#include "PreviewWindow.h" #include "PreviewWindow.h"
#include "EditorSettingWidget.h"
#include "ui_EditorWidgetItem.h" #include "ui_EditorWidgetItem.h"
#include <QPainter> #include <QPainter>
#include <QTreeWidget> #include <QTreeWidget>
@ -26,11 +27,17 @@ class EditorWidgetItem : public QWidget
QTabWidget *tabWidget; QTabWidget *tabWidget;
InfoDisplayWidget* layerInfoDisplayWidget; InfoDisplayWidget* layerInfoDisplayWidget;
ElementPoolWidget* elementInfoDisplayWidget; ElementPoolWidget* elementInfoDisplayWidget;
EditorSettingWidget* editorSettingWidget;
// QT DATA PART // QT DATA PART
LayerWrapper *displayLayer; LayerWrapper *displayLayer;
GraphicElement *displayElement; GraphicElement *displayElement;
QString filePath; QWidget* parent;
void saveImpl(QString filePath)const; void saveImpl(QString filePath)const;
public:
// PROJECT INFO
QString filePath;
QString projectName;
QColor backgroundColor;
public: public:
EditorWidgetItem(QString filePath, QWidget *parent = nullptr); EditorWidgetItem(QString filePath, QWidget *parent = nullptr);
@ -38,6 +45,8 @@ class EditorWidgetItem : public QWidget
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void save() const; void save() const;
void saveAs(QString filePath)const; void saveAs(QString filePath)const;
void handleBackgroundColorChange(QColor color);
void handleProjectNameChange(QString name);
private slots: private slots:
void onLayerChange(LayerWrapper *layer); void onLayerChange(LayerWrapper *layer);

View File

@ -48,11 +48,11 @@ PixelPath GroupElement::getPaintObject() const
} }
//TODO: apply styles and send back //TODO: apply styles and send back
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const { PixelPath SimpleElement::getPaintObject(const LayerStyleContainer& styles) const {
return this->getPaintObject(); return this->getPaintObject();
} }
PixelPath GroupElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const { PixelPath GroupElement::getPaintObject(const LayerStyleContainer& styles) const {
return getPaintObject(); return getPaintObject();
} }
@ -92,7 +92,7 @@ QJsonObject GroupElement::toJson() const
return result; return result;
} }
void SimpleElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles) void SimpleElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles)
{ {
painter->save(); painter->save();
painter->setTransform(transform); painter->setTransform(transform);
@ -102,14 +102,14 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector<
} }
else else
{ {
Renderer::ElementStyleStrokeDemo demo(2); double angle = atan(transform.m12() / transform.m11());
std::shared_ptr<Renderer::ElementStyle> style; double maxScale;
style = styles[0]; if (fabs(cos(angle))>1e-5)
QVector2D scale(transform.m11(), transform.m22()); maxScale = std::max(fabs(transform.m11() / cos(angle)), fabs(transform.m22() / cos(angle)));
scale /= transform.m33(); else
double maxScale = std::max(scale.x(), scale.y()); maxScale = std::max(fabs(transform.m12() / sin(angle)), fabs(transform.m21() / sin(angle)));
double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio(); double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio();
auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, *style, pixelRatio); auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, styles, pixelRatio);
transform.translate(mov.x(), mov.y()); transform.translate(mov.x(), mov.y());
painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio)); painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio));
painter->drawImage(0, 0, img); painter->drawImage(0, 0, img);
@ -117,7 +117,7 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector<
painter->restore(); painter->restore();
} }
void GroupElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles) void GroupElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles)
{ {
sourceLayer->paint(painter, transform); sourceLayer->paint(painter, transform);
} }
@ -125,7 +125,7 @@ void GroupElement::paint(QPainter* painter, QTransform transform, const vector<s
QPixmap SimpleElement::getPreview(QSize size) QPixmap SimpleElement::getPreview(QSize size)
{ {
QPixmap result(size + QSize(5,5)); QPixmap result(size + QSize(5, 5));
QPainter painter(&result); QPainter painter(&result);
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setRenderHint(QPainter::SmoothPixmapTransform);
@ -143,7 +143,7 @@ QPixmap GroupElement::getPreview(QSize size)
painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setRenderHint(QPainter::SmoothPixmapTransform);
sourceLayer->paint(&painter, QTransform(), true); sourceLayer->paint(&painter, QTransform(), true);
painter.end(); painter.end();
QRect rect (cache.getBoundingRect().toRect()); QRect rect(cache.getBoundingRect().toRect());
rect.setTopLeft(rect.topLeft() - QPoint(5, 5)); rect.setTopLeft(rect.topLeft() - QPoint(5, 5));
rect.setBottomRight(rect.bottomRight() + QPoint(5, 5)); rect.setBottomRight(rect.bottomRight() + QPoint(5, 5));
result = result.copy(rect); result = result.copy(rect);

View File

@ -2,7 +2,6 @@
#include "LayerWrapper.h" #include "LayerWrapper.h"
#include "LayerStyle.h" #include "LayerStyle.h"
#include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QPainterPath> #include <QPainterPath>
#include <QImage> #include <QImage>
@ -27,8 +26,8 @@ public:
// TODO: ¸ÄΪBitmapPath // TODO: ¸ÄΪBitmapPath
virtual QJsonObject toJson() const = 0; virtual QJsonObject toJson() const = 0;
virtual PixelPath getPaintObject() const = 0; virtual PixelPath getPaintObject() const = 0;
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0; virtual PixelPath getPaintObject(const LayerStyleContainer& styles) const = 0;
virtual void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) = 0; virtual void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) = 0;
virtual QPixmap getPreview(QSize size) = 0; virtual QPixmap getPreview(QSize size) = 0;
}; };
@ -47,8 +46,8 @@ public:
SimpleElement(QString filePath); SimpleElement(QString filePath);
~SimpleElement() = default; ~SimpleElement() = default;
PixelPath getPaintObject() const override; PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override; PixelPath getPaintObject(const LayerStyleContainer& styles) const override;
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override; void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override;
QPixmap getPreview(QSize size) override; QPixmap getPreview(QSize size) override;
}; };
@ -63,9 +62,9 @@ public:
GroupElement(FolderLayerWrapper* mSourceLayer); GroupElement(FolderLayerWrapper* mSourceLayer);
~GroupElement() = default; ~GroupElement() = default;
PixelPath getPaintObject() const override; PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override; PixelPath getPaintObject(const LayerStyleContainer& styles) const override;
void setSourceLayer(FolderLayerWrapper* sourceLayer); void setSourceLayer(FolderLayerWrapper* sourceLayer);
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override; void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override;
QPixmap getPreview(QSize size) override; QPixmap getPreview(QSize size) override;
}; };

View File

@ -9,31 +9,29 @@
#include <QLineEdit> #include <QLineEdit>
#include <QObject> #include <QObject>
#include <QDebug> #include <QDebug>
#define _USE_JOIN_VIEW_INPUT_RANGE
const std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> LayerStyle::types = { #include <QJsonArray>
{ #include <ranges>
QStringLiteral("描边"),
[]() { return std::make_unique<StrokeElementLayerStyle>(); }
},
{
QStringLiteral("填充"),
[]() { return std::make_unique<FillElementLayerStyle>(); }
}
};
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)
{ {
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), if (!radialStroke(strokePair.first)->materialMap.empty())
strokePair.first)); {
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(),
strokePair.second)); strokePair.first));
}
if (!radialStroke(strokePair.second)->materialMap.empty())
{
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(),
strokePair.second));
}
} }
else else if (!radialStroke(strokePair.first)->materialMap.empty())
{ {
auto material = std::shared_ptr<MaterialStyle>(std::move(strokePair.first->clone())); const auto material = std::shared_ptr(std::move(strokePair.first->clone()));
std::dynamic_pointer_cast<MaterialStyleStroke>(material)->strokeType = Renderer::StrokeType::kBothSides; std::dynamic_pointer_cast<MaterialStyleStroke>(material)->strokeType = Renderer::StrokeType::kBothSides;
baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), material)); baseStyles.push_back(Renderer::BaseStyle(std::make_shared<Renderer::TransformStyle>(), material));
@ -41,50 +39,23 @@ std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
return baseStyles; return baseStyles;
} }
QString StrokeElementLayerStyle::getStyleName() const
{
return QStringLiteral("描边");
}
QWidget* StrokeElementLayerStyle::getInputWidget() QWidget* StrokeElementLayerStyle::getInputWidget()
{ {
if (this->strokePair.first == nullptr) auto* w = new QWidget;
{ auto* materialList = new QListView;
auto materialMap = std::map<float, Renderer::Material>();
this->strokePair.first = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
15,
Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat,
std::shared_ptr<Renderer::MaterialStroke>(new Renderer::StrokeRadialGradient(
materialMap, false
))
));
}
if (this->strokePair.second == nullptr)
{
auto materialMap = std::map<float, Renderer::Material>();
this->strokePair.second = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
15,
Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat,
std::shared_ptr<Renderer::MaterialStroke>(new Renderer::StrokeRadialGradient(
materialMap, false
))
));
}
QWidget* w = new QWidget;
QListView* materialList = new QListView;
QVBoxLayout* layout = new QVBoxLayout(w); auto* layout = new QVBoxLayout(w);
layout->setMargin(0); layout->setMargin(0);
StrokeStyleWidget* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w); auto* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w);
layout->addWidget(leftStrokeView); layout->addWidget(leftStrokeView);
QtMaterialCheckBox* checkEachSideIndependent = new QtMaterialCheckBox(w); auto* checkEachSideIndependent = new QtMaterialCheckBox(w);
checkEachSideIndependent->setText(QStringLiteral("启用两侧独立描边")); checkEachSideIndependent->setText(QStringLiteral("ÓÒ²à¶ÀÁ¢Ãè±ß"));
checkEachSideIndependent->setChecked(enableEachSideIndependent); checkEachSideIndependent->setChecked(enableEachSideIndependent);
layout->addWidget(checkEachSideIndependent); layout->addWidget(checkEachSideIndependent);
StrokeStyleWidget* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w); auto* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w);
layout->addWidget(rightStrokeView); layout->addWidget(rightStrokeView);
rightStrokeView->setDisabled(!this->enableEachSideIndependent); rightStrokeView->setDisabled(!this->enableEachSideIndependent);
@ -97,39 +68,180 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
QWidget* StrokeElementLayerStyle::getListDisplayWidget() const QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
{ {
QWidget* w = new QWidget; auto* w = new QWidget;
QLabel* name = new QLabel(w); auto* name = new QLabel(w);
name->setText(QStringLiteral("Ãè±ß")); name->setText(QStringLiteral("Ãè±ß"));
QHBoxLayout* 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()
{
hash = 0;
for (auto& f : styles
| std::views::values
| std::views::transform(&LayerStyle::toBaseStyles)
| std::views::join
| std::views::transform(&Renderer::BaseStyle::material)
| std::views::transform(&MaterialStyle::encoded)
| std::views::join)
{
const unsigned int u = *reinterpret_cast<unsigned int*>(&f);
hash ^= u + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
}
LayerStyleContainer LayerStyleContainer::fromJson(const QJsonArray& jsonArray)
{
LayerStyleContainer container;
for (const auto& style : jsonArray)
{
container.useStyle(LayerStyle::fromJson(style.toObject()));
}
return container;
}
LayerStyleContainer::LayerStyleContainer() : hash(0)
{
unusedStyles = { {
StrokeElementLayerStyle::displayName(),
[] { return std::make_unique<StrokeElementLayerStyle>(); }
},
{
FillElementLayerStyle::displayName(),
[] { return std::make_unique<FillElementLayerStyle>(); }
} };
}
std::vector<Renderer::BaseStyle> LayerStyleContainer::toBaseStyles() const
{
std::vector<Renderer::BaseStyle> result;
for (const auto& style : styles | std::views::values)
{
auto baseStyles = style->toBaseStyles();
result.insert(result.end(),
std::make_move_iterator(baseStyles.begin()),
std::make_move_iterator(baseStyles.end()));
}
return result;
}
QJsonArray LayerStyleContainer::toJson() const
{
QJsonArray json;
for (const auto& style : styles | std::views::values)
{
json.append(style->toJson());
}
return json;
}
QStringList LayerStyleContainer::unusedStyleNames() const
{
QStringList result;
for(const auto& name : unusedStyles | std::views::keys)
{
result << name;
}
return result;
}
std::unique_ptr<LayerStyle> LayerStyleContainer::makeUnusedStyle(const QString& styleName) const
{
return unusedStyles.at(styleName)();
}
bool LayerStyleContainer::empty() const
{
return styles.empty();
}
bool LayerStyleContainer::full() const
{
return unusedStyles.empty();
}
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::begin()
{
return styles.begin();
}
std::map<QString, std::shared_ptr<LayerStyle>>::iterator LayerStyleContainer::end()
{
return styles.end();
}
bool LayerStyleContainer::useStyle(const std::shared_ptr<LayerStyle>& style)
{
auto styleNode = unusedStyles.extract(style->getDisplayName());
if (styleNode.empty())
{
return false;
}
styles[styleNode.key()] = style;
usedStyles.insert(std::move(styleNode));
return true;
}
bool LayerStyleContainer::dropStyle(const QString& styleName)
{
auto styleNode = usedStyles.extract(styleName);
if (styleNode.empty())
{
return false;
}
styles.erase(styleName);
unusedStyles.insert(std::move(styleNode));
return true;
}
inline size_t LayerStyleContainer::getHash() const
{
return hash;
}
StrokeElementLayerStyle::StrokeElementLayerStyle()
{
const auto materialMap = std::map<float, Renderer::Material>();
this->strokePair.first = std::make_shared<MaterialStyleStroke>(
7,
Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat,
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
);
this->strokePair.second = std::make_shared<MaterialStyleStroke>(
7,
Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat,
std::make_shared<Renderer::StrokeRadialGradient>(materialMap, false)
);
}
StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right) StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right)
{ {
this->strokePair.first = left; this->strokePair.first = left;
this->strokePair.second = right ? right : std::dynamic_pointer_cast<MaterialStyleStroke>( this->strokePair.second = right ? right : std::static_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(left->clone())) std::shared_ptr(std::move(left->clone()))
); );
} }
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
{ {
strokePair.first = std::dynamic_pointer_cast<MaterialStyleStroke>( strokePair.first = std::static_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(other.strokePair.first->clone())) std::shared_ptr(std::move(other.strokePair.first->clone()))
); );
strokePair.second = std::dynamic_pointer_cast<MaterialStyleStroke>( strokePair.second = std::static_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(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
{ {
// todo: 修改打开逻辑
QJsonObject json; QJsonObject json;
json["type"] = getTypeName(); json["type"] = typeName();
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());
@ -143,28 +255,24 @@ std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clone() const
std::vector<Renderer::BaseStyle> FillElementLayerStyle::toBaseStyles() const std::vector<Renderer::BaseStyle> FillElementLayerStyle::toBaseStyles() const
{ {
// TODO: implement
return std::vector<Renderer::BaseStyle>(); return std::vector<Renderer::BaseStyle>();
} }
QString FillElementLayerStyle::getStyleName() const
{
return QStringLiteral("填充");
}
QWidget* FillElementLayerStyle::getInputWidget() QWidget* FillElementLayerStyle::getInputWidget()
{ {
// TODO // TODO
QLineEdit* name = new QLineEdit; auto* name = new QLineEdit;
name->setText(QStringLiteral("Ìî³ä")); name->setText(QStringLiteral("Ìî³ä"));
return name; return name;
} }
QWidget* FillElementLayerStyle::getListDisplayWidget() const QWidget* FillElementLayerStyle::getListDisplayWidget() const
{ {
QWidget* w = new QWidget; auto* w = new QWidget;
QLabel* name = new QLabel(w); auto* name = new QLabel(w);
name->setText(QStringLiteral("Ìî³ä")); name->setText(QStringLiteral("Ìî³ä"));
QHBoxLayout* 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;
@ -192,20 +300,20 @@ std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json) std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
{ {
QString type = json["type"].toString(); QString type = json["type"].toString();
if (type == StrokeElementLayerStyle::getTypeName()) if (type == StrokeElementLayerStyle::typeName())
{ {
auto ptr = std::make_unique<StrokeElementLayerStyle>( auto ptr = std::make_unique<StrokeElementLayerStyle>(
std::dynamic_pointer_cast<MaterialStyleStroke>( std::static_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString())))) std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString()))))
), ),
std::dynamic_pointer_cast<MaterialStyleStroke>( std::static_pointer_cast<MaterialStyleStroke>(
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::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;
} }
else if (type == FillElementLayerStyle::getTypeName()) else if (type == FillElementLayerStyle::typeName())
{ {
return std::make_unique<FillElementLayerStyle>(); return std::make_unique<FillElementLayerStyle>();
} }

View File

@ -1,11 +1,11 @@
#pragma once #pragma once
#include <map>
#include <functional> #include <functional>
#include <utility> #include <utility>
#include <QWidget> #include <set>
#include <QObject> #include <map>
#include <QListWidget> #include <QListWidget>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray>
#include "../Renderer/Painting/ElementStyle.h" #include "../Renderer/Painting/ElementStyle.h"
#include "../Renderer/Painting/MaterialStyleStroke.h" #include "../Renderer/Painting/MaterialStyleStroke.h"
#include "../Renderer/Painting/MaterialStyleFill.h" #include "../Renderer/Painting/MaterialStyleFill.h"
@ -13,64 +13,90 @@
using Renderer::MaterialStyle; using Renderer::MaterialStyle;
using Renderer::MaterialStyleStroke; using Renderer::MaterialStyleStroke;
#define STYLE_TYPENAME(name) static QString getTypeName() { return name; } #define STYLE_NAME(display_name, type_name) \
static QString displayName() { return QStringLiteral(display_name); } \
QString getDisplayName() const override { return QStringLiteral(display_name); } \
static QString typeName() { return type_name; }
#define radialStroke(stroke) std::static_pointer_cast<Renderer::StrokeRadialGradient>(stroke->materialStroke)
/**
* StylegetInputWidget()
* StylegetInputWidget()
*
* LayerStyleElementStylestyle
*
*/
class LayerStyle : public Renderer::ElementStyle class LayerStyle : public Renderer::ElementStyle
{ {
public: public:
const static std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> types;
static std::unique_ptr<LayerStyle> fromJson(const QJsonObject& json); static std::unique_ptr<LayerStyle> fromJson(const QJsonObject& json);
virtual QString getStyleName() const = 0; virtual QString getDisplayName() const = 0;
virtual QWidget* getInputWidget() = 0; virtual QWidget* getInputWidget() = 0;
virtual QWidget* getListDisplayWidget() const = 0; virtual QWidget* getListDisplayWidget() const = 0;
virtual ~LayerStyle() {}; virtual ~LayerStyle() = default;
virtual QJsonObject toJson() const = 0; virtual QJsonObject toJson() const = 0;
virtual std::unique_ptr<LayerStyle> clone() const = 0; virtual std::unique_ptr<LayerStyle> clone() const = 0;
}; };
class LayerStyleContainer : public Renderer::ElementStyle
{
using DisplayNameWithSupplier = std::map<QString, std::function<std::unique_ptr<LayerStyle>()>>;
private:
DisplayNameWithSupplier unusedStyles;
DisplayNameWithSupplier usedStyles;
std::map<QString, std::shared_ptr<LayerStyle>> styles;
size_t hash;
public:
static LayerStyleContainer fromJson(const QJsonArray& jsonArray);
LayerStyleContainer();
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QJsonArray toJson() const;
bool empty() const;
bool full() const;
std::map<QString, std::shared_ptr<LayerStyle>>::iterator begin();
std::map<QString, std::shared_ptr<LayerStyle>>::iterator end();
QStringList unusedStyleNames() const;
std::unique_ptr<LayerStyle> makeUnusedStyle(const QString& styleName) const;
bool useStyle(const std::shared_ptr<LayerStyle>& style);
bool dropStyle(const QString& styleName);
size_t getHash() const;
/**
*
*/
void computeNewHash();
};
class StrokeElementLayerStyle : public LayerStyle class StrokeElementLayerStyle : public LayerStyle
{ {
using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>; using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>;
private:
std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
public: public:
STYLE_TYPENAME("stroke") STYLE_NAME("描边","stroke")
StrokeElementLayerStyle() = default; StrokeElementLayerStyle();
StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr); StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr);
StrokeElementLayerStyle(const StrokeElementLayerStyle& other); StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
~StrokeElementLayerStyle() = default; ~StrokeElementLayerStyle() override = default;
std::vector<Renderer::BaseStyle> toBaseStyles() const override; std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QString getStyleName() 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; std::unique_ptr<LayerStyle> clone() const override;
std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
bool enableEachSideIndependent = false; bool enableEachSideIndependent = false;
}; };
class FillElementLayerStyle : public LayerStyle class FillElementLayerStyle : public LayerStyle
{ {
public: public:
STYLE_TYPENAME("fill") STYLE_NAME("填充","fill")
std::vector<Renderer::BaseStyle> toBaseStyles() const override; std::vector<Renderer::BaseStyle> toBaseStyles() const override;
QString getStyleName() const override;
QWidget* getInputWidget() override; QWidget* getInputWidget() override;
QWidget* getListDisplayWidget() const override; QWidget* getListDisplayWidget() const override;
FillElementLayerStyle() = default; FillElementLayerStyle() = default;
FillElementLayerStyle(const FillElementLayerStyle& other); FillElementLayerStyle(const FillElementLayerStyle& other);
~FillElementLayerStyle() = default; ~FillElementLayerStyle() override = default;
std::vector<std::shared_ptr<Renderer::MaterialStyleFill>> materialStyles; std::vector<std::shared_ptr<Renderer::MaterialStyleFill>> materialStyles;
QJsonObject toJson() const override; QJsonObject toJson() const override;
std::unique_ptr<LayerStyle> clone() const override; std::unique_ptr<LayerStyle> clone() const override;

View File

@ -80,10 +80,7 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
int elementIndex = json.value("element").toInt(); int elementIndex = json.value("element").toInt();
wrappedElement = elementManager->getElementById(elementIndex); wrappedElement = elementManager->getElementById(elementIndex);
QJsonArray stylesArray = json.value("styles").toArray(); QJsonArray stylesArray = json.value("styles").toArray();
for (const auto& style : stylesArray) styles = LayerStyleContainer::fromJson(stylesArray);
{
styles.push_back(LayerStyle::fromJson(style.toObject()));
}
} }
void LayerWrapper::SimpleProperty::apply(PixelPath&cache) void LayerWrapper::SimpleProperty::apply(PixelPath&cache)
@ -135,7 +132,7 @@ void LeafLayerWrapper::refresh(LayerWrapper* layer)
cache.clear(); cache.clear();
if (wrappedElement != nullptr) if (wrappedElement != nullptr)
{ {
cache.addPath(wrappedElement->getPaintObject(&(this->styles))); cache.addPath(wrappedElement->getPaintObject(this->styles));
} }
LayerWrapper::refresh(); LayerWrapper::refresh();
} }
@ -245,10 +242,7 @@ QJsonObject LeafLayerWrapper::toJson() const
QJsonObject json = LayerWrapper::toJson(); QJsonObject json = LayerWrapper::toJson();
json.insert("element", wrappedElement->index); json.insert("element", wrappedElement->index);
json.insert("is-folder", false); json.insert("is-folder", false);
QJsonArray stylesJson; json.insert("styles", styles.toJson());
for (auto& style : styles)
stylesJson.push_back(style->toJson());
json.insert("styles", stylesJson);
return json; return json;
} }

View File

@ -98,8 +98,7 @@ class LeafLayerWrapper : public LayerWrapper
{ {
public: public:
GraphicElement *wrappedElement; GraphicElement *wrappedElement;
//const vector<Renderer::ElementStyleStrokeDemo> styles; LayerStyleContainer styles;
vector<std::shared_ptr<LayerStyle>> styles;
public: public:
~LeafLayerWrapper() = default; ~LeafLayerWrapper() = default;

View File

@ -13,6 +13,7 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
painter->setRenderHint(QPainter::HighQualityAntialiasing); painter->setRenderHint(QPainter::HighQualityAntialiasing);
layerManager = nullptr; layerManager = nullptr;
currentLayer = nullptr; currentLayer = nullptr;
backgroundColor = QColor(255, 255, 255, 255);
} }
void PreviewWindow::initialize(LayerManager *layerManager,QSize windowSize) void PreviewWindow::initialize(LayerManager *layerManager,QSize windowSize)
@ -44,7 +45,7 @@ void PreviewWindow::initializeGL()
void PreviewWindow::paintGL() void PreviewWindow::paintGL()
{ {
glClearColor(1.0, 1.0, 1.0, 1.0); glClearColor(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF(), backgroundColor.alphaF());
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
painter->begin(this); painter->begin(this);
painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing);
@ -113,3 +114,9 @@ void PreviewWindow::mouseReleaseEvent(QMouseEvent* event)
{ {
emit layerInfoChanged(); emit layerInfoChanged();
} }
void PreviewWindow::setBackgroundColor(QColor color)
{
this->backgroundColor = color;
this->repaint();
}

View File

@ -23,6 +23,7 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
QRectF viewportRect; QRectF viewportRect;
LayerWrapper* currentLayer; LayerWrapper* currentLayer;
QPointF m_lastPos; QPointF m_lastPos;
QColor backgroundColor;
void mousePressEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override;
void mouseMoveEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
@ -35,6 +36,7 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
void paintGL() override; void paintGL() override;
void resizeGL(int w, int h) override; void resizeGL(int w, int h) override;
Renderer::ElementRenderer* const getRenderer()const; Renderer::ElementRenderer* const getRenderer()const;
void setBackgroundColor(QColor color);
public slots: public slots:
void currentLayerChanged(LayerWrapper*); void currentLayerChanged(LayerWrapper*);

View File

@ -0,0 +1,21 @@
#include "EditorSettingWidget.h"
#include <QPushButton>
#include <QColorDialog>
#include <QInputDialog>
EditorSettingWidget::EditorSettingWidget(QWidget* parent)
: QWidget(parent)
{
ui.setupUi(this);
connect(ui.backgroundColorButton, &QPushButton::clicked, this, [this]() {
QColor color = QColorDialog::getColor(Qt::white, this, QString::fromLocal8Bit("选择背景颜色"));
if (color.isValid())
{
emit backgroundColorChanged(color);
}
});
connect(ui.renameButton, &QPushButton::clicked, this, [this]() {
QString name = QInputDialog::getText(this, QString::fromLocal8Bit("重命名"), QString::fromLocal8Bit("请输入新的项目名称"));
emit projectNameChanged(name);
});
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <qwidget.h>
#include "ui_EditorSettingWidget.h"
class EditorSettingWidget :
public QWidget
{
Q_OBJECT;
private:
Ui::EditorSettingWidget ui;
public:
EditorSettingWidget(QWidget* parent = nullptr);
signals:
void backgroundColorChanged(QColor);
void projectNameChanged(QString);
};

View File

@ -5,7 +5,6 @@
#include <QListWidget> #include <QListWidget>
#include <QDialog> #include <QDialog>
#include <QComboBox> #include <QComboBox>
#include <QDialogButtonBox>
#include <qtmaterialraisedbutton.h> #include <qtmaterialraisedbutton.h>
#include <qtmaterialflatbutton.h> #include <qtmaterialflatbutton.h>
@ -82,38 +81,39 @@ void InfoDisplayWidget::generateLayerForm()
layout->addRow("scale-Y:", scaleY); layout->addRow("scale-Y:", scaleY);
layout->setRowWrapPolicy(QFormLayout::DontWrapRows); layout->setRowWrapPolicy(QFormLayout::DontWrapRows);
LeafLayerWrapper* leafP = dynamic_cast<LeafLayerWrapper*>(this->displayLayer); if (auto* leafP = dynamic_cast<LeafLayerWrapper*>(this->displayLayer); leafP) {
if (leafP) { auto* styleList = new QListWidget(this);
QListWidget* styleList = new QListWidget(this);
QListWidgetItem* header = new QListWidgetItem; auto* header = new QListWidgetItem;
QWidget* headerWidget = new QWidget(styleList); auto* headerWidget = new QWidget(styleList);
QHBoxLayout* headerLayout = new QHBoxLayout; auto* headerLayout = new QHBoxLayout;
QLabel* headerLabel = new QLabel(headerWidget); auto* headerLabel = new QLabel(headerWidget);
headerLabel->setText("样式列表"); headerLabel->setText("样式列表");
headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
//QtMaterialRaisedButton* addStyleButton = new QtMaterialRaisedButton("+", headerWidget); //QtMaterialRaisedButton* addStyleButton = new QtMaterialRaisedButton("+", headerWidget);
QPushButton* addStyleButton = new QPushButton("+", headerWidget); auto* addStyleButton = new QPushButton("+", headerWidget);
addStyleButton->setFixedSize(QSize(20, 20)); addStyleButton->setFixedSize(QSize(20, 20));
if (leafP->styles.size() >= LayerStyle::types.size()) if (leafP->styles.full())
{ {
addStyleButton->setDisabled(true); addStyleButton->setDisabled(true);
} }
else else
{ {
connect(addStyleButton, &QPushButton::clicked, [&, leafP]() { connect(addStyleButton, &QPushButton::clicked, [&, leafP] {
LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, nullptr, &(leafP->styles)); auto* dialog = new LayerStyleDialog(leafP->styles);
dialog->exec(); dialog->exec();
if (dialog->layerStyle) if (dialog->layerStyle)
{ {
leafP->styles.push_back(dialog->layerStyle); leafP->styles.useStyle(dialog->layerStyle);
emit requireRefreshPreview(); leafP->styles.computeNewHash();
emit requireSelfRefresh();
emit requireRefreshElementWidget(); emit requireRefreshPreview();
} emit requireSelfRefresh();
dialog->deleteLater(); emit requireRefreshElementWidget();
}
dialog->deleteLater();
}); });
} }
@ -179,32 +179,35 @@ void InfoDisplayWidget::generateLayerForm()
{ {
leafP->styles.push_back(std::shared_ptr<LayerStyle>(new StrokeElementLayerStyle())); leafP->styles.push_back(std::shared_ptr<LayerStyle>(new StrokeElementLayerStyle()));
}*/ }*/
std::vector<std::shared_ptr<LayerStyle>>* styles = &(leafP->styles); auto* styles = &leafP->styles;
for (auto styleIterator = styles->begin(); styleIterator != styles->end(); styleIterator++) for (auto styleIterator = styles->begin(); styleIterator != styles->end(); ++styleIterator)
{ {
QListWidgetItem* item = new QListWidgetItem; auto* item = new QListWidgetItem;
QWidget* w = new QWidget; auto* w = new QWidget(this);
item->setSizeHint(QSize(50, 40)); item->setSizeHint(QSize(50, 40));
QHBoxLayout* layout = new QHBoxLayout; auto* layout = new QHBoxLayout(w);
layout->setAlignment(Qt::AlignmentFlag::AlignRight); layout->setAlignment(Qt::AlignmentFlag::AlignRight);
//QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w); //QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w);
//QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w); //QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w);
QPushButton* detailButton = new QPushButton(w); auto* detailButton = new QPushButton(w);
QPushButton* removeButton = new QPushButton(w); auto* removeButton = new QPushButton(w);
detailButton->setText("..."); detailButton->setText("...");
detailButton->setFixedSize(QSize(20, 20)); detailButton->setFixedSize(QSize(20, 20));
removeButton->setText("×"); removeButton->setText("×");
removeButton->setFixedSize(QSize(20, 20)); removeButton->setFixedSize(QSize(20, 20));
connect(detailButton, &QPushButton::clicked, this, connect(detailButton, &QPushButton::clicked, this,
[this, styleIterator]() [this, styles, styleIterator]
{ {
LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, *styleIterator); auto* dialog =
new LayerStyleDialog(*styles, styleIterator->second);
dialog->exec(); dialog->exec();
if (dialog->layerStyle) if (dialog->layerStyle)
{ {
(*styleIterator) = dialog->layerStyle; styleIterator->second = dialog->layerStyle;
styles->computeNewHash();
emit requireRefreshPreview(); emit requireRefreshPreview();
emit requireSelfRefresh(); emit requireSelfRefresh();
emit requireRefreshElementWidget(); emit requireRefreshElementWidget();
@ -213,15 +216,17 @@ void InfoDisplayWidget::generateLayerForm()
}); });
connect(removeButton, &QPushButton::clicked, this, connect(removeButton, &QPushButton::clicked, this,
[this, styleIterator, styles]() [this, styleIterator, styles]
{ {
styles->erase(styleIterator); styles->dropStyle(styleIterator->first);
styles->computeNewHash();
emit requireRefreshPreview(); emit requireRefreshPreview();
emit requireSelfRefresh(); emit requireSelfRefresh();
emit requireRefreshElementWidget(); emit requireRefreshElementWidget();
}); });
QWidget* styleDisplayWidget = (*styleIterator)->getListDisplayWidget(); QWidget* styleDisplayWidget = styleIterator->second->getListDisplayWidget();
styleDisplayWidget->setParent(w); styleDisplayWidget->setParent(w);
styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));

View File

@ -273,7 +273,8 @@ GLuint Renderer::Model::loadPainting(std::string path)
} }
else if (path == "1.json") else if (path == "1.json")
{ {
float widths[] = { 0.43, 0.43 * 0.25 / 0.15, 0.43 * 0.25 / 0.15 }; painting.backgroundColor = QColor(196, 81, 35);
float widths[] = { 0.22, 0.22 * 0.25 / 0.15, 0.22 * 0.25 / 0.15 };
QPainterPath painterPaths[6]; QPainterPath painterPaths[6];
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
if (!SvgFileLoader().loadSvgFile(QString(std::format("../svg/{}.svg", i + 1).c_str()), painterPaths[i])) if (!SvgFileLoader().loadSvgFile(QString(std::format("../svg/{}.svg", i + 1).c_str()), painterPaths[i]))

View File

@ -9,7 +9,7 @@ using namespace Renderer;
constexpr int kMaxLineCount = 20; constexpr int kMaxLineCount = 20;
Painting::Painting() Painting::Painting(QColor backgroundColor) : backgroundColor(backgroundColor)
{ {
} }
@ -171,18 +171,21 @@ void Painting::generateBuffers(QOpenGLFunctions_4_5_Core* glFunc)
//std::cout << std::format("{} {} {} {}\n", contourBuffer->bvhOffset, stylePool[i.first->style], contourBuffer->pointsOffset, contourBuffer->linesOffset); //std::cout << std::format("{} {} {} {}\n", contourBuffer->bvhOffset, stylePool[i.first->style], contourBuffer->pointsOffset, contourBuffer->linesOffset);
} }
glFunc->glCreateBuffers(5, buffers.data()); glFunc->glCreateBuffers(6, buffers.data());
GLuint& bvhSSBO = buffers[0]; GLuint& bvhSSBO = buffers[0];
GLuint& bvhBoundSSBO = buffers[1]; GLuint& bvhBoundSSBO = buffers[1];
GLuint& elementOffsetSSBO = buffers[2]; GLuint& elementOffsetSSBO = buffers[2];
GLuint& elementIndexSSBO = buffers[3]; GLuint& elementIndexSSBO = buffers[3];
GLuint& elementDataSSBO = buffers[4]; GLuint& elementDataSSBO = buffers[4];
GLuint& backgroundColorUBO = buffers[5];
glFunc->glNamedBufferData(buffers[0], bvhChildren.size() * sizeof(bvhChildren[0]), bvhChildren.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[0], bvhChildren.size() * sizeof(bvhChildren[0]), bvhChildren.data(), GL_STATIC_READ);
glFunc->glNamedBufferData(buffers[1], bvhBounds.size() * sizeof(bvhBounds[0]), bvhBounds.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[1], bvhBounds.size() * sizeof(bvhBounds[0]), bvhBounds.data(), GL_STATIC_READ);
glFunc->glNamedBufferData(buffers[2], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[2], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ);
glFunc->glNamedBufferData(buffers[3], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[3], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ);
glFunc->glNamedBufferData(buffers[4], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[4], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ);
glm::vec3 color(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF());
glFunc->glNamedBufferData(buffers[5], sizeof(glm::vec3), &color, GL_STATIC_READ);
} }
GLuint Renderer::Painting::getElementCount() GLuint Renderer::Painting::getElementCount()

View File

@ -64,9 +64,10 @@ namespace Renderer
std::vector<GLuint> elementIndex; std::vector<GLuint> elementIndex;
std::vector<GLfloat> elementData; std::vector<GLfloat> elementData;
int paintingId = 0; int paintingId = 0;
std::array<GLuint, 5> buffers; std::array<GLuint, 6> buffers;
QColor backgroundColor;
Painting(); Painting(QColor backgroundColor = Qt::white);
void addElement(const Element& element, const ElementTransform& transform); void addElement(const Element& element, const ElementTransform& transform);
void addElement(std::shared_ptr<Element> element, QVector4D bound, float rotation, int zIndex); void addElement(std::shared_ptr<Element> element, QVector4D bound, float rotation, int zIndex);
void generateBuffers(QOpenGLFunctions_4_5_Core* glFunc); void generateBuffers(QOpenGLFunctions_4_5_Core* glFunc);

View File

@ -126,6 +126,7 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]);
for (auto level = levels - 1; level < levels; ++level) for (auto level = levels - 1; level < levels; ++level)
{ {
@ -143,7 +144,7 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai
GL_TRUE); GL_TRUE);
program.bind(); program.bind();
glMain->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j); glMain->Uniform2i(0 /*pixelOffset*/, static_cast<GLsizei>(pageSize) * i, static_cast<GLsizei>(pageSize) * j);
glMain->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); glMain->BindImageTexture(0, baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
glMain->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); glMain->BindImageTexture(1, metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);
glMain->DispatchCompute(pageSize / 8, pageSize / 8, 1); glMain->DispatchCompute(pageSize / 8, pageSize / 8, 1);
@ -190,6 +191,7 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag
program.bind(); program.bind();
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]);
glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]);
gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y); gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast<GLsizei>(pageSize) * page.x, static_cast<GLsizei>(pageSize) * page.y);
gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8);

View File

@ -15,7 +15,7 @@ namespace Renderer
{ {
GLuint baseColor; GLuint baseColor;
GLuint metallicRoughness; GLuint metallicRoughness;
std::array<GLuint, 5> buffers; std::array<GLuint, 6> buffers;
}; };
class VirtualTextureManager class VirtualTextureManager

View File

@ -5,6 +5,7 @@
#include <iostream> #include <iostream>
#include <format> #include <format>
#include "consoleapi2.h" #include "consoleapi2.h"
#include <lib/qtmaterialstyle.h>
extern "C" extern "C"
{ {
@ -50,6 +51,9 @@ int main(int argc, char* argv[])
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
QApplication a(argc, argv); QApplication a(argc, argv);
Q_INIT_RESOURCE(resources); Q_INIT_RESOURCE(resources);
QtMaterialTheme theme;
theme.setColor("primary1", QColor(0, 90, 158));
QtMaterialStyle::instance().setTheme(&theme);
//FramelessHelper::Core::setApplicationOSThemeAware(); //FramelessHelper::Core::setApplicationOSThemeAware();
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur); FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
//FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow); //FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);

View File

@ -1,4 +1,6 @@
{ {
"project-name": "样例1",
"background-color": "#ffffff",
"height": 1080, "height": 1080,
"width": 1080, "width": 1080,
"elements": [ "elements": [