quite mega-patch:
add a new function FrameSvg::alphaMask() that lets define an alpha-layer for the frame, that can be the frame itself or a mask- prefix allow for overlay elements on frames that can do a nice filigrane-effect, they can either be: -fixed position at 0,0 -random position consistent across plasma runs (only supported for applet backgrounds) -tiled -scaled svn path=/trunk/KDE/kdelibs/; revision=910655
This commit is contained in:
parent
22179dffbb
commit
831f2564d8
22
applet.cpp
22
applet.cpp
@ -73,6 +73,7 @@
|
||||
#include "scripting/appletscript.h"
|
||||
#include "svg.h"
|
||||
#include "framesvg.h"
|
||||
#include "private/framesvg_p.h"
|
||||
#include "popupapplet.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
@ -123,6 +124,7 @@ Applet::Applet(QObject *parentObject, const QVariantList &args)
|
||||
}
|
||||
|
||||
setParent(parentObject);
|
||||
|
||||
// WARNING: do not access config() OR globalConfig() in this method!
|
||||
// that requires a scene, which is not available at this point
|
||||
d->init();
|
||||
@ -760,6 +762,26 @@ void Applet::setBackgroundHints(const BackgroundHints hints)
|
||||
setMinimumSize(minimumSize().expandedTo(fitSize));
|
||||
}
|
||||
d->background->resizeFrame(boundingRect().size());
|
||||
|
||||
//if the background has an "overlay" element decide a random position for it and then save it so it's consistent across plasma starts
|
||||
if (d->background->hasElement("overlay")) {
|
||||
QSize overlaySize = d->background->elementSize("overlay");
|
||||
|
||||
d->background->d->overlayPos = config().readEntry("overlayposition", QPoint(overlaySize.width()*2, overlaySize.height()*2));
|
||||
|
||||
//position can never be overlaySize.width()*2, overlaySize.height()*2, if it is means we didn't found the position in the config file, or the theme is changed and the overlay size is smaller now
|
||||
if (d->background->d->overlayPos.x() >= overlaySize.width()*2 ||
|
||||
d->background->d->overlayPos.y() >= overlaySize.height()*2) {
|
||||
qsrand(id() + QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
d->background->d->overlayPos.rx() = - (overlaySize.width() /4) + (overlaySize.width() /4) * (qrand() % (4 + 1));
|
||||
|
||||
d->background->d->overlayPos.ry() = - (overlaySize.height() /4) + (overlaySize.height() /4) * (qrand() % (4 + 1));
|
||||
|
||||
config().writeEntry("overlayposition", d->background->d->overlayPos);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (d->background) {
|
||||
qreal left, top, right, bottom;
|
||||
d->background->getMargins(left, top, right, bottom);
|
||||
|
2
applet.h
2
applet.h
@ -36,6 +36,7 @@
|
||||
#include <plasma/plasma.h>
|
||||
#include <plasma/animator.h>
|
||||
#include <plasma/version.h>
|
||||
#include <plasma/framesvg.h>
|
||||
|
||||
class QWidget;
|
||||
|
||||
@ -54,6 +55,7 @@ class Extender;
|
||||
class ExtenderItem;
|
||||
class Package;
|
||||
|
||||
|
||||
/**
|
||||
* @class Applet plasma/applet.h <Plasma/Applet>
|
||||
*
|
||||
|
195
framesvg.cpp
195
framesvg.cpp
@ -19,97 +19,23 @@
|
||||
*/
|
||||
|
||||
#include "framesvg.h"
|
||||
#include "private/framesvg_p.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QSize>
|
||||
#include <QBitmap>
|
||||
#include <QRegion>
|
||||
#include <QTimer>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <plasma/theme.h>
|
||||
#include <plasma/applet.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class FrameData
|
||||
{
|
||||
public:
|
||||
FrameData()
|
||||
: enabledBorders(FrameSvg::AllBorders),
|
||||
frameSize(-1,-1)
|
||||
{
|
||||
}
|
||||
|
||||
FrameData(const FrameData &other)
|
||||
: enabledBorders(other.enabledBorders),
|
||||
frameSize(other.frameSize)
|
||||
{
|
||||
}
|
||||
|
||||
~FrameData()
|
||||
{
|
||||
}
|
||||
|
||||
FrameSvg::EnabledBorders enabledBorders;
|
||||
QPixmap cachedBackground;
|
||||
QRegion cachedMask;
|
||||
QSizeF frameSize;
|
||||
|
||||
//measures
|
||||
int topHeight;
|
||||
int leftWidth;
|
||||
int rightWidth;
|
||||
int bottomHeight;
|
||||
|
||||
//margins, are equal to the measures by default
|
||||
int topMargin;
|
||||
int leftMargin;
|
||||
int rightMargin;
|
||||
int bottomMargin;
|
||||
|
||||
//size of the svg where the size of the "center"
|
||||
//element is contentWidth x contentHeight
|
||||
bool noBorderPadding : 1;
|
||||
bool stretchBorders : 1;
|
||||
bool tileCenter : 1;
|
||||
};
|
||||
|
||||
class FrameSvgPrivate
|
||||
{
|
||||
public:
|
||||
FrameSvgPrivate(FrameSvg *psvg)
|
||||
: q(psvg),
|
||||
cacheAll(false),
|
||||
saveTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
~FrameSvgPrivate()
|
||||
{
|
||||
qDeleteAll(frames);
|
||||
frames.clear();
|
||||
}
|
||||
|
||||
void generateBackground(FrameData *frame);
|
||||
void scheduledCacheUpdate();
|
||||
void updateSizes();
|
||||
void updateNeeded();
|
||||
void updateAndSignalSizes();
|
||||
|
||||
Location location;
|
||||
QString prefix;
|
||||
|
||||
FrameSvg *q;
|
||||
|
||||
bool cacheAll : 1;
|
||||
QStringList framesToSave;
|
||||
QTimer *saveTimer;
|
||||
|
||||
QHash<QString, FrameData*> frames;
|
||||
};
|
||||
|
||||
FrameSvg::FrameSvg(QObject *parent)
|
||||
: Svg(parent),
|
||||
d(new FrameSvgPrivate(this))
|
||||
@ -338,45 +264,50 @@ QRectF FrameSvg::contentsRect() const
|
||||
}
|
||||
}
|
||||
|
||||
QRegion FrameSvg::mask() const
|
||||
QPixmap FrameSvg::alphaMask() const
|
||||
{
|
||||
FrameData *frame = d->frames[d->prefix];
|
||||
|
||||
if (frame->cachedMask.isEmpty()) {
|
||||
// ivan: we are testing whether we have the mask prefixed
|
||||
// elements to use for creating the mask.
|
||||
if (hasElement("mask-" + d->prefix + "center")) {
|
||||
QString oldPrefix = d->prefix;
|
||||
if (hasElement("mask-" + d->prefix + "center")) {
|
||||
QString oldPrefix = d->prefix;
|
||||
|
||||
// We are setting the prefix only temporary to generate
|
||||
// the needed mask image
|
||||
d->prefix = "mask-" + oldPrefix;
|
||||
// We are setting the prefix only temporary to generate
|
||||
// the needed mask image
|
||||
d->prefix = "mask-" + oldPrefix;
|
||||
|
||||
if (!d->frames.contains(d->prefix)) {
|
||||
d->frames.insert(d->prefix, new FrameData(*(d->frames[oldPrefix])));
|
||||
d->updateSizes();
|
||||
}
|
||||
|
||||
FrameData *maskFrame = d->frames[d->prefix];
|
||||
if (maskFrame->cachedBackground.isNull()) {
|
||||
d->generateBackground(maskFrame);
|
||||
if (maskFrame->cachedBackground.isNull()) {
|
||||
return QRegion();
|
||||
}
|
||||
}
|
||||
|
||||
frame->cachedMask = QBitmap(maskFrame->cachedBackground.alphaChannel().createMaskFromColor(Qt::black));
|
||||
d->prefix = oldPrefix;
|
||||
} else {
|
||||
if (frame->cachedBackground.isNull()) {
|
||||
d->generateBackground(frame);
|
||||
if (frame->cachedBackground.isNull()) {
|
||||
return QRegion();
|
||||
}
|
||||
}
|
||||
frame->cachedMask = QRegion(QBitmap(frame->cachedBackground.alphaChannel().createMaskFromColor(Qt::black)));
|
||||
if (!d->frames.contains(d->prefix)) {
|
||||
d->frames.insert(d->prefix, new FrameData(*(d->frames[oldPrefix])));
|
||||
d->updateSizes();
|
||||
}
|
||||
|
||||
FrameData *maskFrame = d->frames[d->prefix];
|
||||
if (maskFrame->cachedBackground.isNull() || maskFrame->frameSize != frame->frameSize ) {
|
||||
maskFrame->frameSize = frame->frameSize;
|
||||
maskFrame->cachedBackground = QPixmap();
|
||||
|
||||
d->generateBackground(maskFrame);
|
||||
if (maskFrame->cachedBackground.isNull()) {
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
|
||||
d->prefix = oldPrefix;
|
||||
return maskFrame->cachedBackground;
|
||||
} else {
|
||||
if (frame->cachedBackground.isNull()) {
|
||||
d->generateBackground(frame);
|
||||
if (frame->cachedBackground.isNull()) {
|
||||
return QPixmap();
|
||||
}
|
||||
}
|
||||
return frame->cachedBackground;
|
||||
}
|
||||
}
|
||||
|
||||
QRegion FrameSvg::mask() const
|
||||
{
|
||||
FrameData *frame = d->frames[d->prefix];
|
||||
frame->cachedMask = QRegion(QBitmap(alphaMask().alphaChannel().createMaskFromColor(Qt::black)));
|
||||
return frame->cachedMask;
|
||||
}
|
||||
|
||||
@ -423,6 +354,7 @@ QPixmap FrameSvg::framePixmap()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return frame->cachedBackground;
|
||||
}
|
||||
|
||||
@ -458,6 +390,7 @@ void FrameSvgPrivate::generateBackground(FrameData *frame)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QString id = QString::fromLatin1("%5_%4_%3_%2_%1_").
|
||||
arg(frame->enabledBorders).arg(frame->frameSize.width()).arg(frame->frameSize.height()).arg(prefix).arg(q->imagePath());
|
||||
|
||||
@ -632,6 +565,42 @@ void FrameSvgPrivate::generateBackground(FrameData *frame)
|
||||
}
|
||||
}
|
||||
|
||||
//Overlays
|
||||
if (!prefix.startsWith("mask-") && q->hasElement(prefix+"overlay")) {
|
||||
QPoint pos = QPoint(0, 0);
|
||||
QSize overlaySize = q->elementSize(prefix+"overlay");
|
||||
|
||||
//Random pos, stretched and tiled are mutually exclusive
|
||||
if (q->hasElement(prefix+"hint-overlay-random-pos")) {
|
||||
pos = overlayPos;
|
||||
//Stretched or Tiled?
|
||||
} else if (q->hasElement(prefix+"hint-overlay-stretch") || q->hasElement(prefix+"hint-overlay-tile")) {
|
||||
overlaySize = frame->frameSize.toSize();
|
||||
}
|
||||
|
||||
QString id = QString::fromLatin1("overlay_%7_%6_%5_%4_%3_%2_%1_").
|
||||
arg(overlayPos.y()).arg(overlayPos.x()).arg(frame->enabledBorders).arg(frame->frameSize.width()).arg(frame->frameSize.height()).arg(prefix).arg(q->imagePath());
|
||||
|
||||
QPixmap overlay = q->alphaMask();
|
||||
|
||||
QPainter overlayPainter(&overlay);
|
||||
overlayPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
|
||||
//Tiling?
|
||||
if (q->hasElement(prefix+"hint-overlay-tile")) {
|
||||
q->resize(q->elementSize(prefix+"overlay"));
|
||||
overlayPainter.drawTiledPixmap(QRect(QPoint(0,0), overlaySize), q->pixmap(prefix+"overlay"));
|
||||
q->resize();
|
||||
} else {
|
||||
q->paint(&overlayPainter, QRect(overlayPos, overlaySize), prefix+"overlay");
|
||||
}
|
||||
overlayPainter.end();
|
||||
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
||||
p.drawPixmap(overlayPos, overlay, QRect(overlayPos, overlaySize));
|
||||
}
|
||||
|
||||
if (!framesToSave.contains(prefix)) {
|
||||
framesToSave.append(prefix);
|
||||
}
|
||||
@ -639,9 +608,11 @@ void FrameSvgPrivate::generateBackground(FrameData *frame)
|
||||
saveTimer->start(300);
|
||||
}
|
||||
|
||||
|
||||
void FrameSvgPrivate::scheduledCacheUpdate()
|
||||
{
|
||||
foreach ( QString prefixToSave, framesToSave) {
|
||||
//insert background
|
||||
FrameData *frame = frames[prefix];
|
||||
framesToSave.removeAll(prefixToSave);
|
||||
|
||||
@ -651,6 +622,12 @@ void FrameSvgPrivate::scheduledCacheUpdate()
|
||||
//kDebug()<<"Saving to cache frame"<<id;
|
||||
|
||||
Theme::defaultTheme()->insertIntoCache(id, frame->cachedBackground);
|
||||
|
||||
//insert overlay
|
||||
id = QString::fromLatin1("overlay_%7_%6_%5_%4_%3_%2_%1_").
|
||||
arg(overlayPos.y()).arg(overlayPos.x()).arg(frame->enabledBorders).arg(frame->frameSize.width()).arg(frame->frameSize.height()).arg(prefix).arg(q->imagePath());
|
||||
|
||||
Theme::defaultTheme()->insertIntoCache(id, frame->cachedBackground);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +76,9 @@ class FrameSvgPrivate;
|
||||
class PLASMA_EXPORT FrameSvg : public Svg
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class Applet;
|
||||
|
||||
public:
|
||||
/**
|
||||
* These flags represents what borders should be drawn
|
||||
@ -205,6 +208,11 @@ class PLASMA_EXPORT FrameSvg : public Svg
|
||||
*/
|
||||
Q_INVOKABLE QRegion mask() const;
|
||||
|
||||
/**
|
||||
* @return a pixmap whose alpha channel is the opacity of the frame. It may be the frame itself or a special frame with the mask- prefix
|
||||
*/
|
||||
QPixmap alphaMask() const;
|
||||
|
||||
/**
|
||||
* Sets whether saving all the rendered prefixes in a cache or not
|
||||
* @arg cache if use the cache or not
|
||||
|
109
private/framesvg_p.h
Normal file
109
private/framesvg_p.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
|
||||
* Copyright 2009 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, 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 Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef PLASMA_FRAMESVG_P_H
|
||||
#define PLASMA_FRAMESVG_P_H
|
||||
|
||||
#include <QHash>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
class FrameData
|
||||
{
|
||||
public:
|
||||
FrameData()
|
||||
: enabledBorders(FrameSvg::AllBorders),
|
||||
frameSize(-1,-1)
|
||||
{
|
||||
}
|
||||
|
||||
FrameData(const FrameData &other)
|
||||
: enabledBorders(other.enabledBorders),
|
||||
frameSize(other.frameSize)
|
||||
{
|
||||
}
|
||||
|
||||
~FrameData()
|
||||
{
|
||||
}
|
||||
|
||||
FrameSvg::EnabledBorders enabledBorders;
|
||||
QPixmap cachedBackground;
|
||||
QRegion cachedMask;
|
||||
QSizeF frameSize;
|
||||
|
||||
//measures
|
||||
int topHeight;
|
||||
int leftWidth;
|
||||
int rightWidth;
|
||||
int bottomHeight;
|
||||
|
||||
//margins, are equal to the measures by default
|
||||
int topMargin;
|
||||
int leftMargin;
|
||||
int rightMargin;
|
||||
int bottomMargin;
|
||||
|
||||
//size of the svg where the size of the "center"
|
||||
//element is contentWidth x contentHeight
|
||||
bool noBorderPadding : 1;
|
||||
bool stretchBorders : 1;
|
||||
bool tileCenter : 1;
|
||||
};
|
||||
|
||||
class FrameSvgPrivate
|
||||
{
|
||||
public:
|
||||
FrameSvgPrivate(FrameSvg *psvg)
|
||||
: q(psvg),
|
||||
cacheAll(false),
|
||||
saveTimer(0),
|
||||
overlayPos(0,0)
|
||||
{
|
||||
}
|
||||
|
||||
~FrameSvgPrivate()
|
||||
{
|
||||
qDeleteAll(frames);
|
||||
frames.clear();
|
||||
}
|
||||
|
||||
void generateBackground(FrameData *frame);
|
||||
void scheduledCacheUpdate();
|
||||
void updateSizes();
|
||||
void updateNeeded();
|
||||
void updateAndSignalSizes();
|
||||
|
||||
Location location;
|
||||
QString prefix;
|
||||
|
||||
FrameSvg *q;
|
||||
|
||||
bool cacheAll : 1;
|
||||
QStringList framesToSave;
|
||||
QTimer *saveTimer;
|
||||
QPoint overlayPos;
|
||||
|
||||
QHash<QString, FrameData*> frames;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user