Give extenders the 'stacked' look from Pinheiro's mockup. It still needs some minor tweaks, but it allready looks quite sexy.
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=873867
This commit is contained in:
parent
6ef3b851ac
commit
a26b73b6bb
51
dialog.cpp
51
dialog.cpp
@ -38,8 +38,11 @@
|
||||
#include <KDebug>
|
||||
#include <NETRootInfo>
|
||||
|
||||
#include <plasma/panelsvg.h>
|
||||
#include <plasma/theme.h>
|
||||
#include "plasma/applet.h"
|
||||
#include "plasma/extender.h"
|
||||
#include "plasma/private/extender_p.h"
|
||||
#include "plasma/panelsvg.h"
|
||||
#include "plasma/theme.h"
|
||||
|
||||
#ifdef Q_WS_X11
|
||||
#include <X11/Xlib.h>
|
||||
@ -89,7 +92,39 @@ void DialogPrivate::themeUpdated()
|
||||
const int leftWidth = background->marginSize(Plasma::LeftMargin);
|
||||
const int rightWidth = background->marginSize(Plasma::RightMargin);
|
||||
const int bottomHeight = background->marginSize(Plasma::BottomMargin);
|
||||
q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
|
||||
|
||||
//TODO: correct handling of the situation when having vertical panels.
|
||||
Extender *extender = qobject_cast<Extender*>(widget);
|
||||
if (extender) {
|
||||
switch (extender->d->applet->location()) {
|
||||
case BottomEdge:
|
||||
background->setEnabledBorders(PanelSvg::LeftBorder | PanelSvg::TopBorder
|
||||
| PanelSvg::RightBorder);
|
||||
q->setContentsMargins(0, topHeight, 0, 0);
|
||||
break;
|
||||
case TopEdge:
|
||||
background->setEnabledBorders(PanelSvg::LeftBorder | PanelSvg::BottomBorder
|
||||
| PanelSvg::RightBorder);
|
||||
q->setContentsMargins(0, 0, 0, bottomHeight);
|
||||
break;
|
||||
case LeftEdge:
|
||||
background->setEnabledBorders(PanelSvg::TopBorder | PanelSvg::BottomBorder
|
||||
| PanelSvg::RightBorder);
|
||||
q->setContentsMargins(0, topHeight, 0, bottomHeight);
|
||||
break;
|
||||
case RightEdge:
|
||||
background->setEnabledBorders(PanelSvg::TopBorder | PanelSvg::BottomBorder
|
||||
| PanelSvg::LeftBorder);
|
||||
q->setContentsMargins(0, topHeight, 0, bottomHeight);
|
||||
break;
|
||||
default:
|
||||
background->setEnabledBorders(PanelSvg::AllBorders);
|
||||
q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
|
||||
}
|
||||
} else {
|
||||
q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
|
||||
}
|
||||
q->update();
|
||||
}
|
||||
|
||||
void DialogPrivate::adjustView()
|
||||
@ -99,13 +134,15 @@ void DialogPrivate::adjustView()
|
||||
|
||||
kDebug() << "Widget size:" << widget->size()
|
||||
<< "| Widget size hint:" << widget->effectiveSizeHint(Qt::PreferredSize)
|
||||
<< "| Widget minsize hint:" << widget->minimumSize()
|
||||
<< "| Widget maxsize hint:" << widget->maximumSize()
|
||||
<< "| Widget bounding rect:" << widget->boundingRect();
|
||||
|
||||
QRectF boundingRect = widget->boundingRect();
|
||||
boundingRect.setSize(widget->effectiveSizeHint(Qt::PreferredSize));
|
||||
|
||||
//reposition and resize the view.
|
||||
view->setSceneRect(widget->mapToScene(boundingRect).boundingRect());
|
||||
view->setSceneRect(widget->sceneBoundingRect());
|
||||
view->resize(view->mapFromScene(view->sceneRect()).boundingRect().size());
|
||||
view->centerOn(widget);
|
||||
|
||||
@ -115,10 +152,10 @@ void DialogPrivate::adjustView()
|
||||
|
||||
q->setMinimumSize(qMin(int(widget->minimumSize().width()) + left + right, QWIDGETSIZE_MAX),
|
||||
qMin(int(widget->minimumSize().height()) + top + bottom, QWIDGETSIZE_MAX));
|
||||
q->resize(qMin(int(widget->minimumSize().width()) + left + right, QWIDGETSIZE_MAX),
|
||||
qMin(int(widget->minimumSize().height()) + top + bottom, QWIDGETSIZE_MAX));
|
||||
q->setMaximumSize(qMin(int(widget->maximumSize().width()) + left + right, QWIDGETSIZE_MAX),
|
||||
qMin(int(widget->maximumSize().height()) + top + bottom, QWIDGETSIZE_MAX));
|
||||
q->resize(qMin(int(view->size().width()) + left + right, QWIDGETSIZE_MAX),
|
||||
qMin(int(view->size().height()) + top + bottom, QWIDGETSIZE_MAX));
|
||||
q->updateGeometry();
|
||||
|
||||
if (q->size() != prevSize) {
|
||||
@ -316,6 +353,8 @@ void Dialog::setGraphicsWidget(QGraphicsWidget *widget)
|
||||
lay->setSpacing(0);
|
||||
}
|
||||
|
||||
d->themeUpdated();
|
||||
|
||||
if (!d->view) {
|
||||
d->view = new QGraphicsView(this);
|
||||
d->view->setFrameShape(QFrame::NoFrame);
|
||||
|
106
extender.cpp
106
extender.cpp
@ -27,12 +27,14 @@
|
||||
#include "containment.h"
|
||||
#include "corona.h"
|
||||
#include "extenderitem.h"
|
||||
#include "panelsvg.h"
|
||||
#include "popupapplet.h"
|
||||
#include "svg.h"
|
||||
#include "widgets/label.h"
|
||||
|
||||
#include "private/applet_p.h"
|
||||
#include "private/extender_p.h"
|
||||
#include "private/extenderitem_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
@ -42,12 +44,15 @@ Extender::Extender(Applet *applet)
|
||||
d(new ExtenderPrivate(applet, this))
|
||||
{
|
||||
applet->d->extender = this;
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
d->layout = new QGraphicsLinearLayout(this);
|
||||
d->layout->setOrientation(Qt::Vertical);
|
||||
d->layout->setContentsMargins(0, 0, 0, 0);
|
||||
d->layout->setSpacing(0);
|
||||
setLayout(d->layout);
|
||||
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
|
||||
d->emptyExtenderLabel = new Label(this);
|
||||
d->emptyExtenderLabel->setText(d->emptyExtenderMessage);
|
||||
d->emptyExtenderLabel->setMinimumSize(QSizeF(150, 64));
|
||||
@ -55,8 +60,6 @@ Extender::Extender(Applet *applet)
|
||||
d->emptyExtenderLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
|
||||
d->layout->addItem(d->emptyExtenderLabel);
|
||||
|
||||
d->adjustSizeHints();
|
||||
|
||||
d->loadExtenderItems();
|
||||
}
|
||||
|
||||
@ -130,6 +133,21 @@ ExtenderItem *Extender::item(const QString &name) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Extender::setExtenderAppearance(Appearance appearance)
|
||||
{
|
||||
if (d->appearance == appearance) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->appearance = appearance;
|
||||
d->updateBorders();
|
||||
}
|
||||
|
||||
Extender::Appearance Extender::extenderAppearance() const
|
||||
{
|
||||
return d->appearance;
|
||||
}
|
||||
|
||||
void Extender::saveState()
|
||||
{
|
||||
foreach (ExtenderItem *item, attachedItems()) {
|
||||
@ -140,7 +158,7 @@ void Extender::saveState()
|
||||
QVariant Extender::itemChange(GraphicsItemChange change, const QVariant &value)
|
||||
{
|
||||
if (change == QGraphicsItem::ItemPositionHasChanged) {
|
||||
emit geometryChanged();
|
||||
d->adjustSize();
|
||||
}
|
||||
|
||||
return QGraphicsWidget::itemChange(change, value);
|
||||
@ -169,7 +187,7 @@ void Extender::itemAddedEvent(ExtenderItem *item, const QPointF &pos)
|
||||
d->emptyExtenderLabel->hide();
|
||||
}
|
||||
|
||||
d->adjustSizeHints();
|
||||
d->adjustSize();
|
||||
}
|
||||
|
||||
void Extender::itemRemovedEvent(ExtenderItem *item)
|
||||
@ -185,7 +203,7 @@ void Extender::itemRemovedEvent(ExtenderItem *item)
|
||||
d->layout->addItem(d->emptyExtenderLabel);
|
||||
}
|
||||
|
||||
d->adjustSizeHints();
|
||||
d->adjustSize();
|
||||
}
|
||||
|
||||
void Extender::itemHoverEnterEvent(ExtenderItem *item)
|
||||
@ -209,7 +227,7 @@ void Extender::itemHoverMoveEvent(ExtenderItem *item, const QPointF &pos)
|
||||
|
||||
//Create a widget that functions as spacer, and add that to the layout.
|
||||
QGraphicsWidget *widget = new QGraphicsWidget(this);
|
||||
widget->setPreferredSize(QSizeF(item->size().width(), item->size().height()));
|
||||
widget->setPreferredSize(QSizeF(item->minimumSize().width(), item->size().height()));
|
||||
widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
d->spacerWidget = widget;
|
||||
d->layout->insertItem(insertIndex, widget);
|
||||
@ -221,7 +239,7 @@ void Extender::itemHoverMoveEvent(ExtenderItem *item, const QPointF &pos)
|
||||
d->emptyExtenderLabel->hide();
|
||||
}
|
||||
|
||||
d->adjustSizeHints();
|
||||
d->adjustSize();
|
||||
}
|
||||
|
||||
void Extender::itemHoverLeaveEvent(ExtenderItem *item)
|
||||
@ -244,7 +262,22 @@ void Extender::itemHoverLeaveEvent(ExtenderItem *item)
|
||||
d->layout->addItem(d->emptyExtenderLabel);
|
||||
}
|
||||
|
||||
d->adjustSizeHints();
|
||||
d->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
PanelSvg::EnabledBorders Extender::enabledBordersForItem(ExtenderItem *item) const
|
||||
{
|
||||
ExtenderItem *topItem = dynamic_cast<ExtenderItem*>(d->layout->itemAt(0));
|
||||
ExtenderItem *bottomItem = dynamic_cast<ExtenderItem*>(d->layout->itemAt(d->layout->count() - 1));
|
||||
if (d->appearance == TopDownStacked && bottomItem != item) {
|
||||
return PanelSvg::LeftBorder | PanelSvg::BottomBorder | PanelSvg::RightBorder;
|
||||
} else if (d->appearance == BottomUpStacked && topItem != item) {
|
||||
return PanelSvg::LeftBorder | PanelSvg::TopBorder | PanelSvg::RightBorder;
|
||||
} else if (d->appearance != NoBorders) {
|
||||
return PanelSvg::LeftBorder | PanelSvg::RightBorder;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +287,8 @@ ExtenderPrivate::ExtenderPrivate(Applet *applet, Extender *extender) :
|
||||
spacerWidget(0),
|
||||
emptyExtenderMessage(i18n("no items")),
|
||||
emptyExtenderLabel(0),
|
||||
popup(false)
|
||||
popup(false),
|
||||
appearance(Extender::NoBorders)
|
||||
{
|
||||
}
|
||||
|
||||
@ -265,32 +299,19 @@ ExtenderPrivate::~ExtenderPrivate()
|
||||
void ExtenderPrivate::addExtenderItem(ExtenderItem *item, const QPointF &pos)
|
||||
{
|
||||
attachedExtenderItems.append(item);
|
||||
q->itemAddedEvent(item, pos);
|
||||
q->itemHoverLeaveEvent(item);
|
||||
q->itemAddedEvent(item, pos);
|
||||
updateBorders();
|
||||
emit q->itemAttached(item);
|
||||
}
|
||||
|
||||
void ExtenderPrivate::removeExtenderItem(ExtenderItem *item)
|
||||
{
|
||||
attachedExtenderItems.removeOne(item);
|
||||
updateBorders();
|
||||
q->itemRemovedEvent(item);
|
||||
}
|
||||
|
||||
void ExtenderPrivate::adjustSizeHints()
|
||||
{
|
||||
if (!q->layout()) {
|
||||
return;
|
||||
}
|
||||
|
||||
q->layout()->updateGeometry();
|
||||
|
||||
q->setMinimumSize(q->layout()->minimumSize());
|
||||
q->setPreferredSize(q->layout()->preferredSize());
|
||||
q->setMaximumSize(q->layout()->maximumSize());
|
||||
|
||||
q->updateGeometry();
|
||||
}
|
||||
|
||||
int ExtenderPrivate::insertIndexFromPos(const QPointF &pos) const
|
||||
{
|
||||
int insertIndex = -1;
|
||||
@ -376,7 +397,40 @@ void ExtenderPrivate::loadExtenderItems()
|
||||
}
|
||||
}
|
||||
|
||||
adjustSizeHints();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void ExtenderPrivate::updateBorders()
|
||||
{
|
||||
foreach (ExtenderItem *item, q->attachedItems()) {
|
||||
if (item && (item->d->background->enabledBorders() != q->enabledBordersForItem(item))) {
|
||||
//call themeChanged to change the backgrounds enabled borders, and move all contained
|
||||
//widgets according to it's changed margins.
|
||||
item->d->themeChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtenderPrivate::adjustSize()
|
||||
{
|
||||
if (q->layout()) {
|
||||
q->layout()->updateGeometry();
|
||||
//FIXME: for some reason the preferred size hint get's set correctly,
|
||||
//but the minimumSizeHint doesn't. Investigate why.
|
||||
q->setMinimumSize(q->layout()->preferredSize());
|
||||
}
|
||||
|
||||
//check if our parentItem is an applet, and set the applets correct minimumsize.
|
||||
Applet *applet = qgraphicsitem_cast<Applet*>(q->parentItem());
|
||||
if (applet) {
|
||||
QSizeF marginSize = applet->size() - applet->contentsRect().size();
|
||||
//FIXME: for some reason the preferred size hint get's set correctly,
|
||||
//but the minimumSizeHint doesn't. Investigate why.
|
||||
applet->setMinimumSize(q->minimumSize() + marginSize);
|
||||
applet->adjustSize();
|
||||
}
|
||||
|
||||
emit q->geometryChanged();
|
||||
}
|
||||
|
||||
} // Plasma namespace
|
||||
|
44
extender.h
44
extender.h
@ -22,6 +22,7 @@
|
||||
|
||||
#include <QtGui/QGraphicsWidget>
|
||||
|
||||
#include "plasma/panelsvg.h"
|
||||
#include "plasma/plasma_export.h"
|
||||
|
||||
namespace Plasma
|
||||
@ -54,6 +55,27 @@ class PLASMA_EXPORT Extender : public QGraphicsWidget
|
||||
Q_PROPERTY(QString emptyExtenderMessage READ emptyExtenderMessage WRITE setEmptyExtenderMessage)
|
||||
|
||||
public:
|
||||
/**
|
||||
* Description on how to render the extender's items.
|
||||
*/
|
||||
enum Appearance {
|
||||
NoBorders = 0, /** Draws no borders on the extender's items. When placed in an applet
|
||||
on the desktop, use this setting and use the standard margins of
|
||||
the applet containing this extender. */
|
||||
BottomUpStacked = 1, /** Draws no borders on the topmost extenderitem, but draws the
|
||||
left, top and right border on subsequent items. When margins
|
||||
of the containing dialog are set to 0, except for the top
|
||||
margin, this leads to the 'stacked' look, recommended for
|
||||
extenders of applet's contained in a panel at the bottom of
|
||||
the screen. */
|
||||
TopDownStacked = 2 /** Draws no borders on the bottom extenderitem, but draws the
|
||||
left, bottom and right border on subsequent items. When margins
|
||||
of the containing dialog are set to 0, except for the bottom
|
||||
margin, this leads to the 'stacked' look, recommended for
|
||||
extenders of applet's contained in a panel at the top of
|
||||
the screen. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an extender. Note that extender expects applet to have a config(), and needs a
|
||||
* scene because of that. So you should only instantiate an extender in init() or later, not
|
||||
@ -102,6 +124,18 @@ class PLASMA_EXPORT Extender : public QGraphicsWidget
|
||||
*/
|
||||
ExtenderItem *item(const QString &name) const;
|
||||
|
||||
/**
|
||||
* Use this function to instruct the extender on how to render it's items. Usually you will
|
||||
* want to call this function in your applet's constraintsEvent, allthough this is already
|
||||
* done for you when using PopupApplet at base class for your applet. Defaults to NoBorders.
|
||||
*/
|
||||
void setExtenderAppearance(Appearance appearance);
|
||||
|
||||
/**
|
||||
* @return the current way of rendering extender items that is used.
|
||||
*/
|
||||
Appearance extenderAppearance() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get's called after an item has been added to this extender. The bookkeeping has already
|
||||
@ -151,6 +185,14 @@ class PLASMA_EXPORT Extender : public QGraphicsWidget
|
||||
*/
|
||||
virtual void saveState();
|
||||
|
||||
/**
|
||||
* This function get's called on every item to determine which background border's to
|
||||
* render.
|
||||
* @param item the item for which it's position or extender has changed.
|
||||
* @return the borders that have to be enabled on it's background.
|
||||
*/
|
||||
virtual PanelSvg::EnabledBorders enabledBordersForItem(ExtenderItem *item) const;
|
||||
|
||||
/**
|
||||
* @reimplemented from QGraphicsWidget
|
||||
*/
|
||||
@ -183,6 +225,8 @@ class PLASMA_EXPORT Extender : public QGraphicsWidget
|
||||
friend class ExtenderPrivate;
|
||||
friend class ExtenderItem;
|
||||
friend class ExtenderItemPrivate;
|
||||
//dialog needs access to the extender's applet location.
|
||||
friend class DialogPrivate;
|
||||
//applet should be able to call saveState();
|
||||
friend class Applet;
|
||||
|
||||
|
576
extenderitem.cpp
576
extenderitem.cpp
@ -46,247 +46,11 @@
|
||||
|
||||
#include "private/applet_p.h"
|
||||
#include "private/extender_p.h"
|
||||
#include "private/extenderitem_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class ExtenderItemPrivate
|
||||
{
|
||||
public:
|
||||
ExtenderItemPrivate(ExtenderItem *extenderItem, Extender *hostExtender)
|
||||
: q(extenderItem),
|
||||
widget(0),
|
||||
toplevel(0),
|
||||
previousTargetExtender(0),
|
||||
extender(hostExtender),
|
||||
title(QString()),
|
||||
sourceAppletId(hostExtender->d->applet->id()),
|
||||
mousePressed(false),
|
||||
expirationTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
~ExtenderItemPrivate()
|
||||
{
|
||||
delete toplevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Rect containing the area of the detachable where the draghandle can be drawn.
|
||||
*/
|
||||
QRectF dragHandleRect()
|
||||
{
|
||||
QRectF rect(bgLeft, bgTop, q->size().width() - bgLeft - bgRight,
|
||||
dragger->elementSize("hint-preferred-icon-size").height() +
|
||||
dragTop + dragBottom);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
QRectF titleRect()
|
||||
{
|
||||
return dragHandleRect().adjusted(dragLeft + collapseIcon->size().width() + 1, dragTop,
|
||||
-toolbox->size().width() - dragRight, -dragBottom);
|
||||
}
|
||||
|
||||
//XXX kinda duplicated from applethandle.
|
||||
//returns true if the applet overlaps with a different view then the current one.
|
||||
bool leaveCurrentView(const QRect &rect)
|
||||
{
|
||||
if ((q->sceneBoundingRect().left() < 0)) {
|
||||
//always leaveCurrentView when the item is in a Plasma::Dialog which can easy be
|
||||
//seen by checking if it is in topleft quadrant and it's not just there because it's
|
||||
//being viewed by the toplevel view.
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
||||
if (widget->geometry().intersects(rect) && widget->isVisible() && widget != toplevel) {
|
||||
//is this widget a plasma view, a different view then our current one,
|
||||
//AND not a dashboardview?
|
||||
QGraphicsView *v = qobject_cast<QGraphicsView*>(widget);
|
||||
QGraphicsView *currentV = 0;
|
||||
|
||||
if (hostApplet()) {
|
||||
currentV = qobject_cast<QGraphicsView*>(hostApplet()->containment()->view());
|
||||
}
|
||||
|
||||
if (v && v != currentV) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect screenRect() {
|
||||
return hostApplet()->containment()->view()
|
||||
->mapFromScene(q->sceneBoundingRect()).boundingRect();
|
||||
}
|
||||
|
||||
void toggleCollapse() {
|
||||
q->setCollapsed(!q->isCollapsed());
|
||||
}
|
||||
|
||||
void updateToolBox() {
|
||||
if (toolbox && dragger && toolboxLayout) {
|
||||
//clean the layout.
|
||||
uint iconHeight = dragger->elementSize("hint-preferred-icon-size").height();
|
||||
|
||||
while (toolboxLayout->count()) {
|
||||
QGraphicsLayoutItem *icon = toolboxLayout->itemAt(0);
|
||||
QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(icon);
|
||||
widget->deleteLater();
|
||||
toolboxLayout->removeAt(0);
|
||||
}
|
||||
|
||||
//add the actions that are actually set to visible.
|
||||
foreach (QAction *action, actions) {
|
||||
if (action->isVisible()) {
|
||||
Icon *icon = new Icon(q);
|
||||
icon->setAction(action);
|
||||
QSizeF iconSize = icon->sizeFromIconSize(iconHeight);
|
||||
icon->setMinimumSize(iconSize);
|
||||
icon->setMaximumSize(iconSize);
|
||||
toolboxLayout->addItem(icon);
|
||||
}
|
||||
}
|
||||
|
||||
if (q->isDetached() && sourceApplet) {
|
||||
Icon *returnToSource = new Icon(q);
|
||||
returnToSource->setSvg("widgets/configuration-icons", "return-to-source");
|
||||
QSizeF iconSize = returnToSource->sizeFromIconSize(iconHeight);
|
||||
returnToSource->setMinimumSize(iconSize);
|
||||
returnToSource->setMaximumSize(iconSize);
|
||||
|
||||
toolboxLayout->addItem(returnToSource);
|
||||
QObject::connect(returnToSource, SIGNAL(clicked()),
|
||||
q, SLOT(moveBackToSource()));
|
||||
}
|
||||
|
||||
toolboxLayout->updateGeometry();
|
||||
|
||||
//position the toolbox correctly.
|
||||
QSizeF minimum = toolboxLayout->minimumSize();
|
||||
toolbox->resize(minimum);
|
||||
toolbox->setPos(q->size().width() - minimum.width() - bgRight,
|
||||
((dragger->size().height() + dragTop + dragBottom) / 2) -
|
||||
(minimum.height() / 2) + bgTop);
|
||||
toolbox->update();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: something like this as static function in corona might be a good idea.
|
||||
QPointF scenePosFromScreenPos(const QPoint &pos) const
|
||||
{
|
||||
//get the stacking order of the toplevel windows and remove the
|
||||
//toplevel view that's only here while dragging, since we're not
|
||||
//interested in finding that.
|
||||
QList<WId> order = KWindowSystem::stackingOrder();
|
||||
if (toplevel) {
|
||||
order.removeOne(toplevel->winId());
|
||||
}
|
||||
|
||||
QGraphicsView *found = 0;
|
||||
foreach (QWidget *w, QApplication::topLevelWidgets()) {
|
||||
QGraphicsView *v = 0;
|
||||
|
||||
//first check if we're over a Dialog.
|
||||
Dialog *dialog = qobject_cast<Dialog*>(w);
|
||||
if (dialog) {
|
||||
if (dialog->isVisible() && dialog->geometry().contains(pos)) {
|
||||
v = qobject_cast<QGraphicsView*>(dialog->layout()->itemAt(0)->widget());
|
||||
if (v) {
|
||||
return v->mapToScene(v->mapFromGlobal(pos));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v = qobject_cast<QGraphicsView *>(w);
|
||||
}
|
||||
|
||||
//else check if it is a QGV:
|
||||
if (v && w->isVisible() && w->geometry().contains(pos)) {
|
||||
if (found && order.contains(found->winId())) {
|
||||
if (order.indexOf(found->winId()) < order.indexOf(v->winId())) {
|
||||
found = v;
|
||||
}
|
||||
} else {
|
||||
found = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return QPointF();
|
||||
}
|
||||
|
||||
return found->mapToScene(found->mapFromGlobal(pos));
|
||||
}
|
||||
|
||||
Applet *hostApplet() const
|
||||
{
|
||||
if (extender) {
|
||||
return extender->d->applet;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void themeChanged()
|
||||
{
|
||||
dragger->setImagePath("widgets/extender-dragger");
|
||||
background->setImagePath("widgets/extender-background");
|
||||
|
||||
dragger->getMargins(dragLeft, dragTop, dragRight, dragBottom);
|
||||
background->getMargins(bgLeft, bgTop, bgRight, bgBottom);
|
||||
|
||||
//setCollapsed recalculates size hints.
|
||||
q->setCollapsed(q->isCollapsed());
|
||||
q->update();
|
||||
}
|
||||
|
||||
ExtenderItem *q;
|
||||
|
||||
QGraphicsItem *widget;
|
||||
QGraphicsWidget *toolbox;
|
||||
QGraphicsLinearLayout *toolboxLayout;
|
||||
QGraphicsView *toplevel;
|
||||
|
||||
Extender *previousTargetExtender;
|
||||
Extender *extender;
|
||||
Applet *sourceApplet;
|
||||
|
||||
KConfigGroup config;
|
||||
|
||||
PanelSvg *dragger;
|
||||
PanelSvg *background;
|
||||
|
||||
Icon *collapseIcon;
|
||||
|
||||
QMap<QString, QAction*> actions;
|
||||
|
||||
QString title;
|
||||
QString name;
|
||||
|
||||
uint sourceAppletId;
|
||||
uint extenderItemId;
|
||||
|
||||
qreal dragLeft, dragTop, dragRight, dragBottom;
|
||||
qreal bgLeft, bgTop, bgRight, bgBottom;
|
||||
|
||||
QPointF deltaScene;
|
||||
QPoint mousePos;
|
||||
|
||||
bool mousePressed;
|
||||
bool mouseOver;
|
||||
|
||||
QTimer *expirationTimer;
|
||||
|
||||
static uint s_maxExtenderItemId;
|
||||
};
|
||||
|
||||
uint ExtenderItemPrivate::s_maxExtenderItemId = 0;
|
||||
|
||||
ExtenderItem::ExtenderItem(Extender *hostExtender, uint extenderItemId)
|
||||
: QGraphicsWidget(hostExtender),
|
||||
d(new ExtenderItemPrivate(this, hostExtender))
|
||||
@ -302,12 +66,15 @@ ExtenderItem::ExtenderItem(Extender *hostExtender, uint extenderItemId)
|
||||
d->extenderItemId = ++ExtenderItemPrivate::s_maxExtenderItemId;
|
||||
}
|
||||
|
||||
//TODO: make sourceApplet a function so stuff doesn't break when the source applet has been
|
||||
//removed.
|
||||
d->sourceApplet = hostExtender->d->applet;
|
||||
|
||||
//create items's configgroup
|
||||
KConfigGroup cg = hostExtender->d->applet->config("ExtenderItems");
|
||||
KConfigGroup dg = KConfigGroup(&cg, QString::number(d->extenderItemId));
|
||||
|
||||
//TODO: automatically load title and icon.
|
||||
if (!dg.readEntry("sourceAppletId", 0)) {
|
||||
//The item is new
|
||||
dg.writeEntry("sourceAppletPluginName", hostExtender->d->applet->pluginName());
|
||||
@ -330,33 +97,22 @@ ExtenderItem::ExtenderItem(Extender *hostExtender, uint extenderItemId)
|
||||
}
|
||||
}
|
||||
|
||||
//create the dragger and standard applet background.
|
||||
d->dragger = new PanelSvg(this);
|
||||
d->background = new PanelSvg(this);
|
||||
d->themeChanged();
|
||||
|
||||
//create the toolbox.
|
||||
d->toolbox = new QGraphicsWidget(this);
|
||||
d->toolboxLayout = new QGraphicsLinearLayout(d->toolbox);
|
||||
d->toolbox->setLayout(d->toolboxLayout);
|
||||
|
||||
//allow the theme to set the size of the icon.
|
||||
QSizeF iconSize = d->dragger->elementSize("hint-preferred-icon-size");
|
||||
|
||||
//create the collapse/applet icon.
|
||||
d->collapseIcon = new Icon(KIcon(hostExtender->d->applet->icon()), "", this);
|
||||
d->collapseIcon->resize(d->collapseIcon->sizeFromIconSize(iconSize.height()));
|
||||
d->collapseIcon->setPos(d->bgLeft + d->dragLeft,
|
||||
(d->dragger->size().height() + d->dragTop + d->dragBottom) / 2 - d->collapseIcon->size().height() / 2 + d->bgTop);
|
||||
connect(d->collapseIcon, SIGNAL(clicked()), this, SLOT(toggleCollapse()));
|
||||
|
||||
//set the extender we want to move to.
|
||||
setExtender(hostExtender);
|
||||
|
||||
setAcceptHoverEvents(true);
|
||||
//set the image paths, image sizes and collapseIcon position.
|
||||
d->themeChanged();
|
||||
|
||||
d->updateToolBox();
|
||||
updateGeometry();
|
||||
setAcceptsHoverEvents(true);
|
||||
|
||||
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), this, SLOT(themeChanged()));
|
||||
}
|
||||
@ -397,7 +153,11 @@ QString ExtenderItem::name() const
|
||||
void ExtenderItem::setWidget(QGraphicsItem *widget)
|
||||
{
|
||||
widget->setParentItem(this);
|
||||
widget->setPos(QPointF(d->bgLeft + d->dragLeft, d->dragHandleRect().height() +
|
||||
|
||||
QSizeF iconSize = d->dragger->elementSize("hint-preferred-icon-size");
|
||||
QSizeF panelSize(QSizeF(size().width() - d->bgLeft - d->bgRight,
|
||||
iconSize.height() + d->dragTop + d->dragBottom));
|
||||
widget->setPos(QPointF(d->bgLeft + d->dragLeft, panelSize.height() +
|
||||
d->bgTop + d->dragTop));
|
||||
d->widget = widget;
|
||||
setCollapsed(isCollapsed()); //updates the size hints.
|
||||
@ -466,6 +226,9 @@ void ExtenderItem::setExtender(Extender *extender, const QPointF &pos)
|
||||
d->expirationTimer = 0;
|
||||
}
|
||||
|
||||
//set the background svg to that of the extender we're moving to.
|
||||
d->themeChanged();
|
||||
|
||||
//we might have to enable or disable the returnToSource button.
|
||||
d->updateToolBox();
|
||||
}
|
||||
@ -578,27 +341,27 @@ void ExtenderItem::setCollapsed(bool collapsed)
|
||||
|
||||
d->widget->setVisible(!collapsed);
|
||||
|
||||
QSizeF minimumSize;
|
||||
QSizeF preferredSize;
|
||||
QSizeF maximumSize;
|
||||
QSizeF min;
|
||||
QSizeF pref;
|
||||
QSizeF max;
|
||||
|
||||
if (d->widget->isWidget()) {
|
||||
QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(d->widget);
|
||||
minimumSize = graphicsWidget->minimumSize();
|
||||
preferredSize = graphicsWidget->preferredSize();
|
||||
maximumSize = graphicsWidget->maximumSize();
|
||||
min = graphicsWidget->minimumSize();
|
||||
pref = graphicsWidget->preferredSize();
|
||||
max = graphicsWidget->maximumSize();
|
||||
} else {
|
||||
minimumSize = d->widget->boundingRect().size();
|
||||
preferredSize = d->widget->boundingRect().size();
|
||||
maximumSize = d->widget->boundingRect().size();
|
||||
min = d->widget->boundingRect().size();
|
||||
pref = d->widget->boundingRect().size();
|
||||
max = d->widget->boundingRect().size();
|
||||
}
|
||||
|
||||
if (collapsed) {
|
||||
setPreferredSize(QSizeF(preferredSize.width() + marginWidth,
|
||||
setPreferredSize(QSizeF(pref.width() + marginWidth,
|
||||
d->dragHandleRect().height() + marginHeight));
|
||||
setMinimumSize(QSizeF(minimumSize.width() + marginWidth,
|
||||
setMinimumSize(QSizeF(min.width() + marginWidth,
|
||||
d->dragHandleRect().height() + marginHeight));
|
||||
setMaximumSize(QSizeF(maximumSize.width() + marginWidth,
|
||||
setMaximumSize(QSizeF(max.width() + marginWidth,
|
||||
d->dragHandleRect().height() + marginHeight));
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
@ -606,16 +369,15 @@ void ExtenderItem::setCollapsed(bool collapsed)
|
||||
d->collapseIcon->setToolTip(i18n("Expand this widget"));
|
||||
}
|
||||
} else {
|
||||
setPreferredSize(QSizeF(preferredSize.width() + marginWidth,
|
||||
preferredSize.height() + d->dragHandleRect().height() + marginHeight));
|
||||
setMinimumSize(QSizeF(minimumSize.width() + marginWidth,
|
||||
minimumSize.height() + d->dragHandleRect().height() + marginHeight));
|
||||
setMaximumSize(QSizeF(maximumSize.width() + marginWidth,
|
||||
maximumSize.height() + d->dragHandleRect().height() + marginHeight));
|
||||
setPreferredSize(QSizeF(pref.width() + marginWidth,
|
||||
pref.height() + d->dragHandleRect().height() + marginHeight));
|
||||
setMinimumSize(QSizeF(min.width() + marginWidth,
|
||||
min.height() + d->dragHandleRect().height() + marginHeight));
|
||||
setMaximumSize(QSizeF(max.width() + marginWidth,
|
||||
max.height() + d->dragHandleRect().height() + marginHeight));
|
||||
|
||||
if (d->widget->isWidget()) {
|
||||
QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(d->widget);
|
||||
setSizePolicy(graphicsWidget->sizePolicy());
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
} else {
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
}
|
||||
@ -626,8 +388,7 @@ void ExtenderItem::setCollapsed(bool collapsed)
|
||||
}
|
||||
|
||||
updateGeometry();
|
||||
|
||||
d->extender->d->adjustSizeHints();
|
||||
d->extender->d->adjustSize();
|
||||
}
|
||||
|
||||
void ExtenderItem::moveBackToSource()
|
||||
@ -647,17 +408,21 @@ void ExtenderItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
painter->setRenderHint(QPainter::TextAntialiasing, true);
|
||||
painter->setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
d->background->paintPanel(painter);
|
||||
if (d->background->enabledBorders() != (PanelSvg::LeftBorder | PanelSvg::RightBorder)) {
|
||||
//Don't paint if only the left and right borders are enabled, we only use the left and right
|
||||
//border in this situation to set the correct margins on this item.
|
||||
d->background->paintPanel(painter, QPointF(0, 0));
|
||||
}
|
||||
|
||||
d->dragger->paintPanel(painter, QPointF(d->bgLeft, d->bgTop));
|
||||
|
||||
//draw the title.
|
||||
//set the font for the title.
|
||||
Plasma::Theme *theme = Plasma::Theme::defaultTheme();
|
||||
QFont font = theme->font(Plasma::Theme::DefaultFont);
|
||||
font.setPointSize(KGlobalSettings::smallestReadableFont().pointSize());
|
||||
font.setWeight(QFont::Bold);
|
||||
|
||||
//XXX: duplicated from windowtaskitem.
|
||||
//create a pixmap with the title that is faded out at the right side of the titleRect.
|
||||
//TODO: hmm, create something generic for this... there's probably more stuff that wants to have
|
||||
//this functionality
|
||||
QRectF rect = QRectF(d->titleRect().width() - 30, 0, 30, d->titleRect().height());
|
||||
@ -693,10 +458,9 @@ void ExtenderItem::resizeEvent(QGraphicsSceneResizeEvent *event)
|
||||
qreal height = event->newSize().height();
|
||||
|
||||
//resize the dragger
|
||||
QSizeF newDraggerSize(width - d->bgLeft - d->bgRight,
|
||||
d->dragger->elementSize("hint-preferred-icon-size").height() +
|
||||
d->dragTop + d->dragBottom);
|
||||
d->dragger->resizePanel(newDraggerSize);
|
||||
d->dragger->resizePanel(QSizeF(width - d->bgLeft - d->bgRight,
|
||||
d->dragger->elementSize("hint-preferred-icon-size").height() +
|
||||
d->dragTop + d->dragBottom));
|
||||
|
||||
//resize the applet background
|
||||
d->background->resizePanel(event->newSize());
|
||||
@ -704,13 +468,17 @@ void ExtenderItem::resizeEvent(QGraphicsSceneResizeEvent *event)
|
||||
//resize the widget
|
||||
if (d->widget && d->widget->isWidget()) {
|
||||
QSizeF newWidgetSize(width - d->bgLeft - d->bgRight - d->dragLeft - d->dragRight,
|
||||
height - d->dragger->size().height() - d->bgTop - d->bgBottom - 2 * d->dragTop - 2 * d->dragBottom);
|
||||
height - d->dragHandleRect().height() - d->bgTop - d->bgBottom -
|
||||
2 * d->dragTop - 2 * d->dragBottom);
|
||||
|
||||
QGraphicsWidget *graphicsWidget = static_cast<QGraphicsWidget*>(d->widget);
|
||||
graphicsWidget->resize(newWidgetSize);
|
||||
}
|
||||
|
||||
d->updateToolBox();
|
||||
//reposition the toolbox.
|
||||
d->repositionToolbox();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
@ -722,13 +490,9 @@ void ExtenderItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
d->mousePressed = true;
|
||||
d->deltaScene = pos();
|
||||
|
||||
Applet *parentApplet = d->hostApplet();
|
||||
|
||||
d->mousePos = event->pos().toPoint();
|
||||
|
||||
parentApplet->raise();
|
||||
setZValue(parentApplet->zValue());
|
||||
d->hostApplet()->raise();
|
||||
setZValue(d->hostApplet()->zValue());
|
||||
|
||||
QPointF mousePos = d->scenePosFromScreenPos(event->screenPos());
|
||||
|
||||
@ -746,6 +510,10 @@ void ExtenderItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->background->enabledBorders() != PanelSvg::AllBorders) {
|
||||
d->themeChanged();
|
||||
}
|
||||
|
||||
//keep track of the movement in scene coordinates. we use this to set the position of the
|
||||
//applet when remaining in the current view.
|
||||
d->deltaScene += event->scenePos() - event->lastScenePos();
|
||||
@ -940,6 +708,236 @@ void ExtenderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
ExtenderItemPrivate::ExtenderItemPrivate(ExtenderItem *extenderItem, Extender *hostExtender)
|
||||
: q(extenderItem),
|
||||
widget(0),
|
||||
toplevel(0),
|
||||
previousTargetExtender(0),
|
||||
extender(hostExtender),
|
||||
dragger(new PanelSvg(extenderItem)),
|
||||
background(new PanelSvg(extenderItem)),
|
||||
title(QString()),
|
||||
sourceAppletId(hostExtender->d->applet->id()),
|
||||
mousePressed(false),
|
||||
expirationTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
ExtenderItemPrivate::~ExtenderItemPrivate()
|
||||
{
|
||||
delete toplevel;
|
||||
}
|
||||
|
||||
//returns a Rect containing the area of the detachable where the draghandle will be drawn.
|
||||
QRectF ExtenderItemPrivate::dragHandleRect()
|
||||
{
|
||||
QSizeF iconSize = dragger->elementSize("hint-preferred-icon-size");
|
||||
QSizeF panelSize(QSizeF(q->size().width() - bgLeft - bgRight,
|
||||
iconSize.height() + dragTop + dragBottom));
|
||||
return QRectF(QPointF(bgLeft, bgTop), panelSize);
|
||||
}
|
||||
|
||||
QRectF ExtenderItemPrivate::titleRect()
|
||||
{
|
||||
return dragHandleRect().adjusted(dragLeft + collapseIcon->size().width() + 1, dragTop,
|
||||
-toolbox->size().width() - dragRight, -dragBottom);
|
||||
}
|
||||
|
||||
bool ExtenderItemPrivate::leaveCurrentView(const QRect &rect)
|
||||
{
|
||||
if ((q->sceneBoundingRect().left() < 0)) {
|
||||
//always leaveCurrentView when the item is in a Plasma::Dialog which can easy be
|
||||
//seen by checking if it is in topleft quadrant and it's not just there because it's
|
||||
//being viewed by the toplevel view.
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (QWidget *widget, QApplication::topLevelWidgets()) {
|
||||
if (widget->geometry().intersects(rect) && widget->isVisible() && widget != toplevel) {
|
||||
//is this widget a plasma view, a different view then our current one,
|
||||
//AND not a dashboardview?
|
||||
QGraphicsView *v = qobject_cast<QGraphicsView*>(widget);
|
||||
QGraphicsView *currentV = 0;
|
||||
|
||||
if (hostApplet()) {
|
||||
currentV = qobject_cast<QGraphicsView*>(hostApplet()->containment()->view());
|
||||
}
|
||||
|
||||
if (v && v != currentV) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QRect ExtenderItemPrivate::screenRect()
|
||||
{
|
||||
return hostApplet()->containment()->view()
|
||||
->mapFromScene(q->sceneBoundingRect()).boundingRect();
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::toggleCollapse()
|
||||
{
|
||||
q->setCollapsed(!q->isCollapsed());
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::updateToolBox()
|
||||
{
|
||||
Q_ASSERT(toolbox);
|
||||
Q_ASSERT(dragger);
|
||||
Q_ASSERT(toolboxLayout);
|
||||
|
||||
uint iconHeight = dragger->elementSize("hint-preferred-icon-size").height();
|
||||
|
||||
//TODO: only delete items that actually have to be deleted, current performance is horrible.
|
||||
//clean the layout.
|
||||
while (toolboxLayout->count()) {
|
||||
QGraphicsLayoutItem *icon = toolboxLayout->itemAt(0);
|
||||
QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(icon);
|
||||
widget->deleteLater();
|
||||
toolboxLayout->removeAt(0);
|
||||
}
|
||||
|
||||
//add the actions that are actually set to visible.
|
||||
foreach (QAction *action, actions) {
|
||||
if (action->isVisible()) {
|
||||
Icon *icon = new Icon(q);
|
||||
icon->setAction(action);
|
||||
QSizeF iconSize = icon->sizeFromIconSize(iconHeight);
|
||||
icon->setMinimumSize(iconSize);
|
||||
icon->setMaximumSize(iconSize);
|
||||
toolboxLayout->addItem(icon);
|
||||
}
|
||||
}
|
||||
|
||||
//add the returntosource icon if we are detached, and have a source applet.
|
||||
if (q->isDetached() && sourceApplet) {
|
||||
Icon *returnToSource = new Icon(q);
|
||||
returnToSource->setSvg("widgets/configuration-icons", "return-to-source");
|
||||
QSizeF iconSize = returnToSource->sizeFromIconSize(iconHeight);
|
||||
returnToSource->setMinimumSize(iconSize);
|
||||
returnToSource->setMaximumSize(iconSize);
|
||||
|
||||
toolboxLayout->addItem(returnToSource);
|
||||
QObject::connect(returnToSource, SIGNAL(clicked()), q, SLOT(moveBackToSource()));
|
||||
}
|
||||
|
||||
toolboxLayout->updateGeometry();
|
||||
|
||||
//position the toolbox correctly.
|
||||
QSizeF minimum = toolboxLayout->minimumSize();
|
||||
toolbox->resize(minimum);
|
||||
repositionToolbox();
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::repositionToolbox()
|
||||
{
|
||||
QSizeF minimum = toolboxLayout->minimumSize();
|
||||
toolbox->setPos(q->size().width() - minimum.width() - bgRight,
|
||||
((dragHandleRect().height() + dragTop + dragBottom)/2) -
|
||||
(minimum.height()/2) + bgTop);
|
||||
}
|
||||
|
||||
//TODO: something like this as static function in corona might be a good idea.
|
||||
QPointF ExtenderItemPrivate::scenePosFromScreenPos(const QPoint &pos) const
|
||||
{
|
||||
//get the stacking order of the toplevel windows and remove the toplevel view that's
|
||||
//only here while dragging, since we're not interested in finding that.
|
||||
QList<WId> order = KWindowSystem::stackingOrder();
|
||||
if (toplevel) {
|
||||
order.removeOne(toplevel->winId());
|
||||
}
|
||||
|
||||
QGraphicsView *found = 0;
|
||||
foreach (QWidget *w, QApplication::topLevelWidgets()) {
|
||||
QGraphicsView *v = 0;
|
||||
|
||||
//first check if we're over a Dialog.
|
||||
Dialog *dialog = qobject_cast<Dialog*>(w);
|
||||
if (dialog) {
|
||||
if (dialog->isVisible() && dialog->geometry().contains(pos)) {
|
||||
v = qobject_cast<QGraphicsView*>(dialog->layout()->itemAt(0)->widget());
|
||||
if (v) {
|
||||
return v->mapToScene(v->mapFromGlobal(pos));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v = qobject_cast<QGraphicsView *>(w);
|
||||
}
|
||||
|
||||
//else check if it is a QGV:
|
||||
if (v && w->isVisible() && w->geometry().contains(pos)) {
|
||||
if (found && order.contains(found->winId())) {
|
||||
if (order.indexOf(found->winId()) < order.indexOf(v->winId())) {
|
||||
found = v;
|
||||
}
|
||||
} else {
|
||||
found = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return QPointF();
|
||||
}
|
||||
|
||||
return found->mapToScene(found->mapFromGlobal(pos));
|
||||
}
|
||||
|
||||
Applet *ExtenderItemPrivate::hostApplet() const
|
||||
{
|
||||
if (extender) {
|
||||
return extender->d->applet;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ExtenderItemPrivate::themeChanged()
|
||||
{
|
||||
QSizeF iconSize = dragger->elementSize("hint-preferred-icon-size");
|
||||
|
||||
background->setImagePath("widgets/extender-background");
|
||||
if (mousePressed) {
|
||||
background->setEnabledBorders(PanelSvg::AllBorders);
|
||||
} else {
|
||||
background->setEnabledBorders(extender->enabledBordersForItem(q));
|
||||
}
|
||||
background->getMargins(bgLeft, bgTop, bgRight, bgBottom);
|
||||
|
||||
dragger->setImagePath("widgets/extender-dragger");
|
||||
dragger->getMargins(dragLeft, dragTop, dragRight, dragBottom);
|
||||
|
||||
QSizeF panelSize(QSizeF(q->size().width() - bgLeft - bgRight,
|
||||
iconSize.height() + dragTop + dragBottom));
|
||||
|
||||
//resize the collapse icon.
|
||||
collapseIcon->resize(collapseIcon->sizeFromIconSize(iconSize.height()));
|
||||
|
||||
//reposition the collapse icon based on the new margins and size.
|
||||
collapseIcon->setPos(bgLeft + dragLeft,
|
||||
(panelSize.height() + dragTop + dragBottom)/2 -
|
||||
collapseIcon->size().height()/2 + bgTop);
|
||||
|
||||
//reposition the widget based on the new margins.
|
||||
if (widget) {
|
||||
widget->setPos(QPointF(bgLeft + dragLeft, panelSize.height() +
|
||||
bgTop + dragTop));
|
||||
}
|
||||
|
||||
//reposition the toolbox.
|
||||
repositionToolbox();
|
||||
|
||||
//setCollapsed recalculates size hints.
|
||||
q->setCollapsed(q->isCollapsed());
|
||||
|
||||
q->update();
|
||||
}
|
||||
|
||||
uint ExtenderItemPrivate::s_maxExtenderItemId = 0;
|
||||
|
||||
} // namespace Plasma
|
||||
|
||||
#include "extenderitem.moc"
|
||||
|
@ -213,6 +213,7 @@ class PLASMA_EXPORT ExtenderItem : public QGraphicsWidget
|
||||
ExtenderItemPrivate * const d;
|
||||
|
||||
friend class Extender;
|
||||
friend class ExtenderPrivate;
|
||||
};
|
||||
} // namespace Plasma
|
||||
#endif // PLASMA_EXTENDERITEM_H
|
||||
|
@ -185,6 +185,11 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
|
||||
q->setLayout(lay);
|
||||
}
|
||||
|
||||
Extender *extender = qobject_cast<Extender*>(gWidget);
|
||||
if (extender) {
|
||||
extender->setExtenderAppearance(Extender::NoBorders);
|
||||
}
|
||||
|
||||
q->setMinimumSize(gWidget->minimumSize() + marginSize);
|
||||
lay->addItem(gWidget);
|
||||
//gWidget->installEventFilter(q);
|
||||
@ -235,6 +240,15 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
|
||||
if (gWidget) {
|
||||
Corona *corona = qobject_cast<Corona *>(gWidget->scene());
|
||||
|
||||
Extender *extender = qobject_cast<Extender*>(gWidget);
|
||||
if (extender) {
|
||||
if (q->location() == TopEdge) {
|
||||
extender->setExtenderAppearance(Extender::TopDownStacked);
|
||||
} else {
|
||||
extender->setExtenderAppearance(Extender::BottomUpStacked);
|
||||
}
|
||||
}
|
||||
|
||||
//could that cast ever fail??
|
||||
if (corona) {
|
||||
corona->addOffscreenWidget(gWidget);
|
||||
@ -289,9 +303,8 @@ bool PopupApplet::eventFilter(QObject *watched, QEvent *event)
|
||||
QTimer::singleShot(100, this, SLOT(clearPopupLostFocus()));
|
||||
}
|
||||
|
||||
/*
|
||||
if (watched == graphicsWidget() && (event->type() == QEvent::GraphicsSceneResize)) {
|
||||
kDebug() << "do the resize!";
|
||||
/**
|
||||
if (layout() && watched == graphicsWidget() && (event->type() == QEvent::GraphicsSceneResize)) {
|
||||
//sizes are recalculated in the constraintsevent so let's just call that.
|
||||
d->popupConstraintsEvent(Plasma::FormFactorConstraint);
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QPointF>
|
||||
#include "../extender.h"
|
||||
|
||||
class QGraphicsGridLayout;
|
||||
class QGraphicsLinearLayout;
|
||||
@ -45,9 +46,10 @@ class ExtenderPrivate
|
||||
|
||||
void addExtenderItem(ExtenderItem *item, const QPointF &pos = QPointF(-1, -1));
|
||||
void removeExtenderItem(ExtenderItem *item);
|
||||
void adjustSizeHints();
|
||||
int insertIndexFromPos(const QPointF &pos) const;
|
||||
void loadExtenderItems();
|
||||
void updateBorders();
|
||||
void adjustSize();
|
||||
|
||||
Extender *q;
|
||||
|
||||
@ -67,6 +69,8 @@ class ExtenderPrivate
|
||||
|
||||
bool popup;
|
||||
|
||||
Extender::Appearance appearance;
|
||||
|
||||
static QGraphicsGridLayout *s_popupLayout;
|
||||
};
|
||||
|
||||
|
@ -19,18 +19,15 @@
|
||||
|
||||
#include "extenderapplet_p.h"
|
||||
|
||||
#include "extender.h"
|
||||
#include "extenderitem.h"
|
||||
|
||||
#include <KDebug>
|
||||
#include <KIcon>
|
||||
#include "../extender.h"
|
||||
#include "../extenderitem.h"
|
||||
|
||||
#include <QGraphicsLinearLayout>
|
||||
|
||||
ExtenderApplet::ExtenderApplet(QObject *parent, const QVariantList &args)
|
||||
: Plasma::Applet(parent, args)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
}
|
||||
|
||||
ExtenderApplet::~ExtenderApplet()
|
||||
@ -39,44 +36,28 @@ ExtenderApplet::~ExtenderApplet()
|
||||
|
||||
void ExtenderApplet::init()
|
||||
{
|
||||
new Plasma::Extender(this);
|
||||
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout();
|
||||
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
|
||||
layout->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
setLayout(layout);
|
||||
extender()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
connect(extender(), SIGNAL(geometryChanged()), this, SLOT(adjustSize()));
|
||||
connect(extender(), SIGNAL(itemDetached(Plasma::ExtenderItem*)),
|
||||
this, SLOT(itemDetached(Plasma::ExtenderItem*)));
|
||||
layout->addItem(extender());
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void ExtenderApplet::adjustSize()
|
||||
{
|
||||
layout()->updateGeometry();
|
||||
|
||||
qreal left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
extender()->setExtenderAppearance(Plasma::Extender::NoBorders);
|
||||
extender()->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
|
||||
setPreferredSize(QSizeF(left + right + layout()->preferredWidth(),
|
||||
top + bottom + layout()->preferredHeight()));
|
||||
setMinimumSize(QSizeF(left + right + layout()->minimumWidth(),
|
||||
top + bottom + layout()->minimumHeight()));
|
||||
setMaximumSize(QSizeF(left + right + layout()->maximumWidth(),
|
||||
top + bottom + layout()->maximumHeight()));
|
||||
connect(extender(), SIGNAL(itemDetached(Plasma::ExtenderItem*)),
|
||||
this, SLOT(itemDetached(Plasma::ExtenderItem*)));
|
||||
|
||||
layout->addItem(extender());
|
||||
updateGeometry();
|
||||
//This wasn't necesarry before... but it is now. weirdness.
|
||||
resize(size().width(), preferredHeight());
|
||||
layout()->invalidate();
|
||||
}
|
||||
|
||||
void ExtenderApplet::itemDetached(Plasma::ExtenderItem *)
|
||||
{
|
||||
kDebug() << "item detached: " << extender()->attachedItems().count();
|
||||
if (!extender()->attachedItems().count()) {
|
||||
destroy();
|
||||
//FIXME: only fire the signal when the item is really detached, not just being dragged away.
|
||||
kDebug() << "delete the extender applet...";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,11 @@
|
||||
|
||||
#include "applet.h"
|
||||
|
||||
/**
|
||||
* This class is used as a 'host' for detached extender items. When an extender item is dropped
|
||||
* somewhere, this applet is added at the location where the item is dropped, and the item is added
|
||||
* to it's extender.
|
||||
*/
|
||||
class ExtenderApplet : public Plasma::Applet
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -33,7 +38,6 @@ class ExtenderApplet : public Plasma::Applet
|
||||
|
||||
public Q_SLOTS:
|
||||
void itemDetached(Plasma::ExtenderItem *);
|
||||
void adjustSize();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,101 @@
|
||||
#ifndef WIDGETS_EXTENDERITEM_P_H
|
||||
#define WIDGETS_EXTENDERITEM_P_H
|
||||
/*
|
||||
* Copyright 2008 by Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#endif // WIDGETS_EXTENDERITEM_P_H
|
||||
#ifndef LIBS_PLASMA_EXTENDERITEM_P_H
|
||||
#define LIBS_PLASMA_EXTENDERITEM_P_H
|
||||
|
||||
#include <QPointF>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <QString>
|
||||
|
||||
class QGraphicsItem;
|
||||
class QGraphicsWidget;
|
||||
class QGraphicsLinearLayout;
|
||||
class QGraphicsView;
|
||||
class QTimer;
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
class Applet;
|
||||
class ExtenderItem;
|
||||
class Extender;
|
||||
class Icon;
|
||||
class PanelSvg;
|
||||
|
||||
class ExtenderItemPrivate
|
||||
{
|
||||
public:
|
||||
ExtenderItemPrivate(ExtenderItem *extenderItem, Extender *hostExtender);
|
||||
~ExtenderItemPrivate();
|
||||
|
||||
QRectF dragHandleRect();
|
||||
QRectF titleRect();
|
||||
bool leaveCurrentView(const QRect &rect);
|
||||
QRect screenRect();
|
||||
void toggleCollapse();
|
||||
void updateToolBox();
|
||||
void repositionToolbox();
|
||||
QPointF scenePosFromScreenPos(const QPoint &pos) const;
|
||||
Applet *hostApplet() const;
|
||||
void themeChanged();
|
||||
|
||||
ExtenderItem *q;
|
||||
|
||||
QGraphicsItem *widget;
|
||||
QGraphicsWidget *toolbox;
|
||||
QGraphicsLinearLayout *toolboxLayout;
|
||||
QGraphicsView *toplevel;
|
||||
|
||||
Extender *previousTargetExtender;
|
||||
Extender *extender;
|
||||
Applet *sourceApplet;
|
||||
|
||||
KConfigGroup config;
|
||||
|
||||
PanelSvg *dragger;
|
||||
PanelSvg *background;
|
||||
|
||||
Icon *collapseIcon;
|
||||
|
||||
QMap<QString, QAction*> actions;
|
||||
|
||||
QString title;
|
||||
QString name;
|
||||
|
||||
uint sourceAppletId;
|
||||
uint extenderItemId;
|
||||
|
||||
qreal dragLeft, dragTop, dragRight, dragBottom;
|
||||
qreal bgLeft, bgTop, bgRight, bgBottom;
|
||||
|
||||
QPointF deltaScene;
|
||||
QPoint mousePos;
|
||||
|
||||
bool mousePressed;
|
||||
bool mouseOver;
|
||||
|
||||
QTimer *expirationTimer;
|
||||
|
||||
static uint s_maxExtenderItemId;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LIB_PLASMA_EXTENDERITEM_P_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user