209 lines
8.0 KiB
C++
209 lines
8.0 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, const QString& subtitle, QWidget* parent) {
|
||
auto* btn = new QPushButton(parent);
|
||
btn->setCheckable(false);
|
||
btn->setCursor(Qt::PointingHandCursor);
|
||
btn->setMinimumHeight(86);
|
||
btn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||
btn->setText(title + QStringLiteral("\n") + subtitle);
|
||
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
|
||
|
||
BlackholeResolveDialog::BlackholeResolveDialog(const QString& blackholeName, QWidget* parent)
|
||
: QDialog(parent),
|
||
m_blackholeName(blackholeName) {
|
||
setModal(true);
|
||
setMinimumSize(560, 420);
|
||
setWindowTitle(QStringLiteral("黑洞解决"));
|
||
|
||
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("第 1 步:选择黑洞解决算法"), m_pageSelect);
|
||
auto* sub = new QLabel(QStringLiteral("当前黑洞:%1").arg(m_blackholeName), m_pageSelect);
|
||
title->setStyleSheet("font-size: 18px; font-weight: 600;");
|
||
sub->setStyleSheet("color: palette(mid);");
|
||
layout->addWidget(title);
|
||
layout->addWidget(sub);
|
||
|
||
auto* btnCopy = makeAlgoButton(
|
||
QStringLiteral("复制背景其他区域"),
|
||
QStringLiteral("进入画布拖动取样框,直观选择复制来源。"),
|
||
m_pageSelect);
|
||
auto* btnOriginal = makeAlgoButton(
|
||
QStringLiteral("使用原始背景"),
|
||
QStringLiteral("撤销黑洞显示,恢复抠图前背景区域。"),
|
||
m_pageSelect);
|
||
auto* btnModel = makeAlgoButton(
|
||
QStringLiteral("模型补全(SDXL Inpaint)"),
|
||
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: 18px; font-weight: 600;");
|
||
m_detailHint = new QLabel(m_pageDetail);
|
||
m_detailHint->setWordWrap(true);
|
||
m_detailHint->setStyleSheet("color: palette(mid);");
|
||
layout->addWidget(m_detailTitle);
|
||
layout->addWidget(m_detailHint);
|
||
|
||
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("说明:点击“应用”后进入画布拖动模式。\n在画布中拖动青色取样框,松开鼠标即可将该区域复制到黑洞位置并自动移除黑洞。"),
|
||
panel);
|
||
tip->setWordWrap(true);
|
||
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);
|
||
auto* note = new QLabel(
|
||
QStringLiteral("适用场景:当前黑洞区域无需二次修补,只需恢复抠图前背景;应用后黑洞会自动移除。"),
|
||
m_originalDetail);
|
||
note->setWordWrap(true);
|
||
note->setStyleSheet("color: palette(mid);");
|
||
oLay->addWidget(desc);
|
||
oLay->addWidget(note);
|
||
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(QStringLiteral("This is part of a Chinese painting; please complete the background for me, following the style of the other parts."));
|
||
m_promptEdit->setMinimumHeight(90);
|
||
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("第 2 步:复制背景其他区域"));
|
||
m_detailHint->setText(QStringLiteral("准备进入画布拖动取样框模式。"));
|
||
m_algoDetails->setCurrentWidget(m_copyDetail);
|
||
} else if (algo == Algorithm::UseOriginalBackground) {
|
||
m_detailTitle->setText(QStringLiteral("第 2 步:使用原始背景"));
|
||
m_detailHint->setText(QStringLiteral("确认后将切换为原始背景显示。"));
|
||
m_algoDetails->setCurrentWidget(m_originalDetail);
|
||
} else {
|
||
m_detailTitle->setText(QStringLiteral("第 2 步:模型补全(SDXL Inpaint)"));
|
||
m_detailHint->setText(QStringLiteral("输入提示词(可选),点击应用后将生成预览。"));
|
||
m_algoDetails->setCurrentWidget(m_modelDetail);
|
||
}
|
||
m_pages->setCurrentWidget(m_pageDetail);
|
||
}
|
||
|