diff options
Diffstat (limited to 'src/extras/Styles/Base/TumblerStyle.qml')
-rw-r--r-- | src/extras/Styles/Base/TumblerStyle.qml | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/src/extras/Styles/Base/TumblerStyle.qml b/src/extras/Styles/Base/TumblerStyle.qml new file mode 100644 index 00000000..3ebcb7a2 --- /dev/null +++ b/src/extras/Styles/Base/TumblerStyle.qml @@ -0,0 +1,330 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Extras module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtGraphicalEffects 1.0 +import QtQuick.Controls 1.0 +import QtQuick.Controls.Private 1.0 +import QtQuick.Extras 1.3 +import QtQuick.Extras.Styles 1.3 +import QtQuick.Extras.Private 1.0 + +/*! + \qmltype TumblerStyle + \inqmlmodule QtQuick.Extras.Styles + \since QtQuick.Extras.Styles 1.2 + \ingroup extrasstyles + \brief Provides custom styling for Tumbler. + + \note TumblerStyle requires Qt 5.3.2 or later. + + You can create a custom tumbler by replacing the following delegates: + \list + \li \l background + \li \l foreground + \li \l separator + \li \l delegate + \li \l highlight + \li \l frame + \endlist +*/ + +Style { + id: tumblerStyle + + padding.left: __padding + padding.right: __padding + padding.top: __padding + padding.bottom: __padding + + /*! + \since 1.3 + + The \l Tumbler that this style is attached to. + */ + readonly property Tumbler control: __control + + /*! + This property holds the spacing between each delegate. + */ + property real spacing: 0 + + /*! + This property holds the amount of items visible in each column. + + This value should be an odd number. + */ + property int visibleItemCount: 3 + + /*! + \internal + + TODO: how do we handle differing padding values? + */ + readonly property real __padding: Math.max(6, Math.round(TextSingleton.implicitHeight * 0.4)) + /*! \internal */ + property real __delegateHeight: 0 + /*! \internal */ + property real __separatorWidth: 0 + + /*! + The background of the tumbler. + */ + property Component background: Rectangle { + gradient: Gradient { + GradientStop { position: 0.00; color: "#acacac" } + GradientStop { position: 0.12; color: "#d5d5d5" } + GradientStop { position: 0.24; color: "#e8e8e8" } + GradientStop { position: 0.39; color: "#ffffff" } + GradientStop { position: 0.61; color: "#ffffff" } + GradientStop { position: 0.76; color: "#e8e8e8" } + GradientStop { position: 0.88; color: "#d5d5d5" } + GradientStop { position: 1.00; color: "#acacac" } + } + } + + /*! + The foreground of the tumbler. + */ + property Component foreground: Item { + clip: true + + Rectangle { + id: rect + anchors.fill: parent + // Go one pixel larger than our parent so that we can hide our one pixel frame + // that the shadow is created from. + anchors.margins: -1 + color: "transparent" + border.color: "black" + visible: false + } + + DropShadow { + anchors.fill: rect + source: rect + radius: __padding + samples: Math.min(32, radius * 2) + } + } + + /*! + The separator between each column. + + The \l {Item::}{implicitWidth} property must be set, and should be the + same value for each separator. + */ + property Component separator: Canvas { + implicitWidth: Math.max(10, Math.round(TextSingleton.implicitHeight * 0.4)) + + onPaint: { + var ctx = getContext("2d"); + ctx.reset(); + + ctx.fillStyle = "#11000000"; + ctx.fillRect(0, 0, width, height); + ctx.fillStyle = "#11000000"; + ctx.fillRect(width * 0.2, 0, width * 0.6, height); + ctx.fillStyle = "#66000000"; + ctx.fillRect(width * 0.4, 0, width * 0.2, height); + } + } + + /*! + The foreground of each column. + + In terms of stacking order, this component is displayed above the + delegate and highlight components, but below the foreground component. + + \table + \row \li \c {readonly property int} \b styleData.column + \li The index of the column that contains this item. + \row \li \c {readonly property bool} \b styleData.activeFocus + \li \c true if the column that contains this item has active focus. + + \endtable + + Delegates for items in specific columns can be defined using + TumblerColumn's \l {TumblerColumn::columnForeground}{columnForeground} + property, which will be used instead of this component. + */ + property Component columnForeground + + /*! + The frame around the tumbler. + + The \l {Item::}{implicitWidth} property must be set, and should be the + same value for each separator. + */ + property Component frame: Canvas { + onPaint: { + // workaround for QTBUG-40792 + var ctx = getContext("2d"); + ctx.reset(); + + var cornerRadius = Math.max(2, Math.round(TextSingleton.implicitHeight * 0.2)); + var outerLineWidth = Math.max(1, Math.round(TextSingleton.implicitHeight * 0.05)); + var innerLineWidth = __padding - outerLineWidth; + + ctx.save(); + ctx.lineWidth = outerLineWidth; + ctx.beginPath(); + ctx.roundedRect(0, 0, width, height, cornerRadius, cornerRadius); + ctx.roundedRect(outerLineWidth, outerLineWidth, width - outerLineWidth * 2, height - outerLineWidth * 2, + cornerRadius - outerLineWidth, cornerRadius - outerLineWidth); + ctx.clip(); + + ctx.beginPath(); + ctx.rect(0, 0, width, height); + var gradient = ctx.createLinearGradient(width / 2, 0, width / 2, height); + gradient.addColorStop(0, "#33b3b3b3"); + gradient.addColorStop(1, "#4ce6e6e6"); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.restore(); + + // The inner stroke must account for its corner radius. + cornerRadius -= outerLineWidth; + + ctx.save(); + ctx.lineWidth = innerLineWidth; + ctx.beginPath(); + ctx.roundedRect(outerLineWidth, outerLineWidth, width - outerLineWidth * 2, height - outerLineWidth * 2, + cornerRadius, cornerRadius); + ctx.roundedRect(outerLineWidth + innerLineWidth, outerLineWidth + innerLineWidth, + width - outerLineWidth * 2 - innerLineWidth * 2, height - outerLineWidth * 2 - innerLineWidth * 2, + cornerRadius - innerLineWidth, cornerRadius - innerLineWidth); + ctx.clip(); + + ctx.beginPath(); + ctx.rect(0, 0, width, height); + gradient = ctx.createLinearGradient(width / 2, 0, width / 2, height); + gradient.addColorStop(0, "#4c666666"); + gradient.addColorStop(1, "#40cccccc"); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.restore(); + } + } + + /*! + The delegate provides a template defining each item instantiated in the + column. Each instance of this component has access to the following properties: + + \table + \row \li \c {readonly property int} \b styleData.index + \li The index of this delegate in the model. + \row \li \c {readonly property int} \b styleData.column + \li The index of the column that contains this item. + \row \li \c {readonly property real} \b styleData.value + \li The value for this delegate from the model. + \row \li \c {readonly property bool} \b styleData.current + \li \c true if this delegate is the current item. + \row \li \c {readonly property real} \b styleData.displacement + \li \c A value from \c {-visibleItemCount / 2} to + \c {visibleItemCount / 2} which represents how far away + this item is from being the current item, with \c 0 being + completely current. + + For example, the item below will be 40% opaque when + it is not the current item, and transition to 100% + opacity when it becomes the current item: + + \code + delegate: Text { + text: styleData.value + opacity: 0.4 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6 + } + \endcode + \row \li \c {readonly property bool} \b styleData.activeFocus + \li \c true if the column that contains this item has active focus. + + \endtable + + Properties of the model are also available depending upon the type of + \l {qml-data-models}{Data Model}. + + Delegates for items in specific columns can be defined using + TumblerColumn's \l {TumblerColumn::delegate}{delegate} property, which + will be used instead of this delegate. + + The \l {Item::}{implicitHeight} property must be set, and it must be + the same for each delegate. + */ + property Component delegate: Item { + implicitHeight: (control.height - padding.top - padding.bottom) / tumblerStyle.visibleItemCount + + Text { + id: label + text: styleData.value + color: "#666666" + opacity: 0.4 + Math.max(0, 1 - Math.abs(styleData.displacement)) * 0.6 + font.pixelSize: Math.round(TextSingleton.font.pixelSize * 1.25) + anchors.centerIn: parent + } + } + + /*! + The delegate for the highlight of each column. + + Delegates for the highlight of specific columns can be defined using + TumblerColumn's \l {TumblerColumn::highlight}{highlight} property, + which will be used instead of this delegate. + + Each instance of this component has access to the following properties: + + \table + \row \li \c {readonly property int} \b styleData.index + \li The index of this column in the tumbler. + \row \li \c {readonly property int} \b styleData.columnIndex + \li The index of the column that contains this highlight. + \row \li \c {readonly property bool} \b styleData.activeFocus + \li \c true if the column that contains this highlight has active focus. + \endtable + */ + property Component highlight + + /*! \internal */ + property Component panel: Item { + implicitWidth: { + var w = (__separatorWidth * (control.columnCount - 1)) + tumblerStyle.padding.left + tumblerStyle.padding.right; + for (var i = 0; i < control.columnCount; ++i) + w += control.getColumn(i).width; + return w; + } + implicitHeight: TextSingleton.implicitHeight * 10 + tumblerStyle.padding.top + tumblerStyle.padding.bottom + } +} |