11#include <private/qtquicktemplates2-config_p.h>
12#if QT_CONFIG(quicktemplates2_container)
13#include "qquicktabbar_p.h"
14#include "qquickdialogbuttonbox_p.h"
19#include <QtCore/private/qobject_p.h>
20#include <QtCore/qscopedvaluerollback.h>
21#include <QtQml/private/qqmlpropertytopropertybinding_p.h>
22#include <QtQuick/private/qquickitem_p.h>
23#include <QtQuick/private/qquicksafearea_p.h>
24#include <QtQuick/private/qquickitemchangelistener_p.h>
25#include <QtQuick/private/qquickwindowmodule_p_p.h>
29using namespace Qt::StringLiterals;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
115 | QQuickItemPrivate::Geometry | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight;
117static void layoutItem(QQuickItem *item, qreal y, qreal width)
123 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
124 if (!p->widthValid()) {
125 item->setWidth(width);
126 p->widthValidFlag =
false;
130void QQuickApplicationWindowPrivate::updateHasBackgroundFlags()
135 QQuickItemPrivate *backgroundPrivate = QQuickItemPrivate::get(background);
136 hasBackgroundWidth = backgroundPrivate->widthValid();
137 hasBackgroundHeight = backgroundPrivate->heightValid();
140void QQuickApplicationWindowPrivate::relayout()
142 Q_Q(QQuickApplicationWindow);
143 if (!componentComplete)
149 QScopedValueRollback<
bool> guard(insideRelayout,
true);
153 auto menuBarHeight = [
this]{
return menuBar && menuBar->isVisible() ? menuBar->height() : 0; };
154 auto headerheight = [
this]{
return header && header->isVisible() ? header->height() : 0; };
155 auto footerHeight = [
this]{
return footer && footer->isVisible() ? footer->height() : 0; };
157 control->setSize(q->size());
159 layoutItem(menuBar, 0, q->width());
160 layoutItem(header, menuBarHeight(), q->width());
161 layoutItem(footer, control->height() - footerHeight(), q->width());
164 if (!hasBackgroundWidth && qFuzzyIsNull(background->x()))
165 background->setWidth(q->width());
166 if (!hasBackgroundHeight && qFuzzyIsNull(background->y()))
167 background->setHeight(q->height());
173 auto *controlSafeArea =
static_cast<QQuickSafeArea*>(qmlAttachedPropertiesObject<QQuickSafeArea>(control));
174 auto *windowSafeArea =
static_cast<QQuickSafeArea*>(qmlAttachedPropertiesObject<QQuickSafeArea>(q));
175 const auto inheritedMargins = windowSafeArea->margins();
176 controlSafeArea->setAdditionalMargins(QMarginsF(
177 0, (menuBarHeight() + headerheight()) - inheritedMargins.top(),
178 0, footerHeight() - inheritedMargins.bottom()));
181void QQuickApplicationWindowPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change,
const QRectF &diff)
185 if (!insideRelayout && item == background && change.sizeChange()) {
188 updateHasBackgroundFlags();
194void QQuickApplicationWindowPrivate::itemVisibilityChanged(QQuickItem *item)
200void QQuickApplicationWindowPrivate::itemImplicitWidthChanged(QQuickItem *item)
206void QQuickApplicationWindowPrivate::itemImplicitHeightChanged(QQuickItem *item)
212void QQuickApplicationWindowPrivate::updateFont(
const QFont &f)
214 Q_Q(QQuickApplicationWindow);
215 const bool changed = font != f;
218 QQuickControlPrivate::updateFontRecur(q->QQuickWindow::contentItem(), f);
220 const QList<QQuickPopup *> popups = q->findChildren<QQuickPopup *>();
221 for (QQuickPopup *popup : popups)
222 QQuickControlPrivate::get(
static_cast<QQuickControl *>(popup->popupItem()))->inheritFont(f);
225 emit q->fontChanged();
228void QQuickApplicationWindowPrivate::resolveFont()
230 QFont resolvedFont = font.resolve(QQuickTheme::font(QQuickTheme::System));
231 setFont_helper(resolvedFont);
236 auto *appWindow = qobject_cast<QQuickApplicationWindow *>(window);
237 auto *appWindowPriv = appWindow ? QQuickApplicationWindowPrivate::get(appWindow) :
nullptr;
239 QQuickItem *item = window->activeFocusItem();
243 if (appWindow && item == appWindowPriv->control)
247 item = item->parentItem();
252void QQuickApplicationWindowPrivate::_q_updateActiveFocus()
254 Q_Q(QQuickApplicationWindow);
255 setActiveFocusControl(findActiveFocusControl(q));
258void QQuickApplicationWindowPrivate::setActiveFocusControl(QQuickItem *control)
260 Q_Q(QQuickApplicationWindow);
261 if (activeFocusControl != control) {
262 activeFocusControl = control;
263 emit q->activeFocusControlChanged();
267void QQuickApplicationWindowPrivate::contentData_append(QQmlListProperty<QObject> *prop, QObject *obj)
269 QQuickItemPrivate::data_append(prop, obj);
272 if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(obj))
273 QQuickPopupPrivate::get(popup)->setWindow(
static_cast<QQuickApplicationWindow *>(prop->data));
276void QQuickApplicationWindowPrivate::cancelBackground()
278 Q_Q(QQuickApplicationWindow);
279 quickCancelDeferred(q, backgroundName());
282void QQuickApplicationWindowPrivate::executeBackground(
bool complete)
284 Q_Q(QQuickApplicationWindow);
285 if (background.wasExecuted())
288 if (!background || complete)
289 quickBeginDeferred(q, backgroundName(), background);
291 quickCompleteDeferred(q, backgroundName(), background);
293 updateHasBackgroundFlags();
298QQuickApplicationWindow::QQuickApplicationWindow(QWindow *parent)
299 : QQuickWindowQmlImpl(*(
new QQuickApplicationWindowPrivate), parent)
301 connect(
this, SIGNAL(activeFocusItemChanged()),
this, SLOT(_q_updateActiveFocus()));
304QQuickApplicationWindow::~QQuickApplicationWindow()
306 Q_D(QQuickApplicationWindow);
307 d->setActiveFocusControl(
nullptr);
308 disconnect(
this, SIGNAL(activeFocusItemChanged()),
this, SLOT(_q_updateActiveFocus()));
310 QQuickItemPrivate::get(d->menuBar)->removeItemChangeListener(d, ItemChanges);
312 QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, ItemChanges);
314 QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, ItemChanges);
317QQuickApplicationWindowAttached *QQuickApplicationWindow::qmlAttachedProperties(QObject *object)
319 return new QQuickApplicationWindowAttached(object);
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340QQuickItem *QQuickApplicationWindow::background()
const
342 QQuickApplicationWindowPrivate *d =
const_cast<QQuickApplicationWindowPrivate *>(d_func());
344 d->executeBackground();
345 return d->background;
348void QQuickApplicationWindow::setBackground(QQuickItem *background)
350 Q_D(QQuickApplicationWindow);
351 if (d->background == background)
354 if (!d->background.isExecuting())
355 d->cancelBackground();
358 d->hasBackgroundWidth =
false;
359 d->hasBackgroundHeight =
false;
361 QQuickControlPrivate::hideOldItem(d->background);
363 d->background = background;
366 background->setParentItem(QQuickWindow::contentItem());
368 if (qFuzzyIsNull(background->z()))
369 background->setZ(-1);
374 if (!d->background.isExecuting()) {
375 d->updateHasBackgroundFlags();
377 if (isComponentComplete())
381 if (!d->background.isExecuting())
382 emit backgroundChanged();
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406QQuickItem *QQuickApplicationWindow::header()
const
408 Q_D(
const QQuickApplicationWindow);
412void QQuickApplicationWindow::setHeader(QQuickItem *header)
414 Q_D(QQuickApplicationWindow);
415 if (d->header == header)
419 QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, ItemChanges);
420 d->header->setParentItem(
nullptr);
424 header->setParentItem(QQuickWindow::contentItem());
425 QQuickItemPrivate *p = QQuickItemPrivate::get(header);
426 p->addItemChangeListener(d, ItemChanges);
427 if (qFuzzyIsNull(header->z()))
429 if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(header))
430 toolBar->setPosition(QQuickToolBar::Header);
431#if QT_CONFIG(quicktemplates2_container)
432 else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(header))
433 tabBar->setPosition(QQuickTabBar::Header);
434 else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(header))
435 buttonBox->setPosition(QQuickDialogButtonBox::Header);
438 header->stackBefore(d->control);
440 if (isComponentComplete())
442 emit headerChanged();
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465QQuickItem *QQuickApplicationWindow::footer()
const
467 Q_D(
const QQuickApplicationWindow);
471void QQuickApplicationWindow::setFooter(QQuickItem *footer)
473 Q_D(QQuickApplicationWindow);
474 if (d->footer == footer)
478 QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, ItemChanges);
479 d->footer->setParentItem(
nullptr);
483 footer->setParentItem(QQuickWindow::contentItem());
484 QQuickItemPrivate *p = QQuickItemPrivate::get(footer);
485 p->addItemChangeListener(d, ItemChanges);
486 if (qFuzzyIsNull(footer->z()))
488 if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(footer))
489 toolBar->setPosition(QQuickToolBar::Footer);
490#if QT_CONFIG(quicktemplates2_container)
491 else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(footer))
492 tabBar->setPosition(QQuickTabBar::Footer);
493 else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(footer))
494 buttonBox->setPosition(QQuickDialogButtonBox::Footer);
496 footer->stackAfter(d->control);
499 if (isComponentComplete())
501 emit footerChanged();
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524QQmlListProperty<QObject> QQuickApplicationWindowPrivate::contentData()
526 Q_Q(QQuickApplicationWindow);
527 return QQmlListProperty<QObject>(q->contentItem(), q,
528 QQuickApplicationWindowPrivate::contentData_append,
529 QQuickItemPrivate::data_count,
530 QQuickItemPrivate::data_at,
531 QQuickItemPrivate::data_clear);
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550QQuickItem *QQuickApplicationWindow::contentItem()
const
552 Q_D(
const QQuickApplicationWindow);
553 return d->control->contentItem();
557
558
559
560
561
562
563
564
565
568
569
570
571
572
573
574
575
576
579
580
581
582
583
584
585
586
587
590
591
592
593
594
595
596
597
598
601
602
603
604
605
606
607
608
609
610
611
612
613
614QQuickItem *QQuickApplicationWindow::activeFocusControl()
const
616 Q_D(
const QQuickApplicationWindow);
617 return d->activeFocusControl;
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636QFont QQuickApplicationWindow::font()
const
638 Q_D(
const QQuickApplicationWindow);
642void QQuickApplicationWindow::setFont(
const QFont &font)
644 Q_D(QQuickApplicationWindow);
645 if (d->font.resolveMask() == font.resolveMask() && d->font == font)
648 QFont resolvedFont = font.resolve(QQuickTheme::font(QQuickTheme::System));
649 d->setFont_helper(resolvedFont);
652void QQuickApplicationWindow::resetFont()
658
659
660
661
662
663
664
665
666
667
668
669
670
671QLocale QQuickApplicationWindow::locale()
const
673 Q_D(
const QQuickApplicationWindow);
677void QQuickApplicationWindow::setLocale(
const QLocale &locale)
679 Q_D(QQuickApplicationWindow);
680 if (d->locale == locale)
684 QQuickControlPrivate::updateLocaleRecur(QQuickWindow::contentItem(), locale);
687 const QList<QQuickPopup *> popups = QQuickWindow::contentItem()->findChildren<QQuickPopup *>();
688 for (QQuickPopup *popup : popups)
689 QQuickControlPrivate::get(
static_cast<QQuickControl *>(popup->popupItem()))->updateLocale(locale,
false);
691 emit localeChanged();
694void QQuickApplicationWindow::resetLocale()
696 setLocale(QLocale());
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717QQuickItem *QQuickApplicationWindow::menuBar()
const
719 Q_D(
const QQuickApplicationWindow);
723void QQuickApplicationWindow::setMenuBar(QQuickItem *menuBar)
725 Q_D(QQuickApplicationWindow);
726 if (d->menuBar == menuBar)
730 QQuickItemPrivate::get(d->menuBar)->removeItemChangeListener(d, ItemChanges);
731 d->menuBar->setParentItem(
nullptr);
733 d->menuBar = menuBar;
735 menuBar->setParentItem(QQuickWindow::contentItem());
736 QQuickItemPrivate *p = QQuickItemPrivate::get(menuBar);
737 p->addItemChangeListener(d, ItemChanges);
738 if (qFuzzyIsNull(menuBar->z()))
742 menuBar->stackBefore(header());
744 menuBar->stackBefore(d->control);
746 if (isComponentComplete())
748 emit menuBarChanged();
751bool QQuickApplicationWindow::isComponentComplete()
const
753 Q_D(
const QQuickApplicationWindow);
754 return d->componentComplete;
757void QQuickApplicationWindow::classBegin()
759 Q_D(QQuickApplicationWindow);
760 d->componentComplete =
false;
761 QQuickWindowQmlImpl::classBegin();
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779 d->control =
new QQuickControl(QQuickWindow::contentItem());
780 d->control->setObjectName(
"ApplicationWindowContentControl");
781 auto *contentItem =
new QQuickContentItem(
this, d->control);
788 d->control->setContentItem(contentItem);
790 auto *context = qmlContext(
this);
791 auto installPropertyBinding = [&](QObject *targetObject,
const QString &targetPropertyName,
792 QObject *sourceObject,
const QString &sourcePropertyName) {
793 const QQmlProperty targetProperty(targetObject, targetPropertyName);
794 QQmlAnyBinding binding = QQmlPropertyToPropertyBinding::create(
795 context->engine(), QQmlProperty(sourceObject, sourcePropertyName), targetProperty);
796 binding.installOn(targetProperty);
804 auto *controlSafeArea = qmlAttachedPropertiesObject<QQuickSafeArea>(d->control);
805 installPropertyBinding(
this,
"leftPadding"_L1, controlSafeArea,
"margins.left"_L1);
806 installPropertyBinding(
this,
"topPadding"_L1, controlSafeArea,
"margins.top"_L1);
807 installPropertyBinding(
this,
"rightPadding"_L1, controlSafeArea,
"margins.right"_L1);
808 installPropertyBinding(
this,
"bottomPadding"_L1, controlSafeArea,
"margins.bottom"_L1);
811 auto *windowSafeArea =
static_cast<QQuickSafeArea*>(qmlAttachedPropertiesObject<QQuickSafeArea>(
this));
812 QObject::connect(windowSafeArea, &QQuickSafeArea::marginsChanged,
this, [d]{
817void QQuickApplicationWindow::componentComplete()
819 Q_D(QQuickApplicationWindow);
820 d->componentComplete =
true;
821 QQuickWindow::contentItem()->setObjectName(QQmlMetaType::prettyTypeName(
this));
822 d->executeBackground(
true);
823 QQuickWindowQmlImpl::componentComplete();
827void QQuickApplicationWindow::resizeEvent(QResizeEvent *event)
829 Q_D(QQuickApplicationWindow);
830 QQuickWindowQmlImpl::resizeEvent(event);
837 Q_DECLARE_PUBLIC(QQuickApplicationWindowAttached)
848 Q_Q(QQuickApplicationWindowAttached);
852 QQuickApplicationWindow *oldWindow = qobject_cast<QQuickApplicationWindow *>(window);
853 if (oldWindow && !QQuickApplicationWindowPrivate::get(oldWindow))
857 disconnect(oldWindow, &QQuickApplicationWindow::activeFocusControlChanged,
858 this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange);
859 QObject::disconnect(oldWindow, &QQuickApplicationWindow::menuBarChanged,
860 q, &QQuickApplicationWindowAttached::menuBarChanged);
861 QObject::disconnect(oldWindow, &QQuickApplicationWindow::headerChanged,
862 q, &QQuickApplicationWindowAttached::headerChanged);
863 QObject::disconnect(oldWindow, &QQuickApplicationWindow::footerChanged,
864 q, &QQuickApplicationWindowAttached::footerChanged);
866 disconnect(window, &QQuickWindow::activeFocusItemChanged,
867 this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange);
870 QQuickApplicationWindow *newWindow = qobject_cast<QQuickApplicationWindow *>(wnd);
872 connect(newWindow, &QQuickApplicationWindow::activeFocusControlChanged,
873 this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange);
874 QObject::connect(newWindow, &QQuickApplicationWindow::menuBarChanged,
875 q, &QQuickApplicationWindowAttached::menuBarChanged);
876 QObject::connect(newWindow, &QQuickApplicationWindow::headerChanged,
877 q, &QQuickApplicationWindowAttached::headerChanged);
878 QObject::connect(newWindow, &QQuickApplicationWindow::footerChanged,
879 q, &QQuickApplicationWindowAttached::footerChanged);
881 connect(wnd, &QQuickWindow::activeFocusItemChanged,
882 this, &QQuickApplicationWindowAttachedPrivate::activeFocusChange);
886 emit q->windowChanged();
887 emit q->contentItemChanged();
890 if ((oldWindow && oldWindow->menuBar()) || (newWindow && newWindow->menuBar()))
891 emit q->menuBarChanged();
892 if ((oldWindow && oldWindow->header()) || (newWindow && newWindow->header()))
893 emit q->headerChanged();
894 if ((oldWindow && oldWindow->footer()) || (newWindow && newWindow->footer()))
895 emit q->footerChanged();
900 Q_Q(QQuickApplicationWindowAttached);
901 QQuickItem *control =
nullptr;
902 if (QQuickApplicationWindow *appWindow = qobject_cast<QQuickApplicationWindow *>(window))
903 control = appWindow->activeFocusControl();
905 control = findActiveFocusControl(window);
906 if (activeFocusControl == control)
909 activeFocusControl = control;
910 emit q->activeFocusControlChanged();
913QQuickApplicationWindowAttached::QQuickApplicationWindowAttached(QObject *parent)
914 : QObject(*(
new QQuickApplicationWindowAttachedPrivate), parent)
916 Q_D(QQuickApplicationWindowAttached);
917 if (QQuickItem *item = qobject_cast<QQuickItem *>(parent)) {
918 d->windowChange(item->window());
919 QObjectPrivate::connect(item, &QQuickItem::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange);
921 QQuickItem *p = item;
923 if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(p->parent())) {
924 d->windowChange(popup->window());
925 QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange);
930 }
else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(parent)) {
931 d->windowChange(popup->window());
932 QObjectPrivate::connect(popup, &QQuickPopup::windowChanged, d, &QQuickApplicationWindowAttachedPrivate::windowChange);
937
938
939
940
941
942
943
944
945QQuickApplicationWindow *QQuickApplicationWindowAttached::window()
const
947 Q_D(
const QQuickApplicationWindowAttached);
948 return qobject_cast<QQuickApplicationWindow *>(d->window);
952
953
954
955
956
957
958
959
960QQuickItem *QQuickApplicationWindowAttached::contentItem()
const
962 Q_D(
const QQuickApplicationWindowAttached);
963 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
964 return window->contentItem();
969
970
971
972
973
974
975
976
977
978QQuickItem *QQuickApplicationWindowAttached::activeFocusControl()
const
980 Q_D(
const QQuickApplicationWindowAttached);
981 return d->activeFocusControl;
985
986
987
988
989
990
991
992
993
994QQuickItem *QQuickApplicationWindowAttached::header()
const
996 Q_D(
const QQuickApplicationWindowAttached);
997 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
998 return window->header();
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012QQuickItem *QQuickApplicationWindowAttached::footer()
const
1014 Q_D(
const QQuickApplicationWindowAttached);
1015 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
1016 return window->footer();
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031QQuickItem *QQuickApplicationWindowAttached::menuBar()
const
1033 Q_D(
const QQuickApplicationWindowAttached);
1034 if (QQuickApplicationWindow *window = qobject_cast<QQuickApplicationWindow *>(d->window))
1035 return window->menuBar();
1041#include "moc_qquickapplicationwindow_p.cpp"
QQuickItem * activeFocusControl
bool isInteractiveControlType(const QQuickItem *item)
static void layoutItem(QQuickItem *item, qreal y, qreal width)
static const QQuickItemPrivate::ChangeTypes ItemChanges
Styled top-level window with support for a header and footer.
static QQuickItem * findActiveFocusControl(QQuickWindow *window)