Files
hfut-bishe/client/gui/dialogs/BlackholeResolveDialog.cpp
T
2026-05-14 17:30:20 +08:00

188 lines
6.9 KiB
C++

#include "dialogs/BlackholeResolveDialog.h"
#include <QDialogButtonBox>
#include <QFrame>
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QStackedWidget>
#include <QVBoxLayout>
namespace {
QPushButton* makeAlgoButton(const QString& title, QWidget* parent) {
auto* btn = new QPushButton(parent);
btn->setCheckable(false);
btn->setCursor(Qt::PointingHandCursor);
btn->setMinimumHeight(48);
btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
btn->setText(title);
btn->setStyleSheet(
"QPushButton { text-align: left; padding: 10px 12px; border: 1px solid palette(mid); border-radius: 8px; }"
"QPushButton:hover { border-color: palette(highlight); }");
return btn;
}
} // namespace
QString BlackholeResolveDialog::defaultModelInpaintPrompt() {
return QStringLiteral(
"中国画局部,需去除人物并只补背景:请严格依据掩膜外已见的笔墨皴擦、设色层次、留白与纸绢肌理,"
"在掩膜内自然延展,补全为山石、坡岸、云水、苔点或空灵留白等,与外缘笔法、墨色与气韵连贯衔接;"
"禁止出现人物轮廓、肢体、衣褶、五官、手足、发丝、肤色、投影及去人后的模糊晕带、鬼影边缘与色块台阶,"
"整体须像原画从未画入人物一样自然,不留修补感。");
}
BlackholeResolveDialog::BlackholeResolveDialog(const QString& blackholeName, QWidget* parent)
: QDialog(parent),
m_blackholeName(blackholeName) {
setModal(true);
setMinimumSize(400, 320);
setWindowTitle(QStringLiteral("修复 · %1").arg(m_blackholeName));
auto* root = new QVBoxLayout(this);
m_pages = new QStackedWidget(this);
root->addWidget(m_pages, 1);
buildSelectPage();
buildDetailPage();
m_pages->setCurrentWidget(m_pageSelect);
}
QString BlackholeResolveDialog::promptText() const {
return m_promptEdit ? m_promptEdit->toPlainText().trimmed() : QString();
}
void BlackholeResolveDialog::buildSelectPage() {
m_pageSelect = new QWidget(this);
auto* layout = new QVBoxLayout(m_pageSelect);
layout->setContentsMargins(8, 8, 8, 8);
layout->setSpacing(12);
auto* title = new QLabel(QStringLiteral("方式"), m_pageSelect);
title->setStyleSheet("font-size: 16px; font-weight: 600;");
layout->addWidget(title);
auto* btnCopy = makeAlgoButton(QStringLiteral("复制背景"), m_pageSelect);
auto* btnOriginal = makeAlgoButton(QStringLiteral("原始背景"), m_pageSelect);
auto* btnModel = makeAlgoButton(QStringLiteral("模型补全"), m_pageSelect);
layout->addWidget(btnCopy);
layout->addWidget(btnOriginal);
layout->addWidget(btnModel);
layout->addStretch(1);
auto* btns = new QDialogButtonBox(QDialogButtonBox::Cancel, m_pageSelect);
connect(btns, &QDialogButtonBox::rejected, this, &QDialog::reject);
layout->addWidget(btns);
connect(btnCopy, &QPushButton::clicked, this, [this]() {
enterAlgorithmPage(Algorithm::CopyBackgroundRegion);
});
connect(btnOriginal, &QPushButton::clicked, this, [this]() {
enterAlgorithmPage(Algorithm::UseOriginalBackground);
});
connect(btnModel, &QPushButton::clicked, this, [this]() {
enterAlgorithmPage(Algorithm::ModelInpaint);
});
m_pages->addWidget(m_pageSelect);
}
void BlackholeResolveDialog::buildDetailPage() {
m_pageDetail = new QWidget(this);
auto* layout = new QVBoxLayout(m_pageDetail);
layout->setContentsMargins(8, 8, 8, 8);
layout->setSpacing(10);
m_detailTitle = new QLabel(m_pageDetail);
m_detailTitle->setStyleSheet("font-size: 15px; font-weight: 600;");
layout->addWidget(m_detailTitle);
m_algoDetails = new QStackedWidget(m_pageDetail);
// 详情页 A:复制背景其他区域(交互布局)
m_copyDetail = new QWidget(m_algoDetails);
{
auto* cLay = new QVBoxLayout(m_copyDetail);
cLay->setSpacing(8);
auto* panel = new QFrame(m_copyDetail);
panel->setFrameShape(QFrame::StyledPanel);
auto* pLay = new QVBoxLayout(panel);
pLay->setSpacing(8);
auto* tip = new QLabel(QStringLiteral("应用后在画布拖取样框。"), panel);
tip->setStyleSheet("color: palette(mid);");
pLay->addWidget(tip);
cLay->addWidget(panel);
cLay->addStretch(1);
}
// 详情页 B:使用原始背景(确认布局)
m_originalDetail = new QWidget(m_algoDetails);
{
auto* oLay = new QVBoxLayout(m_originalDetail);
oLay->setSpacing(8);
auto* desc = new QLabel(QStringLiteral("仅隐藏黑洞,不改动背景文件。"), m_originalDetail);
desc->setWordWrap(true);
oLay->addWidget(desc);
oLay->addStretch(1);
}
// 详情页 C:模型补全(提示词)
m_modelDetail = new QWidget(m_algoDetails);
{
auto* mLay = new QVBoxLayout(m_modelDetail);
mLay->setSpacing(8);
auto* panel = new QFrame(m_modelDetail);
panel->setFrameShape(QFrame::StyledPanel);
auto* pLay = new QVBoxLayout(panel);
pLay->setSpacing(8);
m_promptEdit = new QPlainTextEdit(panel);
m_promptEdit->setPlainText(BlackholeResolveDialog::defaultModelInpaintPrompt());
m_promptEdit->setPlaceholderText(QStringLiteral("可按画面增删;若全部删空,请求时仍使用内置默认描述"));
m_promptEdit->setMinimumHeight(72);
pLay->addWidget(m_promptEdit);
mLay->addWidget(panel);
mLay->addStretch(1);
}
m_algoDetails->addWidget(m_copyDetail);
m_algoDetails->addWidget(m_originalDetail);
m_algoDetails->addWidget(m_modelDetail);
layout->addWidget(m_algoDetails, 1);
auto* btns = new QDialogButtonBox(m_pageDetail);
auto* btnBack = btns->addButton(QStringLiteral("返回"), QDialogButtonBox::ActionRole);
auto* btnApply = btns->addButton(QStringLiteral("确定"), QDialogButtonBox::AcceptRole);
auto* btnCancel = btns->addButton(QDialogButtonBox::Cancel);
connect(btnBack, &QPushButton::clicked, this, [this]() {
m_pages->setCurrentWidget(m_pageSelect);
});
connect(btnApply, &QPushButton::clicked, this, &QDialog::accept);
connect(btnCancel, &QPushButton::clicked, this, &QDialog::reject);
layout->addWidget(btns);
m_pages->addWidget(m_pageDetail);
}
void BlackholeResolveDialog::enterAlgorithmPage(Algorithm algo) {
m_selectedAlgorithm = algo;
if (algo == Algorithm::CopyBackgroundRegion) {
m_detailTitle->setText(QStringLiteral("复制背景"));
m_algoDetails->setCurrentWidget(m_copyDetail);
} else if (algo == Algorithm::UseOriginalBackground) {
m_detailTitle->setText(QStringLiteral("原始背景"));
m_algoDetails->setCurrentWidget(m_originalDetail);
} else {
m_detailTitle->setText(QStringLiteral("模型补全"));
m_algoDetails->setCurrentWidget(m_modelDetail);
}
m_pages->setCurrentWidget(m_pageDetail);
}