From bb64aef56bd43891bd6f91aee25bdfe6633c3a98 Mon Sep 17 00:00:00 2001
From: Jens Bache-Wiig <jens.bache-wiig@digia.com>
Date: Mon, 27 May 2013 17:54:54 +0200
Subject: [PATCH] Refactor TableView styling API

We don't want to directly expose the item properties in
the namespace of the loader. Instead we standardize on
styleData as a property container.

Change-Id: Ib451e06ab393ba4945c96076d71dd3f96489e0c7
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
---
 examples/quick/controls/tableview/main.qml    |  86 ++++++-------
 src/controls/TableView.qml                    | 119 ++++++++++--------
 src/styles/Base/TableViewStyle.qml            |  23 ++--
 src/styles/Desktop/TableViewStyle.qml         |  28 +++--
 .../data/tableview/table_delegate.qml         |   6 +-
 5 files changed, 134 insertions(+), 128 deletions(-)

diff --git a/examples/quick/controls/tableview/main.qml b/examples/quick/controls/tableview/main.qml
index 0e5683147..02c7e6f02 100644
--- a/examples/quick/controls/tableview/main.qml
+++ b/examples/quick/controls/tableview/main.qml
@@ -183,7 +183,7 @@ Window {
 
                     itemDelegate: Item {
                         Rectangle{
-                            color: itemValue.get(0).color
+                            color: styleData.value.get(0).color
                             anchors.top:parent.top
                             anchors.right:parent.right
                             anchors.bottom:parent.bottom
@@ -196,9 +196,9 @@ Window {
                             anchors.margins: 4
                             anchors.left: parent.left
                             anchors.verticalCenter: parent.verticalCenter
-                            elide: itemElideMode
-                            text: itemValue.get(0).description
-                            color: itemTextColor
+                            elide: styleData.elideMode
+                            text: styleData.value.get(0).description
+                            color: styleData.textColor
                         }
                     }
 
@@ -251,32 +251,23 @@ Window {
                                 anchors.margins: 4
                                 anchors.left: parent.left
                                 anchors.verticalCenter: parent.verticalCenter
-                                elide: itemElideMode
-                                text: itemValue !== undefined  ? itemValue : ""
-                                color: itemTextColor
+                                elide: styleData.elideMode
+                                text: styleData.value !== undefined  ? styleData.value : ""
+                                color: styleData.textColor
                             }
                         }
                     }
 
-                    Component {
-                        id: slickRowDelegate
-                        Rectangle { color: alternateBackground ? "#cef" : "white" }
-                    }
-
                     Component {
                         id: delegate2
-                        Item {
-                            height: itemSelected? 60 : 20
-                            Behavior on height{ NumberAnimation{} }
-                            Text {
-                                width: parent.width
-                                anchors.margins: 4
-                                anchors.left: parent.left
-                                anchors.verticalCenter: parent.verticalCenter
-                                elide: itemElideMode
-                                text: itemValue !== undefined  ? itemValue : ""
-                                color: itemTextColor
-                            }
+                        Text {
+                            width: parent.width
+                            anchors.margins: 4
+                            anchors.left: parent.left
+                            anchors.verticalCenter: parent.verticalCenter
+                            elide: styleData.elideMode
+                            text: styleData.value !== undefined  ? styleData.value : ""
+                            color: styleData.textColor
                         }
                     }
 
@@ -289,10 +280,10 @@ Window {
                                 anchors.margins: 4
                                 anchors.left: parent.left
                                 anchors.verticalCenter: parent.verticalCenter
-                                elide: itemElideMode
-                                text: itemValue !== undefined ? itemValue : ""
-                                color: itemTextColor
-                                visible: !itemSelected
+                                elide: styleData.elideMode
+                                text: styleData.value !== undefined ? styleData.value : ""
+                                color: styleData.textColor
+                                visible: !styleData.selected
                             }
                             Loader { // Initialize text editor lazily to improve performance
                                 id: loaderEditor
@@ -301,19 +292,19 @@ Window {
                                 Connections {
                                     target: loaderEditor.item
                                     onAccepted: {
-                                        if (typeof itemValue === 'number')
-                                            model.setProperty(row, role, Number(parseFloat(loaderEditor.item.text).toFixed(0)))
+                                        if (typeof styleData.value === 'number')
+                                            model.setProperty(styleData.row, styleData.role, Number(parseFloat(loaderEditor.item.text).toFixed(0)))
                                         else
-                                            model.setProperty(row, role, loaderEditor.item.text)
+                                            model.setProperty(styleData.row, styleData.role, loaderEditor.item.text)
                                     }
                                 }
-                                sourceComponent: itemSelected ? editor : null
+                                sourceComponent: styleData.selected ? editor : null
                                 Component {
                                     id: editor
                                     TextInput {
                                         id: textinput
-                                        color: itemTextColor
-                                        text: itemValue
+                                        color: styleData.textColor
+                                        text: styleData.value
                                         MouseArea {
                                             id: mouseArea
                                             anchors.fill: parent
@@ -354,25 +345,22 @@ Window {
                             source: "images/header.png"
                             border{left:2;right:2;top:2;bottom:2}
                             Text {
-                                text: itemValue
+                                text: styleData.value
                                 anchors.centerIn:parent
                                 color:"#333"
                             }
                         }
 
                         rowDelegate: Rectangle {
-                            height: 20
-                            color: rowSelected ? "#448" : (alternateBackground ? "#eee" : "#fff")
-                            border.color:"#ccc"
-                            border.width: 1
-                            anchors.left: parent ? parent.left : undefined
-                            anchors.leftMargin: -2
-                            anchors.rightMargin: -1
+                            height: (delegateChooser.currentIndex == 1 && styleData.selected) ? 30 : 20
+                            Behavior on height{ NumberAnimation{} }
+
+                            color: styleData.selected ? "#448" : (styleData.alternate? "#eee" : "#fff")
                             BorderImage{
                                 id: selected
                                 anchors.fill: parent
                                 source: "images/selectedrow.png"
-                                visible: rowSelected
+                                visible: styleData.selected
                                 border{left:2; right:2; top:2; bottom:2}
                                 SequentialAnimation {
                                     running: true; loops: Animation.Infinite
@@ -383,14 +371,10 @@ Window {
                         }
 
                         itemDelegate: {
-                            switch (delegateChooser.currentIndex) {
-                            case 0:
-                                return delegate1
-                            case 1:
-                                return delegate2
-                            case 2:
-                                return editableDelegate
-                            }
+                            if (delegateChooser.currentIndex == 2)
+                                return editableDelegate;
+                            else
+                                return delegate1;
                         }
                     }
                 }
diff --git a/src/controls/TableView.qml b/src/controls/TableView.qml
index ca0df45a1..4cde5d3e3 100644
--- a/src/controls/TableView.qml
+++ b/src/controls/TableView.qml
@@ -128,22 +128,23 @@ ScrollView {
 
     In the item delegate you have access to the following special properties:
     \list
-    \li  itemSelected - if the item is currently selected
-    \li  itemValue - the value or text for this item
-    \li  itemTextColor - the default text color for an item
-    \li  row - the index of the row
-    \li  column - the index of the column
-    \li  itemElideMode - the elide mode of the column
-    \li  itemTextAlignment - the horizontal text alignment of the column
+    \li  styleData.selected - if the item is currently selected
+    \li  styleData.value - the value or text for this item
+    \li  styleData.textColor - the default text color for an item
+    \li  styleData.row - the index of the row
+    \li  styleData.column - the index of the column
+    \li  styleData.elideMode - the elide mode of the column
+    \li  styleData.textAlignment - the horizontal text alignment of the column
     \endlist
+
     Example:
     \code
     itemDelegate: Item {
         Text {
             anchors.verticalCenter: parent.verticalCenter
-            color: itemTextColor
-            elide: itemElideMode
-            text: itemValue
+            color: styleData.textColor
+            elide: styleData.elideMode
+            text: styleData.value
         }
     }
     \endcode */
@@ -153,9 +154,9 @@ ScrollView {
 
     In the row delegate you have access to the following special properties:
     \list
-    \li  alternateBackground - if the row uses the alternate background color
-    \li  rowSelected - if the row is currently selected
-    \li  index - the index of the row
+    \li  styleData.alternate - true when the row uses the alternate background color
+    \li  styleData.selected - true when the row is currently selected
+    \li  styleData.row - the index of the row
     \endlist
     */
     property Component rowDelegate: __style ? __style.rowDelegate : null
@@ -166,7 +167,16 @@ ScrollView {
         The default value is the base color of the SystemPalette. */
     property alias backgroundColor: colorRect.color
 
-    /*! This property defines a delegate to draw a header. */
+    /*! This property defines a delegate to draw a header.
+
+    In the header delegate you have access to the following special properties:
+    \list
+    \li  styleData.value - the value or text for this item
+    \li  styleData.column - the index of the column
+    \li  styleData.pressed - true when the column is being pressed
+    \li  styleData.containsMouse - true when the column is under the mouse
+    \endlist
+    */
     property Component headerDelegate: __style ? __style.headerDelegate : null
 
     /*! Index of the current sort column.
@@ -408,11 +418,13 @@ ScrollView {
                     width: rowfiller.width
                     height: rowfiller.rowHeight
                     sourceComponent: root.rowDelegate
-                    readonly property bool alternateBackground: (index + rowCount) % 2 === 1
-                    readonly property bool rowSelected: false
+                    property QtObject styleData: QtObject {
+                        readonly property bool alternate: (index + rowCount) % 2 === 1
+                        readonly property bool selected: false
+                        readonly property bool hasActiveFocus: root.activeFocus
+                    }
                     readonly property var model: listView.model
                     readonly property var modelData: null
-                    readonly property bool hasActiveFocus: root.activeFocus
                 }
             }
         }
@@ -439,7 +451,7 @@ ScrollView {
             height: rowstyle.height
 
             readonly property int rowIndex: model.index
-            readonly property bool alternateBackground: alternatingRowColors && rowIndex % 2 == 1
+            readonly property bool alternate: alternatingRowColors && rowIndex % 2 == 1
             readonly property var itemModelData: typeof modelData == "undefined" ? null : modelData
             readonly property var itemModel: model
             readonly property bool itemSelected: ListView.isCurrentItem
@@ -457,12 +469,14 @@ ScrollView {
 
                 // these properties are exposed to the row delegate
                 // Note: these properties should be mirrored in the row filler as well
-                readonly property bool alternateBackground: rowitem.alternateBackground
-                readonly property bool rowSelected: rowitem.itemSelected
-                readonly property int row: rowitem.rowIndex
+                property QtObject styleData: QtObject {
+                    readonly property int row: rowitem.rowIndex
+                    readonly property bool alternate: rowitem.alternate
+                    readonly property bool selected: rowitem.itemSelected
+                    readonly property bool hasActiveFocus: root.activeFocus
+                }
                 readonly property var model: listView.model
                 readonly property var modelData: rowitem.itemModelData
-                readonly property bool hasActiveFocus: root.activeFocus
             }
             Row {
                 id: itemrow
@@ -482,20 +496,22 @@ ScrollView {
                         readonly property var model: listView.model
                         readonly property var modelData: itemModelData
 
-                        readonly property var itemValue: __hasModelRole ? itemModel[role] // Qml ListModel and QAbstractItemModel
-                                                                        : __hasModelDataRole ? modelData[role] // QObjectList / QObject
-                                                                        : modelData != undefined ? modelData : "" // Models without role
-                        readonly property bool itemSelected: rowitem.itemSelected
-                        readonly property color itemTextColor: rowitem.itemTextColor
-                        readonly property int row: rowitem.rowIndex
-                        readonly property int column: index
-                        readonly property int itemElideMode: __column.elideMode
-                        readonly property int itemTextAlignment: __column.horizontalAlignment
-                        readonly property string role: __column.role
+                        property QtObject styleData: QtObject {
+                            readonly property var value: __hasModelRole ? itemModel[role] // Qml ListModel and QAbstractItemModel
+                                                                            : __hasModelDataRole ? modelData[role] // QObjectList / QObject
+                                                                                                 : modelData != undefined ? modelData : "" // Models without role
+                            readonly property int row: rowitem.rowIndex
+                            readonly property int column: index
+                            readonly property int elideMode: __column.elideMode
+                            readonly property int textAlignment: __column.horizontalAlignment
+                            readonly property bool selected: rowitem.itemSelected
+                            readonly property color textColor: rowitem.itemTextColor
+                            readonly property string role: __column.role
+                        }
 
                         readonly property TableViewColumn __column: columns[index]
-                        readonly property bool __hasModelRole: role && itemModel.hasOwnProperty(role)
-                        readonly property bool __hasModelDataRole: role && modelData && modelData.hasOwnProperty(role)
+                        readonly property bool __hasModelRole: styleData.role && itemModel.hasOwnProperty(styleData.role)
+                        readonly property bool __hasModelDataRole: styleData.role && modelData && modelData.hasOwnProperty(styleData.role)
                     }
                 }
                 onWidthChanged: listView.contentWidth = width
@@ -545,13 +561,12 @@ ScrollView {
                             sourceComponent: root.headerDelegate
                             anchors.left: parent.left
                             anchors.right: parent.right
-                            property string itemValue: columns[index].title
-                            property string itemSort:  (sortIndicatorVisible && index == sortIndicatorColumn) ? (sortIndicatorOrder == Qt.AscendingOrder ? "up" : "down") : "";
-                            property bool itemPressed: headerClickArea.pressed
-                            property bool itemContainsMouse: headerClickArea.containsMouse
-                            property string itemPosition: columnCount === 1 ? "only" :
-                                                                                index===columnCount-1 ? "end" :
-                                                                                                          index===0 ? "beginning" : ""
+                            property QtObject styleData: QtObject {
+                                readonly property string value: columns[index].title
+                                readonly property bool pressed: headerClickArea.pressed
+                                readonly property bool containsMouse: headerClickArea.containsMouse
+                                readonly property int column: index
+                            }
                         }
                         Rectangle{
                             id: targetmark
@@ -612,11 +627,12 @@ ScrollView {
 
                         Loader {
                             id: draghandle
-                            property string itemValue: columns[index].title
-                            property string itemSort:  (sortIndicatorVisible && index == sortIndicatorColumn) ? (sortIndicatorOrder == Qt.AscendingOrder ? "up" : "down") : "";
-                            property bool itemPressed: headerClickArea.pressed
-                            property bool itemContainsMouse: headerClickArea.containsMouse
-                            property string itemPosition
+                            property QtObject styleData: QtObject{
+                                readonly property string value: columns[index].title
+                                readonly property bool pressed: headerClickArea.pressed
+                                readonly property bool containsMouse: headerClickArea.containsMouse
+                                readonly property int column: index
+                            }
 
                             parent: tableHeader
                             width: columns[index].width
@@ -661,11 +677,12 @@ ScrollView {
             }
             Loader {
                 id: loader
-                property string itemValue
-                property string itemSort
-                property bool itemPressed
-                property bool itemContainsMouse
-                property string itemPosition
+                property QtObject styleData: QtObject{
+                    readonly property string value: ""
+                    readonly property bool pressed: false
+                    readonly property bool containsMouse: false
+                    readonly property int column: -1
+                }
 
                 anchors.top: parent.top
                 anchors.right: parent.right
diff --git a/src/styles/Base/TableViewStyle.qml b/src/styles/Base/TableViewStyle.qml
index 669b934f2..6d4f9feb9 100644
--- a/src/styles/Base/TableViewStyle.qml
+++ b/src/styles/Base/TableViewStyle.qml
@@ -70,12 +70,13 @@ ScrollViewStyle {
     /* Delegate for header. This delegate is described in \l TableView::headerDelegate */
     property Component headerDelegate: BorderImage {
         source: "images/header.png"
+        border.left: 4
         Text {
             anchors.fill: parent
             verticalAlignment: Text.AlignVCenter
             horizontalAlignment: Text.AlignLeft
             anchors.leftMargin: 4
-            text: itemValue
+            text: styleData.value
             color: textColor
             renderType: Text.NativeRendering
         }
@@ -93,21 +94,21 @@ ScrollViewStyle {
     property Component rowDelegate: Rectangle {
         implicitHeight: 20
         implicitWidth: 80
-        property color selectedColor: hasActiveFocus ? "#38d" : "#999"
+        property color selectedColor: styleData.hasActiveFocus ? "#38d" : "#999"
         gradient: Gradient {
-            GradientStop { color: rowSelected ? Qt.lighter(selectedColor, 1.3)  : alternateBackground ? "#f2f2f2" : "white" ; position: 0 }
-            GradientStop { color: rowSelected ? Qt.lighter(selectedColor, 1.0)  : alternateBackground ? "#f2f2f2" : "white" ; position: 1 }
+            GradientStop { color: styleData.selected ? Qt.lighter(selectedColor, 1.3)  : styleData.alternate ? "#f2f2f2" : "white" ; position: 0 }
+            GradientStop { color: styleData.selected ? Qt.lighter(selectedColor, 1.0)  : styleData.alternate ? "#f2f2f2" : "white" ; position: 1 }
         }
         Rectangle {
             anchors.bottom: parent.bottom
             width: parent.width
             height: 1
-            color: rowSelected ? Qt.darker(selectedColor, 1.4) : "transparent"
+            color: styleData.elected ? Qt.darker(selectedColor, 1.4) : "transparent"
         }
         Rectangle {
             anchors.top: parent.top
             width: parent.width ; height: 1
-            color: rowSelected ? Qt.darker(selectedColor, 1.1) : "transparent"
+            color: styleData.elected ? Qt.darker(selectedColor, 1.1) : "transparent"
         }
     }
 
@@ -123,18 +124,18 @@ ScrollViewStyle {
             anchors.margins: 6
             anchors.left: parent.left
             anchors.right: parent.right
-            horizontalAlignment: itemTextAlignment
+            horizontalAlignment: styleData.textAlignment
             anchors.verticalCenter: parent.verticalCenter
             anchors.verticalCenterOffset: 1
-            elide: itemElideMode
-            text: itemValue != undefined ? itemValue : ""
-            color: itemTextColor
+            elide: styleData.elideMode
+            text: styleData.value != undefined ? styleData.value : ""
+            color: styleData.textColor
             renderType: Text.NativeRendering
         }
         Text {
             id: sizehint
             font: label.font
-            text: itemValue ? itemValue : ""
+            text: styleData.value ? styleData.value : ""
             visible: false
         }
     }
diff --git a/src/styles/Desktop/TableViewStyle.qml b/src/styles/Desktop/TableViewStyle.qml
index 52fb96357..c8eac3c62 100644
--- a/src/styles/Desktop/TableViewStyle.qml
+++ b/src/styles/Desktop/TableViewStyle.qml
@@ -65,19 +65,23 @@ ScrollViewStyle {
         elementType: "header"
         activeControl: itemSort
         raised: true
-        sunken: itemPressed
-        text: itemValue
-        hover: itemContainsMouse
-        hints: itemPosition
+        sunken: styleData.pressed
+        text: styleData.value
+        hover: styleData.containsMouse
+        hints: headerPosition
+        property string itemSort:  (control.sortIndicatorVisible && styleData.column === control.sortIndicatorColumn) ? (control.sortIndicatorOrder == Qt.AscendingOrder ? "up" : "down") : "";
+        property string headerPosition: control.columnCount === 1 ? "only" :
+                                                          styleData.column === control.columnCount-1 ? "end" :
+                                                                                  styleData.column === 0 ? "beginning" : ""
     }
 
     property Component rowDelegate: StyleItem {
         id: rowstyle
         elementType: "itemrow"
-        activeControl: alternateBackground ? "alternate" : ""
-        selected: rowSelected ? true : false
+        activeControl: styleData.alternate ? "alternate" : ""
+        selected: styleData.selected ? true : false
         height: Math.max(16, rowstyle.implicitHeight)
-        active: hasActiveFocus
+        active: styleData.hasActiveFocus
     }
 
     property Component itemDelegate: Item {
@@ -92,17 +96,17 @@ ScrollViewStyle {
             font: __styleitem.font
             anchors.left: parent.left
             anchors.right: parent.right
-            horizontalAlignment: itemTextAlignment
+            horizontalAlignment: styleData.textAlignment
             anchors.verticalCenter: parent.verticalCenter
-            elide: itemElideMode
-            text: itemValue != undefined ? itemValue : ""
-            color: itemTextColor
+            elide: styleData.elideMode
+            text: styleData.value !== undefined ? styleData.value : ""
+            color: styleData.textColor
             renderType: Text.NativeRendering
         }
         Text {
             id: sizehint
             font: label.font
-            text: itemValue ? itemValue : ""
+            text: styleData.value ? styleData.value : ""
             visible: false
         }
     }
diff --git a/tests/auto/controls/data/tableview/table_delegate.qml b/tests/auto/controls/data/tableview/table_delegate.qml
index a3ab621d9..82b08ba53 100644
--- a/tests/auto/controls/data/tableview/table_delegate.qml
+++ b/tests/auto/controls/data/tableview/table_delegate.qml
@@ -56,14 +56,14 @@ TableView {
     }
     headerDelegate: Text {
         height: 40
-        text: itemValue
+        text: styleData.value
     }
     itemDelegate: Text {
         width: parent.width
         anchors.left: parent.left
         anchors.verticalCenter: parent.verticalCenter
-        text: itemValue !== undefined ? itemValue : ""
-        color: itemTextColor
+        text: styleData.value !== undefined ? styleData.value : ""
+        color: styleData.textColor
         MouseArea {
             anchors.fill: parent
             onClicked: table.test = 1
-- 
GitLab