thedesk/platform/messagedialog/messagedialoghelper.cpp
2023-09-20 20:29:02 +10:00

153 lines
5 KiB
C++

/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2020 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "messagedialoghelper.h"
#include "messagedialog.h"
#include <QApplication>
#include <QDebug>
#include <QGraphicsBlurEffect>
#include <QMainWindow>
#include <QPainter>
#include <QPointer>
#include <QWindow>
#include <tcsdtools.h>
#include <tscrim.h>
#include <tvariantanimation.h>
struct MessageDialogHelperPrivate {
MessageDialog* dlg;
QEventLoop eventLoop;
QPointer<QWindow> parent;
QPointer<QWidget> parentWidget;
QPointer<QWidget> cover2;
const int coverOverscan = 50;
};
MessageDialogHelper::MessageDialogHelper() :
QPlatformMessageDialogHelper() {
d = new MessageDialogHelperPrivate();
d->dlg = new MessageDialog();
connect(d->dlg, &MessageDialog::clicked, this, [this] {
if (d->eventLoop.isRunning()) d->eventLoop.exit();
this->hide();
});
connect(d->dlg, &MessageDialog::checkBoxStateChanged, this, &MessageDialogHelper::checkBoxStateChanged);
connect(d->dlg, &MessageDialog::clicked, this, &MessageDialogHelper::clicked);
}
MessageDialogHelper::~MessageDialogHelper() {
d->dlg->deleteLater();
if (d->cover2) d->cover2->deleteLater();
delete d;
}
void MessageDialogHelper::updateWindowGeometry() {
if (d->parent) {
QRect geometry;
if (d->parentWidget) {
geometry = QRect(-d->coverOverscan, -d->coverOverscan, d->parentWidget->width() + 2 * d->coverOverscan, d->parentWidget->height() + 2 * d->coverOverscan);
} else {
geometry = QRect(-d->coverOverscan, -d->coverOverscan, d->parent->width() + 2 * d->coverOverscan, d->parent->height() + 2 * d->coverOverscan);
}
if (d->cover2) d->cover2->setGeometry(geometry);
d->dlg->updateGeometry();
} else {
d->dlg->setFixedSize(d->dlg->frameGeometry().size());
}
}
void MessageDialogHelper::exec() {
d->dlg->setOptions(this->options());
d->eventLoop.exec();
}
bool MessageDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow* parent) {
QWidget* widget = nullptr;
if (parent) {
for (QWidget* w : QApplication::allWidgets()) {
if (w->winId() == parent->winId()) widget = w->window();
}
}
QMainWindow* mainWindow = qobject_cast<QMainWindow*>(widget);
if (mainWindow && tCsdTools::csdsInstalled(mainWindow)) widget = mainWindow->centralWidget();
d->parentWidget = widget;
d->dlg->setOptions(this->options());
d->dlg->setWindowFlags(windowFlags);
if (d->parent) {
d->parent->disconnect(this);
}
d->parent = parent;
connect(parent, &QWindow::widthChanged, this, &MessageDialogHelper::updateWindowGeometry);
connect(parent, &QWindow::heightChanged, this, &MessageDialogHelper::updateWindowGeometry);
connect(parent, &QWindow::xChanged, this, &MessageDialogHelper::updateWindowGeometry);
connect(parent, &QWindow::yChanged, this, &MessageDialogHelper::updateWindowGeometry);
if (widget) {
tScrim::scrimForWidget(widget)->show();
d->dlg->setParent(widget);
d->dlg->show();
d->dlg->raise();
// For some reason, Qt doesn't render this properly on tCsd apps
// but it fixes itself if we have a transparent widget on top
d->cover2 = new QWidget();
d->cover2->setAttribute(Qt::WA_TransparentForMouseEvents);
d->cover2->setParent(widget);
d->cover2->show();
d->cover2->raise();
d->dlg->animateIn();
}
updateWindowGeometry();
d->dlg->show();
return true;
}
void MessageDialogHelper::hide() {
if (d->parentWidget) {
d->dlg->animateOut();
tScrim::scrimForWidget(d->parentWidget)->hide();
if (d->cover2) d->cover2->hide();
} else {
d->dlg->hide();
if (d->cover2) d->cover2->hide();
}
}
void MessageDialogHelper::setOptions(const QSharedPointer<QMessageDialogOptions>& options) {
QPlatformMessageDialogHelper::setOptions(options);
d->dlg->setOptions(options);
}
QVariant MessageDialogHelper::styleHint(StyleHint hint) const {
if (hint == DialogIsQtWindow) {
return true;
}
return QPlatformMessageDialogHelper::StyleHint(hint);
}