summaryrefslogtreecommitdiff
path: root/src/controls/Private
diff options
context:
space:
mode:
authorCaroline Chao <caroline.chao@digia.com>2013-07-31 13:38:35 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-16 17:32:06 +0200
commit5483ccd3547dcb3edbe4c50d70e6921ee5c5cb7a (patch)
tree634db3b0a47cf54e68fe232d5664cbde2dd8579a /src/controls/Private
parent2b308e33bec09c8a792b37282f6172a59dc3d543 (diff)
downloadqtquickcontrols-5483ccd3547dcb3edbe4c50d70e6921ee5c5cb7a.tar.gz
Move Styles and Private under controls
Register the C++ private API from the controls plugin. The private plugin is not needed anymore. The Controls "submodules" Styles and Private are moved to the controls subfolder in the sources tree. Change-Id: I98358227c945b6cd1a8dbff9d07e6cad4f044277 Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'src/controls/Private')
-rw-r--r--src/controls/Private/AbstractCheckable.qml149
-rw-r--r--src/controls/Private/BasicButton.qml219
-rw-r--r--src/controls/Private/Control.qml92
-rw-r--r--src/controls/Private/FocusFrame.qml68
-rw-r--r--src/controls/Private/ModalPopupBehavior.qml135
-rw-r--r--src/controls/Private/ScrollBar.qml231
-rw-r--r--src/controls/Private/ScrollViewHelper.qml203
-rw-r--r--src/controls/Private/StackView.js68
-rw-r--r--src/controls/Private/StackViewSlideDelegate.qml138
-rw-r--r--src/controls/Private/Style.qml59
-rw-r--r--src/controls/Private/TabBar.qml305
-rw-r--r--src/controls/Private/private.pri42
-rw-r--r--src/controls/Private/qmldir18
-rw-r--r--src/controls/Private/qquickabstractstyle.cpp98
-rw-r--r--src/controls/Private/qquickabstractstyle_p.h78
-rw-r--r--src/controls/Private/qquickcontrolsettings.cpp147
-rw-r--r--src/controls/Private/qquickcontrolsettings_p.h87
-rw-r--r--src/controls/Private/qquickcontrolsprivate_p.h71
-rw-r--r--src/controls/Private/qquickpadding_p.h91
-rw-r--r--src/controls/Private/qquickrangemodel.cpp524
-rw-r--r--src/controls/Private/qquickrangemodel_p.h128
-rw-r--r--src/controls/Private/qquickrangemodel_p_p.h111
-rw-r--r--src/controls/Private/qquickspinboxvalidator.cpp230
-rw-r--r--src/controls/Private/qquickspinboxvalidator_p.h125
-rw-r--r--src/controls/Private/qquickstyleitem.cpp1495
-rw-r--r--src/controls/Private/qquickstyleitem_p.h265
-rw-r--r--src/controls/Private/qquicktooltip.cpp83
-rw-r--r--src/controls/Private/qquicktooltip_p.h65
-rw-r--r--src/controls/Private/qquickwheelarea.cpp204
-rw-r--r--src/controls/Private/qquickwheelarea_p.h121
-rw-r--r--src/controls/Private/style.js63
31 files changed, 5713 insertions, 0 deletions
diff --git a/src/controls/Private/AbstractCheckable.qml b/src/controls/Private/AbstractCheckable.qml
new file mode 100644
index 00000000..02348b71
--- /dev/null
+++ b/src/controls/Private/AbstractCheckable.qml
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** 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.0
+
+/*!
+ \qmltype AbstractCheckable
+ \inqmlmodule QtQuick.Controls 1.0
+ \ingroup controls
+ \brief An abstract representation of a checkable control with a label
+ \qmlabstract
+ \internal
+
+ A checkable control is one that has two states: checked (on) and
+ unchecked (off). AbstractCheckable encapsulates the basic behavior and
+ states that are required by checkable controls.
+
+ Examples of checkable controls are RadioButton and
+ CheckBox. CheckBox extends AbstractCheckable's behavior by adding a third
+ state: partially checked.
+*/
+
+Control {
+ id: abstractCheckable
+
+ /*!
+ Emitted whenever the control is clicked.
+ */
+ signal clicked
+
+ /*!
+ \qmlproperty bool AbstractCheckable::pressed
+
+ This property is \c true if the control is being pressed.
+ Set this property to manually invoke a mouse click.
+ */
+ property alias pressed: mouseArea.effectivePressed
+
+ /*! \qmlproperty bool AbstractCheckcable::hovered
+
+ This property indicates whether the control is being hovered.
+ */
+ readonly property alias hovered: mouseArea.containsMouse
+
+ /*!
+ This property is \c true if the control is checked.
+ */
+ property bool checked: false
+
+ /*!
+ This property is \c true if the control takes the focus when it is
+ pressed; \l{QQuickItem::forceActiveFocus()}{forceActiveFocus()} will be
+ called on the control.
+ */
+ property bool activeFocusOnPress: false
+
+ /*!
+ This property stores the ExclusiveGroup that the control belongs to.
+ */
+ property ExclusiveGroup exclusiveGroup: null
+
+ /*!
+ This property holds the text that the label should display.
+ */
+ property string text
+
+ /*! \internal */
+ property var __cycleStatesHandler: cycleRadioButtonStates
+
+ activeFocusOnTab: true
+
+ MouseArea {
+ id: mouseArea
+ focus: true
+ anchors.fill: parent
+ hoverEnabled: true
+ enabled: !keyPressed
+
+ property bool keyPressed: false
+ property bool effectivePressed: pressed && containsMouse || keyPressed
+
+ onClicked: abstractCheckable.clicked();
+
+ onPressed: if (activeFocusOnPress) forceActiveFocus();
+
+ onReleased: {
+ if (containsMouse && (!exclusiveGroup || !checked))
+ __cycleStatesHandler();
+ }
+ }
+
+ /*! \internal */
+ onExclusiveGroupChanged: {
+ if (exclusiveGroup)
+ exclusiveGroup.bindCheckable(abstractCheckable)
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Space && !event.isAutoRepeat && !mouseArea.pressed)
+ mouseArea.keyPressed = true;
+ }
+
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Space && !event.isAutoRepeat && mouseArea.keyPressed) {
+ mouseArea.keyPressed = false;
+ if (!exclusiveGroup || !checked)
+ __cycleStatesHandler();
+ clicked();
+ }
+ }
+}
diff --git a/src/controls/Private/BasicButton.qml b/src/controls/Private/BasicButton.qml
new file mode 100644
index 00000000..f07aea86
--- /dev/null
+++ b/src/controls/Private/BasicButton.qml
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** 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.0
+import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Styles 1.0
+
+/*!
+ \qmltype BasicButton
+ \internal
+ \qmlabstract
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+
+Control {
+ id: button
+
+ /*! This signal is emitted when the button is clicked. */
+ signal clicked
+
+ /*! \qmlproperty bool BasicButton::pressed
+
+ This property holds whether the button is being pressed. */
+ readonly property alias pressed: behavior.effectivePressed
+
+ /*! \qmlproperty bool BasicButton::hovered
+
+ This property indicates whether the control is being hovered.
+ */
+ readonly property alias hovered: behavior.containsMouse
+
+ /*! This property holds whether the button is checkable.
+
+ The default value is \c false. */
+ property bool checkable: false
+
+ /*! This property holds whether the button is checked.
+
+ Only checkable buttons can be checked.
+
+ The default value is \c false. */
+ property bool checked: false
+
+ /*! This property holds the ExclusiveGroup that the button belongs to.
+
+ The default value is \c null. */
+ property ExclusiveGroup exclusiveGroup: null
+
+ /*! This property holds the associated button action.
+
+ If a button has an action associated, the action defines the
+ button's properties like checked, text, tooltip etc.
+
+ When an action is set, it's still possible to override the \l text,
+ \l tooltip, \l iconSource, and \l iconName properties.
+
+ The default value is \c null. */
+ property Action action: null
+
+ /*! This property specifies whether the button should gain active focus when pressed.
+
+ The default value is \c false. */
+ property bool activeFocusOnPress: false
+
+ /*! This property holds the text shown on the button. If the button has no
+ text, the \l text property will be an empty string.
+
+ The default value is the empty string.
+ */
+ property string text: action ? action.text : ""
+
+ /*! This property holds the button tooltip. */
+ property string tooltip: action ? (action.tooltip || StyleHelpers.removeMnemonics(action.text)) : ""
+
+ /*! This property holds the icon shown on the button. If the button has no
+ icon, the iconSource property will be an empty string.
+
+ The default value is the empty string.
+ */
+ property url iconSource: action ? action.iconSource : ""
+
+ /*! The image label source as theme name.
+ When an icon from the platform icon theme is found, this takes
+ precedence over iconSource.
+ */
+ property string iconName: action ? action.iconName : ""
+
+ /*! \internal */
+ property color __textColor: syspal.text
+ /*! \internal */
+ property string __position: "only"
+ /*! \internal */
+ readonly property bool __iconOverriden: button.action && (button.action.iconSource !== button.iconSource || button.action.iconName !== button.iconName)
+ /*! \internal */
+ property Action __action: action || ownAction
+ /*! \internal */
+ readonly property Action __iconAction: __iconOverriden ? ownAction : __action
+
+ /*! \internal */
+ onExclusiveGroupChanged: {
+ if (exclusiveGroup)
+ exclusiveGroup.bindCheckable(button)
+ }
+
+ Accessible.role: Accessible.Button
+ Accessible.description: tooltip
+
+ /*! \internal */
+ function accessiblePressAction() {
+ __action.trigger()
+ }
+
+ Action {
+ id: ownAction
+ iconSource: !button.action || __iconOverriden ? button.iconSource : ""
+ iconName: !button.action || __iconOverriden ? button.iconName : ""
+ }
+
+ Connections {
+ target: __action
+ onTriggered: button.clicked()
+ }
+
+ activeFocusOnTab: true
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.pressed)
+ behavior.keyPressed = true;
+ }
+
+ Keys.onReleased: {
+ if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed) {
+ behavior.keyPressed = false;
+ __action.trigger()
+ }
+ }
+
+ MouseArea {
+ id: behavior
+ property bool keyPressed: false
+ property bool effectivePressed: pressed && containsMouse || keyPressed
+
+ anchors.fill: parent
+ hoverEnabled: true
+ enabled: !keyPressed
+
+ onReleased: if (containsMouse) __action.trigger()
+ onExited: Tooltip.hideText()
+ onCanceled: Tooltip.hideText()
+ onPressed: {
+ if (activeFocusOnPress)
+ button.forceActiveFocus()
+ if (button.checkable && !button.action && !(button.checked && button.exclusiveGroup))
+ button.checked = !button.checked
+ }
+
+ Timer {
+ interval: 1000
+ running: behavior.containsMouse && !pressed && tooltip.length
+ onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
+ }
+ }
+
+ /*! \internal */
+ property var __behavior: behavior
+
+ SystemPalette { id: syspal }
+
+ states: [
+ State {
+ name: "boundAction"
+ when: action !== null
+ PropertyChanges {
+ target: button
+ enabled: action.enabled
+ checkable: action.checkable
+ checked: action.checked
+ }
+ }
+ ]
+}
diff --git a/src/controls/Private/Control.qml b/src/controls/Private/Control.qml
new file mode 100644
index 00000000..05916c0a
--- /dev/null
+++ b/src/controls/Private/Control.qml
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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.Styles 1.0
+
+/*!
+ \qmltype Control
+ \internal
+ \qmlabstract
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+FocusScope {
+ id: root
+
+ /*! \qmlproperty Component Control::style
+
+ The style Component for this control.
+ \sa {Qt Quick Controls Styles QML Types}
+
+ */
+ property Component style
+
+ /*! \internal */
+ property QtObject __style: styleLoader.item
+
+ /*! \internal */
+ property Item __panel: panelLoader.item
+
+ /*! \internal */
+ property var styleHints
+
+ implicitWidth: __panel ? __panel.implicitWidth: 0
+ implicitHeight: __panel ? __panel.implicitHeight: 0
+ activeFocusOnTab: false
+
+ /*! \internal */
+ property alias __styleData: styleLoader.styleData
+
+ Loader {
+ id: panelLoader
+ anchors.fill: parent
+ sourceComponent: __style ? __style.panel : null
+ onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
+ Loader {
+ id: styleLoader
+ sourceComponent: style
+ property Item __control: root
+ property QtObject styleData: null
+ onStatusChanged: {
+ if (status === Loader.Error)
+ console.error("Failed to load Style for", root)
+ }
+ }
+ }
+}
diff --git a/src/controls/Private/FocusFrame.qml b/src/controls/Private/FocusFrame.qml
new file mode 100644
index 00000000..0bf9174a
--- /dev/null
+++ b/src/controls/Private/FocusFrame.qml
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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.0
+import QtQuick.Controls.Private 1.0
+
+/*!
+ \qmltype FocusFrame
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+Item {
+ id: root
+ activeFocusOnTab: false
+ Accessible.role: Accessible.StatusBar
+
+ anchors.topMargin: focusMargin
+ anchors.leftMargin: focusMargin
+ anchors.rightMargin: focusMargin
+ anchors.bottomMargin: focusMargin
+
+ property int focusMargin: loader.item ? loader.item.margin : -3
+
+ Loader {
+ id: loader
+ z: 2
+ anchors.fill: parent
+ sourceComponent: Qt.createComponent(Settings.style + "/FocusFrameStyle.qml", root)
+ }
+}
diff --git a/src/controls/Private/ModalPopupBehavior.qml b/src/controls/Private/ModalPopupBehavior.qml
new file mode 100644
index 00000000..1c6db2ff
--- /dev/null
+++ b/src/controls/Private/ModalPopupBehavior.qml
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** 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
+
+// KNOWN ISSUES
+// none
+
+/*!
+ \qmltype ModalPopupBehavior
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+Item {
+ id: popupBehavior
+
+ property bool showing: false
+ property bool whenAlso: true // modifier to the "showing" property
+ property bool consumeCancelClick: true
+ property int delay: 0 // delay before popout becomes visible
+ property int deallocationDelay: 3000 // 3 seconds
+
+ property Component popupComponent
+
+ property alias popup: popupLoader.item // read-only
+ property alias window: popupBehavior.root // read-only
+
+ signal prepareToShow
+ signal prepareToHide
+ signal cancelledByClick
+
+ // implementation
+
+ anchors.fill: parent
+
+ onShowingChanged: notifyChange()
+ onWhenAlsoChanged: notifyChange()
+ function notifyChange() {
+ if(showing && whenAlso) {
+ if(popupLoader.sourceComponent == undefined) {
+ popupLoader.sourceComponent = popupComponent;
+ }
+ } else {
+ mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior
+ if(Qt.isQtObject(popupLoader.item)) {
+ popupBehavior.prepareToHide();
+ popupLoader.item.opacity = 0;
+ }
+ }
+ }
+
+ property Item root: findRoot()
+ function findRoot() {
+ var p = parent;
+ while(p.parent != undefined)
+ p = p.parent;
+
+ return p;
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ enabled: false // enabled only when popout is showing
+ onPressed: {
+ popupBehavior.showing = false;
+ mouse.accepted = consumeCancelClick;
+ cancelledByClick();
+ }
+ }
+
+ Loader {
+ id: popupLoader
+ }
+
+ Timer { // visibility timer
+ running: Qt.isQtObject(popupLoader.item) && showing && whenAlso
+ interval: delay
+ onTriggered: {
+ popupBehavior.prepareToShow();
+ mouseArea.enabled = true;
+ popup.opacity = 1;
+ }
+ }
+
+ Timer { // deallocation timer
+ running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0
+ interval: deallocationDelay
+ onTriggered: popupLoader.sourceComponent = undefined
+ }
+
+ states: State {
+ name: "active"
+ when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0
+ ParentChange { target: popupBehavior; parent: root }
+ }
+ }
+
diff --git a/src/controls/Private/ScrollBar.qml b/src/controls/Private/ScrollBar.qml
new file mode 100644
index 00000000..c21d6562
--- /dev/null
+++ b/src/controls/Private/ScrollBar.qml
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** 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.0
+import QtQuick.Controls.Private 1.0
+
+/*!
+ \qmltype ScrollBar
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+Item {
+ id: scrollbar
+
+ property bool isTransient: false
+ property bool active: false
+ property int orientation: Qt.Horizontal
+ property alias minimumValue: slider.minimumValue
+ property alias maximumValue: slider.maximumValue
+ property alias value: slider.value
+
+ activeFocusOnTab: false
+
+ Accessible.role: Accessible.ScrollBar
+ implicitWidth: panelLoader.implicitWidth
+ implicitHeight: panelLoader.implicitHeight
+
+ property bool upPressed
+ property bool downPressed
+ property bool pageUpPressed
+ property bool pageDownPressed
+ property bool handlePressed
+
+
+ property Item __panel: panelLoader.item
+ Loader {
+ id: panelLoader
+ anchors.fill: parent
+ sourceComponent: __style ? __style.__scrollbar : null
+ onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
+ property alias __control: scrollbar
+ property QtObject __styleData: QtObject {
+ readonly property alias horizontal: internal.horizontal
+ readonly property alias upPressed: scrollbar.upPressed
+ readonly property alias downPressed: scrollbar.downPressed
+ readonly property alias handlePressed: scrollbar.handlePressed
+ }
+ }
+
+ MouseArea {
+ id: internal
+ property bool horizontal: orientation === Qt.Horizontal
+ property int pageStep: internal.horizontal ? width : height
+ property int singleStep: 20
+ property bool scrollToClickposition: internal.scrollToClickPosition
+ anchors.fill: parent
+ cursorShape: __panel.visible ? Qt.ArrowCursor : Qt.IBeamCursor // forces a cursor change
+
+ property bool autoincrement: false
+ property bool scrollToClickPosition: __style ? __style.scrollToClickedPosition : 0
+
+ // Update hover item
+ onEntered: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
+ onExited: if (!pressed) __panel.activeControl = "none"
+ onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
+ hoverEnabled: true
+
+ property var pressedX
+ property var pressedY
+ property int oldPosition
+ property int grooveSize
+
+ Timer {
+ running: upPressed || downPressed || pageUpPressed || pageDownPressed
+ interval: 350
+ onTriggered: internal.autoincrement = true
+ }
+
+ Timer {
+ running: internal.autoincrement
+ interval: 60
+ repeat: true
+ onTriggered: {
+ if (upPressed && internal.containsMouse)
+ internal.decrement();
+ else if (downPressed && internal.containsMouse)
+ internal.increment();
+ else if (pageUpPressed)
+ internal.decrementPage();
+ else if (pageDownPressed)
+ internal.incrementPage();
+ }
+ }
+
+ onPositionChanged: {
+ if (handlePressed) {
+ if (!horizontal)
+ slider.position = oldPosition + (mouseY - pressedY)
+ else
+ slider.position = oldPosition + (mouseX - pressedX)
+ }
+ }
+
+ onPressed: {
+ __panel.activeControl = __panel.hitTest(mouseX, mouseY)
+ scrollToClickposition = scrollToClickPosition
+ var handleRect = __panel.subControlRect("handle")
+ grooveSize = horizontal ? __panel.subControlRect("groove").width -
+ handleRect.width:
+ __panel.subControlRect("groove").height -
+ handleRect.height;
+ if (__panel.activeControl === "handle") {
+ pressedX = mouseX;
+ pressedY = mouseY;
+ handlePressed = true;
+ oldPosition = slider.position;
+ } else if (__panel.activeControl === "up") {
+ decrement();
+ upPressed = Qt.binding(function() {return containsMouse});
+ } else if (__panel.activeControl === "down") {
+ increment();
+ downPressed = Qt.binding(function() {return containsMouse});
+ } else if (!scrollToClickposition){
+ if (__panel.activeControl === "upPage") {
+ decrementPage();
+ pageUpPressed = true;
+ } else if (__panel.activeControl === "downPage") {
+ incrementPage();
+ pageDownPressed = true;
+ }
+ } else {
+ slider.position = horizontal ? mouseX - handleRect.width/2
+ : mouseY - handleRect.height/2
+ }
+ }
+
+ onReleased: {
+ __panel.activeControl = __panel.hitTest(mouseX, mouseY);
+ autoincrement = false;
+ upPressed = false;
+ downPressed = false;
+ handlePressed = false;
+ pageUpPressed = false;
+ pageDownPressed = false;
+ }
+
+ onWheel: {
+ var stepCount = -(wheel.angleDelta.x ? wheel.angleDelta.x : wheel.angleDelta.y) / 120
+ if (stepCount != 0) {
+ if (wheel.modifiers & Qt.ControlModifier || wheel.modifiers & Qt.ShiftModifier)
+ incrementPage(stepCount)
+ else
+ increment(stepCount)
+ }
+ }
+
+ function incrementPage(stepCount) {
+ value = boundValue(value + getSteps(pageStep, stepCount))
+ }
+
+ function decrementPage(stepCount) {
+ value = boundValue(value - getSteps(pageStep, stepCount))
+ }
+
+ function increment(stepCount) {
+ value = boundValue(value + getSteps(singleStep, stepCount))
+ }
+
+ function decrement(stepCount) {
+ value = boundValue(value - getSteps(singleStep, stepCount))
+ }
+
+ function boundValue(val) {
+ return Math.min(Math.max(val, minimumValue), maximumValue)
+ }
+
+ function getSteps(step, count) {
+ if (count)
+ step *= count
+ return step
+ }
+
+ RangeModel {
+ id: slider
+ minimumValue: 0.0
+ maximumValue: 1.0
+ value: 0
+ stepSize: 0.0
+ inverted: false
+ positionAtMaximum: internal.grooveSize
+ }
+ }
+}
diff --git a/src/controls/Private/ScrollViewHelper.qml b/src/controls/Private/ScrollViewHelper.qml
new file mode 100644
index 00000000..791c5e02
--- /dev/null
+++ b/src/controls/Private/ScrollViewHelper.qml
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** 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.0
+import QtQuick.Controls.Private 1.0
+
+/*!
+ \qmltype ScrollViewHeader
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+Item {
+ id: wheelarea
+
+ property alias horizontalScrollBar: hscrollbar
+ property alias verticalScrollBar: vscrollbar
+ property bool blockUpdates: false
+ property int availableHeight
+ property int availableWidth
+ property int contentHeight
+ property int contentWidth
+ property real originX
+ property real originY
+
+ property int leftMargin: outerFrame ? root.__style.padding.left : 0
+ property int rightMargin: outerFrame ? root.__style.padding.right : 0
+ property int topMargin: outerFrame ? root.__style.padding.top : 0
+ property int bottomMargin: outerFrame ? root.__style.padding.bottom : 0
+
+ anchors.fill: parent
+
+ property bool recursionGuard: false
+
+ function doLayout() {
+ if (!recursionGuard) {
+ recursionGuard = true
+ wheelarea.availableWidth = viewport.width
+ wheelarea.availableHeight = viewport.height
+ wheelarea.contentWidth = flickableItem !== null ? flickableItem.contentWidth : 0
+ wheelarea.contentHeight = flickableItem !== null ? flickableItem.contentHeight : 0
+ wheelarea.originX = flickableItem !== null ? flickableItem.originX : 0
+ wheelarea.originY = flickableItem !== null ? flickableItem.originY : 0
+ recursionGuard = false
+ }
+ }
+
+ Connections {
+ target: viewport
+ onWidthChanged: doLayout()
+ onHeightChanged: doLayout()
+ }
+
+ Connections {
+ target: flickableItem
+ onContentWidthChanged: doLayout()
+ onContentHeightChanged: doLayout()
+ }
+
+ Connections {
+ target: flickableItem
+ onContentXChanged: {
+ hscrollbar.flash()
+ vscrollbar.flash()
+ }
+ onContentYChanged: {
+ hscrollbar.flash()
+ vscrollbar.flash()
+ }
+ }
+
+ Loader {
+ id: cornerFill
+ z: 1
+ sourceComponent: __style.corner
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: bottomMargin
+ anchors.rightMargin: rightMargin
+ width: visible ? vscrollbar.width : 0
+ height: visible ? hscrollbar.height : 0
+ visible: hscrollbar.visible && !hscrollbar.isTransient && vscrollbar.visible && !vscrollbar.isTransient
+ }
+
+ ScrollBar {
+ id: hscrollbar
+ isTransient: !!__panel && !!__panel.transient
+ active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
+ enabled: !isTransient || __panel.visible
+ orientation: Qt.Horizontal
+ visible: contentWidth > availableWidth
+ height: visible ? implicitHeight : 0
+ z: 1
+ maximumValue: contentWidth > availableWidth ? originX + contentWidth - availableWidth : 0
+ minimumValue: originX
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: cornerFill.left
+ anchors.leftMargin: leftMargin
+ anchors.bottomMargin: bottomMargin
+ onValueChanged: {
+ if (!blockUpdates) {
+ flickableItem.contentX = value
+ }
+ }
+ Binding {
+ target: hscrollbar.__panel
+ property: "raised"
+ value: vscrollbar.active
+ when: hscrollbar.isTransient
+ }
+ Binding {
+ target: hscrollbar.__panel
+ property: "visible"
+ value: true
+ when: !hscrollbar.isTransient
+ }
+ function flash() {
+ if (hscrollbar.isTransient) {
+ hscrollbar.__panel.on = true
+ hscrollbar.__panel.visible = true
+ }
+ }
+ }
+
+ ScrollBar {
+ id: vscrollbar
+ isTransient: !!__panel && !!__panel.transient
+ active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
+ enabled: !isTransient || __panel.visible
+ orientation: Qt.Vertical
+ visible: contentHeight > availableHeight
+ width: visible ? implicitWidth : 0
+ z: 1
+ anchors.bottom: cornerFill.top
+ maximumValue: contentHeight > availableHeight ? originY + contentHeight - availableHeight + __viewTopMargin : 0
+ minimumValue: originY
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.topMargin: __scrollBarTopMargin + topMargin
+ anchors.rightMargin: rightMargin
+ onValueChanged: {
+ if (flickableItem && !blockUpdates && enabled) {
+ flickableItem.contentY = value
+ }
+ }
+ Binding {
+ target: vscrollbar.__panel
+ property: "raised"
+ value: hscrollbar.active
+ when: vscrollbar.isTransient
+ }
+ Binding {
+ target: vscrollbar.__panel
+ property: "visible"
+ value: true
+ when: !vscrollbar.isTransient
+ }
+ function flash() {
+ if (vscrollbar.isTransient) {
+ vscrollbar.__panel.on = true
+ vscrollbar.__panel.visible = true
+ }
+ }
+ }
+}
diff --git a/src/controls/Private/StackView.js b/src/controls/Private/StackView.js
new file mode 100644
index 00000000..fa9bb08e
--- /dev/null
+++ b/src/controls/Private/StackView.js
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+var stackView = [];
+
+function push(p)
+{
+ if (!p)
+ return
+ stackView.push(p)
+ __depth++
+ return p
+}
+
+function pop()
+{
+ if (stackView.length === 0)
+ return null
+ var p = stackView.pop()
+ __depth--
+ return p
+}
+
+function current()
+{
+ if (stackView.length === 0)
+ return null
+ return stackView[stackView.length-1]
+}
+
diff --git a/src/controls/Private/StackViewSlideDelegate.qml b/src/controls/Private/StackViewSlideDelegate.qml
new file mode 100644
index 00000000..6cc1c683
--- /dev/null
+++ b/src/controls/Private/StackViewSlideDelegate.qml
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** 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.0
+
+/*!
+ \qmltype StackViewSlideTransition
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+StackViewDelegate {
+ id: root
+
+ property bool horizontal: true
+
+ function getTransition(properties)
+ {
+ return root[horizontal ? "horizontalSlide" : "verticalSlide"][properties.name]
+ }
+
+ function transitionFinished(properties)
+ {
+ properties.exitItem.x = 0
+ properties.exitItem.y = 0
+ }
+
+ property QtObject horizontalSlide: QtObject {
+ property Component pushTransition: StackViewTransition {
+ PropertyAnimation {
+ target: enterItem
+ property: "x"
+ from: target.width
+ to: 0
+ duration: 300
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "x"
+ from: 0
+ to: -target.width
+ duration: 300
+ }
+ }
+
+ property Component popTransition: StackViewTransition {
+ PropertyAnimation {
+ target: enterItem
+ property: "x"
+ from: -target.width
+ to: 0
+ duration: 300
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "x"
+ from: 0
+ to: target.width
+ duration: 300
+ }
+ }
+ property Component replaceTransition: pushTransition
+ }
+
+ property QtObject verticalSlide: QtObject {
+ property Component pushTransition: StackViewTransition {
+ PropertyAnimation {
+ target: enterItem
+ property: "y"
+ from: target.height
+ to: 0
+ duration: 300
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "y"
+ from: 0
+ to: -target.height
+ duration: 300
+ }
+ }
+
+ property Component popTransition: StackViewTransition {
+ PropertyAnimation {
+ target: enterItem
+ property: "y"
+ from: -target.height
+ to: 0
+ duration: 300
+ }
+ PropertyAnimation {
+ target: exitItem
+ property: "y"
+ from: 0
+ to: target.height
+ duration: 300
+ }
+ property Component replaceTransition: pushTransition
+ }
+ }
+}
diff --git a/src/controls/Private/Style.qml b/src/controls/Private/Style.qml
new file mode 100644
index 00000000..6b4c08ef
--- /dev/null
+++ b/src/controls/Private/Style.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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.0
+import QtQuick.Controls.Private 1.0
+
+/*!
+ \qmltype Style
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+
+AbstractStyle {
+ /*! The control attached to this style */
+ readonly property Item control: __control
+
+ /*! \internal */
+ property var __syspal: SystemPalette {
+ colorGroup: control.enabled ?
+ SystemPalette.Active : SystemPalette.Disabled
+ }
+}
diff --git a/src/controls/Private/TabBar.qml b/src/controls/Private/TabBar.qml
new file mode 100644
index 00000000..8341c922
--- /dev/null
+++ b/src/controls/Private/TabBar.qml
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** 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.0
+
+/*!
+ \qmltype TabBar
+ \internal
+ \inqmlmodule QtQuick.Controls.Private 1.0
+*/
+FocusScope {
+ id: tabbar
+ height: Math.max(tabrow.height, Math.max(leftCorner.height, rightCorner.height))
+ width: tabView.width
+
+ activeFocusOnTab: true
+
+ Keys.onRightPressed: {
+ if (tabView && tabView.currentIndex < tabView.count - 1)
+ tabView.currentIndex = tabView.currentIndex + 1
+ }
+ Keys.onLeftPressed: {
+ if (tabView && tabView.currentIndex > 0)
+ tabView.currentIndex = tabView.currentIndex - 1
+ }
+
+ onTabViewChanged: parent = tabView
+ visible: tabView ? tabView.tabsVisible : true
+
+ property var tabView
+ property var style
+ property var styleItem: tabView.__styleItem ? tabView.__styleItem : null
+
+ property bool tabsMovable: styleItem ? styleItem.tabsMovable : false
+
+ property int tabsAlignment: styleItem ? styleItem.tabsAlignment : Qt.AlignLeft
+
+ property int tabOverlap: styleItem ? styleItem.tabOverlap : 0
+
+ property int elide: Text.ElideRight
+
+ property real availableWidth: tabbar.width - leftCorner.width - rightCorner.width
+
+ property var __selectedTabRect
+
+ function tab(index) {
+ for (var i = 0; i < tabrow.children.length; ++i) {
+ if (tabrow.children[i].tabindex == index) {
+ return tabrow.children[i]
+ }
+ }
+ return null;
+ }
+
+ /*! \internal */
+ function __isAncestorOf(item, child) {
+ //TODO: maybe removed from 5.2 if the function was merged in qtdeclarative
+ if (child === item)
+ return false;
+
+ while (child) {
+ child = child.parent;
+ if (child === item)
+ return true;
+ }
+ return false;
+ }
+ Loader {
+ id: background
+ anchors.fill: parent
+ sourceComponent: styleItem ? styleItem.tabBar : undefined
+ }
+
+ ListView {
+ id: tabrow
+ objectName: "tabrow"
+ Accessible.role: Accessible.PageTabList
+ LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
+ spacing: -tabOverlap
+ orientation: Qt.Horizontal
+ interactive: false
+ focus: true
+
+ width: Math.min(availableWidth, count ? contentWidth : availableWidth)
+ height: currentItem ? currentItem.height : 0
+
+ highlightMoveDuration: 0
+ currentIndex: tabView.currentIndex
+ onCurrentIndexChanged: tabrow.positionViewAtIndex(currentIndex, ListView.Contain)
+
+ moveDisplaced: Transition {
+ NumberAnimation {
+ property: "x"
+ duration: 125
+ easing.type: Easing.OutQuad
+ }
+ }
+
+ states: [
+ State {
+ name: "left"
+ when: tabsAlignment === Qt.AlignLeft
+ AnchorChanges { target:tabrow ; anchors.left: parent.left }
+ PropertyChanges { target:tabrow ; anchors.leftMargin: leftCorner.width }
+ },
+ State {
+ name: "center"
+ when: tabsAlignment === Qt.AlignHCenter
+ AnchorChanges { target:tabrow ; anchors.horizontalCenter: tabbar.horizontalCenter }
+ },
+ State {
+ name: "right"
+ when: tabsAlignment === Qt.AlignRight
+ AnchorChanges { target:tabrow ; anchors.right: parent.right }
+ PropertyChanges { target:tabrow ; anchors.rightMargin: rightCorner.width }
+ }
+ ]
+
+ model: tabView.__tabs
+
+ delegate: MouseArea {
+ id: tabitem
+ objectName: "mousearea"
+ hoverEnabled: true
+ focus: true
+
+ Binding {
+ target: tabbar
+ when: selected
+ property: "__selectedTabRect"
+ value: Qt.rect(x, y, width, height)
+ }
+
+ drag.target: tabsMovable ? tabloader : null
+ drag.axis: Drag.XAxis
+ drag.minimumX: drag.active ? 0 : -Number.MAX_VALUE
+ drag.maximumX: tabrow.width - tabitem.width
+
+ property int tabindex: index
+ property bool selected : tabView.currentIndex === index
+ property string title: modelData.title
+ property bool nextSelected: tabView.currentIndex === index + 1
+ property bool previousSelected: tabView.currentIndex === index - 1
+
+ z: selected ? 1 : -index
+ implicitWidth: tabloader.implicitWidth
+ implicitHeight: tabloader.implicitHeight
+
+ function changeTab() {
+ tabView.currentIndex = index;
+ var next = tabbar.nextItemInFocusChain(true);
+ if (__isAncestorOf(tabView.getTab(currentIndex), next))
+ next.forceActiveFocus();
+ }
+
+ onClicked: {
+ if (tabrow.interactive) {
+ changeTab()
+ }
+ }
+ onPressed: {
+ if (!tabrow.interactive) {
+ changeTab()
+ }
+ }
+
+ Loader {
+ id: tabloader
+
+ property Item control: tabView
+ property int index: tabindex
+
+ property QtObject styleData: QtObject {
+ readonly property alias index: tabitem.tabindex
+ readonly property alias selected: tabitem.selected
+ readonly property alias title: tabitem.title
+ readonly property alias nextSelected: tabitem.nextSelected
+ readonly property alias previsousSelected: tabitem.previousSelected
+ readonly property alias hovered: tabitem.containsMouse
+ readonly property bool activeFocus: tabbar.activeFocus
+ readonly property real availableWidth: tabbar.availableWidth
+ }
+
+ sourceComponent: loader.item ? loader.item.tab : null
+
+ Drag.keys: "application/x-tabbartab"
+ Drag.active: tabitem.drag.active
+ Drag.source: tabitem
+
+ property real __prevX: 0
+ property real __dragX: 0
+ onXChanged: {
+ if (Drag.active) {
+ // keep track for the snap back animation
+ __dragX = tabitem.mapFromItem(tabrow, tabloader.x, 0).x
+
+ // when moving to the left, the hot spot is the left edge and vice versa
+ Drag.hotSpot.x = x < __prevX ? 0 : width
+ __prevX = x
+ }
+ }
+
+ width: tabitem.width
+ state: Drag.active ? "drag" : ""
+
+ transitions: [
+ Transition {
+ to: "drag"
+ PropertyAction { target: tabloader; property: "parent"; value: tabrow }
+ },
+ Transition {
+ from: "drag"
+ SequentialAnimation {
+ PropertyAction { target: tabloader; property: "parent"; value: tabitem }
+ NumberAnimation {
+ target: tabloader
+ duration: 50
+ easing.type: Easing.OutQuad
+ property: "x"
+ from: tabloader.__dragX
+ to: 0
+ }
+ }
+ }
+ ]
+ }
+
+ Accessible.role: Accessible.PageTab
+ Accessible.name: modelData.title
+ }
+ }
+
+ Loader {
+ id: leftCorner
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ sourceComponent: styleItem ? styleItem.leftCorner : undefined
+ width: item ? item.implicitWidth : 0
+ height: item ? item.implicitHeight : 0
+ }
+
+ Loader {
+ id: rightCorner
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ sourceComponent: styleItem ? styleItem.rightCorner : undefined
+ width: item ? item.implicitWidth : 0
+ height: item ? item.implicitHeight : 0
+ }
+
+ DropArea {
+ anchors.fill: tabrow
+ keys: "application/x-tabbartab"
+ onPositionChanged: {
+ var source = drag.source
+ var target = tabrow.itemAt(drag.x, drag.y)
+ if (source && target && source !== target) {
+ source = source.drag.target
+ target = target.drag.target
+ var center = target.parent.x + target.width / 2
+ if ((source.index > target.index && source.x < center)
+ || (source.index < target.index && source.x + source.width > center))
+ tabView.moveTab(source.index, target.index)
+ }
+ }
+ }
+}
diff --git a/src/controls/Private/private.pri b/src/controls/Private/private.pri
new file mode 100644
index 00000000..bd001c0a
--- /dev/null
+++ b/src/controls/Private/private.pri
@@ -0,0 +1,42 @@
+HEADERS += \
+ $$PWD/qquicktooltip_p.h \
+ $$PWD/qquickspinboxvalidator_p.h \
+ $$PWD/qquickrangemodel_p.h \
+ $$PWD/qquickrangemodel_p_p.h \
+ $$PWD/qquickcontrolsettings_p.h \
+ $$PWD/qquickwheelarea_p.h \
+ $$PWD/qquickabstractstyle_p.h \
+ $$PWD/qquickpadding_p.h \
+ $$PWD/qquickcontrolsprivate_p.h
+
+SOURCES += \
+ $$PWD/qquicktooltip.cpp \
+ $$PWD/qquickspinboxvalidator.cpp \
+ $$PWD/qquickrangemodel.cpp \
+ $$PWD/qquickcontrolsettings.cpp \
+ $$PWD/qquickwheelarea.cpp \
+ $$PWD/qquickabstractstyle.cpp
+
+qtHaveModule(widgets) {
+ QT += widgets
+ HEADERS += $$PWD/qquickstyleitem_p.h
+ SOURCES += $$PWD/qquickstyleitem.cpp
+}
+
+# private qml files
+PRIVATE_QML_FILES += \
+ $$PWD/AbstractCheckable.qml \
+ $$PWD/TabBar.qml \
+ $$PWD/BasicButton.qml \
+ $$PWD/Control.qml \
+ $$PWD/Style.qml \
+ $$PWD/style.js \
+ $$PWD/ModalPopupBehavior.qml \
+ $$PWD/StackViewSlideDelegate.qml \
+ $$PWD/StackView.js \
+ $$PWD/ScrollViewHelper.qml \
+ $$PWD/ScrollBar.qml \
+ $$PWD/FocusFrame.qml \
+ $$PWD/qmldir
+
+QML_FILES += $$PRIVATE_QML_FILES
diff --git a/src/controls/Private/qmldir b/src/controls/Private/qmldir
new file mode 100644
index 00000000..1ee66461
--- /dev/null
+++ b/src/controls/Private/qmldir
@@ -0,0 +1,18 @@
+module QtQuick.Controls.Private
+AbstractCheckable 1.0 AbstractCheckable.qml
+Control 1.0 Control.qml
+FocusFrame 1.0 FocusFrame.qml
+Margins 1.0 Margins.qml
+BasicButton 1.0 BasicButton.qml
+ScrollBar 1.0 ScrollBar.qml
+ScrollViewHelper 1.0 ScrollViewHelper.qml
+Style 1.0 Style.qml
+TabBar 1.0 TabBar.qml
+StackViewSlideDelegate 1.0 StackViewSlideDelegate.qml
+StyleHelpers 1.0 style.js
+JSArray 1.0 StackView.js
+GroupBoxStyle 1.0 ../Styles/Base/GroupBoxStyle.qml
+SpinBoxStyle 1.0 ../Styles/Base/SpinBoxStyle.qml
+ToolBarStyle 1.0 ../Styles/Base/ToolBarStyle.qml
+StatusBarStyle 1.0 ../Styles/Base/StatusBarStyle.qml
+ToolButtonStyle 1.0 ../Styles/Base/ToolButtonStyle.qml
diff --git a/src/controls/Private/qquickabstractstyle.cpp b/src/controls/Private/qquickabstractstyle.cpp
new file mode 100644
index 00000000..eba57b03
--- /dev/null
+++ b/src/controls/Private/qquickabstractstyle.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickabstractstyle_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype AbstractStyle
+ \instantiates QQuickAbstractStyle
+ \qmlabstract
+ \internal
+*/
+
+/*!
+ \qmlproperty int AbstractStyle::padding.top
+ \qmlproperty int AbstractStyle::padding.left
+ \qmlproperty int AbstractStyle::padding.right
+ \qmlproperty int AbstractStyle::padding.bottom
+
+ This grouped property holds the \c top, \c left, \c right and \c bottom padding.
+*/
+
+QQuickAbstractStyle::QQuickAbstractStyle(QObject *parent) : QObject(parent)
+{
+}
+
+QQmlListProperty<QObject> QQuickAbstractStyle::data()
+{
+ return QQmlListProperty<QObject>(this, 0, &QQuickAbstractStyle::data_append, &QQuickAbstractStyle::data_count,
+ &QQuickAbstractStyle::data_at, &QQuickAbstractStyle::data_clear);
+}
+
+void QQuickAbstractStyle::data_append(QQmlListProperty<QObject> *list, QObject *object)
+{
+ if (QQuickAbstractStyle *style = qobject_cast<QQuickAbstractStyle *>(list->object))
+ style->m_data.append(object);
+}
+
+int QQuickAbstractStyle::data_count(QQmlListProperty<QObject> *list)
+{
+ if (QQuickAbstractStyle *style = qobject_cast<QQuickAbstractStyle *>(list->object))
+ return style->m_data.count();
+ return 0;
+}
+
+QObject *QQuickAbstractStyle::data_at(QQmlListProperty<QObject> *list, int index)
+{
+ if (QQuickAbstractStyle *style = qobject_cast<QQuickAbstractStyle *>(list->object))
+ return style->m_data.at(index);
+ return 0;
+}
+
+void QQuickAbstractStyle::data_clear(QQmlListProperty<QObject> *list)
+{
+ if (QQuickAbstractStyle *style = qobject_cast<QQuickAbstractStyle *>(list->object))
+ style->m_data.clear();
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickabstractstyle_p.h b/src/controls/Private/qquickabstractstyle_p.h
new file mode 100644
index 00000000..13764053
--- /dev/null
+++ b/src/controls/Private/qquickabstractstyle_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKABSTRACTSTYLE_H
+#define QQUICKABSTRACTSTYLE_H
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqmllist.h>
+#include "qquickpadding_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickAbstractStyle : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQuickPadding* padding READ padding CONSTANT)
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
+ Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+ QQuickAbstractStyle(QObject *parent = 0);
+
+ QQuickPadding* padding() { return &m_padding; }
+
+ QQmlListProperty<QObject> data();
+
+private:
+ static void data_append(QQmlListProperty<QObject> *list, QObject *object);
+ static int data_count(QQmlListProperty<QObject> *list);
+ static QObject *data_at(QQmlListProperty<QObject> *list, int index);
+ static void data_clear(QQmlListProperty<QObject> *list);
+
+ QQuickPadding m_padding;
+ QList<QObject *> m_data;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKABSTRACTSTYLE_H
diff --git a/src/controls/Private/qquickcontrolsettings.cpp b/src/controls/Private/qquickcontrolsettings.cpp
new file mode 100644
index 00000000..e2daa17f
--- /dev/null
+++ b/src/controls/Private/qquickcontrolsettings.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickcontrolsettings_p.h"
+#include <qquickitem.h>
+#include <qcoreapplication.h>
+#include <qqmlengine.h>
+#include <qdir.h>
+
+QT_BEGIN_NAMESPACE
+
+static QString defaultStyleName()
+{
+ //Only enable QStyle support when we are using QApplication
+ if (QCoreApplication::instance()->inherits("QApplication"))
+ return QLatin1String("Desktop");
+ return QLatin1String("Base");
+}
+
+static QString styleImportName()
+{
+ QString name = qgetenv("QT_QUICK_CONTROLS_STYLE");
+ if (name.isEmpty())
+ name = defaultStyleName();
+ return QFileInfo(name).fileName();
+}
+
+static QString styleImportPath(QQmlEngine *engine, const QString &styleName)
+{
+ QString path = qgetenv("QT_QUICK_CONTROLS_STYLE");
+ QFileInfo info(path);
+ if (info.isRelative()) {
+ foreach (const QString &import, engine->importPathList()) {
+ QDir dir(import + QLatin1String("/QtQuick/Controls/Styles"));
+ if (dir.exists(styleName)) {
+ path = dir.absolutePath();
+ break;
+ }
+ }
+ } else {
+ path = info.absolutePath();
+ }
+ return path;
+}
+
+QQuickControlSettings::QQuickControlSettings(QQmlEngine *engine)
+{
+ m_name = styleImportName();
+ m_path = styleImportPath(engine, m_name);
+
+ if (!QFile::exists(styleFilePath())) {
+ QString unknownStyle = m_name;
+ m_name = defaultStyleName();
+ m_path = styleImportPath(engine, m_name);
+ qWarning() << "WARNING: Cannot find style" << unknownStyle << "- fallback:" << styleFilePath();
+ }
+
+ connect(this, SIGNAL(styleNameChanged()), SIGNAL(styleChanged()));
+ connect(this, SIGNAL(stylePathChanged()), SIGNAL(styleChanged()));
+}
+
+QUrl QQuickControlSettings::style() const
+{
+ return QUrl::fromLocalFile(styleFilePath());
+}
+
+QString QQuickControlSettings::styleName() const
+{
+ return m_name;
+}
+
+void QQuickControlSettings::setStyleName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ emit styleNameChanged();
+ }
+}
+
+QString QQuickControlSettings::stylePath() const
+{
+ return m_path;
+}
+
+void QQuickControlSettings::setStylePath(const QString &path)
+{
+ if (m_path != path) {
+ m_path = path;
+ emit stylePathChanged();
+ }
+}
+
+QString QQuickControlSettings::styleFilePath() const
+{
+ return m_path + QLatin1Char('/') + m_name;
+}
+
+extern Q_GUI_EXPORT int qt_defaultDpiX();
+
+qreal QQuickControlSettings::dpiScaleFactor() const
+{
+#ifndef Q_OS_MAC
+ return (qreal(qt_defaultDpiX()) / 96.0);
+#endif
+ return 1.0;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickcontrolsettings_p.h b/src/controls/Private/qquickcontrolsettings_p.h
new file mode 100644
index 00000000..8ff0ecbf
--- /dev/null
+++ b/src/controls/Private/qquickcontrolsettings_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKCONTROLSETTINGS_P_H
+#define QQUICKCONTROLSETTINGS_P_H
+
+#include <QtCore/qurl.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQmlEngine;
+
+class QQuickControlSettings : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QUrl style READ style NOTIFY styleChanged)
+ Q_PROPERTY(QString styleName READ styleName WRITE setStyleName NOTIFY styleNameChanged)
+ Q_PROPERTY(QString stylePath READ stylePath WRITE setStylePath NOTIFY stylePathChanged)
+ Q_PROPERTY(qreal dpiScaleFactor READ dpiScaleFactor CONSTANT)
+
+public:
+ QQuickControlSettings(QQmlEngine *engine);
+
+ QUrl style() const;
+
+ QString styleName() const;
+ void setStyleName(const QString &name);
+
+ QString stylePath() const;
+ void setStylePath(const QString &path);
+
+ qreal dpiScaleFactor() const;
+
+signals:
+ void styleChanged();
+ void styleNameChanged();
+ void stylePathChanged();
+
+private:
+ QString styleFilePath() const;
+
+ QString m_name;
+ QString m_path;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTROLSETTINGS_P_H
diff --git a/src/controls/Private/qquickcontrolsprivate_p.h b/src/controls/Private/qquickcontrolsprivate_p.h
new file mode 100644
index 00000000..068b2a21
--- /dev/null
+++ b/src/controls/Private/qquickcontrolsprivate_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKCONTROLSPRIVATE_P_H
+#define QQUICKCONTROLSPRIVATE_P_H
+
+#include "qqml.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickControlsPrivate {
+
+public:
+
+ inline static QObject *registerTooltipModule(QQmlEngine *engine, QJSEngine *jsEngine)
+ {
+ Q_UNUSED(engine);
+ Q_UNUSED(jsEngine);
+ return new QQuickTooltip();
+ }
+
+ inline static QObject *registerSettingsModule(QQmlEngine *engine, QJSEngine *jsEngine)
+ {
+ Q_UNUSED(engine);
+ Q_UNUSED(jsEngine);
+ return new QQuickControlSettings(engine);
+ }
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKCONTROLSPRIVATE_P_H
diff --git a/src/controls/Private/qquickpadding_p.h b/src/controls/Private/qquickpadding_p.h
new file mode 100644
index 00000000..1830df4c
--- /dev/null
+++ b/src/controls/Private/qquickpadding_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPADDING_H
+#define QQUICKPADDING_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickPadding : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int left READ left WRITE setLeft NOTIFY leftChanged)
+ Q_PROPERTY(int top READ top WRITE setTop NOTIFY topChanged)
+ Q_PROPERTY(int right READ right WRITE setRight NOTIFY rightChanged)
+ Q_PROPERTY(int bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
+
+ int m_left;
+ int m_top;
+ int m_right;
+ int m_bottom;
+
+public:
+ QQuickPadding(QObject *parent = 0) :
+ QObject(parent),
+ m_left(0),
+ m_top(0),
+ m_right(0),
+ m_bottom(0) {}
+
+ int left() const { return m_left; }
+ int top() const { return m_top; }
+ int right() const { return m_right; }
+ int bottom() const { return m_bottom; }
+
+public slots:
+ void setLeft(int arg) { if (m_left != arg) {m_left = arg; emit leftChanged();}}
+ void setTop(int arg) { if (m_top != arg) {m_top = arg; emit topChanged();}}
+ void setRight(int arg) { if (m_right != arg) {m_right = arg; emit rightChanged();}}
+ void setBottom(int arg) {if (m_bottom != arg) {m_bottom = arg; emit bottomChanged();}}
+
+signals:
+ void leftChanged();
+ void topChanged();
+ void rightChanged();
+ void bottomChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKPADDING_H
diff --git a/src/controls/Private/qquickrangemodel.cpp b/src/controls/Private/qquickrangemodel.cpp
new file mode 100644
index 00000000..ee1ade32
--- /dev/null
+++ b/src/controls/Private/qquickrangemodel.cpp
@@ -0,0 +1,524 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ With this class, the user sets a value range and a position range, which
+ represent the valid values/positions the model can assume. It is worth telling
+ that the value property always has priority over the position property. A nice use
+ case, would be a Slider implementation with the help of QQuickRangeModel. If the user sets
+ a value range to [0,100], a position range to [50,100] and sets the value
+ to 80, the equivalent position would be 90. After that, if the user decides to
+ resize the slider, the value would be the same, but the knob position would
+ be updated due to the new position range.
+*/
+
+#include "qquickrangemodel_p.h"
+#include "qquickrangemodel_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickRangeModelPrivate::QQuickRangeModelPrivate(QQuickRangeModel *qq)
+ : q_ptr(qq)
+{
+}
+
+QQuickRangeModelPrivate::~QQuickRangeModelPrivate()
+{
+}
+
+void QQuickRangeModelPrivate::init()
+{
+ minimum = 0;
+ maximum = 99;
+ stepSize = 0;
+ value = 0;
+ pos = 0;
+ posatmin = 0;
+ posatmax = 0;
+ inverted = false;
+}
+
+/*!
+ Calculates the position that is going to be seen outside by the component
+ that is using QQuickRangeModel. It takes into account the \l stepSize,
+ \l positionAtMinimum, \l positionAtMaximum properties
+ and \a position that is passed as parameter.
+*/
+
+qreal QQuickRangeModelPrivate::publicPosition(qreal position) const
+{
+ // Calculate the equivalent stepSize for the position property.
+ const qreal min = effectivePosAtMin();
+ const qreal max = effectivePosAtMax();
+ const qreal valueRange = maximum - minimum;
+ const qreal positionValueRatio = valueRange ? (max - min) / valueRange : 0;
+ const qreal positionStep = stepSize * positionValueRatio;
+
+ if (positionStep == 0)
+ return (min < max) ? qBound(min, position, max) : qBound(max, position, min);
+
+ const int stepSizeMultiplier = (position - min) / positionStep;
+
+ // Test whether value is below minimum range
+ if (stepSizeMultiplier < 0)
+ return min;
+
+ qreal leftEdge = (stepSizeMultiplier * positionStep) + min;
+ qreal rightEdge = ((stepSizeMultiplier + 1) * positionStep) + min;
+
+ if (min < max) {
+ leftEdge = qMin(leftEdge, max);
+ rightEdge = qMin(rightEdge, max);
+ } else {
+ leftEdge = qMax(leftEdge, max);
+ rightEdge = qMax(rightEdge, max);
+ }
+
+ if (qAbs(leftEdge - position) <= qAbs(rightEdge - position))
+ return leftEdge;
+ return rightEdge;
+}
+
+/*!
+ Calculates the value that is going to be seen outside by the component
+ that is using QQuickRangeModel. It takes into account the \l stepSize,
+ \l minimumValue, \l maximumValue properties
+ and \a value that is passed as parameter.
+*/
+
+qreal QQuickRangeModelPrivate::publicValue(qreal value) const
+{
+ // It is important to do value-within-range check this
+ // late (as opposed to during setPosition()). The reason is
+ // QML bindings; a position that is initially invalid because it lays
+ // outside the range, might become valid later if the range changes.
+
+ if (stepSize == 0)
+ return qBound(minimum, value, maximum);
+
+ const int stepSizeMultiplier = (value - minimum) / stepSize;
+
+ // Test whether value is below minimum range
+ if (stepSizeMultiplier < 0)
+ return minimum;
+
+ const qreal leftEdge = qMin(maximum, (stepSizeMultiplier * stepSize) + minimum);
+ const qreal rightEdge = qMin(maximum, ((stepSizeMultiplier + 1) * stepSize) + minimum);
+ const qreal middle = (leftEdge + rightEdge) / 2;
+
+ return (value <= middle) ? leftEdge : rightEdge;
+}
+
+/*!
+ Checks if the \l value or \l position, that is seen by the user, has changed and emits the changed signal if it
+ has changed.
+*/
+
+void QQuickRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition)
+{
+ Q_Q(QQuickRangeModel);
+
+ // Effective value and position might have changed even in cases when e.g. d->value is
+ // unchanged. This will be the case when operating with values outside range:
+ const qreal newValue = q->value();
+ const qreal newPosition = q->position();
+ if (!qFuzzyCompare(newValue, oldValue))
+ emit q->valueChanged(newValue);
+ if (!qFuzzyCompare(newPosition, oldPosition))
+ emit q->positionChanged(newPosition);
+}
+
+/*!
+ Constructs a QQuickRangeModel with \a parent
+*/
+
+QQuickRangeModel::QQuickRangeModel(QObject *parent)
+ : QObject(parent), d_ptr(new QQuickRangeModelPrivate(this))
+{
+ Q_D(QQuickRangeModel);
+ d->init();
+}
+
+/*!
+ \internal
+ Constructs a QQuickRangeModel with private class pointer \a dd and \a parent
+*/
+
+QQuickRangeModel::QQuickRangeModel(QQuickRangeModelPrivate &dd, QObject *parent)
+ : QObject(parent), d_ptr(&dd)
+{
+ Q_D(QQuickRangeModel);
+ d->init();
+}
+
+/*!
+ Destroys the QQuickRangeModel
+*/
+
+QQuickRangeModel::~QQuickRangeModel()
+{
+ delete d_ptr;
+ d_ptr = 0;
+}
+
+/*!
+ Sets the range of valid positions, that \l position can assume externally, with
+ \a min and \a max.
+ Such range is represented by \l positionAtMinimum and \l positionAtMaximum
+*/
+
+void QQuickRangeModel::setPositionRange(qreal min, qreal max)
+{
+ Q_D(QQuickRangeModel);
+
+ bool emitPosAtMinChanged = !qFuzzyCompare(min, d->posatmin);
+ bool emitPosAtMaxChanged = !qFuzzyCompare(max, d->posatmax);
+
+ if (!(emitPosAtMinChanged || emitPosAtMaxChanged))
+ return;
+
+ const qreal oldPosition = position();
+ d->posatmin = min;
+ d->posatmax = max;
+
+ // When a new positionRange is defined, the position property must be updated based on the value property.
+ // For instance, imagine that you have a valueRange of [0,100] and a position range of [20,100],
+ // if a user set the value to 50, the position would be 60. If this positionRange is updated to [0,100], then
+ // the new position, based on the value (50), will be 50.
+ // If the newPosition is different than the old one, it must be updated, in order to emit
+ // the positionChanged signal.
+ d->pos = d->equivalentPosition(d->value);
+
+ if (emitPosAtMinChanged)
+ emit positionAtMinimumChanged(d->posatmin);
+ if (emitPosAtMaxChanged)
+ emit positionAtMaximumChanged(d->posatmax);
+
+ d->emitValueAndPositionIfChanged(value(), oldPosition);
+}
+/*!
+ Sets the range of valid values, that \l value can assume externally, with
+ \a min and \a max. The range has the following constraint: \a min must be less or equal \a max
+ Such range is represented by \l minimumValue and \l maximumValue
+*/
+
+void QQuickRangeModel::setRange(qreal min, qreal max)
+{
+ Q_D(QQuickRangeModel);
+
+ bool emitMinimumChanged = !qFuzzyCompare(min, d->minimum);
+ bool emitMaximumChanged = !qFuzzyCompare(max, d->maximum);
+
+ if (!(emitMinimumChanged || emitMaximumChanged))
+ return;
+
+ const qreal oldValue = value();
+ const qreal oldPosition = position();
+
+ d->minimum = min;
+ d->maximum = qMax(min, max);
+
+ // Update internal position if it was changed. It can occurs if internal value changes, due to range update
+ d->pos = d->equivalentPosition(d->value);
+
+ if (emitMinimumChanged)
+ emit minimumChanged(d->minimum);
+ if (emitMaximumChanged)
+ emit maximumChanged(d->maximum);
+
+ d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+ \property QQuickRangeModel::minimumValue
+ \brief the minimum value that \l value can assume
+
+ This property's default value is 0
+*/
+
+void QQuickRangeModel::setMinimum(qreal min)
+{
+ Q_D(const QQuickRangeModel);
+ setRange(min, d->maximum);
+}
+
+qreal QQuickRangeModel::minimum() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->minimum;
+}
+
+/*!
+ \property QQuickRangeModel::maximumValue
+ \brief the maximum value that \l value can assume
+
+ This property's default value is 99
+*/
+
+void QQuickRangeModel::setMaximum(qreal max)
+{
+ Q_D(const QQuickRangeModel);
+ // if the new maximum value is smaller than
+ // minimum, update minimum too
+ setRange(qMin(d->minimum, max), max);
+}
+
+qreal QQuickRangeModel::maximum() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->maximum;
+}
+
+/*!
+ \property QQuickRangeModel::stepSize
+ \brief the value that is added to the \l value and \l position property
+
+ Example: If a user sets a range of [0,100] and stepSize
+ to 30, the valid values that are going to be seen externally would be: 0, 30, 60, 90, 100.
+*/
+
+void QQuickRangeModel::setStepSize(qreal stepSize)
+{
+ Q_D(QQuickRangeModel);
+
+ stepSize = qMax(qreal(0.0), stepSize);
+ if (qFuzzyCompare(stepSize, d->stepSize))
+ return;
+
+ const qreal oldValue = value();
+ const qreal oldPosition = position();
+ d->stepSize = stepSize;
+
+ emit stepSizeChanged(d->stepSize);
+ d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+qreal QQuickRangeModel::stepSize() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->stepSize;
+}
+
+/*!
+ Returns a valid position, respecting the \l positionAtMinimum,
+ \l positionAtMaximum and the \l stepSize properties.
+ Such calculation is based on the parameter \a value (which is valid externally).
+*/
+
+qreal QQuickRangeModel::positionForValue(qreal value) const
+{
+ Q_D(const QQuickRangeModel);
+
+ const qreal unconstrainedPosition = d->equivalentPosition(value);
+ return d->publicPosition(unconstrainedPosition);
+}
+
+/*!
+ \property QQuickRangeModel::position
+ \brief the current position of the model
+
+ Represents a valid external position, based on the \l positionAtMinimum,
+ \l positionAtMaximum and the \l stepSize properties.
+ The user can set it internally with a position, that is not within the current position range,
+ since it can become valid if the user changes the position range later.
+*/
+
+qreal QQuickRangeModel::position() const
+{
+ Q_D(const QQuickRangeModel);
+
+ // Return the internal position but observe boundaries and
+ // stepSize restrictions.
+ return d->publicPosition(d->pos);
+}
+
+void QQuickRangeModel::setPosition(qreal newPosition)
+{
+ Q_D(QQuickRangeModel);
+
+ if (qFuzzyCompare(newPosition, d->pos))
+ return;
+
+ const qreal oldPosition = position();
+ const qreal oldValue = value();
+
+ // Update position and calculate new value
+ d->pos = newPosition;
+ d->value = d->equivalentValue(d->pos);
+ d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+ \property QQuickRangeModel::positionAtMinimum
+ \brief the minimum value that \l position can assume
+
+ This property's default value is 0
+*/
+
+void QQuickRangeModel::setPositionAtMinimum(qreal min)
+{
+ Q_D(QQuickRangeModel);
+ setPositionRange(min, d->posatmax);
+}
+
+qreal QQuickRangeModel::positionAtMinimum() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->posatmin;
+}
+
+/*!
+ \property QQuickRangeModel::positionAtMaximum
+ \brief the maximum value that \l position can assume
+
+ This property's default value is 0
+*/
+
+void QQuickRangeModel::setPositionAtMaximum(qreal max)
+{
+ Q_D(QQuickRangeModel);
+ setPositionRange(d->posatmin, max);
+}
+
+qreal QQuickRangeModel::positionAtMaximum() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->posatmax;
+}
+
+/*!
+ Returns a valid value, respecting the \l minimumValue,
+ \l maximumValue and the \l stepSize properties.
+ Such calculation is based on the parameter \a position (which is valid externally).
+*/
+
+qreal QQuickRangeModel::valueForPosition(qreal position) const
+{
+ Q_D(const QQuickRangeModel);
+
+ const qreal unconstrainedValue = d->equivalentValue(position);
+ return d->publicValue(unconstrainedValue);
+}
+
+/*!
+ \property QQuickRangeModel::value
+ \brief the current value of the model
+
+ Represents a valid external value, based on the \l minimumValue,
+ \l maximumValue and the \l stepSize properties.
+ The user can set it internally with a value, that is not within the current range,
+ since it can become valid if the user changes the range later.
+*/
+
+qreal QQuickRangeModel::value() const
+{
+ Q_D(const QQuickRangeModel);
+
+ // Return internal value but observe boundaries and
+ // stepSize restrictions
+ return d->publicValue(d->value);
+}
+
+void QQuickRangeModel::setValue(qreal newValue)
+{
+ Q_D(QQuickRangeModel);
+
+ if (qFuzzyCompare(newValue, d->value))
+ return;
+
+ const qreal oldValue = value();
+ const qreal oldPosition = position();
+
+ // Update relative value and position
+ d->value = newValue;
+ d->pos = d->equivalentPosition(d->value);
+ d->emitValueAndPositionIfChanged(oldValue, oldPosition);
+}
+
+/*!
+ \property QQuickRangeModel::inverted
+ \brief the model is inverted or not
+
+ The model can be represented with an inverted behavior, e.g. when \l value assumes
+ the maximum value (represented by \l maximumValue) the \l position will be at its
+ minimum (represented by \l positionAtMinimum).
+*/
+
+void QQuickRangeModel::setInverted(bool inverted)
+{
+ Q_D(QQuickRangeModel);
+ if (inverted == d->inverted)
+ return;
+
+ d->inverted = inverted;
+ emit invertedChanged(d->inverted);
+
+ // After updating the internal value, the position property can change.
+ setPosition(d->equivalentPosition(d->value));
+}
+
+bool QQuickRangeModel::inverted() const
+{
+ Q_D(const QQuickRangeModel);
+ return d->inverted;
+}
+
+/*!
+ Sets the \l value to \l minimumValue.
+*/
+
+void QQuickRangeModel::toMinimum()
+{
+ Q_D(const QQuickRangeModel);
+ setValue(d->minimum);
+}
+
+/*!
+ Sets the \l value to \l maximumValue.
+*/
+
+void QQuickRangeModel::toMaximum()
+{
+ Q_D(const QQuickRangeModel);
+ setValue(d->maximum);
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickrangemodel_p.h b/src/controls/Private/qquickrangemodel_p.h
new file mode 100644
index 00000000..a15843d7
--- /dev/null
+++ b/src/controls/Private/qquickrangemodel_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKRANGEMODEL_P_H
+#define QQUICKRANGEMODEL_P_H
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickRangeModelPrivate;
+
+class QQuickRangeModel : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true)
+ Q_PROPERTY(qreal minimumValue READ minimum WRITE setMinimum NOTIFY minimumChanged)
+ Q_PROPERTY(qreal maximumValue READ maximum WRITE setMaximum NOTIFY maximumChanged)
+ Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged)
+ Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged)
+ Q_PROPERTY(qreal positionAtMinimum READ positionAtMinimum WRITE setPositionAtMinimum NOTIFY positionAtMinimumChanged)
+ Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged)
+ Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged)
+
+public:
+ QQuickRangeModel(QObject *parent = 0);
+ virtual ~QQuickRangeModel();
+
+ void setRange(qreal min, qreal max);
+ void setPositionRange(qreal min, qreal max);
+
+ void setStepSize(qreal stepSize);
+ qreal stepSize() const;
+
+ void setMinimum(qreal min);
+ qreal minimum() const;
+
+ void setMaximum(qreal max);
+ qreal maximum() const;
+
+ void setPositionAtMinimum(qreal posAtMin);
+ qreal positionAtMinimum() const;
+
+ void setPositionAtMaximum(qreal posAtMax);
+ qreal positionAtMaximum() const;
+
+ void setInverted(bool inverted);
+ bool inverted() const;
+
+ qreal value() const;
+ qreal position() const;
+
+ Q_INVOKABLE qreal valueForPosition(qreal position) const;
+ Q_INVOKABLE qreal positionForValue(qreal value) const;
+
+public Q_SLOTS:
+ void toMinimum();
+ void toMaximum();
+ void setValue(qreal value);
+ void setPosition(qreal position);
+
+Q_SIGNALS:
+ void valueChanged(qreal value);
+ void positionChanged(qreal position);
+
+ void stepSizeChanged(qreal stepSize);
+
+ void invertedChanged(bool inverted);
+
+ void minimumChanged(qreal min);
+ void maximumChanged(qreal max);
+ void positionAtMinimumChanged(qreal min);
+ void positionAtMaximumChanged(qreal max);
+
+protected:
+ QQuickRangeModel(QQuickRangeModelPrivate &dd, QObject *parent);
+ QQuickRangeModelPrivate* d_ptr;
+
+private:
+ Q_DISABLE_COPY(QQuickRangeModel)
+ Q_DECLARE_PRIVATE(QQuickRangeModel)
+
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickRangeModel)
+
+#endif // QQUICKRANGEMODEL_P_H
diff --git a/src/controls/Private/qquickrangemodel_p_p.h b/src/controls/Private/qquickrangemodel_p_p.h
new file mode 100644
index 00000000..9ddf16c2
--- /dev/null
+++ b/src/controls/Private/qquickrangemodel_p_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKRANGEMODEL_P_P_H
+#define QQUICKRANGEMODEL_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt Components API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickrangemodel_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickRangeModelPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickRangeModel)
+public:
+ QQuickRangeModelPrivate(QQuickRangeModel *qq);
+ virtual ~QQuickRangeModelPrivate();
+
+ void init();
+
+ qreal posatmin, posatmax;
+ qreal minimum, maximum, stepSize, pos, value;
+
+ uint inverted : 1;
+
+ QQuickRangeModel *q_ptr;
+
+ inline qreal effectivePosAtMin() const {
+ return inverted ? posatmax : posatmin;
+ }
+
+ inline qreal effectivePosAtMax() const {
+ return inverted ? posatmin : posatmax;
+ }
+
+ inline qreal equivalentPosition(qreal value) const {
+ // Return absolute position from absolute value
+ const qreal valueRange = maximum - minimum;
+ if (valueRange == 0)
+ return effectivePosAtMin();
+
+ const qreal scale = (effectivePosAtMax() - effectivePosAtMin()) / valueRange;
+ return (value - minimum) * scale + effectivePosAtMin();
+ }
+
+ inline qreal equivalentValue(qreal pos) const {
+ // Return absolute value from absolute position
+ const qreal posRange = effectivePosAtMax() - effectivePosAtMin();
+ if (posRange == 0)
+ return minimum;
+
+ const qreal scale = (maximum - minimum) / posRange;
+ return (pos - effectivePosAtMin()) * scale + minimum;
+ }
+
+ qreal publicPosition(qreal position) const;
+ qreal publicValue(qreal value) const;
+ void emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition);
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKRANGEMODEL_P_P_H
diff --git a/src/controls/Private/qquickspinboxvalidator.cpp b/src/controls/Private/qquickspinboxvalidator.cpp
new file mode 100644
index 00000000..a39a8deb
--- /dev/null
+++ b/src/controls/Private/qquickspinboxvalidator.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickspinboxvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QQuickSpinBoxValidator::QQuickSpinBoxValidator(QObject *parent)
+ : QValidator(parent), m_value(0), m_step(1), m_initialized(false)
+{
+ m_validator.setTop(99);
+ m_validator.setBottom(0);
+ m_validator.setDecimals(0);
+ m_validator.setNotation(QDoubleValidator::StandardNotation);
+
+ QLocale locale;
+ locale.setNumberOptions(QLocale::OmitGroupSeparator);
+ setLocale(locale);
+
+ connect(this, SIGNAL(valueChanged()), this, SIGNAL(textChanged()));
+ connect(this, SIGNAL(minimumValueChanged()), this, SIGNAL(textChanged()));
+ connect(this, SIGNAL(maximumValueChanged()), this, SIGNAL(textChanged()));
+ connect(this, SIGNAL(decimalsChanged()), this, SIGNAL(textChanged()));
+ connect(this, SIGNAL(prefixChanged()), this, SIGNAL(textChanged()));
+ connect(this, SIGNAL(suffixChanged()), this, SIGNAL(textChanged()));
+}
+
+QQuickSpinBoxValidator::~QQuickSpinBoxValidator()
+{
+}
+
+QString QQuickSpinBoxValidator::text() const
+{
+ return m_prefix + locale().toString(m_value, 'f', m_validator.decimals()) + m_suffix;
+}
+
+qreal QQuickSpinBoxValidator::value() const
+{
+ return m_value;
+}
+
+void QQuickSpinBoxValidator::setValue(qreal value)
+{
+ if (m_initialized) {
+ value = qBound(minimumValue(), value, maximumValue());
+ value = QString::number(value, 'f', m_validator.decimals()).toDouble();
+ }
+
+ if (m_value != value) {
+ m_value = value;
+ emit valueChanged();
+ }
+}
+
+qreal QQuickSpinBoxValidator::minimumValue() const
+{
+ return m_validator.bottom();
+}
+
+void QQuickSpinBoxValidator::setMinimumValue(qreal min)
+{
+ if (min != m_validator.bottom()) {
+ m_validator.setBottom(min);
+ emit minimumValueChanged();
+ if (m_initialized)
+ setValue(m_value);
+ }
+}
+
+qreal QQuickSpinBoxValidator::maximumValue() const
+{
+ return m_validator.top();
+}
+
+void QQuickSpinBoxValidator::setMaximumValue(qreal max)
+{
+ if (max != m_validator.top()) {
+ m_validator.setTop(max);
+ emit maximumValueChanged();
+ if (m_initialized)
+ setValue(m_value);
+ }
+}
+
+int QQuickSpinBoxValidator::decimals() const
+{
+ return m_validator.decimals();
+}
+
+void QQuickSpinBoxValidator::setDecimals(int decimals)
+{
+ if (decimals != m_validator.decimals()) {
+ m_validator.setDecimals(decimals);
+ emit decimalsChanged();
+ if (m_initialized)
+ setValue(m_value);
+ }
+}
+
+qreal QQuickSpinBoxValidator::stepSize() const
+{
+ return m_step;
+}
+
+void QQuickSpinBoxValidator::setStepSize(qreal step)
+{
+ if (m_step != step) {
+ m_step = step;
+ emit stepSizeChanged();
+ }
+}
+
+QString QQuickSpinBoxValidator::prefix() const
+{
+ return m_prefix;
+}
+
+void QQuickSpinBoxValidator::setPrefix(const QString &prefix)
+{
+ if (m_prefix != prefix) {
+ m_prefix = prefix;
+ emit prefixChanged();
+ }
+}
+
+QString QQuickSpinBoxValidator::suffix() const
+{
+ return m_suffix;
+}
+
+void QQuickSpinBoxValidator::setSuffix(const QString &suffix)
+{
+ if (m_suffix != suffix) {
+ m_suffix = suffix;
+ emit suffixChanged();
+ }
+}
+
+void QQuickSpinBoxValidator::fixup(QString &input) const
+{
+ input.remove(locale().groupSeparator());
+}
+
+QValidator::State QQuickSpinBoxValidator::validate(QString &input, int &pos) const
+{
+ if (pos > 0 && pos < input.length()) {
+ if (input.at(pos - 1) == locale().groupSeparator())
+ return QValidator::Invalid;
+ if (input.at(pos - 1) == locale().decimalPoint() && m_validator.decimals() == 0)
+ return QValidator::Invalid;
+ }
+
+ if (!m_prefix.isEmpty() && !input.startsWith(m_prefix)) {
+ input.prepend(m_prefix);
+ pos += m_prefix.length();
+ }
+
+ if (!m_suffix.isEmpty() && !input.endsWith(m_suffix))
+ input.append(m_suffix);
+
+ QString value = input.mid(m_prefix.length(), input.length() - m_prefix.length() - m_suffix.length());
+ int valuePos = pos - m_prefix.length();
+ QValidator::State state = m_validator.validate(value, valuePos);
+ input = m_prefix + value + m_suffix;
+ pos = m_prefix.length() + valuePos;
+
+ if (state == QValidator::Acceptable) {
+ bool ok = false;
+ qreal val = locale().toDouble(value, &ok);
+ if (ok)
+ const_cast<QQuickSpinBoxValidator *>(this)->setValue(val);
+ }
+ return state;
+}
+
+void QQuickSpinBoxValidator::componentComplete()
+{
+ m_initialized = true;
+ setValue(m_value);
+}
+
+void QQuickSpinBoxValidator::increment()
+{
+ setValue(m_value + m_step);
+}
+
+void QQuickSpinBoxValidator::decrement()
+{
+ setValue(m_value - m_step);
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickspinboxvalidator_p.h b/src/controls/Private/qquickspinboxvalidator_p.h
new file mode 100644
index 00000000..09468fce
--- /dev/null
+++ b/src/controls/Private/qquickspinboxvalidator_p.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSPINBOXVALIDATOR_P_H
+#define QQUICKSPINBOXVALIDATOR_P_H
+
+#include <QtGui/qvalidator.h>
+#include <QtQml/qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickSpinBoxValidator : public QValidator, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QString text READ text NOTIFY textChanged)
+ Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY(qreal minimumValue READ minimumValue WRITE setMinimumValue NOTIFY minimumValueChanged)
+ Q_PROPERTY(qreal maximumValue READ maximumValue WRITE setMaximumValue NOTIFY maximumValueChanged)
+ Q_PROPERTY(int decimals READ decimals WRITE setDecimals NOTIFY decimalsChanged)
+ Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged)
+ Q_PROPERTY(QString prefix READ prefix WRITE setPrefix NOTIFY prefixChanged)
+ Q_PROPERTY(QString suffix READ suffix WRITE setSuffix NOTIFY suffixChanged)
+
+public:
+ explicit QQuickSpinBoxValidator(QObject *parent = 0);
+ virtual ~QQuickSpinBoxValidator();
+
+ QString text() const;
+
+ qreal value() const;
+ void setValue(qreal value);
+
+ qreal minimumValue() const;
+ void setMinimumValue(qreal min);
+
+ qreal maximumValue() const;
+ void setMaximumValue(qreal max);
+
+ int decimals() const;
+ void setDecimals(int decimals);
+
+ qreal stepSize() const;
+ void setStepSize(qreal step);
+
+ QString prefix() const;
+ void setPrefix(const QString &prefix);
+
+ QString suffix() const;
+ void setSuffix(const QString &suffix);
+
+ void fixup(QString &input) const;
+ State validate(QString &input, int &pos) const;
+
+ void classBegin() { }
+ void componentComplete();
+
+public Q_SLOTS:
+ void increment();
+ void decrement();
+
+Q_SIGNALS:
+ void valueChanged();
+ void minimumValueChanged();
+ void maximumValueChanged();
+ void decimalsChanged();
+ void stepSizeChanged();
+ void prefixChanged();
+ void suffixChanged();
+ void textChanged();
+
+private:
+ qreal m_value;
+ qreal m_step;
+ QString m_prefix;
+ QString m_suffix;
+ bool m_initialized;
+ QDoubleValidator m_validator;
+
+ Q_DISABLE_COPY(QQuickSpinBoxValidator)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickSpinBoxValidator)
+
+#endif // QQUICKSPINBOXVALIDATOR_P_H
diff --git a/src/controls/Private/qquickstyleitem.cpp b/src/controls/Private/qquickstyleitem.cpp
new file mode 100644
index 00000000..e1c9ee18
--- /dev/null
+++ b/src/controls/Private/qquickstyleitem.cpp
@@ -0,0 +1,1495 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickstyleitem_p.h"
+
+#include <qstringbuilder.h>
+#include <qpainter.h>
+#include <qpixmapcache.h>
+#include <qstyle.h>
+#include <qstyleoption.h>
+#include <qapplication.h>
+#include <qsgsimpletexturenode.h>
+#include <qquickwindow.h>
+#include "private/qguiapplication_p.h"
+#include <QtGui/qpa/qplatformtheme.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_OSX
+#include <Carbon/Carbon.h>
+
+static inline HIRect qt_hirectForQRect(const QRect &convertRect, const QRect &rect = QRect())
+{
+ return CGRectMake(convertRect.x() + rect.x(), convertRect.y() + rect.y(),
+ convertRect.width() - rect.width(), convertRect.height() - rect.height());
+}
+
+/*! \internal
+
+ Returns the CoreGraphics CGContextRef of the paint device. 0 is
+ returned if it can't be obtained. It is the caller's responsibility to
+ CGContextRelease the context when finished using it.
+
+ \warning This function is only available on Mac OS X.
+ \warning This function is duplicated in qmacstyle_mac.mm
+*/
+CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
+{
+
+ if (pdev->devType() == QInternal::Image) {
+ const QImage *i = static_cast<const QImage*>(pdev);
+ QImage *image = const_cast< QImage*>(i);
+ CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
+ uint flags = kCGImageAlphaPremultipliedFirst;
+ flags |= kCGBitmapByteOrder32Host;
+ CGContextRef ret = 0;
+
+ ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+
+ CGContextTranslateCTM(ret, 0, image->height());
+ CGContextScaleCTM(ret, 1, -1);
+ return ret;
+ }
+ return 0;
+}
+
+#endif
+
+class QQuickStyleNode : public QSGSimpleTextureNode
+{
+public:
+ ~QQuickStyleNode()
+ {
+ delete texture();
+ }
+
+ void setTexture(QSGTexture *texture)
+ {
+ delete QSGSimpleTextureNode::texture();
+ QSGSimpleTextureNode::setTexture(texture);
+ }
+};
+
+QQuickStyleItem::QQuickStyleItem(QQuickItem *parent)
+ : QQuickItem(parent),
+ m_styleoption(0),
+ m_itemType(Undefined),
+ m_sunken(false),
+ m_raised(false),
+ m_active(true),
+ m_selected(false),
+ m_focus(false),
+ m_hover(false),
+ m_on(false),
+ m_horizontal(true),
+ m_transient(false),
+ m_sharedWidget(false),
+ m_minimum(0),
+ m_maximum(100),
+ m_value(0),
+ m_step(0),
+ m_paintMargins(0),
+ m_contentWidth(0),
+ m_contentHeight(0)
+
+{
+ m_font = qApp->font();
+ setFlag(QQuickItem::ItemHasContents, true);
+ setSmooth(false);
+
+ connect(this, SIGNAL(widthChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(heightChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(enabledChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(infoChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(onChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(selectedChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(textChanged()), this, SLOT(updateSizeHint()));
+ connect(this, SIGNAL(textChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(activeChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(raisedChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(sunkenChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(hoverChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(maximumChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(minimumChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(valueChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(horizontalChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(transientChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(hasFocusChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(activeControlChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(hintChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(propertiesChanged()), this, SLOT(updateSizeHint()));
+ connect(this, SIGNAL(propertiesChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(elementTypeChanged()), this, SLOT(updateItem()));
+ connect(this, SIGNAL(contentWidthChanged(int)), this, SLOT(updateSizeHint()));
+ connect(this, SIGNAL(contentHeightChanged(int)), this, SLOT(updateSizeHint()));
+ connect(this, SIGNAL(widthChanged()), this, SLOT(updateRect()));
+}
+
+QQuickStyleItem::~QQuickStyleItem()
+{
+ delete m_styleoption;
+ m_styleoption = 0;
+}
+
+void QQuickStyleItem::initStyleOption()
+{
+ QString type = elementType();
+ if (m_styleoption)
+ m_styleoption->state = 0;
+
+ QString sizeHint = m_hints.value("size").toString();
+ QPlatformTheme::Font platformFont = (sizeHint == "mini") ? QPlatformTheme::MiniFont :
+ (sizeHint == "small") ? QPlatformTheme::SmallFont :
+ QPlatformTheme::SystemFont;
+
+ switch (m_itemType) {
+ case Button: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionButton();
+
+ QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
+ opt->text = text();
+ opt->icon = m_properties["icon"].value<QIcon>();
+ int e = qApp->style()->pixelMetric(QStyle::PM_ButtonIconSize, m_styleoption, 0);
+ opt->iconSize = QSize(e, e);
+ opt->features = (activeControl() == "default") ?
+ QStyleOptionButton::DefaultButton :
+ QStyleOptionButton::None;
+ if (platformFont == QPlatformTheme::SystemFont)
+ platformFont = QPlatformTheme::PushButtonFont;
+ const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont);
+ if (font)
+ opt->fontMetrics = QFontMetrics(*font);
+ QObject * menu = m_properties["menu"].value<QObject *>();
+ if (menu) {
+ opt->features |= QStyleOptionButton::HasMenu;
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ if (platformFont == QPlatformTheme::PushButtonFont)
+ menu->setProperty("__xOffset", 12);
+ else
+ menu->setProperty("__xOffset", 11);
+ if (platformFont == QPlatformTheme::MiniFont)
+ menu->setProperty("__yOffset", 5);
+ else if (platformFont == QPlatformTheme::SmallFont)
+ menu->setProperty("__yOffset", 6);
+ else
+ menu->setProperty("__yOffset", 3);
+ if (font)
+ menu->setProperty("__font", *font);
+ }
+#endif
+ }
+ }
+ break;
+ case ItemRow: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionViewItem();
+
+ QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(m_styleoption);
+ opt->features = 0;
+ if (activeControl() == "alternate")
+ opt->features |= QStyleOptionViewItem::Alternate;
+ }
+ break;
+
+ case Splitter: {
+ if (!m_styleoption) {
+ m_styleoption = new QStyleOption;
+ }
+ }
+ break;
+
+ case Item: {
+ if (!m_styleoption) {
+ m_styleoption = new QStyleOptionViewItem();
+ }
+ QStyleOptionViewItem *opt = qstyleoption_cast<QStyleOptionViewItem*>(m_styleoption);
+ opt->features = QStyleOptionViewItem::HasDisplay;
+ opt->text = text();
+ opt->textElideMode = Qt::ElideRight;
+ QPalette pal = m_styleoption->palette;
+ pal.setBrush(QPalette::Base, Qt::NoBrush);
+ m_styleoption->palette = pal;
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::ItemViewFont)) {
+ opt->fontMetrics = QFontMetrics(*font);
+ opt->font = *font;
+ }
+ }
+ break;
+ case Header: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionHeader();
+
+ QStyleOptionHeader *opt = qstyleoption_cast<QStyleOptionHeader*>(m_styleoption);
+ opt->text = text();
+ opt->sortIndicator = activeControl() == "down" ?
+ QStyleOptionHeader::SortDown
+ : activeControl() == "up" ?
+ QStyleOptionHeader::SortUp : QStyleOptionHeader::None;
+ QString headerpos = m_properties.value("headerpos").toString();
+ if (headerpos == "beginning")
+ opt->position = QStyleOptionHeader::Beginning;
+ else if (headerpos == "end")
+ opt->position = QStyleOptionHeader::End;
+ else if (headerpos == "only")
+ opt->position = QStyleOptionHeader::OnlyOneSection;
+ else
+ opt->position = QStyleOptionHeader::Middle;
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::HeaderViewFont))
+ opt->fontMetrics = QFontMetrics(*font);
+ }
+ break;
+ case ToolButton: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionToolButton();
+
+ QStyleOptionToolButton *opt =
+ qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
+ opt->subControls = QStyle::SC_ToolButton;
+ opt->state |= QStyle::State_AutoRaise;
+ opt->activeSubControls = QStyle::SC_ToolButton;
+ opt->text = text();
+ opt->icon = m_properties["icon"].value<QIcon>();
+
+ // For now icon only is displayed by default.
+ opt->toolButtonStyle = Qt::ToolButtonIconOnly;
+ if (opt->icon.isNull() && !opt->text.isEmpty())
+ opt->toolButtonStyle = Qt::ToolButtonTextOnly;
+
+ int e = qApp->style()->pixelMetric(QStyle::PM_ToolBarIconSize, m_styleoption, 0);
+ opt->iconSize = QSize(e, e);
+
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::ToolButtonFont)) {
+ opt->fontMetrics = QFontMetrics(*font);
+ opt->font = *font;
+ }
+
+ }
+ break;
+ case ToolBar: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionToolBar();
+ }
+ break;
+ case Tab: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionTab();
+
+
+ QStyleOptionTab *opt = qstyleoption_cast<QStyleOptionTab*>(m_styleoption);
+ opt->text = text();
+
+ if (m_properties.value("hasFrame").toBool())
+ opt->features |= QStyleOptionTab::HasFrame;
+
+ QString orientation = m_properties.value("orientation").toString();
+ QString position = m_properties.value("tabpos").toString();
+ QString selectedPosition = m_properties.value("selectedpos").toString();
+
+ opt->shape = (orientation == "Bottom") ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
+ if (position == QLatin1String("beginning"))
+ opt->position = QStyleOptionTab::Beginning;
+ else if (position == QLatin1String("end"))
+ opt->position = QStyleOptionTab::End;
+ else if (position == QLatin1String("only"))
+ opt->position = QStyleOptionTab::OnlyOneTab;
+ else
+ opt->position = QStyleOptionTab::Middle;
+
+ if (selectedPosition == QLatin1String("next"))
+ opt->selectedPosition = QStyleOptionTab::NextIsSelected;
+ else if (selectedPosition == QLatin1String("previous"))
+ opt->selectedPosition = QStyleOptionTab::PreviousIsSelected;
+ else
+ opt->selectedPosition = QStyleOptionTab::NotAdjacent;
+
+
+ } break;
+
+ case Frame: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionFrame();
+
+ QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(m_styleoption);
+ opt->frameShape = QFrame::StyledPanel;
+ opt->lineWidth = 1;
+ opt->midLineWidth = 1;
+ }
+ break;
+ case FocusRect: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionFocusRect();
+ // Needed on windows
+ m_styleoption->state |= QStyle::State_KeyboardFocusChange;
+ }
+ break;
+ case TabFrame: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionTabWidgetFrame();
+ QStyleOptionTabWidgetFrame *opt = qstyleoption_cast<QStyleOptionTabWidgetFrame*>(m_styleoption);
+
+ opt->selectedTabRect = m_properties["selectedTabRect"].toRect();
+ opt->shape = m_properties["orientation"] == Qt::BottomEdge ? QTabBar::RoundedSouth : QTabBar::RoundedNorth;
+ if (minimum())
+ opt->selectedTabRect = QRect(value(), 0, minimum(), height());
+ opt->tabBarSize = QSize(minimum() , height());
+ // oxygen style needs this hack
+ opt->leftCornerWidgetSize = QSize(value(), 0);
+ }
+ break;
+ case MenuBar:
+ if (!m_styleoption) {
+ QStyleOptionMenuItem *menuOpt = new QStyleOptionMenuItem();
+ menuOpt->menuItemType = QStyleOptionMenuItem::EmptyArea;
+ m_styleoption = menuOpt;
+ }
+
+ break;
+ case MenuBarItem:
+ {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionMenuItem();
+
+ QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption);
+ opt->text = text();
+ opt->menuItemType = QStyleOptionMenuItem::Normal;
+
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(QPlatformTheme::MenuBarFont)) {
+ opt->font = *font;
+ opt->fontMetrics = QFontMetrics(opt->font);
+ m_font = opt->font;
+ }
+ }
+ break;
+ case Menu: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionMenuItem();
+ }
+ break;
+ case MenuItem:
+ case ComboBoxItem:
+ {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionMenuItem();
+
+ QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption);
+ // For GTK style. See below, in setElementType()
+ setProperty("_q_isComboBoxPopupItem", m_itemType == ComboBoxItem);
+ if (text().isEmpty()) {
+ opt->menuItemType = QStyleOptionMenuItem::Separator;
+ } else {
+ opt->text = text();
+
+ if (m_properties["isSubmenu"].toBool()) {
+ opt->menuItemType = QStyleOptionMenuItem::SubMenu;
+ } else {
+ QString shortcut = m_properties["shortcut"].toString();
+ if (!shortcut.isEmpty()) {
+ opt->text += QLatin1Char('\t') + shortcut;
+ opt->tabWidth = qMax(opt->tabWidth, qRound(textWidth(shortcut)));
+ }
+
+ if (m_properties["checkable"].toBool()) {
+ opt->checked = on();
+ QVariant exclusive = m_properties["exclusive"];
+ opt->checkType = exclusive.toBool() ? QStyleOptionMenuItem::Exclusive :
+ QStyleOptionMenuItem::NonExclusive;
+ } else {
+ opt->menuItemType = QStyleOptionMenuItem::Normal;
+ }
+ }
+ if (m_properties["icon"].canConvert<QIcon>())
+ opt->icon = m_properties["icon"].value<QIcon>();
+
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(m_itemType == ComboBoxItem ? QPlatformTheme::ComboMenuItemFont : QPlatformTheme::MenuFont)) {
+ opt->font = *font;
+ opt->fontMetrics = QFontMetrics(opt->font);
+ m_font = opt->font;
+ }
+ }
+ }
+ break;
+ case CheckBox:
+ case RadioButton:
+ {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionButton();
+
+ QStyleOptionButton *opt = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
+ if (!on())
+ opt->state |= QStyle::State_Off;
+ if (m_properties.value("partiallyChecked").toBool())
+ opt->state |= QStyle::State_NoChange;
+ opt->text = text();
+ }
+ break;
+ case Edit: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionFrame();
+
+ QStyleOptionFrame *opt = qstyleoption_cast<QStyleOptionFrame*>(m_styleoption);
+ opt->lineWidth = 1; // this must be non-zero
+ }
+ break;
+ case ComboBox :{
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionComboBox();
+
+ QStyleOptionComboBox *opt = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption);
+
+ if (platformFont == QPlatformTheme::SystemFont)
+ platformFont = QPlatformTheme::PushButtonFont;
+ const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont);
+ if (font)
+ opt->fontMetrics = QFontMetrics(*font);
+ opt->currentText = text();
+ opt->editable = false;
+#ifdef Q_OS_OSX
+ if (m_properties["popup"].canConvert<QObject *>() && style() == "mac") {
+ QObject *popup = m_properties["popup"].value<QObject *>();
+ if (platformFont == QPlatformTheme::MiniFont) {
+ popup->setProperty("__xOffset", -2);
+ popup->setProperty("__yOffset", 5);
+ } else {
+ if (platformFont == QPlatformTheme::SmallFont)
+ popup->setProperty("__xOffset", -1);
+ popup->setProperty("__yOffset", 6);
+ }
+ if (font)
+ popup->setProperty("__font", *font);
+ }
+#endif
+ }
+ break;
+ case SpinBox: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionSpinBox();
+
+ QStyleOptionSpinBox *opt = qstyleoption_cast<QStyleOptionSpinBox*>(m_styleoption);
+ opt->frame = true;
+ if (value() & 0x1)
+ opt->activeSubControls = QStyle::SC_SpinBoxUp;
+ else if (value() & (1<<1))
+ opt->activeSubControls = QStyle::SC_SpinBoxDown;
+ opt->subControls = QStyle::SC_All;
+ opt->stepEnabled = 0;
+ if (value() & (1<<2))
+ opt->stepEnabled |= QAbstractSpinBox::StepUpEnabled;
+ if (value() & (1<<3))
+ opt->stepEnabled |= QAbstractSpinBox::StepDownEnabled;
+ }
+ break;
+ case Slider:
+ case Dial:
+ {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionSlider();
+
+ QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
+ opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
+ opt->upsideDown = !horizontal();
+ opt->minimum = minimum();
+ opt->maximum = maximum();
+ opt->sliderPosition = value();
+ opt->singleStep = step();
+
+ if (opt->singleStep) {
+ qreal numOfSteps = (opt->maximum - opt->minimum) / opt->singleStep;
+ // at least 5 pixels between tick marks
+ if (numOfSteps && (width() / numOfSteps < 5))
+ opt->tickInterval = qRound((5 * numOfSteps / width()) + 0.5) * step();
+ else
+ opt->tickInterval = opt->singleStep;
+
+ } else // default Qt-components implementation
+ opt->tickInterval = opt->maximum != opt->minimum ? 1200 / (opt->maximum - opt->minimum) : 0;
+
+ opt->sliderValue = value();
+ opt->subControls = QStyle::SC_SliderGroove | QStyle::SC_SliderHandle;
+ opt->tickPosition = (activeControl() == "ticks" ?
+ QSlider::TicksBelow : QSlider::NoTicks);
+ if (opt->tickPosition != QSlider::NoTicks)
+ opt->subControls |= QStyle::SC_SliderTickmarks;
+
+ opt->activeSubControls = QStyle::SC_SliderHandle;
+ }
+ break;
+ case ProgressBar: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionProgressBar();
+
+ QStyleOptionProgressBar *opt = qstyleoption_cast<QStyleOptionProgressBar*>(m_styleoption);
+ opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
+ opt->minimum = minimum();
+ opt->maximum = maximum();
+ opt->progress = value();
+ }
+ break;
+ case GroupBox: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionGroupBox();
+
+ QStyleOptionGroupBox *opt = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption);
+ opt->text = text();
+ opt->lineWidth = 1;
+ opt->subControls = QStyle::SC_GroupBoxLabel;
+ opt->features = 0;
+ if (m_properties["sunken"].toBool()) { // Qt draws an ugly line here so I ignore it
+ opt->subControls |= QStyle::SC_GroupBoxFrame;
+ } else {
+ opt->features |= QStyleOptionFrame::Flat;
+ }
+ if (m_properties["checkable"].toBool())
+ opt->subControls |= QStyle::SC_GroupBoxCheckBox;
+
+ }
+ break;
+ case ScrollBar: {
+ if (!m_styleoption)
+ m_styleoption = new QStyleOptionSlider();
+
+ QStyleOptionSlider *opt = qstyleoption_cast<QStyleOptionSlider*>(m_styleoption);
+ opt->minimum = minimum();
+ opt->maximum = maximum();
+ opt->pageStep = qMax(0, int(horizontal() ? width() : height()));
+ opt->orientation = horizontal() ? Qt::Horizontal : Qt::Vertical;
+ opt->sliderPosition = value();
+ opt->sliderValue = value();
+ opt->activeSubControls = (activeControl() == QLatin1String("up"))
+ ? QStyle::SC_ScrollBarSubLine : (activeControl() == QLatin1String("down")) ?
+ QStyle::SC_ScrollBarAddLine :
+ (activeControl() == QLatin1String("handle")) ?
+ QStyle::SC_ScrollBarSlider : hover() ? QStyle::SC_ScrollBarGroove : QStyle::SC_None;
+ if (raised())
+ opt->state |= QStyle::State_On;
+
+ opt->sliderValue = value();
+ opt->subControls = QStyle::SC_All;
+
+ setTransient(qApp->style()->styleHint(QStyle::SH_ScrollBar_Transient, m_styleoption));
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!m_styleoption)
+ m_styleoption = new QStyleOption();
+
+ m_styleoption->styleObject = this;
+ m_styleoption->direction = qApp->layoutDirection();
+ m_styleoption->rect = QRect(m_paintMargins, 0, width() - 2* m_paintMargins, height());
+
+ if (isEnabled()) {
+ m_styleoption->state |= QStyle::State_Enabled;
+ m_styleoption->palette.setCurrentColorGroup(QPalette::Active);
+ } else {
+ m_styleoption->palette.setCurrentColorGroup(QPalette::Disabled);
+ }
+ if (m_active)
+ m_styleoption->state |= QStyle::State_Active;
+ else
+ m_styleoption->palette.setCurrentColorGroup(QPalette::Inactive);
+ if (m_sunken)
+ m_styleoption->state |= QStyle::State_Sunken;
+ if (m_raised)
+ m_styleoption->state |= QStyle::State_Raised;
+ if (m_selected)
+ m_styleoption->state |= QStyle::State_Selected;
+ if (m_focus)
+ m_styleoption->state |= QStyle::State_HasFocus;
+ if (m_on)
+ m_styleoption->state |= QStyle::State_On;
+ if (m_hover)
+ m_styleoption->state |= QStyle::State_MouseOver;
+ if (m_horizontal)
+ m_styleoption->state |= QStyle::State_Horizontal;
+
+ if (sizeHint == "mini") {
+ m_styleoption->state |= QStyle::State_Mini;
+ } else if (sizeHint == "small") {
+ m_styleoption->state |= QStyle::State_Small;
+ }
+
+}
+
+/*
+ * Property style
+ *
+ * Returns a simplified style name.
+ *
+ * QMacStyle = "mac"
+ * QWindowsXPStyle = "windowsxp"
+ * QFusionStyle = "fusion"
+ */
+
+QString QQuickStyleItem::style() const
+{
+ QString style = qApp->style()->metaObject()->className();
+ style = style.toLower();
+ if (style.startsWith(QLatin1Char('q')))
+ style = style.right(style.length() - 1);
+ if (style.endsWith("style"))
+ style = style.left(style.length() - 5);
+ return style;
+}
+
+QString QQuickStyleItem::hitTest(int px, int py)
+{
+ QStyle::SubControl subcontrol = QStyle::SC_All;
+ switch (m_itemType) {
+ case SpinBox :{
+ subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_SpinBox,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ QPoint(px,py), 0);
+ if (subcontrol == QStyle::SC_SpinBoxUp)
+ return "up";
+ else if (subcontrol == QStyle::SC_SpinBoxDown)
+ return "down";
+
+ }
+ break;
+
+ case Slider: {
+ subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_Slider,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ QPoint(px,py), 0);
+ if (subcontrol == QStyle::SC_SliderHandle)
+ return "handle";
+
+ }
+ break;
+ case ScrollBar: {
+ subcontrol = qApp->style()->hitTestComplexControl(QStyle::CC_ScrollBar,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ QPoint(px,py), 0);
+ if (subcontrol == QStyle::SC_ScrollBarSlider)
+ return "handle";
+
+ if (subcontrol == QStyle::SC_ScrollBarSubLine)
+ return "up";
+ else if (subcontrol == QStyle::SC_ScrollBarSubPage)
+ return "upPage";
+
+ if (subcontrol == QStyle::SC_ScrollBarAddLine)
+ return "down";
+ else if (subcontrol == QStyle::SC_ScrollBarAddPage)
+ return "downPage";
+ }
+ break;
+ default:
+ break;
+ }
+ return "none";
+}
+
+QSize QQuickStyleItem::sizeFromContents(int width, int height)
+{
+ initStyleOption();
+
+ QSize size;
+ switch (m_itemType) {
+ case RadioButton:
+ size = qApp->style()->sizeFromContents(QStyle::CT_RadioButton, m_styleoption, QSize(width,height));
+ break;
+ case CheckBox:
+ size = qApp->style()->sizeFromContents(QStyle::CT_CheckBox, m_styleoption, QSize(width,height));
+ break;
+ case ToolBar:
+ size = QSize(200, style().contains("windows") ? 30 : 42);
+ break;
+ case ToolButton: {
+ QStyleOptionToolButton *btn = qstyleoption_cast<QStyleOptionToolButton*>(m_styleoption);
+ int w = 0;
+ int h = 0;
+ if (btn->toolButtonStyle != Qt::ToolButtonTextOnly) {
+ QSize icon = btn->iconSize;
+ w = icon.width();
+ h = icon.height();
+ }
+ if (btn->toolButtonStyle != Qt::ToolButtonIconOnly) {
+ QSize textSize = btn->fontMetrics.size(Qt::TextShowMnemonic, btn->text);
+ textSize.setWidth(textSize.width() + btn->fontMetrics.width(QLatin1Char(' '))*2);
+ if (btn->toolButtonStyle == Qt::ToolButtonTextUnderIcon) {
+ h += 4 + textSize.height();
+ if (textSize.width() > w)
+ w = textSize.width();
+ } else if (btn->toolButtonStyle == Qt::ToolButtonTextBesideIcon) {
+ w += 4 + textSize.width();
+ if (textSize.height() > h)
+ h = textSize.height();
+ } else { // TextOnly
+ w = textSize.width();
+ h = textSize.height();
+ }
+ }
+ btn->rect.setSize(QSize(w, h));
+ size = qApp->style()->sizeFromContents(QStyle::CT_ToolButton, m_styleoption, QSize(w, h)); }
+ break;
+ case Button: {
+ QStyleOptionButton *btn = qstyleoption_cast<QStyleOptionButton*>(m_styleoption);
+ int newWidth = qMax(width, btn->fontMetrics.width(btn->text));
+ int newHeight = qMax(height, btn->fontMetrics.height());
+ size = qApp->style()->sizeFromContents(QStyle::CT_PushButton, m_styleoption, QSize(newWidth, newHeight)); }
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ // Cancel out QMacStylePrivate::PushButton*Offset, or part of it
+ size -= QSize(7, 6);
+ }
+#endif
+ break;
+ case ComboBox: {
+ QStyleOptionComboBox *btn = qstyleoption_cast<QStyleOptionComboBox*>(m_styleoption);
+ int newWidth = qMax(width, btn->fontMetrics.width(btn->currentText));
+ int newHeight = qMax(height, btn->fontMetrics.height());
+ size = qApp->style()->sizeFromContents(QStyle::CT_ComboBox, m_styleoption, QSize(newWidth, newHeight)); }
+ break;
+ case Tab:
+ size = qApp->style()->sizeFromContents(QStyle::CT_TabBarTab, m_styleoption, QSize(width,height));
+ break;
+ case Slider:
+ size = qApp->style()->sizeFromContents(QStyle::CT_Slider, m_styleoption, QSize(width,height));
+ break;
+ case ProgressBar:
+ size = qApp->style()->sizeFromContents(QStyle::CT_ProgressBar, m_styleoption, QSize(width,height));
+ break;
+ case SpinBox:
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ size = qApp->style()->sizeFromContents(QStyle::CT_SpinBox, m_styleoption, QSize(width, height + 5));
+ break;
+ }
+#endif // fall trough if not mac
+ case Edit:
+#ifdef Q_OS_OSX
+ if (style() =="mac") {
+ QString sizeHint = m_hints.value("size").toString();
+ if ((sizeHint == "small") || (sizeHint == "mini"))
+ size = QSize(width, 19);
+ else
+ size = QSize(width, 22);
+ if (style() == "mac" && hints().value("rounded").toBool())
+ size += QSize(4, 4);
+
+ } else
+#endif
+ {
+ // We have to create a new style option since we might be calling with a QStyleOptionSpinBox
+ QStyleOptionFrame frame;
+ frame.state = m_styleoption->state;
+ frame.lineWidth = qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, m_styleoption, 0);
+ frame.rect = m_styleoption->rect;
+ size = qApp->style()->sizeFromContents(QStyle::CT_LineEdit, &frame, QSize(width, height));
+ }
+ break;
+ case GroupBox: {
+ QStyleOptionGroupBox *box = qstyleoption_cast<QStyleOptionGroupBox*>(m_styleoption);
+ QFontMetrics metrics(box->fontMetrics);
+ int baseWidth = metrics.width(box->text) + metrics.width(QLatin1Char(' '));
+ int baseHeight = metrics.height() + m_contentHeight;
+ if (box->subControls & QStyle::SC_GroupBoxCheckBox) {
+ baseWidth += qApp->style()->pixelMetric(QStyle::PM_IndicatorWidth);
+ baseWidth += qApp->style()->pixelMetric(QStyle::PM_CheckBoxLabelSpacing);
+ baseHeight = qMax(baseHeight, qApp->style()->pixelMetric(QStyle::PM_IndicatorHeight));
+ }
+ size = qApp->style()->sizeFromContents(QStyle::CT_GroupBox, m_styleoption, QSize(qMax(baseWidth, m_contentWidth), baseHeight));
+ }
+ break;
+ case Header:
+ size = qApp->style()->sizeFromContents(QStyle::CT_HeaderSection, m_styleoption, QSize(width,height));
+#ifdef Q_OS_OSX
+ if (style() =="mac")
+ size.setHeight(15);
+#endif
+ break;
+ case ItemRow:
+ case Item: //fall through
+ size = qApp->style()->sizeFromContents(QStyle::CT_ItemViewItem, m_styleoption, QSize(width,height));
+ break;
+ case MenuBarItem:
+ size = qApp->style()->sizeFromContents(QStyle::CT_MenuBarItem, m_styleoption, QSize(width,height));
+ break;
+ case MenuBar:
+ size = qApp->style()->sizeFromContents(QStyle::CT_MenuBar, m_styleoption, QSize(width,height));
+ break;
+ case Menu:
+ size = qApp->style()->sizeFromContents(QStyle::CT_Menu, m_styleoption, QSize(width,height));
+ break;
+ case MenuItem:
+ case ComboBoxItem:
+ size = qApp->style()->sizeFromContents(QStyle::CT_MenuItem, m_styleoption, QSize(width,height));
+ break;
+ default:
+ break;
+ } return size;
+}
+
+void QQuickStyleItem::setContentWidth(int arg)
+{
+ if (m_contentWidth != arg) {
+ m_contentWidth = arg;
+ emit contentWidthChanged(arg);
+ }
+}
+
+void QQuickStyleItem::setContentHeight(int arg)
+{
+ if (m_contentHeight != arg) {
+ m_contentHeight = arg;
+ emit contentHeightChanged(arg);
+ }
+}
+
+void QQuickStyleItem::updateSizeHint()
+{
+ QSize implicitSize = sizeFromContents(m_contentWidth, m_contentHeight);
+ setImplicitSize(implicitSize.width(), implicitSize.height());
+}
+
+void QQuickStyleItem::updateRect()
+{
+ initStyleOption();
+ m_styleoption->rect.setWidth(width());
+}
+
+int QQuickStyleItem::pixelMetric(const QString &metric)
+{
+
+ if (metric == "scrollbarExtent")
+ return qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0 );
+ else if (metric == "defaultframewidth")
+ return qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, 0);
+ else if (metric == "taboverlap")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarTabOverlap, 0 );
+ else if (metric == "tabbaseoverlap")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseOverlap, m_styleoption );
+ else if (metric == "tabhspace")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarTabHSpace, 0 );
+ else if (metric == "indicatorwidth")
+ return qApp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth, 0 );
+ else if (metric == "tabvspace")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarTabVSpace, 0 );
+ else if (metric == "tabbaseheight")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarBaseHeight, 0 );
+ else if (metric == "tabvshift")
+ return qApp->style()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, 0 );
+ else if (metric == "menubarhmargin")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuBarHMargin, 0 );
+ else if (metric == "menubarvmargin")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuBarVMargin, 0 );
+ else if (metric == "menubarpanelwidth")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuBarPanelWidth, 0 );
+ else if (metric == "menubaritemspacing")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuBarItemSpacing, 0 );
+ else if (metric == "spacebelowmenubar")
+ return qApp->style()->styleHint(QStyle::SH_MainWindow_SpaceBelowMenuBar, m_styleoption);
+ else if (metric == "menuhmargin")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuHMargin, 0 );
+ else if (metric == "menuvmargin")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuVMargin, 0 );
+ else if (metric == "menupanelwidth")
+ return qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0 );
+ else if (metric == "submenuoverlap")
+ return qApp->style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0 );
+ else if (metric == "splitterwidth")
+ return qApp->style()->pixelMetric(QStyle::PM_SplitterWidth, 0 );
+ else if (metric == "scrollbarspacing")
+ return abs(qApp->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, 0 ));
+ return 0;
+}
+
+QVariant QQuickStyleItem::styleHint(const QString &metric)
+{
+ initStyleOption();
+ if (metric == "comboboxpopup") {
+ return qApp->style()->styleHint(QStyle::SH_ComboBox_Popup, m_styleoption);
+ } else if (metric == "highlightedTextColor") {
+ QPalette pal = QApplication::palette("QAbstractItemView");
+ pal.setCurrentColorGroup(m_styleoption->palette.currentColorGroup());
+ return pal.highlightedText().color().name();
+ } else if (metric == "textColor") {
+ QPalette pal = qApp->palette();
+ pal.setCurrentColorGroup(active()? QPalette::Active : QPalette::Inactive);
+ return pal.text().color().name();
+ } else if (metric == "focuswidget") {
+ return qApp->style()->styleHint(QStyle::SH_FocusFrame_AboveWidget);
+ } else if (metric == "tabbaralignment") {
+ int result = qApp->style()->styleHint(QStyle::SH_TabBar_Alignment);
+ if (result == Qt::AlignCenter)
+ return "center";
+ return "left";
+ } else if (metric == "externalScrollBars") {
+ return qApp->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents);
+ } else if (metric == "scrollToClickPosition")
+ return qApp->style()->styleHint(QStyle::SH_ScrollBar_LeftClickAbsolutePosition);
+ else if (metric == "activateItemOnSingleClick")
+ return qApp->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick);
+ return 0;
+
+ // Add SH_Menu_SpaceActivatesItem, SH_Menu_SubMenuPopupDelay
+}
+
+void QQuickStyleItem::setHints(const QVariantMap &str)
+{
+ if (m_hints != str) {
+ m_hints = str;
+ initStyleOption();
+ updateSizeHint();
+ if (m_styleoption->state & QStyle::State_Mini) {
+ m_font.setPointSize(9.);
+ emit fontChanged();
+ } else if (m_styleoption->state & QStyle::State_Small) {
+ m_font.setPointSize(11.);
+ emit fontChanged();
+ } else {
+ emit hintChanged();
+ }
+ }
+}
+
+void QQuickStyleItem::resetHints()
+{
+ m_hints.clear();
+}
+
+
+void QQuickStyleItem::setElementType(const QString &str)
+{
+ if (m_type == str)
+ return;
+
+ m_type = str;
+
+ emit elementTypeChanged();
+ if (m_styleoption) {
+ delete m_styleoption;
+ m_styleoption = 0;
+ }
+
+ // Only enable visible if the widget can animate
+ if (str == "menu") {
+ m_itemType = Menu;
+ } else if (str == "menuitem") {
+ m_itemType = MenuItem;
+ } else if (str == "item" || str == "itemrow" || str == "header") {
+#ifdef Q_OS_OSX
+ m_font.setPointSize(11.0);
+ emit fontChanged();
+#endif
+ if (str == "header") {
+ m_itemType = Header;
+ } else {
+ m_itemType = (str == "item") ? Item : ItemRow;
+ }
+ } else if (str == "groupbox") {
+ m_itemType = GroupBox;
+ } else if (str == "tab") {
+ m_itemType = Tab;
+ } else if (str == "tabframe") {
+ m_itemType = TabFrame;
+ } else if (str == "comboboxitem") {
+ // Gtk uses qobject cast, hence we need to separate this from menuitem
+ // On mac, we temporarily use the menu item because it has more accurate
+ // palette.
+ m_itemType = ComboBoxItem;
+ } else if (str == "toolbar") {
+ m_itemType = ToolBar;
+ } else if (str == "toolbutton") {
+ m_itemType = ToolButton;
+ } else if (str == "slider") {
+ m_itemType = Slider;
+ } else if (str == "frame") {
+ m_itemType = Frame;
+ } else if (str == "combobox") {
+ m_itemType = ComboBox;
+ } else if (str == "splitter") {
+ m_itemType = Splitter;
+ } else if (str == "progressbar") {
+ m_itemType = ProgressBar;
+ } else if (str == "button") {
+ m_itemType = Button;
+ } else if (str == "checkbox") {
+ m_itemType = CheckBox;
+ } else if (str == "radiobutton") {
+ m_itemType = RadioButton;
+ } else if (str == "edit") {
+ m_itemType = Edit;
+ } else if (str == "spinbox") {
+ m_itemType = SpinBox;
+ } else if (str == "scrollbar") {
+ m_itemType = ScrollBar;
+ } else if (str == "widget") {
+ m_itemType = Widget;
+ } else if (str == "focusframe") {
+ m_itemType = FocusFrame;
+ } else if (str == "focusrect") {
+ m_itemType = FocusRect;
+ } else if (str == "dial") {
+ m_itemType = Dial;
+ } else if (str == "statusbar") {
+ m_itemType = StatusBar;
+ } else if (str == "machelpbutton") {
+ m_itemType = MacHelpButton;
+ } else if (str == "scrollareacorner") {
+ m_itemType = ScrollAreaCorner;
+ } else if (str == "menubar") {
+ m_itemType = MenuBar;
+ } else if (str == "menubaritem") {
+ m_itemType = MenuBarItem;
+ } else {
+ m_itemType = Undefined;
+ }
+ updateSizeHint();
+}
+
+QRectF QQuickStyleItem::subControlRect(const QString &subcontrolString)
+{
+ QStyle::SubControl subcontrol = QStyle::SC_None;
+ initStyleOption();
+ switch (m_itemType) {
+ case SpinBox:
+ {
+ QStyle::ComplexControl control = QStyle::CC_SpinBox;
+ if (subcontrolString == QLatin1String("down"))
+ subcontrol = QStyle::SC_SpinBoxDown;
+ else if (subcontrolString == QLatin1String("up"))
+ subcontrol = QStyle::SC_SpinBoxUp;
+ else if (subcontrolString == QLatin1String("edit")){
+ subcontrol = QStyle::SC_SpinBoxEditField;
+ }
+ return qApp->style()->subControlRect(control,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ subcontrol);
+
+ }
+ break;
+ case Slider:
+ {
+ QStyle::ComplexControl control = QStyle::CC_Slider;
+ if (subcontrolString == QLatin1String("handle"))
+ subcontrol = QStyle::SC_SliderHandle;
+ else if (subcontrolString == QLatin1String("groove"))
+ subcontrol = QStyle::SC_SliderGroove;
+ return qApp->style()->subControlRect(control,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ subcontrol);
+
+ }
+ break;
+ case ScrollBar:
+ {
+ QStyle::ComplexControl control = QStyle::CC_ScrollBar;
+ if (subcontrolString == QLatin1String("slider"))
+ subcontrol = QStyle::SC_ScrollBarSlider;
+ if (subcontrolString == QLatin1String("groove"))
+ subcontrol = QStyle::SC_ScrollBarGroove;
+ else if (subcontrolString == QLatin1String("handle"))
+ subcontrol = QStyle::SC_ScrollBarSlider;
+ else if (subcontrolString == QLatin1String("add"))
+ subcontrol = QStyle::SC_ScrollBarAddPage;
+ else if (subcontrolString == QLatin1String("sub"))
+ subcontrol = QStyle::SC_ScrollBarSubPage;
+ return qApp->style()->subControlRect(control,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ subcontrol);
+ }
+ break;
+ default:
+ break;
+ }
+ return QRectF();
+}
+
+namespace {
+class QHighDpiPixmapsEnabler {
+public:
+ QHighDpiPixmapsEnabler()
+ :wasEnabled(false)
+ {
+ if (!qApp->testAttribute(Qt::AA_UseHighDpiPixmaps)) {
+ qApp->setAttribute(Qt::AA_UseHighDpiPixmaps);
+ wasEnabled = true;
+ }
+ }
+
+ ~QHighDpiPixmapsEnabler()
+ {
+ if (wasEnabled)
+ qApp->setAttribute(Qt::AA_UseHighDpiPixmaps, false);
+ }
+private:
+ bool wasEnabled;
+};
+}
+
+void QQuickStyleItem::paint(QPainter *painter)
+{
+ initStyleOption();
+ if (QStyleOptionMenuItem *opt = qstyleoption_cast<QStyleOptionMenuItem*>(m_styleoption))
+ painter->setFont(opt->font);
+ else {
+ QPlatformTheme::Font platformFont = (m_styleoption->state & QStyle::State_Mini) ? QPlatformTheme::MiniFont :
+ (m_styleoption->state & QStyle::State_Small) ? QPlatformTheme::SmallFont :
+ QPlatformTheme::NFonts;
+ if (platformFont != QPlatformTheme::NFonts)
+ if (const QFont *font = QGuiApplicationPrivate::platformTheme()->font(platformFont))
+ painter->setFont(*font);
+ }
+
+ // Set AA_UseHighDpiPixmaps when calling style code to make QIcon return
+ // "retina" pixmaps. The flag is controlled by the application so we can't
+ // set it unconditinally.
+ QHighDpiPixmapsEnabler enabler;
+
+ switch (m_itemType) {
+ case Button:
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ // Add back what was substracted in sizeFromContents()
+ m_styleoption->rect.adjust(-4, -2, 3, 4);
+ }
+#endif
+ qApp->style()->drawControl(QStyle::CE_PushButton, m_styleoption, painter);
+ break;
+ case ItemRow :{
+ QPixmap pixmap;
+ // Only draw through style once
+ const QString pmKey = QLatin1Literal("itemrow") % QString::number(m_styleoption->state,16) % activeControl();
+ if (!QPixmapCache::find(pmKey, pixmap) || pixmap.width() < width() || height() != pixmap.height()) {
+ int newSize = width();
+ pixmap = QPixmap(newSize, height());
+ pixmap.fill(Qt::transparent);
+ QPainter pixpainter(&pixmap);
+ qApp->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, m_styleoption, &pixpainter);
+ if ((style() == "mac" || !qApp->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected)) && selected()) {
+ QPalette pal = QApplication::palette("QAbstractItemView");
+ pal.setCurrentColorGroup(m_styleoption->palette.currentColorGroup());
+ pixpainter.fillRect(m_styleoption->rect, pal.highlight());
+ }
+ QPixmapCache::insert(pmKey, pixmap);
+ }
+ painter->drawPixmap(0, 0, pixmap);
+ }
+ break;
+ case Item:
+ qApp->style()->drawControl(QStyle::CE_ItemViewItem, m_styleoption, painter);
+ break;
+ case Header:
+ qApp->style()->drawControl(QStyle::CE_Header, m_styleoption, painter);
+ break;
+ case ToolButton:
+
+#ifdef Q_OS_OSX
+ if (style() == "mac" && hints().value("segmented").toBool()) {
+ const QPaintDevice *target = painter->device();
+ HIThemeSegmentDrawInfo sgi;
+ sgi.version = 0;
+ sgi.state = isEnabled() ? kThemeStateActive : kThemeStateDisabled;
+ if (sunken()) sgi.state |= kThemeStatePressed;
+ sgi.size = kHIThemeSegmentSizeNormal;
+ sgi.kind = kHIThemeSegmentKindTextured;
+ sgi.value = on() && !sunken() ? kThemeButtonOn : kThemeButtonOff;
+
+ sgi.adornment |= kHIThemeSegmentAdornmentLeadingSeparator;
+ if (sunken()) {
+ sgi.adornment |= kHIThemeSegmentAdornmentTrailingSeparator;
+ }
+ SInt32 button_height;
+ GetThemeMetric(kThemeMetricButtonRoundedHeight, &button_height);
+ QString buttonPos = m_properties.value("position").toString();
+ sgi.position = buttonPos == "leftmost" ? kHIThemeSegmentPositionFirst :
+ buttonPos == "rightmost" ? kHIThemeSegmentPositionLast :
+ buttonPos == "h_middle" ? kHIThemeSegmentPositionMiddle :
+ kHIThemeSegmentPositionOnly;
+ QRect centered = m_styleoption->rect;
+ centered.setHeight(button_height);
+ centered.moveCenter(m_styleoption->rect.center());
+ HIRect hirect = qt_hirectForQRect(centered.translated(0, -1), QRect(0, 0, 0, 0));
+ HIThemeDrawSegment(&hirect, &sgi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
+ } else
+#endif
+ qApp->style()->drawComplexControl(QStyle::CC_ToolButton, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
+ break;
+ case Tab:
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ m_styleoption->rect.translate(0, 1); // Unhack QMacStyle's hack
+ qApp->style()->drawControl(QStyle::CE_TabBarTabShape, m_styleoption, painter);
+ m_styleoption->rect.translate(0, -1);
+ qApp->style()->drawControl(QStyle::CE_TabBarTabLabel, m_styleoption, painter);
+ } else
+#endif
+ {
+ qApp->style()->drawControl(QStyle::CE_TabBarTab, m_styleoption, painter);
+ }
+ break;
+ case Frame:
+ qApp->style()->drawControl(QStyle::CE_ShapedFrame, m_styleoption, painter);
+ break;
+ case FocusFrame:
+ qApp->style()->drawControl(QStyle::CE_FocusFrame, m_styleoption, painter);
+ break;
+ case FocusRect:
+ qApp->style()->drawPrimitive(QStyle::PE_FrameFocusRect, m_styleoption, painter);
+ break;
+ case TabFrame:
+ qApp->style()->drawPrimitive(QStyle::PE_FrameTabWidget, m_styleoption, painter);
+ break;
+ case MenuBar:
+ qApp->style()->drawControl(QStyle::CE_MenuBarEmptyArea, m_styleoption, painter);
+ break;
+ case MenuBarItem:
+ qApp->style()->drawControl(QStyle::CE_MenuBarItem, m_styleoption, painter);
+ break;
+ case MenuItem:
+ case ComboBoxItem: // fall through
+ qApp->style()->drawControl(QStyle::CE_MenuItem, m_styleoption, painter);
+ break;
+ case CheckBox:
+ qApp->style()->drawControl(QStyle::CE_CheckBox, m_styleoption, painter);
+ break;
+ case RadioButton:
+ qApp->style()->drawControl(QStyle::CE_RadioButton, m_styleoption, painter);
+ break;
+ case Edit: {
+#ifdef Q_OS_OSX
+ if (style() == "mac" && hints().value("rounded").toBool()) {
+ const QPaintDevice *target = painter->device();
+ HIThemeFrameDrawInfo fdi;
+ fdi.version = 0;
+ fdi.state = kThemeStateActive;
+ SInt32 frame_size;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+ fdi.kind = kHIThemeFrameTextFieldRound;
+ if ((m_styleoption->state & QStyle::State_ReadOnly) || !(m_styleoption->state & QStyle::State_Enabled))
+ fdi.state = kThemeStateInactive;
+ fdi.isFocused = hasFocus();
+ HIRect hirect = qt_hirectForQRect(m_styleoption->rect.adjusted(2, 2, -2, 2), QRect(0, 0, 0, 0));
+ HIThemeDrawFrame(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal);
+ } else
+#endif
+ qApp->style()->drawPrimitive(QStyle::PE_PanelLineEdit, m_styleoption, painter);
+ }
+ break;
+ case MacHelpButton:
+#ifdef Q_OS_OSX
+ {
+ const QPaintDevice *target = painter->device();
+ HIThemeButtonDrawInfo fdi;
+ fdi.kind = kThemeRoundButtonHelp;
+ fdi.version = 0;
+ fdi.adornment = 0;
+ fdi.state = sunken() ? kThemeStatePressed : kThemeStateActive;
+ HIRect hirect = qt_hirectForQRect(m_styleoption->rect,QRect(0, 0, 0, 0));
+ HIThemeDrawButton(&hirect, &fdi, qt_mac_cg_context(target), kHIThemeOrientationNormal, NULL);
+ }
+#endif
+ break;
+ case Widget:
+ qApp->style()->drawPrimitive(QStyle::PE_Widget, m_styleoption, painter);
+ break;
+ case ScrollAreaCorner:
+ qApp->style()->drawPrimitive(QStyle::PE_PanelScrollAreaCorner, m_styleoption, painter);
+ break;
+ case Splitter:
+ if (m_styleoption->rect.width() == 1)
+ painter->fillRect(0, 0, width(), height(), m_styleoption->palette.dark().color());
+ else
+ qApp->style()->drawControl(QStyle::CE_Splitter, m_styleoption, painter);
+ break;
+ case ComboBox:
+ {
+ qApp->style()->drawComplexControl(QStyle::CC_ComboBox,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ painter);
+ // This is needed on mac as it will use the painter color and ignore the palette
+ QPen pen = painter->pen();
+ painter->setPen(m_styleoption->palette.text().color());
+ qApp->style()->drawControl(QStyle::CE_ComboBoxLabel, m_styleoption, painter);
+ painter->setPen(pen);
+ } break;
+ case SpinBox:
+ qApp->style()->drawComplexControl(QStyle::CC_SpinBox,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ painter);
+ break;
+ case Slider:
+ qApp->style()->drawComplexControl(QStyle::CC_Slider,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ painter);
+ break;
+ case Dial:
+ qApp->style()->drawComplexControl(QStyle::CC_Dial,
+ qstyleoption_cast<QStyleOptionComplex*>(m_styleoption),
+ painter);
+ break;
+ case ProgressBar:
+ qApp->style()->drawControl(QStyle::CE_ProgressBar, m_styleoption, painter);
+ break;
+ case ToolBar:
+ painter->fillRect(m_styleoption->rect, m_styleoption->palette.window().color());
+ qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter);
+ painter->save();
+ painter->setPen(style() != "fusion" ? m_styleoption->palette.dark().color().darker(120) :
+ m_styleoption->palette.window().color().lighter(107));
+ painter->drawLine(m_styleoption->rect.bottomLeft(), m_styleoption->rect.bottomRight());
+ painter->restore();
+ break;
+ case StatusBar:
+#ifdef Q_OS_OSX
+ if (style() == "mac") {
+ qApp->style()->drawControl(QStyle::CE_ToolBar, m_styleoption, painter);
+ painter->setPen(m_styleoption->palette.dark().color().darker(120));
+ painter->drawLine(m_styleoption->rect.topLeft(), m_styleoption->rect.topRight());
+ } else
+#endif
+ {
+ painter->fillRect(m_styleoption->rect, m_styleoption->palette.window().color());
+ painter->setPen(m_styleoption->palette.dark().color().darker(120));
+ painter->drawLine(m_styleoption->rect.topLeft(), m_styleoption->rect.topRight());
+ qApp->style()->drawPrimitive(QStyle::PE_PanelStatusBar, m_styleoption, painter);
+ }
+ break;
+ case GroupBox:
+ qApp->style()->drawComplexControl(QStyle::CC_GroupBox, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
+ break;
+ case ScrollBar:
+ qApp->style()->drawComplexControl(QStyle::CC_ScrollBar, qstyleoption_cast<QStyleOptionComplex*>(m_styleoption), painter);
+ setOn(false);
+ break;
+ case Menu: {
+ QStyleHintReturnMask val;
+ qApp->style()->styleHint(QStyle::SH_Menu_Mask, m_styleoption, 0, &val);
+ painter->save();
+ painter->setClipRegion(val.region);
+ painter->fillRect(m_styleoption->rect, m_styleoption->palette.window());
+ painter->restore();
+ qApp->style()->drawPrimitive(QStyle::PE_PanelMenu, m_styleoption, painter);
+
+ if (int fw = qApp->style()->pixelMetric(QStyle::PM_MenuPanelWidth)) {
+ QStyleOptionFrame frame;
+ frame.state = QStyle::State_None;
+ frame.lineWidth = fw;
+ frame.midLineWidth = 0;
+ frame.rect = m_styleoption->rect;
+ qApp->style()->drawPrimitive(QStyle::PE_FrameMenu, &frame, painter);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+qreal QQuickStyleItem::textWidth(const QString &text)
+{
+ QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
+ return fm.boundingRect(text).width();
+}
+
+qreal QQuickStyleItem::textHeight(const QString &text)
+{
+ QFontMetricsF fm = QFontMetricsF(m_styleoption->fontMetrics);
+ return text.isEmpty() ? fm.height() :
+ fm.boundingRect(text).height();
+}
+
+QString QQuickStyleItem::elidedText(const QString &text, int elideMode, int width)
+{
+ return m_styleoption->fontMetrics.elidedText(text, Qt::TextElideMode(elideMode), width);
+}
+
+bool QQuickStyleItem::hasThemeIcon(const QString &icon) const
+{
+ return QIcon::hasThemeIcon(icon);
+}
+
+bool QQuickStyleItem::event(QEvent *ev)
+{
+ if (ev->type() == QEvent::StyleAnimationUpdate) {
+ polish();
+ return true;
+ } else if (ev->type() == QEvent::StyleChange) {
+ if (m_itemType == ScrollBar)
+ initStyleOption();
+ }
+ return QQuickItem::event(ev);
+}
+
+QSGNode *QQuickStyleItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
+{
+ if (m_image.isNull()) {
+ delete node;
+ return 0;
+ }
+
+ QQuickStyleNode *styleNode = static_cast<QQuickStyleNode *>(node);
+ if (!styleNode)
+ styleNode = new QQuickStyleNode;
+
+ styleNode->setTexture(window()->createTextureFromImage(m_image, QQuickWindow::TextureCanUseAtlas));
+ styleNode->setRect(boundingRect());
+ return styleNode;
+}
+
+void QQuickStyleItem::updatePolish()
+{
+ if (width() >= 1 && height() >= 1) { // Note these are reals so 1 pixel is minimum
+ float devicePixelRatio = window() ? window()->devicePixelRatio() : qApp->devicePixelRatio();
+ m_image = QImage(width() * devicePixelRatio, height() * devicePixelRatio, QImage::Format_ARGB32_Premultiplied);
+ m_image.setDevicePixelRatio(devicePixelRatio);
+ m_image.fill(Qt::transparent);
+ QPainter painter(&m_image);
+ painter.setLayoutDirection(qApp->layoutDirection());
+ paint(&painter);
+ QQuickItem::update();
+ } else if (!m_image.isNull()) {
+ m_image = QImage();
+ QQuickItem::update();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickstyleitem_p.h b/src/controls/Private/qquickstyleitem_p.h
new file mode 100644
index 00000000..cfe9866e
--- /dev/null
+++ b/src/controls/Private/qquickstyleitem_p.h
@@ -0,0 +1,265 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSTYLEITEM_P_H
+#define QQUICKSTYLEITEM_P_H
+
+#include <QtGui/qimage.h>
+#include <QtQuick/qquickitem.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWidget;
+class QStyleOption;
+
+class QQuickStyleItem: public QQuickItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY( bool sunken READ sunken WRITE setSunken NOTIFY sunkenChanged)
+ Q_PROPERTY( bool raised READ raised WRITE setRaised NOTIFY raisedChanged)
+ Q_PROPERTY( bool active READ active WRITE setActive NOTIFY activeChanged)
+ Q_PROPERTY( bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
+ Q_PROPERTY( bool hasFocus READ hasFocus WRITE sethasFocus NOTIFY hasFocusChanged)
+ Q_PROPERTY( bool on READ on WRITE setOn NOTIFY onChanged)
+ Q_PROPERTY( bool hover READ hover WRITE setHover NOTIFY hoverChanged)
+ Q_PROPERTY( bool horizontal READ horizontal WRITE setHorizontal NOTIFY horizontalChanged)
+ Q_PROPERTY( bool transient READ transient WRITE setTransient NOTIFY transientChanged)
+
+ Q_PROPERTY( QString elementType READ elementType WRITE setElementType NOTIFY elementTypeChanged)
+ Q_PROPERTY( QString text READ text WRITE setText NOTIFY textChanged)
+ Q_PROPERTY( QString activeControl READ activeControl WRITE setActiveControl NOTIFY activeControlChanged)
+ Q_PROPERTY( QString style READ style NOTIFY styleChanged)
+ Q_PROPERTY( QVariantMap hints READ hints WRITE setHints NOTIFY hintChanged RESET resetHints)
+ Q_PROPERTY( QVariantMap properties READ properties WRITE setProperties NOTIFY propertiesChanged)
+ Q_PROPERTY( QFont font READ font NOTIFY fontChanged)
+
+ // For range controls
+ Q_PROPERTY( int minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
+ Q_PROPERTY( int maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
+ Q_PROPERTY( int value READ value WRITE setValue NOTIFY valueChanged)
+ Q_PROPERTY( int step READ step WRITE setStep NOTIFY stepChanged)
+ Q_PROPERTY( int paintMargins READ paintMargins WRITE setPaintMargins NOTIFY paintMarginsChanged)
+
+ Q_PROPERTY( int contentWidth READ contentWidth() WRITE setContentWidth NOTIFY contentWidthChanged)
+ Q_PROPERTY( int contentHeight READ contentHeight() WRITE setContentHeight NOTIFY contentHeightChanged)
+
+public:
+ QQuickStyleItem(QQuickItem *parent = 0);
+ ~QQuickStyleItem();
+
+ enum Type {
+ Undefined,
+ Button,
+ RadioButton,
+ CheckBox,
+ ComboBox,
+ ComboBoxItem,
+ Dial,
+ ToolBar,
+ ToolButton,
+ Tab,
+ TabFrame,
+ Frame,
+ FocusFrame,
+ FocusRect,
+ SpinBox,
+ Slider,
+ ScrollBar,
+ ProgressBar,
+ Edit,
+ GroupBox,
+ Header,
+ Item,
+ ItemRow,
+ Splitter,
+ Menu,
+ MenuItem,
+ Widget,
+ StatusBar,
+ ScrollAreaCorner,
+ MacHelpButton,
+ MenuBar,
+ MenuBarItem
+ };
+
+ void paint(QPainter *);
+
+ bool sunken() const { return m_sunken; }
+ bool raised() const { return m_raised; }
+ bool active() const { return m_active; }
+ bool selected() const { return m_selected; }
+ bool hasFocus() const { return m_focus; }
+ bool on() const { return m_on; }
+ bool hover() const { return m_hover; }
+ bool horizontal() const { return m_horizontal; }
+ bool transient() const { return m_transient; }
+
+ int minimum() const { return m_minimum; }
+ int maximum() const { return m_maximum; }
+ int step() const { return m_step; }
+ int value() const { return m_value; }
+ int paintMargins() const { return m_paintMargins; }
+
+ QString elementType() const { return m_type; }
+ QString text() const { return m_text; }
+ QString activeControl() const { return m_activeControl; }
+ QVariantMap hints() const { return m_hints; }
+ QVariantMap properties() const { return m_properties; }
+ QFont font() const { return m_font;}
+ QString style() const;
+
+ void setSunken(bool sunken) { if (m_sunken != sunken) {m_sunken = sunken; emit sunkenChanged();}}
+ void setRaised(bool raised) { if (m_raised!= raised) {m_raised = raised; emit raisedChanged();}}
+ void setActive(bool active) { if (m_active!= active) {m_active = active; emit activeChanged();}}
+ void setSelected(bool selected) { if (m_selected!= selected) {m_selected = selected; emit selectedChanged();}}
+ void sethasFocus(bool focus) { if (m_focus != focus) {m_focus = focus; emit hasFocusChanged();}}
+ void setOn(bool on) { if (m_on != on) {m_on = on ; emit onChanged();}}
+ void setHover(bool hover) { if (m_hover != hover) {m_hover = hover ; emit hoverChanged();}}
+ void setHorizontal(bool horizontal) { if (m_horizontal != horizontal) {m_horizontal = horizontal; emit horizontalChanged();}}
+ void setTransient(bool transient) { if (m_transient != transient) {m_transient = transient; emit transientChanged();}}
+ void setMinimum(int minimum) { if (m_minimum!= minimum) {m_minimum = minimum; emit minimumChanged();}}
+ void setMaximum(int maximum) { if (m_maximum != maximum) {m_maximum = maximum; emit maximumChanged();}}
+ void setValue(int value) { if (m_value!= value) {m_value = value; emit valueChanged();}}
+ void setStep(int step) { if (m_step != step) { m_step = step; emit stepChanged(); }}
+ void setPaintMargins(int value) { if (m_paintMargins!= value) {m_paintMargins = value;} }
+ void setElementType(const QString &str);
+ void setText(const QString &str) { if (m_text != str) {m_text = str; emit textChanged();}}
+ void setActiveControl(const QString &str) { if (m_activeControl != str) {m_activeControl = str; emit activeControlChanged();}}
+ void setHints(const QVariantMap &str);
+ void setProperties(const QVariantMap &props) { if (m_properties != props) { m_properties = props; emit propertiesChanged(); } }
+ void resetHints();
+
+ int contentWidth() const { return m_contentWidth; }
+ void setContentWidth(int arg);
+
+ int contentHeight() const { return m_contentHeight; }
+ void setContentHeight(int arg);
+
+ virtual void initStyleOption ();
+
+ Q_INVOKABLE qreal textWidth(const QString &);
+ Q_INVOKABLE qreal textHeight(const QString &);
+
+public Q_SLOTS:
+ int pixelMetric(const QString&);
+ QVariant styleHint(const QString&);
+ void updateSizeHint();
+ void updateRect();
+ void updateItem(){polish();}
+ QString hitTest(int x, int y);
+ QRectF subControlRect(const QString &subcontrolString);
+ QString elidedText(const QString &text, int elideMode, int width);
+ bool hasThemeIcon(const QString &) const;
+
+Q_SIGNALS:
+ void elementTypeChanged();
+ void textChanged();
+ void sunkenChanged();
+ void raisedChanged();
+ void activeChanged();
+ void selectedChanged();
+ void hasFocusChanged();
+ void onChanged();
+ void hoverChanged();
+ void horizontalChanged();
+ void transientChanged();
+ void minimumChanged();
+ void maximumChanged();
+ void stepChanged();
+ void valueChanged();
+ void activeControlChanged();
+ void infoChanged();
+ void styleChanged();
+ void paintMarginsChanged();
+ void hintChanged();
+ void propertiesChanged();
+ void fontChanged();
+
+ void contentWidthChanged(int arg);
+ void contentHeightChanged(int arg);
+
+protected:
+ virtual bool event(QEvent *);
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+ virtual void updatePolish();
+
+private:
+ QSize sizeFromContents(int width, int height);
+
+protected:
+ QWidget *m_dummywidget;
+ QStyleOption *m_styleoption;
+ Type m_itemType;
+
+ QString m_type;
+ QString m_text;
+ QString m_activeControl;
+ QVariantMap m_hints;
+ QVariantMap m_properties;
+ QFont m_font;
+
+ bool m_sunken;
+ bool m_raised;
+ bool m_active;
+ bool m_selected;
+ bool m_focus;
+ bool m_hover;
+ bool m_on;
+ bool m_horizontal;
+ bool m_transient;
+ bool m_sharedWidget;
+
+ int m_minimum;
+ int m_maximum;
+ int m_value;
+ int m_step;
+ int m_paintMargins;
+
+ int m_contentWidth;
+ int m_contentHeight;
+
+ QImage m_image;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSTYLEITEM_P_H
diff --git a/src/controls/Private/qquicktooltip.cpp b/src/controls/Private/qquicktooltip.cpp
new file mode 100644
index 00000000..ae4366d9
--- /dev/null
+++ b/src/controls/Private/qquicktooltip.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicktooltip_p.h"
+#include <qquickwindow.h>
+#include <qquickitem.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
+#ifndef QT_NO_WIDGETS
+#include <qtooltip.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QQuickTooltip::QQuickTooltip(QObject *parent)
+ : QObject(parent)
+{
+
+}
+
+void QQuickTooltip::showText(QQuickItem *item, const QPointF &pos, const QString &str)
+{
+ if (!item || !item->window())
+ return;
+#ifndef QT_NO_WIDGETS
+ if (QGuiApplicationPrivate::platformIntegration()->
+ hasCapability(QPlatformIntegration::MultipleWindows) &&
+ QCoreApplication::instance()->inherits("QApplication"))
+ QToolTip::showText(item->window()->mapToGlobal(item->mapToScene(pos).toPoint()), str);
+#else
+ Q_UNUSED(item);
+ Q_UNUSED(pos);
+ Q_UNUSED(str);
+#endif
+}
+
+void QQuickTooltip::hideText()
+{
+#ifndef QT_NO_WIDGETS
+ QToolTip::hideText();
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquicktooltip_p.h b/src/controls/Private/qquicktooltip_p.h
new file mode 100644
index 00000000..20f91830
--- /dev/null
+++ b/src/controls/Private/qquicktooltip_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKTOOLTIP_P_H
+#define QQUICKTOOLTIP_P_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPointF;
+class QQuickItem;
+
+class QQuickTooltip : public QObject
+{
+ Q_OBJECT
+
+public:
+ QQuickTooltip(QObject *parent = 0);
+
+ Q_INVOKABLE void showText(QQuickItem *item, const QPointF &pos, const QString &text);
+ Q_INVOKABLE void hideText();
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKTOOLTIP_P_H
diff --git a/src/controls/Private/qquickwheelarea.cpp b/src/controls/Private/qquickwheelarea.cpp
new file mode 100644
index 00000000..101e22bf
--- /dev/null
+++ b/src/controls/Private/qquickwheelarea.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickwheelarea_p.h"
+
+QT_BEGIN_NAMESPACE
+
+// On Mac OS X, the scrolling speed in Safari is roughly 2.5 times faster
+// than in TextEdit (the native app). The former is using high-resolution
+// pixel-based delta values as they are, which is fine for a typical web
+// content, whereas the latter evidently makes scrolling slower to make it
+// feel natural and more precise for typical document type of content.
+// => we'll compromise between the two for now, and pick an arbitrary value
+// to make the pixel-based scrolling speed something between the two
+static const qreal pixelDeltaAdjustment = 0.5;
+
+// The default scroll speed for typical angle-based mouse wheels. The value
+// comes originally from QTextEdit, which sets 20px steps by default.
+static const qreal defaultScrollSpeed = 20.0;
+
+QQuickWheelArea::QQuickWheelArea(QQuickItem *parent)
+ : QQuickItem(parent),
+ m_horizontalMinimumValue(0),
+ m_horizontalMaximumValue(0),
+ m_verticalMinimumValue(0),
+ m_verticalMaximumValue(0),
+ m_horizontalValue(0),
+ m_verticalValue(0),
+ m_verticalDelta(0),
+ m_horizontalDelta(0),
+ m_scrollSpeed(defaultScrollSpeed)
+{
+
+}
+
+QQuickWheelArea::~QQuickWheelArea()
+{
+
+}
+
+void QQuickWheelArea::wheelEvent(QWheelEvent *we)
+{
+ QPoint numPixels = we->pixelDelta();
+ QPoint numDegrees = we->angleDelta() / 8;
+
+ if (!numPixels.isNull()) {
+ setHorizontalDelta(numPixels.x() * pixelDeltaAdjustment);
+ setVerticalDelta(numPixels.y() * pixelDeltaAdjustment);
+ } else if (!numDegrees.isNull()) {
+ setHorizontalDelta(numDegrees.x() / 15.0 * m_scrollSpeed);
+ setVerticalDelta(numDegrees.y() / 15.0 * m_scrollSpeed);
+ }
+
+ we->accept();
+}
+
+void QQuickWheelArea::setHorizontalMinimumValue(qreal value)
+{
+ m_horizontalMinimumValue = value;
+}
+
+qreal QQuickWheelArea::horizontalMinimumValue() const
+{
+ return m_horizontalMinimumValue;
+}
+
+void QQuickWheelArea::setHorizontalMaximumValue(qreal value)
+{
+ m_horizontalMaximumValue = value;
+}
+
+qreal QQuickWheelArea::horizontalMaximumValue() const
+{
+ return m_horizontalMaximumValue;
+}
+
+void QQuickWheelArea::setVerticalMinimumValue(qreal value)
+{
+ m_verticalMinimumValue = value;
+}
+
+qreal QQuickWheelArea::verticalMinimumValue() const
+{
+ return m_verticalMinimumValue;
+}
+
+void QQuickWheelArea::setVerticalMaximumValue(qreal value)
+{
+ m_verticalMaximumValue = value;
+}
+
+qreal QQuickWheelArea::verticalMaximumValue() const
+{
+ return m_verticalMaximumValue;
+}
+
+void QQuickWheelArea::setHorizontalValue(qreal value)
+{
+ value = qBound<qreal>(m_horizontalMinimumValue, value, m_horizontalMaximumValue);
+
+ if (value != m_horizontalValue) {
+ m_horizontalValue = value;
+ emit horizontalValueChanged();
+ }
+}
+
+qreal QQuickWheelArea::horizontalValue() const
+{
+ return m_horizontalValue;
+}
+
+void QQuickWheelArea::setVerticalValue(qreal value)
+{
+ value = qBound<qreal>(m_verticalMinimumValue, value, m_verticalMaximumValue);
+
+ if (value != m_verticalValue) {
+ m_verticalValue = value;
+ emit verticalValueChanged();
+ }
+}
+
+qreal QQuickWheelArea::verticalValue() const
+{
+ return m_verticalValue;
+}
+
+void QQuickWheelArea::setVerticalDelta(qreal value)
+{
+ m_verticalDelta = value;
+ setVerticalValue(m_verticalValue - m_verticalDelta);
+
+ emit verticalWheelMoved();
+}
+
+qreal QQuickWheelArea::verticalDelta() const
+{
+ return m_verticalDelta;
+}
+
+void QQuickWheelArea::setHorizontalDelta(qreal value)
+{
+ m_horizontalDelta = value;
+ setHorizontalValue(m_horizontalValue - m_horizontalDelta);
+
+ emit horizontalWheelMoved();
+}
+
+qreal QQuickWheelArea::horizontalDelta() const
+{
+ return m_horizontalDelta;
+}
+
+void QQuickWheelArea::setScrollSpeed(qreal value)
+{
+ if (value != m_scrollSpeed) {
+ m_scrollSpeed = value;
+ emit scrollSpeedChanged();
+ }
+}
+
+qreal QQuickWheelArea::scrollSpeed() const
+{
+ return m_scrollSpeed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/controls/Private/qquickwheelarea_p.h b/src/controls/Private/qquickwheelarea_p.h
new file mode 100644
index 00000000..057ad56d
--- /dev/null
+++ b/src/controls/Private/qquickwheelarea_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKWHEELAREA_P_H
+#define QQUICKWHEELAREA_P_H
+
+#include <QtGui/qevent.h>
+#include <QtQuick/qquickitem.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickWheelArea : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal verticalDelta READ verticalDelta WRITE setVerticalDelta NOTIFY verticalWheelMoved)
+ Q_PROPERTY(qreal horizontalDelta READ horizontalDelta WRITE setHorizontalDelta NOTIFY horizontalWheelMoved)
+ Q_PROPERTY(qreal horizontalMinimumValue READ horizontalMinimumValue WRITE setHorizontalMinimumValue)
+ Q_PROPERTY(qreal horizontalMaximumValue READ horizontalMaximumValue WRITE setHorizontalMaximumValue)
+ Q_PROPERTY(qreal verticalMinimumValue READ verticalMinimumValue WRITE setVerticalMinimumValue)
+ Q_PROPERTY(qreal verticalMaximumValue READ verticalMaximumValue WRITE setVerticalMaximumValue)
+ Q_PROPERTY(qreal horizontalValue READ horizontalValue WRITE setHorizontalValue)
+ Q_PROPERTY(qreal verticalValue READ verticalValue WRITE setVerticalValue)
+ Q_PROPERTY(qreal scrollSpeed READ scrollSpeed WRITE setScrollSpeed NOTIFY scrollSpeedChanged)
+
+public:
+ QQuickWheelArea(QQuickItem *parent = 0);
+ virtual ~QQuickWheelArea();
+
+ void setHorizontalMinimumValue(qreal value);
+ qreal horizontalMinimumValue() const;
+
+ void setHorizontalMaximumValue(qreal value);
+ qreal horizontalMaximumValue() const;
+
+ void setVerticalMinimumValue(qreal value);
+ qreal verticalMinimumValue() const;
+
+ void setVerticalMaximumValue(qreal value);
+ qreal verticalMaximumValue() const;
+
+ void setHorizontalValue(qreal value);
+ qreal horizontalValue() const;
+
+ void setVerticalValue(qreal value);
+ qreal verticalValue() const;
+
+ void setVerticalDelta(qreal value);
+ qreal verticalDelta() const;
+
+ void setHorizontalDelta(qreal value);
+ qreal horizontalDelta() const;
+
+ void setScrollSpeed(qreal value);
+ qreal scrollSpeed() const;
+
+ void wheelEvent(QWheelEvent *event);
+
+Q_SIGNALS:
+ void verticalValueChanged();
+ void horizontalValueChanged();
+ void verticalWheelMoved();
+ void horizontalWheelMoved();
+ void scrollSpeedChanged();
+
+private:
+ qreal m_horizontalMinimumValue;
+ qreal m_horizontalMaximumValue;
+ qreal m_verticalMinimumValue;
+ qreal m_verticalMaximumValue;
+ qreal m_horizontalValue;
+ qreal m_verticalValue;
+ qreal m_verticalDelta;
+ qreal m_horizontalDelta;
+ qreal m_scrollSpeed;
+
+ Q_DISABLE_COPY(QQuickWheelArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickWheelArea)
+
+#endif // QQUICKWHEELAREA_P_H
diff --git a/src/controls/Private/style.js b/src/controls/Private/style.js
new file mode 100644
index 00000000..2c47ff0e
--- /dev/null
+++ b/src/controls/Private/style.js
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+.pragma library
+
+function underlineAmpersands(match, p1, p2, p3) {
+ if (p2 === "&")
+ return p1.concat(p2, p3)
+ return p1.concat("<u>", p2, "</u>", p3)
+}
+
+function removeAmpersands(match, p1, p2, p3) {
+ return p1.concat(p2, p3)
+}
+
+function replaceAmpersands(text, replaceFunction) {
+ return text.replace(/([^&]*)&(.)([^&]*)/g, replaceFunction)
+}
+
+function stylizeMnemonics(text) {
+ return replaceAmpersands(text, underlineAmpersands)
+}
+
+function removeMnemonics(text) {
+ return replaceAmpersands(text, removeAmpersands)
+}