qgraphicswidget_p.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/graphicsview/qgraphicswidget_p.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtWidgets module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qglobal.h"-
41-
42#ifndef QT_NO_GRAPHICSVIEW-
43-
44#include <QtCore/qdebug.h>-
45#include <QtCore/qnumeric.h>-
46#include "qgraphicswidget_p.h"-
47#include "qgraphicslayoutitem_p.h"-
48#include "qgraphicslayout.h"-
49#include "qgraphicsscene_p.h"-
50#include <QtWidgets/qapplication.h>-
51#include <QtWidgets/qgraphicsscene.h>-
52#include <QtWidgets/qstyleoption.h>-
53#include <QtWidgets/QStyleOptionTitleBar>-
54#include <QtWidgets/QGraphicsSceneMouseEvent>-
55#if defined(Q_DEAD_CODE_FROM_QT4_MAC) && !defined(QT_NO_STYLE_MAC)-
56# include <private/qmacstyle_mac_p.h>-
57#endif-
58-
59QT_BEGIN_NAMESPACE-
60-
61void QGraphicsWidgetPrivate::init(QGraphicsItem *parentItem, Qt::WindowFlags wFlags)-
62{-
63 Q_Q(QGraphicsWidget);-
64-
65 attributes = 0;-
66 isWidget = 1; // QGraphicsItem::isWidget() returns true.-
67 focusNext = focusPrev = q;-
68 focusPolicy = Qt::NoFocus;-
69-
70 adjustWindowFlags(&wFlags);-
71 windowFlags = wFlags;-
72-
73 q->setParentItem(parentItem);-
74 q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType));-
75 q->setGraphicsItem(q);-
76-
77 resolveLayoutDirection();-
78 q->unsetWindowFrameMargins();-
79 flags |= QGraphicsItem::ItemUsesExtendedStyleOption;-
80 flags |= QGraphicsItem::ItemSendsGeometryChanges;-
81 if (windowFlags & Qt::Window)-
82 flags |= QGraphicsItem::ItemIsPanel;-
83}-
84-
85qreal QGraphicsWidgetPrivate::titleBarHeight(const QStyleOptionTitleBar &options) const-
86{-
87 Q_Q(const QGraphicsWidget);-
88 int height = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options);-
89 return (qreal)height;-
90}-
91-
92/*!-
93 \internal-
94*/-
95QGraphicsWidgetPrivate::QGraphicsWidgetPrivate()-
96 : margins(nullptr),-
97 layout(nullptr),-
98 inheritedPaletteResolveMask(0),-
99 inheritedFontResolveMask(0),-
100 inSetGeometry(false),-
101 polished(false),-
102 inSetPos(false),-
103 autoFillBackground(false),-
104 focusPolicy(Qt::NoFocus),-
105 focusNext(nullptr),-
106 focusPrev(nullptr),-
107 windowFlags(),-
108 windowData(nullptr),-
109 setWindowFrameMargins(false),-
110 windowFrameMargins(nullptr)-
111{-
112}
never executed: end of block
0
113-
114QGraphicsWidgetPrivate::~QGraphicsWidgetPrivate()-
115{-
116 // Remove any lazily allocated data-
117 delete[] margins;-
118 delete[] windowFrameMargins;-
119 delete windowData;-
120}-
121-
122/*!-
123 \internal-
124-
125 Ensures that margins is allocated.-
126 This function must be called before any dereferencing.-
127*/-
128void QGraphicsWidgetPrivate::ensureMargins() const-
129{-
130 if (!margins) {-
131 margins = new qreal[4];-
132 for (int i = 0; i < 4; ++i)-
133 margins[i] = 0;-
134 }-
135}-
136-
137/*!-
138 \internal-
139-
140 Ensures that windowFrameMargins is allocated.-
141 This function must be called before any dereferencing.-
142*/-
143void QGraphicsWidgetPrivate::ensureWindowFrameMargins() const-
144{-
145 if (!windowFrameMargins) {-
146 windowFrameMargins = new qreal[4];-
147 for (int i = 0; i < 4; ++i)-
148 windowFrameMargins[i] = 0;-
149 }-
150}-
151-
152/*!-
153 \internal-
154-
155 Ensures that windowData is allocated.-
156 This function must be called before any dereferencing.-
157*/-
158void QGraphicsWidgetPrivate::ensureWindowData()-
159{-
160 if (!windowData)-
161 windowData = new WindowData;-
162}-
163-
164void QGraphicsWidgetPrivate::setPalette_helper(const QPalette &palette)-
165{-
166 if (this->palette == palette && this->palette.resolve() == palette.resolve())-
167 return;-
168 updatePalette(palette);-
169}-
170-
171void QGraphicsWidgetPrivate::resolvePalette(uint inheritedMask)-
172{-
173 inheritedPaletteResolveMask = inheritedMask;-
174 QPalette naturalPalette = naturalWidgetPalette();-
175 QPalette resolvedPalette = palette.resolve(naturalPalette);-
176 updatePalette(resolvedPalette);-
177}-
178-
179void QGraphicsWidgetPrivate::updatePalette(const QPalette &palette)-
180{-
181 Q_Q(QGraphicsWidget);-
182 // Update local palette setting.-
183 this->palette = palette;-
184-
185 // Calculate new mask.-
186 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))-
187 inheritedPaletteResolveMask = 0;-
188 int mask = palette.resolve() | inheritedPaletteResolveMask;-
189-
190 // Propagate to children.-
191 for (int i = 0; i < children.size(); ++i) {-
192 QGraphicsItem *item = children.at(i);-
193 if (item->isWidget()) {-
194 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);-
195 if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))-
196 w->d_func()->resolvePalette(mask);-
197 } else {-
198 item->d_ptr->resolvePalette(mask);-
199 }-
200 }-
201-
202 // Notify change.-
203 QEvent event(QEvent::PaletteChange);-
204 QApplication::sendEvent(q, &event);-
205}-
206-
207void QGraphicsWidgetPrivate::setLayoutDirection_helper(Qt::LayoutDirection direction)-
208{-
209 Q_Q(QGraphicsWidget);-
210 if ((direction == Qt::RightToLeft) == (testAttribute(Qt::WA_RightToLeft)))-
211 return;-
212 q->setAttribute(Qt::WA_RightToLeft, (direction == Qt::RightToLeft));-
213-
214 // Propagate this change to all children.-
215 for (int i = 0; i < children.size(); ++i) {-
216 QGraphicsItem *item = children.at(i);-
217 if (item->isWidget()) {-
218 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);-
219 if (widget->parentWidget() && !widget->testAttribute(Qt::WA_SetLayoutDirection))-
220 widget->d_func()->setLayoutDirection_helper(direction);-
221 }-
222 }-
223-
224 // Send the notification event to this widget item.-
225 QEvent e(QEvent::LayoutDirectionChange);-
226 QApplication::sendEvent(q, &e);-
227}-
228-
229void QGraphicsWidgetPrivate::resolveLayoutDirection()-
230{-
231 Q_Q(QGraphicsWidget);-
232 if (q->testAttribute(Qt::WA_SetLayoutDirection)) {-
233 return;-
234 }-
235 if (QGraphicsWidget *parentWidget = q->parentWidget()) {-
236 setLayoutDirection_helper(parentWidget->layoutDirection());-
237 } else if (scene) {-
238 // ### shouldn't the scene have a layoutdirection really? how does-
239 // ### QGraphicsWidget get changes from QApplication::layoutDirection?-
240 setLayoutDirection_helper(QApplication::layoutDirection());-
241 } else {-
242 setLayoutDirection_helper(QApplication::layoutDirection());-
243 }-
244}-
245-
246QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const-
247{-
248 Q_Q(const QGraphicsWidget);-
249 QPalette palette;-
250 if (QGraphicsWidget *parent = q->parentWidget()) {-
251 palette = parent->palette();-
252 } else if (scene) {-
253 palette = scene->palette();-
254 }-
255 palette.resolve(0);-
256 return palette;-
257}-
258-
259void QGraphicsWidgetPrivate::setFont_helper(const QFont &font)-
260{-
261 if (this->font == font && this->font.resolve() == font.resolve())-
262 return;-
263 updateFont(font);-
264}-
265-
266void QGraphicsWidgetPrivate::resolveFont(uint inheritedMask)-
267{-
268 Q_Q(QGraphicsWidget);-
269 inheritedFontResolveMask = inheritedMask;-
270 if (QGraphicsWidget *p = q->parentWidget())-
271 inheritedFontResolveMask |= p->d_func()->inheritedFontResolveMask;-
272 QFont naturalFont = naturalWidgetFont();-
273 QFont resolvedFont = font.resolve(naturalFont);-
274 updateFont(resolvedFont);-
275}-
276-
277void QGraphicsWidgetPrivate::updateFont(const QFont &font)-
278{-
279 Q_Q(QGraphicsWidget);-
280 // Update the local font setting.-
281 this->font = font;-
282-
283 // Calculate new mask.-
284 if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation))-
285 inheritedFontResolveMask = 0;-
286 int mask = font.resolve() | inheritedFontResolveMask;-
287-
288 // Propagate to children.-
289 for (int i = 0; i < children.size(); ++i) {-
290 QGraphicsItem *item = children.at(i);-
291 if (item->isWidget()) {-
292 QGraphicsWidget *w = static_cast<QGraphicsWidget *>(item);-
293 if (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))-
294 w->d_func()->resolveFont(mask);-
295 } else {-
296 item->d_ptr->resolveFont(mask);-
297 }-
298 }-
299-
300 if (!polished)-
301 return;-
302 // Notify change.-
303 QEvent event(QEvent::FontChange);-
304 QApplication::sendEvent(q, &event);-
305}-
306-
307QFont QGraphicsWidgetPrivate::naturalWidgetFont() const-
308{-
309 Q_Q(const QGraphicsWidget);-
310 QFont naturalFont; // ### no application font support-
311 if (QGraphicsWidget *parent = q->parentWidget()) {-
312 naturalFont = parent->font();-
313 } else if (scene) {-
314 naturalFont = scene->font();-
315 }-
316 naturalFont.resolve(0);-
317 return naturalFont;-
318}-
319-
320void QGraphicsWidgetPrivate::initStyleOptionTitleBar(QStyleOptionTitleBar *option)-
321{-
322 Q_Q(QGraphicsWidget);-
323 ensureWindowData();-
324 q->initStyleOption(option);-
325 option->rect.setHeight(titleBarHeight(*option));-
326 option->titleBarFlags = windowFlags;-
327 option->subControls = QStyle::SC_TitleBarCloseButton | QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu;-
328 option->activeSubControls = windowData->hoveredSubControl;-
329 bool isActive = q->isActiveWindow();-
330 if (isActive) {option->state|=.setFlag(QStyle::State_Active;, isActive);-
331 if (isActive) {
isActiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
332 option->titleBarState = Qt::WindowActive;-
333 option->titleBarState |= QStyle::State_Active;-
334 } else {option->state &= ~QStyle::State_Active;
never executed: end of block
0
335 option->titleBarState = Qt::WindowNoState;-
336 }
never executed: end of block
0
337 QFont windowTitleFont = QApplication::font("QMdiSubWindowTitleBar");-
338 QRect textRect = q->style()->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, 0);-
339 option->text = QFontMetrics(windowTitleFont).elidedText(-
340 windowData->windowTitle, Qt::ElideRight, textRect.width());-
341}
never executed: end of block
0
342-
343void QGraphicsWidgetPrivate::adjustWindowFlags(Qt::WindowFlags *flags)-
344{-
345 bool customize = (*flags & (Qt::CustomizeWindowHint-
346 | Qt::FramelessWindowHint-
347 | Qt::WindowTitleHint-
348 | Qt::WindowSystemMenuHint-
349 | Qt::WindowMinimizeButtonHint-
350 | Qt::WindowMaximizeButtonHint-
351 | Qt::WindowContextHelpButtonHint));-
352-
353 uint type = (*flags & Qt::WindowType_Mask);-
354 if (customize)-
355 ;-
356 else if (type == Qt::Dialog || type == Qt::Sheet)-
357 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowContextHelpButtonHint;-
358 else if (type == Qt::Tool)-
359 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint;-
360 else if (type == Qt::Window || type == Qt::SubWindow)-
361 *flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint-
362 | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint;-
363}-
364-
365void QGraphicsWidgetPrivate::windowFrameMouseReleaseEvent(QGraphicsSceneMouseEvent *event)-
366{-
367 Q_Q(QGraphicsWidget);-
368 ensureWindowData();-
369 if (windowData->grabbedSection != Qt::NoSection) {-
370 if (windowData->grabbedSection == Qt::TitleBarArea) {-
371 windowData->buttonSunken = false;-
372 QStyleOptionTitleBar bar;-
373 initStyleOptionTitleBar(&bar);-
374 // make sure that the coordinates (rect and pos) we send to the style are positive.-
375 bar.rect = q->windowFrameRect().toRect();-
376 bar.rect.moveTo(0,0);-
377 bar.rect.setHeight(q->style()->pixelMetric(QStyle::PM_TitleBarHeight, &bar));-
378 QPointF pos = event->pos();-
379 if (windowFrameMargins) {-
380 pos.rx() += windowFrameMargins[Left];-
381 pos.ry() += windowFrameMargins[Top];-
382 }-
383 bar.subControls = QStyle::SC_TitleBarCloseButton;-
384 if (q->style()->subControlRect(QStyle::CC_TitleBar, &bar,-
385 QStyle::SC_TitleBarCloseButton,-
386 event->widget()).contains(pos.toPoint())) {-
387 q->close();-
388 }-
389 }-
390 if (!(static_cast<QGraphicsSceneMouseEvent *>(event)->buttons()))-
391 windowData->grabbedSection = Qt::NoSection;-
392 event->accept();-
393 }-
394}-
395-
396void QGraphicsWidgetPrivate::windowFrameMousePressEvent(QGraphicsSceneMouseEvent *event)-
397{-
398 Q_Q(QGraphicsWidget);-
399 if (event->button() != Qt::LeftButton)-
400 return;-
401-
402 ensureWindowData();-
403 windowData->startGeometry = q->geometry();-
404 windowData->grabbedSection = q->windowFrameSectionAt(event->pos());-
405 ensureWindowData();-
406 if (windowData->grabbedSection == Qt::TitleBarArea-
407 && windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton) {-
408 windowData->buttonSunken = true;-
409 q->update();-
410 }-
411 event->setAccepted(windowData->grabbedSection != Qt::NoSection);-
412}-
413-
414/*!-
415 Used to calculate the-
416 Precondition:-
417 \a widget should support either hfw or wfh-
418-
419 If \a heightForWidth is set to false, this function will query the width for height-
420 instead. \a width will then be interpreted as height, \a minh and \a maxh will be interpreted-
421 as minimum width and maximum width.-
422 */-
423static qreal minimumHeightForWidth(qreal width, qreal minh, qreal maxh,-
424 const QGraphicsWidget *widget,-
425 bool heightForWidth = true)-
426{-
427 qreal minimumHeightForWidth = -1;-
428 const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();-
429 if (hasHFW == heightForWidth) {-
430 minimumHeightForWidth = hasHFW-
431 ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(width, -1)).height()-
432 : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, width)).width(); //"width" is here height!-
433 } else {-
434 // widthForHeight-
435 const qreal constraint = width;-
436 while (maxh - minh > 0.1) {-
437 qreal middle = minh + (maxh - minh)/2;-
438 // ### really bad, if we are a widget with a layout it will call-
439 // layout->effectiveSizeHint(Qt::MiniumumSize), which again will call-
440 // sizeHint three times because of how the cache works-
441 qreal hfw = hasHFW-
442 ? widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(middle, -1)).height()-
443 : widget->effectiveSizeHint(Qt::MinimumSize, QSizeF(-1, middle)).width();-
444 if (hfw > constraint) {-
445 minh = middle;-
446 } else if (hfw <= constraint) {-
447 maxh = middle;-
448 }-
449 }-
450 minimumHeightForWidth = maxh;-
451 }-
452 return minimumHeightForWidth;-
453}-
454-
455static qreal minimumWidthForHeight(qreal height, qreal minw, qreal maxw,-
456 const QGraphicsWidget *widget)-
457{-
458 return minimumHeightForWidth(height, minw, maxw, widget, false);-
459}-
460-
461static QSizeF closestAcceptableSize(const QSizeF &proposed,-
462 const QGraphicsWidget *widget)-
463{-
464 const QSizeF current = widget->size();-
465-
466 qreal minw = proposed.width();-
467 qreal maxw = current.width();-
468 qreal minh = proposed.height();-
469 qreal maxh = current.height();-
470-
471 qreal middlew = maxw;-
472 qreal middleh = maxh;-
473 qreal min_hfw;-
474 min_hfw = minimumHeightForWidth(maxw, minh, maxh, widget);-
475-
476 do {-
477 if (maxw - minw < 0.1) {-
478 // we still haven't found anything, cut off binary search-
479 minw = maxw;-
480 minh = maxh;-
481 }-
482 middlew = minw + (maxw - minw)/2.0;-
483 middleh = minh + (maxh - minh)/2.0;-
484-
485 min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);-
486-
487 if (min_hfw > middleh) {-
488 minw = middlew;-
489 minh = middleh;-
490 } else if (min_hfw <= middleh) {-
491 maxw = middlew;-
492 maxh = middleh;-
493 }-
494 } while (maxw != minw);-
495-
496 min_hfw = minimumHeightForWidth(middlew, minh, maxh, widget);-
497-
498 QSizeF result;-
499 if (min_hfw < maxh) {-
500 result = QSizeF(middlew, min_hfw);-
501 } else {-
502 // Needed because of the cut-off we do above.-
503 result = QSizeF(minimumWidthForHeight(maxh, proposed.width(), current.width(), widget), maxh);-
504 }-
505 return result;-
506}-
507-
508static void _q_boundGeometryToSizeConstraints(const QRectF &startGeometry,-
509 QRectF *rect, Qt::WindowFrameSection section,-
510 const QSizeF &min, const QSizeF &max,-
511 const QGraphicsWidget *widget)-
512{-
513 const QRectF proposedRect = *rect;-
514 qreal width = qBound(min.width(), proposedRect.width(), max.width());-
515 qreal height = qBound(min.height(), proposedRect.height(), max.height());-
516-
517 const bool hasHFW = QGraphicsLayoutItemPrivate::get(widget)->hasHeightForWidth();-
518 const bool hasWFH = QGraphicsLayoutItemPrivate::get(widget)->hasWidthForHeight();-
519-
520 const bool widthChanged = proposedRect.width() != widget->size().width();-
521 const bool heightChanged = proposedRect.height() != widget->size().height();-
522-
523 if (hasHFW || hasWFH) {-
524 if (widthChanged || heightChanged) {-
525 qreal minExtent;-
526 qreal maxExtent;-
527 qreal constraint;-
528 qreal proposed;-
529 if (hasHFW) {-
530 minExtent = min.height();-
531 maxExtent = max.height();-
532 constraint = width;-
533 proposed = proposedRect.height();-
534 } else {-
535 // width for height-
536 minExtent = min.width();-
537 maxExtent = max.width();-
538 constraint = height;-
539 proposed = proposedRect.width();-
540 }-
541 if (minimumHeightForWidth(constraint, minExtent, maxExtent, widget, hasHFW) > proposed) {-
542 QSizeF effectiveSize = closestAcceptableSize(QSizeF(width, height), widget);-
543 width = effectiveSize.width();-
544 height = effectiveSize.height();-
545 }-
546 }-
547 }-
548-
549 switch (section) {-
550 case Qt::LeftSection:-
551 rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),-
552 qRound(width), startGeometry.height());-
553 break;-
554 case Qt::TopLeftSection:-
555 rect->setRect(startGeometry.right() - qRound(width), startGeometry.bottom() - qRound(height),-
556 qRound(width), qRound(height));-
557 break;-
558 case Qt::TopSection:-
559 rect->setRect(startGeometry.left(), startGeometry.bottom() - qRound(height),-
560 startGeometry.width(), qRound(height));-
561 break;-
562 case Qt::TopRightSection:-
563 rect->setTop(rect->bottom() - qRound(height));-
564 rect->setWidth(qRound(width));-
565 break;-
566 case Qt::RightSection:-
567 rect->setWidth(qRound(width));-
568 break;-
569 case Qt::BottomRightSection:-
570 rect->setWidth(qRound(width));-
571 rect->setHeight(qRound(height));-
572 break;-
573 case Qt::BottomSection:-
574 rect->setHeight(qRound(height));-
575 break;-
576 case Qt::BottomLeftSection:-
577 rect->setRect(startGeometry.right() - qRound(width), startGeometry.top(),-
578 qRound(width), qRound(height));-
579 break;-
580 default:-
581 break;-
582 }-
583}-
584-
585void QGraphicsWidgetPrivate::windowFrameMouseMoveEvent(QGraphicsSceneMouseEvent *event)-
586{-
587 Q_Q(QGraphicsWidget);-
588 ensureWindowData();-
589 if (!(event->buttons() & Qt::LeftButton) || windowData->hoveredSubControl != QStyle::SC_TitleBarLabel)-
590 return;-
591-
592 QLineF delta(q->mapFromScene(event->buttonDownScenePos(Qt::LeftButton)), event->pos());-
593 QLineF parentDelta(q->mapToParent(delta.p1()), q->mapToParent(delta.p2()));-
594 QLineF parentXDelta(q->mapToParent(QPointF(delta.p1().x(), 0)), q->mapToParent(QPointF(delta.p2().x(), 0)));-
595 QLineF parentYDelta(q->mapToParent(QPointF(0, delta.p1().y())), q->mapToParent(QPointF(0, delta.p2().y())));-
596-
597 QRectF newGeometry;-
598 switch (windowData->grabbedSection) {-
599 case Qt::LeftSection:-
600 newGeometry = QRectF(windowData->startGeometry.topLeft()-
601 + QPointF(parentXDelta.dx(), parentXDelta.dy()),-
602 windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));-
603 break;-
604 case Qt::TopLeftSection:-
605 newGeometry = QRectF(windowData->startGeometry.topLeft()-
606 + QPointF(parentDelta.dx(), parentDelta.dy()),-
607 windowData->startGeometry.size() - QSizeF(delta.dx(), delta.dy()));-
608 break;-
609 case Qt::TopSection:-
610 newGeometry = QRectF(windowData->startGeometry.topLeft()-
611 + QPointF(parentYDelta.dx(), parentYDelta.dy()),-
612 windowData->startGeometry.size() - QSizeF(0, delta.dy()));-
613 break;-
614 case Qt::TopRightSection:-
615 newGeometry = QRectF(windowData->startGeometry.topLeft()-
616 + QPointF(parentYDelta.dx(), parentYDelta.dy()),-
617 windowData->startGeometry.size() - QSizeF(-delta.dx(), delta.dy()));-
618 break;-
619 case Qt::RightSection:-
620 newGeometry = QRectF(windowData->startGeometry.topLeft(),-
621 windowData->startGeometry.size() + QSizeF(delta.dx(), 0));-
622 break;-
623 case Qt::BottomRightSection:-
624 newGeometry = QRectF(windowData->startGeometry.topLeft(),-
625 windowData->startGeometry.size() + QSizeF(delta.dx(), delta.dy()));-
626 break;-
627 case Qt::BottomSection:-
628 newGeometry = QRectF(windowData->startGeometry.topLeft(),-
629 windowData->startGeometry.size() + QSizeF(0, delta.dy()));-
630 break;-
631 case Qt::BottomLeftSection:-
632 newGeometry = QRectF(windowData->startGeometry.topLeft()-
633 + QPointF(parentXDelta.dx(), parentXDelta.dy()),-
634 windowData->startGeometry.size() - QSizeF(delta.dx(), -delta.dy()));-
635 break;-
636 case Qt::TitleBarArea:-
637 newGeometry = QRectF(windowData->startGeometry.topLeft()-
638 + QPointF(parentDelta.dx(), parentDelta.dy()),-
639 windowData->startGeometry.size());-
640 break;-
641 case Qt::NoSection:-
642 break;-
643 }-
644-
645 if (windowData->grabbedSection != Qt::NoSection) {-
646 _q_boundGeometryToSizeConstraints(windowData->startGeometry, &newGeometry,-
647 windowData->grabbedSection,-
648 q->effectiveSizeHint(Qt::MinimumSize),-
649 q->effectiveSizeHint(Qt::MaximumSize),-
650 q);-
651 q->setGeometry(newGeometry);-
652 }-
653}-
654-
655void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event)-
656{-
657 Q_Q(QGraphicsWidget);-
658 if (!hasDecoration())-
659 return;-
660-
661 ensureWindowData();-
662-
663 if (q->rect().contains(event->pos())) {-
664 if (windowData->buttonMouseOver || windowData->hoveredSubControl != QStyle::SC_None)-
665 windowFrameHoverLeaveEvent(event);-
666 return;-
667 }-
668-
669 bool wasMouseOver = windowData->buttonMouseOver;-
670 QRect oldButtonRect = windowData->buttonRect;-
671 windowData->buttonRect = QRect();-
672 windowData->buttonMouseOver = false;-
673 QPointF pos = event->pos();-
674 QStyleOptionTitleBar bar;-
675 // make sure that the coordinates (rect and pos) we send to the style are positive.-
676 if (windowFrameMargins) {-
677 pos.rx() += windowFrameMargins[Left];-
678 pos.ry() += windowFrameMargins[Top];-
679 }-
680 initStyleOptionTitleBar(&bar);-
681 bar.rect = q->windowFrameRect().toRect();-
682 bar.rect.moveTo(0,0);-
683 bar.rect.setHeight(int(titleBarHeight(bar)));-
684-
685 Qt::CursorShape cursorShape = Qt::ArrowCursor;-
686 bool needsSetCursorCall = true;-
687 switch (q->windowFrameSectionAt(event->pos())) {-
688 case Qt::TopLeftSection:-
689 case Qt::BottomRightSection:-
690 cursorShape = Qt::SizeFDiagCursor;-
691 break;-
692 case Qt::TopRightSection:-
693 case Qt::BottomLeftSection:-
694 cursorShape = Qt::SizeBDiagCursor;-
695 break;-
696 case Qt::LeftSection:-
697 case Qt::RightSection:-
698 cursorShape = Qt::SizeHorCursor;-
699 break;-
700 case Qt::TopSection:-
701 case Qt::BottomSection:-
702 cursorShape = Qt::SizeVerCursor;-
703 break;-
704 case Qt::TitleBarArea:-
705 windowData->buttonRect = q->style()->subControlRect(-
706 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarCloseButton, 0);-
707#ifdef Q_DEAD_CODE_FROM_QT4_MAC-
708 // On mac we should hover if we are in the 'area' of the buttons-
709 windowData->buttonRect |= q->style()->subControlRect(-
710 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMinButton, 0);-
711 windowData->buttonRect |= q->style()->subControlRect(-
712 QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMaxButton, 0);-
713#endif-
714 if (windowData->buttonRect.contains(pos.toPoint()))-
715 windowData->buttonMouseOver = true;-
716 event->ignore();-
717 break;-
718 default:-
719 needsSetCursorCall = false;-
720 event->ignore();-
721 }-
722#ifndef QT_NO_CURSOR-
723 if (needsSetCursorCall)-
724 q->setCursor(cursorShape);-
725#endif-
726 // update buttons if we hover over them-
727 windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0);-
728 if (windowData->hoveredSubControl != QStyle::SC_TitleBarCloseButton)-
729 windowData->hoveredSubControl = QStyle::SC_TitleBarLabel;-
730-
731 if (windowData->buttonMouseOver != wasMouseOver) {-
732 if (!oldButtonRect.isNull())-
733 q->update(QRectF(oldButtonRect).translated(q->windowFrameRect().topLeft()));-
734 if (!windowData->buttonRect.isNull())-
735 q->update(QRectF(windowData->buttonRect).translated(q->windowFrameRect().topLeft()));-
736 }-
737}-
738-
739void QGraphicsWidgetPrivate::windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event)-
740{-
741 Q_UNUSED(event);-
742 Q_Q(QGraphicsWidget);-
743 if (hasDecoration()) {-
744 // ### restore the cursor, don't override it-
745#ifndef QT_NO_CURSOR-
746 q->unsetCursor();-
747#endif-
748-
749 ensureWindowData();-
750-
751 bool needsUpdate = false;-
752 if (windowData->hoveredSubControl == QStyle::SC_TitleBarCloseButton-
753 || windowData->buttonMouseOver)-
754 needsUpdate = true;-
755-
756 // update the hover state (of buttons etc...)-
757 windowData->hoveredSubControl = QStyle::SC_None;-
758 windowData->buttonMouseOver = false;-
759 windowData->buttonRect = QRect();-
760 if (needsUpdate)-
761 q->update(windowData->buttonRect);-
762 }-
763}-
764-
765bool QGraphicsWidgetPrivate::hasDecoration() const-
766{-
767 return (windowFlags & Qt::Window) && (windowFlags & Qt::WindowTitleHint);-
768}-
769-
770/**-
771 * is called after a reparent has taken place to fix up the focus chain(s)-
772 */-
773void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *newParent, QGraphicsScene *oldScene, QGraphicsScene *newScene)-
774{-
775 Q_Q(QGraphicsWidget);-
776 Q_ASSERT(focusNext && focusPrev);-
777-
778 if (q_ptr->isPanel()) {-
779 // panels are never a part of their parent's or ancestors' focus-
780 // chains. so reparenting a panel is easy; there's nothing to-
781 // do.-
782 return;-
783 }-
784-
785 // we're not a panel, so find the first widget in the focus chain-
786 // (this), and the last (this, or the last widget that is still-
787 // a descendent of this). also find the widgets that currently /-
788 // before reparenting point to this widgets' focus chain.-
789 QGraphicsWidget *focusFirst = q;-
790 QGraphicsWidget *focusBefore = focusPrev;-
791 QGraphicsWidget *focusLast = focusFirst;-
792 QGraphicsWidget *focusAfter = focusNext;-
793 do {-
794 if (!q->isAncestorOf(focusAfter))-
795 break;-
796 focusLast = focusAfter;-
797 } while ((focusAfter = focusAfter->d_func()->focusNext));-
798-
799 if (!parent && oldScene && oldScene != newScene && oldScene->d_func()->tabFocusFirst == q) {-
800 // detach from old scene's top level focus chain.-
801 oldScene->d_func()->tabFocusFirst = (focusAfter != q) ? focusAfter : 0;-
802 }-
803-
804 // detach from current focus chain; skip this widget subtree.-
805 focusBefore->d_func()->focusNext = focusAfter;-
806 focusAfter->d_func()->focusPrev = focusBefore;-
807-
808 if (newParent) {-
809 // attach to new parent's focus chain as the last element-
810 // in its chain.-
811 QGraphicsWidget *newFocusFirst = newParent;-
812 QGraphicsWidget *newFocusLast = newFocusFirst;-
813 QGraphicsWidget *newFocusAfter = newFocusFirst->d_func()->focusNext;-
814 do {-
815 if (!newParent->isAncestorOf(newFocusAfter))-
816 break;-
817 newFocusLast = newFocusAfter;-
818 } while ((newFocusAfter = newFocusAfter->d_func()->focusNext));-
819-
820 newFocusLast->d_func()->focusNext = q;-
821 focusLast->d_func()->focusNext = newFocusAfter;-
822 newFocusAfter->d_func()->focusPrev = focusLast;-
823 focusPrev = newFocusLast;-
824 } else {-
825 // no new parent, so just link up our own prev->last widgets.-
826 focusPrev = focusLast;-
827 focusLast->d_func()->focusNext = q;-
828 }-
829}-
830-
831void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l)-
832{-
833 delete (this->layout);-
834 layout = l;-
835 if (!l) {-
836 Q_Q(QGraphicsWidget);-
837 q->updateGeometry();-
838 }-
839}-
840-
841qreal QGraphicsWidgetPrivate::width() const-
842{-
843 Q_Q(const QGraphicsWidget);-
844 return q->geometry().width();-
845}-
846-
847void QGraphicsWidgetPrivate::setWidth(qreal w)-
848{-
849 if (qIsNaN(w))-
850 return;-
851 Q_Q(QGraphicsWidget);-
852 if (q->geometry().width() == w)-
853 return;-
854-
855 q->setGeometry(QRectF(q->x(), q->y(), w, height()));-
856}-
857-
858void QGraphicsWidgetPrivate::resetWidth()-
859{-
860 Q_Q(QGraphicsWidget);-
861 q->setGeometry(QRectF(q->x(), q->y(), 0, height()));-
862}-
863-
864qreal QGraphicsWidgetPrivate::height() const-
865{-
866 Q_Q(const QGraphicsWidget);-
867 return q->geometry().height();-
868}-
869-
870void QGraphicsWidgetPrivate::setHeight(qreal h)-
871{-
872 if (qIsNaN(h))-
873 return;-
874 Q_Q(QGraphicsWidget);-
875 if (q->geometry().height() == h)-
876 return;-
877-
878 q->setGeometry(QRectF(q->x(), q->y(), width(), h));-
879}-
880-
881void QGraphicsWidgetPrivate::resetHeight()-
882{-
883 Q_Q(QGraphicsWidget);-
884 q->setGeometry(QRectF(q->x(), q->y(), width(), 0));-
885}-
886-
887void QGraphicsWidgetPrivate::setGeometryFromSetPos()-
888{-
889 if (inSetGeometry)-
890 return;-
891 Q_Q(QGraphicsWidget);-
892 inSetPos = 1;-
893 // Ensure setGeometry is called (avoid recursion when setPos is-
894 // called from within setGeometry).-
895 q->setGeometry(QRectF(pos, q->size()));-
896 inSetPos = 0 ;-
897}-
898-
899QT_END_NAMESPACE-
900-
901#endif //QT_NO_GRAPHICSVIEW-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9