2 * Copyright 2008 Marco Martin <notmart@gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "panelcontroller.h"
23 #include <QApplication>
25 #include <QVBoxLayout>
26 #include <QDesktopWidget>
29 #include <QMouseEvent>
31 #include <QToolButton>
33 #include <KColorUtils>
34 #include <KIconLoader>
36 #include <KWindowSystem>
38 #include <Plasma/Containment>
39 #include <Plasma/Corona>
40 #include <Plasma/PaintUtils>
41 #include <Plasma/Theme>
42 #include <Plasma/FrameSvg>
43 #include <Plasma/Dialog>
45 #include "plasmaapp.h"
46 #include "positioningruler.h"
47 #include "toolbutton.h"
49 #include <kephal/screens.h>
51 class PanelController::ButtonGroup
: public QFrame
54 ButtonGroup(QWidget
*parent
)
57 background
= new Plasma::FrameSvg(this);
58 background
->setImagePath("widgets/frame");
59 background
->setElementPrefix("plain");
62 void paintEvent(QPaintEvent
*event
)
66 QPainter
painter(this);
67 background
->resizeFrame(size());
68 background
->paintFrame(&painter
);
71 Plasma::FrameSvg
*background
;
75 class PanelController::Private
78 Private(PanelController
*panelControl
)
81 orientation(Qt::Horizontal
),
82 location(Plasma::BottomEdge
),
94 ToolButton
*addTool(QAction
*action
, QWidget
*parent
, Qt::ToolButtonStyle style
= Qt::ToolButtonTextBesideIcon
)
96 ToolButton
*tool
= new ToolButton(parent
);
97 tool
->setToolButtonStyle(style
);
98 tool
->setAction(action
);
99 actionWidgets
.append(tool
);
104 ToolButton
*addTool(const QString iconName
, const QString iconText
, QWidget
*parent
, Qt::ToolButtonStyle style
= Qt::ToolButtonTextBesideIcon
, bool checkButton
= false)
106 //TODO take advantage of setDefaultAction using the containment's actions if possible
107 ToolButton
*tool
= new ToolButton(parent
);
109 KIcon icon
= KIcon(iconName
);
110 if (!icon
.isNull() && !iconName
.isNull()) {
114 tool
->setText(iconText
);
115 tool
->setToolButtonStyle(style
);
117 if (style
== Qt::ToolButtonIconOnly
) {
118 tool
->setToolTip(iconText
);
121 tool
->setCheckable(checkButton
);
122 tool
->setAutoExclusive(checkButton
);
127 void resizeFrameHeight(const int newHeight
)
134 case Plasma::LeftEdge
:
135 case Plasma::RightEdge
:
136 containment
->resize(QSize(newHeight
, (int)containment
->size().height()));
137 containment
->setMinimumSize(QSize(newHeight
, (int)containment
->minimumSize().height()));
138 containment
->setMaximumSize(QSize(newHeight
, (int)containment
->maximumSize().height()));
140 case Plasma::TopEdge
:
141 case Plasma::BottomEdge
:
143 containment
->resize(QSize((int)containment
->size().width(), newHeight
));
144 containment
->setMinimumSize(QSize((int)containment
->minimumSize().width(), newHeight
));
145 containment
->setMaximumSize(QSize((int)containment
->maximumSize().width(), newHeight
));
150 void rulersMoved(int offset
, int minLength
, int maxLength
)
156 QSize
preferredSize(containment
->preferredSize().toSize());
159 case Plasma::LeftEdge
:
160 case Plasma::RightEdge
:
161 containment
->resize(QSize((int)containment
->size().width(), qBound(minLength
, preferredSize
.height(), maxLength
)));
162 containment
->setMinimumSize(QSize((int)containment
->minimumSize().width(), minLength
));
163 containment
->setMaximumSize(QSize((int)containment
->maximumSize().width(), maxLength
));
165 case Plasma::TopEdge
:
166 case Plasma::BottomEdge
:
168 containment
->resize(QSize(qBound(minLength
, preferredSize
.width(), maxLength
), (int)containment
->size().height()));
169 containment
->setMinimumSize(QSize(minLength
, (int)containment
->minimumSize().height()));
170 containment
->setMaximumSize(QSize(maxLength
, (int)containment
->maximumSize().height()));
174 emit q
->offsetChanged(offset
);
177 void alignToggled(bool toggle
)
183 if (q
->sender() == leftAlignTool
) {
184 emit q
->alignmentChanged(Qt::AlignLeft
);
185 ruler
->setAlignment(Qt::AlignLeft
);
186 } else if (q
->sender() == centerAlignTool
) {
187 emit q
->alignmentChanged(Qt::AlignCenter
);
188 ruler
->setAlignment(Qt::AlignCenter
);
189 } else if (q
->sender() == rightAlignTool
) {
190 emit q
->alignmentChanged(Qt::AlignRight
);
191 ruler
->setAlignment(Qt::AlignRight
);
194 emit q
->offsetChanged(0);
198 void panelVisibilityModeChanged(bool toggle
)
204 if (q
->sender() == normalPanelTool
) {
205 emit q
->panelVisibilityModeChanged(PanelView::NormalPanel
);
206 } else if (q
->sender() == autoHideTool
) {
207 emit q
->panelVisibilityModeChanged(PanelView::AutoHide
);
208 } else if (q
->sender() == underWindowsTool
) {
209 emit q
->panelVisibilityModeChanged(PanelView::LetWindowsCover
);
215 if (optionsDialog
->isVisible()) {
216 optionsDialog
->hide();
218 KWindowSystem::setState(optionsDialog
->winId(), NET::SkipTaskbar
| NET::SkipPager
| NET::Sticky
);
219 QPoint pos
= q
->mapToGlobal(settingsTool
->pos());
220 optionsDialog
->layout()->activate();
221 optionsDialog
->resize(optionsDialog
->sizeHint());
222 QSize s
= optionsDialog
->size();
225 case Plasma::BottomEdge
:
226 pos
= QPoint(pos
.x(), pos
.y() - s
.height());
228 case Plasma::TopEdge
:
229 pos
= QPoint(pos
.x(), pos
.y() + settingsTool
->size().height());
231 case Plasma::LeftEdge
:
232 pos
= QPoint(pos
.x() + settingsTool
->size().width(), pos
.y());
234 case Plasma::RightEdge
:
235 pos
= QPoint(pos
.x() - s
.width(), pos
.y());
238 if (pos
.y() - s
.height() > 0) {
239 pos
= QPoint(pos
.x(), pos
.y() - s
.height());
241 pos
= QPoint(pos
.x(), pos
.y() + settingsTool
->size().height());
245 QRect screenRect
= Kephal::ScreenUtils::screenGeometry(containment
->screen());
247 if (pos
.rx() + s
.width() > screenRect
.right()) {
248 pos
.rx() -= ((pos
.rx() + s
.width()) - screenRect
.right());
251 if (pos
.ry() + s
.height() > screenRect
.bottom()) {
252 pos
.ry() -= ((pos
.ry() + s
.height()) - screenRect
.bottom());
255 pos
.rx() = qMax(0, pos
.rx());
256 optionsDialog
->move(pos
);
257 optionsDialog
->show();
264 Kephal::ScreenUtils::screenGeometry(containment
->screen());
267 case Plasma::LeftEdge
:
268 case Plasma::RightEdge
:
269 ruler
->setAvailableLength(screenGeom
.height());
270 ruler
->setMaxLength(qMin((int)containment
->maximumSize().height(), screenGeom
.height()));
271 ruler
->setMinLength(containment
->minimumSize().height());
273 case Plasma::TopEdge
:
274 case Plasma::BottomEdge
:
276 ruler
->setAvailableLength(screenGeom
.width());
277 ruler
->setMaxLength(qMin((int)containment
->maximumSize().width(), screenGeom
.width()));
278 ruler
->setMinLength(containment
->minimumSize().width());
285 const int length
= ruler
->availableLength();
286 rulersMoved(0, length
, length
);
288 ruler
->setMaxLength(length
);
289 ruler
->setMinLength(length
);
292 enum DragElement
{ NoElement
= 0,
298 Plasma::Containment
*containment
;
299 Qt::Orientation orientation
;
300 Plasma::Location location
;
301 QBoxLayout
*extLayout
;
305 DragElement dragging
;
307 Plasma::FrameSvg
*background
;
308 Plasma::Dialog
*optionsDialog
;
309 QBoxLayout
*optDialogLayout
;
310 ToolButton
*settingsTool
;
311 Plasma::Svg
*iconSvg
;
313 ToolButton
*moveTool
;
314 ToolButton
*sizeTool
;
317 ToolButton
*leftAlignTool
;
318 ToolButton
*centerAlignTool
;
319 ToolButton
*rightAlignTool
;
322 ToolButton
*normalPanelTool
;
323 ToolButton
*autoHideTool
;
324 ToolButton
*underWindowsTool
;
325 ToolButton
*expandTool
;
327 //Widgets for actions
328 QList
<QWidget
*> actionWidgets
;
330 PositioningRuler
*ruler
;
334 static const int minimumHeight
= 10;
337 PanelController::PanelController(QWidget
* parent
)
343 QPalette pal
= palette();
344 pal
.setBrush(backgroundRole(), Qt::transparent
);
347 d
->background
= new Plasma::FrameSvg(this);
348 d
->background
->setImagePath("dialogs/background");
349 d
->background
->setContainsMultipleImages(true);
351 d
->iconSvg
= new Plasma::Svg(this);
352 d
->iconSvg
->setImagePath("widgets/configuration-icons");
353 d
->iconSvg
->setContainsMultipleImages(true);
354 d
->iconSvg
->resize(KIconLoader::SizeSmall
, KIconLoader::SizeSmall
);
356 //setWindowFlags(Qt::Popup);
357 setWindowFlags(Qt::FramelessWindowHint
);
358 KWindowSystem::setState(winId(), NET::SkipTaskbar
| NET::SkipPager
| NET::Sticky
);
359 setAttribute(Qt::WA_DeleteOnClose
);
360 setFocus(Qt::ActiveWindowFocusReason
);
363 d
->extLayout
= new QBoxLayout(QBoxLayout::TopToBottom
, this);
364 setLayout(d
->extLayout
);
366 d
->background
->setEnabledBorders(Plasma::FrameSvg::TopBorder
);
367 d
->extLayout
->setContentsMargins(0, d
->background
->marginSize(Plasma::TopMargin
), 0, 0);
369 d
->layout
= new QBoxLayout(QBoxLayout::LeftToRight
);
370 d
->layout
->setContentsMargins(4, 4, 4, 4);
371 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
372 d
->layout
->setDirection(QBoxLayout::RightToLeft
);
374 d
->layout
->setDirection(QBoxLayout::LeftToRight
);
376 d
->layout
->setSpacing(4);
378 d
->layout
->addStretch();
379 d
->extLayout
->addLayout(d
->layout
);
384 //first the container
385 QFrame
*alignFrame
= new ButtonGroup(this);
386 QVBoxLayout
*alignLayout
= new QVBoxLayout(alignFrame
);
389 d
->alignLabel
= new QLabel(i18n("Panel Alignment"), this);
390 alignLayout
->addWidget(d
->alignLabel
);
392 d
->leftAlignTool
= d
->addTool("format-justify-left", i18n("Left"), alignFrame
, Qt::ToolButtonTextBesideIcon
, true);
393 d
->leftAlignTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
394 alignLayout
->addWidget(d
->leftAlignTool
);
395 d
->leftAlignTool
->setChecked(true);
396 connect(d
->leftAlignTool
, SIGNAL(toggled(bool)), this, SLOT(alignToggled(bool)));
398 d
->centerAlignTool
= d
->addTool("format-justify-center", i18n("Center"), alignFrame
, Qt::ToolButtonTextBesideIcon
, true);
399 d
->centerAlignTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
400 alignLayout
->addWidget(d
->centerAlignTool
);
401 connect(d
->centerAlignTool
, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
403 d
->rightAlignTool
= d
->addTool("format-justify-right", i18n("Right"), alignFrame
, Qt::ToolButtonTextBesideIcon
, true);
404 d
->rightAlignTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
405 alignLayout
->addWidget(d
->rightAlignTool
);
406 connect(d
->rightAlignTool
, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
410 //first the container
411 QFrame
*modeFrame
= new ButtonGroup(this);
412 QVBoxLayout
*modeLayout
= new QVBoxLayout(modeFrame
);
414 d
->modeLabel
= new QLabel(i18n("Visibility"), this);
415 modeLayout
->addWidget(d
->modeLabel
);
417 d
->normalPanelTool
= d
->addTool("checkmark", i18n("Always visible"), modeFrame
, Qt::ToolButtonTextBesideIcon
, true);
418 d
->normalPanelTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
419 modeLayout
->addWidget(d
->normalPanelTool
);
420 connect(d
->normalPanelTool
, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
422 d
->autoHideTool
= d
->addTool("video-display", i18n("Auto hide"), modeFrame
, Qt::ToolButtonTextBesideIcon
, true);
423 d
->autoHideTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
424 modeLayout
->addWidget(d
->autoHideTool
);
425 connect(d
->autoHideTool
, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
427 d
->underWindowsTool
= d
->addTool("view-fullscreen", i18n("Windows can cover"), modeFrame
, Qt::ToolButtonTextBesideIcon
, true);
428 d
->underWindowsTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
429 modeLayout
->addWidget(d
->underWindowsTool
);
430 connect(d
->underWindowsTool
, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
432 d
->layout
->addStretch();
433 d
->moveTool
= d
->addTool(QString(), i18n("Screen Edge"), this);
434 d
->moveTool
->setIcon(d
->iconSvg
->pixmap("move"));
435 d
->moveTool
->installEventFilter(this);
436 d
->moveTool
->setCursor(Qt::SizeAllCursor
);
437 d
->layout
->addWidget(d
->moveTool
);
439 d
->sizeTool
= d
->addTool(QString(), i18n("Height"), this);
440 d
->sizeTool
->installEventFilter(this);
441 d
->sizeTool
->setCursor(Qt::SizeVerCursor
);
442 d
->layout
->addWidget(d
->sizeTool
);
443 d
->layout
->addStretch();
446 d
->layout
->addSpacing(20);
448 //Settings popup menu
449 d
->settingsTool
= d
->addTool("configure", i18n("More Settings"), this);
450 d
->layout
->addWidget(d
->settingsTool
);
451 connect(d
->settingsTool
, SIGNAL(pressed()), this, SLOT(settingsPopup()));
452 d
->optionsDialog
= new Plasma::Dialog(0); // don't pass in a parent; breaks with some lesser WMs
453 d
->optionsDialog
->installEventFilter(this);
454 KWindowSystem::setState(d
->optionsDialog
->winId(), NET::SkipTaskbar
| NET::SkipPager
| NET::Sticky
);
455 d
->optDialogLayout
= new QVBoxLayout(d
->optionsDialog
);
456 d
->optDialogLayout
->setMargin(0);
457 d
->optDialogLayout
->addWidget(alignFrame
);
458 d
->optDialogLayout
->addWidget(modeFrame
);
461 d
->expandTool
= d
->addTool(QString(), i18n("Maximize Panel"), this);
462 d
->expandTool
->setIcon(d
->iconSvg
->pixmap("size-horizontal"));
463 d
->expandTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
464 d
->optDialogLayout
->addWidget(d
->expandTool
);
465 connect(d
->expandTool
, SIGNAL(clicked()), this, SLOT(maximizePanel()));
467 ToolButton
*closeControllerTool
= d
->addTool("window-close", i18n("Close this configuration window"), this, Qt::ToolButtonIconOnly
, false);
468 d
->layout
->addWidget(closeControllerTool
);
469 connect(closeControllerTool
, SIGNAL(clicked()), this, SLOT(hide()));
471 d
->ruler
= new PositioningRuler(this);
472 connect(d
->ruler
, SIGNAL(rulersMoved(int, int, int)), this, SLOT(rulersMoved(int, int, int)));
473 d
->extLayout
->addWidget(d
->ruler
);
475 connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged()));
479 PanelController::~PanelController()
481 //TODO: should we try and only call this when something has actually been
482 // altered that we care about?
483 PlasmaApp::self()->corona()->requestConfigSync();
484 delete d
->optionsDialog
;
485 d
->optionsDialog
= 0;
489 void PanelController::setContainment(Plasma::Containment
*containment
)
495 d
->containment
= containment
;
498 while (!d
->actionWidgets
.isEmpty()) {
499 child
= d
->actionWidgets
.first();
500 //try to remove from both layouts
501 d
->layout
->removeWidget(child
);
502 d
->optDialogLayout
->removeWidget(child
);
503 d
->actionWidgets
.removeFirst();
504 child
->deleteLater();
507 int insertIndex
= d
->layout
->count() - 3;
509 QAction
*action
= containment
->action("add widgets");
511 ToolButton
*addWidgetTool
= d
->addTool(action
, this);
512 d
->layout
->insertWidget(insertIndex
, addWidgetTool
);
514 connect(addWidgetTool
, SIGNAL(clicked()), this, SLOT(hide()));
517 action
= containment
->action("lock widgets");
519 ToolButton
*lockWidgetsTool
= d
->addTool(action
, this);
520 d
->layout
->insertWidget(insertIndex
, lockWidgetsTool
);
522 connect(lockWidgetsTool
, SIGNAL(clicked()), this, SLOT(hide()));
525 action
= containment
->action("remove");
527 ToolButton
*removePanelTool
= d
->addTool(action
, this);
528 removePanelTool
->setSizePolicy(QSizePolicy::Expanding
, QSizePolicy::Preferred
);
529 d
->optDialogLayout
->insertWidget(insertIndex
, removePanelTool
);
530 connect(removePanelTool
, SIGNAL(clicked()), this, SLOT(hide()));
536 QSize
PanelController::sizeHint() const
539 Kephal::ScreenUtils::screenGeometry(d
->containment
->screen());
541 switch (d
->location
) {
542 case Plasma::LeftEdge
:
543 case Plasma::RightEdge
:
544 return QSize(QWidget::sizeHint().width(), screenGeom
.height());
546 case Plasma::TopEdge
:
547 case Plasma::BottomEdge
:
549 return QSize(screenGeom
.width(), QWidget::sizeHint().height());
554 QPoint
PanelController::positionForPanelGeometry(const QRect
&panelGeom
) const
557 Kephal::ScreenUtils::screenGeometry(d
->containment
->screen());
559 switch (d
->location
) {
560 case Plasma::LeftEdge
:
561 return QPoint(panelGeom
.right(), screenGeom
.top());
563 case Plasma::RightEdge
:
564 return QPoint(panelGeom
.left() - width(), screenGeom
.top());
566 case Plasma::TopEdge
:
567 return QPoint(screenGeom
.left(), panelGeom
.bottom());
569 case Plasma::BottomEdge
:
571 return QPoint(screenGeom
.left(), panelGeom
.top() - height());
576 void PanelController::setLocation(const Plasma::Location
&loc
)
578 if (d
->location
== loc
) {
583 d
->ruler
->setLocation(loc
);
585 Kephal::ScreenUtils::screenGeometry(d
->containment
->screen());
588 case Plasma::LeftEdge
:
589 d
->layout
->setDirection(QBoxLayout::TopToBottom
);
590 //The external layout gwts auto flipped when QApplication::layoutDirection() changes
591 //and it shouldn't, the internal one no and it should, so i must manually invert both
592 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
593 d
->extLayout
->setDirection(QBoxLayout::LeftToRight
);
595 d
->extLayout
->setDirection(QBoxLayout::RightToLeft
);
597 d
->background
->setEnabledBorders(Plasma::FrameSvg::RightBorder
);
598 d
->extLayout
->setContentsMargins(0, 0, d
->background
->marginSize(Plasma::RightMargin
), 0);
601 case Plasma::RightEdge
:
602 d
->layout
->setDirection(QBoxLayout::TopToBottom
);
603 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
604 d
->extLayout
->setDirection(QBoxLayout::RightToLeft
);
606 d
->extLayout
->setDirection(QBoxLayout::LeftToRight
);
608 d
->background
->setEnabledBorders(Plasma::FrameSvg::LeftBorder
);
609 d
->extLayout
->setContentsMargins(d
->background
->marginSize(Plasma::LeftMargin
), 0, 0, 0);
612 case Plasma::TopEdge
:
613 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
614 d
->layout
->setDirection(QBoxLayout::RightToLeft
);
616 d
->layout
->setDirection(QBoxLayout::LeftToRight
);
618 d
->extLayout
->setDirection(QBoxLayout::BottomToTop
);
619 d
->background
->setEnabledBorders(Plasma::FrameSvg::BottomBorder
);
620 d
->extLayout
->setContentsMargins(0, 0, 0, d
->background
->marginSize(Plasma::BottomMargin
));
623 case Plasma::BottomEdge
:
625 if (QApplication::layoutDirection() == Qt::RightToLeft
) {
626 d
->layout
->setDirection(QBoxLayout::RightToLeft
);
628 d
->layout
->setDirection(QBoxLayout::LeftToRight
);
630 d
->extLayout
->setDirection(QBoxLayout::TopToBottom
);
631 d
->background
->setEnabledBorders(Plasma::FrameSvg::TopBorder
);
632 d
->extLayout
->setContentsMargins(0, d
->background
->marginSize(Plasma::TopMargin
), 0, 0);
638 case Plasma::LeftEdge
:
639 case Plasma::RightEdge
:
640 d
->sizeTool
->setCursor(Qt::SizeHorCursor
);
641 d
->sizeTool
->setText(i18n("Width"));
642 d
->sizeTool
->setIcon(d
->iconSvg
->pixmap("size-horizontal"));
643 d
->expandTool
->setIcon(d
->iconSvg
->pixmap("size-vertical"));
644 d
->leftAlignTool
->setText(i18n("Top"));
645 d
->rightAlignTool
->setText(i18n("Bottom"));
647 d
->ruler
->setAvailableLength(screenGeom
.height());
650 case Plasma::TopEdge
:
651 case Plasma::BottomEdge
:
653 d
->sizeTool
->setCursor(Qt::SizeVerCursor
);
654 d
->sizeTool
->setText(i18n("Height"));
655 d
->sizeTool
->setIcon(d
->iconSvg
->pixmap("size-vertical"));
656 d
->expandTool
->setIcon(d
->iconSvg
->pixmap("size-horizontal"));
657 d
->leftAlignTool
->setText(i18n("Left"));
658 d
->rightAlignTool
->setText(i18n("Right"));
660 d
->ruler
->setAvailableLength(screenGeom
.width());
663 d
->ruler
->setMaximumSize(d
->ruler
->sizeHint());
668 Plasma::Location
PanelController::location() const
673 void PanelController::setOffset(int newOffset
)
675 if (newOffset
!= d
->ruler
->offset()) {
676 d
->ruler
->setOffset(newOffset
);
680 int PanelController::offset() const
682 return d
->ruler
->offset();
685 void PanelController::setAlignment(const Qt::Alignment
&newAlignment
)
687 if (newAlignment
!= d
->ruler
->alignment()) {
688 if (newAlignment
== Qt::AlignLeft
) {
689 d
->leftAlignTool
->setChecked(true);
690 } else if (newAlignment
== Qt::AlignCenter
) {
691 d
->centerAlignTool
->setChecked(true);
692 } else if (newAlignment
== Qt::AlignRight
) {
693 d
->rightAlignTool
->setChecked(true);
696 d
->ruler
->setAlignment(newAlignment
);
700 Qt::Alignment
PanelController::alignment() const
702 return d
->ruler
->alignment();
705 void PanelController::setVisibilityMode(PanelView::VisibilityMode mode
)
708 case PanelView::AutoHide
:
709 d
->autoHideTool
->setChecked(true);
711 case PanelView::LetWindowsCover
:
712 d
->underWindowsTool
->setChecked(true);
714 case PanelView::NormalPanel
:
716 d
->normalPanelTool
->setChecked(true);
721 PanelView::VisibilityMode
PanelController::panelVisibilityMode() const
723 if (d
->underWindowsTool
->isChecked()) {
724 return PanelView::LetWindowsCover
;
725 } else if (d
->autoHideTool
->isChecked()) {
726 return PanelView::AutoHide
;
728 return PanelView::NormalPanel
;
732 void PanelController::themeChanged()
734 QColor color
= Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor
);
735 QPalette p
= d
->alignLabel
->palette();
736 p
.setColor(QPalette::Normal
, QPalette::WindowText
, color
);
737 p
.setColor(QPalette::Inactive
, QPalette::WindowText
, color
);
738 d
->alignLabel
->setPalette(p
);
739 d
->modeLabel
->setPalette(p
);
741 d
->sizeTool
->setIcon(d
->iconSvg
->pixmap("move"));
743 switch (d
->location
) {
744 case Plasma::LeftEdge
:
745 case Plasma::RightEdge
:
746 d
->sizeTool
->setIcon(d
->iconSvg
->pixmap("size-horizontal"));
748 case Plasma::TopEdge
:
749 case Plasma::BottomEdge
:
751 d
->sizeTool
->setIcon(d
->iconSvg
->pixmap("size-vertical"));
755 void PanelController::paintEvent(QPaintEvent
*event
)
759 QPainter
painter(this);
760 painter
.setCompositionMode(QPainter::CompositionMode_Source
);
762 d
->background
->resizeFrame(size());
763 d
->background
->paintFrame(&painter
);
766 bool PanelController::eventFilter(QObject
*watched
, QEvent
*event
)
768 if (watched
== d
->optionsDialog
&& event
->type() == QEvent::WindowDeactivate
) {
769 if (!d
->settingsTool
->underMouse()) {
770 d
->optionsDialog
->hide();
772 if (!isActiveWindow()) {
776 } else if (watched
== d
->moveTool
) {
777 if (event
->type() == QEvent::MouseButtonPress
) {
778 d
->dragging
= Private::MoveButtonElement
;
779 } else if (event
->type() == QEvent::MouseButtonRelease
) {
780 d
->dragging
= Private::NoElement
;
781 } else if (event
->type() == QEvent::MouseMove
) {
782 QMouseEvent
*mouseEvent
= static_cast<QMouseEvent
*>(event
);
783 mouseMoveFilter(mouseEvent
);
785 } else if (watched
== d
->sizeTool
) {
786 if (event
->type() == QEvent::MouseButtonPress
) {
787 QMouseEvent
*mouseEvent
= static_cast<QMouseEvent
*>(event
);
788 d
->startDragPos
= mouseEvent
->pos();
789 d
->dragging
= Private::ResizeButtonElement
;
790 } else if (event
->type() == QEvent::MouseButtonRelease
) {
791 //resets properties saved during the drag
792 d
->startDragPos
= QPoint(0, 0);
793 d
->dragging
= Private::NoElement
;
794 setCursor(Qt::ArrowCursor
);
795 } else if (event
->type() == QEvent::MouseMove
) {
796 QMouseEvent
*mouseEvent
= static_cast<QMouseEvent
*>(event
);
797 mouseMoveFilter(mouseEvent
);
804 void PanelController::mouseMoveFilter(QMouseEvent
*event
)
806 if (d
->dragging
== Private::NoElement
|| !d
->containment
) {
810 QRect screenGeom
= Kephal::ScreenUtils::screenGeometry(d
->containment
->screen());
812 if (d
->dragging
== Private::MoveButtonElement
) {
813 //only move when the mouse cursor is out of the controller to avoid an endless reposition cycle
814 if (geometry().contains(event
->globalPos())) {
818 if (!screenGeom
.contains(event
->globalPos())) {
819 //move panel to new screen if dragged there
820 int targetScreen
= Kephal::ScreenUtils::screenId(event
->globalPos());
821 //kDebug() << "Moving panel from screen" << d->containment->screen() << "to screen" << targetScreen;
822 d
->containment
->setScreen(targetScreen
);
826 //create a dead zone so you can go across the middle without having it hop to one side
827 float dzFactor
= 0.35;
828 QPoint offset
= QPoint(screenGeom
.width()*dzFactor
,screenGeom
.height()*dzFactor
);
829 QRect deadzone
= QRect(screenGeom
.topLeft()+offset
, screenGeom
.bottomRight()-offset
);
830 if (deadzone
.contains(event
->globalPos())) {
831 //kDebug() << "In the deadzone:" << deadzone;
835 const Plasma::Location oldLocation
= d
->containment
->location();
836 Plasma::Location newLocation
= oldLocation
;
837 float screenAspect
= float(screenGeom
.height())/screenGeom
.width();
839 /* Use diagonal lines so we get predictable behavior when moving the panel
840 * y=topleft.y+(x-topleft.x)*aspectratio topright < bottomleft
841 * y=bottomleft.y-(x-topleft.x)*aspectratio topleft < bottomright
843 if (event
->globalY() < screenGeom
.y()+(event
->globalX()-screenGeom
.x())*screenAspect
) {
844 if (event
->globalY() < screenGeom
.bottomLeft().y()-(event
->globalX()-screenGeom
.x())*screenAspect
) {
845 if (d
->containment
->location() == Plasma::TopEdge
) {
848 newLocation
= Plasma::TopEdge
;
850 } else if (d
->containment
->location() == Plasma::RightEdge
) {
853 newLocation
= Plasma::RightEdge
;
856 if (event
->globalY() < screenGeom
.bottomLeft().y()-(event
->globalX()-screenGeom
.x())*screenAspect
) {
857 if (d
->containment
->location() == Plasma::LeftEdge
) {
860 newLocation
= Plasma::LeftEdge
;
862 } else if(d
->containment
->location() == Plasma::BottomEdge
) {
865 newLocation
= Plasma::BottomEdge
;
870 //If the orientation changed swap width and height
871 if (oldLocation
!= newLocation
) {
872 emit
locationChanged(newLocation
);
878 //Resize handle moved
879 switch (location()) {
880 case Plasma::LeftEdge
: {
881 int newX
= mapToGlobal(event
->pos()).x() - d
->startDragPos
.x();
882 if (newX
- d
->minimumHeight
> screenGeom
.left() &&
883 newX
- screenGeom
.left() <= screenGeom
.width()/3) {
884 move(newX
, pos().y());
885 d
->resizeFrameHeight(geometry().left() - screenGeom
.left());
889 case Plasma::RightEdge
: {
890 int newX
= mapToGlobal(event
->pos()).x() - d
->startDragPos
.x();
891 if (newX
+ width() + d
->minimumHeight
< screenGeom
.right() &&
892 newX
+ width() - screenGeom
.left() >= 2*(screenGeom
.width()/3)) {
893 move(newX
, pos().y());
894 d
->resizeFrameHeight(screenGeom
.right() - geometry().right());
898 case Plasma::TopEdge
: {
899 int newY
= mapToGlobal(event
->pos()).y() - d
->startDragPos
.y();
900 if ( newY
- d
->minimumHeight
> screenGeom
.top() &&
901 newY
- screenGeom
.top()<= screenGeom
.height()/3) {
902 move(pos().x(), newY
);
903 d
->resizeFrameHeight(geometry().top() - screenGeom
.top());
907 case Plasma::BottomEdge
:
909 int newY
= mapToGlobal(event
->pos()).y() - d
->startDragPos
.y();
910 if ( newY
+ height() + d
->minimumHeight
< screenGeom
.bottom() &&
911 newY
+ height() - screenGeom
.top() >= 2*(screenGeom
.height()/3)) {
912 move(pos().x(), newY
);
913 d
->resizeFrameHeight(screenGeom
.bottom() - geometry().bottom());
920 void PanelController::focusOutEvent(QFocusEvent
* event
)
923 if (!d
->optionsDialog
->isActiveWindow()) {
924 d
->optionsDialog
->hide();
929 #include "panelcontroller.moc"