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>
28
#include <QMouseEvent>
30
#include <QToolButton>
35
#include <KColorUtils>
36
#include <KIconLoader>
38
#include <kwindowsystem.h>
41
#include <Plasma/Containment>
42
#include <Plasma/Corona>
43
#include <Plasma/PaintUtils>
44
#include <Plasma/Theme>
45
#include <Plasma/FrameSvg>
46
#include <Plasma/Dialog>
48
#include "desktopcorona.h"
49
#include "plasmaapp.h"
50
#include "positioningruler.h"
51
#include "toolbutton.h"
52
#include "widgetsexplorer/widgetexplorer.h"
54
class PanelController::ButtonGroup: public QFrame
57
ButtonGroup(QWidget *parent)
60
background = new Plasma::FrameSvg(this);
61
background->setImagePath("widgets/frame");
62
background->setElementPrefix("plain");
65
void paintEvent(QPaintEvent *event)
69
QPainter painter(this);
70
background->resizeFrame(size());
71
background->paintFrame(&painter);
74
Plasma::FrameSvg *background;
79
static const int MINIMUM_HEIGHT = 10;
81
PanelController::PanelController(QWidget* parent)
82
: ControllerWindow(parent),
85
m_dragging(NoElement),
86
m_startDragControllerPos(0,0),
87
m_startDragMousePos(0,0),
96
setAttribute(Qt::WA_TranslucentBackground);
97
QPalette pal = palette();
98
pal.setBrush(backgroundRole(), Qt::transparent);
101
m_iconSvg = new Plasma::Svg(this);
102
m_iconSvg->setImagePath("widgets/configuration-icons");
103
m_iconSvg->setContainsMultipleImages(true);
104
m_iconSvg->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
106
//setWindowFlags(Qt::Popup);
107
//setWindowFlags(Qt::FramelessWindowHint);
108
KWindowSystem::setState(winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky | NET::KeepAbove);
109
setAttribute(Qt::WA_DeleteOnClose);
110
setFocus(Qt::ActiveWindowFocusReason);
113
m_configWidget = new QWidget(this);
114
layout()->addWidget(m_configWidget);
116
m_extLayout = new QBoxLayout(QBoxLayout::TopToBottom, m_configWidget);
117
m_extLayout->setContentsMargins(0, background()->marginSize(Plasma::TopMargin), 0, 0);
119
m_layout = new QBoxLayout(QBoxLayout::LeftToRight);
120
m_layout->setContentsMargins(0, 0, 0, 0);
122
if (QApplication::layoutDirection() == Qt::RightToLeft) {
123
m_layout->setDirection(QBoxLayout::RightToLeft);
125
m_layout->setDirection(QBoxLayout::LeftToRight);
128
m_layout->addStretch();
129
m_extLayout->addLayout(m_layout);
134
//first the container
135
QFrame *alignFrame = new ButtonGroup(m_configWidget);
136
QVBoxLayout *alignLayout = new QVBoxLayout(alignFrame);
138
m_alignLabel = new QLabel(i18n("Panel Alignment"), m_configWidget);
139
alignLayout->addWidget(m_alignLabel);
141
m_leftAlignTool = addTool("format-justify-left", i18n("Left"), alignFrame, Qt::ToolButtonTextBesideIcon, true);
142
m_leftAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
143
alignLayout->addWidget(m_leftAlignTool);
144
m_leftAlignTool->setChecked(true);
145
connect(m_leftAlignTool, SIGNAL(toggled(bool)), this, SLOT(alignToggled(bool)));
147
m_centerAlignTool = addTool("format-justify-center", i18n("Center"), alignFrame, Qt::ToolButtonTextBesideIcon, true);
148
m_centerAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
149
alignLayout->addWidget(m_centerAlignTool);
150
connect(m_centerAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
152
m_rightAlignTool = addTool("format-justify-right", i18n("Right"), alignFrame, Qt::ToolButtonTextBesideIcon, true);
153
m_rightAlignTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
154
alignLayout->addWidget(m_rightAlignTool);
155
connect(m_rightAlignTool, SIGNAL(clicked(bool)), this, SLOT(alignToggled(bool)));
159
//first the container
160
QFrame *modeFrame = new ButtonGroup(m_configWidget);
161
QVBoxLayout *modeLayout = new QVBoxLayout(modeFrame);
163
m_modeLabel = new QLabel(i18n("Visibility"), m_configWidget);
164
modeLayout->addWidget(m_modeLabel);
166
m_normalPanelTool = addTool("layer-visible-on", i18n("Always visible"), modeFrame, Qt::ToolButtonTextBesideIcon, true);
167
m_normalPanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
168
modeLayout->addWidget(m_normalPanelTool);
169
connect(m_normalPanelTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
171
m_autoHideTool = addTool("video-display", i18n("Auto-hide"), modeFrame, Qt::ToolButtonTextBesideIcon, true);
172
m_autoHideTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
173
modeLayout->addWidget(m_autoHideTool);
174
connect(m_autoHideTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
176
m_underWindowsTool = addTool("view-fullscreen", i18n("Windows can cover"), modeFrame, Qt::ToolButtonTextBesideIcon, true);
177
m_underWindowsTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
178
modeLayout->addWidget(m_underWindowsTool);
179
connect(m_underWindowsTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
181
m_overWindowsTool = addTool("view-restore", i18n("Windows go below"), modeFrame, Qt::ToolButtonTextBesideIcon, true);
182
m_overWindowsTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
183
modeLayout->addWidget(m_overWindowsTool);
184
connect(m_overWindowsTool, SIGNAL(toggled(bool)), this, SLOT(panelVisibilityModeChanged(bool)));
186
m_layout->addStretch();
187
m_moveTool = addTool(QString(), i18n("Screen Edge"), m_configWidget);
188
m_moveTool->setIcon(m_iconSvg->pixmap("move"));
189
m_moveTool->installEventFilter(this);
190
m_moveTool->setCursor(Qt::SizeAllCursor);
191
m_moveTool->setToolTip(i18n("Press left mouse button and drag to a screen edge to change panel edge"));
192
m_layout->addWidget(m_moveTool);
194
m_sizeTool = addTool(QString(), i18n("Height"), m_configWidget);
195
m_sizeTool->installEventFilter(this);
196
m_sizeTool->setCursor(Qt::SizeVerCursor);
197
m_sizeTool->setToolTip(i18n("Press left mouse button and drag vertically to change panel height"));
198
m_layout->addWidget(m_sizeTool);
199
m_layout->addStretch();
202
m_layout->addSpacing(20);
204
//Settings popup menu
205
m_settingsTool = addTool("configure", i18n("More Settings"), m_configWidget);
206
m_settingsTool->setToolTip(i18n("Show more options about panel alignment, visibility and other settings"));
207
m_layout->addWidget(m_settingsTool);
208
connect(m_settingsTool, SIGNAL(pressed()), this, SLOT(settingsPopup()));
209
m_optionsDialog = new Plasma::Dialog(0); // don't pass in a parent; breaks with some lesser WMs
210
m_optionsDialog->installEventFilter(this);
211
KWindowSystem::setState(m_optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky | NET::KeepAbove);
212
m_optDialogLayout = new QVBoxLayout(m_optionsDialog);
213
m_optDialogLayout->setMargin(0);
214
m_optDialogLayout->addWidget(alignFrame);
215
m_optDialogLayout->addWidget(modeFrame);
218
m_expandTool = addTool(QString(), i18n("Maximize Panel"), m_configWidget);
219
m_expandTool->setIcon(m_iconSvg->pixmap("size-horizontal"));
220
m_expandTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
221
m_optDialogLayout->addWidget(m_expandTool);
222
connect(m_expandTool, SIGNAL(clicked()), this, SLOT(maximizePanel()));
224
m_closeControllerTool = addTool("window-close", i18n("Close this configuration window"), m_configWidget, Qt::ToolButtonIconOnly, false);
225
m_layout->addWidget(m_closeControllerTool);
226
connect(m_closeControllerTool, SIGNAL(clicked()), this, SLOT(close()));
228
m_ruler = new PositioningRuler(m_configWidget);
229
connect(m_ruler, SIGNAL(rulersMoved(int, int, int)), this, SLOT(rulersMoved(int, int, int)));
230
m_extLayout->addWidget(m_ruler);
232
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged()));
236
PanelController::~PanelController()
238
//TODO: should we try and only call this when something has actually been
239
// altered that we care about?
240
PlasmaApp::self()->corona()->requestConfigSync();
241
delete m_optionsDialog;
244
void PanelController::setContainment(Plasma::Containment *c)
250
ControllerWindow::setContainment(c);
251
PlasmaApp::self()->hideController(containment()->screen());
254
while (!m_actionWidgets.isEmpty()) {
255
child = m_actionWidgets.first();
256
//try to remove from both layouts
257
m_layout->removeWidget(child);
258
m_optDialogLayout->removeWidget(child);
259
m_actionWidgets.removeFirst();
260
child->deleteLater();
263
int insertIndex = m_layout->count() - 3;
265
QAction *action = containment()->action("add widgets");
266
if (action && action->isEnabled()) {
267
ToolButton *addWidgetTool = addTool(action, this);
268
m_layout->insertWidget(insertIndex, addWidgetTool);
270
connect(containment(), SIGNAL(showAddWidgetsInterface(QPointF)), this, SLOT(switchToWidgetExplorer()));
273
action = new QAction(i18n("Add Spacer"), this);
274
ToolButton *addSpaceTool = addTool(action, this);
275
addSpaceTool->setToolTip(i18n("Add a spacer to the panel useful to add some space between two widgets"));
276
m_layout->insertWidget(insertIndex, addSpaceTool);
278
connect(action, SIGNAL(triggered()), this, SLOT(addSpace()));
280
action = containment()->action("lock widgets");
281
if (action && action->isEnabled()) {
282
ToolButton *lockWidgetsTool = addTool(action, this);
283
m_optDialogLayout->addWidget(lockWidgetsTool, m_optDialogLayout->count() - 2);
284
connect(lockWidgetsTool, SIGNAL(clicked()), m_optionsDialog, SLOT(hide()));
285
connect(lockWidgetsTool, SIGNAL(clicked()), this, SLOT(hide()));
288
action = containment()->action("remove");
289
if (action && action->isEnabled()) {
290
ToolButton *removePanelTool = addTool(action, this);
291
removePanelTool->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
292
m_optDialogLayout->insertWidget(insertIndex, removePanelTool);
293
connect(removePanelTool, SIGNAL(clicked()), this, SLOT(hide()));
299
void PanelController::moveEvent(QMoveEvent *event)
301
//FIXME: this is a glorious hack: it causes the window to be positioned correctly after kwin positions it incorrectly.
302
//TODO: the proper way to do is to give a window type specific to the panel controller, that gets positioned correctly
303
if (((location() == Plasma::BottomEdge || location() == Plasma::TopEdge) &&
304
event->oldPos().x() != event->pos().x()) ||
305
((location() == Plasma::LeftEdge || location() == Plasma::RightEdge) &&
306
event->oldPos().y() != event->pos().y())) {
307
emit offsetChanged(m_ruler->offset());
309
ControllerWindow::moveEvent(event);
312
void PanelController::showEvent(QShowEvent *event)
315
setMaximumSize(PlasmaApp::self()->corona()->screenGeometry(containment()->screen()).size());
318
ControllerWindow::showEvent(event);
321
void PanelController::setLocation(const Plasma::Location &loc)
323
if (location() == loc) {
327
ControllerWindow::setLocation(loc);
331
void PanelController::syncToLocation()
333
const Plasma::Location loc = location();
334
m_ruler->setLocation(loc);
336
//The external layout gwts auto flipped when QApplication::layoutDirection() changes
337
//and it shouldn't, the internal one no and it should, so i must manually invert both
339
case Plasma::LeftEdge:
340
if (QApplication::layoutDirection() == Qt::RightToLeft) {
341
m_extLayout->setDirection(QBoxLayout::LeftToRight);
342
m_extLayout->setContentsMargins(background()->marginSize(Plasma::LeftMargin), 0, 0, 0);
345
m_extLayout->setDirection(QBoxLayout::RightToLeft);
346
m_extLayout->setContentsMargins(0, 0, background()->marginSize(Plasma::RightMargin), 0);
348
m_layout->setDirection(QBoxLayout::TopToBottom);
352
case Plasma::RightEdge:
353
if (QApplication::layoutDirection() == Qt::RightToLeft) {
354
m_extLayout->setDirection(QBoxLayout::RightToLeft);
355
m_extLayout->setContentsMargins(0, 0, background()->marginSize(Plasma::RightMargin), 0);
357
m_extLayout->setDirection(QBoxLayout::LeftToRight);
358
m_extLayout->setContentsMargins(background()->marginSize(Plasma::LeftMargin), 0, 0, 0);
360
m_layout->setDirection(QBoxLayout::TopToBottom);
363
case Plasma::TopEdge:
364
if (QApplication::layoutDirection() == Qt::RightToLeft) {
365
m_layout->setDirection(QBoxLayout::RightToLeft);
368
m_layout->setDirection(QBoxLayout::LeftToRight);
370
m_extLayout->setDirection(QBoxLayout::BottomToTop);
371
m_extLayout->setContentsMargins(0, 0, 0, background()->marginSize(Plasma::BottomMargin));
374
case Plasma::BottomEdge:
376
if (QApplication::layoutDirection() == Qt::RightToLeft) {
377
m_layout->setDirection(QBoxLayout::RightToLeft);
380
m_layout->setDirection(QBoxLayout::LeftToRight);
382
m_extLayout->setDirection(QBoxLayout::TopToBottom);
383
m_extLayout->setContentsMargins(0, background()->marginSize(Plasma::TopMargin), 0, 0);
387
const QRect screenGeom = PlasmaApp::self()->corona()->screenGeometry(containment()->screen());
390
case Plasma::LeftEdge:
391
case Plasma::RightEdge:
392
m_sizeTool->setCursor(Qt::SizeHorCursor);
393
m_sizeTool->setText(i18n("Width"));
394
m_sizeTool->setIcon(m_iconSvg->pixmap("size-horizontal"));
395
m_expandTool->setIcon(m_iconSvg->pixmap("size-vertical"));
396
m_leftAlignTool->setText(i18n("Top"));
397
m_rightAlignTool->setText(i18n("Bottom"));
400
case Plasma::TopEdge:
401
case Plasma::BottomEdge:
403
m_sizeTool->setCursor(Qt::SizeVerCursor);
404
m_sizeTool->setText(i18n("Height"));
405
m_sizeTool->setIcon(m_iconSvg->pixmap("size-vertical"));
406
m_expandTool->setIcon(m_iconSvg->pixmap("size-horizontal"));
407
m_leftAlignTool->setText(i18n("Left"));
408
m_rightAlignTool->setText(i18n("Right"));
413
QSize rulerSize = m_ruler->sizeHint();
415
m_ruler->setFixedSize(rulerSize);
419
setMinimumSize(QSize(0, 0));
420
setMaximumSize(sizeHint());
424
void PanelController::setOffset(int newOffset)
426
if (newOffset != m_ruler->offset()) {
427
m_ruler->setOffset(newOffset);
431
int PanelController::offset() const
433
return m_ruler->offset();
436
void PanelController::setAlignment(const Qt::Alignment &newAlignment)
438
if (newAlignment != m_ruler->alignment()) {
439
if (newAlignment == Qt::AlignLeft) {
440
m_leftAlignTool->setChecked(true);
441
} else if (newAlignment == Qt::AlignCenter) {
442
m_centerAlignTool->setChecked(true);
443
} else if (newAlignment == Qt::AlignRight) {
444
m_rightAlignTool->setChecked(true);
447
m_ruler->setAlignment(newAlignment);
451
Qt::Alignment PanelController::alignment() const
453
return m_ruler->alignment();
456
void PanelController::setVisibilityMode(PanelView::VisibilityMode mode)
459
case PanelView::AutoHide:
460
m_autoHideTool->setChecked(true);
462
case PanelView::LetWindowsCover:
463
m_underWindowsTool->setChecked(true);
465
case PanelView::WindowsGoBelow:
466
m_overWindowsTool->setChecked(true);
468
case PanelView::NormalPanel:
470
m_normalPanelTool->setChecked(true);
475
PanelView::VisibilityMode PanelController::panelVisibilityMode() const
477
if (m_underWindowsTool->isChecked()) {
478
return PanelView::LetWindowsCover;
479
} else if (m_overWindowsTool->isChecked()) {
480
return PanelView::WindowsGoBelow;
481
} else if (m_autoHideTool->isChecked()) {
482
return PanelView::AutoHide;
484
return PanelView::NormalPanel;
488
void PanelController::themeChanged()
490
QColor color = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
491
QPalette p = m_alignLabel->palette();
492
p.setColor(QPalette::Normal, QPalette::WindowText, color);
493
p.setColor(QPalette::Inactive, QPalette::WindowText, color);
494
m_alignLabel->setPalette(p);
495
m_modeLabel->setPalette(p);
497
m_sizeTool->setIcon(m_iconSvg->pixmap("move"));
499
if (orientation() == Qt::Horizontal) {
500
m_sizeTool->setIcon(m_iconSvg->pixmap("size-vertical"));
502
m_sizeTool->setIcon(m_iconSvg->pixmap("size-horizontal"));
506
void PanelController::switchToWidgetExplorer()
508
m_configWidget->hide();
509
showWidgetExplorer();
512
void PanelController::switchToController()
514
setGraphicsWidget(0);
515
m_configWidget->show();
519
bool PanelController::eventFilter(QObject *watched, QEvent *event)
521
ControllerWindow::eventFilter(watched, event);
523
if (event->type() == QEvent::MouseButtonPress) {
524
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
525
m_lastPos = mouseEvent->globalPos();
528
if (watched == m_optionsDialog && event->type() == QEvent::WindowDeactivate && (!isControllerViewVisible())) {
529
if (!m_settingsTool->underMouse()) {
530
m_optionsDialog->hide();
533
if (!isActiveWindow()) {
537
} else if (watched == m_moveTool) {
538
if (event->type() == QEvent::MouseButtonPress) {
539
m_dragging = MoveButtonElement;
540
m_moveTool->grabMouse();
541
} else if (event->type() == QEvent::MouseButtonRelease) {
542
m_dragging = NoElement;
543
m_moveTool->releaseMouse();
544
emit locationChanged(location());
545
} else if (event->type() == QEvent::MouseMove) {
546
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
547
mouseMoveFilter(mouseEvent);
549
} else if (watched == m_sizeTool) {
550
if (event->type() == QEvent::MouseButtonPress) {
551
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
552
m_startDragMousePos = mouseEvent->globalPos();
553
m_startDragControllerPos = pos(); // the global position of the controller window
554
m_dragging = ResizeButtonElement;
555
} else if (event->type() == QEvent::MouseButtonRelease) {
556
//resets properties saved during the drag
557
m_startDragMousePos = QPoint(0, 0);
558
m_startDragControllerPos = QPoint(0, 0);
559
m_dragging = NoElement;
560
setCursor(Qt::ArrowCursor);
561
} else if (event->type() == QEvent::MouseMove) {
562
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
563
mouseMoveFilter(mouseEvent);
570
void PanelController::mouseMoveFilter(QMouseEvent *event)
572
if (m_dragging == NoElement || !containment()) {
576
DesktopCorona *corona = PlasmaApp::self()->corona();
577
const QRect screenGeom = corona->screenGeometry(containment()->screen());
579
if (m_dragging == MoveButtonElement) {
581
if (!screenGeom.contains(event->globalPos())) {
582
//move panel to new screen if dragged there
583
int targetScreen = corona->screenId(event->globalPos());
585
//kDebug() << "Moving panel from screen" << containment()->screen() << "to screen" << targetScreen;
586
containment()->setScreen(targetScreen);
590
if (location() == Plasma::BottomEdge || location() == Plasma::TopEdge) {
591
emit partialMove(QPoint(0, m_lastPos.y() - event->globalY()));
592
} else if (location() == Plasma::LeftEdge || location() == Plasma::RightEdge) {
593
emit partialMove(QPoint(m_lastPos.x() - event->globalX(), 0));
595
m_lastPos = event->globalPos();
597
//create a dead zone so you can go across the middle without having it hop to one side
598
float dzFactor = 0.35;
599
QPoint offset = QPoint(screenGeom.width()*dzFactor,screenGeom.height()*dzFactor);
600
QRect deadzone = QRect(screenGeom.topLeft()+offset, screenGeom.bottomRight()-offset);
601
if (deadzone.contains(event->globalPos())) {
602
//kDebug() << "In the deadzone:" << deadzone;
606
const Plasma::Location oldLocation = containment()->location();
607
Plasma::Location newLocation = oldLocation;
608
float screenAspect = float(screenGeom.height())/screenGeom.width();
610
/* Use diagonal lines so we get predictable behavior when moving the panel
611
* y=topleft.y+(x-topleft.x)*aspectratio topright < bottomleft
612
* y=bottomleft.y-(x-topleft.x)*aspectratio topleft < bottomright
614
if (event->globalY() < screenGeom.y()+(event->globalX()-screenGeom.x())*screenAspect) {
615
if (event->globalY() < screenGeom.bottomLeft().y()-(event->globalX()-screenGeom.x())*screenAspect) {
616
if (containment()->location() == Plasma::TopEdge) {
619
newLocation = Plasma::TopEdge;
621
} else if (containment()->location() == Plasma::RightEdge) {
624
newLocation = Plasma::RightEdge;
627
if (event->globalY() < screenGeom.bottomLeft().y()-(event->globalX()-screenGeom.x())*screenAspect) {
628
if (containment()->location() == Plasma::LeftEdge) {
631
newLocation = Plasma::LeftEdge;
633
} else if(containment()->location() == Plasma::BottomEdge) {
636
newLocation = Plasma::BottomEdge;
641
//If the orientation changed swap width and height
642
if (oldLocation != newLocation) {
643
emit locationChanged(newLocation);
649
//Resize handle moved
650
switch (location()) {
651
case Plasma::LeftEdge: {
652
int newX = m_startDragControllerPos.x() + event->globalX() - m_startDragMousePos.x();
653
newX = qMax(newX, screenGeom.left() + MINIMUM_HEIGHT);
654
newX = qMin(newX, screenGeom.left() + screenGeom.width()/3);
655
move(newX, pos().y());
656
resizeFrameHeight(geometry().left() - screenGeom.left());
659
case Plasma::RightEdge: {
660
int newX = m_startDragControllerPos.x() + event->globalX() - m_startDragMousePos.x();
661
newX = qMin(newX, screenGeom.right() - MINIMUM_HEIGHT - width());
662
newX = qMax(newX, screenGeom.left() + 2*(screenGeom.width()/3) - width());
663
move(newX, pos().y());
664
resizeFrameHeight(screenGeom.right() - geometry().right());
667
case Plasma::TopEdge: {
668
int newY = m_startDragControllerPos.y() + event->globalY() - m_startDragMousePos.y();
669
newY = qMax(newY, screenGeom.top() + MINIMUM_HEIGHT);
670
newY = qMin(newY, screenGeom.top() + screenGeom.height()/3);
671
move(pos().x(), newY);
672
resizeFrameHeight(geometry().top() - screenGeom.top());
675
case Plasma::BottomEdge:
677
int newY = m_startDragControllerPos.y() + event->globalY() - m_startDragMousePos.y();
678
newY = qMin(newY, screenGeom.bottom() - MINIMUM_HEIGHT - height());
679
newY = qMax(newY, screenGeom.top() + 2*(screenGeom.height()/3) - height());
680
move(pos().x(), newY);
681
resizeFrameHeight(screenGeom.bottom() - geometry().bottom());
687
void PanelController::focusOutEvent(QFocusEvent * event)
690
if (!m_optionsDialog->isActiveWindow() && !isControllerViewVisible() && !isActiveWindow()) {
691
m_optionsDialog->hide();
696
ToolButton *PanelController::addTool(QAction *action, QWidget *parent, Qt::ToolButtonStyle style)
698
ToolButton *tool = new ToolButton(parent);
699
tool->setToolButtonStyle(style);
700
tool->setAction(action);
701
m_actionWidgets.append(tool);
706
ToolButton *PanelController::addTool(const QString iconName, const QString iconText, QWidget *parent, Qt::ToolButtonStyle style, bool checkButton)
708
//TODO take advantage of setDefaultAction using the containment's actions if possible
709
ToolButton *tool = new ToolButton(parent);
711
KIcon icon = KIcon(iconName);
712
if (!icon.isNull() && !iconName.isNull()) {
716
tool->setText(iconText);
717
tool->setToolButtonStyle(style);
719
if (style == Qt::ToolButtonIconOnly) {
720
tool->setToolTip(iconText);
723
tool->setCheckable(checkButton);
724
tool->setAutoExclusive(checkButton);
729
void PanelController::resizeFrameHeight(const int newHeight)
731
if (!containment()) {
735
switch (location()) {
736
case Plasma::LeftEdge:
737
case Plasma::RightEdge:
738
containment()->setMinimumSize(QSize(newHeight, (int)containment()->minimumSize().height()));
739
containment()->setMaximumSize(QSize(newHeight, (int)containment()->maximumSize().height()));
740
containment()->resize(QSize(newHeight, (int)containment()->size().height()));
742
case Plasma::TopEdge:
743
case Plasma::BottomEdge:
745
containment()->setMinimumSize(QSize((int)containment()->minimumSize().width(), newHeight));
746
containment()->setMaximumSize(QSize((int)containment()->maximumSize().width(), newHeight));
747
containment()->resize(QSize((int)containment()->size().width(), newHeight));
752
void PanelController::rulersMoved(int offset, int minLength, int maxLength)
754
if (!containment()) {
758
QSize preferredSize(containment()->preferredSize().toSize());
760
switch (location()) {
761
case Plasma::LeftEdge:
762
case Plasma::RightEdge:
763
containment()->resize(QSize((int)containment()->size().width(), qBound(minLength, preferredSize.height(), maxLength)));
764
containment()->setMinimumSize(QSize((int)containment()->minimumSize().width(), minLength));
765
containment()->setMaximumSize(QSize((int)containment()->maximumSize().width(), maxLength));
767
case Plasma::TopEdge:
768
case Plasma::BottomEdge:
770
containment()->resize(QSize(qBound(minLength, preferredSize.width(), maxLength), (int)containment()->size().height()));
771
containment()->setMinimumSize(QSize(minLength, (int)containment()->minimumSize().height()));
772
containment()->setMaximumSize(QSize(maxLength, (int)containment()->maximumSize().height()));
776
emit offsetChanged(offset);
779
void PanelController::alignToggled(bool toggle)
785
if (sender() == m_leftAlignTool) {
786
emit alignmentChanged(Qt::AlignLeft);
787
m_ruler->setAlignment(Qt::AlignLeft);
788
} else if (sender() == m_centerAlignTool) {
789
emit alignmentChanged(Qt::AlignCenter);
790
m_ruler->setAlignment(Qt::AlignCenter);
791
} else if (sender() == m_rightAlignTool) {
792
emit alignmentChanged(Qt::AlignRight);
793
m_ruler->setAlignment(Qt::AlignRight);
796
emit offsetChanged(0);
797
m_ruler->setOffset(0);
800
void PanelController::panelVisibilityModeChanged(bool toggle)
806
if (sender() == m_normalPanelTool) {
807
emit panelVisibilityModeChanged(PanelView::NormalPanel);
808
} else if (sender() == m_autoHideTool) {
809
emit panelVisibilityModeChanged(PanelView::AutoHide);
810
} else if (sender() == m_underWindowsTool) {
811
emit panelVisibilityModeChanged(PanelView::LetWindowsCover);
812
} else if (sender() == m_overWindowsTool) {
813
emit panelVisibilityModeChanged(PanelView::WindowsGoBelow);
817
void PanelController::settingsPopup()
819
if (m_optionsDialog->isVisible()) {
820
m_optionsDialog->hide();
822
KWindowSystem::setState(m_optionsDialog->winId(), NET::SkipTaskbar | NET::SkipPager | NET::Sticky | NET::KeepAbove);
823
QPoint pos = mapToGlobal(m_settingsTool->pos());
824
m_optionsDialog->layout()->activate();
825
m_optionsDialog->resize(m_optionsDialog->sizeHint());
826
QSize s = m_optionsDialog->size();
828
switch (location()) {
829
case Plasma::BottomEdge:
830
pos = QPoint(pos.x(), pos.y() - s.height());
832
case Plasma::TopEdge:
833
pos = QPoint(pos.x(), pos.y() + m_settingsTool->size().height());
835
case Plasma::LeftEdge:
836
pos = QPoint(pos.x() + m_settingsTool->size().width(), pos.y());
838
case Plasma::RightEdge:
839
pos = QPoint(pos.x() - s.width(), pos.y());
842
if (pos.y() - s.height() > 0) {
843
pos = QPoint(pos.x(), pos.y() - s.height());
845
pos = QPoint(pos.x(), pos.y() + m_settingsTool->size().height());
849
const QRect screenGeom = PlasmaApp::self()->corona()->screenGeometry(containment()->screen());
851
if (pos.rx() + s.width() > screenGeom.right()) {
852
pos.rx() -= ((pos.rx() + s.width()) - screenGeom.right());
855
if (pos.ry() + s.height() > screenGeom.bottom()) {
856
pos.ry() -= ((pos.ry() + s.height()) - screenGeom.bottom());
859
pos.rx() = qMax(0, pos.rx());
860
m_optionsDialog->move(pos);
861
m_optionsDialog->show();
865
void PanelController::syncRuler()
867
const QRect screenGeom = PlasmaApp::self()->corona()->screenGeometry(containment()->screen());
869
switch (location()) {
870
case Plasma::LeftEdge:
871
case Plasma::RightEdge:
872
m_ruler->setAvailableLength(screenGeom.height());
873
m_ruler->setMaxLength(qMin((int)containment()->maximumSize().height(), screenGeom.height()));
874
m_ruler->setMinLength(containment()->minimumSize().height());
876
case Plasma::TopEdge:
877
case Plasma::BottomEdge:
879
m_ruler->setAvailableLength(screenGeom.width());
880
m_ruler->setMaxLength(qMin((int)containment()->maximumSize().width(), screenGeom.width()));
881
m_ruler->setMinLength(containment()->minimumSize().width());
886
void PanelController::resizeEvent(QResizeEvent *event)
888
bool showText = true;
890
switch (location()) {
891
case Plasma::LeftEdge:
892
case Plasma::RightEdge:
895
case Plasma::TopEdge:
896
case Plasma::BottomEdge:
898
const int screen = containment()->screen();
899
const QRect screenGeom = PlasmaApp::self()->corona()->screenGeometry(screen);
900
QRegion availGeom(screenGeom);
901
if (m_extLayout->sizeHint().width() > screenGeom.width()) {
908
//FIXME: better (and faster) way to do that?
909
for (int i=0; i < m_layout->count(); ++i) {
910
ToolButton *button = qobject_cast<ToolButton *>(m_layout->itemAt(i)->widget());
913
if (showText && button != m_closeControllerTool) {
914
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
916
button->setToolButtonStyle(Qt::ToolButtonIconOnly);
921
ControllerWindow::resizeEvent(event);
924
void PanelController::maximizePanel()
926
const int length = m_ruler->availableLength();
927
const int screen = containment()->screen();
928
const QRect screenGeom = PlasmaApp::self()->corona()->screenGeometry(screen);
929
QRegion availGeom(screenGeom);
930
foreach (PanelView *view, PlasmaApp::self()->panelViews()) {
931
if (view->containment() != containment() &&
932
view->screen() == screen && view->visibilityMode() == PanelView::NormalPanel) {
933
availGeom = availGeom.subtracted(view->geometry());
937
const int w = containment()->size().width();
938
const int h = containment()->size().height();
940
switch (location()) {
941
case Plasma::LeftEdge: {
942
QRect r = availGeom.intersected(QRect(0, 0, w, length)).boundingRect();
947
case Plasma::RightEdge: {
948
QRect r = availGeom.intersected(QRect(screenGeom.right() - w, 0, w, length)).boundingRect();
953
case Plasma::TopEdge: {
954
QRect r = availGeom.intersected(QRect(0, 0, length, h)).boundingRect();
959
case Plasma::BottomEdge:
961
QRect r = availGeom.intersected(QRect(0, screenGeom.bottom() - h, length, h)).boundingRect();
967
rulersMoved(offset, length, length);
968
m_ruler->setMaxLength(length);
969
m_ruler->setMinLength(length);
972
void PanelController::addSpace()
974
Plasma::Applet *spacer = containment()->addApplet("panelspacer_internal");
976
QMetaObject::invokeMethod(spacer, "updateConfigurationMode", Q_ARG(bool, true));
980
#include "panelcontroller.moc"