Files
cbh/ElaWidgetTools/private/ElaApplicationPrivate.cpp
2025-09-19 22:40:52 +08:00

195 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);
}
}