24 #include "private/dialog_p.h"
27 #include <QSvgRenderer>
28 #include <QResizeEvent>
29 #include <QMouseEvent>
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"
66 void DialogPrivate::scheduleBorderCheck(
bool triggeredByResize)
69 if (triggeredByResize) {
70 resizeChecksWithBorderCheck =
true;
86 moveTimer =
new QTimer(q);
87 moveTimer->setSingleShot(
true);
88 QObject::connect(moveTimer, SIGNAL(timeout()), q, SLOT(checkBorders()));
94 void DialogPrivate::themeChanged()
101 q->setAttribute(Qt::WA_NoSystemBackground, !translucency);
106 void DialogPrivate::updateMask()
110 translucency ? background->mask() : QRegion());
114 q->setMask(background->mask());
118 void DialogPrivate::checkBorders()
123 void DialogPrivate::delayedAdjustSize()
125 q->syncToGraphicsWidget();
128 void DialogPrivate::checkBorders(
bool updateMaskIfNeeded)
130 if (resizeChecksWithBorderCheck) {
131 background->resizeFrame(q->size());
135 const FrameSvg::EnabledBorders currentBorders = background->enabledBorders();
138 Extender *extender = qobject_cast<Extender*>(graphicsWidget);
144 QDesktopWidget *desktop = QApplication::desktop();
148 }
else if (graphicsWidget) {
154 foreach (QRect rect, r.rects()) {
155 if (rect.width() > maxRect.width() && rect.height() > maxRect.height()) {
162 avail = desktop->availableGeometry(desktop->screenNumber(q));
163 screenGeom = desktop->screenGeometry(desktop->screenNumber(q));
166 QRect dialogGeom = q->geometry();
171 qreal bottomHeight(0);
175 background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
177 switch (applet->location()) {
179 if (applet->containment() &&
180 dialogGeom.bottom() + 2 >= screenGeom.bottom() - applet->containment()->size().height() &&
181 dialogGeom.width() <= applet->containment()->size().width()) {
182 borders &= ~FrameSvg::BottomBorder;
190 if (applet->containment() &&
191 dialogGeom.top() <= screenGeom.top() + applet->containment()->size().height() &&
192 dialogGeom.width() <= applet->containment()->size().width()) {
193 borders &= ~FrameSvg::TopBorder;
201 if (applet->containment() &&
202 dialogGeom.left() <= screenGeom.left() + applet->containment()->size().width() &&
203 dialogGeom.height() <= applet->containment()->size().height()) {
204 borders &= ~FrameSvg::LeftBorder;
211 if (applet->containment() &&
212 dialogGeom.right() + 2 >= screenGeom.right() - applet->containment()->size().width() &&
213 dialogGeom.height() <= applet->containment()->size().height()) {
214 borders &= ~FrameSvg::RightBorder;
226 if (q->isVisible()) {
227 if (dialogGeom.left() <= avail.left()) {
228 borders &= ~FrameSvg::LeftBorder;
230 if (dialogGeom.top() <= avail.top()) {
231 borders &= ~FrameSvg::TopBorder;
234 if (dialogGeom.right() + 2 > avail.right()) {
235 borders &= ~FrameSvg::RightBorder;
237 if (dialogGeom.bottom() + 2 > avail.bottom()) {
238 borders &= ~FrameSvg::BottomBorder;
242 background->setEnabledBorders(borders);
252 extender->d->setDisabledBordersHint(disabledBorders);
255 qreal left, top, right, bottom;
256 background->getMargins(left, top, right, bottom);
257 if (extender->d->scrollWidget->viewportGeometry().height() < extender->d->scrollWidget->contentsSize().height()) {
258 if (QApplication::layoutDirection() == Qt::RightToLeft) {
265 background->getMargins(leftWidth, topHeight, rightWidth, bottomHeight);
269 q->setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
271 if (resizeChecksWithBorderCheck) {
272 updateResizeCorners();
275 }
else if (currentBorders != borders) {
276 if (updateMaskIfNeeded) {
283 resizeChecksWithBorderCheck =
false;
288 d->adjustViewTimer->stop();
290 if (d->view && graphicsWidget && d->resizeStartCorner != -1) {
291 const int prevStartCorner = d->resizeStartCorner;
292 d->resizeStartCorner = -1;
293 QSize prevSize = size();
302 int left, top, right, bottom;
303 getContentsMargins(&left, &top, &right, &bottom);
305 QDesktopWidget *desktop = QApplication::desktop();
306 QSize maxSize = desktop->availableGeometry(desktop->screenNumber(
this)).size();
308 graphicsWidget->setMaximumSize(maxSize - QSize(left + right, top + bottom).boundedTo(graphicsWidget->effectiveSizeHint(Qt::MaximumSize).toSize()));
310 setMinimumSize(0, 0);
311 setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
313 QSize newSize(qMin(
int(graphicsWidget->size().width()) + left + right, maxSize.width()),
314 qMin(
int(graphicsWidget->size().height()) + top + bottom, maxSize.height()));
316 const QSizeF minimum = graphicsWidget->effectiveSizeHint(Qt::MinimumSize);
317 QSize newMinimumSize(qMin(
int(minimum.width()) + left + right, maxSize.width()),
318 qMin(
int(minimum.height()) + top + bottom, maxSize.height()));
321 QSize newMaximumSize(qMin(
int(graphicsWidget->maximumSize().width()) + left + right, maxSize.width()),
322 qMin(
int(graphicsWidget->maximumSize().height()) + top + bottom, maxSize.height()));
327 QRect currentGeometry(geometry());
328 currentGeometry.setSize(newSize);
331 currentGeometry.setSize(newSize);
333 currentGeometry.moveTopRight(geometry().topRight());
336 currentGeometry.moveBottomLeft(geometry().bottomLeft());
338 setGeometry(currentGeometry);
343 setMinimumSize(newMinimumSize);
344 setMaximumSize(newMaximumSize);
351 QRectF sceneRect(graphicsWidget->sceneBoundingRect());
353 sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
354 sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
355 d->view->setSceneRect(sceneRect);
358 d->view->centerOn(graphicsWidget);
360 if (size() != prevSize) {
365 d->resizeStartCorner = prevStartCorner;
369 int DialogPrivate::calculateWidthForHeightAndRatio(
int height, qreal ratio)
371 switch (aspectRatioMode) {
373 return qRound(height * ratio);
387 :
QWidget(parent, f | Qt::FramelessWindowHint),
388 d(new DialogPrivate(this))
390 setMouseTracking(
true);
391 setAttribute(Qt::WA_TranslucentBackground);
393 d->background->setImagePath(
"dialogs/background");
395 d->background->resizeFrame(size());
396 connect(d->background, SIGNAL(repaintNeeded()),
this, SLOT(themeChanged()));
398 QPalette pal = palette();
399 pal.setColor(backgroundRole(), Qt::transparent);
403 d->adjustViewTimer =
new QTimer(
this);
404 d->adjustViewTimer->setSingleShot(
true);
407 d->adjustSizeTimer =
new QTimer(
this);
408 d->adjustSizeTimer->setSingleShot(
true);
409 connect(d->adjustSizeTimer, SIGNAL(timeout()),
this, SLOT(delayedAdjustSize()));
422 p.setCompositionMode(QPainter::CompositionMode_Source);
423 d->background->paintFrame(&p, e->rect(), e->rect());
428 if (event->modifiers() == Qt::AltModifier) {
431 setCursor(Qt::SizeBDiagCursor);
433 setCursor(Qt::SizeFDiagCursor);
435 setCursor(Qt::SizeFDiagCursor);
437 setCursor(Qt::SizeBDiagCursor);
438 }
else if (!(event->buttons() & Qt::LeftButton)) {
448 qreal aspectRatio = (qreal)width() / (qreal)height();
450 switch(d->resizeStartCorner) {
452 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() - event->y()));
453 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
454 if (newWidth == -1) {
455 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), event->x()));
457 position = QPoint(x(), y() + height() - newHeight);
460 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height() - event->y()));
461 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
462 if (newWidth == -1) {
463 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() - event->x()));
465 position = QPoint(x() + width() - newWidth, y() + height() - newHeight);
468 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), event->y()));
469 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
470 if (newWidth == -1) {
471 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width() - event->x()));
473 position = QPoint(x() + width() - newWidth, y());
476 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), event->y()));
477 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
478 if (newWidth == -1) {
479 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), event->x()));
481 position = QPoint(x(), y());
484 newHeight = qMin(maximumHeight(), qMax(minimumHeight(), height()));
485 newWidth = d->calculateWidthForHeightAndRatio(newHeight, aspectRatio);
486 if (newWidth == -1) {
487 newWidth = qMin(maximumWidth(), qMax(minimumWidth(), width()));
489 position = QPoint(x(), y());
493 QRect newGeom(position, QSize(newWidth, newHeight));
496 if (d->leftResizeMin > -1 && newGeom.left() > d->leftResizeMin) {
497 newGeom.setLeft(d->leftResizeMin);
500 if (d->topResizeMin > -1 && newGeom.top() > d->topResizeMin) {
501 newGeom.setTop(d->topResizeMin);
504 if (d->rightResizeMin > -1 && newGeom.right() < d->rightResizeMin) {
505 newGeom.setRight(d->rightResizeMin);
508 if (d->bottomResizeMin > -1 && newGeom.bottom() < d->bottomResizeMin) {
509 newGeom.setBottom(d->bottomResizeMin);
512 if ((newGeom.width() >= minimumSize().width()) && (newGeom.height() >= minimumSize().height())) {
513 setGeometry(newGeom);
550 if (event->key() == Qt::Key_Escape) {
564 d->scheduleBorderCheck(
true);
566 if (d->resizeStartCorner != -1 && d->view && d->graphicsWidgetPtr) {
568 graphicsWidget->resize(d->view->size());
570 QRectF sceneRect(graphicsWidget->sceneBoundingRect());
571 sceneRect.setWidth(qMax(qreal(1), sceneRect.width()));
572 sceneRect.setHeight(qMax(qreal(1), sceneRect.height()));
573 d->view->setSceneRect(sceneRect);
574 d->view->centerOn(graphicsWidget);
578 void DialogPrivate::updateResizeCorners()
580 const int resizeAreaMargin = 20;
581 const QRect r = q->rect();
582 const FrameSvg::EnabledBorders borders = background->enabledBorders();
593 resizeAreaMargin, resizeAreaMargin);
599 resizeAreas[
Dialog::NorthWest] = QRect(0, 0, resizeAreaMargin, resizeAreaMargin);
606 r.bottom() - resizeAreaMargin,
607 resizeAreaMargin, resizeAreaMargin);
614 resizeAreaMargin, resizeAreaMargin);
620 if (d->graphicsWidgetPtr) {
621 d->graphicsWidgetPtr.data()->removeEventFilter(
this);
624 d->graphicsWidgetPtr = widget;
633 QVBoxLayout *lay =
new QVBoxLayout(
this);
642 d->view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
643 d->view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
644 d->view->setFrameShape(QFrame::NoFrame);
645 d->view->viewport()->setAutoFillBackground(
false);
646 layout()->addWidget(d->view);
649 d->view->setScene(widget->scene());
652 d->view->centerOn(widget);
653 if (widget->layout()) {
654 widget->layout()->activate();
656 static_cast<QGraphicsLayoutItem *
>(widget)->updateGeometry();
657 widget->resize(widget->size().expandedTo(widget->effectiveSizeHint(Qt::MinimumSize)));
663 widget->installEventFilter(
this);
664 d->view->installEventFilter(
this);
674 return d->graphicsWidgetPtr.data();
679 if (d->resizeStartCorner ==
Dialog::NoCorner && watched == d->graphicsWidgetPtr.data() &&
680 (
event->type() == QEvent::GraphicsSceneResize ||
event->type() == QEvent::GraphicsSceneMove)) {
681 d->adjustViewTimer->start(150);
689 if (event->type() == QEvent::Enter && watched == d->view) {
708 d->updateResizeCorners();
711 if (graphicsWidget &&
712 ((d->view && graphicsWidget->size().toSize() != d->view->size()) ||
713 d->oldGraphicsWidgetMinimumSize != graphicsWidget->minimumSize() ||
714 d->oldGraphicsWidgetMaximumSize != graphicsWidget->maximumSize())) {
717 d->oldGraphicsWidgetMinimumSize = graphicsWidget->minimumSize().toSize();
718 d->oldGraphicsWidgetMaximumSize = graphicsWidget->maximumSize().toSize();
725 if (graphicsWidget) {
726 graphicsWidget->setFocus();
742 if (graphicsWidget) {
743 graphicsWidget->setFocus();
751 d->scheduleBorderCheck();
757 d->resizeCorners = corners;
758 d->updateResizeCorners();
764 return d->resizeCorners;
769 return d->resizeStartCorner >
NoCorner;
774 d->leftResizeMin = left;
775 d->topResizeMin = top;
776 d->rightResizeMin = right;
777 d->bottomResizeMin = bottom;
783 *left = d->leftResizeMin;
787 *top = d->topResizeMin;
791 *right = d->rightResizeMin;
795 *bottom = d->bottomResizeMin;
867 foreach (
const QRect &r, d->resizeAreas) {
868 if (r.contains(point)) {
877 return d->aspectRatioMode;
886 d->aspectRatioMode = mode;
890 #include "dialog.moc"