Files
CalibratorLauncher/widgets/overlaydialogswidget.cpp
2026-01-02 19:20:35 +09:00

323 lines
8.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "overlaydialogswidget.h"
#include <QApplication>
OverlayDialog::OverlayDialog(QWidget *parent)
: QWidget(parent), m_type(Information), m_inputMode(false)
{
setupUI();
hide();
}
void OverlayDialog::setupUI()
{
// 设置为覆盖整个父窗口
setAttribute(Qt::WA_StyledBackground);
setStyleSheet("background: transparent;");
auto *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
// 半透明背景遮罩
m_backgroundOverlay = new QWidget(this);
m_backgroundOverlay->setStyleSheet("background: rgba(0, 0, 0, 0.5);");
mainLayout->addWidget(m_backgroundOverlay);
// 对话框容器 - 居中显示
m_dialogContainer = new QWidget(m_backgroundOverlay);
m_dialogContainer->setFixedWidth(420);
m_dialogContainer->setStyleSheet(
"QWidget { background: white; border-radius: 12px; }");
auto *dialogLayout = new QVBoxLayout(m_dialogContainer);
dialogLayout->setContentsMargins(24, 24, 24, 20);
dialogLayout->setSpacing(16);
// 标题栏
auto *headerLayout = new QHBoxLayout();
headerLayout->setSpacing(12);
m_iconLabel = new QLabel(this);
m_iconLabel->setFixedSize(32, 32);
m_iconLabel->setAlignment(Qt::AlignCenter);
m_iconLabel->setStyleSheet("font-size: 24px;");
headerLayout->addWidget(m_iconLabel);
m_titleLabel = new QLabel("提示", this);
m_titleLabel->setStyleSheet(
"font-size: 18px; font-weight: bold; color: #263238;");
headerLayout->addWidget(m_titleLabel, 1);
dialogLayout->addLayout(headerLayout);
// 消息内容
m_messageLabel = new QLabel(this);
m_messageLabel->setWordWrap(true);
m_messageLabel->setStyleSheet(
"font-size: 14px; color: #546E7A; line-height: 1.6; padding: 8px 0;");
dialogLayout->addWidget(m_messageLabel);
// 输入框(默认隐藏)
m_inputEdit = new QLineEdit(this);
m_inputEdit->setFixedHeight(44);
m_inputEdit->setStyleSheet(
"QLineEdit { border: 2px solid #E0E0E0; border-radius: 8px; padding: 0 12px; "
"font-size: 14px; background: #FAFAFA; }"
"QLineEdit:focus { border-color: #1976D2; background: white; }");
m_inputEdit->hide();
dialogLayout->addWidget(m_inputEdit);
// 按钮区域
auto *buttonLayout = new QHBoxLayout();
buttonLayout->setSpacing(12);
buttonLayout->addStretch();
m_rejectBtn = new QPushButton("取消", this);
m_rejectBtn->setFixedSize(100, 44);
m_rejectBtn->setCursor(Qt::PointingHandCursor);
m_rejectBtn->setStyleSheet(
"QPushButton { background: #ECEFF1; color: #546E7A; border: none; "
"border-radius: 8px; font-size: 14px; font-weight: 500; }"
"QPushButton:hover { background: #CFD8DC; }"
"QPushButton:pressed { background: #B0BEC5; }");
connect(m_rejectBtn, &QPushButton::clicked, this, &OverlayDialog::onRejectClicked);
buttonLayout->addWidget(m_rejectBtn);
m_acceptBtn = new QPushButton("确定", this);
m_acceptBtn->setFixedSize(100, 44);
m_acceptBtn->setCursor(Qt::PointingHandCursor);
m_acceptBtn->setStyleSheet(
"QPushButton { background: #1976D2; color: white; border: none; "
"border-radius: 8px; font-size: 14px; font-weight: 500; }"
"QPushButton:hover { background: #1565C0; }"
"QPushButton:pressed { background: #0D47A1; }");
connect(m_acceptBtn, &QPushButton::clicked, this, &OverlayDialog::onAcceptClicked);
buttonLayout->addWidget(m_acceptBtn);
dialogLayout->addLayout(buttonLayout);
// 居中布局
auto *overlayLayout = new QVBoxLayout(m_backgroundOverlay);
overlayLayout->addStretch();
auto *centerLayout = new QHBoxLayout();
centerLayout->addStretch();
centerLayout->addWidget(m_dialogContainer);
centerLayout->addStretch();
overlayLayout->addLayout(centerLayout);
overlayLayout->addStretch();
}
void OverlayDialog::setTitle(const QString &title)
{
m_titleLabel->setText(title);
}
void OverlayDialog::setMessage(const QString &message)
{
m_messageLabel->setText(message);
}
void OverlayDialog::setDialogType(DialogType type)
{
m_type = type;
updateTypeIcon();
// 根据类型调整按钮显示
switch (type)
{
case Information:
case Warning:
m_rejectBtn->hide();
m_acceptBtn->setText("确定");
break;
case Question:
m_rejectBtn->show();
m_rejectBtn->setText("取消");
m_acceptBtn->setText("确定");
break;
case Input:
m_rejectBtn->show();
m_rejectBtn->setText("取消");
m_acceptBtn->setText("确定");
break;
}
}
void OverlayDialog::setInputMode(bool inputMode, const QString &placeholder)
{
m_inputMode = inputMode;
m_inputEdit->setVisible(inputMode);
m_inputEdit->setPlaceholderText(placeholder);
m_inputEdit->clear();
}
void OverlayDialog::setCallback(std::function<void(bool, const QString &)> callback)
{
m_callback = callback;
}
void OverlayDialog::updateTypeIcon()
{
QString icon;
QString color;
switch (m_type)
{
case Information:
icon = "";
color = "#1976D2";
break;
case Warning:
icon = "";
color = "#F57C00";
break;
case Question:
icon = "?";
color = "#1976D2";
break;
case Input:
icon = "";
color = "#1976D2";
break;
}
m_iconLabel->setText(icon);
m_iconLabel->setStyleSheet(QString("font-size: 24px; color: %1;").arg(color));
}
void OverlayDialog::showDialog()
{
if (parentWidget())
{
setGeometry(parentWidget()->rect());
}
show();
raise();
animateShow();
if (m_inputMode)
{
m_inputEdit->setFocus();
}
}
void OverlayDialog::hideDialog()
{
animateHide();
}
void OverlayDialog::onAcceptClicked()
{
QString inputText = m_inputMode ? m_inputEdit->text() : QString();
emit accepted(inputText);
if (m_callback)
{
m_callback(true, inputText);
}
hideDialog();
}
void OverlayDialog::onRejectClicked()
{
emit rejected();
if (m_callback)
{
m_callback(false, QString());
}
hideDialog();
}
void OverlayDialog::animateShow()
{
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
setGraphicsEffect(effect);
QPropertyAnimation *animation = new QPropertyAnimation(effect, "opacity");
animation->setDuration(150);
animation->setStartValue(0.0);
animation->setEndValue(1.0);
animation->start(QPropertyAnimation::DeleteWhenStopped);
}
void OverlayDialog::animateHide()
{
QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect(this);
setGraphicsEffect(effect);
QPropertyAnimation *animation = new QPropertyAnimation(effect, "opacity");
animation->setDuration(100);
animation->setStartValue(1.0);
animation->setEndValue(0.0);
connect(animation, &QPropertyAnimation::finished, this, [this]()
{
hide();
deleteLater(); });
animation->start(QPropertyAnimation::DeleteWhenStopped);
}
// 静态便捷方法
void OverlayDialog::information(QWidget *parent, const QString &title, const QString &message)
{
// 找到顶层窗口
QWidget *topLevel = parent;
while (topLevel->parentWidget())
topLevel = topLevel->parentWidget();
auto *dialog = new OverlayDialog(topLevel);
dialog->setTitle(title);
dialog->setMessage(message);
dialog->setDialogType(Information);
dialog->showDialog();
}
void OverlayDialog::warning(QWidget *parent, const QString &title, const QString &message)
{
QWidget *topLevel = parent;
while (topLevel->parentWidget())
topLevel = topLevel->parentWidget();
auto *dialog = new OverlayDialog(topLevel);
dialog->setTitle(title);
dialog->setMessage(message);
dialog->setDialogType(Warning);
dialog->showDialog();
}
void OverlayDialog::question(QWidget *parent, const QString &title, const QString &message,
std::function<void(bool)> callback)
{
QWidget *topLevel = parent;
while (topLevel->parentWidget())
topLevel = topLevel->parentWidget();
auto *dialog = new OverlayDialog(topLevel);
dialog->setTitle(title);
dialog->setMessage(message);
dialog->setDialogType(Question);
dialog->setCallback([callback](bool accepted, const QString &)
{ callback(accepted); });
dialog->showDialog();
}
void OverlayDialog::input(QWidget *parent, const QString &title, const QString &prompt,
std::function<void(bool, const QString &)> callback,
const QString &defaultText)
{
QWidget *topLevel = parent;
while (topLevel->parentWidget())
topLevel = topLevel->parentWidget();
auto *dialog = new OverlayDialog(topLevel);
dialog->setTitle(title);
dialog->setMessage(prompt);
dialog->setDialogType(Input);
dialog->setInputMode(true, "请输入...");
dialog->m_inputEdit->setText(defaultText);
dialog->setCallback(callback);
dialog->showDialog();
}