[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