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