• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Plasma

panelappletoverlay.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2008 Aaron Seigo <aseigo@kde.org>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as
00006  *   published by the Free Software Foundation; either version 2,
00007  *   or (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details
00013  *
00014  *   You should have received a copy of the GNU Library General Public
00015  *   License along with this program; if not, write to the
00016  *   Free Software Foundation, Inc.,
00017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018  */
00019 
00020 #include "panelappletoverlay.h"
00021 
00022 #include <QGraphicsLinearLayout>
00023 #include <QPainter>
00024 #include <QTimer>
00025 
00026 #include <KGlobalSettings>
00027 #include <KIcon>
00028 
00029 #include <plasma/applet.h>
00030 #include <plasma/containment.h>
00031 #include <plasma/paintutils.h>
00032 #include <plasma/theme.h>
00033 
00034 class AppletMoveSpacer : public QGraphicsWidget
00035 {
00036 public:
00037     AppletMoveSpacer(Plasma::Applet *applet)
00038         : QGraphicsWidget(applet->containment()),
00039           m_applet(applet)
00040     {
00041     }
00042 
00043 protected:
00044     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget * widget = 0)
00045     {
00046         Q_UNUSED(option)
00047         Q_UNUSED(widget)
00048 
00049         /*
00050            results in odd painting corruption
00051         if (collidesWithItem(m_applet, Qt::IntersectsItemBoundingRect)) {
00052             painter->fillRect(contentsRect(), Qt::transparent);
00053             return;
00054         }
00055         */
00056 
00057         //TODO: make this a pretty gradient?
00058         painter->setRenderHint(QPainter::Antialiasing);
00059         QPainterPath p = Plasma::PaintUtils::roundedRectangle(contentsRect().adjusted(1, 1, -2, -2), 4);
00060         QColor c = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00061         c.setAlphaF(0.3);
00062 
00063         painter->fillPath(p, c);
00064     }
00065 
00066 private:
00067     QGraphicsWidget *m_applet;
00068 };
00069 
00070 PanelAppletOverlay::PanelAppletOverlay(Plasma::Applet *applet, QWidget *parent)
00071     : QWidget(parent),
00072       m_applet(applet),
00073       m_spacer(0),
00074       m_layout(static_cast<QGraphicsLinearLayout*>(applet->containment()->layout())), // ++assumptions;
00075       m_index(0),
00076       m_clickDrag(false)
00077 {
00078     int i = 0;
00079     for (; i < m_layout->count(); ++i) {
00080         QGraphicsWidget *w = dynamic_cast<QGraphicsWidget*>(m_layout->itemAt(i));
00081         if (w == m_applet) {
00082             m_index = i;
00083             break;
00084         }
00085     }
00086 
00087     syncOrientation();
00088     syncGeometry();
00089 
00090     connect(m_applet, SIGNAL(destroyed(QObject*)), this, SLOT(deleteLater()));
00091     connect(m_applet, SIGNAL(geometryChanged()), this, SLOT(delaySyncGeometry()));
00092 }
00093 
00094 PanelAppletOverlay::~PanelAppletOverlay()
00095 {
00096     if (m_spacer) {
00097         m_layout->removeItem(m_spacer);
00098         m_spacer->deleteLater();
00099         m_spacer = 0;
00100     }
00101 }
00102 
00103 void PanelAppletOverlay::paintEvent(QPaintEvent *event)
00104 {
00105     Q_UNUSED(event)
00106 
00107     QStyleOption op;
00108     op.initFrom(this);
00109 
00110     bool hovered = op.state & QStyle::State_MouseOver;
00111     bool mover = mouseGrabber() == this;
00112     if (!hovered || mover) {
00113         return;
00114     }
00115 
00116     QPainter p(this);
00117     KIcon icon("transform-move");
00118     int iconSize;
00119     QRect iconRect;
00120 
00121     if (m_orientation == Qt::Horizontal) {
00122         iconSize = qMin(qMin(height(), int(m_applet->size().width())), 64);
00123         iconRect = QRect(rect().center() - QPoint(iconSize / 2, iconSize / 2), QSize(iconSize, iconSize));
00124     } else {
00125         iconSize = qMin(qMin(width(), int(m_applet->size().height())), 64);
00126         iconRect = QRect(rect().center() - QPoint(iconSize / 2, iconSize / 2), QSize(iconSize, iconSize));
00127     }
00128 
00129     p.drawPixmap(iconRect, icon.pixmap(iconSize, iconSize));
00130 }
00131 
00132 void PanelAppletOverlay::mousePressEvent(QMouseEvent *event)
00133 {
00134     Q_UNUSED(event)
00135 
00136     //kDebug();
00137     if (m_clickDrag) {
00138         setMouseTracking(false);
00139         m_clickDrag = false;
00140         m_origin = QPoint();
00141         return;
00142     }
00143 
00144     m_clickDrag = false;
00145     if (!m_spacer) {
00146         m_spacer = new AppletMoveSpacer(m_applet);
00147     } else {
00148         m_layout->removeItem(m_spacer);
00149     }
00150 
00151     m_origin = mapToParent(event->pos());
00152     m_spacer->setMinimumSize(m_applet->geometry().size());
00153     m_spacer->setMaximumSize(m_applet->geometry().size());
00154     m_layout->removeItem(m_applet);
00155     m_layout->insertItem(m_index, m_spacer);
00156     m_applet->setZValue(m_applet->zValue() + 1);
00157 
00158     if (m_orientation == Qt::Horizontal) {
00159         m_offset = geometry().x() - m_origin.x();
00160     } else {
00161         m_offset = geometry().y() - m_origin.y();
00162     }
00163     grabMouse();
00164 }
00165 
00166 void PanelAppletOverlay::mouseMoveEvent(QMouseEvent *event)
00167 {
00168     Q_UNUSED(event)
00169 
00170     QPoint p = mapToParent(event->pos());
00171     QRect g = geometry();
00172 
00173     if (m_orientation == Qt::Horizontal) {
00174         g.moveLeft(p.x() + m_offset);
00175     } else {
00176         g.moveTop(p.y() + m_offset);
00177     }
00178 
00179     m_applet->setGeometry(g);
00180 
00181     // swap items if we pass completely over the next/previou item or cross
00182     // more than halfway across it, whichever comes first
00183     if (m_orientation == Qt::Horizontal) {
00184         if (m_prevGeom.isValid() && g.left() <= m_prevGeom.left()) {
00185             swapWithPrevious();
00186         } else if (m_nextGeom.isValid() && g.right() >= m_nextGeom.right()) {
00187             swapWithNext();
00188         }
00189     } else if (m_prevGeom.isValid() && g.top() <= m_prevGeom.top()) {
00190         swapWithPrevious();
00191     } else if (m_nextGeom.isValid() && g.bottom() >= m_nextGeom.bottom()) {
00192         swapWithNext();
00193     }
00194 
00195     //kDebug() << "=================================";
00196 }
00197 
00198 void PanelAppletOverlay::mouseReleaseEvent(QMouseEvent *event)
00199 {
00200     Q_UNUSED(event)
00201 
00202     if (!m_origin.isNull()) {
00203         //kDebug() << m_clickDrag << m_origin << mapToParent(event->pos());
00204         if (m_orientation == Qt::Horizontal) {
00205             m_clickDrag = abs(mapToParent(event->pos()).x() - m_origin.x()) < KGlobalSettings::dndEventDelay();
00206         } else {
00207             m_clickDrag = abs(mapToParent(event->pos()).y() - m_origin.y()) < KGlobalSettings::dndEventDelay();
00208         }
00209 
00210         if (m_clickDrag) {
00211             //kDebug() << "click dragging." << this << mouseGrabber();
00212             setMouseTracking(true);
00213             event->setAccepted(false);
00214             return;
00215         }
00216     }
00217 
00218     //kDebug();
00219     m_layout->removeItem(m_spacer);
00220     m_spacer->deleteLater();
00221     m_spacer = 0;
00222     m_layout->insertItem(m_index, m_applet);
00223     m_applet->setZValue(m_applet->zValue() - 1);
00224     releaseMouse();
00225 }
00226 
00227 void PanelAppletOverlay::enterEvent(QEvent *event)
00228 {
00229     Q_UNUSED(event)
00230     update();
00231 }
00232 
00233 void PanelAppletOverlay::leaveEvent(QEvent *event)
00234 {
00235     Q_UNUSED(event)
00236     update();
00237 }
00238 
00239 void PanelAppletOverlay::swapWithPrevious()
00240 {
00241     //kDebug();
00242     --m_index;
00243 
00244     if (m_index > 0) {
00245         m_prevGeom = m_layout->itemAt(m_index - 1)->geometry();
00246     } else {
00247         m_prevGeom = QRectF();
00248     }
00249 
00250     m_nextGeom = m_layout->itemAt(m_index + 1)->geometry();
00251     m_layout->removeItem(m_spacer);
00252     m_layout->insertItem(m_index, m_spacer);
00253 }
00254 
00255 void PanelAppletOverlay::swapWithNext()
00256 {
00257     //kDebug();
00258     ++m_index;
00259 
00260     if (m_index < m_layout->count() - 1) {
00261         m_nextGeom = m_layout->itemAt(m_index + 1)->geometry();
00262     } else {
00263         m_nextGeom = QRectF();
00264     }
00265 
00266     m_prevGeom = m_layout->itemAt(m_index - 1)->geometry();
00267     m_layout->removeItem(m_spacer);
00268     m_layout->insertItem(m_index, m_spacer);
00269 }
00270 
00271 void PanelAppletOverlay::delaySyncGeometry()
00272 {
00273     // we need to do this because it gets called in a round-about-way
00274     // from our own mouseMoveEvent. if we call syncGeometry directly,
00275     // we end up with a maze of duplicated and confused mouseMoveEvents
00276     // of which only half are real (the other half being caused by the
00277     // immediate call to syncGeometry!)
00278     QTimer::singleShot(0, this, SLOT(syncGeometry()));
00279 }
00280 
00281 void PanelAppletOverlay::syncGeometry()
00282 {
00283     //kDebug();
00284     setGeometry(m_applet->geometry().toRect());
00285 
00286     if (m_index > 0) {
00287         m_prevGeom = m_layout->itemAt(m_index - 1)->geometry();
00288     } else {
00289         m_prevGeom = QRectF();
00290     }
00291 
00292     if (m_index < m_layout->count() - 1) {
00293         m_nextGeom = m_layout->itemAt(m_index + 1)->geometry();
00294     } else {
00295         m_nextGeom = QRectF();
00296     }
00297 }
00298 
00299 void PanelAppletOverlay::syncOrientation()
00300 {
00301     m_orientation = m_applet->formFactor() == Plasma::Horizontal ? Qt::Horizontal : Qt::Vertical;
00302 }
00303 
00304 #include "panelappletoverlay.moc"
00305 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal