00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "pager.h"
00021
00022 #include <math.h>
00023
00024 #include <QApplication>
00025 #include <QPainter>
00026 #include <QStyleOptionGraphicsItem>
00027 #include <QFont>
00028 #include <QGraphicsSceneHoverEvent>
00029 #include <QDesktopWidget>
00030 #include <QTimer>
00031 #include <QX11Info>
00032
00033 #include <KDialog>
00034 #include <KColorScheme>
00035 #include <KConfigDialog>
00036 #include <KGlobalSettings>
00037 #include <KSharedConfig>
00038 #include <KWindowSystem>
00039 #include <NETRootInfo>
00040 #include <KToolInvocation>
00041 #include <kmanagerselection.h>
00042
00043 #include <plasma/svg.h>
00044 #include <plasma/panelsvg.h>
00045 #include <plasma/theme.h>
00046 #include <plasma/animator.h>
00047
00048 const int WINDOW_UPDATE_DELAY = 500;
00049 const int DRAG_SWITCH_DELAY = 1000;
00050
00051 Pager::Pager(QObject *parent, const QVariantList &args)
00052 : Plasma::Applet(parent, args),
00053 m_dialog(0),
00054 m_displayedText(Number),
00055 m_showWindowIcons(false),
00056 m_showOwnBackground(false),
00057 m_rows(2),
00058 m_columns(0),
00059 m_hoverIndex(-1),
00060 m_dragId(0),
00061 m_dirtyDesktop(-1),
00062 m_dragStartDesktop(-1),
00063 m_dragHighlightedDesktop(-1),
00064 m_dragSwitchDesktop(-1)
00065 {
00066 setAcceptsHoverEvents(true);
00067 setAcceptDrops(true);
00068 setHasConfigurationInterface(true);
00069
00070 m_background = new Plasma::PanelSvg(this);
00071 m_background->setImagePath("widgets/pager");
00072 m_background->setCacheAllRenderedPanels(true);
00073
00074
00075 m_desktopCount = KWindowSystem::numberOfDesktops();
00076 m_size = QSizeF(176, 88);
00077 resize(m_size);
00078 }
00079
00080 void Pager::init()
00081 {
00082 createMenu();
00083
00084 KConfigGroup cg = config();
00085 m_displayedText = (DisplayedText)cg.readEntry("displayedText", (int)m_displayedText);
00086 m_showWindowIcons = cg.readEntry("showWindowIcons", m_showWindowIcons);
00087 m_rows = globalConfig().readEntry("rows", m_rows);
00088
00089 if (m_rows < 1) {
00090 m_rows = 1;
00091 } else if (m_rows > m_desktopCount) {
00092 m_rows = m_desktopCount;
00093 }
00094
00095 m_timer = new QTimer(this);
00096 m_timer->setSingleShot(true);
00097 connect(m_timer, SIGNAL(timeout()), this, SLOT(recalculateWindowRects()));
00098
00099 m_dragSwitchTimer = new QTimer(this);
00100 m_dragSwitchTimer->setSingleShot(true);
00101 connect(m_dragSwitchTimer, SIGNAL(timeout()), this, SLOT(dragSwitch()));
00102
00103 connect(KWindowSystem::self(), SIGNAL(currentDesktopChanged(int)), this, SLOT(currentDesktopChanged(int)));
00104 connect(KWindowSystem::self(), SIGNAL(windowAdded(WId)), this, SLOT(windowAdded(WId)));
00105 connect(KWindowSystem::self(), SIGNAL(windowRemoved(WId)), this, SLOT(windowRemoved(WId)));
00106 connect(KWindowSystem::self(), SIGNAL(activeWindowChanged(WId)), this, SLOT(activeWindowChanged(WId)));
00107 connect(KWindowSystem::self(), SIGNAL(numberOfDesktopsChanged(int)), this, SLOT(numberOfDesktopsChanged(int)));
00108 connect(KWindowSystem::self(), SIGNAL(desktopNamesChanged()), this, SLOT(desktopNamesChanged()));
00109 connect(KWindowSystem::self(), SIGNAL(stackingOrderChanged()), this, SLOT(stackingOrderChanged()));
00110 connect(KWindowSystem::self(), SIGNAL(windowChanged(WId,unsigned int)), this, SLOT(windowChanged(WId,unsigned int)));
00111 connect(KWindowSystem::self(), SIGNAL(showingDesktopChanged(bool)), this, SLOT(showingDesktopChanged(bool)));
00112 connect(QApplication::desktop(), SIGNAL(resized(int)), SLOT(desktopsSizeChanged()));
00113
00114 m_desktopLayoutOwner = new KSelectionOwner( QString( "_NET_DESKTOP_LAYOUT_S%1" )
00115 .arg( QX11Info::appScreen()).toLatin1().constData(), QX11Info::appScreen(), this );
00116 connect( m_desktopLayoutOwner, SIGNAL( lostOwnership()), SLOT( lostDesktopLayoutOwner()));
00117 if ( !m_desktopLayoutOwner->claim( false ))
00118 lostDesktopLayoutOwner();
00119
00120 recalculateGeometry();
00121
00122 m_currentDesktop = KWindowSystem::currentDesktop();
00123 }
00124
00125 void Pager::constraintsEvent(Plasma::Constraints constraints)
00126 {
00127 if (constraints & Plasma::SizeConstraint) {
00128 recalculateGeometry();
00129 recalculateWindowRects();
00130 if (m_background->hasElementPrefix(QString())) {
00131 m_background->setElementPrefix(QString());
00132 m_background->resizePanel(size());
00133 }
00134 }
00135 if (constraints & Plasma::FormFactorConstraint) {
00136 if (formFactor() == Plasma::Horizontal) {
00137 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
00138 } else if (formFactor() == Plasma::Vertical) {
00139 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00140 } else {
00141 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
00142 }
00143 }
00144 }
00145
00146 void Pager::createMenu()
00147 {
00148 QAction* configureDesktop = new QAction(SmallIcon("configure"),i18n("&Configure Desktops..."), this);
00149 m_actions.append(configureDesktop);
00150 connect(configureDesktop, SIGNAL(triggered(bool)), this , SLOT(slotConfigureDesktop()));
00151 }
00152
00153 QList<QAction*> Pager::contextualActions()
00154 {
00155 return m_actions;
00156 }
00157
00158 void Pager::slotConfigureDesktop()
00159 {
00160 QString error;
00161 KToolInvocation::startServiceByDesktopName("desktop", QStringList(), &error);
00162 }
00163
00164 void Pager::createConfigurationInterface(KConfigDialog *parent)
00165 {
00166 QWidget *widget = new QWidget();
00167 ui.setupUi(widget);
00168 parent->setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
00169 parent->addPage(widget, parent->windowTitle(), icon());
00170 connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
00171 connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
00172
00173 ui.displayedTextComboBox->clear();
00174 ui.displayedTextComboBox->addItem(i18n("Desktop Number"));
00175 ui.displayedTextComboBox->addItem(i18n("Desktop Name"));
00176 ui.displayedTextComboBox->addItem(i18n("None"));
00177 ui.displayedTextComboBox->setCurrentIndex((int)m_displayedText);
00178 ui.displayedTextComboBox->setToolTip(i18n("What will appear when the mouse is over a desktop miniature"));
00179 ui.showWindowIconsCheckBox->setChecked(m_showWindowIcons);
00180 ui.spinRows->setValue(m_rows);
00181 ui.spinRows->setMaximum(m_desktopCount);
00182 }
00183
00184 bool Pager::posOnDesktopRect(const QRectF& r, const QPointF& pos)
00185 {
00186 qreal leftMargin;
00187 qreal topMargin;
00188 qreal rightMargin;
00189 qreal bottomMargin;
00190
00191 if (m_showOwnBackground && m_background) {
00192 m_background->setElementPrefix(QString());
00193 m_background->getMargins(leftMargin, topMargin, rightMargin, bottomMargin);
00194
00195 if (r.left() > leftMargin) {
00196 leftMargin = 0;
00197 }
00198 if (r.top() > topMargin) {
00199 leftMargin = 0;
00200 }
00201 if (geometry().width() - r.right() < rightMargin) {
00202 leftMargin = 0;
00203 }
00204 if (geometry().bottom() - r.bottom() < bottomMargin) {
00205 leftMargin = 0;
00206 }
00207
00208 return r.adjusted(-leftMargin, -topMargin, rightMargin, bottomMargin).contains(pos);
00209 } else {
00210 return r.contains(pos);
00211 }
00212 }
00213
00214 void Pager::recalculateGeometry()
00215 {
00216 if (!m_rects.isEmpty() && geometry().size() == m_size) {
00217
00218 return;
00219 }
00220
00221 int padding = 2;
00222 int textMargin = 3;
00223 int columns = m_desktopCount / m_rows + m_desktopCount % m_rows;
00224
00225 qreal leftMargin;
00226 qreal topMargin;
00227 qreal rightMargin;
00228 qreal bottomMargin;
00229
00230 if (formFactor() == Plasma::Vertical || formFactor() == Plasma::Horizontal) {
00231 m_background->setElementPrefix(QString());
00232 m_background->getMargins(leftMargin, topMargin, rightMargin, bottomMargin);
00233
00234 qreal ratio = (qreal)QApplication::desktop()->width() / (qreal)QApplication::desktop()->height();
00235
00236
00237 if (geometry().width() - leftMargin - rightMargin < KIconLoader::SizeSmall*ratio * columns + padding*(columns-1) ||
00238 geometry().height() - topMargin - bottomMargin < KIconLoader::SizeSmall * m_rows + padding*(m_rows-1)) {
00239 m_showOwnBackground = false;
00240 leftMargin = topMargin = rightMargin = bottomMargin = padding = textMargin = 0;
00241 } else {
00242 m_showOwnBackground = true;
00243 }
00244 } else {
00245 getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
00246 }
00247
00248 qreal itemHeight;
00249 qreal itemWidth;
00250
00251 if (formFactor() == Plasma::Vertical) {
00252 itemWidth = (geometry().width() - leftMargin - rightMargin - padding * (columns - 1)) / columns;
00253 m_widthScaleFactor = itemWidth / QApplication::desktop()->width();
00254 itemHeight = QApplication::desktop()->height() * m_widthScaleFactor;
00255 m_heightScaleFactor = m_widthScaleFactor;
00256 } else {
00257 itemHeight = (geometry().height() - topMargin - bottomMargin - padding * (m_rows - 1)) / m_rows;
00258 m_heightScaleFactor = itemHeight / QApplication::desktop()->height();
00259 itemWidth = QApplication::desktop()->width() * m_heightScaleFactor;
00260 if (m_displayedText == Name) {
00261
00262
00263 for (int i = 0; i < m_desktopCount; i++) {
00264 QFontMetricsF metrics(KGlobalSettings::taskbarFont());
00265 QSizeF textSize = metrics.size(Qt::TextSingleLine, KWindowSystem::desktopName(i+1));
00266 if (textSize.width() + textMargin * 2 > itemWidth) {
00267 itemWidth = textSize.width() + textMargin * 2;
00268 }
00269 }
00270 }
00271 m_widthScaleFactor = itemWidth / QApplication::desktop()->width();
00272 }
00273
00274 m_rects.clear();
00275 m_animations.clear();
00276 QRectF itemRect;
00277 itemRect.setWidth(floor(itemWidth - 1));
00278 itemRect.setHeight(floor(itemHeight - 1));
00279 for (int i = 0; i < m_desktopCount; i++) {
00280 itemRect.moveLeft(leftMargin + floor((i % columns) * (itemWidth + padding)));
00281 itemRect.moveTop(topMargin + floor((i / columns) * (itemHeight + padding)));
00282 m_rects.append(itemRect);
00283 AnimInfo anim;
00284 anim.animId = -1;
00285 anim.fadeIn = true;
00286 anim.alpha = 0;
00287 m_animations.append(anim);
00288 }
00289
00290
00291 if (m_background->hasElementPrefix("normal")) {
00292 m_background->setElementPrefix("normal");
00293 m_background->resizePanel(itemRect.size());
00294 }
00295 if (m_background->hasElementPrefix("active")) {
00296 m_background->setElementPrefix("active");
00297 m_background->resizePanel(itemRect.size());
00298 }
00299 if (m_background->hasElementPrefix("hover")) {
00300 m_background->setElementPrefix("hover");
00301 m_background->resizePanel(itemRect.size());
00302 }
00303
00304 m_size = QSizeF(ceil(columns * itemWidth + padding * (columns - 1) + leftMargin + rightMargin),
00305 ceil(m_rows * itemHeight + padding * (m_rows - 1) + topMargin + bottomMargin));
00306
00307
00308
00309 resize(m_size);
00310 setPreferredSize(m_size);
00311 if (m_desktopLayoutOwner && columns != m_columns) {
00312
00313 m_columns = columns;
00314 NET::Orientation orient = NET::OrientationHorizontal;
00315 NETRootInfo i( QX11Info::display(), 0 );
00316 i.setDesktopLayout( orient, columns, m_rows, NET::DesktopLayoutCornerTopLeft );
00317 }
00318 }
00319
00320 void Pager::recalculateWindowRects()
00321 {
00322 QList<WId> windows = KWindowSystem::stackingOrder();
00323 m_windowRects.clear();
00324 for (int i = 0; i < m_desktopCount; i++) {
00325 m_windowRects.append(QList<QPair<WId, QRect> >());
00326 }
00327 m_activeWindows.clear();
00328 foreach(WId window, windows) {
00329 KWindowInfo info = KWindowSystem::windowInfo(window, NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState);
00330 NET::WindowType type = info.windowType(NET::NormalMask | NET::DialogMask | NET::OverrideMask |
00331 NET::UtilityMask | NET::DesktopMask | NET::DockMask |
00332 NET::TopMenuMask | NET::SplashMask | NET::ToolbarMask |
00333 NET::MenuMask);
00334
00335
00336
00337
00338 if (type == NET::Desktop || type == NET::Dock || type == NET::TopMenu ||
00339 type == NET::Splash || type == NET::Menu || type == NET::Toolbar ||
00340 info.hasState(NET::SkipPager) || info.isMinimized()) {
00341 continue;
00342 }
00343
00344 for (int i = 0; i < m_desktopCount; i++) {
00345 if (!info.isOnDesktop(i+1)) {
00346 continue;
00347 }
00348 QRect windowRect = info.frameGeometry();
00349 if( KWindowSystem::mapViewport())
00350 windowRect = fixViewportPosition( windowRect );
00351 windowRect = QRectF(windowRect.x() * m_widthScaleFactor,
00352 windowRect.y() * m_heightScaleFactor,
00353 windowRect.width() * m_widthScaleFactor,
00354 windowRect.height() * m_heightScaleFactor).toRect();
00355 windowRect.translate(m_rects[i].topLeft().toPoint());
00356 m_windowRects[i].append(QPair<WId, QRect>(window, windowRect));
00357 if (window == KWindowSystem::activeWindow()) {
00358 m_activeWindows.append(windowRect);
00359 }
00360 }
00361 }
00362
00363 if (m_dirtyDesktop < 0 || m_dirtyDesktop >= m_rects.count()) {
00364 update();
00365 } else {
00366 update(m_rects[m_dirtyDesktop]);
00367 }
00368 }
00369
00370 void Pager::configAccepted()
00371 {
00372 KConfigGroup cg = config();
00373 bool changed = false;
00374
00375 if ((int)m_displayedText != ui.displayedTextComboBox->currentIndex()) {
00376 m_displayedText = (DisplayedText)ui.displayedTextComboBox->currentIndex();
00377 cg.writeEntry("displayedText", (int)m_displayedText);
00378 changed = true;
00379 }
00380
00381 if (m_showWindowIcons != ui.showWindowIconsCheckBox->isChecked()) {
00382 m_showWindowIcons = ui.showWindowIconsCheckBox->isChecked();
00383 cg.writeEntry("showWindowIcons", m_showWindowIcons);
00384 changed = true;
00385 }
00386
00387
00388
00389
00390 if (m_rows != ui.spinRows->value()) {
00391 KConfigGroup globalcg = globalConfig();
00392 m_rows = ui.spinRows->value();
00393 if (m_rows > m_desktopCount) {
00394 m_rows = m_desktopCount;
00395 }
00396 globalcg.writeEntry("rows", m_rows);
00397 changed = true;
00398 }
00399
00400 if (changed) {
00401 configNeedsSaving();
00402
00403 m_columns = 0;
00404 m_size = QSizeF(-1, -1);
00405 recalculateGeometry();
00406 recalculateWindowRects();
00407 update();
00408 }
00409 }
00410
00411 void Pager::currentDesktopChanged(int desktop)
00412 {
00413 m_currentDesktop = desktop;
00414
00415 m_dirtyDesktop = -1;
00416
00417 if (!m_timer->isActive()) {
00418 m_timer->start(WINDOW_UPDATE_DELAY);
00419 }
00420 }
00421
00422 void Pager::windowAdded(WId id)
00423 {
00424 Q_UNUSED(id)
00425
00426 KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState);
00427 m_dirtyDesktop = info.desktop() - 1;
00428
00429 if (!m_timer->isActive()) {
00430 m_timer->start(WINDOW_UPDATE_DELAY);
00431 }
00432 }
00433
00434 void Pager::windowRemoved(WId id)
00435 {
00436 Q_UNUSED(id)
00437
00438 KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState);
00439 m_dirtyDesktop = info.desktop() - 1;
00440
00441 if (!m_timer->isActive()) {
00442 m_timer->start(WINDOW_UPDATE_DELAY);
00443 }
00444 }
00445
00446 void Pager::activeWindowChanged(WId id)
00447 {
00448 Q_UNUSED(id)
00449
00450 KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState);
00451 m_dirtyDesktop = info.desktop() - 1;
00452
00453 if (!m_timer->isActive()) {
00454 m_timer->start(WINDOW_UPDATE_DELAY);
00455 }
00456 }
00457
00458 void Pager::numberOfDesktopsChanged(int num)
00459 {
00460 m_dirtyDesktop = -1;
00461
00462 m_desktopCount = num;
00463 if (m_rows > m_desktopCount) {
00464 m_rows = m_desktopCount;
00465 }
00466 m_rects.clear();
00467 recalculateGeometry();
00468
00469 if (!m_timer->isActive()) {
00470 m_timer->start(WINDOW_UPDATE_DELAY);
00471 }
00472 }
00473
00474 void Pager::desktopNamesChanged()
00475 {
00476 m_dirtyDesktop = -1;
00477
00478 m_rects.clear();
00479 recalculateGeometry();
00480
00481 if (!m_timer->isActive()) {
00482 m_timer->start(WINDOW_UPDATE_DELAY);
00483 }
00484 }
00485
00486 void Pager::stackingOrderChanged()
00487 {
00488 m_dirtyDesktop = -1;
00489
00490 if (!m_timer->isActive()) {
00491 m_timer->start(WINDOW_UPDATE_DELAY);
00492 }
00493 }
00494
00495 void Pager::windowChanged(WId id, unsigned int properties)
00496 {
00497 Q_UNUSED(id)
00498
00499 if (properties & NET::WMGeometry) {
00500 KWindowInfo info = KWindowSystem::windowInfo(id, NET::WMGeometry | NET::WMFrameExtents | NET::WMWindowType | NET::WMDesktop | NET::WMState | NET::XAWMState);
00501 m_dirtyDesktop = info.desktop() - 1;
00502 } else {
00503 m_dirtyDesktop = -1;
00504 }
00505
00506 if (properties & NET::WMGeometry ||
00507 properties & NET::WMDesktop) {
00508 if (!m_timer->isActive()) {
00509 m_timer->start(WINDOW_UPDATE_DELAY);
00510 }
00511 }
00512 }
00513
00514 void Pager::showingDesktopChanged(bool showing)
00515 {
00516 m_dirtyDesktop = -1;
00517
00518 Q_UNUSED(showing)
00519 if (!m_timer->isActive()) {
00520 m_timer->start(WINDOW_UPDATE_DELAY);
00521 }
00522 }
00523
00524 void Pager::desktopsSizeChanged()
00525 {
00526 m_dirtyDesktop = -1;
00527
00528 m_rects.clear();
00529 recalculateGeometry();
00530
00531 if (!m_timer->isActive()) {
00532 m_timer->start(WINDOW_UPDATE_DELAY);
00533 }
00534 }
00535
00536 void Pager::mousePressEvent(QGraphicsSceneMouseEvent *event)
00537 {
00538 if (event->buttons() != Qt::RightButton)
00539 {
00540 for (int i = 0; i < m_desktopCount; i++) {
00541 if (posOnDesktopRect(m_rects[i], event->pos())) {
00542 m_dragStartDesktop = m_dragHighlightedDesktop = i;
00543 m_dragOriginalPos = m_dragCurrentPos = event->pos();
00544 if (m_dragOriginal.isEmpty()) {
00545 m_dragOriginal = m_rects[i].toRect();
00546 }
00547
00548 update();
00549 return;
00550 }
00551 }
00552 }
00553 Applet::mousePressEvent(event);
00554 }
00555
00556 void Pager::wheelEvent(QGraphicsSceneWheelEvent *e)
00557 {
00558 int newDesk;
00559 int desktops = KWindowSystem::numberOfDesktops();
00560
00561
00562
00563
00564
00565 if (e->delta() < 0)
00566 {
00567 newDesk = m_currentDesktop % desktops + 1;
00568 }
00569 else
00570 {
00571 newDesk = (desktops + m_currentDesktop - 2) % desktops + 1;
00572 }
00573
00574 KWindowSystem::setCurrentDesktop(newDesk);
00575 m_currentDesktop = newDesk;
00576 update();
00577
00578 Applet::wheelEvent(e);
00579 }
00580
00581 void Pager::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
00582 {
00583 if (m_dragId > 0) {
00584 m_dragCurrentPos = event->pos();
00585 m_dragHighlightedDesktop = -1;
00586 for (int i = 0; i < m_desktopCount; i++) {
00587 if (m_rects[i].contains(event->pos().toPoint())) {
00588 m_dragHighlightedDesktop = i;
00589 break;
00590 }
00591 }
00592 m_hoverRect = QRectF();
00593 foreach (const QRectF &rect, m_rects) {
00594 if (rect.contains(event->pos())) {
00595 m_hoverRect = rect;
00596 break;
00597 }
00598 }
00599 update();
00600 event->accept();
00601 return;
00602 } else if (m_dragId != -1 && m_dragStartDesktop != -1 &&
00603 (event->pos() - m_dragOriginalPos).toPoint().manhattanLength() > KGlobalSettings::dndEventDelay()) {
00604 m_dragId = -1;
00605 for (int k = m_windowRects[m_dragStartDesktop].count() - 1; k >= 0 ; k--) {
00606 if (m_windowRects[m_dragStartDesktop][k].second.contains(m_dragOriginalPos.toPoint())) {
00607 m_dragOriginal = m_windowRects[m_dragStartDesktop][k].second;
00608 m_dragId = m_windowRects[m_dragStartDesktop][k].first;
00609 event->accept();
00610 break;
00611 }
00612 }
00613 }
00614
00615 if (m_dragOriginal.isEmpty()) {
00616 Applet::mouseMoveEvent(event);
00617 }
00618 }
00619
00620 void Pager::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
00621 {
00622 if (m_dragId > 0) {
00623 if (m_dragHighlightedDesktop != -1) {
00624 QPointF dest = m_dragCurrentPos - m_rects[m_dragHighlightedDesktop].topLeft() - m_dragOriginalPos + m_dragOriginal.topLeft();
00625 dest = QPointF(dest.x()/m_widthScaleFactor, dest.y()/m_heightScaleFactor);
00626
00627 dest = QPointF(qMax(dest.x(), qreal(0.0)), qMax(dest.y(), qreal(0.0)));
00628 if( !KWindowSystem::mapViewport()) {
00629 KWindowSystem::setOnDesktop(m_dragId, m_dragHighlightedDesktop+1);
00630
00631 NETRootInfo i( QX11Info::display(), 0 );
00632 int flags = ( 0x20 << 12 ) | ( 0x03 << 8 ) | 1;
00633 i.moveResizeWindowRequest( m_dragId, flags, dest.toPoint().x(), dest.toPoint().y(), 0, 0 );
00634 } else {
00635
00636
00637
00638 dest += KWindowSystem::desktopToViewport( m_dragHighlightedDesktop+1, false );
00639 QPoint d = KWindowSystem::constrainViewportRelativePosition( dest.toPoint());
00640 NETRootInfo i( QX11Info::display(), 0 );
00641 int flags = ( 0x20 << 12 ) | ( 0x03 << 8 ) | 1;
00642 i.moveResizeWindowRequest( m_dragId, flags, d.x(), d.y(), 0, 0 );
00643 }
00644 }
00645 m_timer->start();
00646 } else if (m_dragStartDesktop != -1 && posOnDesktopRect(m_rects[m_dragStartDesktop], event->pos()) &&
00647 m_currentDesktop != m_dragStartDesktop + 1) {
00648
00649 KWindowSystem::setCurrentDesktop(m_dragStartDesktop + 1);
00650 m_currentDesktop = m_dragStartDesktop + 1;
00651 }
00652
00653 m_dragId = 0;
00654 m_dragOriginal = QRect();
00655 m_dragHighlightedDesktop = -1;
00656 m_dragStartDesktop = -1;
00657 m_dragOriginalPos = m_dragCurrentPos = QPointF();
00658
00659 update();
00660 Applet::mouseReleaseEvent(event);
00661 }
00662
00663
00664
00665 void Pager::handleHoverMove(const QPointF& pos)
00666 {
00667 bool changedHover = !posOnDesktopRect(m_hoverRect, pos);
00668 Plasma::Animator *anim = Plasma::Animator::self();
00669
00670 if (changedHover && m_hoverIndex > -1) {
00671 if (m_animations[m_hoverIndex].animId != -1) {
00672 Plasma::Animator::self()->stopCustomAnimation(m_animations[m_hoverIndex].animId);
00673 }
00674 m_animations[m_hoverIndex].fadeIn = false;
00675 m_animations[m_hoverIndex].alpha = 1;
00676 m_animations[m_hoverIndex].animId = anim->customAnimation(40 / (1000 / s_FadeOutDuration), s_FadeOutDuration,Plasma::Animator::EaseOutCurve, this,"animationUpdate");
00677 }
00678
00679 if (!changedHover) {
00680 return;
00681 }
00682
00683 int i = 0;
00684 foreach (const QRectF &rect, m_rects) {
00685 if (posOnDesktopRect(rect, pos)) {
00686 if (m_hoverRect != rect) {
00687 m_hoverRect = rect;
00688 m_hoverIndex = i;
00689 if (m_animations[m_hoverIndex].animId != -1) {
00690 anim->stopCustomAnimation(m_animations[i].animId);
00691 }
00692 m_animations[m_hoverIndex].fadeIn = true;
00693 m_animations[m_hoverIndex].alpha = 0;
00694 m_animations[m_hoverIndex].animId = anim->customAnimation(40 / (1000 / s_FadeInDuration), s_FadeInDuration,Plasma::Animator::EaseInCurve, this,"animationUpdate");
00695 update();
00696 }
00697 return;
00698 }
00699 i++;
00700 }
00701 m_hoverIndex = -1;
00702 m_hoverRect = QRectF();
00703 update();
00704 }
00705
00706
00707
00708 void Pager::handleHoverLeave()
00709 {
00710 if (m_hoverRect != QRectF()) {
00711 m_hoverRect = QRectF();
00712 update();
00713 }
00714
00715 if (m_hoverIndex != -1) {
00716 if (m_animations[m_hoverIndex].animId != -1) {
00717 Plasma::Animator::self()->stopCustomAnimation(m_animations[m_hoverIndex].animId);
00718 }
00719 m_animations[m_hoverIndex].fadeIn = false;
00720 m_animations[m_hoverIndex].alpha = 1;
00721 m_animations[m_hoverIndex].animId = Plasma::Animator::self()->customAnimation(40 / (1000 / s_FadeOutDuration), s_FadeOutDuration,Plasma::Animator::EaseOutCurve, this,"animationUpdate");
00722 m_hoverIndex = -1;
00723 }
00724
00725
00726
00727
00728
00729
00730 if (m_dragId || m_dragStartDesktop != -1) {
00731 m_dragId = 0;
00732 m_dragOriginal = QRect();
00733 m_dragHighlightedDesktop = -1;
00734 m_dragStartDesktop = -1;
00735 m_dragOriginalPos = m_dragCurrentPos = QPointF();
00736 update();
00737 }
00738 }
00739
00740 void Pager::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
00741 {
00742 handleHoverMove(event->pos());
00743 Applet::hoverEnterEvent(event);
00744 }
00745
00746 void Pager::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
00747 {
00748 handleHoverMove(event->pos());
00749 }
00750
00751 void Pager::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
00752 {
00753 handleHoverLeave();
00754 Applet::hoverLeaveEvent(event);
00755 }
00756
00757 void Pager::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
00758 {
00759
00760 event->setAccepted(false);
00761 handleHoverMove(event->pos());
00762
00763 if (m_hoverIndex != -1) {
00764 m_dragSwitchDesktop = m_hoverIndex;
00765 m_dragSwitchTimer->start(DRAG_SWITCH_DELAY);
00766 }
00767 Applet::dragEnterEvent(event);
00768 }
00769
00770 void Pager::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
00771 {
00772 handleHoverMove(event->pos());
00773
00774 if (m_dragSwitchDesktop != m_hoverIndex && m_hoverIndex != -1) {
00775 m_dragSwitchDesktop = m_hoverIndex;
00776 m_dragSwitchTimer->start(DRAG_SWITCH_DELAY);
00777 } else if (m_hoverIndex == -1) {
00778 m_dragSwitchDesktop = m_hoverIndex;
00779 m_dragSwitchTimer->stop();
00780 }
00781 Applet::dragMoveEvent(event);
00782 }
00783
00784 void Pager::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
00785 {
00786 handleHoverLeave();
00787
00788 m_dragSwitchDesktop = -1;
00789 m_dragSwitchTimer->stop();
00790 Applet::dragLeaveEvent(event);
00791 }
00792
00793 void Pager::animationUpdate(qreal progress, int animId)
00794 {
00795 int i = 0;
00796 foreach (AnimInfo anim, m_animations) {
00797 if (anim.animId == animId) {
00798 break;
00799 }
00800 i++;
00801 }
00802
00803 if (i >= m_animations.size()) {
00804 return;
00805 }
00806
00807 m_animations[i].alpha = m_animations[i].fadeIn ? progress : 1 - progress;
00808
00809 if (progress == 1) {
00810 m_animations[i].animId = -1;
00811 m_animations[i].fadeIn = true;
00812 }
00813
00814
00815 update();
00816 }
00817
00818 void Pager::dragSwitch()
00819 {
00820 if (m_dragSwitchDesktop == -1) {
00821 return;
00822 }
00823 KWindowSystem::setCurrentDesktop(m_dragSwitchDesktop + 1);
00824 m_currentDesktop = m_dragSwitchDesktop + 1;
00825 }
00826
00827 void Pager::paintInterface(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRect &contentsRect)
00828 {
00829 Q_UNUSED( option );
00830 Q_UNUSED( contentsRect );
00831
00832 KColorScheme plasmaColorTheme = KColorScheme(QPalette::Active, KColorScheme::View, Plasma::Theme::defaultTheme()->colorScheme());
00833 painter->setFont(KGlobalSettings::taskbarFont());
00834
00835
00836 QColor defaultTextColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00837 QColor hoverColor = defaultTextColor;
00838 hoverColor.setAlpha(64);
00839
00840
00841 QColor drawingColor = plasmaColorTheme.foreground(KColorScheme::InactiveText).color();
00842 drawingColor.setAlpha(50);
00843 QBrush windowBrush(drawingColor);
00844
00845 drawingColor.setAlpha(192);
00846 QBrush windowBrushActiveDesk(drawingColor);
00847
00848
00849 drawingColor = plasmaColorTheme.foreground(KColorScheme::NeutralText).color();
00850 drawingColor.setAlpha(238);
00851 QPen windowPen(drawingColor);
00852
00853
00854 QPen activeWindowPen(defaultTextColor);
00855
00856
00857 drawingColor.setAlpha(190);
00858 QBrush activeWindowBrush(drawingColor);
00859
00860 drawingColor.setAlpha(228);
00861 QBrush activeWindowBrushActiveDesk(drawingColor);
00862
00863 if (m_showOwnBackground && (formFactor() == Plasma::Vertical || formFactor() == Plasma::Horizontal)) {
00864 m_background->setElementPrefix(QString());
00865 m_background->paintPanel(painter, contentsRect);
00866 }
00867
00868
00869 painter->setPen(Qt::NoPen);
00870 if (!m_background->hasElementPrefix("hover")) {
00871 for (int i = 0; i < m_desktopCount; i++) {
00872 if (m_rects[i] == m_hoverRect) {
00873 QColor animHoverColor = hoverColor;
00874 if (m_animations[i].animId > -1) {
00875 animHoverColor.setAlpha(hoverColor.alpha()*m_animations[i].alpha);
00876 }
00877 painter->setBrush(animHoverColor);
00878 painter->drawRect(m_rects[i]);
00879 }
00880 }
00881 }
00882
00883
00884 painter->setPen(windowPen);
00885 for (int i = 0; i < m_windowRects.count(); i++) {
00886 for (int j = 0; j < m_windowRects[i].count(); j++) {
00887 QRect rect = m_windowRects[i][j].second;
00888 if (m_rects[m_currentDesktop-1].contains(rect)) {
00889 if (m_activeWindows.contains(rect)) {
00890 painter->setBrush(activeWindowBrushActiveDesk);
00891 painter->setPen(activeWindowPen);
00892 } else {
00893 painter->setBrush(windowBrushActiveDesk);
00894 painter->setPen(windowPen);
00895 }
00896 } else {
00897 if (m_activeWindows.contains(rect)) {
00898 painter->setBrush(activeWindowBrush);
00899 painter->setPen(activeWindowPen);
00900 } else {
00901 painter->setBrush(windowBrush);
00902 painter->setPen(windowPen);
00903 }
00904 }
00905 if (m_dragId == m_windowRects[i][j].first) {
00906 rect.translate((m_dragCurrentPos - m_dragOriginalPos).toPoint());
00907 painter->setClipRect(option->exposedRect);
00908 } else {
00909 painter->setClipRect(m_rects[i].adjusted(1, 1, -1, -1));
00910 }
00911 painter->drawRect(rect);
00912 if ((rect.width() > 16) && (rect.height() > 16) && m_showWindowIcons){
00913 painter->drawPixmap(rect.x() + (rect.width() - 16) / 2, rect.y() + (rect.height() - 16) / 2, 16, 16,
00914 KWindowSystem::icon(m_windowRects[i][j].first, 16, 16, true));
00915 }
00916 }
00917 }
00918
00919
00920 painter->setClipRect(option->exposedRect);
00921 painter->setBrush(Qt::NoBrush);
00922
00923 QString prefix;
00924 for (int i = 0; i < m_desktopCount; i++) {
00925 if (i + 1 == m_currentDesktop || i == m_dragHighlightedDesktop) {
00926 prefix = "active";
00927 } else {
00928 prefix = "normal";
00929 }
00930
00931
00932 if (m_background->hasElementPrefix(prefix)) {
00933 m_background->setElementPrefix(prefix);
00934 if (m_animations[i].animId > -1) {
00935 QPixmap pixmap(m_rects[i].size().toSize());
00936 QColor alphaColor(0,0,0);
00937
00938
00939 alphaColor.setAlphaF(1.0-m_animations[i].alpha);
00940 pixmap.fill(alphaColor);
00941
00942 QPainter buffPainter(&pixmap);
00943 buffPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
00944
00945 m_background->paintPanel(&buffPainter, QRectF(QPointF(0, 0), m_rects[i].size()));
00946 buffPainter.end();
00947 painter->drawPixmap(m_rects[i].topLeft(), pixmap);
00948
00949 m_background->setElementPrefix("hover");
00950
00951 alphaColor.setAlphaF(m_animations[i].alpha);
00952
00953 pixmap = QPixmap(m_rects[i].size().toSize());
00954 pixmap.fill(alphaColor);
00955 buffPainter.begin(&pixmap);
00956 buffPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
00957 m_background->paintPanel(&buffPainter, QRectF(QPointF(0, 0), m_rects[i].size()));
00958 painter->drawPixmap(m_rects[i].topLeft(), pixmap);
00959 } else {
00960
00961 if (m_rects[i] == m_hoverRect) {
00962 m_background->setElementPrefix("hover");
00963 }
00964 m_background->paintPanel(painter, m_rects[i], m_rects[i].topLeft());
00965 }
00966 } else {
00967 QPen drawingPen;
00968
00969 if (i + 1 == m_currentDesktop || i == m_dragHighlightedDesktop) {
00970 defaultTextColor.setAlphaF(1);
00971 drawingPen = QPen(defaultTextColor);
00972 } else {
00973 drawingPen = QPen(plasmaColorTheme.foreground(KColorScheme::InactiveText).color());
00974 }
00975
00976 painter->setPen(drawingPen);
00977 painter->drawRect(m_rects[i]);
00978 }
00979
00980
00981 if (m_animations[i].animId == -1) {
00982 defaultTextColor.setAlphaF(1);
00983 }
00984 defaultTextColor.setAlphaF(m_animations[i].alpha / 2 + 0.5);
00985 painter->setPen(defaultTextColor);
00986
00987 if (m_displayedText==Number) {
00988 painter->drawText(m_rects[i], Qt::AlignCenter, QString::number(i+1));
00989 } else if (m_displayedText==Name) {
00990 painter->drawText(m_rects[i], Qt::AlignCenter, KWindowSystem::desktopName(i+1));
00991 }
00992 }
00993 }
00994
00995 void Pager::lostDesktopLayoutOwner()
00996 {
00997 delete m_desktopLayoutOwner;
00998 m_desktopLayoutOwner = NULL;
00999 }
01000
01001
01002
01003
01004 QRect Pager::fixViewportPosition( const QRect& r )
01005 {
01006 int x = r.center().x() % qApp->desktop()->width();
01007 int y = r.center().y() % qApp->desktop()->height();
01008 if( x < 0 )
01009 x = x + qApp->desktop()->width();
01010 if( y < 0 )
01011 y = y + qApp->desktop()->height();
01012 return QRect( x - r.width() / 2, y - r.height() / 2, r.width(), r.height());
01013 }
01014
01015 #include "pager.moc"