Start of improved applet drag & drop. What works now is:
* dragging an applet creates a top level window so the applet won't appear behind the panel when dragging, as is the case now. * dragging leaves a semi transparent version of the applet at the original location, so it's clear to the user where the applet came from and where it will go when the drag is cancelled. There are still some open issues, I'm working on those... svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=806484
This commit is contained in:
parent
bb55e8eb78
commit
1172ef79e9
59
applet.cpp
59
applet.cpp
@ -700,23 +700,43 @@ QList<QAction*> Applet::contextualActions()
|
|||||||
|
|
||||||
void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||||
{
|
{
|
||||||
|
QPainter *p;
|
||||||
|
QPixmap pixmap(size().toSize());
|
||||||
|
|
||||||
|
QGraphicsView* qgv = qobject_cast<QGraphicsView*>(widget->parent());
|
||||||
|
bool ghost = (qgv && (qgv == d->ghostView));
|
||||||
|
|
||||||
|
if (ghost) {
|
||||||
|
// The applet has to be displayed semi transparent. Create a pixmap and a painter on
|
||||||
|
// that pixmap where the applet can draw on so we can draw the result transparently
|
||||||
|
// at the end.
|
||||||
|
kDebug() << "Painting ghosted...";
|
||||||
|
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
p = new QPainter();
|
||||||
|
p->begin(&pixmap);
|
||||||
|
} else {
|
||||||
|
p = painter;
|
||||||
|
}
|
||||||
|
|
||||||
if (d->shadow && d->shadow->shadowedSize() != boundingRect().size()) {
|
if (d->shadow && d->shadow->shadowedSize() != boundingRect().size()) {
|
||||||
//kDebug() << "sizes are " << d->shadow->shadowedSize() << boundingRect().size();
|
//kDebug() << "sizes are " << d->shadow->shadowedSize() << boundingRect().size();
|
||||||
d->shadow->generate();
|
d->shadow->generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->save();
|
p->save();
|
||||||
|
|
||||||
if (transform().isRotating()) {
|
if (transform().isRotating()) {
|
||||||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
painter->setRenderHint(QPainter::Antialiasing);
|
p->setRenderHint(QPainter::Antialiasing);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->background &&
|
if (d->background &&
|
||||||
formFactor() != Plasma::Vertical &&
|
formFactor() != Plasma::Vertical &&
|
||||||
formFactor() != Plasma::Horizontal) {
|
formFactor() != Plasma::Horizontal) {
|
||||||
//kDebug() << "option rect is" << option->rect;
|
//kDebug() << "option rect is" << option->rect;
|
||||||
d->background->paintPanel(painter, option->rect, QPointF(0,0));
|
d->background->paintPanel(p, option->rect, QPointF(0,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!d->failed) {
|
if (!d->failed) {
|
||||||
@ -731,17 +751,29 @@ void Applet::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
|
|||||||
Containment::StyleOption coption(*option);
|
Containment::StyleOption coption(*option);
|
||||||
coption.view = v;
|
coption.view = v;
|
||||||
|
|
||||||
paintInterface(painter, &coption, contentsRect);
|
paintInterface(p, &coption, contentsRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
p->restore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//kDebug() << "paint interface of" << (QObject*) this;
|
//kDebug() << "paint interface of" << (QObject*) this;
|
||||||
paintInterface(painter, option, contentsRect);
|
paintInterface(p, option, contentsRect);
|
||||||
|
}
|
||||||
|
p->restore();
|
||||||
|
|
||||||
|
if (ghost) {
|
||||||
|
// Lets display the pixmap that we've just drawn... transparently.
|
||||||
|
p->setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
|
p->fillRect(pixmap.rect(), QColor(0, 0, 0, (0.3 * 255)));
|
||||||
|
p->end();
|
||||||
|
|
||||||
|
delete p;
|
||||||
|
|
||||||
|
kDebug() << "draw the pixmap!";
|
||||||
|
painter->drawPixmap(0, 0, pixmap);
|
||||||
}
|
}
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
@ -800,6 +832,17 @@ void Applet::setAspectRatioMode(Plasma::AspectRatioMode mode)
|
|||||||
d->aspectRatioMode = mode;
|
d->aspectRatioMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QGraphicsView * Applet::ghostView()
|
||||||
|
{
|
||||||
|
return d->ghostView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Applet::setGhostView( QGraphicsView * view )
|
||||||
|
{
|
||||||
|
d->ghostView = view;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void Applet::registerAsDragHandle( QGraphicsItem * item )
|
void Applet::registerAsDragHandle( QGraphicsItem * item )
|
||||||
{
|
{
|
||||||
if (!item) {
|
if (!item) {
|
||||||
|
13
applet.h
13
applet.h
@ -230,6 +230,19 @@ class PLASMA_EXPORT Applet : public QGraphicsWidget
|
|||||||
*/
|
*/
|
||||||
void setAspectRatioMode(Plasma::AspectRatioMode);
|
void setAspectRatioMode(Plasma::AspectRatioMode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The view where the applet appears ghosted.
|
||||||
|
*/
|
||||||
|
QGraphicsView * ghostView();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a view which displays the applet semi transparent.
|
||||||
|
*
|
||||||
|
* @param view The view where the applet should appear 'ghosted'. Set to
|
||||||
|
* 0 to don't ghost the applet anywhere.
|
||||||
|
*/
|
||||||
|
void setGhostView(QGraphicsView * view);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all known applets.
|
* Returns a list of all known applets.
|
||||||
*
|
*
|
||||||
|
@ -85,6 +85,7 @@ public:
|
|||||||
KConfigGroup *mainConfig;
|
KConfigGroup *mainConfig;
|
||||||
Plasma::Constraints pendingConstraints;
|
Plasma::Constraints pendingConstraints;
|
||||||
Plasma::AspectRatioMode aspectRatioMode;
|
Plasma::AspectRatioMode aspectRatioMode;
|
||||||
|
QGraphicsView* ghostView;
|
||||||
ImmutabilityType immutability;
|
ImmutabilityType immutability;
|
||||||
int constraintsTimerId;
|
int constraintsTimerId;
|
||||||
bool hasConfigurationInterface : 1;
|
bool hasConfigurationInterface : 1;
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <KColorScheme>
|
#include <KColorScheme>
|
||||||
#include <KGlobalSettings>
|
#include <KGlobalSettings>
|
||||||
#include <KIcon>
|
#include <KIcon>
|
||||||
|
#include <KWindowSystem>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -57,7 +58,8 @@ AppletHandle::AppletHandle(Containment *parent, Applet *applet)
|
|||||||
m_scaleWidth(1.0),
|
m_scaleWidth(1.0),
|
||||||
m_scaleHeight(1.0),
|
m_scaleHeight(1.0),
|
||||||
m_buttonsOnRight(false),
|
m_buttonsOnRight(false),
|
||||||
m_pendingFade(false)
|
m_pendingFade(false),
|
||||||
|
m_topview(0)
|
||||||
{
|
{
|
||||||
KColorScheme colorScheme(QPalette::Active, KColorScheme::View, Theme::defaultTheme()->colorScheme());
|
KColorScheme colorScheme(QPalette::Active, KColorScheme::View, Theme::defaultTheme()->colorScheme());
|
||||||
m_gradientColor = colorScheme.background(KColorScheme::NormalBackground).color();
|
m_gradientColor = colorScheme.background(KColorScheme::NormalBackground).color();
|
||||||
@ -270,6 +272,10 @@ void AppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
setZValue(m_applet->zValue());
|
setZValue(m_applet->zValue());
|
||||||
}
|
}
|
||||||
event->accept();
|
event->accept();
|
||||||
|
//set mousePos to the position in the applet, in screencoords, so it becomes easy
|
||||||
|
//to reposition the toplevel view to the correct position.
|
||||||
|
m_mousePos = event->screenPos() - m_applet->view()->mapToGlobal(
|
||||||
|
m_applet->view()->mapFromScene(m_applet->pos()));
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -333,6 +339,12 @@ void AppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MoveButton: {
|
case MoveButton: {
|
||||||
|
if (m_topview) {
|
||||||
|
m_topview->hide();
|
||||||
|
delete m_topview;
|
||||||
|
m_topview = 0;
|
||||||
|
m_applet->setGhostView(0);
|
||||||
|
}
|
||||||
//find out if we were dropped on a panel or something
|
//find out if we were dropped on a panel or something
|
||||||
QWidget *w = QApplication::topLevelAt(event->screenPos());
|
QWidget *w = QApplication::topLevelAt(event->screenPos());
|
||||||
kDebug() << "move to widget" << w;
|
kDebug() << "move to widget" << w;
|
||||||
@ -340,14 +352,21 @@ void AppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
Plasma::View *v = qobject_cast<Plasma::View *>(w);
|
Plasma::View *v = qobject_cast<Plasma::View *>(w);
|
||||||
if (v) {
|
if (v) {
|
||||||
Containment *c = v->containment();
|
Containment *c = v->containment();
|
||||||
//XXX the dashboard view won't give us a containment. if it did, this could
|
QPoint pos = v->mapFromGlobal(event->screenPos() - m_mousePos);
|
||||||
|
|
||||||
|
//XXX the dashboard view won't give us a
|
||||||
|
//containment. if it did, this could
|
||||||
//break shit.
|
//break shit.
|
||||||
if (c && c != m_containment) {
|
if (c && c != m_containment) {
|
||||||
//we actually have been dropped on another containment, so move there
|
//we actually have been dropped on another
|
||||||
|
//containment, so move there
|
||||||
//we have a screenpos, we need a scenepos
|
//we have a screenpos, we need a scenepos
|
||||||
//FIXME how reliable is this transform?
|
//FIXME how reliable is this transform?
|
||||||
QPoint pos = v->mapFromGlobal(event->screenPos());
|
|
||||||
switchContainment(c, v->mapToScene(pos));
|
switchContainment(c, v->mapToScene(pos));
|
||||||
|
} else {
|
||||||
|
//just update the position
|
||||||
|
kDebug() << "just update the position";
|
||||||
|
m_applet->setPos(v->mapToScene(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -392,25 +411,37 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
QPointF delta = curPos-lastPos;
|
QPointF delta = curPos-lastPos;
|
||||||
|
|
||||||
if (m_pressedButton == MoveButton) {
|
if (m_pressedButton == MoveButton) {
|
||||||
setPos(pos()+delta);
|
if (!m_topview) { //create a new toplevel view
|
||||||
// test for containment change
|
m_topview = new View(m_applet->containment(), -1, 0);
|
||||||
if (!m_containment->sceneBoundingRect().contains(event->scenePos())) {
|
m_topview->setTrackContainmentChanges(false);
|
||||||
// see which containment it belongs to
|
|
||||||
Corona * corona = qobject_cast<Corona*>(scene());
|
m_topview->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint
|
||||||
if (corona) {
|
| Qt::WindowStaysOnTopHint);
|
||||||
QList<Containment*> containments = corona->containments();
|
KWindowSystem::setState(m_topview->winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||||
for (int i = 0; i < containments.size(); ++i) {
|
|
||||||
if (containments[i]->sceneBoundingRect().contains(event->scenePos())) {
|
m_topview->setWallpaperEnabled(false);
|
||||||
// add the applet to the new containment
|
|
||||||
// and take it from the old one
|
//TODO: when zoomed out, this doesn't work correctly
|
||||||
//kDebug() << "moving to other containment with position" << pos() << event->scenePos();
|
m_topview->setSceneRect(m_applet->sceneBoundingRect());
|
||||||
//kDebug() << "position before reparenting" << pos() << scenePos();
|
|
||||||
switchContainment(containments[i], scenePos());
|
// Calculate the size of the applet in screen coordinates.
|
||||||
break;
|
QPointF bottomRight = m_applet->pos();
|
||||||
}
|
bottomRight.setX(bottomRight.x() + m_applet->size().width());
|
||||||
}
|
bottomRight.setY(bottomRight.y() + m_applet->size().height());
|
||||||
}
|
|
||||||
|
QPoint tL = m_applet->view()->mapToGlobal(m_applet->view()->mapFromScene(
|
||||||
|
m_applet->pos()));
|
||||||
|
QPoint bR = m_applet->view()->mapToGlobal(m_applet->view()->mapFromScene(
|
||||||
|
bottomRight));
|
||||||
|
|
||||||
|
m_topview->resize(bR.x() - tL.x(), bR.y() - tL.y());
|
||||||
|
m_topview->show();
|
||||||
|
|
||||||
|
m_applet->setGhostView(m_applet->containment()->view());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_topview->move((event->screenPos() - m_mousePos));
|
||||||
|
|
||||||
} else if (m_pressedButton == RotateButton ||
|
} else if (m_pressedButton == RotateButton ||
|
||||||
m_pressedButton == ResizeButton) {
|
m_pressedButton == ResizeButton) {
|
||||||
if (_k_distanceForPoint(delta) <= 1.0) {
|
if (_k_distanceForPoint(delta) <= 1.0) {
|
||||||
@ -510,6 +541,7 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//pos relative to scene
|
//pos relative to scene
|
||||||
void AppletHandle::switchContainment(Containment *containment, const QPointF &pos)
|
void AppletHandle::switchContainment(Containment *containment, const QPointF &pos)
|
||||||
{
|
{
|
||||||
@ -665,7 +697,6 @@ void AppletHandle::calculateSize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_rect.adjust(-HANDLE_WIDTH, -HANDLE_WIDTH, HANDLE_WIDTH, HANDLE_WIDTH);
|
m_rect.adjust(-HANDLE_WIDTH, -HANDLE_WIDTH, HANDLE_WIDTH, HANDLE_WIDTH);
|
||||||
|
|
||||||
if (m_applet->pos().x() <= ((HANDLE_WIDTH * 2) + ICON_SIZE)) {
|
if (m_applet->pos().x() <= ((HANDLE_WIDTH * 2) + ICON_SIZE)) {
|
||||||
m_rect.adjust(0.0, 0.0, ICON_SIZE, 0.0);
|
m_rect.adjust(0.0, 0.0, ICON_SIZE, 0.0);
|
||||||
m_buttonsOnRight = true;
|
m_buttonsOnRight = true;
|
||||||
|
@ -31,6 +31,7 @@ namespace Plasma
|
|||||||
{
|
{
|
||||||
class Applet;
|
class Applet;
|
||||||
class Containment;
|
class Containment;
|
||||||
|
class View;
|
||||||
|
|
||||||
class AppletHandle : public QObject, public QGraphicsItem
|
class AppletHandle : public QObject, public QGraphicsItem
|
||||||
{
|
{
|
||||||
@ -96,6 +97,9 @@ class AppletHandle : public QObject, public QGraphicsItem
|
|||||||
QTimer *m_hoverTimer;
|
QTimer *m_hoverTimer;
|
||||||
bool m_buttonsOnRight;
|
bool m_buttonsOnRight;
|
||||||
bool m_pendingFade;
|
bool m_pendingFade;
|
||||||
|
View *m_topview;
|
||||||
|
QPoint m_mousePos; //the position of the mousecursor relative to the
|
||||||
|
//applets position.
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user