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

Plasma

panelcontroller.cpp

Go to the documentation of this file.
00001 /*
00002  *   Copyright 2008 Marco Martin <notmart@gmail.com>
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU Library General Public License as
00006  *   published by the Free Software Foundation; either version 2, or
00007  *   (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 "panelcontroller.h"
00021 
00022 #include <QAction>
00023 #include <QApplication>
00024 #include <QBoxLayout>
00025 #include <QVBoxLayout>
00026 #include <QDesktopWidget>
00027 #include <QFrame>
00028 #include <QLabel>
00029 #include <QMouseEvent>
00030 #include <QPainter>
00031 #include <QToolButton>
00032 
00033 #include <KColorUtils>
00034 #include <KIconLoader>
00035 #include <KIcon>
00036 #include <KWindowSystem>
00037 
00038 #include <Plasma/Containment>
00039 #include <Plasma/Corona>
00040 #include <Plasma/PaintUtils>
00041 #include <Plasma/Theme>
00042 #include <Plasma/FrameSvg>
00043 #include <Plasma/Dialog>
00044 
00045 #include "plasmaapp.h"
00046 #include "positioningruler.h"
00047 #include "toolbutton.h"
00048 
00049 #include <kephal/screens.h>
00050 
00051 class PanelController::ButtonGroup: public QFrame
00052 {
00053 public:
00054     ButtonGroup(QWidget *parent)
00055        : QFrame(parent)
00056     {
00057         background = new Plasma::FrameSvg(this);
00058         background->setImagePath("widgets/frame");
00059         background->setElementPrefix("plain");
00060     }
00061 
00062     void paintEvent(QPaintEvent *event)
00063     {
00064         Q_UNUSED(event)
00065 
00066         QPainter painter(this);
00067         background->resizeFrame(size());
00068         background->paintFrame(&painter);
00069     }
00070 
00071     Plasma::FrameSvg *background;
00072 };
00073 
00074 
00075 class PanelController::Private
00076 {
00077 public:
00078     Private(PanelController *panelControl)
00079        : q(panelControl),
00080          containment(0),
00081          orientation(Qt::Horizontal),
00082          location(Plasma::BottomEdge),
00083          extLayout(0),
00084          layout(0),
00085          dragging(NoElement),
00086          startDragPos(0,0),
00087          leftAlignTool(0),
00088          centerAlignTool(0),
00089          rightAlignTool(0),
00090          drawMoveHint(false)
00091     {
00092     }
00093 
00094     ToolButton *addTool(QAction *action, QWidget *parent, Qt::ToolButtonStyle style = Qt::ToolButtonTextBesideIcon)
00095     {
00096         ToolButton *tool = new ToolButton(parent);
00097         tool->setToolButtonStyle(style);
00098         tool->setAction(action);
00099         actionWidgets.append(tool);
00100 
00101         return tool;
00102     }
00103 
00104     ToolButton *addTool(const QString iconName, const QString iconText, QWidget *parent, Qt::ToolButtonStyle style = Qt::ToolButtonTextBesideIcon, bool checkButton = false)
00105     {
00106         //TODO take advantage of setDefaultAction using the containment's actions if possible
00107         ToolButton *tool = new ToolButton(parent);
00108 
00109         KIcon icon = KIcon(iconName);
00110         if (!icon.isNull() && !iconName.isNull()) {
00111             tool->setIcon(icon);
00112         }
00113 
00114         tool->setText(iconText);
00115         tool->setToolButtonStyle(style);
00116 
00117         if (style == Qt::ToolButtonIconOnly) {
00118             tool->setToolTip(iconText);
00119         }
00120 
00121         tool->setCheckable(checkButton);
00122         tool->setAutoExclusive(checkButton);
00123 
00124         return tool;
00125     }
00126 
00127     void resizeFrameHeight(const int newHeight)
00128     {
00129         if (!containment) {
00130             return;
00131         }
00132 
00133         switch (location) {
00134         case Plasma::LeftEdge:
00135         case Plasma::RightEdge:
00136             containment->resize(QSize(newHeight, (int)containment->size().height()));
00137             containment->setMinimumSize(QSize(newHeight, (int)containment->minimumSize().height()));
00138             containment->setMaximumSize(QSize(newHeight, (int)containment->maximumSize().height()));
00139             break;
00140         case Plasma::TopEdge:
00141         case Plasma::BottomEdge:
00142         default:
00143             containment->resize(QSize((int)containment->size().width(), newHeight));
00144             containment->setMinimumSize(QSize((int)containment->minimumSize().width(), newHeight));
00145             containment->setMaximumSize(QSize((int)containment->maximumSize().width(), newHeight));
00146             break;
00147        }
00148     }
00149 
00150     void rulersMoved(int offset, int minLength, int maxLength)
00151     {
00152          if (!containment) {
00153             return;
00154          }
00155 
00156          QSize preferredSize(containment->preferredSize().toSize());
00157 
00158          switch (location) {
00159          case Plasma::LeftEdge:
00160          case Plasma::RightEdge:
00161              containment->resize(QSize((int)containment->size().width(), qBound(minLength, preferredSize.height(), maxLength)));
00162              containment->setMinimumSize(QSize((int)containment->minimumSize().width(), minLength));
00163              containment->setMaximumSize(QSize((int)containment->maximumSize().width(), maxLength));
00164              break;
00165          case Plasma::TopEdge:
00166          case Plasma::BottomEdge:
00167          default:
00168              containment->resize(QSize(qBound(minLength, preferredSize.width(), maxLength), (int)containment->size().height()));
00169              containment->setMinimumSize(QSize(minLength, (int)containment->minimumSize().height()));
00170              containment->setMaximumSize(QSize(maxLength, (int)containment->maximumSize().height()));
00171              break;
00172         }
00173 
00174         emit q->offsetChanged(offset);
00175     }
00176 
00177     void alignToggled(bool toggle)
00178     {
00179         if (!toggle) {
00180             return;
00181         }
00182 
00183         if (q->sender() == leftAlignTool) {
00184             emit q->alignmentChanged(Qt::AlignLeft);
00185             ruler->setAlignment(Qt::AlignLeft);
00186         } else if (q->sender() == centerAlignTool) {
00187             emit q->alignmentChanged(Qt::AlignCenter);
00188             ruler->setAlignment(Qt::AlignCenter);
00189         } else if (q->sender() == rightAlignTool) {
00190             emit q->alignmentChanged(Qt::AlignRight);
00191             ruler->setAlignment(Qt::AlignRight);
00192         }
00193 
00194         emit q->offsetChanged(0);
00195         ruler->setOffset(0);
00196     }
00197 
00198     void panelVisibilityModeChanged(bool toggle)
00199     {
00200         if (!toggle) {
00201             return;
00202         }
00203 
00204         if (q->sender() == normalPanelTool) {
00205             emit q->panelVisibilityModeChanged(PanelView::NormalPanel);
00206         } else if (q->sender() == autoHideTool) {
00207             emit q->panelVisibilityModeChanged(PanelView::AutoHide);
00208         } else if (q->sender() == underWindowsTool) {
00209             emit q->panelVisibilityModeChanged(PanelView::LetWindowsCover);
00210         }
00211     }
00212 
00213     void settingsPopup()
00214     {
00215         if (optionsDialog->isVisible()) {
00216             optionsDialog->hide();
00217         } else {
00218             KWindowSystem::setState(optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky);
00219             QPoint pos = q->mapToGlobal(settingsTool->pos());
00220             optionsDialog->layout()->activate();
00221             optionsDialog->resize(optionsDialog->sizeHint());
00222             QSize s = optionsDialog->size();
00223 
00224             switch (location) {
00225                 case Plasma::BottomEdge:
00226                 pos = QPoint(pos.x(), pos.y() - s.height());
00227                 break;
00228             case Plasma::TopEdge:
00229                 pos = QPoint(pos.x(), pos.y() + settingsTool->size().height());
00230                 break;
00231             case Plasma::LeftEdge:
00232                 pos = QPoint(pos.x() + settingsTool->size().width(), pos.y());
00233                 break;
00234             case Plasma::RightEdge:
00235                 pos = QPoint(pos.x() - s.width(), pos.y());
00236                 break;
00237             default:
00238                 if (pos.y() - s.height() > 0) {
00239                     pos = QPoint(pos.x(), pos.y() - s.height());
00240                 } else {
00241                     pos = QPoint(pos.x(), pos.y() + settingsTool->size().height());
00242                 }
00243             }
00244 
00245             QRect screenRect = Kephal::ScreenUtils::screenGeometry(containment->screen());
00246 
00247             if (pos.rx() + s.width() > screenRect.right()) {
00248                 pos.rx() -= ((pos.rx() + s.width()) - screenRect.right());
00249             }
00250 
00251             if (pos.ry() + s.height() > screenRect.bottom()) {
00252                 pos.ry() -= ((pos.ry() + s.height()) - screenRect.bottom());
00253             }
00254 
00255             pos.rx() = qMax(0, pos.rx());
00256             optionsDialog->move(pos);
00257             optionsDialog->show();
00258         }
00259     }
00260 
00261     void syncRuler()
00262     {
00263         QRect screenGeom =
00264               Kephal::ScreenUtils::screenGeometry(containment->screen());
00265 
00266         switch (location) {
00267         case Plasma::LeftEdge:
00268         case Plasma::RightEdge:
00269             ruler->setAvailableLength(screenGeom.height());
00270             ruler->setMaxLength(qMin((int)containment->maximumSize().height(), screenGeom.height()));
00271             ruler->setMinLength(containment->minimumSize().height());
00272             break;
00273         case Plasma::TopEdge:
00274         case Plasma::BottomEdge:
00275         default:
00276             ruler->setAvailableLength(screenGeom.width());
00277             ruler->setMaxLength(qMin((int)containment->maximumSize().width(), screenGeom.width()));
00278             ruler->setMinLength(containment->minimumSize().width());
00279             break;
00280         }
00281     }
00282 
00283     void maximizePanel()
00284     {
00285         const int length = ruler->availableLength();
00286         rulersMoved(0, length, length);
00287         ruler->setOffset(0);
00288         ruler->setMaxLength(length);
00289         ruler->setMinLength(length);
00290     }
00291 
00292      enum DragElement { NoElement = 0,
00293                         ResizeButtonElement,
00294                         MoveButtonElement
00295                       };
00296 
00297     PanelController *q;
00298     Plasma::Containment *containment;
00299     Qt::Orientation orientation;
00300     Plasma::Location location;
00301     QBoxLayout *extLayout;
00302     QBoxLayout *layout;
00303     QLabel *alignLabel;
00304     QLabel *modeLabel;
00305     DragElement dragging;
00306     QPoint startDragPos;
00307     Plasma::FrameSvg *background;
00308     Plasma::Dialog *optionsDialog;
00309     QBoxLayout *optDialogLayout;
00310     ToolButton *settingsTool;
00311     Plasma::Svg *iconSvg;
00312 
00313     ToolButton *moveTool;
00314     ToolButton *sizeTool;
00315 
00316     //Alignment buttons
00317     ToolButton *leftAlignTool;
00318     ToolButton *centerAlignTool;
00319     ToolButton *rightAlignTool;
00320 
00321     //Panel mode buttons
00322     ToolButton *normalPanelTool;
00323     ToolButton *autoHideTool;
00324     ToolButton *underWindowsTool;
00325     ToolButton *expandTool;
00326 
00327     //Widgets for actions
00328     QList<QWidget *> actionWidgets;
00329 
00330     PositioningRuler *ruler;
00331 
00332     bool drawMoveHint;
00333 
00334     static const int minimumHeight = 10;
00335 };
00336 
00337 PanelController::PanelController(QWidget* parent)
00338    : QWidget(0),
00339      d(new Private(this))
00340 {
00341     Q_UNUSED(parent)
00342 
00343     QPalette pal = palette();
00344     pal.setBrush(backgroundRole(), Qt::transparent);
00345     setPalette(pal);
00346 
00347     d->background = new Plasma::FrameSvg(this);
00348     d->background->setImagePath("dialogs/background");
00349     d->background->setContainsMultipleImages(true);
00350 
00351     d->iconSvg = new Plasma::Svg(this);
00352     d->iconSvg->setImagePath("widgets/configuration-icons");
00353     d->iconSvg->setContainsMultipleImages(true);
00354     d->iconSvg->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
00355 
00356     //setWindowFlags(Qt::Popup);
00357     setWindowFlags(Qt::FramelessWindowHint);
00358     KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky);
00359     setAttribute(Qt::WA_DeleteOnClose);
00360     setFocus(Qt::ActiveWindowFocusReason);
00361 
00362     //layout setup
00363     d->extLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
00364     setLayout(d->extLayout);
00365 
00366     d->background->setEnabledBorders(Plasma::FrameSvg::TopBorder);
00367     d->extLayout->setContentsMargins(0, d->background->marginSize(Plasma::TopMargin), 0, 0);
00368 
00369     d->layout = new QBoxLayout(QBoxLayout::LeftToRight);
00370     d->layout->setContentsMargins(4, 4, 4, 4);
00371     if (QApplication::layoutDirection() == Qt::RightToLeft) {
00372         d->layout->setDirection(QBoxLayout::RightToLeft);
00373     } else {
00374         d->layout->setDirection(QBoxLayout::LeftToRight);
00375     }
00376     d->layout->setSpacing(4);
00377 
00378     d->layout->addStretch();
00379     d->extLayout->addLayout(d->layout);
00380 
00381     //Add buttons
00382 
00383     //alignment
00384     //first the container
00385     QFrame *alignFrame = new ButtonGroup(this);
00386     QVBoxLayout *alignLayout = new QVBoxLayout(alignFrame);
00387 
00388 
00389     d->alignLabel = new QLabel(i18n("Panel Alignment"), this);
00390     alignLayout->addWidget(d->alignLabel);
00391 
00392     d->leftAlignTool = d->addTool("format-justify-left", i18n("Left"), alignFrame,  Qt::ToolButtonTextBesideIcon, true);
00393     d->leftAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00394     alignLayout->addWidget(d->leftAlignTool);
00395     d->leftAlignTool->setChecked(true);
00396     connect(d->leftAlignTool, SIGNAL(toggled(bool)), this, SLOT(alignToggled(bool)));
00397 
00398     d->centerAlignTool = d->addTool("format-justify-center", i18n("Center"), alignFrame,  Qt::ToolButtonTextBesideIcon, true);
00399     d->centerAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00400     alignLayout->addWidget(d->centerAlignTool);
00401     connect(d->centerAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
00402 
00403     d->rightAlignTool = d->addTool("format-justify-right", i18n("Right"), alignFrame,  Qt::ToolButtonTextBesideIcon, true);
00404     d->rightAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00405     alignLayout->addWidget(d->rightAlignTool);
00406     connect(d->rightAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
00407 
00408 
00409     //Panel mode
00410     //first the container
00411     QFrame *modeFrame = new ButtonGroup(this);
00412     QVBoxLayout *modeLayout = new QVBoxLayout(modeFrame);
00413 
00414     d->modeLabel = new QLabel(i18n("Visibility"), this);
00415     modeLayout->addWidget(d->modeLabel);
00416 
00417     d->normalPanelTool = d->addTool("checkmark", i18n("Always visible"), modeFrame,  Qt::ToolButtonTextBesideIcon, true);
00418     d->normalPanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00419     modeLayout->addWidget(d->normalPanelTool);
00420     connect(d->normalPanelTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
00421 
00422     d->autoHideTool = d->addTool("video-display", i18n("Auto hide"), modeFrame,  Qt::ToolButtonTextBesideIcon, true);
00423     d->autoHideTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00424     modeLayout->addWidget(d->autoHideTool);
00425     connect(d->autoHideTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
00426 
00427     d->underWindowsTool = d->addTool("view-fullscreen", i18n("Windows can cover"), modeFrame,  Qt::ToolButtonTextBesideIcon, true);
00428     d->underWindowsTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00429     modeLayout->addWidget(d->underWindowsTool);
00430     connect(d->underWindowsTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
00431 
00432     d->layout->addStretch();
00433     d->moveTool = d->addTool(QString(), i18n("Screen Edge"), this);
00434     d->moveTool->setIcon(d->iconSvg->pixmap("move"));
00435     d->moveTool->installEventFilter(this);
00436     d->moveTool->setCursor(Qt::SizeAllCursor);
00437     d->layout->addWidget(d->moveTool);
00438 
00439     d->sizeTool = d->addTool(QString(), i18n("Height"), this);
00440     d->sizeTool->installEventFilter(this);
00441     d->sizeTool->setCursor(Qt::SizeVerCursor);
00442     d->layout->addWidget(d->sizeTool);
00443     d->layout->addStretch();
00444 
00445     //other buttons
00446     d->layout->addSpacing(20);
00447 
00448     //Settings popup menu
00449     d->settingsTool = d->addTool("configure", i18n("More Settings"), this);
00450     d->layout->addWidget(d->settingsTool);
00451     connect(d->settingsTool, SIGNAL(pressed()), this, SLOT(settingsPopup()));
00452     d->optionsDialog = new Plasma::Dialog(0); // don't pass in a parent; breaks with some lesser WMs
00453     d->optionsDialog->installEventFilter(this);
00454     KWindowSystem::setState(d->optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky);
00455     d->optDialogLayout = new QVBoxLayout(d->optionsDialog);
00456     d->optDialogLayout->setMargin(0);
00457     d->optDialogLayout->addWidget(alignFrame);
00458     d->optDialogLayout->addWidget(modeFrame);
00459 
00460 
00461     d->expandTool = d->addTool(QString(), i18n("Maximize Panel"), this);
00462     d->expandTool->setIcon(d->iconSvg->pixmap("size-horizontal"));
00463     d->expandTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00464     d->optDialogLayout->addWidget(d->expandTool);
00465     connect(d->expandTool, SIGNAL(clicked()), this, SLOT(maximizePanel()));
00466 
00467     ToolButton *closeControllerTool = d->addTool("window-close", i18n("Close this configuration window"), this, Qt::ToolButtonIconOnly, false);
00468     d->layout->addWidget(closeControllerTool);
00469     connect(closeControllerTool, SIGNAL(clicked()), this, SLOT(hide()));
00470 
00471     d->ruler = new PositioningRuler(this);
00472     connect(d->ruler, SIGNAL(rulersMoved(int, int, int)), this, SLOT(rulersMoved(int, int, int)));
00473     d->extLayout->addWidget(d->ruler);
00474 
00475     connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged()));
00476     themeChanged();
00477 }
00478 
00479 PanelController::~PanelController()
00480 {
00481     //TODO: should we try and only call this when something has actually been
00482     //      altered that we care about?
00483     PlasmaApp::self()->corona()->requestConfigSync();
00484     delete d->optionsDialog;
00485     d->optionsDialog = 0;
00486     delete d;
00487 }
00488 
00489 void PanelController::setContainment(Plasma::Containment *containment)
00490 {
00491     if (!containment) {
00492         return;
00493     }
00494 
00495     d->containment = containment;
00496 
00497     QWidget *child;
00498     while (!d->actionWidgets.isEmpty()) {
00499         child = d->actionWidgets.first();
00500         //try to remove from both layouts
00501         d->layout->removeWidget(child);
00502         d->optDialogLayout->removeWidget(child);
00503         d->actionWidgets.removeFirst();
00504         child->deleteLater();
00505     }
00506 
00507     int insertIndex = d->layout->count() - 3;
00508 
00509     QAction *action = containment->action("add widgets");
00510     if (action) {
00511         ToolButton *addWidgetTool = d->addTool(action, this);
00512         d->layout->insertWidget(insertIndex, addWidgetTool);
00513         ++insertIndex;
00514         connect(addWidgetTool, SIGNAL(clicked()), this, SLOT(hide()));
00515     }
00516 
00517     action = containment->action("lock widgets");
00518     if (action) {
00519         ToolButton *lockWidgetsTool = d->addTool(action, this);
00520         d->layout->insertWidget(insertIndex, lockWidgetsTool);
00521         ++insertIndex;
00522         connect(lockWidgetsTool, SIGNAL(clicked()), this, SLOT(hide()));
00523     }
00524 
00525     action = containment->action("remove");
00526     if (action) {
00527         ToolButton *removePanelTool = d->addTool(action, this);
00528         removePanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00529         d->optDialogLayout->insertWidget(insertIndex, removePanelTool);
00530         connect(removePanelTool, SIGNAL(clicked()), this, SLOT(hide()));
00531     }
00532 
00533     d->syncRuler();
00534 }
00535 
00536 QSize PanelController::sizeHint() const
00537 {
00538     QRect screenGeom =
00539         Kephal::ScreenUtils::screenGeometry(d->containment->screen());
00540 
00541     switch (d->location) {
00542     case Plasma::LeftEdge:
00543     case Plasma::RightEdge:
00544         return QSize(QWidget::sizeHint().width(), screenGeom.height());
00545         break;
00546     case Plasma::TopEdge:
00547     case Plasma::BottomEdge:
00548     default:
00549         return QSize(screenGeom.width(), QWidget::sizeHint().height());
00550         break;
00551     }
00552 }
00553 
00554 QPoint PanelController::positionForPanelGeometry(const QRect &panelGeom) const
00555 {
00556     QRect screenGeom =
00557         Kephal::ScreenUtils::screenGeometry(d->containment->screen());
00558 
00559     switch (d->location) {
00560     case Plasma::LeftEdge:
00561         return QPoint(panelGeom.right(), screenGeom.top());
00562         break;
00563     case Plasma::RightEdge:
00564         return QPoint(panelGeom.left() - width(), screenGeom.top());
00565         break;
00566     case Plasma::TopEdge:
00567         return QPoint(screenGeom.left(), panelGeom.bottom());
00568         break;
00569     case Plasma::BottomEdge:
00570     default:
00571         return QPoint(screenGeom.left(), panelGeom.top() - height());
00572         break;
00573     }
00574 }
00575 
00576 void PanelController::setLocation(const Plasma::Location &loc)
00577 {
00578     if (d->location == loc) {
00579         return;
00580     }
00581 
00582     d->location = loc;
00583     d->ruler->setLocation(loc);
00584     QRect screenGeom =
00585         Kephal::ScreenUtils::screenGeometry(d->containment->screen());
00586 
00587     switch (loc) {
00588     case Plasma::LeftEdge:
00589         d->layout->setDirection(QBoxLayout::TopToBottom);
00590         //The external layout gwts auto flipped when QApplication::layoutDirection() changes
00591         //and it shouldn't, the internal one no and it should, so i must manually invert both
00592         if (QApplication::layoutDirection() == Qt::RightToLeft) {
00593             d->extLayout->setDirection(QBoxLayout::LeftToRight);
00594         } else {
00595             d->extLayout->setDirection(QBoxLayout::RightToLeft);
00596         }
00597         d->background->setEnabledBorders(Plasma::FrameSvg::RightBorder);
00598         d->extLayout->setContentsMargins(0, 0, d->background->marginSize(Plasma::RightMargin), 0);
00599 
00600         break;
00601     case Plasma::RightEdge:
00602         d->layout->setDirection(QBoxLayout::TopToBottom);
00603         if (QApplication::layoutDirection() == Qt::RightToLeft) {
00604             d->extLayout->setDirection(QBoxLayout::RightToLeft);
00605         } else {
00606             d->extLayout->setDirection(QBoxLayout::LeftToRight);
00607         }
00608         d->background->setEnabledBorders(Plasma::FrameSvg::LeftBorder);
00609         d->extLayout->setContentsMargins(d->background->marginSize(Plasma::LeftMargin), 0, 0, 0);
00610 
00611         break;
00612     case Plasma::TopEdge:
00613         if (QApplication::layoutDirection() == Qt::RightToLeft) {
00614             d->layout->setDirection(QBoxLayout::RightToLeft);
00615         } else {
00616             d->layout->setDirection(QBoxLayout::LeftToRight);
00617         }
00618         d->extLayout->setDirection(QBoxLayout::BottomToTop);
00619         d->background->setEnabledBorders(Plasma::FrameSvg::BottomBorder);
00620         d->extLayout->setContentsMargins(0, 0, 0, d->background->marginSize(Plasma::BottomMargin));
00621 
00622         break;
00623     case Plasma::BottomEdge:
00624     default:
00625         if (QApplication::layoutDirection() == Qt::RightToLeft) {
00626             d->layout->setDirection(QBoxLayout::RightToLeft);
00627         } else {
00628             d->layout->setDirection(QBoxLayout::LeftToRight);
00629         }
00630         d->extLayout->setDirection(QBoxLayout::TopToBottom);
00631         d->background->setEnabledBorders(Plasma::FrameSvg::TopBorder);
00632         d->extLayout->setContentsMargins(0, d->background->marginSize(Plasma::TopMargin), 0, 0);
00633 
00634         break;
00635     }
00636 
00637     switch (loc) {
00638     case Plasma::LeftEdge:
00639     case Plasma::RightEdge:
00640         d->sizeTool->setCursor(Qt::SizeHorCursor);
00641         d->sizeTool->setText(i18n("Width"));
00642         d->sizeTool->setIcon(d->iconSvg->pixmap("size-horizontal"));
00643         d->expandTool->setIcon(d->iconSvg->pixmap("size-vertical"));
00644         d->leftAlignTool->setText(i18n("Top"));
00645         d->rightAlignTool->setText(i18n("Bottom"));
00646 
00647         d->ruler->setAvailableLength(screenGeom.height());
00648 
00649         break;
00650     case Plasma::TopEdge:
00651     case Plasma::BottomEdge:
00652     default:
00653         d->sizeTool->setCursor(Qt::SizeVerCursor);
00654         d->sizeTool->setText(i18n("Height"));
00655         d->sizeTool->setIcon(d->iconSvg->pixmap("size-vertical"));
00656         d->expandTool->setIcon(d->iconSvg->pixmap("size-horizontal"));
00657         d->leftAlignTool->setText(i18n("Left"));
00658         d->rightAlignTool->setText(i18n("Right"));
00659 
00660         d->ruler->setAvailableLength(screenGeom.width());
00661     }
00662 
00663     d->ruler->setMaximumSize(d->ruler->sizeHint());
00664 
00665     d->syncRuler();
00666 }
00667 
00668 Plasma::Location PanelController::location() const
00669 {
00670     return d->location;
00671 }
00672 
00673 void PanelController::setOffset(int newOffset)
00674 {
00675     if (newOffset != d->ruler->offset()) {
00676         d->ruler->setOffset(newOffset);
00677     }
00678 }
00679 
00680 int PanelController::offset() const
00681 {
00682     return d->ruler->offset();
00683 }
00684 
00685 void PanelController::setAlignment(const Qt::Alignment &newAlignment)
00686 {
00687     if (newAlignment != d->ruler->alignment()) {
00688         if (newAlignment == Qt::AlignLeft) {
00689             d->leftAlignTool->setChecked(true);
00690         } else if (newAlignment == Qt::AlignCenter) {
00691             d->centerAlignTool->setChecked(true);
00692         } else if (newAlignment == Qt::AlignRight) {
00693             d->rightAlignTool->setChecked(true);
00694         }
00695 
00696         d->ruler->setAlignment(newAlignment);
00697     }
00698 }
00699 
00700 Qt::Alignment PanelController::alignment() const
00701 {
00702     return d->ruler->alignment();
00703 }
00704 
00705 void PanelController::setVisibilityMode(PanelView::VisibilityMode mode)
00706 {
00707     switch (mode) {
00708     case PanelView::AutoHide:
00709         d->autoHideTool->setChecked(true);
00710         break;
00711     case PanelView::LetWindowsCover:
00712         d->underWindowsTool->setChecked(true);
00713         break;
00714     case PanelView::NormalPanel:
00715     default:
00716         d->normalPanelTool->setChecked(true);
00717         break;
00718     }
00719 }
00720 
00721 PanelView::VisibilityMode PanelController::panelVisibilityMode() const
00722 {
00723     if (d->underWindowsTool->isChecked()) {
00724         return PanelView::LetWindowsCover;
00725     } else if (d->autoHideTool->isChecked()) {
00726         return PanelView::AutoHide;
00727     } else {
00728         return PanelView::NormalPanel;
00729     }
00730 }
00731 
00732 void PanelController::themeChanged()
00733 {
00734     QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
00735     QPalette p = d->alignLabel->palette();
00736     p.setColor(QPalette::Normal, QPalette::WindowText, color);
00737     p.setColor(QPalette::Inactive, QPalette::WindowText, color);
00738     d->alignLabel->setPalette(p);
00739     d->modeLabel->setPalette(p);
00740 
00741     d->sizeTool->setIcon(d->iconSvg->pixmap("move"));
00742 
00743     switch (d->location) {
00744         case Plasma::LeftEdge:
00745         case Plasma::RightEdge:
00746             d->sizeTool->setIcon(d->iconSvg->pixmap("size-horizontal"));
00747             break;
00748         case Plasma::TopEdge:
00749         case Plasma::BottomEdge:
00750         default:
00751             d->sizeTool->setIcon(d->iconSvg->pixmap("size-vertical"));
00752     }
00753 }
00754 
00755 void PanelController::paintEvent(QPaintEvent *event)
00756 {
00757     Q_UNUSED(event)
00758 
00759     QPainter painter(this);
00760     painter.setCompositionMode(QPainter::CompositionMode_Source );
00761 
00762     d->background->resizeFrame(size());
00763     d->background->paintFrame(&painter);
00764 }
00765 
00766 bool PanelController::eventFilter(QObject *watched, QEvent *event)
00767 {
00768     if (watched == d->optionsDialog && event->type() == QEvent::WindowDeactivate) {
00769         if (!d->settingsTool->underMouse()) {
00770             d->optionsDialog->hide();
00771         }
00772         if (!isActiveWindow()) {
00773             close();
00774         }
00775         return true;
00776     } else if (watched == d->moveTool) {
00777         if (event->type() == QEvent::MouseButtonPress) {
00778             d->dragging = Private::MoveButtonElement;
00779         } else if (event->type() == QEvent::MouseButtonRelease) {
00780             d->dragging = Private::NoElement;
00781         } else if (event->type() == QEvent::MouseMove) {
00782             QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
00783             mouseMoveFilter(mouseEvent);
00784         }
00785     } else if (watched == d->sizeTool) {
00786         if (event->type() == QEvent::MouseButtonPress) {
00787             QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
00788             d->startDragPos = mouseEvent->pos();
00789             d->dragging = Private::ResizeButtonElement;
00790         } else if (event->type() == QEvent::MouseButtonRelease) {
00791             //resets properties saved during the drag
00792             d->startDragPos = QPoint(0, 0);
00793             d->dragging = Private::NoElement;
00794             setCursor(Qt::ArrowCursor);
00795         } else if (event->type() == QEvent::MouseMove) {
00796             QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
00797             mouseMoveFilter(mouseEvent);
00798         }
00799     }
00800 
00801     return false;
00802 }
00803 
00804 void PanelController::mouseMoveFilter(QMouseEvent *event)
00805 {
00806     if (d->dragging == Private::NoElement || !d->containment) {
00807         return;
00808     }
00809 
00810     QRect screenGeom = Kephal::ScreenUtils::screenGeometry(d->containment->screen());
00811 
00812     if (d->dragging == Private::MoveButtonElement) {
00813         //only move when the mouse cursor is out of the controller to avoid an endless reposition cycle
00814         if (geometry().contains(event->globalPos())) {
00815             return;
00816         }
00817 
00818         if (!screenGeom.contains(event->globalPos())) {
00819             //move panel to new screen if dragged there
00820             int targetScreen = Kephal::ScreenUtils::screenId(event->globalPos());
00821             //kDebug() << "Moving panel from screen" << d->containment->screen() << "to screen" << targetScreen;
00822             d->containment->setScreen(targetScreen);
00823             return;
00824         }
00825 
00826         //create a dead zone so you can go across the middle without having it hop to one side
00827         float dzFactor = 0.35;
00828         QPoint offset = QPoint(screenGeom.width()*dzFactor,screenGeom.height()*dzFactor);
00829         QRect deadzone = QRect(screenGeom.topLeft()+offset, screenGeom.bottomRight()-offset);
00830         if (deadzone.contains(event->globalPos())) {
00831             //kDebug() << "In the deadzone:" << deadzone;
00832             return;
00833         }
00834 
00835         const Plasma::Location oldLocation = d->containment->location();
00836         Plasma::Location newLocation = oldLocation;
00837         float screenAspect = float(screenGeom.height())/screenGeom.width();
00838 
00839         /* Use diagonal lines so we get predictable behavior when moving the panel
00840          * y=topleft.y+(x-topleft.x)*aspectratio   topright < bottomleft
00841          * y=bottomleft.y-(x-topleft.x)*aspectratio   topleft < bottomright
00842          */
00843         if (event->globalY() < screenGeom.y()+(event->globalX()-screenGeom.x())*screenAspect) {
00844             if (event->globalY() < screenGeom.bottomLeft().y()-(event->globalX()-screenGeom.x())*screenAspect) {
00845                 if (d->containment->location() == Plasma::TopEdge) {
00846                     return;
00847                 } else {
00848                     newLocation = Plasma::TopEdge;
00849                 }
00850             } else if (d->containment->location() == Plasma::RightEdge) {
00851                     return;
00852             } else {
00853                 newLocation = Plasma::RightEdge;
00854             }
00855         } else {
00856             if (event->globalY() < screenGeom.bottomLeft().y()-(event->globalX()-screenGeom.x())*screenAspect) {
00857                 if (d->containment->location() == Plasma::LeftEdge) {
00858                     return;
00859                 } else {
00860                     newLocation = Plasma::LeftEdge;
00861                 }
00862             } else if(d->containment->location() == Plasma::BottomEdge) {
00863                     return;
00864             } else {
00865                 newLocation = Plasma::BottomEdge;
00866             }
00867         }
00868 
00869 
00870         //If the orientation changed swap width and height
00871         if (oldLocation != newLocation) {
00872             emit locationChanged(newLocation);
00873         }
00874 
00875         return;
00876     }
00877 
00878     //Resize handle moved
00879     switch (location()) {
00880     case Plasma::LeftEdge: {
00881         int newX = mapToGlobal(event->pos()).x() - d->startDragPos.x();
00882         if (newX - d->minimumHeight > screenGeom.left() &&
00883             newX - screenGeom.left() <= screenGeom.width()/3) {
00884             move(newX, pos().y());
00885             d->resizeFrameHeight(geometry().left() - screenGeom.left());
00886         }
00887         break;
00888     }
00889     case Plasma::RightEdge: {
00890         int newX = mapToGlobal(event->pos()).x() - d->startDragPos.x();
00891         if (newX + width() + d->minimumHeight < screenGeom.right() &&
00892             newX + width() - screenGeom.left() >= 2*(screenGeom.width()/3)) {
00893             move(newX, pos().y());
00894             d->resizeFrameHeight(screenGeom.right() - geometry().right());
00895         }
00896         break;
00897     }
00898     case Plasma::TopEdge: {
00899         int newY = mapToGlobal(event->pos()).y() - d->startDragPos.y();
00900         if ( newY - d->minimumHeight > screenGeom.top() &&
00901              newY - screenGeom.top()<= screenGeom.height()/3) {
00902             move(pos().x(), newY);
00903             d->resizeFrameHeight(geometry().top() - screenGeom.top());
00904         }
00905         break;
00906     }
00907     case Plasma::BottomEdge:
00908     default: {
00909         int newY = mapToGlobal(event->pos()).y() - d->startDragPos.y();
00910         if ( newY + height() + d->minimumHeight < screenGeom.bottom() &&
00911              newY + height() - screenGeom.top() >= 2*(screenGeom.height()/3)) {
00912             move(pos().x(), newY);
00913             d->resizeFrameHeight(screenGeom.bottom() - geometry().bottom());
00914         }
00915         break;
00916     }
00917     }
00918 }
00919 
00920 void PanelController::focusOutEvent(QFocusEvent * event)
00921 {
00922     Q_UNUSED(event)
00923     if (!d->optionsDialog->isActiveWindow()) {
00924         d->optionsDialog->hide();
00925         close();
00926     }
00927 }
00928 
00929 #include "panelcontroller.moc"

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
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
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