c0274df69a
NO_CHANGELOG
276 lines
7.0 KiB
C++
276 lines
7.0 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2011 Aaron Seigo <aseigo@kde.org>
|
|
SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
SPDX-License-Identifier: LGPL-2.0-or-later
|
|
*/
|
|
|
|
#include "debug_p.h"
|
|
#include "dialogshadows_p.h"
|
|
|
|
#include <KWindowShadow>
|
|
|
|
class DialogShadows::Private
|
|
{
|
|
public:
|
|
Private(DialogShadows *shadows)
|
|
: q(shadows)
|
|
{
|
|
}
|
|
|
|
~Private()
|
|
{
|
|
}
|
|
|
|
void clearTiles();
|
|
void setupTiles();
|
|
void initTile(const QString &element);
|
|
void updateShadow(QWindow *window, Plasma::FrameSvg::EnabledBorders);
|
|
void clearShadow(QWindow *window);
|
|
void updateShadows();
|
|
void windowDestroyed(QObject *deletedObject);
|
|
|
|
DialogShadows *q;
|
|
|
|
QHash<QWindow *, Plasma::FrameSvg::EnabledBorders> m_windows;
|
|
QHash<QWindow *, KWindowShadow *> m_shadows;
|
|
QVector<KWindowShadowTile::Ptr> m_tiles;
|
|
};
|
|
|
|
class DialogShadowsSingleton
|
|
{
|
|
public:
|
|
DialogShadowsSingleton()
|
|
{
|
|
}
|
|
|
|
DialogShadows self;
|
|
};
|
|
|
|
Q_GLOBAL_STATIC(DialogShadowsSingleton, privateDialogShadowsSelf)
|
|
|
|
DialogShadows::DialogShadows(QObject *parent, const QString &prefix)
|
|
: Plasma::Svg(parent)
|
|
, d(new Private(this))
|
|
{
|
|
setImagePath(prefix);
|
|
connect(this, SIGNAL(repaintNeeded()), this, SLOT(updateShadows()));
|
|
}
|
|
|
|
DialogShadows::~DialogShadows()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
DialogShadows *DialogShadows::self()
|
|
{
|
|
return &privateDialogShadowsSelf->self;
|
|
}
|
|
|
|
void DialogShadows::addWindow(QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
|
{
|
|
if (!window) {
|
|
return;
|
|
}
|
|
|
|
d->m_windows[window] = enabledBorders;
|
|
d->updateShadow(window, enabledBorders);
|
|
connect(window, SIGNAL(destroyed(QObject *)), this, SLOT(windowDestroyed(QObject *)), Qt::UniqueConnection);
|
|
}
|
|
|
|
void DialogShadows::removeWindow(QWindow *window)
|
|
{
|
|
if (!d->m_windows.contains(window)) {
|
|
return;
|
|
}
|
|
|
|
d->m_windows.remove(window);
|
|
disconnect(window, nullptr, this, nullptr);
|
|
d->clearShadow(window);
|
|
|
|
if (d->m_windows.isEmpty()) {
|
|
d->clearTiles();
|
|
}
|
|
}
|
|
|
|
void DialogShadows::setEnabledBorders(QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
|
{
|
|
if (!window || !d->m_windows.contains(window)) {
|
|
return;
|
|
}
|
|
|
|
d->updateShadow(window, enabledBorders);
|
|
}
|
|
|
|
void DialogShadows::Private::windowDestroyed(QObject *deletedObject)
|
|
{
|
|
QWindow *window = static_cast<QWindow *>(deletedObject);
|
|
|
|
m_windows.remove(window);
|
|
clearShadow(window);
|
|
|
|
if (m_windows.isEmpty()) {
|
|
clearTiles();
|
|
}
|
|
}
|
|
|
|
void DialogShadows::Private::updateShadows()
|
|
{
|
|
setupTiles();
|
|
QHash<QWindow *, Plasma::FrameSvg::EnabledBorders>::const_iterator i;
|
|
for (i = m_windows.constBegin(); i != m_windows.constEnd(); ++i) {
|
|
updateShadow(i.key(), i.value());
|
|
}
|
|
}
|
|
|
|
void DialogShadows::Private::initTile(const QString &element)
|
|
{
|
|
const QImage image = q->pixmap(element).toImage();
|
|
|
|
KWindowShadowTile::Ptr tile = KWindowShadowTile::Ptr::create();
|
|
tile->setImage(image);
|
|
|
|
m_tiles << tile;
|
|
}
|
|
|
|
void DialogShadows::Private::setupTiles()
|
|
{
|
|
clearTiles();
|
|
|
|
initTile(QStringLiteral("shadow-top"));
|
|
initTile(QStringLiteral("shadow-topright"));
|
|
initTile(QStringLiteral("shadow-right"));
|
|
initTile(QStringLiteral("shadow-bottomright"));
|
|
initTile(QStringLiteral("shadow-bottom"));
|
|
initTile(QStringLiteral("shadow-bottomleft"));
|
|
initTile(QStringLiteral("shadow-left"));
|
|
initTile(QStringLiteral("shadow-topleft"));
|
|
}
|
|
|
|
void DialogShadows::Private::clearTiles()
|
|
{
|
|
m_tiles.clear();
|
|
}
|
|
|
|
void DialogShadows::Private::updateShadow(QWindow *window, Plasma::FrameSvg::EnabledBorders enabledBorders)
|
|
{
|
|
if (m_tiles.isEmpty()) {
|
|
setupTiles();
|
|
}
|
|
|
|
KWindowShadow *&shadow = m_shadows[window];
|
|
|
|
if (!shadow) {
|
|
shadow = new KWindowShadow(q);
|
|
}
|
|
|
|
if (shadow->isCreated()) {
|
|
shadow->destroy();
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
|
shadow->setTopTile(m_tiles.at(0));
|
|
} else {
|
|
shadow->setTopTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::TopBorder && enabledBorders & Plasma::FrameSvg::RightBorder) {
|
|
shadow->setTopRightTile(m_tiles.at(1));
|
|
} else {
|
|
shadow->setTopRightTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
|
shadow->setRightTile(m_tiles.at(2));
|
|
} else {
|
|
shadow->setRightTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder && enabledBorders & Plasma::FrameSvg::RightBorder) {
|
|
shadow->setBottomRightTile(m_tiles.at(3));
|
|
} else {
|
|
shadow->setBottomRightTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
|
shadow->setBottomTile(m_tiles.at(4));
|
|
} else {
|
|
shadow->setBottomTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder && enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
|
shadow->setBottomLeftTile(m_tiles.at(5));
|
|
} else {
|
|
shadow->setBottomLeftTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
|
shadow->setLeftTile(m_tiles.at(6));
|
|
} else {
|
|
shadow->setLeftTile(nullptr);
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::TopBorder && enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
|
shadow->setTopLeftTile(m_tiles.at(7));
|
|
} else {
|
|
shadow->setTopLeftTile(nullptr);
|
|
}
|
|
|
|
QMargins padding;
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::TopBorder) {
|
|
const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-top-margin"));
|
|
if (marginHint.isValid()) {
|
|
padding.setTop(marginHint.height());
|
|
} else {
|
|
padding.setTop(m_tiles[0]->image().height());
|
|
}
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::RightBorder) {
|
|
const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-right-margin"));
|
|
if (marginHint.isValid()) {
|
|
padding.setRight(marginHint.width());
|
|
} else {
|
|
padding.setRight(m_tiles[2]->image().width());
|
|
}
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::BottomBorder) {
|
|
const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-bottom-margin"));
|
|
if (marginHint.isValid()) {
|
|
padding.setBottom(marginHint.height());
|
|
} else {
|
|
padding.setBottom(m_tiles[4]->image().height());
|
|
}
|
|
}
|
|
|
|
if (enabledBorders & Plasma::FrameSvg::LeftBorder) {
|
|
const QSize marginHint = q->elementSize(QStringLiteral("shadow-hint-left-margin"));
|
|
if (marginHint.isValid()) {
|
|
padding.setLeft(marginHint.width());
|
|
} else {
|
|
padding.setLeft(m_tiles[6]->image().width());
|
|
}
|
|
}
|
|
|
|
shadow->setPadding(padding);
|
|
shadow->setWindow(window);
|
|
|
|
if (!shadow->create()) {
|
|
qCWarning(LOG_PLASMAQUICK) << "Couldn't create KWindowShadow for" << window;
|
|
}
|
|
}
|
|
|
|
void DialogShadows::Private::clearShadow(QWindow *window)
|
|
{
|
|
delete m_shadows.take(window);
|
|
}
|
|
|
|
bool DialogShadows::enabled() const
|
|
{
|
|
return hasElement(QStringLiteral("shadow-left"));
|
|
}
|
|
|
|
#include "moc_dialogshadows_p.cpp"
|