Plasma
panelappletoverlay.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00051
00052
00053
00054
00055
00056
00057
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())),
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
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
00182
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
00196 }
00197
00198 void PanelAppletOverlay::mouseReleaseEvent(QMouseEvent *event)
00199 {
00200 Q_UNUSED(event)
00201
00202 if (!m_origin.isNull()) {
00203
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
00212 setMouseTracking(true);
00213 event->setAccepted(false);
00214 return;
00215 }
00216 }
00217
00218
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
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
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
00274
00275
00276
00277
00278 QTimer::singleShot(0, this, SLOT(syncGeometry()));
00279 }
00280
00281 void PanelAppletOverlay::syncGeometry()
00282 {
00283
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