#include "dialogs/BlackholeResolveDialog.h" #include #include #include #include #include #include #include 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); }