24#include "private/dialog_p.h"
27#include <QSvgRenderer>
28#include <QResizeEvent>
35#include <QtGui/QVBoxLayout>
36#include <QtGui/QGraphicsSceneEvent>
37#include <QtGui/QGraphicsView>
38#include <QtGui/QGraphicsWidget>
39#include <QApplication>
40#include <QDesktopWidget>
41#include <QVarLengthArray>
42#include <QGraphicsLayout>
45#include <kwindowsystem.h>
53#include "plasma/private/extender_p.h"
54#include "plasma/private/dialogshadows_p.h"
67void DialogPrivate::scheduleBorderCheck(
bool triggeredByResize)
70 if (triggeredByResize) {
71 resizeChecksWithBorderCheck =
true;
87 moveTimer =
new QTimer(q);
88 moveTimer->setSingleShot(
true);
89 QObject::connect(moveTimer, SIGNAL(timeout()), q, SLOT(checkBorders()));
95void DialogPrivate::themeChanged()
102 q->setAttribute(Qt::WA_NoSystemBackground, !translucency);
108void DialogPrivate::updateMask()
112 translucency ? background->mask() : QRegion());
116 q->setMask(background->mask());
120void DialogPrivate::checkBorders()
125void DialogPrivate::delayedAdjustSize()
127 q->syncToGraphicsWidget();
130void DialogPrivate::checkBorders(
bool updateMaskIfNeeded)
132 if (resizeChecksWithBorderCheck) {
133 background->resizeFrame(q->size());
137 const FrameSvg::EnabledBorders currentBorders = background->enabledBorders();
140 Extender *extender = qobject_cast<Extender*>(graphicsWidget);
146 QDesktopWidget *desktop = QApplication::desktop();
149 c = qobject_cast<Plasma::Corona *>(applet->scene());
150 }
else if (graphicsWidget) {
151 c = qobject_cast<Plasma::Corona *>(graphicsWidget->scene());
157 avail = QRegion(desktop->availableGeometry(desktop->screenNumber(q)));
158 screenGeom = desktop->screenGeometry(desktop->screenNumber(q));
161 QRect dialogGeom = q->geometry();
166 qreal bottomHeight(0);
170 if (applet && !q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) {
171 background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
176 dialogGeom.bottom() + 2 >= screenGeom.bottom() - applet->
containment()->size().height() &&
177 dialogGeom.width() <= applet->
containment()->size().width()) {
178 borders &= ~FrameSvg::BottomBorder;
187 dialogGeom.top() <= screenGeom.top() + applet->
containment()->size().height() &&
188 dialogGeom.width() <= applet->
containment()->size().width()) {
189 borders &= ~FrameSvg::TopBorder;
198 dialogGeom.left() <= screenGeom.left() + applet->
containment()->size().width() &&
199 dialogGeom.height() <= applet->
containment()->size().height()) {
200 borders &= ~FrameSvg::LeftBorder;
208 dialogGeom.right() + 2 >= screenGeom.right() - applet->
containment()->size().width() &&
209 dialogGeom.height() <= applet->
containment()->size().height()) {
210 borders &= ~FrameSvg::RightBorder;
222 if (q->isVisible() && !q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) {
223 if (!avail.contains(QPoint(dialogGeom.left()-1, dialogGeom.center().y()))) {
224 borders &= ~FrameSvg::LeftBorder;
226 if (!avail.contains(QPoint(dialogGeom.center().x(), dialogGeom.top()-1))) {
227 borders &= ~FrameSvg::TopBorder;
230 if (!avail.contains(QPoint(dialogGeom.right()+1, dialogGeom.center().y()))) {
231 borders &= ~FrameSvg::RightBorder;
233 if (!avail.contains(QPoint(dialogGeom.center().x(), dialogGeom.bottom()+1))) {
234 borders &= ~FrameSvg::BottomBorder;
238 background->setEnabledBorders(borders);
239 DialogShadows::self()->addWindow(q, borders);
249 extender->d->setDisabledBordersHint(disabledBorders);
252 qreal left, top, right, bottom;
253 background->getMargins(left, top, right, bottom);
254 if (extender->d->scrollWidget->viewportGeometry().height() < extender->d->scrollWidget->contentsSize().height()) {
255 if (QApplication::layoutDirection() == Qt::RightToLeft) {
262 background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
266 q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
268 if (resizeChecksWithBorderCheck) {
269 updateResizeCorners();
272 }
else if (currentBorders != borders) {
273 if (updateMaskIfNeeded) {
280 resizeChecksWithBorderCheck =
false;
285 d->adjustViewTimer->stop();
288 const int prevStartCorner = d->resizeStartCorner;
289 d->resizeStartCorner = -1;
290 QSize prevSize = size();
299 int left, top, right, bottom;
300 getContentsMargins(&left, &top, &right, &bottom);
302 QDesktopWidget *desktop = QApplication::desktop();
303 QSize maxSize = desktop->availableGeometry(desktop->screenNumber(
this)).size();
305 setMinimumSize(0, 0);
306 setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
308 QSize newSize(qMin(
int(
graphicsWidget->size().width()) + left + right, maxSize.width()),
309 qMin(
int(
graphicsWidget->size().height()) + top + bottom, maxSize.height()));
311 const QSizeF minimum =
graphicsWidget->effectiveSizeHint(Qt::MinimumSize);
312 QSize newMinimumSize(qMin(
int(minimum.width()) + left + right, maxSize.width()),
313 qMin(
int(minimum.height()) + top + bottom, maxSize.height()));
316 QSize newMaximumSize(qMin(
int(
graphicsWidget->maximumSize().width()) + left + right, maxSize.width()),
317 qMin(
int(
graphicsWidget->maximumSize().height()) + top + bottom, maxSize.height()));
322 QRect currentGeometry(geometry());
323 currentGeometry.setSize(newSize);
326 currentGeometry.setSize(newSize);
328 currentGeometry.moveTopRight(geometry().topRight());
331 currentGeometry.moveBottomLeft(geometry().bottomLeft());
333 setGeometry(currentGeometry);
338 setMinimumSize(newMinimumSize);
339 setMaximumSize(newMaximumSize);
348 sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
349 sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
350 d->view->setSceneRect(sceneRect);
355 if (size() != prevSize) {
360 d->resizeStartCorner = prevStartCorner;
364int DialogPrivate::calculateWidthForHeightAndRatio(
int height, qreal ratio)
366 switch (aspectRatioMode) {
368 return qRound(height * ratio);
382 :
QWidget(parent, f | Qt::FramelessWindowHint),
383 d(new DialogPrivate(this))
385 setMouseTracking(
true);
386 setAttribute(Qt::WA_TranslucentBackground);
388 d->background->setImagePath(
"dialogs/background");
390 d->background->resizeFrame(size());
391 connect(d->background, SIGNAL(repaintNeeded()),
this, SLOT(themeChanged()));
393 QPalette pal = palette();
394 pal.setColor(backgroundRole(), Qt::transparent);
398 d->adjustViewTimer =
new QTimer(
this);
399 d->adjustViewTimer->setSingleShot(
true);
402 d->adjustSizeTimer =
new QTimer(
this);
403 d->adjustSizeTimer->setSingleShot(
true);
404 connect(d->adjustSizeTimer, SIGNAL(timeout()),
this, SLOT(delayedAdjustSize()));
411 DialogShadows::self()->removeWindow(
this);
418 p.setCompositionMode(QPainter::CompositionMode_Source);
419 d->background->paintFrame(&p, e->rect(), e->rect());
424 if (
event->modifiers() == Qt::AltModifier) {
427 setCursor(Qt::SizeBDiagCursor);
429 setCursor(Qt::SizeFDiagCursor);
431 setCursor(Qt::SizeFDiagCursor);
433 setCursor(Qt::SizeBDiagCursor);
434 }
else if (!(
event->buttons() & Qt::LeftButton)) {
444 qreal aspectRatio = (qreal)width() / (qreal)height();
446 switch(d->resizeStartCorner) {
448 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() -
event->y()));
449 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
450 if (newWidth == -1) {
451 newWidth = qMin(maximumWidth(), qMax(minimumWidth(),
event->x()));
453 position = QPoint(x(), y() + height() - newHeight);
456 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() -
event->y()));
457 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
458 if (newWidth == -1) {
459 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() -
event->x()));
461 position = QPoint(x() + width() - newWidth, y() + height() - newHeight);
464 newHeight = qMin(maximumHeight(), qMax(minimumHeight(),
event->y()));
465 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
466 if (newWidth == -1) {
467 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() -
event->x()));
469 position = QPoint(x() + width() - newWidth, y());
472 newHeight = qMin(maximumHeight(), qMax(minimumHeight(),
event->y()));
473 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
474 if (newWidth == -1) {
475 newWidth = qMin(maximumWidth(), qMax(minimumWidth(),
event->x()));
477 position = QPoint(x(), y());
480 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height()));
481 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
482 if (newWidth == -1) {
483 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width()));
485 position = QPoint(x(), y());
489 QRect newGeom(position, QSize(newWidth, newHeight));
492 if (d->leftResizeMin > -1 && newGeom.left() > d->leftResizeMin) {
493 newGeom.setLeft(d->leftResizeMin);
496 if (d->topResizeMin > -1 && newGeom.top() > d->topResizeMin) {
497 newGeom.setTop(d->topResizeMin);
500 if (d->rightResizeMin > -1 && newGeom.right() < d->rightResizeMin) {
501 newGeom.setRight(d->rightResizeMin);
504 if (d->bottomResizeMin > -1 && newGeom.bottom() < d->bottomResizeMin) {
505 newGeom.setBottom(d->bottomResizeMin);
508 if ((newGeom.width() >= minimumSize().width()) && (newGeom.height() >= minimumSize().height())) {
509 setGeometry(newGeom);
513 QWidget::mouseMoveEvent(
event);
530 QWidget::mousePressEvent(
event);
541 QWidget::mouseReleaseEvent(
event);
546 if (
event->key() == Qt::Key_Escape) {
553 return QWidget::event(
event);
560 d->scheduleBorderCheck(
true);
562 if (d->resizeStartCorner != -1 && d->view && d->graphicsWidgetPtr) {
567 sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
568 sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
569 d->view->setSceneRect(sceneRect);
574void DialogPrivate::updateResizeCorners()
576 const int resizeAreaMargin = 20;
577 const QRect r = q->rect();
578 const FrameSvg::EnabledBorders borders = background->enabledBorders();
589 resizeAreaMargin, resizeAreaMargin);
595 resizeAreas[
Dialog::NorthWest] = QRect(0, 0, resizeAreaMargin, resizeAreaMargin);
602 r.bottom() - resizeAreaMargin,
603 resizeAreaMargin, resizeAreaMargin);
610 resizeAreaMargin, resizeAreaMargin);
616 if (d->graphicsWidgetPtr) {
617 d->graphicsWidgetPtr.data()->removeEventFilter(
this);
620 d->graphicsWidgetPtr = widget;
623 Plasma::Corona *c = qobject_cast<Plasma::Corona *>(widget->scene());
629 QVBoxLayout *lay =
new QVBoxLayout(
this);
638 d->view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
639 d->view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
640 d->view->setFrameShape(QFrame::NoFrame);
641 d->view->viewport()->setAutoFillBackground(
false);
642 layout()->addWidget(d->view);
645 d->view->setScene(widget->scene());
648 d->view->centerOn(widget);
649 if (widget->layout()) {
650 widget->layout()->activate();
652 static_cast<QGraphicsLayoutItem *
>(widget)->updateGeometry();
653 widget->resize(widget->size().expandedTo(widget->effectiveSizeHint(Qt::MinimumSize)));
659 widget->installEventFilter(
this);
660 d->view->installEventFilter(
this);
670 return d->graphicsWidgetPtr.data();
675 if (d->resizeStartCorner ==
Dialog::NoCorner && watched == d->graphicsWidgetPtr.data() &&
676 (
event->type() == QEvent::GraphicsSceneResize ||
event->type() == QEvent::GraphicsSceneMove)) {
677 d->adjustViewTimer->start(150);
685 if (
event->type() == QEvent::Enter && watched == d->view) {
689 return QWidget::eventFilter(watched,
event);
704 d->updateResizeCorners();
708 ((d->view &&
graphicsWidget->size().toSize() != d->view->size()) ||
709 d->oldGraphicsWidgetMinimumSize !=
graphicsWidget->minimumSize() ||
710 d->oldGraphicsWidgetMaximumSize !=
graphicsWidget->maximumSize())) {
713 d->oldGraphicsWidgetMinimumSize =
graphicsWidget->minimumSize().toSize();
714 d->oldGraphicsWidgetMaximumSize =
graphicsWidget->maximumSize().toSize();
727 DialogShadows::self()->addWindow(
this, d->background->enabledBorders());
748 d->scheduleBorderCheck();
754 d->resizeCorners = corners;
755 d->updateResizeCorners();
761 return d->resizeCorners;
766 return d->resizeStartCorner >
NoCorner;
771 d->leftResizeMin = left;
772 d->topResizeMin = top;
773 d->rightResizeMin = right;
774 d->bottomResizeMin = bottom;
780 *left = d->leftResizeMin;
784 *top = d->topResizeMin;
788 *right = d->rightResizeMin;
792 *bottom = d->bottomResizeMin;
864 foreach (
const QRect &r, d->resizeAreas) {
865 if (r.contains(point)) {
874 return d->aspectRatioMode;
883 d->aspectRatioMode = mode;
Containment * containment() const
virtual Location location() const
Returns the location of the scene which is displaying applet.
A QGraphicsScene for Plasma::Applets.
virtual QRegion availableScreenRegion(int id) const
Returns the available region for a given screen.
virtual QRect screenGeometry(int id) const
Returns the geometry of a given screen.
void addOffscreenWidget(QGraphicsWidget *widget)
Adds a widget in the topleft quadrant in the scene.
void mousePressEvent(QMouseEvent *event)
void setMinimumResizeLimits(int left, int top, int right, int bottom)
Sets the minimum values that each of four sides of the rect may expand to or from.
void moveEvent(QMoveEvent *event)
void keyPressEvent(QKeyEvent *event)
void resizeEvent(QResizeEvent *e)
void mouseReleaseEvent(QMouseEvent *event)
void dialogResized()
Fires when the dialog automatically resizes.
bool isUserResizing() const
void setResizeHandleCorners(ResizeCorners corners)
void setAspectRatioMode(Plasma::AspectRatioMode mode)
Sets the preferred aspect ratio mode for placement and resizing.
void setGraphicsWidget(QGraphicsWidget *widget)
Sets a QGraphicsWidget to be shown as the content in this dialog.
void getMinimumResizeLimits(int *left, int *top, int *right, int *bottom)
Retrives the minimum resize limits for the dialog.
void animatedShow(Plasma::Direction direction)
Causes an animated show; requires compositing to work, otherwise the dialog will simply show.
void showEvent(QShowEvent *event)
void syncToGraphicsWidget()
Adjusts the dialog to the associated QGraphicsWidget's geometry Should not normally need to be called...
void animatedHide(Plasma::Direction direction)
Causes an animated hide; requires compositing to work, otherwise the dialog will simply hide.
void mouseMoveEvent(QMouseEvent *event)
Dialog(QWidget *parent=0, Qt::WindowFlags f=Qt::Window)
void paintEvent(QPaintEvent *e)
Reimplemented from QWidget.
QGraphicsWidget * graphicsWidget()
bool inControlArea(const QPoint &point)
Convenience method to know whether the point is in a control area (e.g.
ResizeCorners resizeCorners() const
Convenience method to get the enabled resize corners.
void dialogVisible(bool status)
Emit a signal when the dialog become visible/invisible.
bool eventFilter(QObject *watched, QEvent *event)
bool event(QEvent *event)
void hideEvent(QHideEvent *event)
void focusInEvent(QFocusEvent *event)
Plasma::AspectRatioMode aspectRatioMode() const
Provides an SVG with borders.
static Theme * defaultTheme()
Singleton pattern accessor.
Q_INVOKABLE bool windowTranslucencyEnabled() const
void enableBlurBehind(WId window, bool enable, const QRegion ®ion)
Instructs the window manager to blur the background in the specified region behind the given window.
void slideWindow(WId id, Plasma::Location location, int offset)
Mark a window as sliding from screen edge.
void overrideShadow(WId window, bool override)
Forbid te windowmanager to automatically generate a shadow for this window.
Namespace for everything in libplasma.
AspectRatioMode
Defines the aspect ratio used when scaling an applet.
@ KeepAspectRatio
The applet keeps a fixed aspect ratio.
@ Square
The applet is always a square.
@ ConstrainedSquare
The applet is no wider (in horizontal formfactors) or no higher (in vertical ones) than a square.
Location
The Location enumeration describes where on screen an element, such as an Applet or its managing cont...
@ LeftEdge
Along the left side of the screen.
@ Desktop
On the planar desktop layer, extending across the full screen from edge to edge.
@ TopEdge
Along the top of the screen.
@ RightEdge
Along the right side of the screen.
@ BottomEdge
Along the bottom of the screen.
Direction
The Direction enumeration describes in which direction, relative to the Applet (and its managing cont...
@ Right
Display to the right.
@ Left
Display to the left.