[editor/style] 修改了style相关的GUI

* 为LayerStyleDialog提供最大大小和滚动条 | #30
* 为StrokeElementLayerStyle适配变宽样式 | #33
main
ArgonarioD 2023-03-28 19:51:35 +08:00
parent 1295e2255a
commit bb7c30a896
6 changed files with 187 additions and 36 deletions

View File

@ -1,7 +1,10 @@
#include "LayerStyleDialog.h"
#include <QGuiApplication>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QScreen>
#include <QScrollBar>
LayerStyleDialog::LayerStyleDialog(
LayerStyleContainer* pStyles,
@ -13,13 +16,16 @@ LayerStyleDialog::LayerStyleDialog(
dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter);
this->setLayout(dialogLayout);
styleScrollArea = new QScrollArea(this);
dialogLayout->addWidget(styleScrollArea, 1, 0);
if (existedStyle)
{
this->modifyingStyle = existedStyle->clone();
this->styleWidget = modifyingStyle->getInputWidget();
this->styleWidget->setParent(this);
dialogLayout->addWidget(styleWidget, 1, 0);
styleScrollArea->setWidget(styleWidget);
}
else
{
@ -36,7 +42,7 @@ LayerStyleDialog::LayerStyleDialog(
this->styleWidget = this->modifyingStyle->getInputWidget();
this->styleWidget->setParent(this);
this->dialogLayout->addWidget(styleWidget, 1, 0);
styleScrollArea->setWidget(styleWidget);
connect(typeSelector, &QComboBox::currentTextChanged,
this, &LayerStyleDialog::onStyleTypeSelectorChanged);
}
@ -45,6 +51,11 @@ LayerStyleDialog::LayerStyleDialog(
connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject);
dialogLayout->addWidget(buttonBox, 2, 0);
const auto* screen = QGuiApplication::screenAt(this->geometry().center());
this->setMaximumHeight(screen->geometry().height() / 4 * 3);
styleScrollArea->setMinimumWidth(styleWidget->width() + styleScrollArea->verticalScrollBar()->width() + 2);
styleScrollArea->adjustSize();
styleScrollArea->setWidgetResizable(true);
this->adjustSize();
}
@ -56,16 +67,13 @@ void LayerStyleDialog::accept()
void LayerStyleDialog::onStyleTypeSelectorChanged(const QString& current)
{
if (this->styleWidget)
{
this->dialogLayout->removeWidget(this->styleWidget);
this->styleWidget->setParent(nullptr);
delete styleWidget;
}
this->modifyingStyle = std::move(styles->makeUnusedStyle(current));
this->styleWidget->deleteLater();
this->styleWidget = this->modifyingStyle->getInputWidget();
this->styleWidget->setParent(this);
this->dialogLayout->addWidget(styleWidget, 1, 0);
//this->dialogLayout->addWidget(styleWidget, 1, 0);
this->styleScrollArea->setWidget(styleWidget);
styleScrollArea->setMinimumWidth(styleWidget->width() + styleScrollArea->verticalScrollBar()->width() + 2);
this->styleWidget->adjustSize();
this->adjustSize();
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "LayerStyle.h"
#include <QDialog>
#include <QScrollArea>
#include <QGridLayout>
class LayerStyleDialog : public QDialog
@ -9,6 +10,7 @@ class LayerStyleDialog : public QDialog
private:
QWidget* styleWidget;
QGridLayout* dialogLayout;
QScrollArea* styleScrollArea;
LayerStyleContainer* styles;
std::unique_ptr<LayerStyle> modifyingStyle;
public:

View File

@ -8,12 +8,18 @@
#include <ranges>
#include <utility>
// Stroke Table
constexpr int COLUMN_WIDTH = 0;
constexpr int COLUMN_COLOR = 1;
constexpr int COLUMN_METALLIC = 2;
constexpr int COLUMN_ROUGHNESS = 3;
constexpr int COLUMN_OPERATIONS = 4;
// Width Table
constexpr int COLUMN_LENGTH = 0;
constexpr int COLUMN_WIDTH_RATIO = 1;
constexpr int COLUMN_WIDTH_OPERATIONS = 2;
inline Renderer::Material newMaterial()
{
return {ColorHelper::instance().getPrimary1()};
@ -47,12 +53,16 @@ StrokeStyleWidget::StrokeStyleWidget(
viewLayout->addWidget(strokeProperties);
viewLayout->addWidget(widthField);
initTable(radialStroke(stroke));
initStrokeTable(radialStroke(stroke));
viewLayout->addWidget(strokeTable);
initAddButton();
initStrokeAddButton();
viewLayout->addWidget(addButton);
initWidthWidget();
viewLayout->addWidget(enableVariableWidth);
viewLayout->addWidget(widthWidget);
this->adjustSize();
}
@ -97,12 +107,10 @@ void StrokeStyleWidget::initStrokeSettings()
});
}
void StrokeStyleWidget::initTable(const std::shared_ptr<Renderer::StrokeRadialGradient>& materialStroke)
void StrokeStyleWidget::initStrokeTable(const std::shared_ptr<Renderer::StrokeRadialGradient>& materialStroke)
{
this->strokeTable = new QTableWidget(this);
this->strokeTable = new QTableWidget(materialStroke->materialMap.size(), 5, this);
strokeTable->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
strokeTable->setColumnCount(5);
strokeTable->setRowCount(materialStroke->materialMap.size());
QStringList headers;
headers << QStringLiteral("ÀëÐľàÀëÕ¼±È")
<< QStringLiteral("ÑÕÉ«")
@ -116,14 +124,15 @@ void StrokeStyleWidget::initTable(const std::shared_ptr<Renderer::StrokeRadialGr
// ÄÚÈÝ
for (auto& [width, material] : std::views::reverse(materialStroke->materialMap))
{
setTableRow(row, width, material);
setStrokeTableRow(row, width, material);
row++;
}
connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged);
connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged);
// 记录currentItemChanged是为了能够在变更宽度map的key时也能取到原本的值
connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onStrokeCurrentItemChanged);
connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onStrokeCellChanged);
}
void StrokeStyleWidget::initAddButton()
void StrokeStyleWidget::initStrokeAddButton()
{
this->addButton = new QtMaterialRaisedButton("+", strokeTable);
addButton->setFixedHeight(30);
@ -145,13 +154,91 @@ void StrokeStyleWidget::initAddButton()
materialMap[newWidth] = newMaterial;
const int newRow = this->strokeTable->rowCount();
this->strokeTable->insertRow(newRow);
setTableRow(newRow, newWidth, materialMap[newWidth]);
setStrokeTableRow(newRow, newWidth, materialMap[newWidth]);
this->strokeTable->update();
handlingRowInsert = false;
});
}
void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& material)
void StrokeStyleWidget::initWidthWidget()
{
this->enableVariableWidth = new QtMaterialCheckBox(this);
this->widthWidget = new QWidget(this);
auto* widthWidgetLayout = new QVBoxLayout(widthWidget);
this->widthTable = new QTableWidget(stroke->widthMap.size(), 3, widthWidget);
this->widthAddButton = new QtMaterialRaisedButton("+", widthWidget);
widthWidgetLayout->addWidget(widthTable);
widthWidgetLayout->addWidget(widthAddButton);
enableVariableWidth->setText(QStringLiteral("宽度可变"));
connect(enableVariableWidth, &QtMaterialCheckBox::toggled, [this](bool checked){
widthWidget->setVisible(checked);
if (!checked)
{
stroke->widthMap.clear();
}
});
widthWidget->setVisible(!stroke->widthMap.empty());
enableVariableWidth->setChecked(!stroke->widthMap.empty());
QStringList headerLabels;
headerLabels << QStringLiteral("长度占比") << QStringLiteral("宽度缩放比") << QStringLiteral("其他操作");
widthTable->setHorizontalHeaderLabels(headerLabels);
widthTable->setMinimumHeight(widthTable->horizontalHeader()->height() * 4);
widthTable->setMinimumWidth(widthTable->sizeHint().width());
widthTable->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
for (int row = 0; const auto& [length, widthRatio] : stroke->widthMap)
{
setWidthTableRow(row, length, widthRatio);
++row;
}
connect(widthTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onWidthCurrentItemChanged);
connect(widthTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onWidthCellChanged);
widthAddButton->setFixedHeight(30);
widthAddButton->setBackgroundColor(ColorHelper::instance().getPrimary1());
connect(widthAddButton, &QtMaterialRaisedButton::clicked, [this] {
auto& widthMap = stroke->widthMap;
float newLength;
if (widthMap.empty())
{
newLength = 1.f;
}
else
{
const auto firstPair = widthMap.begin();
newLength = firstPair->first / 2;
}
widthMap[newLength] = 1.f;
const int newRow = this->widthTable->rowCount();
this->widthTable->insertRow(newRow);
setWidthTableRow(newRow, newLength, widthMap[newLength]);
this->widthTable->update();
});
}
void StrokeStyleWidget::setWidthTableRow(int row, float length, float ratio)
{
auto* lengthItem = new QTableWidgetItem;
lengthItem->setData(Qt::EditRole, length);
widthTable->setItem(row, COLUMN_LENGTH, lengthItem);
auto* widthRatioItem = new QTableWidgetItem;
widthRatioItem->setData(Qt::EditRole, ratio);
widthTable->setItem(row, COLUMN_WIDTH_RATIO, widthRatioItem);
auto* removeButton = new QtMaterialRaisedButton("-", widthTable);
removeButton->setBackgroundColor(ColorHelper::instance().getPrimary1());
removeButton->setFixedSize(20, 20);
widthTable->setCellWidget(row, COLUMN_WIDTH_OPERATIONS, removeButton);
connect(removeButton, &QtMaterialRaisedButton::clicked, [this, lengthItem] {
stroke->widthMap.erase(lengthItem->data(Qt::EditRole).toFloat());
this->widthTable->removeRow(lengthItem->row());
});
}
void StrokeStyleWidget::setStrokeTableRow(int row, float width, Renderer::Material& material)
{
auto* widthItem = new QTableWidgetItem;
widthItem->setData(Qt::EditRole, width);
@ -186,24 +273,24 @@ void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& ma
});
}
void StrokeStyleWidget::onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
void StrokeStyleWidget::onStrokeCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
{
if (!current) return;
const int column = current->column();
if (column != COLUMN_COLOR && column != COLUMN_OPERATIONS)
{
this->currentItemValue = current->data(Qt::EditRole);
this->currentStrokeItemValue = current->data(Qt::EditRole);
}
}
void StrokeStyleWidget::onCellChanged(int row, int column)
void StrokeStyleWidget::onStrokeCellChanged(int row, int column)
{
if (handlingRowInsert) return;
const auto changedItem = strokeTable->item(row, column);
const auto changedItemValue = changedItem->text().toFloat();
const auto changedItemValue = changedItem->data(Qt::EditRole).toFloat();
if (changedItemValue < 0 || 1 < changedItemValue)
{
changedItem->setData(Qt::EditRole, this->currentItemValue.toFloat());
changedItem->setData(Qt::EditRole, this->currentStrokeItemValue.toFloat());
return;
}
const auto changedWidth = strokeTable->item(row, COLUMN_WIDTH)->data(Qt::EditRole).toFloat();
@ -211,7 +298,7 @@ void StrokeStyleWidget::onCellChanged(int row, int column)
{
case COLUMN_WIDTH:
{
float oldWidth = this->currentItemValue.toFloat();
float oldWidth = this->currentStrokeItemValue.toFloat();
auto node = radialStroke(stroke)->materialMap.extract(oldWidth);
if (node.empty())
{
@ -234,3 +321,46 @@ void StrokeStyleWidget::onCellChanged(int row, int column)
}
}
}
void StrokeStyleWidget::onWidthCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
{
if (!current) return;
const int column = current->column();
if (column != COLUMN_WIDTH_OPERATIONS)
{
this->currentWidthItemValue = current->data(Qt::EditRole);
}
}
void StrokeStyleWidget::onWidthCellChanged(int row, int column)
{
const auto changedItem = widthTable->item(row, column);
const auto changedItemValue = changedItem->data(Qt::EditRole).toFloat();
if (column == COLUMN_LENGTH && (changedItemValue < 0 || 1 < changedItemValue))
{
changedItem->setData(Qt::EditRole, this->currentWidthItemValue.toFloat());
return;
}
const auto changedLength = widthTable->item(row, COLUMN_LENGTH)->data(Qt::EditRole).toFloat();
switch (column)
{
case COLUMN_LENGTH:
{
float oldLength = this->currentWidthItemValue.toFloat();
auto node = stroke->widthMap.extract(oldLength);
if (node.empty())
{
break;
}
node.key() = changedLength;
stroke->widthMap.insert(std::move(node));
strokeTable->sortItems(COLUMN_LENGTH, Qt::DescendingOrder);
break;
}
case COLUMN_WIDTH_RATIO:
{
stroke->widthMap[changedLength] = changedItemValue;
break;
}
}
}

View File

@ -11,26 +11,37 @@ class StrokeStyleWidget : public QWidget
{
Q_OBJECT
private:
QVariant currentItemValue;
QVariant currentStrokeItemValue;
QVariant currentWidthItemValue;
QtMaterialCheckBox* enableGradual;
QComboBox* endTypeBox;
QtMaterialTextField* widthField;
QTableWidget* strokeTable;
QtMaterialRaisedButton* addButton;
QtMaterialCheckBox* enableVariableWidth;
QWidget* widthWidget;
QTableWidget* widthTable;
QtMaterialRaisedButton* widthAddButton;
bool handlingRowInsert = false;
void initStrokeSettings();
void initTable(const std::shared_ptr<Renderer::StrokeRadialGradient>& materialStroke);
void initAddButton();
void setTableRow(int row, float width, Renderer::Material& material);
void initStrokeTable(const std::shared_ptr<Renderer::StrokeRadialGradient>& materialStroke);
void setStrokeTableRow(int row, float width, Renderer::Material& material);
void initStrokeAddButton();
void initWidthWidget();
void setWidthTableRow(int row, float length, float ratio);
public:
StrokeStyleWidget(const std::shared_ptr<MaterialStyleStroke>& stroke, QWidget* parent = nullptr);
std::shared_ptr<MaterialStyleStroke> stroke;
protected slots:
void onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
void onCellChanged(int row, int column);
void onStrokeCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
void onStrokeCellChanged(int row, int column);
void onWidthCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
void onWidthCellChanged(int row, int column);
};

View File

@ -41,7 +41,6 @@ std::vector<Renderer::BaseStyle> StrokeElementLayerStyle::toBaseStyles() const
QWidget* StrokeElementLayerStyle::getInputWidget()
{
auto* w = new QWidget;
auto* materialList = new QListView;
auto* layout = new QVBoxLayout(w);
layout->setMargin(0);

View File

@ -103,7 +103,7 @@ std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
{
return std::make_unique<MaterialStyleStroke>(halfWidth, strokeType, endType, materialStroke->clone());
return std::make_unique<MaterialStyleStroke>(halfWidth, strokeType, endType, materialStroke->clone(), widthMap);
}
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
@ -112,7 +112,8 @@ bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
&& halfWidth == static_cast<const MaterialStyleStroke&>(m).halfWidth
&& strokeType == static_cast<const MaterialStyleStroke&>(m).strokeType
&& endType == static_cast<const MaterialStyleStroke&>(m).endType
&& *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke;
&& *materialStroke == *static_cast<const MaterialStyleStroke&>(m).materialStroke
&& widthMap == static_cast<const MaterialStyleStroke&>(m).widthMap;
}
float Renderer::MaterialStyleStroke::getHalfWidth() const