mirror of
https://github.com/KDE/latte-dock.git
synced 2025-02-04 01:47:31 +03:00
provide effect/masks regions for custom backgrounds
--PlasmaExtended::Theme produces QRegions based on corners radius that can be consumed afterwards from Effects calculations in order to provide correct QRegions for custom backgrounds produced from custom background radius option
This commit is contained in:
parent
bd16a0da69
commit
1142950f69
@ -31,6 +31,7 @@
|
||||
// Qt
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QPainter>
|
||||
#include <QProcess>
|
||||
|
||||
// KDE
|
||||
@ -414,13 +415,74 @@ void Theme::loadThemeLightness()
|
||||
}
|
||||
}
|
||||
|
||||
const CornerRegions &Theme::cornersMask(const int &size)
|
||||
const CornerRegions &Theme::cornersMask(const int &radius)
|
||||
{
|
||||
if (m_cornerRegions.contains(size)) {
|
||||
return m_cornerRegions[size];
|
||||
if (m_cornerRegions.contains(radius)) {
|
||||
return m_cornerRegions[radius];
|
||||
}
|
||||
|
||||
return m_cornerRegions[size];
|
||||
qDebug() << radius;
|
||||
CornerRegions corners;
|
||||
|
||||
int axis = (2 * radius) + 2;
|
||||
QImage cornerimage(axis, axis, QImage::Format_ARGB32);
|
||||
QPainter painter(&cornerimage);
|
||||
//!does not provide valid masks
|
||||
//painter.setRenderHints(QPainter::Antialiasing);
|
||||
|
||||
QPen pen(Qt::black);
|
||||
pen.setStyle(Qt::SolidLine);
|
||||
pen.setWidth(1);
|
||||
painter.setPen(pen);
|
||||
|
||||
QRect rectArea(0,0,axis,axis);
|
||||
painter.fillRect(rectArea, Qt::white);
|
||||
painter.drawRoundedRect(rectArea, axis, axis);
|
||||
|
||||
QRegion topleft;
|
||||
for(int y=0; y<radius; ++y) {
|
||||
QRgb *line = (QRgb *)cornerimage.scanLine(y);
|
||||
|
||||
QString bits;
|
||||
int width{0};
|
||||
for(int x=0; x<radius; ++x) {
|
||||
QRgb point = line[x];
|
||||
|
||||
if (QColor(point) == Qt::black) {
|
||||
bits = bits + "1 ";
|
||||
width = qMax(0, x);
|
||||
break;
|
||||
} else {
|
||||
bits = bits + "0 ";
|
||||
}
|
||||
}
|
||||
|
||||
if (width>0) {
|
||||
topleft += QRect(0, y, width, 1);
|
||||
}
|
||||
|
||||
qDebug()<< " " << bits;
|
||||
}
|
||||
corners.topLeft = topleft;
|
||||
|
||||
QTransform transform;
|
||||
transform.rotate(90);
|
||||
corners.topRight = transform.map(corners.topLeft);
|
||||
corners.topRight.translate(corners.topLeft.boundingRect().width(), 0);
|
||||
|
||||
corners.bottomRight = transform.map(corners.topRight);
|
||||
corners.bottomRight.translate(corners.topLeft.boundingRect().width(), 0);
|
||||
|
||||
corners.bottomLeft = transform.map(corners.bottomRight);
|
||||
corners.bottomLeft.translate(corners.topLeft.boundingRect().width(), 0);
|
||||
|
||||
//qDebug() << " reg top;: " << corners.topLeft;
|
||||
//qDebug() << " reg topr: " << corners.topRight;
|
||||
//qDebug() << " reg bottomr: " << corners.bottomRight;
|
||||
//qDebug() << " reg bottoml: " << corners.bottomLeft;
|
||||
|
||||
m_cornerRegions[radius] = corners;
|
||||
return m_cornerRegions[radius];
|
||||
}
|
||||
|
||||
void Theme::loadConfig()
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
WindowSystem::SchemeColors *lightTheme() const;
|
||||
WindowSystem::SchemeColors *darkTheme() const;
|
||||
|
||||
const CornerRegions &cornersMask(const int &size);
|
||||
const CornerRegions &cornersMask(const int &radius);
|
||||
|
||||
void load();
|
||||
|
||||
|
@ -54,14 +54,19 @@ Effects::~Effects()
|
||||
void Effects::init()
|
||||
{
|
||||
connect(this, &Effects::backgroundOpacityChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::backgroundCornersMaskChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::backgroundRadiusEnabledChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::drawEffectsChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::enabledBordersChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::rectChanged, this, &Effects::updateEffects);
|
||||
connect(this, &Effects::backgroundRadiusChanged, this, &Effects::updateBackgroundCorners);
|
||||
|
||||
connect(this, &Effects::backgroundCornersMaskChanged, this, &Effects::updateMask);
|
||||
connect(this, &Effects::backgroundRadiusEnabledChanged, this, &Effects::updateMask);
|
||||
connect(this, &Effects::subtractedMaskRegionsChanged, this, &Effects::updateMask);
|
||||
connect(this, &Effects::unitedMaskRegionsChanged, this, &Effects::updateMask);
|
||||
|
||||
connect(this, &Effects::backgroundRadiusChanged, this, &Effects::updateBackgroundCorners);
|
||||
|
||||
connect(this, &Effects::drawShadowsChanged, this, [&]() {
|
||||
if (m_view->behaveAsPlasmaPanel()) {
|
||||
updateEnabledBorders();
|
||||
@ -359,6 +364,39 @@ void Effects::removeUnitedMaskRegion(const QString ®ionid)
|
||||
emit unitedMaskRegionsChanged();
|
||||
}
|
||||
|
||||
QRegion Effects::customMask(const QRect &rect)
|
||||
{
|
||||
QRegion result = rect;
|
||||
int dx = rect.right() - m_cornersMaskRegion.topLeft.boundingRect().width() + 1;
|
||||
int dy = rect.bottom() - m_cornersMaskRegion.topLeft.boundingRect().height() + 1;
|
||||
|
||||
if (m_hasTopLeftCorner) {
|
||||
QRegion tl = m_cornersMaskRegion.topLeft;
|
||||
tl.translate(rect.x(), rect.y());
|
||||
result = result.subtracted(tl);
|
||||
}
|
||||
|
||||
if (m_hasTopRightCorner) {
|
||||
QRegion tr = m_cornersMaskRegion.topRight;
|
||||
tr.translate(rect.x() + dx, rect.y());
|
||||
result = result.subtracted(tr);
|
||||
}
|
||||
|
||||
if (m_hasBottomRightCorner) {
|
||||
QRegion br = m_cornersMaskRegion.bottomRight;
|
||||
br.translate(rect.x() + dx, rect.y() + dy);
|
||||
result = result.subtracted(br);
|
||||
}
|
||||
|
||||
if (m_hasBottomLeftCorner) {
|
||||
QRegion bl = m_cornersMaskRegion.bottomLeft;
|
||||
bl.translate(rect.x(), rect.y() + dy);
|
||||
result = result.subtracted(bl);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QRegion Effects::maskCombinedRegion()
|
||||
{
|
||||
QRegion region = m_mask;
|
||||
@ -380,9 +418,10 @@ void Effects::updateBackgroundCorners()
|
||||
return;
|
||||
}
|
||||
|
||||
PlasmaExtended::CornerRegions corners = m_corona->themeExtended()->cornersMask(m_backgroundRadius);
|
||||
m_corona->themeExtended()->cornersMask(m_backgroundRadius);
|
||||
|
||||
m_cornersMaskRegion = corners;
|
||||
m_cornersMaskRegion = m_corona->themeExtended()->cornersMask(m_backgroundRadius);
|
||||
emit backgroundCornersMaskChanged();
|
||||
}
|
||||
|
||||
void Effects::updateMask()
|
||||
@ -394,26 +433,35 @@ void Effects::updateMask()
|
||||
m_view->setMask(maskCombinedRegion());
|
||||
}
|
||||
} else {
|
||||
//! this is used when compositing is disabled and provides
|
||||
//! the correct way for the mask to be painted in order for
|
||||
//! rounded corners to be shown correctly
|
||||
//! the enabledBorders check was added because there was cases
|
||||
//! that the mask region wasn't calculated correctly after location changes
|
||||
if (!m_background) {
|
||||
if (m_background && m_background->enabledBorders() != m_enabledBorders) {
|
||||
delete m_background;
|
||||
QRegion fixedMask;
|
||||
|
||||
if (m_backgroundRadiusEnabled) {
|
||||
//! CustomBackground way
|
||||
fixedMask = customMask(QRect(0,0,m_mask.width(), m_mask.height()));
|
||||
} else {
|
||||
//! Plasma::Theme way
|
||||
//! this is used when compositing is disabled and provides
|
||||
//! the correct way for the mask to be painted in order for
|
||||
//! rounded corners to be shown correctly
|
||||
//! the enabledBorders check was added because there was cases
|
||||
//! that the mask region wasn't calculated correctly after location changes
|
||||
if (!m_background) {
|
||||
if (m_background && m_background->enabledBorders() != m_enabledBorders) {
|
||||
delete m_background;
|
||||
}
|
||||
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
}
|
||||
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
if (m_background->imagePath() != "widgets/panel-background") {
|
||||
m_background->setImagePath(QStringLiteral("widgets/panel-background"));
|
||||
}
|
||||
|
||||
m_background->setEnabledBorders(m_enabledBorders);
|
||||
m_background->resizeFrame(m_mask.size());
|
||||
fixedMask = m_background->mask();
|
||||
}
|
||||
|
||||
if (m_background->imagePath() != "widgets/panel-background") {
|
||||
m_background->setImagePath(QStringLiteral("widgets/panel-background"));
|
||||
}
|
||||
|
||||
m_background->setEnabledBorders(m_enabledBorders);
|
||||
m_background->resizeFrame(m_mask.size());
|
||||
QRegion fixedMask = m_background->mask();
|
||||
fixedMask.translate(m_mask.x(), m_mask.y());
|
||||
|
||||
//! fix for KF5.32 that return empty QRegion's for the mask
|
||||
@ -452,30 +500,34 @@ void Effects::updateEffects()
|
||||
if (m_drawEffects) {
|
||||
if (!m_view->behaveAsPlasmaPanel()) {
|
||||
if (!m_rect.isNull() && !m_rect.isEmpty()) {
|
||||
//! this is used when compositing is disabled and provides
|
||||
//! the correct way for the mask to be painted in order for
|
||||
//! rounded corners to be shown correctly
|
||||
if (!m_background) {
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
QRegion backMask;
|
||||
|
||||
if (m_backgroundRadiusEnabled) {
|
||||
//! CustomBackground way
|
||||
backMask = customMask(QRect(0,0,m_rect.width(), m_rect.height()));
|
||||
} else {
|
||||
//! Plasma::Theme way
|
||||
//! this is used when compositing is disabled and provides
|
||||
//! the correct way for the mask to be painted in order for
|
||||
//! rounded corners to be shown correctly
|
||||
if (!m_background) {
|
||||
m_background = new Plasma::FrameSvg(this);
|
||||
}
|
||||
|
||||
if (m_background->imagePath() != "widgets/panel-background") {
|
||||
m_background->setImagePath(QStringLiteral("widgets/panel-background"));
|
||||
}
|
||||
|
||||
m_background->setEnabledBorders(m_enabledBorders);
|
||||
m_background->resizeFrame(m_rect.size());
|
||||
|
||||
backMask = m_background->mask();
|
||||
}
|
||||
|
||||
if (m_background->imagePath() != "widgets/panel-background") {
|
||||
m_background->setImagePath(QStringLiteral("widgets/panel-background"));
|
||||
}
|
||||
|
||||
m_background->setEnabledBorders(m_enabledBorders);
|
||||
m_background->resizeFrame(m_rect.size());
|
||||
|
||||
QRegion backMask = m_background->mask();
|
||||
|
||||
//! There are cases that mask is NULL even though it should not
|
||||
//! Example: SidebarOnDemand from v0.10 that BEHAVEASPLASMAPANEL in EditMode
|
||||
//! switching multiple times between inConfigureAppletsMode and LiveEditMode
|
||||
//! is such a case
|
||||
QRegion fixedMask;
|
||||
|
||||
//! adjust mask coordinates based on local coordinates
|
||||
int fX = m_rect.x(); int fY = m_rect.y();
|
||||
|
||||
|
||||
#if KF5_VERSION_MINOR >= 65
|
||||
//! Latte is now using GtkFrameExtents so Effects geometries must be adjusted
|
||||
//! windows that use GtkFrameExtents and apply Effects on them they take GtkFrameExtents
|
||||
@ -489,6 +541,12 @@ void Effects::updateEffects()
|
||||
}
|
||||
#endif
|
||||
|
||||
//! There are cases that mask is NULL even though it should not
|
||||
//! Example: SidebarOnDemand from v0.10 that BEHAVEASPLASMAPANEL in EditMode
|
||||
//! switching multiple times between inConfigureAppletsMode and LiveEditMode
|
||||
//! is such a case
|
||||
QRegion fixedMask;
|
||||
|
||||
if (!backMask.isNull()) {
|
||||
fixedMask = backMask;
|
||||
fixedMask.translate(fX, fY);
|
||||
@ -633,6 +691,11 @@ void Effects::updateEnabledBorders()
|
||||
}
|
||||
}
|
||||
|
||||
m_hasTopLeftCorner = (borders == Plasma::FrameSvg::AllBorders) || ((borders & Plasma::FrameSvg::TopBorder) && (borders & Plasma::FrameSvg::LeftBorder));
|
||||
m_hasTopRightCorner = (borders == Plasma::FrameSvg::AllBorders) || ((borders & Plasma::FrameSvg::TopBorder) && (borders & Plasma::FrameSvg::RightBorder));
|
||||
m_hasBottomLeftCorner = (borders == Plasma::FrameSvg::AllBorders) || ((borders & Plasma::FrameSvg::BottomBorder) && (borders & Plasma::FrameSvg::LeftBorder));
|
||||
m_hasBottomRightCorner = (borders == Plasma::FrameSvg::AllBorders) || ((borders & Plasma::FrameSvg::BottomBorder) && (borders & Plasma::FrameSvg::RightBorder));
|
||||
|
||||
if (m_enabledBorders != borders) {
|
||||
m_enabledBorders = borders;
|
||||
emit enabledBordersChanged();
|
||||
|
@ -149,6 +149,7 @@ private slots:
|
||||
private:
|
||||
bool backgroundRadiusIsEnabled() const;
|
||||
qreal currentMidValue(const qreal &max, const qreal &factor, const qreal &min) const;
|
||||
QRegion customMask(const QRect &rect);
|
||||
QRegion maskCombinedRegion();
|
||||
|
||||
private:
|
||||
@ -160,6 +161,11 @@ private:
|
||||
bool m_forceTopBorder{false};
|
||||
bool m_forceBottomBorder{false};
|
||||
|
||||
bool m_hasTopLeftCorner{false};
|
||||
bool m_hasTopRightCorner{false};
|
||||
bool m_hasBottomLeftCorner{false};
|
||||
bool m_hasBottomRightCorner{false};
|
||||
|
||||
int m_editShadow{0};
|
||||
int m_innerShadow{0};
|
||||
|
||||
|
@ -281,6 +281,20 @@ Item{
|
||||
&& !root.hideLengthScreenGaps))
|
||||
}
|
||||
|
||||
Binding{
|
||||
target: latteView && latteView.effects ? latteView.effects : null
|
||||
property: "backgroundRadius"
|
||||
when: latteView && latteView.effects
|
||||
value: background.customRadius
|
||||
}
|
||||
|
||||
Binding{
|
||||
target: latteView && latteView.effects ? latteView.effects : null
|
||||
property: "backgroundRadiusEnabled"
|
||||
when: latteView && latteView.effects
|
||||
value: background.customRadiusIsEnabled
|
||||
}
|
||||
|
||||
Binding{
|
||||
target: latteView && latteView.effects ? latteView.effects : null
|
||||
property: "backgroundOpacity"
|
||||
|
@ -968,6 +968,7 @@ PlasmaComponents.Page {
|
||||
RowLayout {
|
||||
Layout.minimumWidth: dialog.optionsWidth
|
||||
Layout.maximumWidth: Layout.minimumWidth
|
||||
enabled: LatteCore.WindowSystem.compositingActive
|
||||
visible: dialog.kirigamiLibraryIsFound
|
||||
|
||||
PlasmaComponents.Label {
|
||||
|
Loading…
x
Reference in New Issue
Block a user