[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-panel-devel
Subject: Re: [REVIEW] Improved applet drag&drop support
From: Rob Scheepmaker <r.scheepmaker () student ! utwente ! nl>
Date: 2008-05-10 17:33:33
Message-ID: 20080510173333.GC18519 () student ! utwente ! nl
[Download RAW message or body]
On Sat, May 10, 2008 at 07:19:20PM +0200, Rob Scheepmaker wrote:
> Hi,
>
> I've improved my drag&drop patch some more. This patch tries to improve
Maybe I should include the patch... :s
Rob Scheepmaker
(pinda)
["plasmadnd.diff" (text/x-diff)]
Index: applet_p.h
===================================================================
--- applet_p.h (revision 806205)
+++ applet_p.h (working copy)
@@ -85,6 +85,7 @@
KConfigGroup *mainConfig;
Plasma::Constraints pendingConstraints;
Plasma::AspectRatioMode aspectRatioMode;
+ QGraphicsView* ghostView;
ImmutabilityType immutability;
int constraintsTimerId;
bool hasConfigurationInterface : 1;
Index: applet.h
===================================================================
--- applet.h (revision 806205)
+++ applet.h (working copy)
@@ -231,6 +231,19 @@
void setAspectRatioMode(Plasma::AspectRatioMode);
/**
+ * @return The view wher e 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.
*
* @param category Only applets matchin this category will be returned.
Index: applet.cpp
===================================================================
--- applet.cpp (revision 806205)
+++ applet.cpp (working copy)
@@ -700,23 +700,43 @@
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()) {
//kDebug() << "sizes are " << d->shadow->shadowedSize() << \
boundingRect().size(); d->shadow->generate();
}
- painter->save();
+ p->save();
if (transform().isRotating()) {
- painter->setRenderHint(QPainter::SmoothPixmapTransform);
- painter->setRenderHint(QPainter::Antialiasing);
+ p->setRenderHint(QPainter::SmoothPixmapTransform);
+ p->setRenderHint(QPainter::Antialiasing);
}
if (d->background &&
formFactor() != Plasma::Vertical &&
formFactor() != Plasma::Horizontal) {
//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) {
@@ -731,17 +751,29 @@
Containment::StyleOption coption(*option);
coption.view = v;
- paintInterface(painter, &coption, contentsRect);
+ paintInterface(p, &coption, contentsRect);
}
- painter->restore();
+ p->restore();
return;
}
//kDebug() << "paint interface of" << (QObject*) this;
- paintInterface(painter, option, contentsRect);
+ paintInterface(p, option, contentsRect);
}
- painter->restore();
+ 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);
+ }
}
void Applet::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem \
*option, @@ -800,6 +832,17 @@
d->aspectRatioMode = mode;
}
+QGraphicsView * Applet::ghostView()
+{
+ return d->ghostView;
+}
+
+void Applet::setGhostView( QGraphicsView * view )
+{
+ d->ghostView = view;
+ update();
+}
+
void Applet::registerAsDragHandle( QGraphicsItem * item )
{
if (!item) {
Index: applethandle_p.h
===================================================================
--- applethandle_p.h (revision 806205)
+++ applethandle_p.h (working copy)
@@ -31,6 +31,7 @@
{
class Applet;
class Containment;
+class View;
class AppletHandle : public QObject, public QGraphicsItem
{
@@ -96,6 +97,9 @@
QTimer *m_hoverTimer;
bool m_buttonsOnRight;
bool m_pendingFade;
+ View *m_topview;
+ QPoint m_mousePos; //the position of the mousecursor relative to the
+ //applets position.
};
}
Index: applethandle.cpp
===================================================================
--- applethandle.cpp (revision 806205)
+++ applethandle.cpp (working copy)
@@ -28,6 +28,7 @@
#include <KColorScheme>
#include <KGlobalSettings>
#include <KIcon>
+#include <KWindowSystem>
#include <cmath>
#include <math.h>
@@ -57,7 +58,8 @@
m_scaleWidth(1.0),
m_scaleHeight(1.0),
m_buttonsOnRight(false),
- m_pendingFade(false)
+ m_pendingFade(false),
+ m_topview(0)
{
KColorScheme colorScheme(QPalette::Active, KColorScheme::View, \
Theme::defaultTheme()->colorScheme());
m_gradientColor = \
colorScheme.background(KColorScheme::NormalBackground).color(); @@ -270,6 +272,10 @@
setZValue(m_applet->zValue());
}
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();
return;
}
@@ -333,6 +339,12 @@
}
break;
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
QWidget *w = QApplication::topLevelAt(event->screenPos());
kDebug() << "move to widget" << w;
@@ -340,14 +352,21 @@
Plasma::View *v = qobject_cast<Plasma::View *>(w);
if (v) {
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.
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
//FIXME how reliable is this transform?
- QPoint pos = v->mapFromGlobal(event->screenPos());
switchContainment(c, v->mapToScene(pos));
+ } else {
+ //just update the position
+ kDebug() << "just update the position";
+ m_applet->setPos(v->mapToScene(pos));
}
}
}
@@ -392,25 +411,38 @@
QPointF delta = curPos-lastPos;
if (m_pressedButton == MoveButton) {
- setPos(pos()+delta);
- // test for containment change
- if (!m_containment->sceneBoundingRect().contains(event->scenePos())) {
- // see which containment it belongs to
- Corona * corona = qobject_cast<Corona*>(scene());
- if (corona) {
- QList<Containment*> containments = corona->containments();
- for (int i = 0; i < containments.size(); ++i) {
- if \
(containments[i]->sceneBoundingRect().contains(event->scenePos())) {
- // add the applet to the new containment
- // and take it from the old one
- //kDebug() << "moving to other containment with position" << \
pos() << event->scenePos();
- //kDebug() << "position before reparenting" << pos() << \
scenePos();
- switchContainment(containments[i], scenePos());
- break;
- }
- }
- }
+ if (!m_topview) { //create a new toplevel view
+ m_topview = new View(m_applet->containment(), -1, 0);
+ m_topview->setTrackContainmentChanges(false);
+ //TODO: is there a window flag to make this not appear in the task \
manager? + m_topview->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint
+ | Qt::WindowStaysOnTopHint);
+
+ m_topview->setWallpaperEnabled(false);
+
+ //TODO: when zoomed out, this doesn't work correctly
+ m_topview->setSceneRect(m_applet->sceneBoundingRect());
+
+ // Calculate the size of the applet in screen coordinates.
+ 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());
+
+ kDebug() << "setGhostView: " << m_applet->containment()->view();
}
+
+ m_topview->move((event->screenPos() - m_mousePos));
+
} else if (m_pressedButton == RotateButton ||
m_pressedButton == ResizeButton) {
if (_k_distanceForPoint(delta) <= 1.0) {
@@ -510,6 +542,7 @@
}
}
+
//pos relative to scene
void AppletHandle::switchContainment(Containment *containment, const QPointF &pos)
{
@@ -665,7 +698,6 @@
}
m_rect.adjust(-HANDLE_WIDTH, -HANDLE_WIDTH, HANDLE_WIDTH, HANDLE_WIDTH);
-
if (m_applet->pos().x() <= ((HANDLE_WIDTH * 2) + ICON_SIZE)) {
m_rect.adjust(0.0, 0.0, ICON_SIZE, 0.0);
m_buttonsOnRight = true;
_______________________________________________
Panel-devel mailing list
Panel-devel@kde.org
https://mail.kde.org/mailman/listinfo/panel-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic