summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/controls/ApplicationWindow.qml44
-rw-r--r--src/controls/Private/ContentItem.qml109
-rw-r--r--src/controls/Private/private.pri1
-rw-r--r--src/controls/Private/qmldir1
-rw-r--r--tests/auto/controls/data/tst_applicationwindow.qml73
-rw-r--r--tests/manual/ApplicationWindow/main.qml186
6 files changed, 413 insertions, 1 deletions
diff --git a/src/controls/ApplicationWindow.qml b/src/controls/ApplicationWindow.qml
index 6e0160df2..f54fa8f51 100644
--- a/src/controls/ApplicationWindow.qml
+++ b/src/controls/ApplicationWindow.qml
@@ -115,6 +115,48 @@ Window {
*/
property Item statusBar
+ // The below documentation was supposed to be written as a grouped property, but qdoc would
+ // not render it correctly due to a bug (https://bugreports.qt-project.org/browse/QTBUG-34206)
+ /*!
+ \qmlproperty ApplicationWindow::contentItem
+
+ This group holds the size constraints of the content item. This is the area between the
+ \l ToolBar and the \l StatusBar.
+ The \l ApplicationWindow will use this as input when calculating the effective size
+ constraints of the actual window.
+ It holds these 6 properties for describing the minimum, implicit and maximum sizes:
+ \table
+ \header \li Grouped property \li Description
+ \row \li contentItem.minimumWidth \li The minimum width of the content item.
+ \row \li contentItem.minimumHeight \li The minimum height of the content item.
+ \row \li contentItem.implicitWidth \li The implicit width of the content item.
+ \row \li contentItem.implicitHeight \li The implicit height of the content item.
+ \row \li contentItem.maximumWidth \li The maximum width of the content item.
+ \row \li contentItem.maximumHeight \li The maximum height of the content item.
+ \endtable
+ */
+ property alias contentItem : contentArea
+
+ /*! \internal */
+ property real __topBottomMargins: contentArea.y + statusBarArea.height
+ /*! \internal
+ There is a similar macro QWINDOWSIZE_MAX in qwindow_p.h that is used to limit the
+ range of QWindow::maximum{Width,Height}
+ However, in case we have a very big number (> 2^31) conversion will fail, and it will be
+ converted to 0, resulting in that we will call setMaximumWidth(0)....
+ We therefore need to enforce the limit at a level where we are still operating on
+ floating point values.
+ */
+ readonly property real __qwindowsize_max: (1 << 24) - 1
+
+ width: contentArea.__noImplicitWidthGiven ? 0 : Math.min(Math.max(minimumWidth, contentArea.implicitWidth), maximumWidth)
+ height: contentArea.__noImplicitHeightGiven ? 0 : Math.min(Math.max(minimumHeight, contentArea.implicitHeight + __topBottomMargins), maximumHeight)
+
+ minimumWidth: contentArea.__noMinimumWidthGiven ? 0 : contentArea.minimumWidth
+ minimumHeight: contentArea.__noMinimumHeightGiven ? 0 : (contentArea.minimumHeight + __topBottomMargins)
+
+ maximumWidth: Math.min(__qwindowsize_max, contentArea.maximumWidth)
+ maximumHeight: Math.min(__qwindowsize_max, contentArea.maximumHeight + __topBottomMargins)
onToolBarChanged: { if (toolBar) { toolBar.parent = toolBarArea } }
onStatusBarChanged: { if (statusBar) { statusBar.parent = statusBarArea } }
@@ -140,7 +182,7 @@ Window {
Keys.forwardTo: menuBar ? [menuBar.__contentItem] : []
- Item {
+ ContentItem {
id: contentArea
anchors.top: toolBarArea.bottom
anchors.left: parent.left
diff --git a/src/controls/Private/ContentItem.qml b/src/controls/Private/ContentItem.qml
new file mode 100644
index 000000000..dbb4a50e2
--- /dev/null
+++ b/src/controls/Private/ContentItem.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Layouts 1.1
+
+Item {
+ id: contentItem
+ property real minimumWidth: __calcMinimum('Width')
+ property real minimumHeight: __calcMinimum('Height')
+ property real maximumWidth: __calcMaximum('Width')
+ property real maximumHeight: __calcMaximum('Height')
+ implicitWidth: __calcImplicitWidth()
+ implicitHeight: __calcImplicitHeight()
+
+ /*! \internal */
+ property Item __layoutItem: contentItem.children.length === 1 ? contentItem.children[0] : null
+ /*! \internal */
+ property real __marginsWidth: __layoutItem ? __layoutItem.anchors.leftMargin + __layoutItem.anchors.rightMargin : 0
+ /*! \internal */
+ property real __marginsHeight: __layoutItem ? __layoutItem.anchors.topMargin + __layoutItem.anchors.bottomMargin : 0
+
+ /*! \internal */
+ property bool __noMinimumWidthGiven : false
+ /*! \internal */
+ property bool __noMinimumHeightGiven : false
+ /*! \internal */
+ property bool __noImplicitWidthGiven : false
+ /*! \internal */
+ property bool __noImplicitHeightGiven : false
+
+ function __calcImplicitWidth() {
+ if (__layoutItem && __layoutItem.anchors.fill)
+ return __calcImplicit('Width')
+ return contentItem.childrenRect.x + contentItem.childrenRect.width
+ }
+
+ function __calcImplicitHeight() {
+ if (__layoutItem && __layoutItem.anchors.fill)
+ return __calcImplicit('Height')
+ return contentItem.childrenRect.y + contentItem.childrenRect.height
+ }
+
+ function __calcImplicit(hw) {
+ var pref = __layoutItem.Layout['preferred' + hw]
+ if (pref < 0) {
+ pref = __layoutItem['implicit' + hw]
+ }
+ contentItem['__noImplicit' + hw + 'Given'] = (pref === 0 ? true : false)
+ pref += contentItem['__margins' + hw]
+ return pref
+ }
+
+ function __calcMinimum(hw) { // hw is 'Width' or 'Height'
+ return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('minimum', hw) : 0
+ }
+
+ function __calcMaximum(hw) { // hw is 'Width' or 'Height'
+ return (__layoutItem && __layoutItem.anchors.fill) ? __calcMinMax('maximum', hw) : Number.POSITIVE_INFINITY
+ }
+
+ function __calcMinMax(minMaxConstraint, hw) {
+ var attachedPropName = minMaxConstraint + hw
+ var extent = __layoutItem.Layout[attachedPropName]
+
+ if (minMaxConstraint === 'minimum')
+ contentItem['__noMinimum' + hw + 'Given'] = (extent === 0 ? true : false)
+
+ extent += contentItem['__margins' + hw]
+ return extent
+ }
+}
diff --git a/src/controls/Private/private.pri b/src/controls/Private/private.pri
index 304649745..7852edffb 100644
--- a/src/controls/Private/private.pri
+++ b/src/controls/Private/private.pri
@@ -45,6 +45,7 @@ PRIVATE_QML_FILES += \
$$PWD/ColumnMenuContent.qml \
$$PWD/MenuContentItem.qml \
$$PWD/MenuContentScroller.qml \
+ $$PWD/ContentItem.qml \
$$PWD/qmldir
QML_FILES += $$PRIVATE_QML_FILES
diff --git a/src/controls/Private/qmldir b/src/controls/Private/qmldir
index 351387806..5dc8061cd 100644
--- a/src/controls/Private/qmldir
+++ b/src/controls/Private/qmldir
@@ -19,4 +19,5 @@ ToolButtonStyle 1.0 ../Styles/Base/ToolButtonStyle.qml
MenuContentItem 1.0 MenuContentItem.qml
MenuContentScroller 1.0 MenuContentScroller.qml
ColumnMenuContent 1.0 ColumnMenuContent.qml
+ContentItem 1.0 ContentItem.qml
singleton TextSingleton 1.0 TextSingleton.qml
diff --git a/tests/auto/controls/data/tst_applicationwindow.qml b/tests/auto/controls/data/tst_applicationwindow.qml
index e424cc2d5..590231f45 100644
--- a/tests/auto/controls/data/tst_applicationwindow.qml
+++ b/tests/auto/controls/data/tst_applicationwindow.qml
@@ -94,5 +94,78 @@ TestCase {
verify(contentArea.height < oldHeight)
window.destroy()
}
+
+
+ function test_defaultContentItemConstraints_data() {
+ return [
+ { tag: "height",
+ input: {height: 100},
+ expected: {implicitHeight: 100} },
+ { tag: "height_y",
+ input: {height: 100, y: 10},
+ expected: {implicitHeight: 110} },
+ { tag: "height_implicitHeight_anchorsFill",
+ input: {height: 100, implicitHeight: 10, anchorsFill: true},
+ expected: {implicitHeight: 10} },
+ { tag: "height_implicitHeight_anchorsFill_margins",
+ input: {height: 100, implicitHeight: 10, anchorsFill: true, anchors_margins: 20},
+ expected: {implicitHeight: 50} },
+ { tag: "height_anchorsFill_margins",
+ input: {height: 100, anchorsFill: true, anchors_margins: 20},
+ expected: {implicitHeight: 40} },
+ { tag: "anchorsFill_margins", //Rectangle { anchors.fill: parent; anchors.margins: 20 }
+ input: {anchorsFill: true, anchors_margins: 20},
+ expected: {implicitHeight: 40} },
+ { tag: "anchorsFill_margins0", //Rectangle { anchors.fill: parent; anchors.margins: 0 }
+ input: {anchorsFill: true, anchors_margins: 0},
+ expected: {implicitHeight: 0} },
+ { tag: "minimum_implicit_maximum_anchorsFill",
+ input: {anchorsFill: true, Layout_minimumHeight: 10, implicitHeight: 100, Layout_maximumHeight: 150},
+ expected: {minimumHeight: 10, implicitHeight: 100, maximumHeight: 150} },
+ { tag: "minimum_implicit_maximum_anchorsFill_margins",
+ input: {anchorsFill: true, anchors_margins: 20, Layout_minimumHeight: 10, implicitHeight: 100, Layout_maximumHeight: 150},
+ expected: {minimumHeight: 50, implicitHeight: 140, maximumHeight: 190} },
+ { tag: "minimum_height_maximum_anchorsFill",
+ input: {anchorsFill: true, Layout_minimumHeight: 0, height: 100, Layout_maximumHeight: 150},
+ expected: {minimumHeight: 0, implicitHeight: 0, maximumHeight: 150} },
+ ];
+ }
+ function test_defaultContentItemConstraints(data) {
+ var input = data.input
+ var expected = data.expected
+
+ var str = ''
+ // serialize....
+ for (var varName in input) {
+ var realName = varName.replace('_', '.')
+ // anchorsFill is special...
+ if (realName === 'anchorsFill') {
+ str += 'anchors.fill:parent;'
+ } else if (input[varName] !== undefined) {
+ // serialize the other properties...
+ str += realName + ':' + input[varName] +';'
+ }
+ }
+
+ var test_control = 'import QtQuick 2.1; \
+ import QtQuick.Controls 1.1; \
+ import QtQuick.Layouts 1.1; \
+ ApplicationWindow { \
+ id: window; \
+ Rectangle { \
+ id: rect; \
+ color: \'red\'; \
+ ' + str + '\
+ } \
+ } '
+
+ var window = Qt.createQmlObject(test_control, container, '')
+ wait(0)
+
+ for (var propName in expected) {
+ compare(window.contentItem[propName], expected[propName])
+ }
+ }
+
}
}
diff --git a/tests/manual/ApplicationWindow/main.qml b/tests/manual/ApplicationWindow/main.qml
new file mode 100644
index 000000000..a9a64ac54
--- /dev/null
+++ b/tests/manual/ApplicationWindow/main.qml
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the Qt Quick Controls module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+
+
+
+import QtQuick 2.1
+import QtQuick.Controls 1.1
+import QtQuick.Layouts 1.1
+
+
+ApplicationWindow {
+ id: window
+ title: "Window constraints"
+
+ property var g_content: canvas_Component.createObject(contentItem)
+
+ menuBar: MenuBar {
+ Menu {
+ title: "Options"
+ MenuItem {
+ id: ckToolBarVisible
+ text: "Show ToolBar"
+ checkable: true
+ checked: true
+ }
+ MenuItem {
+ id: ckStatusBarVisible
+ text: "Show StatusBar"
+ checkable: true
+ checked: true
+ }
+ MenuItem {
+ id: ckUseLayout
+ text: "Use layout"
+ checkable: true
+ checked: false
+ onCheckedChanged: {
+ if (g_content) {
+ g_content.destroy()
+ }
+ if (checked) {
+ g_content = layout_Component.createObject(contentItem)
+ } else {
+ g_content = canvas_Component.createObject(contentItem)
+ }
+ }
+ }
+ }
+ }
+
+
+ toolBar: ToolBar {
+ visible: ckToolBarVisible.checked
+ Row {
+ ToolButton {
+ text: "One"
+ }
+ ToolButton {
+ text: "Two"
+ }
+ }
+ }
+
+ statusBar: StatusBar {
+ visible: ckStatusBarVisible.checked
+ Row {
+ Label {
+ text: "Window size:(" + window.width + "x" + window.height + ")"
+ }
+ }
+ }
+
+ Component {
+ id: layout_Component
+ GridLayout {
+ id: layout
+ anchors.fill: parent
+ rowSpacing: 2
+ columnSpacing: 2
+ columns: 5
+ Repeater {
+ model: 10
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ color: 'red'
+ Layout.minimumWidth: 30
+ Layout.minimumHeight: 30
+ implicitWidth: 42
+ implicitHeight: 42
+ Layout.maximumWidth: 200
+ Layout.maximumHeight: 200
+ Text {
+ anchors.centerIn: parent
+ text: parent.width + "x" + parent.height
+ }
+ }
+ }
+ }
+ }
+
+
+ Component {
+ id: canvas_Component
+ Canvas {
+ id: canvas
+ width: 200
+ height: 200
+ antialiasing: false
+
+ onPaint: {
+ var ctx = getContext('2d')
+ if (ctx) {
+ ctx.save()
+ ctx.fillStyle = "#e0e0e0"
+ ctx.strokeStyle = "#000000"
+ ctx.lineWidth = 1
+
+
+ ctx.fillRect(0, 0, canvas.width, canvas.height)
+
+ ctx.fillStyle = "#000000"
+ ctx.strokeStyle = "#000000"
+ ctx.antiAliasing= false
+
+ ctx.beginPath();
+ for (var x = 5; x < Math.max(canvas.width, canvas.height); x+=5) {
+ var extent = 2
+ if (x % 100 == 0)
+ extent = 10
+ else if (x % 10 == 0)
+ extent = 5
+ else extent = 2
+ ctx.moveTo(x, 0)
+ ctx.lineTo(x, 0 + extent)
+ ctx.moveTo(0, x)
+ ctx.lineTo(0 + extent, x)
+ }
+ ctx.closePath()
+ ctx.stroke()
+
+ ctx.restore()
+ }
+ }
+ }
+ }
+}