Files
cbh/ElaWidgetTools/private/ElaApplicationPrivate.cpp
2025-09-20 01:41:33 +08:00

159 lines
5.7 KiB
C++

#include "ElaApplicationPrivate.h"
#include <QApplication>
#include <QEvent>
#include <QImage>
#include <QPalette>
#include <QScreen>
#include <QThread>
#include <QWidget>
#include <QtMath>
#include "ElaApplication.h"
#include "ElaMicaBaseInitObject.h"
#include "ElaWinShadowHelper.h"
ElaApplicationPrivate::ElaApplicationPrivate(QObject *parent) : QObject{parent} {}
ElaApplicationPrivate::~ElaApplicationPrivate() {}
void ElaApplicationPrivate::onThemeModeChanged(ElaThemeType::ThemeMode themeMode) {
_themeMode = themeMode;
switch (_pWindowDisplayMode) {
case ElaApplicationType::Normal: {
break;
}
case ElaApplicationType::ElaMica: {
_updateAllMicaWidget();
break;
}
default: {
#ifdef Q_OS_WIN
for (auto widget : _micaWidgetList) {
ElaWinShadowHelper::getInstance()->setWindowThemeMode(widget->winId(), _themeMode == ElaThemeType::Light);
}
#endif
break;
}
}
}
bool ElaApplicationPrivate::eventFilter(QObject *watched, QEvent *event) {
switch (event->type()) {
case QEvent::Show: {
if (_pWindowDisplayMode == ElaApplicationType::WindowDisplayMode::ElaMica) {
QWidget *widget = qobject_cast<QWidget *>(watched);
if (widget) {
_updateMica(widget);
}
} else if (_pWindowDisplayMode != ElaApplicationType::WindowDisplayMode::Normal) {
#ifdef Q_OS_WIN
QWidget *widget = qobject_cast<QWidget *>(watched);
if (widget) {
ElaWinShadowHelper::getInstance()->setWindowDisplayMode(widget, _pWindowDisplayMode, _pWindowDisplayMode);
}
#endif
}
break;
}
case QEvent::Move:
case QEvent::Resize: {
if (_pWindowDisplayMode == ElaApplicationType::WindowDisplayMode::ElaMica) {
QWidget *widget = qobject_cast<QWidget *>(watched);
if (widget) {
_updateMica(widget);
}
}
break;
}
case QEvent::Destroy: {
QWidget *widget = qobject_cast<QWidget *>(watched);
if (widget) {
_micaWidgetList.removeOne(widget);
}
break;
}
default: {
break;
}
}
return QObject::eventFilter(watched, event);
}
void ElaApplicationPrivate::_initMicaBaseImage(QImage img) {
Q_Q(ElaApplication);
if (img.isNull()) {
return;
}
QThread *initThread = new QThread();
ElaMicaBaseInitObject *initObject = new ElaMicaBaseInitObject(this);
connect(initThread, &QThread::finished, initObject, &ElaMicaBaseInitObject::deleteLater);
connect(initObject, &ElaMicaBaseInitObject::initFinished, initThread, [=]() {
Q_EMIT q->pWindowDisplayModeChanged();
_updateAllMicaWidget();
initThread->quit();
initThread->wait();
initThread->deleteLater();
});
initObject->moveToThread(initThread);
initThread->start();
connect(this, &ElaApplicationPrivate::initMicaBase, initObject, &ElaMicaBaseInitObject::onInitMicaBase);
Q_EMIT initMicaBase(img);
}
QRect ElaApplicationPrivate::_calculateWindowVirtualGeometry(QWidget *widget) {
QRect geometry = widget->geometry();
qreal xImageRatio = 1, yImageRatio = 1;
QRect relativeGeometry;
if (qApp->screens().count() > 1) {
QScreen *currentScreen = qApp->screenAt(geometry.topLeft());
if (currentScreen) {
QRect screenGeometry = currentScreen->availableGeometry();
xImageRatio = (qreal)_lightBaseImage.width() / screenGeometry.width();
yImageRatio = (qreal)_lightBaseImage.height() / screenGeometry.height();
relativeGeometry = QRect((geometry.x() - screenGeometry.x()) * xImageRatio, (geometry.y() - screenGeometry.y()) * yImageRatio,
geometry.width() * xImageRatio, geometry.height() * yImageRatio);
return relativeGeometry;
}
}
QRect primaryScreenGeometry = qApp->primaryScreen()->availableGeometry();
xImageRatio = (qreal)_lightBaseImage.width() / primaryScreenGeometry.width();
yImageRatio = (qreal)_lightBaseImage.height() / primaryScreenGeometry.height();
relativeGeometry = QRect((geometry.x() - primaryScreenGeometry.x()) * xImageRatio, (geometry.y() - primaryScreenGeometry.y()) * yImageRatio,
geometry.width() * xImageRatio, geometry.height() * yImageRatio);
return relativeGeometry;
}
void ElaApplicationPrivate::_updateMica(QWidget *widget, bool isProcessEvent) {
if (widget->isVisible()) {
QPalette palette = widget->palette();
if (_themeMode == ElaThemeType::Light) {
palette.setBrush(QPalette::Window, _lightBaseImage.copy(_calculateWindowVirtualGeometry(widget))
.scaled(widget->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
} else {
palette.setBrush(
QPalette::Window,
_darkBaseImage.copy(_calculateWindowVirtualGeometry(widget)).scaled(widget->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
}
widget->setPalette(palette);
if (isProcessEvent) {
QApplication::processEvents();
}
}
}
void ElaApplicationPrivate::_updateAllMicaWidget() {
if (_pWindowDisplayMode == ElaApplicationType::WindowDisplayMode::ElaMica) {
for (auto widget : _micaWidgetList) {
_updateMica(widget, false);
}
}
}
void ElaApplicationPrivate::_resetAllMicaWidget() {
for (auto widget : _micaWidgetList) {
QPalette palette = widget->palette();
palette.setBrush(QPalette::Window, Qt::transparent);
widget->setPalette(palette);
}
}