* add an updateConstraints to be used to do things globally that need to

prefix or suffix constraintsUpdated, e.g. manage the shadow
* add experimental support for dynamic shadow, based on a patch by
  zrusin; still issues to be addressed but it gives us the start of a
  layer-based means to do effects

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=696561
This commit is contained in:
Aaron J. Seigo 2007-08-05 08:41:55 +00:00
parent 2a2348b0e4
commit 21c804908e
6 changed files with 264 additions and 9 deletions

View File

@ -25,6 +25,7 @@ set(plasma_LIB_SRCS
plasma.cpp
plasma_export.h
scriptengine.cpp
shadowitem.cpp
svg.cpp
theme.cpp
karambamanager.cpp
@ -82,6 +83,7 @@ set(plasma_LIB_INCLUDES
plasma.h
plasma_export.h
scriptengine.cpp
shadowitem_p.h
svg.h
theme.h)

View File

@ -45,6 +45,7 @@
#include "plasma/packages_p.h"
#include "plasma/plasma.h"
#include "plasma/scriptengine.h"
#include "plasma/shadowitem_p.h"
#include "plasma/svg.h"
#include "plasma/widgets/widget.h"
@ -52,8 +53,7 @@
#include "plasma/widgets/pushbutton.h"
#include "plasma/widgets/vboxlayout.h"
//#include "stackblur_shadows.cpp"
//#define DYNAMIC_SHADOWS
namespace Plasma
{
@ -69,8 +69,9 @@ public:
background(0),
failureText(0),
scriptEngine(0),
cachedBackground(0),
configXml(0),
shadow(0),
cachedBackground(0),
kioskImmutable(false),
immutable(false),
hasConfigurationInterface(false),
@ -94,11 +95,13 @@ public:
delete background;
delete package;
delete configXml;
delete shadow;
delete cachedBackground;
}
void init(Applet* applet)
{
applet->setZValue(100);
//these lines fix behaviour somewhat with update()s after resize in qt 4.3.0,
//but the issues are fixed in 4.3.1 and this breaks shadows.
//applet->setFlag(QGraphicsItem::ItemClipsToShape, false);
@ -304,6 +307,7 @@ public:
Plasma::LineEdit *failureText;
ScriptEngine* scriptEngine;
ConfigXml* configXml;
ShadowItem* shadow;
QPixmap* cachedBackground;
bool kioskImmutable : 1;
bool immutable : 1;
@ -386,6 +390,12 @@ const Package* Applet::package() const
return d->package;
}
void Applet::updateConstraints()
{
constraintsUpdated();
setShadowShown(formFactor() == Planar);
}
void Applet::constraintsUpdated()
{
kDebug() << "Applet::constraintsUpdate(): constraints are FormFactor: " << formFactor() << ", Location: " << location();
@ -610,6 +620,11 @@ QColor Applet::color() const
void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(widget)
if (d->shadow && d->shadow->shadowedSize() != boundingRect().size()) {
//kDebug() << "sizes are " << d->shadow->shadowedSize() << boundingRect().size();
d->shadow->generate();
}
qreal zoomLevel = painter->transform().m11() / transform().m11();
if (zoomLevel == scalingFactor(Plasma::DesktopZoom)) { // Show Desktop
if (d->background) {
@ -815,7 +830,7 @@ QStringList Applet::knownCategories(const QString &parentApp)
QStringList categories;
foreach (KService::Ptr applet, offers) {
QString appletCategory = applet->property("X-KDE-PluginInfo-Category").toString();
kDebug() << " and we have " << appletCategory;
//kDebug() << " and we have " << appletCategory;
if (appletCategory.isEmpty()) {
if (!categories.contains(i18n("Misc"))) {
categories << i18n("Misc");
@ -871,6 +886,69 @@ Applet* Applet::loadApplet(const KPluginInfo& info, uint appletId, const QString
return loadApplet(info.pluginName(), appletId, args);
}
void Applet::setShadowShown(bool shown)
{
//There are various problems with shadows right now:
//
//1) shadows can be seen through translucent areas, which is probably technically correct ubt
//looks odd
//2) the shape of the item odesn't conform to the shape of the standard background, e.g. with
//rounded corners
#ifdef DYNAMIC_SHADOWS
if (shown) {
if (d->shadow) {
d->shadow->setVisible(true);
} else {
d->shadow = new ShadowItem(this);
if (scene()) {
scene()->addItem(d->shadow);
d->shadow->show();
}
}
} else {
delete d->shadow;
d->shadow = 0;
}
#endif
}
bool Applet::isShadowShown() const
{
return d->shadow && d->shadow->isVisible();
}
QVariant Applet::itemChange(GraphicsItemChange change, const QVariant &value)
{
if (!d->shadow) {
return QGraphicsItem::itemChange(change, value);
}
switch (change) {
case ItemPositionChange:
d->shadow->adjustPosition();
break;
case ItemSceneChange: {
QGraphicsScene *newScene = qvariant_cast<QGraphicsScene*>(value);
if (d->shadow->scene())
d->shadow->scene()->removeItem(d->shadow);
if (newScene) {
newScene->addItem(d->shadow);
d->shadow->generate();
d->shadow->adjustPosition();
d->shadow->show();
}
}
break;
case ItemVisibleChange:
d->shadow->setVisible(isVisible());
break;
default:
break;
};
return QGraphicsItem::itemChange(change, value);
}
} // Plasma namespace
#include "applet.moc"

View File

@ -157,6 +157,13 @@ class PLASMA_EXPORT Applet : public Widget
**/
const Package* package() const;
/**
* Called when any of the geometry constraints have been updated.
* This method calls constraintsUpdated, which may be reimplemented,
* once the Applet has been prepared for updating the constraints.
*/
void updateConstraints();
/**
* Called when any of the geometry constraints have been updated.
*
@ -444,6 +451,15 @@ class PLASMA_EXPORT Applet : public Widget
**/
virtual QList<QAction*> contextActions();
/**
* Sets shadow for the given applet.
*/
void setShadowShown(bool);
/**
* Returns true if the given item has a shadow shown.
*/
bool isShadowShown() const;
Q_SIGNALS:
/**
* Emitted when the applet needs to take (or lose) keyboard focus.
@ -513,7 +529,15 @@ class PLASMA_EXPORT Applet : public Widget
**/
bool eventFilter( QObject *o, QEvent *e );
/**
* @internal for adjusting the shadow
*/
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
protected Q_SLOTS:
/**
* @internal used to show the configuration of an applet on first show
*/
void performSetupConfig();
private:

View File

@ -111,7 +111,7 @@ void Corona::setLocation(Location location)
d->location = location;
foreach (Applet* applet, d->applets) {
applet->constraintsUpdated();
applet->updateConstraints();
}
}
@ -148,7 +148,7 @@ void Corona::setFormFactor(FormFactor formFactor)
}
foreach (Applet* applet, d->applets) {
applet->constraintsUpdated();
applet->updateConstraints();
}
}
@ -184,7 +184,8 @@ Applet* Corona::addApplet(const QString& name, const QStringList& args)
// Center exactly:
applet->setPos((width() / 2) - (appWidth / 2),(height() / 2) - (appHeight / 2));
addItem(applet);
applet->updateConstraints();
//applet->constraintsUpdated();
d->applets << applet;
connect(applet, SIGNAL(destroyed(QObject*)),
@ -216,7 +217,7 @@ void Corona::dragEnterEvent( QGraphicsSceneDragDropEvent *event)
//QMouseEvent event(QEvent::MouseButtonPress, event->pos(), Qt::LeftButton, event->mouseButtons(), 0);
//QApplication::sendEvent(this, &event);
}
event->accept();
//TODO Allow dragging an applet from another Corona into this one while
// keeping its settings etc.
@ -274,10 +275,12 @@ void Corona::dropEvent(QGraphicsSceneDragDropEvent *event)
button->boundingRect().height()/2));
}
addItem(button);
button->updateConstraints();
}
event->acceptProposedAction();
} else
} else {
QGraphicsScene::dropEvent(event);
}
}
// void Corona::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)

103
shadowitem.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright (C) 2007 by Zack Rusin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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.
*/
#include "shadowitem_p.h"
#include "effects/blur.cpp"
#include <QPainter>
#include <QImage>
#include <QDebug>
ShadowItem::ShadowItem(QGraphicsItem *item)
{
setZValue(20);
m_shadowParent = 0;
m_offset = QPointF(12, 12);
setShadowParent(item);
}
void ShadowItem::setShadowParent(QGraphicsItem *item)
{
m_shadowParent = item;
adjustPosition();
generate();
}
QGraphicsItem * ShadowItem::shadowParent() const
{
return m_shadowParent;
}
QSize ShadowItem::shadowedSize() const
{
QSize s = boundingRect().size().toSize();
return s - QSize(32, 32);
}
void ShadowItem::generate()
{
if (!m_shadowParent) {
return;
}
QPainterPath path = m_shadowParent->shape();
QRectF rect = path.boundingRect();
QSize s = rect.size().toSize() + QSize(30, 30);
QImage img(s, QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter p(&img);
p.translate(15, 15);
p.setRenderHint(QPainter::Antialiasing);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillPath(path, Qt::gray);
p.end();
#ifdef DO_GLOW
QImage blurred = img;
expblur<16, 7>(img, 7);
p.begin(&img);
p.setCompositionMode(QPainter::CompositionMode_Plus);
p.drawImage(0, 0, blurred);
p.end();
#else
expblur<16, 7>(img, 7);
#endif
setPixmap(QPixmap::fromImage(img));
}
void ShadowItem::adjustPosition()
{
if (!m_shadowParent) {
return;
}
setPos(m_shadowParent->pos() - m_offset);
}
void ShadowItem::setOffset(const QPointF &offset)
{
m_offset = offset;
}
QPointF ShadowItem::offset() const
{
return m_offset;
}

45
shadowitem_p.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2007 by Zack Rusin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License version 2 as
* published by the Free Software Foundation
*
* 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 SHADOWITEM_P_H
#define SHADOWITEM_P_H
#include <QGraphicsPixmapItem>
class ShadowItem : public QGraphicsPixmapItem
{
public:
explicit ShadowItem(QGraphicsItem* item);
void setShadowParent(QGraphicsItem *item);
QGraphicsItem *shadowParent() const;
void setOffset(const QPointF &offset);
QPointF offset() const;
QSize shadowedSize() const;
void generate();
void adjustPosition();
private:
QGraphicsItem *m_shadowParent;
QPointF m_offset;
};
#endif