00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "applethandle_p.h"
00021
00022 #include <QApplication>
00023 #include <QBitmap>
00024 #include <QtGui/QGraphicsSceneMouseEvent>
00025 #include <QtGui/QLinearGradient>
00026 #include <QtGui/QPainter>
00027 #include <QtGui/QApplication>
00028
00029 #include <KColorScheme>
00030 #include <KGlobalSettings>
00031 #include <KIcon>
00032 #include <KWindowSystem>
00033
00034 #include <cmath>
00035 #include <math.h>
00036
00037 #include "applet.h"
00038 #include "applet_p.h"
00039 #include "containment.h"
00040 #include "corona.h"
00041 #include "paintutils.h"
00042 #include "theme.h"
00043 #include "view.h"
00044
00045 namespace Plasma
00046 {
00047
00048 qreal _k_angleForPoints(const QPointF ¢er, const QPointF &pt1, const QPointF &pt2);
00049
00050 AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos)
00051 : QObject(),
00052 QGraphicsItem(parent),
00053 m_pressedButton(NoButton),
00054 m_containment(parent),
00055 m_applet(applet),
00056 m_opacity(0.0),
00057 m_anim(FadeIn),
00058 m_animId(0),
00059 m_angle(0.0),
00060 m_tempAngle(0.0),
00061 m_scaleWidth(1.0),
00062 m_scaleHeight(1.0),
00063 m_buttonsOnRight(false),
00064 m_pendingFade(false),
00065 m_topview(0),
00066 m_entryPos(hoverPos)
00067 {
00068 KColorScheme colorScheme(QPalette::Active, KColorScheme::View, Theme::defaultTheme()->colorScheme());
00069 m_gradientColor = colorScheme.background(KColorScheme::NormalBackground).color();
00070
00071 QTransform originalMatrix = m_applet->transform();
00072 m_applet->resetTransform();
00073
00074 QRectF rect(m_applet->contentsRect());
00075 QPointF center = rect.center();
00076 originalMatrix.translate(center.x(), center.y());
00077
00078 qreal cosine = originalMatrix.m11();
00079 qreal sine = originalMatrix.m12();
00080
00081 m_angle = _k_angleForPoints(QPointF(0, 0),
00082 QPointF(1, 0),
00083 QPointF(cosine, sine));
00084
00085 m_applet->setParentItem(this);
00086
00087 rect = QRectF(m_applet->pos(), m_applet->size());
00088 center = rect.center();
00089 QTransform matrix;
00090 matrix.translate(center.x(), center.y());
00091 matrix.rotateRadians(m_angle);
00092 matrix.translate(-center.x(), -center.y());
00093 setTransform(matrix);
00094
00095 m_hoverTimer = new QTimer(this);
00096 m_hoverTimer->setSingleShot(true);
00097 m_hoverTimer->setInterval(333);
00098
00099 m_leaveTimer = new QTimer(this);
00100 m_leaveTimer->setSingleShot(true);
00101 m_leaveTimer->setInterval(500);
00102
00103 connect(m_hoverTimer, SIGNAL(timeout()), this, SLOT(fadeIn()));
00104 connect(m_leaveTimer, SIGNAL(timeout()), this, SLOT(leaveTimeout()));
00105 connect(m_applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletDestroyed()));
00106
00107 setAcceptsHoverEvents(true);
00108 m_hoverTimer->start();
00109
00110
00111
00112
00113
00114 m_zValue = m_applet->zValue();
00115 m_applet->raise();
00116 m_applet->installSceneEventFilter(this);
00117 setZValue(m_applet->zValue());
00118 }
00119
00120 AppletHandle::~AppletHandle()
00121 {
00122 if (m_applet) {
00123 m_applet->removeSceneEventFilter(this);
00124
00125 QRectF rect = QRectF(m_applet->pos(), m_applet->size());
00126 QPointF center = m_applet->mapFromParent(rect.center());
00127
00128 QPointF newPos = transform().inverted().map(m_applet->pos());
00129 m_applet->setPos(mapToParent(newPos));
00130
00131 QTransform matrix;
00132 matrix.translate(center.x(), center.y());
00133 matrix.rotateRadians(m_angle);
00134 matrix.translate(-center.x(), -center.y());
00135 m_applet->setTransform(matrix);
00136
00137 m_applet->setParentItem(m_containment);
00138
00139 m_applet->setZValue(m_zValue);
00140
00141 m_applet->update();
00142 }
00143 if (m_topview) {
00144 delete m_topview;
00145 }
00146 }
00147
00148 Applet *AppletHandle::applet() const
00149 {
00150 return m_applet;
00151 }
00152
00153 QRectF Plasma::AppletHandle::boundingRect() const
00154 {
00155 return m_totalRect;
00156 }
00157
00158 QPainterPath AppletHandle::shape() const
00159 {
00160
00161 if (m_applet) {
00162 QPainterPath path = PaintUtils::roundedRectangle(m_rect, 10);
00163 return path.united(m_applet->mapToParent(m_applet->shape()));
00164 } else {
00165 return QGraphicsItem::shape();
00166 }
00167 }
00168
00169 QPainterPath handleRect(const QRectF &rect, int radius, bool onRight)
00170 {
00171 QPainterPath path;
00172 if (onRight) {
00173
00174 path.moveTo(rect.left(), rect.top());
00175 path.lineTo(rect.right() - radius, rect.top());
00176 path.quadTo(rect.right(), rect.top(), rect.right(), rect.top() + radius);
00177 path.lineTo(rect.right(), rect.bottom() - radius);
00178 path.quadTo(rect.right(), rect.bottom(), rect.right() - radius, rect.bottom());
00179 path.lineTo(rect.left(), rect.bottom());
00180 } else {
00181
00182 path.moveTo(QPointF(rect.left(), rect.top() + radius));
00183 path.quadTo(rect.left(), rect.top(), rect.left() + radius, rect.top());
00184 path.lineTo(rect.right(), rect.top());
00185 path.lineTo(rect.right(), rect.bottom());
00186 path.lineTo(rect.left() + radius, rect.bottom());
00187 path.quadTo(rect.left(), rect.bottom(), rect.left(), rect.bottom() - radius);
00188 }
00189
00190 path.closeSubpath();
00191 return path;
00192 }
00193
00194 void AppletHandle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
00195 {
00196 Q_UNUSED(option);
00197 Q_UNUSED(widget);
00198
00199 painter->save();
00200 painter->setOpacity(m_opacity);
00201
00202 painter->save();
00203 painter->setOpacity(m_opacity * 0.8);
00204 painter->setPen(Qt::NoPen);
00205 painter->setRenderHints(QPainter::Antialiasing);
00206
00207 QPainterPath path = handleRect(m_rect, 10, m_buttonsOnRight);
00208 painter->strokePath(path, m_gradientColor);
00209 painter->fillPath(path, m_gradientColor.lighter());
00210 painter->restore();
00211
00212
00213 QPointF basePoint = m_rect.topLeft() + QPointF((HANDLE_WIDTH - ICON_SIZE) / 2, ICON_MARGIN);
00214 QPointF step = QPointF(0, ICON_SIZE + ICON_MARGIN);
00215 QPointF separator = step + QPointF(0, ICON_MARGIN);
00216
00217
00218 QPointF shiftC;
00219 QPointF shiftD;
00220 QPointF shiftR;
00221 QPointF shiftM;
00222
00223 switch(m_pressedButton)
00224 {
00225 case ConfigureButton:
00226 shiftC = QPointF(2, 2);
00227 break;
00228 case RemoveButton:
00229 shiftD = QPointF(2, 2);
00230 break;
00231 case RotateButton:
00232 shiftR = QPointF(2, 2);
00233 break;
00234 case ResizeButton:
00235 shiftM = QPointF(2, 2);
00236 break;
00237 default:
00238 break;
00239 }
00240
00241 painter->drawPixmap(basePoint + shiftM, KIcon("transform-scale").pixmap(ICON_SIZE, ICON_SIZE));
00242
00243 basePoint += step;
00244 painter->drawPixmap(basePoint + shiftR, KIcon("transform-rotate").pixmap(ICON_SIZE, ICON_SIZE));
00245
00246 if (m_applet && m_applet->hasConfigurationInterface()) {
00247 basePoint += step;
00248 painter->drawPixmap(basePoint + shiftC, KIcon("configure").pixmap(ICON_SIZE, ICON_SIZE));
00249 }
00250
00251 basePoint = m_rect.bottomLeft() + QPointF((HANDLE_WIDTH - ICON_SIZE) / 2, 0) - step;
00252 painter->drawPixmap(basePoint + shiftD, KIcon("edit-delete").pixmap(ICON_SIZE, ICON_SIZE));
00253
00254 painter->restore();
00255 }
00256
00257 AppletHandle::ButtonType AppletHandle::mapToButton(const QPointF &point) const
00258 {
00259
00260 QPointF basePoint = m_rect.topLeft() + QPointF((HANDLE_WIDTH - ICON_SIZE) / 2, ICON_MARGIN);
00261 QPointF step = QPointF(0, ICON_SIZE + ICON_MARGIN);
00262 QPointF separator = step + QPointF(0, ICON_MARGIN);
00263
00264
00265 QRectF activeArea = QRectF(basePoint, QSizeF(ICON_SIZE, ICON_SIZE));
00266
00267 if (activeArea.contains(point)) {
00268 return ResizeButton;
00269 }
00270
00271 activeArea.translate(step);
00272 if (activeArea.contains(point)) {
00273 return RotateButton;
00274 }
00275
00276 if (m_applet && m_applet->hasConfigurationInterface()) {
00277 activeArea.translate(step);
00278 if (activeArea.contains(point)) {
00279 return ConfigureButton;
00280 }
00281 }
00282
00283 activeArea.moveTop(m_rect.bottom() - activeArea.height() - ICON_MARGIN);
00284 if (activeArea.contains(point)) {
00285 return RemoveButton;
00286 }
00287
00288 return MoveButton;
00289
00290 }
00291
00292
00293 void AppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
00294 {
00295
00296 if (!m_applet) {
00297 QGraphicsItem::mousePressEvent(event);
00298 return;
00299 }
00300
00301 if (m_pendingFade) {
00302
00303 return;
00304 }
00305
00306 if (event->button() == Qt::LeftButton) {
00307 m_pressedButton = mapToButton(event->pos());
00308
00309 if (m_pressedButton != NoButton) {
00310 m_applet->raise();
00311 m_zValue = m_applet->zValue();
00312 setZValue(m_zValue);
00313 }
00314
00315 if (m_pressedButton == MoveButton) {
00316 m_pos = pos();
00317 }
00318 event->accept();
00319
00320 update();
00321
00322
00323
00324 QPoint localpos = m_containment->view()->mapFromScene(m_applet->scenePos());
00325 m_mousePos = event->screenPos() - m_containment->view()->mapToGlobal(localpos);
00326
00327 return;
00328 }
00329
00330 QGraphicsItem::mousePressEvent(event);
00331 }
00332
00333 bool AppletHandle::leaveCurrentView(const QPoint &pos) const
00334 {
00335 foreach (QWidget *widget, QApplication::topLevelWidgets()) {
00336 if (widget->geometry().contains(pos)) {
00337
00338
00339 Plasma::View *v = qobject_cast<Plasma::View *>(widget);
00340 if (v && v != m_applet->containment()->view()
00341 && v != m_topview
00342 && v->containment() != m_containment) {
00343 return true;
00344 }
00345 }
00346 }
00347 return false;
00348 }
00349
00350
00351 void AppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00352 {
00353
00354
00355 if (m_pendingFade) {
00356 startFading(FadeOut, m_entryPos);
00357 m_pendingFade = false;
00358 }
00359
00360 ButtonType releasedAtButton = mapToButton(event->pos());
00361
00362 if (m_applet && event->button() == Qt::LeftButton) {
00363 switch (m_pressedButton) {
00364 case ResizeButton:
00365 case RotateButton: {
00366 if (m_scaleWidth > 0 && m_scaleHeight > 0) {
00367 QRectF rect(m_applet->boundingRect());
00368 const qreal newWidth = rect.width() * m_scaleWidth;
00369 const qreal newHeight = rect.height() * m_scaleHeight;
00370 m_applet->resetTransform();
00371 m_applet->resize(newWidth, newHeight);
00372 scale(1.0/m_scaleWidth, 1.0/m_scaleHeight);
00373 moveBy((rect.width() - newWidth) / 2, (rect.height() - newHeight) / 2);
00374 m_scaleWidth = m_scaleHeight = 0;
00375 }
00376 QRectF rect = QRectF(m_applet->pos(), m_applet->size());
00377 QPointF center = rect.center();
00378
00379 m_angle += m_tempAngle;
00380 m_tempAngle = 0;
00381
00382 QTransform matrix;
00383 matrix.translate(center.x(), center.y());
00384 matrix.rotateRadians(m_angle);
00385 matrix.translate(-center.x(), -center.y());
00386
00387 setTransform(matrix);
00388 m_applet->update();
00389 break;
00390 }
00391 case ConfigureButton:
00392
00393 if (m_pressedButton == releasedAtButton) {
00394 m_applet->showConfigurationInterface();
00395 }
00396 break;
00397 case RemoveButton:
00398 if (m_pressedButton == releasedAtButton) {
00399 forceDisappear();
00400 m_applet->destroy();
00401 }
00402 break;
00403 case MoveButton: {
00404 if (m_topview) {
00405 m_topview->hide();
00406 delete m_topview;
00407 m_topview = 0;
00408 m_applet->d->ghostView = 0;
00409 m_applet->update();
00410 }
00411
00412
00413 if (leaveCurrentView(event->screenPos())) {
00414 startFading(FadeOut, m_entryPos);
00415 Plasma::View *v = Plasma::View::topLevelViewAt(event->screenPos());
00416 if (v && v != m_containment->view()) {
00417 Containment *c = v->containment();
00418 QPoint pos = v->mapFromGlobal(event->screenPos());
00419
00420
00421
00422 switchContainment(c, v->mapToScene(pos));
00423 }
00424 } else {
00425
00426
00427 if (!m_containment->sceneBoundingRect().contains(m_applet->scenePos())) {
00428
00429 Corona * corona = qobject_cast<Corona*>(scene());
00430 if (corona) {
00431 QList<Containment*> containments = corona->containments();
00432 for (int i = 0; i < containments.size(); ++i) {
00433 QPointF pos;
00434 QGraphicsView *v;
00435 v = containments[i]->view();
00436 if (v) {
00437 pos = v->mapToScene(v->mapFromGlobal(event->screenPos() - m_mousePos));
00438
00439 if (containments[i]->sceneBoundingRect().contains(pos)) {
00440
00441
00442
00443
00444 switchContainment(containments[i], pos);
00445 break;
00446 }
00447 }
00448 }
00449 }
00450 }
00451 }
00452 break;
00453 }
00454 default:
00455 break;
00456 }
00457 }
00458
00459 m_pressedButton = NoButton;
00460 update();
00461 }
00462
00463 qreal _k_distanceForPoint(QPointF point)
00464 {
00465 return std::sqrt(point.x()*point.x()+point.y()*point.y());
00466 }
00467
00468 qreal _k_angleForPoints(const QPointF ¢er, const QPointF &pt1, const QPointF &pt2)
00469 {
00470 QPointF vec1 = pt1 - center;
00471 QPointF vec2 = pt2 - center;
00472
00473 qreal alpha = std::atan2(vec1.y(), vec1.x());
00474 qreal beta = std::atan2(vec2.y(), vec2.x());
00475
00476 return beta - alpha;
00477 }
00478
00479 void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00480 {
00481 static const qreal snapAngle = M_PI_2 ;
00482
00483 if (!m_applet) {
00484 QGraphicsItem::mouseMoveEvent(event);
00485 return;
00486 }
00487
00488
00489 QPointF deltaScene = event->scenePos() - event->lastScenePos();
00490
00491 if (m_pressedButton == MoveButton) {
00492 m_pos += deltaScene;
00493
00494
00495 bool toTopLevel = leaveCurrentView(event->screenPos());
00496
00497 if (!toTopLevel) {
00498 setPos(m_pos);
00499 if (m_topview) {
00500
00501
00502 m_topview->hide();
00503 delete m_topview;
00504 m_topview = 0;
00505 m_applet->d->ghostView = 0;
00506 }
00507 } else {
00508
00509
00510
00511 QRect screenRect = QRect(event->screenPos() - m_mousePos,
00512 m_applet->screenRect().size());
00513
00514
00515
00516 if (!m_topview) {
00517 m_topview = new View(m_containment, -1, 0);
00518
00519 m_topview->setTrackContainmentChanges(false);
00520 m_topview->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint
00521 | Qt::WindowStaysOnTopHint);
00522 m_topview->setWallpaperEnabled(false);
00523 m_topview->resize(screenRect.size());
00524 m_topview->setSceneRect(m_applet->sceneBoundingRect());
00525 m_topview->centerOn(m_applet);
00526
00527
00528 qreal scale = screenRect.width() / m_applet->boundingRect().width();
00529 m_topview->scale(scale, scale);
00530
00531
00532
00533
00534
00535
00536 QBitmap bitmap(screenRect.size());
00537 QPainter * shapePainter = new QPainter();
00538 shapePainter->begin(&bitmap);
00539 shapePainter->fillRect(0, 0, screenRect.width(),
00540 screenRect.height(),
00541 Qt::white);
00542 shapePainter->setBrush(Qt::black);
00543 shapePainter->drawPath(m_applet->shape());
00544 shapePainter->end();
00545 delete shapePainter;
00546 m_topview->setMask(bitmap);
00547
00548 m_topview->show();
00549
00550 m_applet->d->ghostView = m_containment->view();
00551
00552
00553
00554
00555
00556
00557 }
00558
00559 m_topview->setGeometry(screenRect);
00560 }
00561
00562 } else if (m_pressedButton == RotateButton ||
00563 m_pressedButton == ResizeButton) {
00564 if (_k_distanceForPoint(deltaScene) <= 1.0) {
00565 return;
00566 }
00567
00568 QPointF pressPos = mapFromScene(event->buttonDownScenePos(Qt::LeftButton));
00569
00570 QRectF rect = QRectF(m_applet->pos(), m_applet->size());
00571 QPointF center = rect.center();
00572
00573 if (m_pressedButton == RotateButton) {
00574 m_tempAngle = _k_angleForPoints(center, pressPos, event->pos());
00575
00576 if (fabs(remainder(m_angle+m_tempAngle, snapAngle)) < 0.15) {
00577 m_tempAngle = m_tempAngle - remainder(m_angle+m_tempAngle, snapAngle);
00578 }
00579
00580 m_scaleWidth = m_scaleHeight = 1.0;
00581 } else {
00582 qreal w = m_applet->size().width();
00583 qreal h = m_applet->size().height();
00584 QSizeF min = m_applet->minimumSize();
00585 QSizeF max = m_applet->maximumSize();
00586
00587
00588
00589 if (min.isEmpty()) {
00590 min = m_applet->boundingRect().size() - m_applet->boundingRect().size();
00591 min += QSizeF(16, 16);
00592 }
00593
00594 bool ignoreAspectRatio = m_applet->aspectRatioMode() == Plasma::IgnoreAspectRatio;
00595
00596 if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
00597 ignoreAspectRatio = !ignoreAspectRatio;
00598 }
00599
00600 if (ignoreAspectRatio) {
00601
00602 qreal newScaleWidth = 0;
00603 qreal newScaleHeight = 0;
00604
00605 QPointF startDistance(pressPos - center);
00606 QPointF currentDistance(event->pos() - center);
00607 newScaleWidth = currentDistance.x() / startDistance.x();
00608 newScaleHeight = currentDistance.y() / startDistance.y();
00609
00610 if (qAbs(w - (newScaleWidth * w)) <= KGlobalSettings::dndEventDelay()) {
00611 newScaleWidth = 1.0;
00612 }
00613 if (qAbs(h - (newScaleHeight * h)) <= KGlobalSettings::dndEventDelay()) {
00614 newScaleHeight = 1.0;
00615 }
00616
00617 if (newScaleHeight * h < min.height()) {
00618 m_scaleHeight = min.height() / h;
00619 } else if (newScaleHeight * h > max.height()) {
00620 m_scaleHeight = max.height() / h;
00621 } else {
00622 m_scaleHeight = newScaleHeight;
00623 }
00624 if (newScaleWidth * w < min.width()) {
00625 m_scaleWidth = min.width() / w;
00626 } else if (newScaleWidth * w > max.width()) {
00627 m_scaleWidth = max.width() / w;
00628 } else {
00629 m_scaleWidth = newScaleWidth;
00630 }
00631 } else {
00632
00633 qreal newScale = 0;
00634
00635 newScale = _k_distanceForPoint(event->pos()-center) / _k_distanceForPoint(pressPos-center);
00636 if (qAbs(h - (newScale * h)) <= KGlobalSettings::dndEventDelay()) {
00637 newScale = 1.0;
00638 }
00639
00640 if (newScale * w < min.width() || newScale * h < min.height()) {
00641 m_scaleWidth = m_scaleHeight = qMax(min.width() / w, min.height() / h);
00642 } else if (newScale * w > max.width() && newScale * h > max.height()) {
00643 m_scaleWidth = m_scaleHeight = qMin(max.width() / w, max.height() / h);
00644 } else {
00645 m_scaleHeight = m_scaleWidth = newScale;
00646 }
00647 }
00648 }
00649
00650 QTransform matrix;
00651 matrix.translate(center.x(), center.y());
00652 matrix.rotateRadians(m_angle+m_tempAngle);
00653 matrix.scale(m_scaleWidth, m_scaleHeight);
00654 matrix.translate(-center.x(), -center.y());
00655 setTransform(matrix);
00656 } else {
00657 QGraphicsItem::mouseMoveEvent(event);
00658 }
00659 }
00660
00661
00662
00663 void AppletHandle::switchContainment(Containment *containment, const QPointF &pos)
00664 {
00665 if (containment->containmentType() != Containment::PanelContainment) {
00666
00667 kDebug() << "desktop";
00668 m_containment = containment;
00669 }
00670
00671 Applet *applet = m_applet;
00672 m_applet = 0;
00673 applet->removeSceneEventFilter(this);
00674 forceDisappear();
00675 applet->disconnect(this);
00676 applet->setZValue(m_zValue);
00677 containment->addApplet(applet, containment->mapFromScene(pos));
00678 update();
00679 }
00680
00681 QVariant AppletHandle::itemChange(GraphicsItemChange change, const QVariant &value)
00682 {
00683 if (change == ItemPositionHasChanged && m_applet) {
00684 m_applet->updateConstraints(Plasma::LocationConstraint);
00685 }
00686 return QGraphicsItem::itemChange(change, value);
00687 }
00688
00689 void AppletHandle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00690 {
00691 Q_UNUSED(event);
00692
00693
00694
00695 m_leaveTimer->stop();
00696
00697 m_hoverTimer->start();
00698 }
00699
00700 void AppletHandle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
00701 {
00702 Q_UNUSED(event);
00703 m_leaveTimer->stop();
00704 }
00705
00706 void AppletHandle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00707 {
00708 Q_UNUSED(event);
00709 m_hoverTimer->stop();
00710
00711 if (m_pressedButton != NoButton) {
00712 m_pendingFade = true;
00713 } else {
00714
00715 m_leaveTimer->start();
00716 }
00717 }
00718
00719 bool AppletHandle::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
00720 {
00721 if (watched == m_applet && event->type() == QEvent::GraphicsSceneHoverLeave) {
00722 hoverLeaveEvent(static_cast<QGraphicsSceneHoverEvent*>(event));
00723 }
00724
00725 return false;
00726 }
00727
00728 void AppletHandle::fadeAnimation(qreal progress)
00729 {
00730 qreal endOpacity = (m_anim == FadeIn) ? 1.0 : 0.0;
00731 m_opacity += (endOpacity - m_opacity) * progress;
00732
00733 if (progress >= 1.0 && m_anim == FadeOut) {
00734 emit disappearDone(this);
00735 }
00736
00737 update();
00738 }
00739
00740 void AppletHandle::fadeIn()
00741 {
00742 startFading(FadeIn, m_entryPos);
00743 }
00744
00745 void AppletHandle::leaveTimeout()
00746 {
00747 startFading(FadeOut, m_entryPos);
00748 }
00749
00750 void AppletHandle::appletDestroyed()
00751 {
00752 m_applet = 0;
00753 deleteLater();
00754 }
00755
00756 void AppletHandle::appletResized()
00757 {
00758 prepareGeometryChange();
00759 calculateSize();
00760 update();
00761 }
00762
00763 void AppletHandle::startFading(FadeType anim, const QPointF &hoverPos)
00764 {
00765 if (m_animId != 0) {
00766 Animator::self()->stopCustomAnimation(m_animId);
00767 }
00768
00769 m_hoverTimer->stop();
00770 m_leaveTimer->stop();
00771
00772 m_entryPos = hoverPos;
00773 qreal time = 250;
00774
00775 if (!m_applet || (anim == FadeOut && m_hoverTimer->isActive())) {
00776
00777 fadeAnimation(1.0);
00778 return;
00779 }
00780
00781 if (anim == FadeIn) {
00782
00783 prepareGeometryChange();
00784 bool wasOnRight = m_buttonsOnRight;
00785 m_buttonsOnRight = m_entryPos.x() > (m_applet->size().width() / 2);
00786 calculateSize();
00787 QPolygonF region = mapToParent(m_rect).intersected(parentWidget()->boundingRect());
00788
00789 if (region != mapToParent(m_rect)) {
00790
00791
00792 m_buttonsOnRight = !m_buttonsOnRight;
00793 calculateSize();
00794 QPolygonF region2 = mapToParent(m_rect).intersected(parentWidget()->boundingRect());
00795 if (region2 != mapToParent(m_rect)) {
00796
00797 QRectF f1 = region.boundingRect();
00798 QRectF f2 = region2.boundingRect();
00799
00800 if ((f2.width() * f2.height()) < (f1.width() * f1.height())) {
00801
00802 m_buttonsOnRight = !m_buttonsOnRight;
00803 calculateSize();
00804 }
00805 }
00806 }
00807
00808 if (wasOnRight != m_buttonsOnRight && m_anim == FadeIn && anim == FadeIn && m_opacity <= 1) {
00809 m_opacity = 0.0;
00810 }
00811
00812 time *= 1.0 - m_opacity;
00813 } else {
00814 time *= m_opacity;
00815 }
00816
00817 m_anim = anim;
00818 m_animId = Animator::self()->customAnimation(40, (int)time, Animator::EaseInOutCurve, this, "fadeAnimation");
00819 }
00820
00821
00822 void AppletHandle::forceDisappear()
00823 {
00824 setAcceptsHoverEvents(false);
00825 startFading(FadeOut, m_entryPos);
00826 }
00827
00828 void AppletHandle::calculateSize()
00829 {
00830 int requiredHeight = ICON_MARGIN +
00831 (ICON_SIZE + ICON_MARGIN) * 4 +
00832 ICON_MARGIN;
00833
00834 if (m_applet->hasConfigurationInterface()) {
00835 requiredHeight += (ICON_SIZE + ICON_MARGIN);
00836 }
00837
00838 int top = m_applet->contentsRect().top();
00839
00840 if (requiredHeight > m_applet->contentsRect().height()) {
00841 top += (m_applet->contentsRect().height() - requiredHeight) / 2.0;
00842 } else {
00843 requiredHeight = m_applet->contentsRect().height();
00844 }
00845
00846 if (m_buttonsOnRight) {
00847
00848 m_rect = QRectF(m_applet->size().width(), top, HANDLE_WIDTH, requiredHeight);
00849 } else {
00850
00851 m_rect = QRectF(-HANDLE_WIDTH, top, HANDLE_WIDTH, requiredHeight);
00852 }
00853
00854 m_rect = m_applet->mapToParent(m_rect).boundingRect();
00855 m_totalRect = m_rect.united(m_applet->geometry());
00856 }
00857
00858 }
00859
00860 #include "applethandle_p.moc"