1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
44 #ifndef QT_NO_GRAPHICSVIEW
46 #include <QtCore/qdebug.h>
47 #include <QtCore/qnumeric.h>
48 #include "qgraphicswidget_p.h"
49 #include "qgraphicslayoutitem_p.h"
50 #include "qgraphicslayout.h"
51 #include "qgraphicsscene_p.h"
52 #include <QtGui/qapplication.h>
53 #include <QtGui/qgraphicsscene.h>
54 #include <QtGui/qstyleoption.h>
55 #include <QtGui/QStyleOptionTitleBar>
56 #include <QtGui/QGraphicsSceneMouseEvent>
57 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
63 void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags)
68 isWidget = 1; // QGraphicsItem::isWidget() returns true.
69 focusNext = focusPrev = q;
70 focusPolicy = Qt::NoFocus;
72 adjustWindowFlags(&wFlags);
76 setParentItemHelper(parentItem, 0, 0);
78 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType));
79 q->setGraphicsItem(q);
81 resolveLayoutDirection();
82 q->unsetWindowFrameMargins();
83 flags |= QGraphicsItem::ItemUsesExtendedStyleOption;
84 flags |= QGraphicsItem::ItemSendsGeometryChanges;
85 if (windowFlags & Qt::Window)
86 flags |= QGraphicsItem::ItemIsPanel;
89 qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const
91 Q_Q(const QGraphicsWidget);
92 int height = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);
93 #if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC)
94 if (qobject_cast<QMacStyle*>(q->style())) {
104 QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate()
106 // Remove any lazily allocated data
108 delete[] windowFrameMargins;
115 Ensures that margins is allocated.
116 This function must be called before any dereferencing.
118 void QGraphicsWidgetPrivate::ensureMargins() const
121 margins = new qreal[4];
122 for (int i = 0; i < 4; ++i)
130 Ensures that windowFrameMargins is allocated.
131 This function must be called before any dereferencing.
133 void QGraphicsWidgetPrivate::ensureWindowFrameMargins() const
135 if (!windowFrameMargins) {
136 windowFrameMargins = new qreal[4];
137 for (int i = 0; i < 4; ++i)
138 windowFrameMargins[i] = 0;
145 Ensures that windowData is allocated.
146 This function must be called before any dereferencing.
148 void QGraphicsWidgetPrivate::ensureWindowData()
151 windowData = new WindowData;
154 void QGraphicsWidgetPrivate::setPalette_helper(const QPalette &palette)
156 if (this->palette == palette && this->palette.resolve() == palette.resolve())
158 updatePalette(palette);
161 void QGraphicsWidgetPrivate::resolvePalette(uint inheritedMask)
163 inheritedPaletteResolveMask = inheritedMask;
164 QPalette naturalPalette = naturalWidgetPalette();
165 QPalette resolvedPalette = palette.resolve(naturalPalette);
166 updatePalette(resolvedPalette);
169 void QGraphicsWidgetPrivate::updatePalette(const QPalette &palette)
171 Q_Q(QGraphicsWidget);
172 // Update local palette setting.
173 this->palette = palette;
175 // Calculate new mask.
176 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
177 inheritedPaletteResolveMask = 0;
178 int mask = palette.resolve() | inheritedPaletteResolveMask;
180 // Propagate to children.
181 for (int i = 0; i < children.size(); ++i) {
182 QGraphicsItem *item = children.at(i);
183 if (item->isWidget()) {
184 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
185 if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
186 w->d_func()->resolvePalette(mask);
188 item->d_ptr->resolvePalette(mask);
193 QEvent event(QEvent::PaletteChange);
194 QApplication::sendEvent(q, &event);
197 void QGraphicsWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)
199 Q_Q(QGraphicsWidget);
200 if ((direction == Qt::RightToLeft) == (testAttribute(Qt::WA_RightToLeft)))
202 q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));
204 // Propagate this change to all children.
205 for (int i = 0; i < children.size(); ++i) {
206 QGraphicsItem *item = children.at(i);
207 if (item->isWidget()) {
208 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
209 if (widget->parentWidget() && !widget->testAttribute(Qt::WA_SetLayoutDirection))
210 widget->d_func()->setLayoutDirection_helper(direction);
214 // Send the notification event to this widget item.
215 QEvent e(QEvent::LayoutDirectionChange);
216 QApplication::sendEvent(q, &e);
219 void QGraphicsWidgetPrivate::resolveLayoutDirection()
221 Q_Q(QGraphicsWidget);
222 if (q->testAttribute(Qt::WA_SetLayoutDirection)) {
225 if (QGraphicsWidget *parentWidget = q->parentWidget()) {
226 setLayoutDirection_helper(parentWidget->layoutDirection());
228 // ### shouldn't the scene have a layoutdirection really? how does
229 // ### QGraphicsWidget get changes from QApplication::layoutDirection?
230 setLayoutDirection_helper(QApplication::layoutDirection());
232 setLayoutDirection_helper(QApplication::layoutDirection());
236 QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const
238 Q_Q(const QGraphicsWidget);
240 if (QGraphicsWidget *parent = q->parentWidget()) {
241 palette = parent->palette();
243 palette = scene->palette();
249 void QGraphicsWidgetPrivate::setFont_helper(const QFont &font)
251 if (this->font == font && this->font.resolve() == font.resolve())
256 void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask)
258 Q_Q(QGraphicsWidget);
259 inheritedFontResolveMask = inheritedMask;
260 if (QGraphicsWidget *p = q->parentWidget())
261 inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask;
262 QFont naturalFont = naturalWidgetFont();
263 QFont resolvedFont = font.resolve(naturalFont);
264 updateFont(resolvedFont);
267 void QGraphicsWidgetPrivate::updateFont(const QFont &font)
269 Q_Q(QGraphicsWidget);
270 // Update the local font setting.
273 // Calculate new mask.
274 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))
275 inheritedFontResolveMask = 0;
276 int mask = font.resolve() | inheritedFontResolveMask;
278 // Propagate to children.
279 for (int i = 0; i < children.size(); ++i) {
280 QGraphicsItem *item = children.at(i);
281 if (item->isWidget()) {
282 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);
283 if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))
284 w->d_func()->resolveFont(mask);
286 item->d_ptr->resolveFont(mask);
293 QEvent event(QEvent::FontChange);
294 QApplication::sendEvent(q, &event);
297 QFont QGraphicsWidgetPrivate::naturalWidgetFont() const
299 Q_Q(const QGraphicsWidget);
300 QFont naturalFont; // ### no application font support
301 if (QGraphicsWidget *parent = q->parentWidget()) {
302 naturalFont = parent->font();
304 naturalFont = scene->font();
306 naturalFont.resolve(0);
310 void QGraphicsWidgetPrivate::initStyleOptionTitleBar(QStyleOptionTitleBar *option)
312 Q_Q(QGraphicsWidget);
314 q->initStyleOption(option);
315 option->rect.setHeight(titleBarHeight(*option));
316 option->titleBarFlags = windowFlags;
317 option->subControls = QStyle::SC_TitleBarCloseButton | QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu;
318 option->activeSubControls = windowData->hoveredSubControl;
319 bool isActive = q->isActiveWindow();
321 option->state |= QStyle::State_Active;
322 option->titleBarState = Qt::WindowActive;
323 option->titleBarState |= QStyle::State_Active;
325 option->state &= ~QStyle::State_Active;
326 option->titleBarState = Qt::WindowNoState;
328 QFont windowTitleFont = QApplication::font("QWorkspaceTitleBar");
329 QRect textRect = q->style()->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, 0);
330 option->text = QFontMetrics(windowTitleFont).elidedText(
331 windowData->windowTitle, Qt::ElideRight, textRect.width());
334 void QGraphicsWidgetPrivate::adjustWindowFlags(Qt::WindowFlags *flags)
336 bool customize = (*flags & (Qt::CustomizeWindowHint
337 | Qt::FramelessWindowHint
338 | Qt::WindowTitleHint
339 | Qt::WindowSystemMenuHint
340 | Qt::WindowMinimizeButtonHint
341 | Qt::WindowMaximizeButtonHint
342 | Qt::WindowContextHelpButtonHint));
344 uint type = (*flags & Qt::WindowType_Mask);
347 else if (type == Qt::Dialog || type == Qt::Sheet)
348 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint;
349 else if (type == Qt::Tool)
350 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;
351 else if (type == Qt::Window || type == Qt::SubWindow)
352 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint
353 | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;
356 void QGraphicsWidgetPrivate::windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event)
358 Q_Q(QGraphicsWidget);
360 if (windowData->grabbedSection != Qt::NoSection) {
361 if (windowData->grabbedSection == Qt::TitleBarArea) {
362 windowData->buttonSunken = false;
363 QStyleOptionTitleBar bar;
364 initStyleOptionTitleBar(&bar);
365 // make sure that the coordinates (rect and pos) we send to the style are positive.
366 bar.rect = q->windowFrameRect().toRect();
367 bar.rect.moveTo(0,0);
368 bar.rect.setHeight(q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &bar));
369 QPointF pos = event->pos();
370 if (windowFrameMargins) {
371 pos.rx() += windowFrameMargins[Left];
372 pos.ry() += windowFrameMargins[Top];
374 bar.subControls = QStyle::SC_TitleBarCloseButton;
375 if (q->style()->subControlRect(QStyle::CC_TitleBar, &bar,
376 QStyle::SC_TitleBarCloseButton,
377 event->widget()).contains(pos.toPoint())) {
381 if (!(static_cast<QGraphicsSceneMouseEvent *>(event)->buttons()))
382 windowData->grabbedSection = Qt::NoSection;
387 void QGraphicsWidgetPrivate::windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event)
389 Q_Q(QGraphicsWidget);
390 if (event->button() != Qt::LeftButton)
394 windowData->startGeometry = q->geometry();
395 windowData->grabbedSection = q->windowFrameSectionAt(event->pos());
397 if (windowData->grabbedSection == Qt::TitleBarArea
398 && windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton) {
399 windowData->buttonSunken = true;
402 event->setAccepted(windowData->grabbedSection != Qt::NoSection);
406 Used to calculate the
408 \a widget should support either hfw or wfh
410 If \a heightForWidth is set to false, this function will query the width for height
411 instead. \a width will then be interpreted as height, \a minh and \a maxh will be interpreted
412 as minimum width and maximum width.
414 static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,
415 const QGraphicsWidget *widget,
416 bool heightForWidth = true)
418 qreal minimumHeightForWidth = -1;
419 const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
420 if (hasHFW == heightForWidth) {
421 minimumHeightForWidth = hasHFW
422 ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()
423 : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, width)).width(); //"width" is here height!
426 const qreal constraint = width;
427 while (maxh - minh > 0.1) {
428 qreal middle = minh + (maxh - minh)/2;
429 // ### really bad, if we are a widget with a layout it will call
430 // layout->effectiveSizeHint(Qt::MiniumumSize), which again will call
431 // sizeHint three times because of how the cache works
433 ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(middle, -1)).height()
434 : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, middle)).width();
435 if (hfw > constraint) {
437 } else if (hfw <= constraint) {
441 minimumHeightForWidth = maxh;
443 return minimumHeightForWidth;
446 static qreal minimumWidthForHeight(qreal height, qreal minw, qreal maxw,
447 const QGraphicsWidget *widget)
449 return minimumHeightForWidth(height, minw, maxw, widget, false);
452 static QSizeF closestAcceptableSize(const QSizeF &proposed,
453 const QGraphicsWidget *widget)
455 const QSizeF current = widget->size();
457 qreal minw = proposed.width();
458 qreal maxw = current.width();
459 qreal minh = proposed.height();
460 qreal maxh = current.height();
462 qreal middlew = maxw;
463 qreal middleh = maxh;
465 min_hfw = minimumHeightForWidth(maxw, minh, maxh, widget);
468 if (maxw - minw < 0.1) {
469 // we still havent found anything, cut off binary search
473 middlew = minw + (maxw - minw)/2.0;
474 middleh = minh + (maxh - minh)/2.0;
476 min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
478 if (min_hfw > middleh) {
481 } else if (min_hfw <= middleh) {
485 } while (maxw != minw);
487 min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);
490 if (min_hfw < maxh) {
491 result = QSizeF(middlew, min_hfw);
493 // Needed because of the cut-off we do above.
494 result = QSizeF(minimumWidthForHeight(maxh, proposed.width(), current.width(), widget), maxh);
499 static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,
500 QRectF *rect, Qt::WindowFrameSection section,
501 const QSizeF &min, const QSizeF &max,
502 const QGraphicsWidget *widget)
504 const QRectF proposedRect = *rect;
505 qreal width = qBound(min.width(), proposedRect.width(), max.width());
506 qreal height = qBound(min.height(), proposedRect.height(), max.height());
508 const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();
509 const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();
511 const bool widthChanged = proposedRect.width() != widget->size().width();
512 const bool heightChanged = proposedRect.height() != widget->size().height();
514 if (hasHFW || hasWFH) {
515 if (widthChanged || heightChanged) {
521 minExtent = min.height();
522 maxExtent = max.height();
524 proposed = proposedRect.height();
527 minExtent = min.width();
528 maxExtent = max.width();
530 proposed = proposedRect.width();
532 if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {
533 QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);
534 width = effectiveSize.width();
535 height = effectiveSize.height();
541 case Qt::LeftSection:
542 rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
543 qRound(width), startGeometry.height());
545 case Qt::TopLeftSection:
546 rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),
547 qRound(width), qRound(height));
550 rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),
551 startGeometry.width(), qRound(height));
553 case Qt::TopRightSection:
554 rect->setTop(rect->bottom() - qRound(height));
555 rect->setWidth(qRound(width));
557 case Qt::RightSection:
558 rect->setWidth(qRound(width));
560 case Qt::BottomRightSection:
561 rect->setWidth(qRound(width));
562 rect->setHeight(qRound(height));
564 case Qt::BottomSection:
565 rect->setHeight(qRound(height));
567 case Qt::BottomLeftSection:
568 rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),
569 qRound(width), qRound(height));
576 void QGraphicsWidgetPrivate::windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event)
578 Q_Q(QGraphicsWidget);
580 if (!(event->buttons() & Qt::LeftButton) || windowData->hoveredSubControl != QStyle::SC_TitleBarLabel)
583 QLineF delta(q->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)), event->pos());
584 QLineF parentDelta(q->mapToParent(delta.p1()), q->mapToParent(delta.p2()));
585 QLineF parentXDelta(q->mapToParent(QPointF(delta.p1().x(), 0)), q->mapToParent(QPointF(delta.p2().x(), 0)));
586 QLineF parentYDelta(q->mapToParent(QPointF(0, delta.p1().y())), q->mapToParent(QPointF(0, delta.p2().y())));
589 switch (windowData->grabbedSection) {
590 case Qt::LeftSection:
591 newGeometry = QRectF(windowData->startGeometry.topLeft()
592 + QPointF(parentXDelta.dx(), parentXDelta.dy()),
593 windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
595 case Qt::TopLeftSection:
596 newGeometry = QRectF(windowData->startGeometry.topLeft()
597 + QPointF(parentDelta.dx(), parentDelta.dy()),
598 windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));
601 newGeometry = QRectF(windowData->startGeometry.topLeft()
602 + QPointF(parentYDelta.dx(), parentYDelta.dy()),
603 windowData->startGeometry.size() - QSizeF(0, delta.dy()));
605 case Qt::TopRightSection:
606 newGeometry = QRectF(windowData->startGeometry.topLeft()
607 + QPointF(parentYDelta.dx(), parentYDelta.dy()),
608 windowData->startGeometry.size() - QSizeF(-delta.dx(), delta.dy()));
610 case Qt::RightSection:
611 newGeometry = QRectF(windowData->startGeometry.topLeft(),
612 windowData->startGeometry.size() + QSizeF(delta.dx(), 0));
614 case Qt::BottomRightSection:
615 newGeometry = QRectF(windowData->startGeometry.topLeft(),
616 windowData->startGeometry.size() + QSizeF(delta.dx(), delta.dy()));
618 case Qt::BottomSection:
619 newGeometry = QRectF(windowData->startGeometry.topLeft(),
620 windowData->startGeometry.size() + QSizeF(0, delta.dy()));
622 case Qt::BottomLeftSection:
623 newGeometry = QRectF(windowData->startGeometry.topLeft()
624 + QPointF(parentXDelta.dx(), parentXDelta.dy()),
625 windowData->startGeometry.size() - QSizeF(delta.dx(), -delta.dy()));
627 case Qt::TitleBarArea:
628 newGeometry = QRectF(windowData->startGeometry.topLeft()
629 + QPointF(parentDelta.dx(), parentDelta.dy()),
630 windowData->startGeometry.size());
636 if (windowData->grabbedSection != Qt::NoSection) {
637 _q_boundGeometryToSizeConstraints(windowData->startGeometry, &newGeometry,
638 windowData->grabbedSection,
639 q->effectiveSizeHint(Qt::MinimumSize),
640 q->effectiveSizeHint(Qt::MaximumSize),
642 q->setGeometry(newGeometry);
646 void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event)
648 Q_Q(QGraphicsWidget);
649 if (!hasDecoration())
654 if (q->rect().contains(event->pos())) {
655 if (windowData->buttonMouseOver || windowData->hoveredSubControl != QStyle::SC_None)
656 windowFrameHoverLeaveEvent(event);
660 bool wasMouseOver = windowData->buttonMouseOver;
661 QRect oldButtonRect = windowData->buttonRect;
662 windowData->buttonRect = QRect();
663 windowData->buttonMouseOver = false;
664 QPointF pos = event->pos();
665 QStyleOptionTitleBar bar;
666 // make sure that the coordinates (rect and pos) we send to the style are positive.
667 if (windowFrameMargins) {
668 pos.rx() += windowFrameMargins[Left];
669 pos.ry() += windowFrameMargins[Top];
671 initStyleOptionTitleBar(&bar);
672 bar.rect = q->windowFrameRect().toRect();
673 bar.rect.moveTo(0,0);
674 bar.rect.setHeight(int(titleBarHeight(bar)));
676 Qt::CursorShape cursorShape = Qt::ArrowCursor;
677 bool needsSetCursorCall = true;
678 switch (q->windowFrameSectionAt(event->pos())) {
679 case Qt::TopLeftSection:
680 case Qt::BottomRightSection:
681 cursorShape = Qt::SizeFDiagCursor;
683 case Qt::TopRightSection:
684 case Qt::BottomLeftSection:
685 cursorShape = Qt::SizeBDiagCursor;
687 case Qt::LeftSection:
688 case Qt::RightSection:
689 cursorShape = Qt::SizeHorCursor;
692 case Qt::BottomSection:
693 cursorShape = Qt::SizeVerCursor;
695 case Qt::TitleBarArea:
696 windowData->buttonRect = q->style()->subControlRect(
697 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarCloseButton, 0);
699 // On mac we should hover if we are in the 'area' of the buttons
700 windowData->buttonRect |= q->style()->subControlRect(
701 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMinButton, 0);
702 windowData->buttonRect |= q->style()->subControlRect(
703 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMaxButton, 0);
705 if (windowData->buttonRect.contains(pos.toPoint()))
706 windowData->buttonMouseOver = true;
710 needsSetCursorCall = false;
714 if (needsSetCursorCall)
715 q->setCursor(cursorShape);
717 // update buttons if we hover over them
718 windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0);
719 if (windowData->hoveredSubControl != QStyle::SC_TitleBarCloseButton)
720 windowData->hoveredSubControl = QStyle::SC_TitleBarLabel;
722 if (windowData->buttonMouseOver != wasMouseOver) {
723 if (!oldButtonRect.isNull())
724 q->update(QRectF(oldButtonRect).translated(q->windowFrameRect().topLeft()));
725 if (!windowData->buttonRect.isNull())
726 q->update(QRectF(windowData->buttonRect).translated(q->windowFrameRect().topLeft()));
730 void QGraphicsWidgetPrivate::windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event)
733 Q_Q(QGraphicsWidget);
734 if (hasDecoration()) {
735 // ### restore the cursor, don't override it
742 bool needsUpdate = false;
743 if (windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton
744 || windowData->buttonMouseOver)
747 // update the hover state (of buttons etc...)
748 windowData->hoveredSubControl = QStyle::SC_None;
749 windowData->buttonMouseOver = false;
750 windowData->buttonRect = QRect();
752 q->update(windowData->buttonRect);
756 bool QGraphicsWidgetPrivate::hasDecoration() const
758 return (windowFlags & Qt::Window) && (windowFlags & Qt::WindowTitleHint);
762 * is called after a reparent has taken place to fix up the focus chain(s)
764 void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene)
766 Q_Q(QGraphicsWidget);
768 Q_ASSERT(focusNext && focusPrev);
770 QGraphicsWidget *n = q; //last one in 'new' list
771 QGraphicsWidget *o = 0; //last one in 'old' list
773 QGraphicsWidget *w = focusNext;
775 QGraphicsWidget *firstOld = 0;
776 bool wasPreviousNew = true;
779 bool isCurrentNew = q->isAncestorOf(w);
781 if (!wasPreviousNew) {
782 n->d_func()->focusNext = w;
783 w->d_func()->focusPrev = n;
786 } else /*if (!isCurrentNew)*/ {
787 if (wasPreviousNew) {
789 o->d_func()->focusNext = w;
790 w->d_func()->focusPrev = o;
797 w = w->d_func()->focusNext;
798 wasPreviousNew = isCurrentNew;
801 // repair the 'old' chain
803 o->d_func()->focusNext = firstOld;
804 firstOld->d_func()->focusPrev = o;
807 // update tabFocusFirst for oldScene if the item is going to be removed from oldScene
809 newScene = newParent->scene();
811 if (oldScene && newScene != oldScene)
812 oldScene->d_func()->tabFocusFirst = (firstOld && firstOld->scene() == oldScene) ? firstOld : 0;
814 QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0;
815 QGraphicsWidget *topLevel = 0;
816 if (topLevelItem && topLevelItem->isWidget())
817 topLevel = static_cast<QGraphicsWidget *>(topLevelItem);
819 if (topLevel && newParent) {
820 QGraphicsWidget *last = topLevel->d_func()->focusPrev;
821 // link last with new chain
822 last->d_func()->focusNext = q;
825 // link last in chain with
826 topLevel->d_func()->focusPrev = n;
827 n->d_func()->focusNext = topLevel;
829 // q is the start of the focus chain
830 n->d_func()->focusNext = q;
836 void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l)
838 delete (this->layout);
841 Q_Q(QGraphicsWidget);
846 qreal QGraphicsWidgetPrivate::width() const
848 Q_Q(const QGraphicsWidget);
849 return q->geometry().width();
852 void QGraphicsWidgetPrivate::setWidth(qreal w)
856 Q_Q(QGraphicsWidget);
857 if (q->geometry().width() == w)
860 q->setGeometry(QRectF(q->x(), q->y(), w, height()));
863 void QGraphicsWidgetPrivate::resetWidth()
865 Q_Q(QGraphicsWidget);
866 q->setGeometry(QRectF(q->x(), q->y(), 0, height()));
869 qreal QGraphicsWidgetPrivate::height() const
871 Q_Q(const QGraphicsWidget);
872 return q->geometry().height();
875 void QGraphicsWidgetPrivate::setHeight(qreal h)
879 Q_Q(QGraphicsWidget);
880 if (q->geometry().height() == h)
883 q->setGeometry(QRectF(q->x(), q->y(), width(), h));
886 void QGraphicsWidgetPrivate::resetHeight()
888 Q_Q(QGraphicsWidget);
889 q->setGeometry(QRectF(q->x(), q->y(), width(), 0));
892 void QGraphicsWidgetPrivate::setGeometryFromSetPos()
896 Q_Q(QGraphicsWidget);
898 // Ensure setGeometry is called (avoid recursion when setPos is
899 // called from within setGeometry).
900 q->setGeometry(QRectF(pos, q->size()));
906 #endif //QT_NO_GRAPHICSVIEW