From 9490e1161817ad74d5441db79bd8bde5c8c8db91 Mon Sep 17 00:00:00 2001
From: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Date: Wed, 29 May 2013 18:43:37 +0200
Subject: [PATCH] Fix missing margins and incorrect size for ToolBar and
 StatusBar

Using the implicitHeight of an item makes ToolBar and StatusBar
a lot more useable with layouts. In addition we enable the padding
property from the style, allowing its content to be positioned
in a more convenient way. This is similar to how we already do it
for GroupBox.

Change-Id: Ia2aa1bcb9ae109718fd752401400222adec242ac
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
---
 src/controls/StatusBar.qml            | 82 +++++++++++++++++++++++----
 src/controls/ToolBar.qml              | 81 ++++++++++++++++++++++----
 src/private/qquickstyleitem.cpp       |  2 +-
 src/styles/Base/StatusBarStyle.qml    | 13 +++--
 src/styles/Base/ToolBarStyle.qml      | 35 +++++++-----
 src/styles/Desktop/StatusBarStyle.qml | 15 +++--
 src/styles/Desktop/ToolBarStyle.qml   | 14 +++--
 7 files changed, 191 insertions(+), 51 deletions(-)

diff --git a/src/controls/StatusBar.qml b/src/controls/StatusBar.qml
index 13edc5eff..068b6b200 100644
--- a/src/controls/StatusBar.qml
+++ b/src/controls/StatusBar.qml
@@ -52,14 +52,20 @@ import QtQuick.Controls.Private 1.0
     The common way of using StatusBar is in relation to \l ApplicationWindow.
 
     Note that the StatusBar does not provide a layout of its own, but requires
-    you to position its contents, for instance by creating a \l Row.
+    you to position its contents, for instance by creating a \l RowLayout.
+
+    If only a single item is used within the StatusBar, it will resize to fit the implicitHeight
+    of its contained item. This makes it particularly suitable for use together with layouts.
+    Otherwise the height is platform dependent.
 
     \code
+    import QtQuick.Controls 1.0
+    import QtQuick.Layouts 1.0
+
     ApplicationWindow {
         statusBar: StatusBar {
-            Label {
-                text: "Read Only"
-                anchors.centerIn: parent
+            RowLayout {
+                Label { text: "Read Only" }
             }
         }
     }
@@ -68,16 +74,68 @@ import QtQuick.Controls.Private 1.0
 
 Item {
     id: statusbar
+
     activeFocusOnTab: false
     Accessible.role: Accessible.StatusBar
+
     width: parent ? parent.width : implicitWidth
-    implicitWidth: loader.item.implicitHeight
-    implicitHeight: loader.item ? loader.item.implicitHeight : 0
+    implicitWidth:  loader.item ? loader.item.implicitWidth : 200
+    implicitHeight: Math.max(container.topMargin + container.bottomMargin + container.calcHeight(),
+                             loader.item ? loader.item.implicitHeight : 19)
+
+    /*! \internal */
     property Component style: Qt.createComponent(Settings.style + "/StatusBarStyle.qml", statusbar)
-    Loader {
-        id: loader
-        anchors.fill: parent
-        sourceComponent: style
-        property var __control: statusbar
-    }
+
+    /*! \internal */
+    property alias __style: styleLoader.item
+
+    /*! \internal */
+    default property alias __content: container.data
+
+    /*!
+        \qmlproperty Item StatusBar::contentItem
+
+        This property holds the content Item of the status bar.
+
+        Items declared as children of a StatusBar are automatically parented to the StatusBar's contentItem.
+        Items created dynamically need to be explicitly parented to the contentItem:
+
+        \note The implicit size of the StatusBar is calculated based on the size of its content. If you want to anchor
+        items inside the status bar, you must specify an explicit width and height on the StatusBar itself.
+    */
+    readonly property alias contentItem: container
+
+    data: [
+        Loader {
+            id: loader
+            anchors.fill: parent
+            sourceComponent: styleLoader.item ? styleLoader.item.panel : null
+            onLoaded: item.z = -1
+            Loader {
+                id: styleLoader
+                property alias __control: statusbar
+                sourceComponent: style
+            }
+        },
+        Item {
+            id: container
+            z: 1
+            focus: true
+            anchors.fill: parent
+
+            anchors.topMargin: topMargin
+            anchors.leftMargin: leftMargin
+            anchors.rightMargin: rightMargin
+            anchors.bottomMargin: bottomMargin
+
+            property int topMargin: __style ? __style.padding.top : 0
+            property int bottomMargin: __style ? __style.padding.bottom : 0
+            property int leftMargin: __style ? __style.padding.left : 0
+            property int rightMargin: __style ? __style.padding.right : 0
+
+            property Item layoutItem: container.children.length === 1 ? container.children[0] : null
+            function calcHeight () { return (layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
+                                                          (layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
+                                                                                     layoutItem.anchors.bottomMargin : 0) : loader.item ? loader.item.implicitHeight : 0) }
+        }]
 }
diff --git a/src/controls/ToolBar.qml b/src/controls/ToolBar.qml
index d2adea56a..e5cc84191 100644
--- a/src/controls/ToolBar.qml
+++ b/src/controls/ToolBar.qml
@@ -53,13 +53,20 @@ import QtQuick.Controls.Private 1.0
     provides styling and is generally designed to work well with ToolButton as
     well as other controls.
 
-    Note that the ToolBar does not provide a layout of its own, but requires you
-    to position its contents, for instance by creating a Row.
+    Note that the ToolBar does not provide a layout of its own, but requires
+    you to position its contents, for instance by creating a \l RowLayout.
+
+    If only a single item is used within the ToolBar, it will resize to fit the implicitHeight
+    of its contained item. This makes it particularly suitable for use together with layouts.
+    Otherwise the height is platform dependent.
 
     \code
+    import QtQuick.Controls 1.0
+    import QtQuick.Layouts 1.0
+
     ApplicationWindow {
         toolBar: ToolBar {
-            Row {
+            RowLayout {
                 ToolButton { ... }
                 ToolButton { ... }
                 ToolButton { ... }
@@ -71,16 +78,68 @@ import QtQuick.Controls.Private 1.0
 
 Item {
     id: toolbar
+
     activeFocusOnTab: false
     Accessible.role: Accessible.ToolBar
+
     width: parent ? parent.width : implicitWidth
-    implicitWidth: loader.item ? loader.item.implicitWidth : 0
-    implicitHeight: loader.item ? loader.item.implicitHeight : 0
+    implicitWidth:  loader.item ? loader.item.implicitWidth : 200
+    implicitHeight: container.topMargin + container.bottomMargin + container.calcHeight()
+
+    /*! \internal */
     property Component style: Qt.createComponent(Settings.style + "/ToolBarStyle.qml", toolbar)
-    Loader {
-        id: loader
-        anchors.fill: parent
-        sourceComponent: style
-        property var __control: toolbar
-    }
+
+    /*! \internal */
+    property alias __style: styleLoader.item
+
+    /*! \internal */
+    default property alias __content: container.data
+
+    /*!
+        \qmlproperty Item ToolBar::contentItem
+
+        This property holds the content Item of the tool bar.
+
+        Items declared as children of a ToolBar are automatically parented to the ToolBar's contentItem.
+        Items created dynamically need to be explicitly parented to the contentItem:
+
+        \note The implicit size of the ToolBar is calculated based on the size of its content. If you want to anchor
+        items inside the tool bar, you must specify an explicit width and height on the ToolBar itself.
+    */
+    readonly property alias contentItem: container
+
+    data: [
+        Loader {
+            id: loader
+            anchors.fill: parent
+            sourceComponent: styleLoader.item ? styleLoader.item.panel : null
+            onLoaded: item.z = -1
+            Loader {
+                id: styleLoader
+                property alias __control: toolbar
+                sourceComponent: style
+            }
+        },
+        Item {
+            id: container
+            z: 1
+            focus: true
+            anchors.fill: parent
+
+            anchors.topMargin: topMargin
+            anchors.leftMargin: leftMargin
+            anchors.rightMargin: rightMargin
+            anchors.bottomMargin: bottomMargin
+
+            property int topMargin: __style ? __style.padding.top : 0
+            property int bottomMargin: __style ? __style.padding.bottom : 0
+            property int leftMargin: __style ? __style.padding.left : 0
+            property int rightMargin: __style ? __style.padding.right : 0
+
+            property Item layoutItem: container.children.length === 1 ? container.children[0] : null
+            function calcHeight () { return (layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
+                                                          (layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
+                                                                                     layoutItem.anchors.bottomMargin : 0) :
+                                                          loader.item ? loader.item.implicitHeight : 0) }
+        }]
 }
diff --git a/src/private/qquickstyleitem.cpp b/src/private/qquickstyleitem.cpp
index 71d98bb60..115841adf 100644
--- a/src/private/qquickstyleitem.cpp
+++ b/src/private/qquickstyleitem.cpp
@@ -734,7 +734,7 @@ QSize QQuickStyleItem::sizeFromContents(int width, int height)
         size =  qApp->style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height));
         break;
     case ToolBar:
-        size = QSize(200, 40);
+        size = QSize(200, style().contains("windows") ? 30 : 42);
         break;
     case ToolButton: {
         QStyleOptionToolButton *btn = qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
diff --git a/src/styles/Base/StatusBarStyle.qml b/src/styles/Base/StatusBarStyle.qml
index 049b15f20..e8abe19ba 100644
--- a/src/styles/Base/StatusBarStyle.qml
+++ b/src/styles/Base/StatusBarStyle.qml
@@ -47,13 +47,16 @@ import QtQuick.Controls.Private 1.0
     \inqmlmodule QtQuick.Controls.Styles 1.0
     \since QtQuick.Controls.Styles 1.0
 */
-Item {
-    implicitHeight: 22
-    implicitWidth: 200
+Style {
 
-    Rectangle {
+    padding.left: 3
+    padding.right: 3
+    padding.top: 3
+    padding.bottom: 2
 
-        anchors.fill: parent
+    property Component panel: Rectangle {
+        implicitHeight: 16
+        implicitWidth: 200
 
         gradient: Gradient{
             GradientStop{color: "#eee" ; position: 0}
diff --git a/src/styles/Base/ToolBarStyle.qml b/src/styles/Base/ToolBarStyle.qml
index aa21195ac..835f82196 100644
--- a/src/styles/Base/ToolBarStyle.qml
+++ b/src/styles/Base/ToolBarStyle.qml
@@ -39,26 +39,35 @@
 ****************************************************************************/
 import QtQuick 2.1
 import QtQuick.Controls 1.0
+import QtQuick.Controls.Private 1.0
 
 /*!
     \qmltype ToolBarStyle
     \internal
     \inqmlmodule QtQuick.Controls.Styles 1.0
 */
-Item {
-    implicitHeight: 42
-    implicitWidth: 200
-    Rectangle {
-        anchors.fill: parent
-        gradient: Gradient{
-            GradientStop{color: "#eee" ; position: 0}
-            GradientStop{color: "#ccc" ; position: 1}
-        }
+Style {
+
+    padding.left: 6
+    padding.right: 6
+    padding.top: 3
+    padding.bottom: 3
+
+    property Component panel: Item {
+        implicitHeight: 40
+        implicitWidth: 200
         Rectangle {
-            anchors.bottom: parent.bottom
-            width: parent.width
-            height: 1
-            color: "#999"
+            anchors.fill: parent
+            gradient: Gradient{
+                GradientStop{color: "#eee" ; position: 0}
+                GradientStop{color: "#ccc" ; position: 1}
+            }
+            Rectangle {
+                anchors.bottom: parent.bottom
+                width: parent.width
+                height: 1
+                color: "#999"
+            }
         }
     }
 }
diff --git a/src/styles/Desktop/StatusBarStyle.qml b/src/styles/Desktop/StatusBarStyle.qml
index 6921a2fe5..930ca773c 100644
--- a/src/styles/Desktop/StatusBarStyle.qml
+++ b/src/styles/Desktop/StatusBarStyle.qml
@@ -46,11 +46,16 @@ import QtQuick.Controls.Private 1.0
     \internal
     \inqmlmodule QtQuick.Controls.Styles 1.0
 */
-Item {
-    implicitHeight: 20
-    implicitWidth: parent ? parent.width : style.implicitWidth
-    StyleItem {
-        id: style
+Style {
+
+    padding.left: 4
+    padding.right: 4
+    padding.top: 3
+    padding.bottom: 2
+
+    property Component panel: StyleItem {
+        implicitHeight: 16
+        implicitWidth: 200
         anchors.fill: parent
         elementType: "statusbar"
     }
diff --git a/src/styles/Desktop/ToolBarStyle.qml b/src/styles/Desktop/ToolBarStyle.qml
index 4c7e036ec..56dfbce38 100644
--- a/src/styles/Desktop/ToolBarStyle.qml
+++ b/src/styles/Desktop/ToolBarStyle.qml
@@ -46,10 +46,16 @@ import QtQuick.Controls.Private 1.0
     \internal
     \inqmlmodule QtQuick.Controls.Styles 1.0
 */
-Item {
-    implicitHeight: Math.max(childrenRect.height, toolbar.implicitHeight)
-    implicitWidth: parent ? parent.width : toolbar.implicitWidth
-    StyleItem {
+Style {
+
+    padding.left: 6
+    padding.right: 6
+    padding.top: 1
+    padding.bottom: style.style == "mac" ? 1 : 2
+
+    StyleItem { id: style ; visible: false}
+
+    property Component panel: StyleItem {
         id: toolbar
         anchors.fill: parent
         elementType: "toolbar"
-- 
GitLab