The Desktop ToolBox and the Panel ToolBox becomes plugins, shipped with

Plasma-Desktop (so shells have to implement their own plugins or pick
one already installed)

Unfortunately, 3 virtuals were needed in AbstractToolBox
void restore(const KConfigGroup &group);
void save(const KConfigGroup &group);
void reposition();

since this is not possible for obvious BC reasons, they are "faked" with
slots, not really nice butthe most painless way.

There shouldn't be significant regressions, but wise to keep an eye on
it in the immediate future

CCMAIL:plasma-devel@kde.org


svn path=/trunk/KDE/kdelibs/; revision=1157537
This commit is contained in:
Marco Martin 2010-07-31 13:02:07 +00:00
parent bccac847d1
commit 72a06cdd14
10 changed files with 72 additions and 1986 deletions

View File

@ -119,14 +119,12 @@ set(plasma_LIB_SRCS
private/dataengineconsumer.cpp
private/dataengineservice.cpp
private/denyallauthorization.cpp
private/desktoptoolbox.cpp
private/extenderapplet.cpp
private/extenderitemmimedata.cpp
private/focusindicator.cpp
private/getsource.cpp
private/nativetabbar.cpp
private/packages.cpp
private/paneltoolbox.cpp
private/pinpairingauthorization.cpp
private/pinpairingdialog.cpp
private/plasmoidservice.cpp
@ -138,7 +136,6 @@ set(plasma_LIB_SRCS
private/storage.cpp
private/style.cpp
private/trustedonlyauthorization.cpp
private/internaltoolbox.cpp
private/tooltip.cpp
private/wallpaperrenderthread.cpp
private/windowpreview.cpp

View File

@ -81,6 +81,19 @@ Containment *AbstractToolBox::containment() const
return d->containment;
}
void AbstractToolBox::restore(const KConfigGroup &group)
{
Q_UNUSED(group)
}
void AbstractToolBox::save(const KConfigGroup &group)
{
Q_UNUSED(group)
}
void AbstractToolBox::reposition()
{}
} // plasma namespace
#include "abstracttoolbox.moc"

View File

@ -27,6 +27,8 @@
class QAction;
class KConfigGroup;
namespace Plasma
{
@ -77,9 +79,40 @@ public:
virtual bool isShowing() const = 0;
virtual void setShowing(const bool show) = 0;
public Q_SLOTS:
//FIXME for KDE5: those should become virtuals
/**
* Restore the ToolBox settings
* It has to be reimplemented in toolboxes that need it
* @since 4.6
*/
void restore(const KConfigGroup &group);
/**
* Save the ToolBox settings
* It has to be reimplemented in toolboxes that need it
* @since 4.6
*/
void save(const KConfigGroup &group);
/**
* Inform the ToolBox it has to reposition itlself
* It has to be reimplemented in toolboxes that need it
* @since 4.6
*/
void reposition();
Q_SIGNALS:
/**
* Toolbox opened or closed
*/
void toggled();
void visibilityChanged(bool);
/**
* Toolbox opened or closed
* @param open tells if the toolbox opened or closed
*/
void visibilityChanged(bool open);
protected:
Containment *containment() const;

View File

@ -48,6 +48,7 @@
#include "kio/job.h"
#include "kio/scheduler.h"
#include "abstracttoolbox.h"
#include "animator.h"
#include "context.h"
#include "containmentactions.h"
@ -64,10 +65,8 @@
#include "private/applet_p.h"
#include "private/applethandle_p.h"
#include "private/containmentactionspluginsconfig_p.h"
#include "private/desktoptoolbox_p.h"
#include "private/extenderitemmimedata_p.h"
#include "private/extenderapplet_p.h"
#include "private/paneltoolbox_p.h"
#include "plasma/plasma.h"
#include "animations/animation.h"
@ -204,7 +203,6 @@ void Containment::init()
d->actions()->addAction("lock widgets", lockDesktopAction);
}
}
if (d->type != PanelContainment && d->type != CustomPanelContainment) {
if (corona()) {
//FIXME this is just here because of the darn keyboard shortcut :/
@ -219,15 +217,15 @@ void Containment::init()
}
}
if (d->type == DesktopContainment && d->toolBox) {
d->toolBox.data()->addTool(action("add widgets"));
if (d->type == DesktopContainment) {
addToolBoxAction(action("add widgets"));
//TODO: do we need some way to allow this be overridden?
// it's always available because shells rely on this
// to offer their own custom configuration as well
QAction *configureContainment = action("configure");
if (configureContainment) {
d->toolBox.data()->addTool(configureContainment);
addToolBoxAction(configureContainment);
}
}
}
@ -365,10 +363,9 @@ void Containment::restore(KConfigGroup &group)
setWallpaper(group.readEntry("wallpaperplugin", defaultWallpaper),
group.readEntry("wallpaperpluginmode", defaultWallpaperMode));
InternalToolBox *internalToolBox = qobject_cast<InternalToolBox *>(d->toolBox.data());
if (internalToolBox) {
internalToolBox->restore(group);
}
QMetaObject::invokeMethod(d->toolBox.data(), "restore", Q_ARG(KConfigGroup, group));
KConfigGroup cfg(&group, "ActionPlugins");
kDebug() << cfg.keyList();
@ -420,10 +417,9 @@ void Containment::save(KConfigGroup &g) const
group.writeEntry("activity", d->context()->currentActivity());
group.writeEntry("activityId", d->context()->currentActivityId());
InternalToolBox *toolBox = qobject_cast<InternalToolBox *>(d->toolBox.data());
if (toolBox) {
toolBox->save(group);
}
QMetaObject::invokeMethod(d->toolBox.data(), "save", Q_ARG(KConfigGroup, group));
if (d->wallpaper) {
group.writeEntry("wallpaperplugin", d->wallpaper->pluginName());
@ -831,17 +827,7 @@ void Containment::setFormFactor(FormFactor formFactor)
d->positionPanel(true);
}
InternalToolBox *toolBox = qobject_cast<InternalToolBox *>(d->toolBox.data());
if (toolBox) {
if (d->formFactor == Vertical) {
toolBox->setCorner(InternalToolBox::Bottom);
//defaults to horizontal
} else if (QApplication::layoutDirection() == Qt::RightToLeft) {
toolBox->setCorner(InternalToolBox::Left);
} else {
toolBox->setCorner(InternalToolBox::Right);
}
}
QMetaObject::invokeMethod(d->toolBox.data(), "reposition");
updateConstraints(Plasma::FormFactorConstraint);
@ -1040,10 +1026,10 @@ void Containment::setScreen(int newScreen, int newDesktop)
Containment *swapScreensWith(0);
if (d->type == DesktopContainment || d->type >= CustomContainment) {
// we want to listen to changes in work area if our screen changes
if (d->screen < 0 && newScreen > -1) {
connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(positionToolBox()), Qt::UniqueConnection);
} else if (newScreen < 0) {
disconnect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SLOT(positionToolBox()));
if (d->toolBox && d->screen < 0 && newScreen > -1) {
connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), d->toolBox.data(), SLOT(positionToolBox()), Qt::UniqueConnection);
} else if (d->toolBox && newScreen < 0) {
disconnect(KWindowSystem::self(), SIGNAL(workAreaChanged()), d->toolBox.data(), SLOT(positionToolBox()));
}
if (newScreen > -1 && corona()) {
@ -1797,7 +1783,9 @@ void Containment::enableAction(const QString &name, bool enable)
void Containment::addToolBoxAction(QAction *action)
{
d->createToolBox();
d->toolBox.data()->addTool(action);
if (d->toolBox) {
d->toolBox.data()->addTool(action);
}
}
void Containment::removeToolBoxAction(QAction *action)
@ -2185,40 +2173,20 @@ void Containment::destroy(bool confirm)
void ContainmentPrivate::createToolBox()
{
if (!toolBox) {
if (isPanelContainment()) {
PanelToolBox *pt = new PanelToolBox(q);
toolBox = pt;
pt->setSize(KIconLoader::SizeSmallMedium);
pt->setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall));
if (q->immutability() != Mutable) {
pt->hide();
}
} else {
DesktopToolBox *dt = new DesktopToolBox(q);
toolBox = dt;
dt->setSize(KIconLoader::SizeSmallMedium);
dt->setIconSize(QSize(KIconLoader::SizeSmall, KIconLoader::SizeSmall));
}
toolBox = Plasma::AbstractToolBox::load(q->corona()->preferredToolBoxPlugin(type), QVariantList(), q);
if (toolBox) {
QObject::connect(toolBox.data(), SIGNAL(toggled()), q, SIGNAL(toolBoxToggled()));
QObject::connect(toolBox.data(), SIGNAL(toggled()), q, SLOT(updateToolBoxVisibility()));
InternalToolBox *internalToolBox = qobject_cast<InternalToolBox *>(toolBox.data());
if (internalToolBox) {
internalToolBox->restore();
positionToolBox();
}
positionToolBox();
}
}
}
void ContainmentPrivate::positionToolBox()
{
InternalToolBox *internalToolBox = qobject_cast<InternalToolBox *>(toolBox.data());
if (internalToolBox) {
internalToolBox->updateToolBox();
internalToolBox->reposition();
}
QMetaObject::invokeMethod(toolBox.data(), "reposition");
}
void ContainmentPrivate::updateToolBoxVisibility()
@ -2259,7 +2227,7 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
if (constraints & Plasma::ImmutableConstraint) {
//update actions
checkRemoveAction();
bool unlocked = q->immutability() == Mutable;
const bool unlocked = q->immutability() == Mutable;
q->setAcceptDrops(unlocked);
q->enableAction("add widgets", unlocked);
@ -2269,17 +2237,6 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
a->updateConstraints(ImmutableConstraint);
}
if (toolBox) {
if (isPanelContainment()) {
toolBox.data()->setVisible(unlocked);
} else {
InternalToolBox *internalToolBox = qobject_cast<InternalToolBox *>(toolBox.data());
if (internalToolBox) {
internalToolBox->setIsMovable(unlocked);
}
}
}
//clear handles on lock
if (!unlocked) {
QMap<Applet*, AppletHandle*> h = handles;
@ -2321,8 +2278,8 @@ void ContainmentPrivate::containmentConstraintsEvent(Plasma::Constraints constra
positionToolBox();
}
if (toolBox && constraints & Plasma::StartupCompletedConstraint && type < Containment::CustomContainment) {
toolBox.data()->addTool(q->action("remove"));
if (constraints & Plasma::StartupCompletedConstraint && type < Containment::CustomContainment) {
q->addToolBoxAction(q->action("remove"));
checkRemoveAction();
}
}

View File

@ -1,793 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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.
*/
#include "desktoptoolbox_p.h"
#include <QAction>
#include <QGraphicsSceneHoverEvent>
#include <QPainter>
#include <QGraphicsLinearLayout>
#include <QGraphicsView>
#include <QWeakPointer>
#include <QPropertyAnimation>
#include <kcolorscheme.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <plasma/animations/animation.h>
#include <plasma/applet.h>
#include <plasma/containment.h>
#include <plasma/framesvg.h>
#include <plasma/paintutils.h>
#include <plasma/theme.h>
#include <plasma/tooltipcontent.h>
#include <plasma/tooltipmanager.h>
#include <plasma/widgets/iconwidget.h>
#include <plasma/widgets/itembackground.h>
namespace Plasma
{
class EmptyGraphicsItem : public QGraphicsWidget
{
public:
EmptyGraphicsItem(QGraphicsItem *parent)
: QGraphicsWidget(parent)
{
setAcceptsHoverEvents(true);
m_layout = new QGraphicsLinearLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
m_background = new Plasma::FrameSvg(this);
m_background->setImagePath("widgets/background");
m_background->setEnabledBorders(FrameSvg::AllBorders);
m_layout->setOrientation(Qt::Vertical);
m_itemBackground = new Plasma::ItemBackground(this);
updateMargins();
}
~EmptyGraphicsItem()
{
}
void updateMargins()
{
qreal left, top, right, bottom;
m_background->getMargins(left, top, right, bottom);
setContentsMargins(left, top, right, bottom);
}
void paint(QPainter *p, const QStyleOptionGraphicsItem *option, QWidget *)
{
m_background->paintFrame(p, option->rect, option->rect);
}
void clearLayout()
{
while (m_layout->count()) {
//safe? at the moment everything it's thre will always be QGraphicsWidget
static_cast<QGraphicsWidget *>(m_layout->itemAt(0))->removeEventFilter(this);
m_layout->removeAt(0);
}
}
void addToLayout(QGraphicsWidget *widget)
{
qreal left, top, right, bottom;
m_itemBackground->getContentsMargins(&left, &top, &right, &bottom);
widget->setContentsMargins(left, top, right, bottom);
m_layout->addItem(widget);
widget->installEventFilter(this);
if (m_layout->count() == 1) {
m_itemBackground->hide();
m_itemBackground->setTargetItem(widget);
}
}
protected:
void resizeEvent(QGraphicsSceneResizeEvent *)
{
m_background->resizeFrame(size());
}
bool eventFilter(QObject *watched, QEvent *event)
{
QGraphicsWidget *widget = qobject_cast<QGraphicsWidget *>(watched);
if (event->type() == QEvent::GraphicsSceneHoverEnter) {
m_itemBackground->setTargetItem(widget);
}
return false;
}
void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
event->accept();
}
void hoverLeaveEvent(QGraphicsSceneHoverEvent *)
{
m_itemBackground->hide();
}
private:
QRectF m_rect;
Plasma::FrameSvg *m_background;
QGraphicsLinearLayout *m_layout;
Plasma::ItemBackground *m_itemBackground;
};
// used with QGrahphicsItem::setData
static const int ToolName = 7001;
class DesktopToolBoxPrivate
{
public:
DesktopToolBoxPrivate(DesktopToolBox *toolbox)
: q(toolbox),
background(0),
containment(0),
icon("plasma"),
toolBacker(0),
animCircleFrame(0),
animHighlightFrame(0),
hovering(false)
{}
void adjustBackgroundBorders()
{
switch (q->corner()) {
case InternalToolBox::TopRight:
background->setEnabledBorders(FrameSvg::BottomBorder|FrameSvg::LeftBorder);
break;
case InternalToolBox::Top:
background->setEnabledBorders(FrameSvg::BottomBorder|FrameSvg::LeftBorder|FrameSvg::RightBorder);
break;
case InternalToolBox::TopLeft:
background->setEnabledBorders(FrameSvg::BottomBorder|FrameSvg::RightBorder);
break;
case InternalToolBox::Left:
background->setEnabledBorders(FrameSvg::BottomBorder|FrameSvg::TopBorder|FrameSvg::RightBorder);
break;
case InternalToolBox::Right:
background->setEnabledBorders(FrameSvg::BottomBorder|FrameSvg::TopBorder|FrameSvg::LeftBorder);
break;
case InternalToolBox::BottomLeft:
background->setEnabledBorders(FrameSvg::TopBorder|FrameSvg::RightBorder);
break;
case InternalToolBox::Bottom:
background->setEnabledBorders(FrameSvg::TopBorder|FrameSvg::LeftBorder|FrameSvg::RightBorder);
break;
case InternalToolBox::BottomRight:
default:
background->setEnabledBorders(FrameSvg::TopBorder|FrameSvg::LeftBorder);
break;
}
}
DesktopToolBox *q;
Plasma::FrameSvg *background;
Containment *containment;
KIcon icon;
EmptyGraphicsItem *toolBacker;
QWeakPointer<QPropertyAnimation> anim;
qreal animCircleFrame;
qreal animHighlightFrame;
QRect shapeRect;
QColor fgColor;
QColor bgColor;
bool hovering : 1;
QMultiMap<AbstractToolBox::ToolType, IconWidget *> tools;
};
DesktopToolBox::DesktopToolBox(Containment *parent)
: InternalToolBox(parent),
d(new DesktopToolBoxPrivate(this))
{
d->background = new Plasma::FrameSvg(this);
d->background->setImagePath("widgets/toolbox");
d->containment = parent;
setZValue(10000000);
setIsMovable(true);
updateTheming();
connect(this, SIGNAL(toggled()), this, SLOT(toggle()));
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
this, SLOT(updateTheming()));
ToolTipManager::self()->registerWidget(this);
}
DesktopToolBox::~DesktopToolBox()
{
delete d;
}
QSize DesktopToolBox::cornerSize() const
{
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
return QSize(size() + left, size() + bottom);
}
QSize DesktopToolBox::fullWidth() const
{
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
int extraSpace = 0;
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+'x');
}
return QSize(size() + left + right + extraSpace, size() + bottom);
}
QSize DesktopToolBox::fullHeight() const
{
d->background->setEnabledBorders(FrameSvg::AllBorders);
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
d->adjustBackgroundBorders();
int extraSpace = 0;
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+'x');
}
return QSize(size() + left, size() + top + bottom + extraSpace);
}
void DesktopToolBox::toolTipAboutToShow()
{
if (isShowing()) {
return;
}
ToolTipContent c(i18n("Tool Box"),
i18n("Click to access configuration options and controls, or to add more widgets to the %1.",
containment()->name()),
KIcon("plasma"));
c.setAutohide(false);
ToolTipManager::self()->setContent(this, c);
}
void DesktopToolBox::toolTipHidden()
{
ToolTipManager::self()->clearContent(this);
}
QRectF DesktopToolBox::boundingRect() const
{
int extraSpace = size();
d->adjustBackgroundBorders();
//keep space for the label and a character more
if (!d->containment->activity().isNull()) {
extraSpace = Plasma::Theme::defaultTheme()->fontMetrics().width(d->containment->activity()+'x');
}
qreal left, top, right, bottom;
d->background->getMargins(left, top, right, bottom);
QRectF rect;
//disable text at corners
if (corner() == TopLeft || corner() == TopRight || corner() == BottomLeft || corner() == BottomRight) {
rect = QRectF(0, 0, size()+left+right, size()+top+bottom);
} else if (corner() == Left || corner() == Right) {
rect = QRectF(0, 0, size()+left+right, size()+extraSpace+top+bottom);
//top or bottom
} else {
rect = QRectF(0, 0, size()+extraSpace+left+right, size()+top+bottom);
}
return rect;
}
void DesktopToolBox::updateTheming()
{
d->bgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
d->fgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
}
void DesktopToolBox::toolTriggered(bool)
{
QAction *action = qobject_cast<QAction *>(sender());
if (isShowing() && (!action || !action->autoRepeat())) {
emit toggled();
}
}
void DesktopToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
QPainterPath p = shape();
QPoint iconPos;
QRect backgroundRect;
const QRectF rect = boundingRect();
const QSize icons = iconSize();
QString cornerElement;
switch (corner()) {
case TopLeft:
cornerElement = "desktop-northwest";
break;
case TopRight:
cornerElement = "desktop-northeast";
break;
case BottomRight:
cornerElement = "desktop-southeast";
break;
case BottomLeft:
cornerElement = "desktop-southwest";
break;
default:
break;
}
QString activityName;
QSize textSize;
if (cornerElement.isNull()) {
activityName = d->containment->activity();
textSize = Plasma::Theme::defaultTheme()->fontMetrics().size(Qt::TextSingleLine, activityName+'x');
}
d->adjustBackgroundBorders();
d->background->resizeFrame(rect.size());
if (!cornerElement.isNull()) {
d->background->paint(painter, rect, cornerElement);
} else {
d->background->paintFrame(painter, rect.topLeft());
}
QRect iconRect;
QRect textRect;
if (corner() == Left || corner() == Right) {
Qt::Alignment alignment;
if (activityName.isNull()) {
alignment = Qt::Alignment(Qt::AlignCenter);
} else {
alignment = Qt::Alignment(Qt::AlignHCenter|Qt::AlignTop);
}
iconRect = QStyle::alignedRect(QApplication::layoutDirection(), alignment, iconSize(), d->background->contentsRect().toRect());
QRect boundRect(QPoint(d->background->contentsRect().top(),
d->background->contentsRect().left()),
QSize(d->background->contentsRect().height(),
d->background->contentsRect().width()));
textRect = QStyle::alignedRect(QApplication::layoutDirection(), Qt::AlignRight|Qt::AlignVCenter, textSize, boundRect);
textRect.moveTopLeft(textRect.topLeft() + QPoint(rect.top(), rect.left()));
} else {
Qt::Alignment alignment;
if (activityName.isNull()) {
alignment = Qt::Alignment(Qt::AlignCenter);
} else {
alignment = Qt::Alignment(Qt::AlignLeft|Qt::AlignVCenter);
}
iconRect = QStyle::alignedRect(QApplication::layoutDirection(), alignment, iconSize(), d->background->contentsRect().toRect());
textRect = QStyle::alignedRect(QApplication::layoutDirection(), Qt::AlignRight|Qt::AlignVCenter, textSize, d->background->contentsRect().toRect());
textRect.moveTopLeft(textRect.topLeft() + rect.topLeft().toPoint());
}
iconRect.moveTopLeft(iconRect.topLeft() + rect.topLeft().toPoint());
iconPos = iconRect.topLeft();
const qreal progress = d->animHighlightFrame;
if (qFuzzyCompare(qreal(1.0), progress)) {
d->icon.paint(painter, QRect(iconPos, iconSize()));
} else if (qFuzzyCompare(qreal(1.0), 1 + progress)) {
d->icon.paint(painter, QRect(iconPos, iconSize()),
Qt::AlignCenter, QIcon::Disabled, QIcon::Off);
} else {
QPixmap disabled = d->icon.pixmap(iconSize(), QIcon::Disabled, QIcon::Off);
QPixmap enabled = d->icon.pixmap(iconSize());
QPixmap result = PaintUtils::transition(
d->icon.pixmap(iconSize(), QIcon::Disabled, QIcon::Off),
d->icon.pixmap(iconSize()), progress);
painter->drawPixmap(QRect(iconPos, iconSize()), result);
}
if (!cornerElement.isNull() || activityName.isNull()) {
return;
}
QColor textColor = Plasma::Theme::defaultTheme()->color(Theme::TextColor);
QColor shadowColor;
QPoint shadowOffset;
if (qGray(textColor.rgb()) > 192) {
shadowColor = Qt::black;
shadowOffset = QPoint(1,1);
} else {
shadowColor = Qt::white;
shadowOffset = QPoint(0,0);
}
QPixmap shadowText = Plasma::PaintUtils::shadowText(activityName, textColor, shadowColor, shadowOffset);
painter->save();
if (corner() == Left || corner() == Right) {
painter->rotate(90);
painter->translate(textRect.left(), -textRect.top()-textRect.height());
painter->drawPixmap(QPoint(0,0), shadowText);
} else {
painter->drawPixmap(textRect.topLeft(), shadowText);
}
painter->restore();
}
QPainterPath DesktopToolBox::shape() const
{
const QRectF rect = boundingRect();
const int w = rect.width();
const int h = rect.height();
QPainterPath path;
switch (corner()) {
case BottomLeft:
path.moveTo(rect.bottomLeft());
path.arcTo(QRectF(rect.left() - w, rect.top(), w * 2, h * 2), 0, 90);
break;
case BottomRight:
path.moveTo(rect.bottomRight());
path.arcTo(QRectF(rect.left(), rect.top(), w * 2, h * 2), 90, 90);
break;
case TopRight:
path.moveTo(rect.topRight());
path.arcTo(QRectF(rect.left(), rect.top() - h, w * 2, h * 2), 180, 90);
break;
case TopLeft:
path.arcTo(QRectF(rect.left() - w, rect.top() - h, w * 2, h * 2), 270, 90);
break;
default:
path.addRect(rect);
break;
}
return path;
}
void DesktopToolBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
if (isShowing() || d->hovering) {
QGraphicsItem::hoverEnterEvent(event);
return;
}
highlight(true);
QGraphicsItem::hoverEnterEvent(event);
}
QGraphicsWidget *DesktopToolBox::toolParent()
{
if (!d->toolBacker) {
d->toolBacker = new EmptyGraphicsItem(this);
d->toolBacker->hide();
}
return d->toolBacker;
}
void DesktopToolBox::showToolBox()
{
if (isShowing()) {
return;
}
if (!d->toolBacker) {
d->toolBacker = new EmptyGraphicsItem(this);
}
d->toolBacker->setZValue(zValue() + 1);
adjustToolBackerGeometry();
d->toolBacker->setOpacity(0);
d->toolBacker->show();
Plasma::Animation *fadeAnim = Animator::create(Animator::FadeAnimation, d->toolBacker);
fadeAnim->setTargetWidget(d->toolBacker);
fadeAnim->setProperty("startOpacity", 0);
fadeAnim->setProperty("targetOpacity", 1);
fadeAnim->start(QAbstractAnimation::DeleteWhenStopped);
}
void DesktopToolBox::addTool(QAction *action)
{
if (!action) {
return;
}
if (actions().contains(action)) {
return;
}
InternalToolBox::addTool(action);
Plasma::IconWidget *tool = new Plasma::IconWidget(toolParent());
tool->setTextBackgroundColor(QColor());
tool->setAction(action);
tool->setDrawBackground(true);
tool->setOrientation(Qt::Horizontal);
tool->resize(tool->sizeFromIconSize(KIconLoader::SizeSmallMedium));
tool->setPreferredIconSize(QSizeF(KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium));
tool->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
tool->hide();
const int height = static_cast<int>(tool->boundingRect().height());
tool->setPos(toolPosition(height));
tool->setZValue(zValue() + 10);
tool->setToolTip(action->text());
//make enabled/disabled tools appear/disappear instantly
connect(tool, SIGNAL(changed()), this, SLOT(updateToolBox()));
ToolType type = AbstractToolBox::MiscTool;
if (!action->data().isNull() && action->data().type() == QVariant::Int) {
int t = action->data().toInt();
if (t >= 0 && t < AbstractToolBox::UserToolType) {
type = static_cast<AbstractToolBox::ToolType>(t);
}
}
d->tools.insert(type, tool);
//kDebug() << "added tool" << type << action->text();
}
void DesktopToolBox::updateToolBox()
{
Plasma::IconWidget *tool = qobject_cast<Plasma::IconWidget *>(sender());
if (tool && !tool->action()) {
QMutableMapIterator<ToolType, IconWidget *> it(d->tools);
while (it.hasNext()) {
it.next();
if (it.value() == tool) {
it.remove();
break;
}
}
tool->deleteLater();
tool = 0;
}
if (isShowing()) {
showToolBox();
} else if (tool && !tool->isEnabled()) {
tool->hide();
}
adjustToolBackerGeometry();
}
void DesktopToolBox::removeTool(QAction *action)
{
QMutableMapIterator<ToolType, IconWidget *> it(d->tools);
while (it.hasNext()) {
it.next();
IconWidget *tool = it.value();
//kDebug() << "checking tool" << tool
if (tool && tool->action() == action) {
//kDebug() << "tool found!";
tool->deleteLater();
it.remove();
break;
}
}
}
void DesktopToolBox::adjustToolBackerGeometry()
{
if (!d->toolBacker) {
return;
}
d->toolBacker->clearLayout();
QMapIterator<ToolType, IconWidget *> it(d->tools);
while (it.hasNext()) {
it.next();
IconWidget *icon = it.value();
//kDebug() << "showing off" << it.key() << icon->text();
if (icon->isEnabled()) {
icon->show();
icon->setDrawBackground(false);
d->toolBacker->addToLayout(icon);
} else {
icon->hide();
}
}
qreal left, top, right, bottom;
d->toolBacker->getContentsMargins(&left, &top, &right, &bottom);
d->toolBacker->adjustSize();
int x = 0;
int y = 0;
const int iconWidth = KIconLoader::SizeMedium;
switch (corner()) {
case TopRight:
x = (int)boundingRect().left() - d->toolBacker->size().width();
y = (int)boundingRect().top();
break;
case Top:
x = (int)boundingRect().center().x() - (d->toolBacker->size().width() / 2);
y = (int)boundingRect().bottom();
break;
case TopLeft:
x = (int)boundingRect().right();
y = (int)boundingRect().top();
break;
case Left:
x = (int)boundingRect().left() + iconWidth;
y = (int)boundingRect().y();
break;
case Right:
x = (int)boundingRect().right() - iconWidth - d->toolBacker->size().width();
y = (int)boundingRect().y();
break;
case BottomLeft:
x = (int)boundingRect().left() + iconWidth;
y = (int)boundingRect().bottom();
break;
case Bottom:
x = (int)boundingRect().center().x() - (d->toolBacker->size().width() / 2);
y = (int)boundingRect().top();
break;
case BottomRight:
default:
x = (int)boundingRect().right() - iconWidth - d->toolBacker->size().width();
y = (int)boundingRect().top();
break;
}
//kDebug() << "starting at" << x << startY;
d->toolBacker->setPos(x, y);
// now check that it actually fits within the parent's boundaries
QRectF backerRect = mapToParent(d->toolBacker->geometry()).boundingRect();
QSizeF parentSize = parentWidget()->size();
if (backerRect.x() < 5) {
d->toolBacker->setPos(mapFromParent(QPointF(5, 0)).x(), y);
} else if (backerRect.right() > parentSize.width() - 5) {
d->toolBacker->setPos(mapFromParent(QPointF(parentSize.width() - 5 - backerRect.width(), 0)).x(), y);
}
if (backerRect.y() < 5) {
d->toolBacker->setPos(x, mapFromParent(QPointF(0, 5)).y());
} else if (backerRect.bottom() > parentSize.height() - 5) {
d->toolBacker->setPos(x, mapFromParent(QPointF(0, parentSize.height() - 5 - backerRect.height())).y());
}
}
void DesktopToolBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
//kDebug() << event->pos() << event->scenePos()
// << d->toolBacker->rect().contains(event->scenePos().toPoint());
if (!d->hovering || isShowing()) {
QGraphicsItem::hoverLeaveEvent(event);
return;
}
highlight(false);
QGraphicsItem::hoverLeaveEvent(event);
}
void DesktopToolBox::hideToolBox()
{
if (d->toolBacker) {
Plasma::Animation *fadeAnim = Animator::create(Animator::FadeAnimation, d->toolBacker);
connect(fadeAnim, SIGNAL(finished()), this, SLOT(hideToolBacker()));
fadeAnim->setTargetWidget(d->toolBacker);
fadeAnim->setProperty("startOpacity", 1);
fadeAnim->setProperty("targetOpacity", 0);
fadeAnim->start(QAbstractAnimation::DeleteWhenStopped);
}
highlight(false);
}
void DesktopToolBox::hideToolBacker()
{
d->toolBacker->hide();
}
void DesktopToolBox::highlight(bool highlighting)
{
if (d->hovering == highlighting) {
return;
}
d->hovering = highlighting;
QPropertyAnimation *anim = d->anim.data();
if (d->hovering) {
if (anim) {
anim->stop();
d->anim.clear();
}
anim = new QPropertyAnimation(this, "highlight", this);
d->anim = anim;
}
if (anim->state() != QAbstractAnimation::Stopped) {
anim->stop();
}
anim->setDuration(250);
anim->setStartValue(0);
anim->setEndValue(1);
if(d->hovering) {
anim->start();
} else {
anim->setDirection(QAbstractAnimation::Backward);
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
}
void DesktopToolBox::setHighlight(qreal progress)
{
d->animHighlightFrame = progress;
update();
}
qreal DesktopToolBox::highlight()
{
return d->animHighlightFrame;
}
void DesktopToolBox::toggle()
{
setShowing(!isShowing());
}
} // plasma namespace
#include "desktoptoolbox_p.moc"

View File

@ -1,91 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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_DESKTOPTOOLBOX_P_H
#define PLASMA_DESKTOPTOOLBOX_P_H
#include <QGraphicsItem>
#include <QObject>
#include <QTime>
#include <kicon.h>
#include <private/internaltoolbox_p.h>
#include "animator.h"
namespace Plasma
{
class Widget;
class EmptyGraphicsItem;
class DesktopToolBoxPrivate;
class DesktopToolBox : public InternalToolBox
{
Q_OBJECT
Q_PROPERTY(qreal highlight READ highlight WRITE setHighlight)
public:
explicit DesktopToolBox(Containment *parent = 0);
~DesktopToolBox();
QRectF boundingRect() const;
QPainterPath shape() const;
void addTool(QAction *action);
void removeTool(QAction *action);
void showToolBox();
void hideToolBox();
QSize cornerSize() const;
QSize fullWidth() const;
QSize fullHeight() const;
QGraphicsWidget *toolParent();
public Q_SLOTS:
void toolTipAboutToShow();
void toolTipHidden();
void updateToolBox();
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
protected Q_SLOTS:
void setHighlight(qreal progress);
qreal highlight();
void updateTheming();
void toolTriggered(bool);
void hideToolBacker();
/**
* show/hide the toolbox
*/
void toggle();
private:
void highlight(bool highlighting);
void adjustToolBackerGeometry();
DesktopToolBoxPrivate *d;
};
} // Plasma namespace
#endif // multiple inclusion guard

View File

@ -1,514 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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.
*/
#include "internaltoolbox_p.h"
#include <QAction>
#include <QApplication>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsView>
#include <QPainter>
#include <QRadialGradient>
#include <kcolorscheme.h>
#include <kconfiggroup.h>
#include <kiconloader.h>
#include <kdebug.h>
#include "corona.h"
#include "theme.h"
#include "widgets/iconwidget.h"
namespace Plasma
{
class InternalToolBoxPrivate
{
public:
InternalToolBoxPrivate(Containment *c)
: containment(c),
corner(InternalToolBox::TopRight),
size(50),
iconSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium),
hidden(false),
showing(false),
movable(false),
dragging(false),
userMoved(false),
iconic(true)
{}
Containment *containment;
InternalToolBox::Corner corner;
int size;
QSize iconSize;
QPoint dragStartRelative;
QTransform viewTransform;
QList<QAction *> actions;
bool hidden : 1;
bool showing : 1;
bool movable : 1;
bool dragging : 1;
bool userMoved : 1;
bool iconic : 1;
};
InternalToolBox::InternalToolBox(Containment *parent)
: AbstractToolBox(parent),
d(new InternalToolBoxPrivate(parent))
{
d->userMoved = false;
setAcceptsHoverEvents(true);
}
InternalToolBox::~InternalToolBox()
{
delete d;
}
Containment *InternalToolBox::containment()
{
return d->containment;
}
QPoint InternalToolBox::toolPosition(int toolHeight)
{
switch (corner()) {
case TopRight:
return QPoint(boundingRect().width(), -toolHeight);
case Top:
return QPoint((int)boundingRect().center().x() - boundingRect().width(), -toolHeight);
case TopLeft:
return QPoint(-boundingRect().width(), -toolHeight);
case Left:
return QPoint(-boundingRect().width(), (int)boundingRect().center().y() - boundingRect().height());
case Right:
return QPoint(boundingRect().width(), (int)boundingRect().center().y() - boundingRect().height());
case BottomLeft:
return QPoint(-boundingRect().width(), toolHeight);
case Bottom:
return QPoint((int)boundingRect().center().x() - d->iconSize.width(), toolHeight);
case BottomRight:
default:
return QPoint(boundingRect().width(), toolHeight);
}
}
QGraphicsWidget *InternalToolBox::toolParent()
{
return this;
}
QList<QAction *> InternalToolBox::actions() const
{
return d->actions;
}
void InternalToolBox::addTool(QAction *action)
{
if (!action) {
return;
}
if (d->actions.contains(action)) {
return;
}
connect(action, SIGNAL(destroyed(QObject*)), this, SLOT(actionDestroyed(QObject*)));
connect(action, SIGNAL(triggered(bool)), this, SLOT(toolTriggered(bool)));
d->actions.append(action);
}
void InternalToolBox::removeTool(QAction *action)
{
disconnect(action, 0, this, 0);
d->actions.removeAll(action);
}
void InternalToolBox::actionDestroyed(QObject *object)
{
d->actions.removeAll(static_cast<QAction*>(object));
}
bool InternalToolBox::isEmpty() const
{
return d->actions.isEmpty();
}
void InternalToolBox::toolTriggered(bool)
{
}
int InternalToolBox::size() const
{
return d->size;
}
void InternalToolBox::setSize(const int newSize)
{
d->size = newSize;
}
QSize InternalToolBox::iconSize() const
{
return d->iconSize;
}
void InternalToolBox::setIconSize(const QSize newSize)
{
d->iconSize = newSize;
}
bool InternalToolBox::isShowing() const
{
return d->showing;
}
void InternalToolBox::setShowing(const bool show)
{
if (show) {
showToolBox();
} else {
hideToolBox();
}
d->showing = show;
}
void InternalToolBox::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
event->accept();
// set grab position relative to toolbox
d->dragStartRelative = mapToParent(event->pos()).toPoint() - pos().toPoint();
} else {
event->ignore();
}
}
QSize InternalToolBox::cornerSize() const
{
return boundingRect().size().toSize();
}
QSize InternalToolBox::fullWidth() const
{
return boundingRect().size().toSize();
}
QSize InternalToolBox::fullHeight() const
{
return boundingRect().size().toSize();
}
void InternalToolBox::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (!d->movable || (!d->dragging && boundingRect().contains(event->pos()))) {
return;
}
d->dragging = true;
d->userMoved = true;
const QPoint newPos = mapToParent(event->pos()).toPoint();
const QPoint curPos = pos().toPoint();
const QSize cSize = cornerSize();
const QSize fHeight = fullHeight();
const QSize fWidth = fullWidth();
const int h = fHeight.height();
const int w = fWidth.width();
const int areaWidth = parentWidget()->size().width();
const int areaHeight = parentWidget()->size().height();
int x = curPos.x();
int y = curPos.y();
// jump to the nearest desktop border
int distanceToLeft = newPos.x() - d->dragStartRelative.x();
int distanceToRight = areaWidth - w - distanceToLeft;
int distanceToTop = newPos.y() - d->dragStartRelative.y();
int distanceToBottom = areaHeight - h - distanceToTop;
int distancetoHorizontalMiddle = qAbs((newPos.x() + boundingRect().size().width()/2) - areaWidth/2 - d->dragStartRelative.x());
int distancetoVerticalMiddle = qAbs((newPos.y() + boundingRect().size().height()/2) - areaHeight/2 - d->dragStartRelative.y());
if (distancetoHorizontalMiddle < 10) {
x = areaWidth/2 - boundingRect().size().width()/2;
} else if (distancetoVerticalMiddle < 10) {
y = areaHeight/2 - boundingRect().size().height()/2;
} else {
// decide which border is the nearest
if (distanceToLeft < distanceToTop && distanceToLeft < distanceToRight &&
distanceToLeft < distanceToBottom ) {
x = 0;
y = (newPos.y() - d->dragStartRelative.y());
} else if (distanceToRight < distanceToTop && distanceToRight < distanceToLeft &&
distanceToRight < distanceToBottom) {
x = areaWidth - w;
y = (newPos.y() - d->dragStartRelative.y());
} else if (distanceToTop < distanceToLeft && distanceToTop < distanceToRight &&
distanceToTop < distanceToBottom ) {
y = 0;
x = (newPos.x() - d->dragStartRelative.x());
} else if (distanceToBottom < distanceToLeft && distanceToBottom < distanceToRight &&
distanceToBottom < distanceToTop) {
y = areaHeight - h;
x = (newPos.x() - d->dragStartRelative.x());
}
}
x = qBound(0, x, areaWidth - w);
y = qBound(0, y, areaHeight - h);
Corner newCorner = corner();
if (x == 0) {
if (y == 0) {
newCorner = TopLeft;
} else if (areaHeight - cSize.height() < newPos.y()) {
y = areaHeight - cSize.height();
newCorner = BottomLeft;
} else {
newCorner = Left;
}
} else if (y == 0) {
if (areaWidth - cSize.width() < newPos.x()) {
x = areaWidth - cSize.width();
newCorner = TopRight;
} else {
newCorner = Top;
}
} else if (x + w >= areaWidth) {
if (areaHeight - cSize.height() < newPos.y()) {
y = areaHeight - cSize.height();
x = areaWidth - cSize.width();
newCorner = BottomRight;
} else {
x = areaWidth - fHeight.width();
newCorner = Right;
}
} else {
y = areaHeight - fWidth.height();
newCorner = Bottom;
}
if (newCorner != corner()) {
prepareGeometryChange();
setCorner(newCorner);
}
setPos(x, y);
}
void InternalToolBox::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && !d->dragging && boundingRect().contains(event->pos())) {
emit toggled();
return;
}
d->dragging = false;
KConfigGroup cg(d->containment->config());
save(cg);
}
bool InternalToolBox::isMovable() const
{
return d->movable;
}
void InternalToolBox::setIsMovable(bool movable)
{
d->movable = movable;
}
void InternalToolBox::setCorner(const Corner corner)
{
d->corner = corner;
}
InternalToolBox::Corner InternalToolBox::corner() const
{
return d->corner;
}
void InternalToolBox::save(KConfigGroup &cg) const
{
if (!d->movable) {
return;
}
KConfigGroup group(&cg, "ToolBox");
if (!d->userMoved) {
group.deleteGroup();
return;
}
int offset = 0;
if (corner() == InternalToolBox::Left ||
corner() == InternalToolBox::Right) {
offset = y();
} else if (corner() == InternalToolBox::Top ||
corner() == InternalToolBox::Bottom) {
offset = x();
}
group.writeEntry("corner", int(corner()));
group.writeEntry("offset", offset);
}
void InternalToolBox::restore(const KConfigGroup &containmentGroup)
{
if (!d->movable) {
return;
}
KConfigGroup group;
if (containmentGroup.isValid()) {
group = containmentGroup;
} else {
group = d->containment->config();
}
group = KConfigGroup(&group, "ToolBox");
if (!group.hasKey("corner")) {
return;
}
d->userMoved = true;
setCorner(Corner(group.readEntry("corner", int(corner()))));
int offset = group.readEntry("offset", 0);
switch (corner()) {
case InternalToolBox::TopLeft:
setPos(0, 0);
break;
case InternalToolBox::Top:
setPos(offset, 0);
break;
case InternalToolBox::TopRight:
setPos(d->containment->size().width() - boundingRect().width(), 0);
break;
case InternalToolBox::Right:
setPos(d->containment->size().width() - boundingRect().width(), offset);
break;
case InternalToolBox::BottomRight:
setPos(d->containment->size().width() - boundingRect().width(), d->containment->size().height() - boundingRect().height());
break;
case InternalToolBox::Bottom:
setPos(offset, d->containment->size().height() - boundingRect().height());
break;
case InternalToolBox::BottomLeft:
setPos(0, d->containment->size().height() - boundingRect().height());
break;
case InternalToolBox::Left:
setPos(0, offset);
break;
}
//kDebug() << "marked as user moved" << pos()
// << (d->containment->containmentType() == Containment::PanelContainment);
}
void InternalToolBox::reposition()
{
if (d->userMoved) {
//FIXME: adjust for situations like changing of the available space
restore();
return;
}
if (d->containment->containmentType() == Containment::PanelContainment ||
d->containment->containmentType() == Containment::CustomPanelContainment) {
QRectF rect = boundingRect();
if (d->containment->formFactor() == Vertical) {
setCorner(InternalToolBox::Bottom);
setPos(d->containment->geometry().width() / 2 - rect.width() / 2,
d->containment->geometry().height() - rect.height());
} else {
//defaulting to Horizontal right now
if (QApplication::layoutDirection() == Qt::RightToLeft) {
setPos(d->containment->geometry().left(),
d->containment->geometry().height() / 2 - rect.height() / 2);
setCorner(InternalToolBox::Left);
} else {
setPos(d->containment->geometry().width() - rect.width(),
d->containment->geometry().height() / 2 - rect.height() / 2);
setCorner(InternalToolBox::Right);
}
}
//kDebug() << "got ourselves a panel containment, moving to" << pos();
} else if (d->containment->corona()) {
//kDebug() << "desktop";
int screen = d->containment->screen();
QRectF avail = d->containment->geometry();
QRectF screenGeom = avail;
if (screen > -1 && screen < d->containment->corona()->numScreens()) {
avail = d->containment->corona()->availableScreenRegion(screen).boundingRect();
screenGeom = d->containment->corona()->screenGeometry(screen);
avail.translate(-screenGeom.topLeft());
}
// Transform to the containment's coordinate system.
screenGeom.moveTo(0, 0);
if (!d->containment->view() || !d->containment->view()->transform().isScaling()) {
if (QApplication::layoutDirection() == Qt::RightToLeft) {
if (avail.top() > screenGeom.top()) {
setPos(avail.topLeft() - QPoint(0, avail.top()));
setCorner(InternalToolBox::Left);
} else if (avail.left() > screenGeom.left()) {
setPos(avail.topLeft() - QPoint(boundingRect().width(), 0));
setCorner(InternalToolBox::Top);
} else {
setPos(avail.topLeft());
setCorner(InternalToolBox::TopLeft);
}
} else {
if (avail.top() > screenGeom.top()) {
setPos(avail.topRight() - QPoint(boundingRect().width(), -avail.top()));
setCorner(InternalToolBox::Right);
} else if (avail.right() < screenGeom.right()) {
setPos(avail.topRight() - QPoint(boundingRect().width(), 0));
setCorner(InternalToolBox::Top);
} else {
setPos(avail.topRight() - QPoint(boundingRect().width(), 0));
setCorner(InternalToolBox::TopRight);
}
}
} else {
if (QApplication::layoutDirection() == Qt::RightToLeft) {
setPos(d->containment->mapFromScene(QPointF(d->containment->geometry().topLeft())));
setCorner(InternalToolBox::TopLeft);
} else {
setPos(d->containment->mapFromScene(QPointF(d->containment->geometry().topRight())));
setCorner(InternalToolBox::TopRight);
}
}
}
}
} // plasma namespace
#include "internaltoolbox_p.moc"

View File

@ -1,119 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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_INTERNALTOOLBOX_P_H
#define PLASMA_INTERNALTOOLBOX_P_H
#include <QGraphicsWidget>
#include "containment.h"
#include "abstracttoolbox.h"
class QAction;
class KConfigGroup;
namespace Plasma
{
class IconWidget;
class InternalToolBoxPrivate;
class InternalToolBox : public AbstractToolBox
{
Q_OBJECT
Q_INTERFACES(QGraphicsItem)
public:
enum Corner {
Top = 0,
TopRight,
TopLeft,
Left,
Right,
Bottom,
BottomRight,
BottomLeft
};
explicit InternalToolBox(Containment *parent);
~InternalToolBox();
/**
* create a toolbox tool from the given action
* @p action the action to associate hte tool with
*/
void addTool(QAction *action);
/**
* remove the tool associated with this action
*/
void removeTool(QAction *action);
bool isEmpty() const;
int size() const;
void setSize(const int newSize);
QSize iconSize() const;
void setIconSize(const QSize newSize);
bool isShowing() const;
void setShowing(const bool show);
virtual QGraphicsWidget *toolParent();
virtual void setCorner(const Corner corner);
virtual Corner corner() const;
bool isMovable() const;
void setIsMovable(bool movable);
void save(KConfigGroup &cg) const;
void restore(const KConfigGroup &containmentGroup = KConfigGroup());
void reposition();
virtual QSize fullWidth() const;
virtual QSize fullHeight() const;
virtual QSize cornerSize() const;
virtual void updateToolBox() {}
void setIconic(bool iconic);
bool iconic() const;
virtual void showToolBox() = 0;
virtual void hideToolBox() = 0;
QList<QAction *> actions() const;
protected:
Containment *containment();
QPoint toolPosition(int toolHeight);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
protected Q_SLOTS:
virtual void toolTriggered(bool);
void actionDestroyed(QObject *object);
private:
InternalToolBoxPrivate *d;
};
} // Plasma namespace
#endif // PLASMA_INTERNALTOOLBOX_P_H

View File

@ -1,319 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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.
*/
#include "paneltoolbox_p.h"
#include <QGraphicsSceneHoverEvent>
#include <QPainter>
#include <QRadialGradient>
#include <QApplication>
#include <QPropertyAnimation>
#include <QWeakPointer>
#include <kcolorscheme.h>
#include <kdebug.h>
#include <plasma/applet.h>
#include <plasma/paintutils.h>
#include <plasma/svg.h>
#include <plasma/theme.h>
#include <plasma/tooltipcontent.h>
#include <plasma/tooltipmanager.h>
namespace Plasma
{
class PanelToolBoxPrivate
{
public:
PanelToolBoxPrivate()
: icon("plasma"),
animFrame(0),
highlighting(false)
{
}
KIcon icon;
QWeakPointer<QPropertyAnimation> anim;
qreal animFrame;
QColor fgColor;
QColor bgColor;
Plasma::Svg *background;
bool highlighting;
};
PanelToolBox::PanelToolBox(Containment *parent)
: InternalToolBox(parent),
d(new PanelToolBoxPrivate)
{
connect(this, SIGNAL(toggled()), this, SLOT(toggle()));
setZValue(10000000);
setFlag(ItemClipsChildrenToShape, false);
//panel toolbox is allowed to zoom, otherwise a part of it will be displayed behind the desktop
//toolbox when the desktop is zoomed out
setFlag(ItemIgnoresTransformations, false);
assignColors();
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()),
this, SLOT(assignColors()));
d->background = new Plasma::Svg(this);
d->background->setImagePath("widgets/toolbox");
d->background->setContainsMultipleImages(true);
ToolTipManager::self()->registerWidget(this);
}
PanelToolBox::~PanelToolBox()
{
d->anim.clear();
delete d;
}
void PanelToolBox::assignColors()
{
d->bgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor);
d->fgColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
}
QRectF PanelToolBox::boundingRect() const
{
QRectF r;
//Only Left,Right and Bottom supported, default to Right
if (corner() == InternalToolBox::Bottom) {
r = QRectF(0, 0, size() * 2, size());
} else if (corner() == InternalToolBox::Left) {
r = QRectF(0, 0, size(), size() * 2);
} else {
r = QRectF(0, 0, size(), size() * 2);
}
if (parentItem()) {
QSizeF s = parentItem()->boundingRect().size();
if (r.height() > s.height()) {
r.setHeight(s.height());
}
if (r.width() > s.width()) {
r.setWidth(s.width());
}
}
return r;
}
void PanelToolBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
const qreal progress = d->animFrame / size();
QRect backgroundRect;
QPoint gradientCenter;
QRectF rect = boundingRect();
QString cornerElement;
if (corner() == InternalToolBox::Bottom) {
gradientCenter = QPoint(rect.center().x(), rect.bottom());
cornerElement = "panel-south";
backgroundRect = d->background->elementRect(cornerElement).toRect();
backgroundRect.moveBottomLeft(shape().boundingRect().bottomLeft().toPoint());
} else if (corner() == InternalToolBox::Right) {
gradientCenter = QPoint(rect.right(), rect.center().y());
cornerElement = "panel-east";
backgroundRect = d->background->elementRect(cornerElement).toRect();
backgroundRect.moveTopRight(shape().boundingRect().topRight().toPoint());
} else {
gradientCenter = QPoint(rect.right(), rect.center().y());
cornerElement = "panel-west";
backgroundRect = d->background->elementRect(cornerElement).toRect();
backgroundRect.moveTopLeft(shape().boundingRect().topLeft().toPoint());
}
d->background->paint(painter, backgroundRect, cornerElement);
QRect iconRect;
//Only Left,Right and Bottom supported, default to Right
if (corner() == InternalToolBox::Bottom) {
iconRect = QRect(QPoint(gradientCenter.x() - iconSize().width() / 2,
(int)rect.bottom() - iconSize().height() - 2), iconSize());
} else if (corner() == InternalToolBox::Left) {
iconRect = QRect(QPoint(2, gradientCenter.y() - iconSize().height() / 2), iconSize());
} else {
iconRect = QRect(QPoint((int)rect.right() - iconSize().width() + 1,
gradientCenter.y() - iconSize().height() / 2), iconSize());
}
if (qFuzzyCompare(qreal(1.0), progress)) {
d->icon.paint(painter, iconRect);
} else if (qFuzzyCompare(qreal(1.0), 1 + progress)) {
d->icon.paint(painter, iconRect, Qt::AlignCenter, QIcon::Disabled, QIcon::Off);
} else {
QPixmap disabled = d->icon.pixmap(iconSize(), QIcon::Disabled, QIcon::Off);
QPixmap enabled = d->icon.pixmap(iconSize());
QPixmap result = PaintUtils::transition(
d->icon.pixmap(iconSize(), QIcon::Disabled, QIcon::Off),
d->icon.pixmap(iconSize()), progress);
painter->drawPixmap(iconRect, result);
}
}
QPainterPath PanelToolBox::shape() const
{
QPainterPath path;
int toolSize = size();// + (int)d->animFrame;
QRectF rect = boundingRect();
//Only Left,Right and Bottom supported, default to Right
if (corner() == InternalToolBox::Bottom) {
path.moveTo(rect.bottomLeft());
path.arcTo(QRectF(rect.center().x() - toolSize,
rect.bottom() - toolSize,
toolSize * 2,
toolSize * 2), 0, 180);
} else if (corner() == InternalToolBox::Left) {
path.arcTo(QRectF(rect.left(),
rect.center().y() - toolSize,
toolSize * 2,
toolSize * 2), 90, -180);
} else {
path.moveTo(rect.topRight());
path.arcTo(QRectF(rect.left(),
rect.center().y() - toolSize,
toolSize * 2,
toolSize * 2), 90, 180);
}
return path;
}
void PanelToolBox::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
highlight(true);
QGraphicsItem::hoverEnterEvent(event);
}
void PanelToolBox::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
//kDebug() << event->pos() << event->scenePos()
if (!isShowing()) {
highlight(false);
}
QGraphicsItem::hoverLeaveEvent(event);
}
void PanelToolBox::showToolBox()
{
}
void PanelToolBox::hideToolBox()
{
}
void PanelToolBox::setShowing(bool show)
{
InternalToolBox::setShowing(show);
highlight(show);
}
void PanelToolBox::toolTipAboutToShow()
{
if (isShowing()) {
return;
}
ToolTipContent c(i18n("Panel Tool Box"),
i18n("Click to access size, location and hiding controls as well as to add "
"new widgets to the panel."),
KIcon("plasma"));
c.setAutohide(false);
ToolTipManager::self()->setContent(this, c);
}
void PanelToolBox::toolTipHidden()
{
ToolTipManager::self()->clearContent(this);
}
void PanelToolBox::highlight(bool highlighting)
{
if (d->highlighting == highlighting) {
return;
}
d->highlighting = highlighting;
QPropertyAnimation *anim = d->anim.data();
if (d->highlighting) {
if (anim) {
anim->stop();
d->anim.clear();
}
anim = new QPropertyAnimation(this, "highlight", this);
d->anim = anim;
}
if (anim->state() != QAbstractAnimation::Stopped) {
anim->stop();
}
anim->setDuration(240);
anim->setStartValue(0);
anim->setEndValue(size());
if(d->highlighting) {
anim->start();
} else {
anim->setDirection(QAbstractAnimation::Backward);
anim->start(QAbstractAnimation::DeleteWhenStopped);
}
}
void PanelToolBox::setHighlightValue(qreal progress)
{
d->animFrame = progress;
update();
}
qreal PanelToolBox::highlightValue() const
{
return d->animFrame;
}
void PanelToolBox::toggle()
{
setShowing(!isShowing());
}
} // plasma namespace
#include "paneltoolbox_p.moc"

View File

@ -1,78 +0,0 @@
/*
* Copyright 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by 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_PANELTOOLBOX_P_H
#define PLASMA_PANELTOOLBOX_P_H
#include <QGraphicsItem>
#include <QObject>
#include <QTime>
#include <kicon.h>
#include <private/internaltoolbox_p.h>
#include "animator.h"
namespace Plasma
{
class Widget;
class EmptyGraphicsItem;
class PanelToolBoxPrivate;
class PanelToolBox : public InternalToolBox
{
Q_OBJECT
Q_PROPERTY(qreal highlight READ highlightValue WRITE setHighlightValue)
public:
explicit PanelToolBox(Containment *parent);
~PanelToolBox();
QRectF boundingRect() const;
QPainterPath shape() const;
void showToolBox();
void hideToolBox();
void setShowing(bool show);
public Q_SLOTS:
void toolTipAboutToShow();
void toolTipHidden();
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
protected slots:
void setHighlightValue(qreal progress);
qreal highlightValue() const;
void toggle();
void assignColors();
private:
void highlight(bool highlighting);
PanelToolBoxPrivate *d;
};
} // Plasma namespace
#endif // multiple inclusion guard