summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/StudioControls/AbstractButton.qml121
-rw-r--r--src/imports/StudioControls/ActionIndicator.qml140
-rw-r--r--src/imports/StudioControls/Button.qml44
-rw-r--r--src/imports/StudioControls/ButtonGroup.qml31
-rw-r--r--src/imports/StudioControls/ButtonRow.qml51
-rw-r--r--src/imports/StudioControls/CheckBox.qml166
-rw-r--r--src/imports/StudioControls/CheckIndicator.qml138
-rw-r--r--src/imports/StudioControls/ComboBox.qml257
-rw-r--r--src/imports/StudioControls/ComboBoxInput.qml163
-rw-r--r--src/imports/StudioControls/ContextMenu.qml91
-rw-r--r--src/imports/StudioControls/ControlScrollBar.qml63
-rw-r--r--src/imports/StudioControls/ExpandingSpacer.qml31
-rw-r--r--src/imports/StudioControls/ItemDelegate.qml31
-rw-r--r--src/imports/StudioControls/Menu.qml65
-rw-r--r--src/imports/StudioControls/MenuItem.qml83
-rw-r--r--src/imports/StudioControls/MenuSeparator.qml45
-rw-r--r--src/imports/StudioControls/RealSliderPopup.qml91
-rw-r--r--src/imports/StudioControls/RealSpinBox.qml354
-rw-r--r--src/imports/StudioControls/RealSpinBoxIndicator.qml204
-rw-r--r--src/imports/StudioControls/RealSpinBoxInput.qml252
-rw-r--r--src/imports/StudioControls/ScrollBar.qml60
-rw-r--r--src/imports/StudioControls/ScrollView.qml71
-rw-r--r--src/imports/StudioControls/SecondColumnLayout.qml32
-rw-r--r--src/imports/StudioControls/Section.qml130
-rw-r--r--src/imports/StudioControls/SectionLabel.qml53
-rw-r--r--src/imports/StudioControls/SectionLayout.qml34
-rw-r--r--src/imports/StudioControls/Slider.qml294
-rw-r--r--src/imports/StudioControls/SliderPopup.qml101
-rw-r--r--src/imports/StudioControls/SpinBox.qml329
-rw-r--r--src/imports/StudioControls/SpinBoxIndicator.qml133
-rw-r--r--src/imports/StudioControls/SpinBoxInput.qml215
-rw-r--r--src/imports/StudioControls/TextArea.qml140
-rw-r--r--src/imports/StudioControls/TextAreaScrollView.qml62
-rw-r--r--src/imports/StudioControls/TextField.qml176
-rw-r--r--src/imports/StudioControls/TranslationIndicator.qml137
-rw-r--r--src/imports/StudioControls/qmldir35
-rw-r--r--src/imports/StudioTheme/Constants.qml81
-rw-r--r--src/imports/StudioTheme/Values.qml125
-rw-r--r--src/imports/StudioTheme/icons.ttfbin0 -> 5280 bytes
-rw-r--r--src/imports/StudioTheme/qmldir2
40 files changed, 4631 insertions, 0 deletions
diff --git a/src/imports/StudioControls/AbstractButton.qml b/src/imports/StudioControls/AbstractButton.qml
new file mode 100644
index 0000000..222334f
--- /dev/null
+++ b/src/imports/StudioControls/AbstractButton.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.AbstractButton {
+ id: myButton
+
+ property alias buttonIcon: buttonIcon.text
+ property alias iconColor: buttonIcon.color
+ property alias backgroundVisible: buttonBackground.visible
+ property alias backgroundRadius: buttonBackground.radius
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+ height: StudioTheme.Values.height
+ width: StudioTheme.Values.height
+ z: myButton.checked ? 10 : 3
+ activeFocusOnTab: false
+
+ background: Rectangle {
+ id: buttonBackground
+ color: myButton.checked ? StudioTheme.Values.themeControlBackgroundChecked : StudioTheme.Values.themeControlBackground
+ border.color: myButton.checked ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ }
+
+ indicator: Item {
+ x: 0
+ y: 0
+ implicitWidth: myButton.width
+ implicitHeight: myButton.height
+
+ T.Label {
+ id: buttonIcon
+ color: StudioTheme.Values.themeTextColor
+ font.family: StudioTheme.Constants.iconFont.family
+ font.pixelSize: StudioTheme.Values.myIconFontSize
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ renderType: Text.QtRendering
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myButton.enabled && !myButton.hovered && !myButton.pressed
+ && !myButton.checked
+ PropertyChanges {
+ target: buttonBackground
+ color: StudioTheme.Values.themeControlBackground
+ }
+ PropertyChanges {
+ target: myButton
+ z: 3
+ }
+ },
+ State {
+ name: "hovered"
+ when: myButton.hovered && !myButton.pressed
+ PropertyChanges {
+ target: buttonBackground
+ color: StudioTheme.Values.themeHoverHighlight
+ }
+ },
+ State {
+ name: "pressed"
+ when: myButton.hovered && myButton.pressed
+ PropertyChanges {
+ target: buttonBackground
+ color: StudioTheme.Values.themeControlBackgroundPressed
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ PropertyChanges {
+ target: myButton
+ z: 10
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myButton.enabled
+ PropertyChanges {
+ target: buttonBackground
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: buttonIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/ActionIndicator.qml b/src/imports/StudioControls/ActionIndicator.qml
new file mode 100644
index 0000000..e261ebe
--- /dev/null
+++ b/src/imports/StudioControls/ActionIndicator.qml
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Rectangle {
+ id: actionIndicator
+
+ property Item myControl
+
+ property bool showBackground: true
+ property alias icon: actionIndicatorIcon
+
+ property bool hover: false
+ property bool pressed: false
+
+ color: actionIndicator.showBackground ? StudioTheme.Values.themeControlBackground : "transparent"
+ border.color: actionIndicator.showBackground ? StudioTheme.Values.themeControlOutline : "transparent"
+
+ implicitWidth: StudioTheme.Values.height
+ implicitHeight: StudioTheme.Values.height
+
+ signal clicked
+
+ T.Label {
+ id: actionIndicatorIcon
+ anchors.fill: parent
+ text: StudioTheme.Constants.actionIcon
+ color: StudioTheme.Values.themeTextColor
+ font.family: StudioTheme.Constants.iconFont.family
+ font.pixelSize: StudioTheme.Values.myIconFontSize
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+
+ states: [
+ State {
+ name: "hovered"
+ when: actionIndicator.hover && !actionIndicator.pressed
+ && (!myControl || (!myControl.edit && !myControl.drag))
+ && actionIndicator.enabled
+ PropertyChanges {
+ target: actionIndicatorIcon
+ scale: 1.2
+ }
+ },
+ State {
+ name: "disabled"
+ when: !actionIndicator.enabled
+ PropertyChanges {
+ target: actionIndicatorIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+ }
+
+ MouseArea {
+ id: actionIndicatorMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onContainsMouseChanged: actionIndicator.hover = containsMouse
+ onClicked: actionIndicator.clicked()
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !actionIndicator.hover
+ && !actionIndicator.pressed && !myControl.hover
+ && !myControl.edit && !myControl.drag && actionIndicator.showBackground
+ PropertyChanges {
+ target: actionIndicator
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "globalHover"
+ when: myControl.hover && !actionIndicator.hover
+ && !actionIndicator.pressed && !myControl.edit
+ && !myControl.drag && actionIndicator.showBackground
+ PropertyChanges {
+ target: actionIndicator
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: myControl.edit && actionIndicator.showBackground
+ PropertyChanges {
+ target: actionIndicator
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag && actionIndicator.showBackground
+ PropertyChanges {
+ target: actionIndicator
+ color: StudioTheme.Values.themeFocusDrag
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled && actionIndicator.showBackground
+ PropertyChanges {
+ target: actionIndicator
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/Button.qml b/src/imports/StudioControls/Button.qml
new file mode 100644
index 0000000..42d7b3e
--- /dev/null
+++ b/src/imports/StudioControls/Button.qml
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+ButtonRow {
+ id: myButtonRow
+
+ property alias buttonIcon: myAbstractButton.buttonIcon
+ property alias iconColor: myAbstractButton.iconColor
+ property alias checkable: myAbstractButton.checkable
+ property alias checked: myAbstractButton.checked
+
+ signal onCheckedChanged()
+
+ AbstractButton {
+ id: myAbstractButton
+ onCheckedChanged: myButtonRow.onCheckedChanged()
+ }
+}
diff --git a/src/imports/StudioControls/ButtonGroup.qml b/src/imports/StudioControls/ButtonGroup.qml
new file mode 100644
index 0000000..1b233c5
--- /dev/null
+++ b/src/imports/StudioControls/ButtonGroup.qml
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+
+T.ButtonGroup {
+
+}
diff --git a/src/imports/StudioControls/ButtonRow.qml b/src/imports/StudioControls/ButtonRow.qml
new file mode 100644
index 0000000..059c38a
--- /dev/null
+++ b/src/imports/StudioControls/ButtonRow.qml
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Row {
+ // TODO When using Item as root it won't react to outer layout
+ id: myButtonGroup
+
+ property alias actionIndicator: actionIndicator
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: myButtonGroup // TODO global hover issue. Can be solved with extra property in ActionIndicator
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ spacing: -StudioTheme.Values.border // TODO Which one is better? Spacing vs. layout function. ALso depends on root item
+}
diff --git a/src/imports/StudioControls/CheckBox.qml b/src/imports/StudioControls/CheckBox.qml
new file mode 100644
index 0000000..5ec29bb
--- /dev/null
+++ b/src/imports/StudioControls/CheckBox.qml
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.CheckBox {
+ id: myCheckBox
+
+ property alias actionIndicator: actionIndicator
+
+ property bool hover: myCheckBox.hovered
+ property bool edit: false
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ property alias labelVisible: checkBoxLabel.visible
+ property alias labelColor: checkBoxLabel.color
+
+ font.pixelSize: StudioTheme.Values.myFontSize
+
+ implicitWidth: Math.max(
+ implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding
+ + implicitIndicatorWidth + spacing + actionIndicator.width)
+ implicitHeight: Math.max(
+ implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ implicitIndicatorHeight + topPadding + bottomPadding)
+
+ spacing: StudioTheme.Values.checkBoxSpacing
+ hoverEnabled: true
+ activeFocusOnTab: false
+
+ contentItem: T.Label {
+ id: checkBoxLabel
+ leftPadding: 0
+ rightPadding: 0
+ verticalAlignment: Text.AlignVCenter
+ text: myCheckBox.text
+ font: myCheckBox.font
+ color: StudioTheme.Values.themeTextColor
+ visible: text !== ""
+ }
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: myCheckBox // TODO global hover issue. Can be solved with extra property in ActionIndicator
+
+ x: checkBoxLabel.visible ? checkBoxLabel.contentWidth + myCheckBox.spacing : 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ indicator: Rectangle {
+ id: checkBoxBackground
+ x: actionIndicator.x + actionIndicator.width
+ - (actionIndicator.visible ? StudioTheme.Values.border : 0)
+ y: 0
+ z: 5
+ implicitWidth: StudioTheme.Values.height
+ implicitHeight: StudioTheme.Values.height
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+
+ T.Label {
+ id: checkedIcon
+ x: (parent.width - checkedIcon.width) / 2
+ y: (parent.height - checkedIcon.height) / 2
+ text: StudioTheme.Constants.tickIcon
+ visible: myCheckBox.checkState === Qt.Checked
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.sliderControlSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ }
+
+ T.Label {
+ id: partiallyCheckedIcon
+ x: (parent.width - checkedIcon.width) / 2
+ y: (parent.height - checkedIcon.height) / 2
+ text: StudioTheme.Constants.triState
+ visible: myCheckBox.checkState === Qt.PartiallyChecked
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.sliderControlSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myCheckBox.enabled && !myCheckBox.hovered
+ && !myCheckBox.pressed
+ PropertyChanges {
+ target: checkBoxBackground
+ color: StudioTheme.Values.themeControlBackground
+ }
+ },
+ State {
+ name: "hovered"
+ when: myCheckBox.hovered && !myCheckBox.pressed
+ && !actionIndicator.hover
+ PropertyChanges {
+ target: checkBoxBackground
+ color: StudioTheme.Values.themeHoverHighlight
+ }
+ },
+ State {
+ name: "pressed"
+ when: myCheckBox.hovered && myCheckBox.pressed
+ PropertyChanges {
+ target: checkBoxBackground
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myCheckBox.enabled
+ PropertyChanges {
+ target: checkBoxBackground
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: checkedIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ PropertyChanges {
+ target: partiallyCheckedIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ PropertyChanges {
+ target: checkBoxLabel
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/CheckIndicator.qml b/src/imports/StudioControls/CheckIndicator.qml
new file mode 100644
index 0000000..4c314b9
--- /dev/null
+++ b/src/imports/StudioControls/CheckIndicator.qml
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Rectangle {
+ id: checkIndicator
+
+ property T.Control myControl
+ property T.Popup myPopup
+
+ property bool hover: false
+ property bool checked: false
+
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ state: "default"
+
+ Connections {
+ target: myPopup
+ onClosed: checkIndicator.checked = false
+ onOpened: checkIndicator.checked = true
+ }
+
+ MouseArea {
+ id: checkIndicatorMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onContainsMouseChanged: checkIndicator.hover = checkIndicatorMouseArea.containsMouse
+ onPressed: {
+ myControl.forceActiveFocus() // TODO
+ myPopup.opened ? myPopup.close() : myPopup.open()
+ }
+ }
+
+ T.Label {
+ id: checkIndicatorIcon
+ anchors.fill: parent
+ color: StudioTheme.Values.themeTextColor
+ text: StudioTheme.Constants.upDownSquare2
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: StudioTheme.Values.sliderControlSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !(checkIndicator.hover
+ || myControl.hover)
+ && !checkIndicator.checked && !myControl.edit
+ && !myControl.drag
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "hovered"
+ when: (checkIndicator.hover || myControl.hover)
+ && !checkIndicator.checked && !myControl.edit
+ && !myControl.drag
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "checked"
+ when: checkIndicator.checked
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "edit"
+ when: myControl.edit && !checkIndicator.checked
+ && !(checkIndicator.hover && myControl.hover)
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag && !checkIndicator.checked
+ && !(checkIndicator.hover && myControl.hover)
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeFocusDrag
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: checkIndicator
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: checkIndicatorIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/ComboBox.qml b/src/imports/StudioControls/ComboBox.qml
new file mode 100644
index 0000000..1b693be
--- /dev/null
+++ b/src/imports/StudioControls/ComboBox.qml
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.ComboBox {
+ id: myComboBox
+
+ property alias actionIndicator: actionIndicator
+ property alias labelColor: comboBoxInput.color
+
+ property bool hover: false // This property is used to indicate the global hover state
+ property bool edit: myComboBox.activeFocus
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ property string __lastAcceptedText: ""
+ signal compressedActivated
+
+ width: StudioTheme.Values.squareComponentWidth * 5
+ height: StudioTheme.Values.height
+
+ leftPadding: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ rightPadding: popupIndicator.width - StudioTheme.Values.border
+ font.pixelSize: StudioTheme.Values.myFontSize
+ wheelEnabled: false
+
+ onFocusChanged: {
+ if (!myComboBox.focus)
+ comboBoxPopup.close()
+ }
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: myComboBox
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ contentItem: ComboBoxInput {
+ id: comboBoxInput
+ myControl: myComboBox
+ text: myComboBox.editText
+ }
+
+ indicator: CheckIndicator {
+ id: popupIndicator
+ myControl: myComboBox
+ myPopup: myComboBox.popup
+ x: comboBoxInput.x + comboBoxInput.width - StudioTheme.Values.border
+ y: 0
+ width: StudioTheme.Values.squareComponentWidth
+ height: StudioTheme.Values.height
+ }
+
+ background: Rectangle {
+ id: comboBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ width: myComboBox.width - actionIndicator.width
+ height: myComboBox.height
+ }
+
+ // Set the initial value for __lastAcceptedText
+ Component.onCompleted: __lastAcceptedText = myComboBox.editText
+
+ onAccepted: {
+ if (myComboBox.editText != __lastAcceptedText) {
+ var pos = find(myComboBox.editText)
+ activated(pos)
+ }
+ __lastAcceptedText = myComboBox.editText
+ }
+
+ Timer {
+ id: myTimer
+ repeat: false
+ running: false
+ interval: 100
+ onTriggered: myComboBox.compressedActivated()
+ }
+
+ onActivated: myTimer.restart()
+
+ delegate: ItemDelegate {
+ id: myItemDelegate
+
+ width: comboBoxPopup.width - comboBoxPopup.leftPadding - comboBoxPopup.rightPadding
+ - (comboBoxPopupScrollBar.visible ? comboBoxPopupScrollBar.contentItem.implicitWidth
+ + 2 : 0) // TODO Magic number
+ height: StudioTheme.Values.height - 2 * StudioTheme.Values.border
+ padding: 0
+
+ contentItem: Text {
+ leftPadding: itemDelegateIconArea.width
+ text: modelData
+ color: StudioTheme.Values.themeTextColor
+ font: myComboBox.font
+ elide: Text.ElideRight
+ verticalAlignment: Text.AlignVCenter
+ }
+
+ Item {
+ id: itemDelegateIconArea
+ width: myItemDelegate.height
+ height: myItemDelegate.height
+
+ T.Label {
+ id: itemDelegateIcon
+ text: StudioTheme.Constants.tickIcon
+ color: myItemDelegate.highlighted ? StudioTheme.Values.themeTextColor : StudioTheme.Values.themeInteraction
+ font.family: StudioTheme.Constants.iconFont.family
+ font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
+ visible: myComboBox.currentIndex === index ? true : false
+ anchors.fill: parent
+ renderType: Text.NativeRendering
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
+ highlighted: myComboBox.highlightedIndex === index
+
+ background: Rectangle {
+ id: itemDelegateBackground
+ x: 0
+ y: 0
+ width: myItemDelegate.width
+ height: myItemDelegate.height
+ color: myItemDelegate.highlighted ? StudioTheme.Values.themeInteraction : "transparent"
+ }
+ }
+
+ popup: T.Popup {
+ id: comboBoxPopup
+ x: comboBoxInput.x
+ y: myComboBox.height - StudioTheme.Values.border
+ width: comboBoxInput.width + popupIndicator.width - StudioTheme.Values.border
+ // TODO Setting the height on the popup solved the problem with the popup of height 0,
+ // but it has the problem that it sometimes extend over the border of the actual window
+ // and is then cut off.
+ height: Math.min(contentItem.implicitHeight + comboBoxPopup.topPadding
+ + comboBoxPopup.bottomPadding,
+ myComboBox.Window.height - topMargin - bottomMargin,
+ StudioTheme.Values.maxComboBoxPopupHeight)
+ padding: StudioTheme.Values.border
+ margins: 0 // If not defined margin will be -1
+ closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
+
+ contentItem: ListView {
+ clip: true
+ implicitHeight: contentHeight
+ model: myComboBox.popup.visible ? myComboBox.delegateModel : null
+ currentIndex: myComboBox.highlightedIndex
+ boundsBehavior: Flickable.StopAtBounds
+ ScrollBar.vertical: ControlScrollBar {
+ id: comboBoxPopupScrollBar
+ }
+ }
+
+ background: Rectangle {
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeInteraction
+ border.width: StudioTheme.Values.border
+ }
+
+ enter: Transition {
+ }
+ exit: Transition {
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: !myComboBox.hover && !myComboBox.edit
+ PropertyChanges {
+ target: myComboBox
+ wheelEnabled: false
+ }
+ PropertyChanges {
+ target: comboBoxInput
+ selectByMouse: false
+ }
+ PropertyChanges {
+ target: comboBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "focus"
+ when: myComboBox.edit && !myComboBox.editable
+ PropertyChanges {
+ target: myComboBox
+ wheelEnabled: true
+ }
+ PropertyChanges {
+ target: comboBoxInput
+ focus: true
+ }
+ },
+ State {
+ name: "edit"
+ when: myComboBox.edit && myComboBox.editable
+ PropertyChanges {
+ target: myComboBox
+ wheelEnabled: true
+ }
+ PropertyChanges {
+ target: comboBoxInput
+ selectByMouse: true
+ }
+ PropertyChanges {
+ target: comboBoxBackground
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ }
+ ]
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Escape)
+ myComboBox.focus = false
+ }
+}
diff --git a/src/imports/StudioControls/ComboBoxInput.qml b/src/imports/StudioControls/ComboBoxInput.qml
new file mode 100644
index 0000000..3485316
--- /dev/null
+++ b/src/imports/StudioControls/ComboBoxInput.qml
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+TextInput {
+ id: textInput
+
+ property T.Control myControl
+
+ property bool edit: textInput.activeFocus
+ property bool drag: false
+
+ z: 2
+ font: myControl.font
+ color: StudioTheme.Values.themeTextColor
+ selectionColor: StudioTheme.Values.themeTextSelectionColor
+ selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
+
+ horizontalAlignment: Qt.AlignLeft
+ verticalAlignment: Qt.AlignVCenter
+ leftPadding: StudioTheme.Values.inputHorizontalPadding
+ rightPadding: StudioTheme.Values.inputHorizontalPadding
+
+ readOnly: !myControl.editable
+ validator: myControl.validator
+ inputMethodHints: myControl.inputMethodHints
+ selectByMouse: false
+ activeFocusOnPress: false
+ clip: true
+
+ Rectangle {
+ id: textInputArea
+ x: 0
+ y: 0
+ z: -1
+ width: textInput.width
+ height: StudioTheme.Values.height
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ }
+
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse
+ enabled: true
+ onTapped: {
+ if (textInput.readOnly) {
+ if (myControl.popup.opened) {
+ myControl.popup.close()
+ } else {
+ myControl.forceActiveFocus()
+ myControl.popup.open()
+ }
+ } else {
+ textInput.forceActiveFocus()
+ }
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ enabled: true
+ hoverEnabled: true
+ propagateComposedEvents: true
+ acceptedButtons: Qt.LeftButton
+ cursorShape: Qt.PointingHandCursor
+ // Sets the global hover
+ onContainsMouseChanged: myControl.hover = containsMouse
+ onPressed: mouse.accepted = false
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !textInput.edit
+ && !mouseArea.containsMouse && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ PropertyChanges {
+ target: tapHandler
+ enabled: true
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.PointingHandCursor
+ }
+ },
+ State {
+ name: "hovered"
+ when: myControl.hover && !textInput.edit && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "focus"
+ when: textInput.edit && !myControl.editable
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "edit"
+ when: textInput.edit && myControl.editable
+ extend: "focus"
+ PropertyChanges {
+ target: tapHandler
+ enabled: false
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.IBeamCursor
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: textInput
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/ContextMenu.qml b/src/imports/StudioControls/ContextMenu.qml
new file mode 100644
index 0000000..9d76855
--- /dev/null
+++ b/src/imports/StudioControls/ContextMenu.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+
+Menu {
+ id: contextMenu
+
+ property Item myTextEdit
+
+ MenuItem {
+ text: "Undo"
+ enabled: myTextEdit.canUndo
+ onTriggered: myTextEdit.undo()
+ /* shortcut: StandardKey.Undo Shortcuts in QQC2 seem to override global shortcuts */
+ }
+ MenuItem {
+ text: "Redo"
+ enabled: myTextEdit.canRedo
+ onTriggered: myTextEdit.redo()
+ /* shortcut: StandardKey.Redo Shortcuts in QQC2 seem to override global shortcuts */
+ }
+
+ MenuSeparator {
+ }
+
+ MenuItem {
+ text: "Copy"
+ enabled: myTextEdit.selectedText !== ""
+ onTriggered: myTextEdit.copy()
+ /* shortcut: StandardKey.Copy Shortcuts in QQC2 seem to override global shortcuts */
+ }
+ MenuItem {
+ text: "Cut"
+ enabled: myTextEdit.selectedText !== "" && !myTextEdit.readOnly
+ onTriggered: myTextEdit.cut()
+ /* shortcut: StandardKey.Cut Shortcuts in QQC2 seem to override global shortcuts */
+ }
+ MenuItem {
+ text: "Paste"
+ enabled: myTextEdit.canPaste
+ onTriggered: myTextEdit.paste()
+ /* shortcut: StandardKey.Paste Shortcuts in QQC2 seem to override global shortcuts */
+ }
+ MenuItem {
+ text: "Delete"
+ enabled: myTextEdit.selectedText !== ""
+ onTriggered: myTextEdit.remove(myTextEdit.selectionStart,
+ myTextEdit.selectionEnd)
+ /* shortcut: StandardKey.Delete Shortcuts in QQC2 seem to override global shortcuts */
+ }
+ MenuItem {
+ text: "Clear"
+ enabled: myTextEdit.text !== ""
+ onTriggered: myTextEdit.clear()
+ /* shortcut: StandardKey.DeleteCompleteLine Shortcuts in QQC2 seem to override global shortcuts */
+ }
+
+ MenuSeparator {
+ }
+
+ MenuItem {
+ text: "Select All"
+ enabled: myTextEdit.text !== ""
+ && myTextEdit.selectedText !== myTextEdit.text
+ onTriggered: myTextEdit.selectAll()
+ /* shortcut: StandardKey.SelectAll Shortcuts in QQC2 seem to override global shortcuts */
+ }
+}
diff --git a/src/imports/StudioControls/ControlScrollBar.qml b/src/imports/StudioControls/ControlScrollBar.qml
new file mode 100644
index 0000000..886e922
--- /dev/null
+++ b/src/imports/StudioControls/ControlScrollBar.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.ScrollBar {
+ id: control
+
+ // This needs to be set, when using T.ScrollBar
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+
+ active: true
+ interactive: true
+ visible: control.size < 1.0 || T.ScrollBar.AlwaysOn
+
+ snapMode: T.ScrollBar.SnapAlways // TODO
+ policy: T.ScrollBar.AsNeeded
+
+ padding: 1 // TODO 0
+ size: 1.0
+ position: 1.0
+ //orientation: Qt.Vertical
+
+ contentItem: Rectangle {
+ id: controlHandle
+ implicitWidth: 4
+ implicitHeight: 4
+ radius: width / 2 // TODO 0
+ color: StudioTheme.Values.themeScrollBarHandle
+ }
+
+ background: Rectangle {
+ id: controlTrack
+ color: StudioTheme.Values.themeScrollBarTrack
+ }
+}
diff --git a/src/imports/StudioControls/ExpandingSpacer.qml b/src/imports/StudioControls/ExpandingSpacer.qml
new file mode 100644
index 0000000..9e48128
--- /dev/null
+++ b/src/imports/StudioControls/ExpandingSpacer.qml
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+
+Item {
+ Layout.fillWidth: true
+}
diff --git a/src/imports/StudioControls/ItemDelegate.qml b/src/imports/StudioControls/ItemDelegate.qml
new file mode 100644
index 0000000..c2190c5
--- /dev/null
+++ b/src/imports/StudioControls/ItemDelegate.qml
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+
+T.ItemDelegate {
+
+}
diff --git a/src/imports/StudioControls/Menu.qml b/src/imports/StudioControls/Menu.qml
new file mode 100644
index 0000000..01a8684
--- /dev/null
+++ b/src/imports/StudioControls/Menu.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.Menu {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ contentHeight + topPadding + bottomPadding)
+
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myFontSize
+
+ margins: 0
+ overlap: 1
+ padding: 0
+
+ closePolicy: T.Popup.CloseOnPressOutside | T.Popup.CloseOnPressOutsideParent | T.Popup.CloseOnEscape
+
+ delegate: MenuItem {
+ }
+
+ contentItem: ListView {
+ model: control.contentModel
+ interactive: Window.window ? contentHeight > Window.window.height : false
+ clip: false
+ currentIndex: control.currentIndex
+ }
+
+ background: Rectangle {
+ implicitWidth: contentItem.childrenRect.width
+ implicitHeight: contentItem.childrenRect.height
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ }
+}
diff --git a/src/imports/StudioControls/MenuItem.qml b/src/imports/StudioControls/MenuItem.qml
new file mode 100644
index 0000000..023f9b0
--- /dev/null
+++ b/src/imports/StudioControls/MenuItem.qml
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+import QtQuick.Controls 2.12
+
+T.MenuItem {
+ id: control
+
+ property int labelSpacing: StudioTheme.Values.contextMenuLabelSpacing
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(
+ implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding,
+ implicitIndicatorHeight + topPadding + bottomPadding)
+
+ padding: 0
+ spacing: 0
+ horizontalPadding: StudioTheme.Values.contextMenuHorizontalPadding
+ action: Action {}
+
+ contentItem: Item {
+ Text {
+ id: textLabel
+ text: control.text
+ font: control.font
+ color: control.enabled ? StudioTheme.Values.themeTextColor : StudioTheme.Values.themeTextColorDisabled
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ Text {
+ id: shortcutLabel
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ text: shortcut.nativeText
+ font: control.font
+ color: textLabel.color
+
+ Shortcut {
+ id: shortcut
+ property int shortcutWorkaround: control.action.shortcut ? control.action.shortcut : 0
+ sequence: shortcutWorkaround
+ }
+ }
+ }
+
+ background: Rectangle {
+ implicitWidth: textLabel.implicitWidth + control.labelSpacing + shortcutLabel.implicitWidth
+ + control.leftPadding + control.rightPadding
+ implicitHeight: StudioTheme.Values.height
+ x: StudioTheme.Values.border
+ y: StudioTheme.Values.border
+ width: control.menu.width - (StudioTheme.Values.border * 2)
+ height: control.height - (StudioTheme.Values.border * 2)
+ color: control.down ? control.palette.midlight : control.highlighted ? StudioTheme.Values.themeInteraction : "transparent"
+ }
+}
diff --git a/src/imports/StudioControls/MenuSeparator.qml b/src/imports/StudioControls/MenuSeparator.qml
new file mode 100644
index 0000000..a2f2f57
--- /dev/null
+++ b/src/imports/StudioControls/MenuSeparator.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.MenuSeparator {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+
+ padding: 0
+
+ contentItem: Rectangle {
+ width: control.parent.width
+ height: StudioTheme.Values.border
+ color: StudioTheme.Values.themeControlOutline
+ }
+}
diff --git a/src/imports/StudioControls/RealSliderPopup.qml b/src/imports/StudioControls/RealSliderPopup.qml
new file mode 100644
index 0000000..d260940
--- /dev/null
+++ b/src/imports/StudioControls/RealSliderPopup.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.Popup {
+ id: sliderPopup
+
+ property T.Control myControl
+
+ dim: false
+ closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
+
+ background: Rectangle {
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeInteraction
+ }
+
+ contentItem: T.Slider {
+ id: slider
+ anchors.fill: parent
+
+ bottomPadding: 0
+ topPadding: 0
+ rightPadding: 3
+ leftPadding: 3
+
+ from: myControl.realFrom
+ value: myControl.realValue
+ to: myControl.realTo
+
+ focusPolicy: Qt.NoFocus
+
+ handle: Rectangle {
+ x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
+ y: slider.topPadding + (slider.availableHeight / 2) - (height / 2)
+ width: StudioTheme.Values.sliderHandleWidth
+ height: StudioTheme.Values.sliderHandleHeight
+ radius: 0
+ color: slider.pressed ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeControlOutline
+ }
+
+ background: Rectangle {
+ x: slider.leftPadding
+ y: slider.topPadding + (slider.availableHeight / 2) - (height / 2)
+ width: slider.availableWidth
+ height: StudioTheme.Values.sliderTrackHeight
+ radius: 0
+ color: StudioTheme.Values.themeSliderInactiveTrack
+
+ Rectangle {
+ width: slider.visualPosition * parent.width
+ height: parent.height
+ color: StudioTheme.Values.themeSliderActiveTrack
+ radius: 0
+ }
+ }
+
+ onMoved: {
+ var currValue = myControl.value
+ myControl.realValue = slider.value
+
+ if (currValue !== myControl.realValue)
+ myControl.realValueModified()
+ }
+ }
+}
diff --git a/src/imports/StudioControls/RealSpinBox.qml b/src/imports/StudioControls/RealSpinBox.qml
new file mode 100644
index 0000000..d1d738e
--- /dev/null
+++ b/src/imports/StudioControls/RealSpinBox.qml
@@ -0,0 +1,354 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.SpinBox {
+ id: mySpinBox
+
+ property real realFrom: 0.0
+ property real realTo: 99.0
+ property real realValue: 1.0
+ property real realStepSize: 1.0
+
+ property alias labelColor: spinBoxInput.color
+ property alias actionIndicator: actionIndicator
+
+ property int decimals: 0
+
+ property real minStepSize: {
+ var tmpMinStepSize = Number((mySpinBox.realStepSize * 0.1).toFixed(mySpinBox.decimals))
+ return (tmpMinStepSize) ? tmpMinStepSize : mySpinBox.realStepSize
+ }
+ property real maxStepSize: {
+ var tmpMaxStepSize = Number((mySpinBox.realStepSize * 10.0).toFixed(mySpinBox.decimals))
+ return (tmpMaxStepSize < mySpinBox.realTo) ? tmpMaxStepSize : mySpinBox.realStepSize
+ }
+
+ property bool edit: spinBoxInput.activeFocus
+ property bool hover: false // This property is used to indicate the global hover state
+ property bool drag: false
+
+ property real realDragRange: realTo - realFrom
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ property bool spinBoxIndicatorVisible: true
+ property real __spinBoxIndicatorWidth: StudioTheme.Values.smallRectWidth - 2
+ * StudioTheme.Values.border
+ property real __spinBoxIndicatorHeight: StudioTheme.Values.height / 2
+ - StudioTheme.Values.border
+
+ property alias sliderIndicatorVisible: sliderIndicator.visible
+ property real __sliderIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __sliderIndicatorHeight: StudioTheme.Values.height
+
+ signal realValueModified
+ signal compressedRealValueModified
+ signal dragStarted
+ signal dragEnded
+
+ // Use custom wheel handling due to bugs
+ property bool __wheelEnabled: false
+ wheelEnabled: false
+
+ width: StudioTheme.Values.squareComponentWidth * 5
+ height: StudioTheme.Values.height
+
+ leftPadding: spinBoxIndicatorDown.x + spinBoxIndicatorDown.width
+ - (spinBoxIndicatorVisible ? 0 : StudioTheme.Values.border)
+ rightPadding: sliderIndicator.width - (sliderIndicatorVisible ? StudioTheme.Values.border : 0)
+
+ font.pixelSize: StudioTheme.Values.myFontSize
+ editable: true
+
+ // Leave this in for now
+ from: -99
+ value: 0
+ to: 99
+
+ validator: DoubleValidator {
+ id: doubleValidator
+ locale: mySpinBox.locale.name
+ notation: DoubleValidator.StandardNotation
+ decimals: mySpinBox.decimals
+ bottom: Math.min(mySpinBox.realFrom, mySpinBox.realTo)
+ top: Math.max(mySpinBox.realFrom, mySpinBox.realTo)
+ }
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: mySpinBox
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ up.indicator: RealSpinBoxIndicator {
+ id: spinBoxIndicatorUp
+ myControl: mySpinBox
+ iconFlip: -1
+ visible: spinBoxIndicatorVisible
+ onRealReleased: mySpinBox.realIncrease()
+ onRealPressAndHold: mySpinBox.realIncrease()
+ x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
+ y: StudioTheme.Values.border
+ width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
+ height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
+
+ realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue < mySpinBox.realTo) : (mySpinBox.realValue > mySpinBox.realTo)
+ }
+
+ down.indicator: RealSpinBoxIndicator {
+ id: spinBoxIndicatorDown
+ myControl: mySpinBox
+ visible: spinBoxIndicatorVisible
+ onRealReleased: mySpinBox.realDecrease()
+ onRealPressAndHold: mySpinBox.realDecrease()
+ x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
+ y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height
+ width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
+ height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
+
+ realEnabled: (mySpinBox.realFrom < mySpinBox.realTo) ? (mySpinBox.realValue > mySpinBox.realFrom) : (mySpinBox.realValue < mySpinBox.realFrom)
+ }
+
+ contentItem: RealSpinBoxInput {
+ id: spinBoxInput
+ myControl: mySpinBox
+ validator: doubleValidator
+ }
+
+ background: Rectangle {
+ id: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ width: mySpinBox.width - actionIndicator.width
+ height: mySpinBox.height
+ }
+
+ CheckIndicator {
+ id: sliderIndicator
+ myControl: mySpinBox
+ myPopup: sliderPopup
+ x: spinBoxInput.x + spinBoxInput.width - StudioTheme.Values.border
+ width: sliderIndicator.visible ? __sliderIndicatorWidth : 0
+ height: sliderIndicator.visible ? __sliderIndicatorHeight : 0
+ visible: false // reasonable default
+ }
+
+ RealSliderPopup {
+ id: sliderPopup
+ myControl: mySpinBox
+ x: spinBoxInput.x
+ y: StudioTheme.Values.height - StudioTheme.Values.border
+ width: spinBoxInput.width + sliderIndicator.width - StudioTheme.Values.border
+ height: StudioTheme.Values.sliderHeight
+
+ enter: Transition {
+ }
+ exit: Transition {
+ }
+ }
+
+ textFromValue: function (value, locale) {
+ return Number(mySpinBox.realValue).toLocaleString(locale, 'f', mySpinBox.decimals)
+ }
+
+ valueFromText: function (text, locale) {
+ mySpinBox.setRealValue(Number.fromLocaleString(locale, spinBoxInput.text))
+ return 0
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: mySpinBox.enabled && !mySpinBox.hover
+ && !mySpinBox.edit && !mySpinBox.drag
+ PropertyChanges {
+ target: mySpinBox
+ __wheelEnabled: false
+ }
+ PropertyChanges {
+ target: spinBoxInput
+ selectByMouse: false
+ }
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: mySpinBox.edit
+ PropertyChanges {
+ target: mySpinBox
+ __wheelEnabled: true
+ }
+ PropertyChanges {
+ target: spinBoxInput
+ selectByMouse: true
+ }
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "drag"
+ when: mySpinBox.drag
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !mySpinBox.enabled
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutlineDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ }
+ ]
+
+ Timer {
+ id: myTimer
+ repeat: false
+ running: false
+ interval: 200
+ onTriggered: mySpinBox.compressedRealValueModified()
+ }
+
+ onRealValueChanged: {
+ spinBoxInput.text = mySpinBox.textFromValue(mySpinBox.realValue, mySpinBox.locale)
+ mySpinBox.value = 0 // Without setting value back to 0, it can happen that one of
+ // the indicator will be disabled due to range logic.
+ }
+ onRealValueModified: myTimer.restart()
+ onFocusChanged: mySpinBox.setValueFromInput()
+ onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText
+ onActiveFocusChanged: {
+ if (mySpinBox.activeFocus)
+ // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
+ spinBoxInput.selectAll()
+
+ if (sliderPopup.opened && !mySpinBox.activeFocus)
+ sliderPopup.close()
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
+ event.accepted = true
+
+ // Store current step size
+ var currStepSize = mySpinBox.realStepSize
+
+ // Set realStepSize according to used modifier key
+ if (event.modifiers & Qt.ControlModifier)
+ mySpinBox.realStepSize = mySpinBox.minStepSize
+
+ if (event.modifiers & Qt.ShiftModifier)
+ mySpinBox.realStepSize = mySpinBox.maxStepSize
+
+ if (event.key === Qt.Key_Up)
+ mySpinBox.realIncrease()
+ else
+ mySpinBox.realDecrease()
+
+ // Reset realStepSize
+ mySpinBox.realStepSize = currStepSize
+ }
+
+ if (event.key === Qt.Key_Escape)
+ mySpinBox.focus = false
+
+ // FIX: This is a temporary fix for QTBUG-74239
+ if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
+ mySpinBox.setValueFromInput()
+ }
+
+ function clamp(v, lo, hi) {
+ return (v < lo || v > hi) ? Math.min(Math.max(lo, v), hi) : v
+ }
+
+ function setValueFromInput() {
+ // FIX: This is a temporary fix for QTBUG-74239
+ var currValue = mySpinBox.realValue
+
+ // Call the function but don't use return value. The realValue property
+ // will be implicitly set inside the function/procedure.
+ mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale)
+
+ if (mySpinBox.realValue !== currValue) {
+ mySpinBox.realValueModified()
+ } else {
+ // Check if input text differs in format from the current value
+ var tmpInputValue = mySpinBox.textFromValue(mySpinBox.realValue, mySpinBox.locale)
+
+ if (tmpInputValue !== spinBoxInput.text)
+ spinBoxInput.text = tmpInputValue
+ }
+ }
+
+ function setRealValue(value) {
+ mySpinBox.realValue = clamp(value,
+ mySpinBox.validator.bottom,
+ mySpinBox.validator.top)
+ }
+
+ function realDecrease() {
+ // Store the current value for comparison
+ var currValue = mySpinBox.realValue
+ mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale)
+
+ setRealValue(mySpinBox.realValue - realStepSize)
+
+ if (mySpinBox.realValue !== currValue)
+ mySpinBox.realValueModified()
+ }
+
+ function realIncrease() {
+ // Store the current value for comparison
+ var currValue = mySpinBox.realValue
+ mySpinBox.valueFromText(spinBoxInput.text, mySpinBox.locale)
+
+ setRealValue(mySpinBox.realValue + realStepSize)
+
+ if (mySpinBox.realValue !== currValue)
+ mySpinBox.realValueModified()
+ }
+}
diff --git a/src/imports/StudioControls/RealSpinBoxIndicator.qml b/src/imports/StudioControls/RealSpinBoxIndicator.qml
new file mode 100644
index 0000000..7cebe1c
--- /dev/null
+++ b/src/imports/StudioControls/RealSpinBoxIndicator.qml
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Rectangle {
+ id: spinBoxIndicator
+
+ property T.Control myControl
+
+ property bool hover: false
+ property bool pressed: false
+ property bool released: false
+ property bool realEnabled: true
+
+ signal realPressed
+ signal realPressAndHold
+ signal realReleased
+
+ property alias iconFlip: spinBoxIndicatorIconScale.yScale
+
+ color: StudioTheme.Values.themeControlBackground
+ border.width: 0
+
+ onEnabledChanged: invalidateEnabled()
+ onRealEnabledChanged: {
+ invalidateEnabled()
+ if (spinBoxIndicator.realEnabled === false)
+ pressAndHoldTimer.stop()
+ }
+
+ // This function is meant to synchronize enabled with realEnabled to avoid
+ // the internal logic messing with the actual state.
+ function invalidateEnabled() {
+ spinBoxIndicator.enabled = spinBoxIndicator.realEnabled
+ }
+
+ Timer {
+ id: pressAndHoldTimer
+ repeat: true
+ running: false
+ interval: 100
+ onTriggered: spinBoxIndicator.realPressAndHold()
+ }
+
+ // This MouseArea is a workaround to avoid some hover state related bugs
+ // when using the actual signal 'up.hovered'. QTBUG-74688
+ MouseArea {
+ id: spinBoxIndicatorMouseArea
+
+ property bool pressedAndHeld: false
+
+ anchors.fill: parent
+ // Shift the MouseArea down by 1 pixel due to potentially overlapping areas
+ anchors.topMargin: iconFlip < 0 ? 0 : 1
+ anchors.bottomMargin: iconFlip < 0 ? 1 : 0
+ hoverEnabled: true
+ pressAndHoldInterval: 500
+ onContainsMouseChanged: spinBoxIndicator.hover = containsMouse
+ onContainsPressChanged: spinBoxIndicator.pressed = containsPress
+ onPressed: {
+ myControl.forceActiveFocus()
+ spinBoxIndicator.realPressed()
+ mouse.accepted = true
+ }
+ onPressAndHold: {
+ pressAndHoldTimer.restart()
+ pressedAndHeld = true
+ }
+ onReleased: {
+ // Only trigger real released when pressAndHold isn't active
+ if (!pressAndHoldTimer.running && containsMouse)
+ spinBoxIndicator.realReleased()
+ pressAndHoldTimer.stop()
+ mouse.accepted = true
+ pressedAndHeld = false
+ }
+ onEntered: {
+ if (pressedAndHeld)
+ pressAndHoldTimer.restart()
+ }
+ onExited: {
+ if (pressAndHoldTimer.running)
+ pressAndHoldTimer.stop()
+ }
+ }
+
+ T.Label {
+ id: spinBoxIndicatorIcon
+ text: StudioTheme.Constants.upDownSquare2
+ color: StudioTheme.Values.themeTextColor
+ renderType: Text.NativeRendering
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ anchors.fill: parent
+ transform: Scale {
+ id: spinBoxIndicatorIconScale
+ origin.x: 0
+ origin.y: spinBoxIndicatorIcon.height / 2
+ yScale: 1
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicatorIcon
+ color: StudioTheme.Values.themeTextColor
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled || !spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicatorIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !(spinBoxIndicator.hover
+ || myControl.hover)
+ && !spinBoxIndicator.pressed && !myControl.edit
+ && !myControl.drag
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeControlBackground
+ }
+ },
+ State {
+ name: "hovered"
+ when: (spinBoxIndicator.hover || myControl.hover)
+ && !spinBoxIndicator.pressed && !myControl.edit
+ && !myControl.drag
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeHoverHighlight
+ }
+ },
+ State {
+ name: "pressed"
+ when: spinBoxIndicator.pressed
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "edit"
+ when: myControl.edit
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeFocusEdit
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeFocusDrag
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/RealSpinBoxInput.qml b/src/imports/StudioControls/RealSpinBoxInput.qml
new file mode 100644
index 0000000..7de0eb7
--- /dev/null
+++ b/src/imports/StudioControls/RealSpinBoxInput.qml
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+TextInput {
+ id: textInput
+
+ property T.Control myControl
+
+ property bool edit: textInput.activeFocus
+ property bool drag: false
+
+ z: 2
+ font: myControl.font
+ color: StudioTheme.Values.themeTextColor
+ selectionColor: StudioTheme.Values.themeTextSelectionColor
+ selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
+
+ horizontalAlignment: Qt.AlignRight
+ verticalAlignment: Qt.AlignVCenter
+ leftPadding: StudioTheme.Values.inputHorizontalPadding
+ rightPadding: StudioTheme.Values.inputHorizontalPadding
+
+ readOnly: !myControl.editable
+ validator: myControl.validator
+ inputMethodHints: myControl.inputMethodHints
+ selectByMouse: false
+ activeFocusOnPress: false
+ clip: true
+
+ // TextInput focus needs to be set to activeFocus whenever it changes,
+ // otherwise TextInput will get activeFocus whenever the parent SpinBox gets
+ // activeFocus. This will lead to weird side effects.
+ onActiveFocusChanged: textInput.focus = activeFocus
+
+ Rectangle {
+ id: textInputArea
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ x: 0
+ y: 0
+ z: -1
+ width: textInput.width
+ height: StudioTheme.Values.height
+ }
+
+ DragHandler {
+ id: dragHandler
+ target: null
+ acceptedDevices: PointerDevice.Mouse
+ enabled: true
+
+ property real initialValue: myControl.realValue
+ property real multiplier: 1.0
+
+ onActiveChanged: {
+ if (dragHandler.active) {
+ dragHandler.initialValue = myControl.realValue
+ mouseArea.cursorShape = Qt.ClosedHandCursor // TODO
+ myControl.drag = true
+ myControl.dragStarted()
+ // Force focus on the non visible component to receive key events
+ dragModifierWorkaround.forceActiveFocus()
+ } else {
+ mouseArea.cursorShape = Qt.PointingHandCursor // TODO
+ myControl.drag = false
+ myControl.dragEnded()
+ // Avoid active focus on the component after dragging
+ dragModifierWorkaround.focus = false
+ textInput.focus = false
+ myControl.focus = false
+ }
+ }
+ onTranslationChanged: calcValue()
+ onMultiplierChanged: calcValue()
+
+ function calcValue() {
+ var tmp = myControl.realDragRange / StudioTheme.Values.dragLength
+ var currValue = myControl.realValue
+ myControl.setRealValue(dragHandler.initialValue + (tmp * dragHandler.translation.x * dragHandler.multiplier))
+ if (currValue !== myControl.realValue)
+ myControl.realValueModified()
+ }
+ }
+
+ Item {
+ id: dragModifierWorkaround
+ Keys.onPressed: {
+ event.accepted = true
+
+ if (event.modifiers & Qt.ControlModifier)
+ dragHandler.multiplier = 0.1
+
+ if (event.modifiers & Qt.ShiftModifier)
+ dragHandler.multiplier = 10.0
+ }
+ Keys.onReleased: {
+ event.accepted = true
+ dragHandler.multiplier = 1.0
+ }
+ }
+
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse
+ enabled: true
+ onTapped: {
+ textInput.forceActiveFocus()
+ textInput.deselect() // QTBUG-75862
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+
+ property real stepSize: myControl.realStepSize
+
+ anchors.fill: parent
+ enabled: true
+ hoverEnabled: true
+ propagateComposedEvents: true
+ acceptedButtons: Qt.LeftButton
+ cursorShape: Qt.PointingHandCursor
+ // Sets the global hover
+ onContainsMouseChanged: myControl.hover = containsMouse
+ onPressed: mouse.accepted = false
+ onWheel: {
+ if (!myControl.__wheelEnabled)
+ return
+
+ // Set stepSize according to used modifier key
+ if (wheel.modifiers & Qt.ControlModifier)
+ mouseArea.stepSize = myControl.minStepSize
+
+ if (wheel.modifiers & Qt.ShiftModifier)
+ mouseArea.stepSize = myControl.maxStepSize
+
+ var currValue = myControl.realValue
+ myControl.valueFromText(textInput.text, myControl.locale)
+ myControl.setRealValue(myControl.realValue + (wheel.angleDelta.y / 120.0 * mouseArea.stepSize))
+
+ if (currValue !== myControl.realValue)
+ myControl.realValueModified()
+
+ // Reset stepSize
+ mouseArea.stepSize = myControl.realStepSize
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !textInput.edit
+ && !mouseArea.containsMouse && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ PropertyChanges {
+ target: dragHandler
+ enabled: true
+ }
+ PropertyChanges {
+ target: tapHandler
+ enabled: true
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.PointingHandCursor
+ }
+ },
+ State {
+ name: "hovered"
+ when: myControl.hover && !textInput.edit && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: textInput.edit && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ PropertyChanges {
+ target: dragHandler
+ enabled: false
+ }
+ PropertyChanges {
+ target: tapHandler
+ enabled: false
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.IBeamCursor
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeFocusDrag
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: textInput
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/ScrollBar.qml b/src/imports/StudioControls/ScrollBar.qml
new file mode 100644
index 0000000..f1bb045
--- /dev/null
+++ b/src/imports/StudioControls/ScrollBar.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.ScrollBar {
+ id: control
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitContentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitContentHeight + topPadding + bottomPadding)
+
+ padding: 0
+ size: 1.0
+ position: 1.0
+ active: true
+ interactive: true
+ visible: control.size < 1.0
+
+ snapMode: T.ScrollBar.NoSnap
+ policy: T.ScrollBar.AsNeeded
+
+ contentItem: Rectangle {
+ id: controlHandle
+ implicitWidth: 10
+ implicitHeight: 10
+ radius: 0
+ color: "#595b5c" //StudioTheme.Values.themeScrollBarHandle
+ }
+
+ background: Rectangle {
+ id: controlTrack
+ color: "#191919" //StudioTheme.Values.themeScrollBarTrack
+ }
+}
diff --git a/src/imports/StudioControls/ScrollView.qml b/src/imports/StudioControls/ScrollView.qml
new file mode 100644
index 0000000..f8a1875
--- /dev/null
+++ b/src/imports/StudioControls/ScrollView.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.ScrollView {
+ id: control
+
+ property alias horizontalThickness: horizontalScrollBar.height
+ property alias verticalThickness: verticalScrollBar.width
+ property bool bothVisible: verticalScrollBar.visible
+ && horizontalScrollBar.visible
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ contentHeight + topPadding + bottomPadding)
+
+ anchors.fill: parent
+
+ rightPadding: verticalScrollBar.visible ? verticalThickness : 0
+ bottomPadding: horizontalScrollBar.visible ? horizontalThickness : 0
+
+ ScrollBar.vertical: ScrollBar {
+ id: verticalScrollBar
+ parent: control
+ x: control.width - verticalThickness
+ y: 0
+ height: control.availableHeight
+ active: horizontalScrollBar.active
+ }
+
+ ScrollBar.horizontal: ScrollBar {
+ id: horizontalScrollBar
+ parent: control
+ x: 0
+ y: control.height - horizontalThickness
+ width: control.availableWidth
+ active: verticalScrollBar.active
+ }
+
+ contentItem: Flickable {
+ boundsMovement: Flickable.StopAtBounds
+ boundsBehavior: Flickable.StopAtBounds
+ interactive: false
+ }
+}
diff --git a/src/imports/StudioControls/SecondColumnLayout.qml b/src/imports/StudioControls/SecondColumnLayout.qml
new file mode 100644
index 0000000..d5c917f
--- /dev/null
+++ b/src/imports/StudioControls/SecondColumnLayout.qml
@@ -0,0 +1,32 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+
+RowLayout {
+ Layout.fillWidth: true
+ spacing: 4
+}
diff --git a/src/imports/StudioControls/Section.qml b/src/imports/StudioControls/Section.qml
new file mode 100644
index 0000000..98a163a
--- /dev/null
+++ b/src/imports/StudioControls/Section.qml
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+import StudioTheme 1.0 as StudioTheme
+
+Item {
+ id: section
+ property alias caption: label.text
+ property int leftPadding: 8
+ property int topPadding: 4
+ property int rightPadding: 0
+
+ property int animationDuration: 0
+
+ property bool expanded: true
+
+ clip: true
+
+ Rectangle {
+ id: header
+ height: StudioTheme.Values.height
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ color: StudioTheme.Values.themeControlBackground
+
+ SectionLabel {
+ id: label
+ anchors.verticalCenter: parent.verticalCenter
+ color: StudioTheme.Values.themeTextColor
+ x: 22
+ //font.bold: true
+ font.pixelSize: StudioTheme.Values.myFontSize
+ // TODO font size?
+ }
+
+ SectionLabel {
+ id: arrow
+ width: StudioTheme.Values.spinControlIconSizeMulti
+ height: StudioTheme.Values.spinControlIconSizeMulti
+ text: StudioTheme.Constants.upDownSquare2
+ color: StudioTheme.Values.themeTextColor
+ renderType: Text.NativeRendering
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.verticalCenter: parent.verticalCenter
+ font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ Behavior on rotation {
+ NumberAnimation {
+ easing.type: Easing.OutCubic
+ duration: animationDuration
+ }
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ section.animationDuration = 120
+ section.expanded = !section.expanded
+ if (!section.expanded) // TODO
+ section.forceActiveFocus()
+ }
+ }
+ }
+
+ default property alias __content: row.children
+
+ readonly property alias contentItem: row
+
+ implicitHeight: Math.round(row.height + header.height)
+
+ Row {
+ id: row
+ anchors.left: parent.left
+ anchors.leftMargin: leftPadding
+ anchors.right: parent.right
+ anchors.rightMargin: rightPadding
+ anchors.top: header.bottom
+ anchors.topMargin: topPadding
+ }
+
+ Behavior on implicitHeight {
+ NumberAnimation {
+ easing.type: Easing.OutCubic
+ duration: animationDuration
+ }
+ }
+
+ states: [
+ State {
+ name: "Collapsed"
+ when: !section.expanded
+ PropertyChanges {
+ target: section
+ implicitHeight: header.height
+ }
+ PropertyChanges {
+ target: arrow
+ rotation: -90
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/SectionLabel.qml b/src/imports/StudioControls/SectionLabel.qml
new file mode 100644
index 0000000..73fec21
--- /dev/null
+++ b/src/imports/StudioControls/SectionLabel.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.Label {
+ id: label
+
+ //property alias tooltip: toolTipArea.tooltip
+ // workaround because PictureSpecifics.qml still use this
+ //property alias toolTip: toolTipArea.tooltip
+
+ width: Math.max(Math.min(240, parent.width - 220), 80)
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.myFontSize // TODO
+ elide: Text.ElideRight
+
+ Layout.preferredWidth: width
+ Layout.minimumWidth: width
+ Layout.maximumWidth: width
+/*
+ ToolTipArea {
+ id: toolTipArea
+ anchors.fill: parent
+ tooltip: label.text
+ }
+*/
+}
diff --git a/src/imports/StudioControls/SectionLayout.qml b/src/imports/StudioControls/SectionLayout.qml
new file mode 100644
index 0000000..22054fe
--- /dev/null
+++ b/src/imports/StudioControls/SectionLayout.qml
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Layouts 1.12
+
+GridLayout {
+ columns: 2
+ columnSpacing: 12
+ rowSpacing: 4
+ width: parent.width - 16
+}
diff --git a/src/imports/StudioControls/Slider.qml b/src/imports/StudioControls/Slider.qml
new file mode 100644
index 0000000..e8cfe2a
--- /dev/null
+++ b/src/imports/StudioControls/Slider.qml
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Shapes 1.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.Slider {
+ id: slider
+
+ property int decimals: 0
+ property bool labels: true
+ property bool tickMarks: false
+ property real tickMarkStepSize: 0.0 // StepSize bug QTBUG-76136
+ property real tickMarkWidth: 1.0
+ property real tickMarkHeight: 4.0
+ readonly property int tickMarkCount: tickMarkStepSize
+ !== 0.0 ? (to - from) / tickMarkStepSize + 1 : 0
+ readonly property real tickMarkSpacing: tickMarkCount
+ !== 0 ? (sliderTrack.width - tickMarkWidth
+ * tickMarkCount) / (tickMarkCount - 1) : 0.0
+
+ property string __activeColor: StudioTheme.Values.themeSliderActiveTrack
+ property string __inactiveColor: StudioTheme.Values.themeSliderInactiveTrack
+
+ property bool hover: false // This property is used to indicate the global hover state
+ property bool edit: slider.activeFocus
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ implicitHandleWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ implicitHandleHeight + topPadding + bottomPadding,
+ StudioTheme.Values.height)
+ padding: 0
+ leftPadding: actionIndicator.width
+ - (actionIndicatorVisible ? StudioTheme.Values.border
+ - StudioTheme.Values.sliderPadding : 0)
+
+ wheelEnabled: false
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: slider
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ handle: Rectangle {
+ id: sliderHandle
+ x: slider.leftPadding + (slider.visualPosition * slider.availableWidth)
+ - (sliderHandle.width / 2)
+ y: slider.topPadding + (slider.availableHeight / 2) - (sliderHandle.height / 2)
+ z: 20
+ implicitWidth: StudioTheme.Values.sliderHandleWidth
+ implicitHeight: StudioTheme.Values.sliderHandleHeight
+ color: StudioTheme.Values.themeSliderHandle
+
+ Shape {
+ id: sliderHandleLabelPointer
+
+ property real __width: StudioTheme.Values.sliderPointerWidth
+ property real __height: StudioTheme.Values.sliderPointerHeight
+ property bool antiAlias: true
+
+ layer.enabled: antiAlias
+ layer.smooth: antiAlias
+ layer.textureSize: Qt.size(width * 2, height * 2)
+
+ implicitWidth: __width
+ implicitHeight: __height
+
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: sliderHandleLabelBackground.bottom
+
+ ShapePath {
+ id: sliderHandleLabelPointerPath
+ strokeColor: "transparent"
+ strokeWidth: 0
+ fillColor: StudioTheme.Values.themeInteraction
+
+ startX: 0
+ startY: 0
+
+ PathLine {
+ x: sliderHandleLabelPointer.__width
+ y: 0
+ }
+ PathLine {
+ x: sliderHandleLabelPointer.__width / 2
+ y: sliderHandleLabelPointer.__height
+ }
+ }
+ }
+
+ Rectangle {
+ id: sliderHandleLabelBackground
+ x: -(sliderHandleLabelBackground.width / 2) + (sliderHandle.width / 2)
+ width: makeEven(
+ sliderHandleLabel.width + StudioTheme.Values.inputHorizontalPadding)
+ height: sliderHandleLabel.height
+ anchors.bottom: parent.top
+ anchors.bottomMargin: StudioTheme.Values.sliderMargin
+ color: StudioTheme.Values.themeInteraction
+
+ Text {
+ id: sliderHandleLabel
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ text: Number.parseFloat(slider.value).toFixed(slider.decimals)
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.sliderFontSize
+ }
+ }
+ }
+
+ function makeEven(value) {
+ var v = Math.round(value)
+ return (v % 2 === 0) ? v : v + 1
+ }
+
+ background: Rectangle {
+ id: sliderTrack
+ x: slider.leftPadding
+ y: slider.topPadding + slider.availableHeight / 2 - height / 2
+ width: slider.availableWidth
+ height: StudioTheme.Values.sliderTrackHeight
+ color: __inactiveColor
+
+ Rectangle {
+ width: slider.visualPosition * parent.width
+ height: parent.height
+ color: __activeColor
+ }
+ }
+
+ Item {
+ id: tickmarkBounds
+ x: sliderTrack.x
+ y: sliderTrack.y
+
+ Text {
+ id: tickmarkFromLabel
+ x: 0
+ y: StudioTheme.Values.sliderPadding
+ text: Number.parseFloat(slider.from).toFixed(slider.decimals)
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.sliderFontSize
+ visible: slider.labels
+ }
+
+ Text {
+ id: tickmarkToLabel
+ x: slider.availableWidth - width
+ y: StudioTheme.Values.sliderPadding
+ text: Number.parseFloat(slider.to).toFixed(slider.decimals)
+ color: StudioTheme.Values.themeTextColor
+ font.pixelSize: StudioTheme.Values.sliderFontSize
+ visible: slider.labels
+ }
+
+ Row {
+ id: tickmarkRow
+ spacing: tickMarkSpacing
+ visible: slider.tickMarks
+
+ Repeater {
+ id: tickmarkRepeater
+ model: tickMarkCount
+ delegate: Rectangle {
+ implicitWidth: tickMarkWidth
+ implicitHeight: StudioTheme.Values.sliderTrackHeight
+ color: x < (slider.visualPosition
+ * slider.availableWidth) ? __inactiveColor : __activeColor
+ }
+ }
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ x: actionIndicator.width
+ y: 0
+ width: slider.width - actionIndicator.width
+ height: slider.height
+ enabled: true
+ hoverEnabled: true
+ propagateComposedEvents: true
+ acceptedButtons: Qt.LeftButton
+ cursorShape: Qt.PointingHandCursor
+ // Sets the global hover
+ onContainsMouseChanged: slider.hover = containsMouse
+ onPressed: mouse.accepted = false
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: slider.enabled && !slider.hover && !slider.edit
+ PropertyChanges {
+ target: slider
+ wheelEnabled: false
+ }
+ },
+ State {
+ name: "hovered"
+ when: slider.enabled && slider.hover && !slider.edit
+ PropertyChanges {
+ target: slider
+ __activeColor: StudioTheme.Values.themeSliderActiveTrackHover
+ __inactiveColor: StudioTheme.Values.themeSliderInactiveTrackHover
+ }
+ PropertyChanges {
+ target: sliderHandle
+ color: StudioTheme.Values.themeSliderHandleHover
+ }
+ },
+ State {
+ name: "focus"
+ when: slider.enabled && slider.edit
+ PropertyChanges {
+ target: slider
+ wheelEnabled: true
+ __activeColor: StudioTheme.Values.themeSliderActiveTrackFocus
+ __inactiveColor: StudioTheme.Values.themeSliderInactiveTrackFocus
+ }
+ PropertyChanges {
+ target: sliderHandle
+ color: StudioTheme.Values.themeSliderHandleFocus
+ }
+ },
+ State {
+ name: "disabled"
+ when: !slider.enabled
+ PropertyChanges {
+ target: tickmarkFromLabel
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ PropertyChanges {
+ target: tickmarkToLabel
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ PropertyChanges {
+ target: sliderHandleLabel
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ PropertyChanges {
+ target: slider
+ __activeColor: StudioTheme.Values.themeControlBackgroundDisabled
+ __inactiveColor: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ PropertyChanges {
+ target: sliderHandleLabelBackground
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ PropertyChanges {
+ target: sliderHandleLabelPointerPath
+ fillColor: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ PropertyChanges {
+ target: sliderHandle
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/SliderPopup.qml b/src/imports/StudioControls/SliderPopup.qml
new file mode 100644
index 0000000..a80ff78
--- /dev/null
+++ b/src/imports/StudioControls/SliderPopup.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.Popup {
+ id: sliderPopup
+
+ property T.Control myControl
+
+ dim: false
+ closePolicy: T.Popup.CloseOnEscape | T.Popup.CloseOnPressOutsideParent
+
+ background: Rectangle {
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeInteraction
+ }
+
+ contentItem: T.Slider {
+ id: slider
+ anchors.fill: parent
+
+ bottomPadding: 0
+ topPadding: 0
+ rightPadding: 3
+ leftPadding: 3
+
+ from: myControl.from
+ value: myControl.value
+ to: myControl.to
+
+ focusPolicy: Qt.NoFocus
+
+ handle: Rectangle {
+ x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
+ y: slider.topPadding + (slider.availableHeight / 2) - (height / 2)
+ width: StudioTheme.Values.sliderHandleWidth
+ height: StudioTheme.Values.sliderHandleHeight
+ radius: 0
+ color: slider.pressed ? StudioTheme.Values.themeInteraction : StudioTheme.Values.themeControlOutline
+ }
+
+ background: Rectangle {
+ x: slider.leftPadding
+ y: slider.topPadding + (slider.availableHeight / 2) - (height / 2)
+ width: slider.availableWidth
+ height: StudioTheme.Values.sliderTrackHeight
+ radius: 0
+ color: StudioTheme.Values.themeSliderInactiveTrack
+
+ Rectangle {
+ width: slider.visualPosition * parent.width
+ height: parent.height
+ color: StudioTheme.Values.themeSliderActiveTrack
+ radius: 0
+ }
+ }
+
+ onMoved: {
+ var currValue = myControl.value
+ myControl.value = slider.value
+
+ if (currValue !== myControl.value)
+ myControl.valueModified()
+ }
+ }
+
+ onOpened: {
+ // Check if value is in sync with text input, if not sync it!
+ var val = myControl.valueFromText(myControl.contentItem.text,
+ myControl.locale)
+ if (myControl.value !== val) {
+ myControl.value = val
+ myControl.valueModified()
+ }
+ }
+}
diff --git a/src/imports/StudioControls/SpinBox.qml b/src/imports/StudioControls/SpinBox.qml
new file mode 100644
index 0000000..60d35ac
--- /dev/null
+++ b/src/imports/StudioControls/SpinBox.qml
@@ -0,0 +1,329 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.SpinBox {
+ id: mySpinBox
+
+ property alias labelColor: spinBoxInput.color
+ property alias actionIndicator: actionIndicator
+
+ property int decimals: 0
+ property int factor: Math.pow(10, decimals)
+
+ property real minStepSize: 1
+ property real maxStepSize: 10
+
+ property bool edit: spinBoxInput.activeFocus
+ property bool hover: false // This property is used to indicate the global hover state
+ property bool drag: false
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ property bool spinBoxIndicatorVisible: true
+ property real __spinBoxIndicatorWidth: StudioTheme.Values.smallRectWidth - (2
+ * StudioTheme.Values.border)
+ property real __spinBoxIndicatorHeight: (StudioTheme.Values.height / 2)
+ - StudioTheme.Values.border
+
+ property alias sliderIndicatorVisible: sliderIndicator.visible
+ property real __sliderIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __sliderIndicatorHeight: StudioTheme.Values.height
+
+ signal compressedValueModified
+
+ // Use custom wheel handling due to bugs
+ property bool __wheelEnabled: false
+ wheelEnabled: false
+
+ width: StudioTheme.Values.squareComponentWidth * 5
+ height: StudioTheme.Values.height
+
+ leftPadding: spinBoxIndicatorDown.x + spinBoxIndicatorDown.width
+ - (spinBoxIndicatorVisible ? 0 : StudioTheme.Values.border)
+ rightPadding: sliderIndicator.width - (sliderIndicatorVisible ? StudioTheme.Values.border : 0)
+
+ font.pixelSize: StudioTheme.Values.myFontSize
+ editable: true
+ validator: mySpinBox.decimals ? doubleValidator : intValidator
+
+ DoubleValidator {
+ id: doubleValidator
+ locale: mySpinBox.locale.name
+ notation: DoubleValidator.StandardNotation
+ decimals: mySpinBox.decimals
+ bottom: Math.min(mySpinBox.from, mySpinBox.to) / mySpinBox.factor
+ top: Math.max(mySpinBox.from, mySpinBox.to) / mySpinBox.factor
+ }
+
+ IntValidator {
+ id: intValidator
+ locale: mySpinBox.locale.name
+ bottom: Math.min(mySpinBox.from, mySpinBox.to)
+ top: Math.max(mySpinBox.from, mySpinBox.to)
+ }
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: mySpinBox
+
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ up.indicator: SpinBoxIndicator {
+ id: spinBoxIndicatorUp
+ myControl: mySpinBox
+
+ visible: spinBoxIndicatorVisible
+ //hover: mySpinBox.up.hovered // TODO QTBUG-74688
+ pressed: mySpinBox.up.pressed
+ iconFlip: -1
+
+ x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
+ y: StudioTheme.Values.border
+ width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
+ height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
+
+ enabled: (mySpinBox.from < mySpinBox.to) ? mySpinBox.value < mySpinBox.to : mySpinBox.value > mySpinBox.to
+ }
+
+ down.indicator: SpinBoxIndicator {
+ id: spinBoxIndicatorDown
+ myControl: mySpinBox
+
+ visible: spinBoxIndicatorVisible
+ //hover: mySpinBox.down.hovered // TODO QTBUG-74688
+ pressed: mySpinBox.down.pressed
+
+ x: actionIndicator.width + (actionIndicatorVisible ? 0 : StudioTheme.Values.border)
+ y: spinBoxIndicatorUp.y + spinBoxIndicatorUp.height
+ width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
+ height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
+
+ enabled: (mySpinBox.from < mySpinBox.to) ? mySpinBox.value > mySpinBox.from : mySpinBox.value < mySpinBox.from
+ }
+
+ contentItem: SpinBoxInput {
+ id: spinBoxInput
+ myControl: mySpinBox
+ }
+
+ background: Rectangle {
+ id: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ width: mySpinBox.width - actionIndicator.width
+ height: mySpinBox.height
+ }
+
+ CheckIndicator {
+ id: sliderIndicator
+ myControl: mySpinBox
+ myPopup: sliderPopup
+
+ x: spinBoxInput.x + spinBoxInput.width - StudioTheme.Values.border
+ width: sliderIndicator.visible ? __sliderIndicatorWidth : 0
+ height: sliderIndicator.visible ? __sliderIndicatorHeight : 0
+ visible: false // reasonable default
+ }
+
+ SliderPopup {
+ id: sliderPopup
+ myControl: mySpinBox
+
+ x: spinBoxInput.x
+ y: StudioTheme.Values.height - StudioTheme.Values.border
+ width: spinBoxInput.width + sliderIndicator.width - StudioTheme.Values.border
+ height: StudioTheme.Values.sliderHeight
+
+ enter: Transition {
+ }
+ exit: Transition {
+ }
+ }
+
+ textFromValue: function (value, locale) {
+ return Number(value / mySpinBox.factor).toLocaleString(locale, 'f',
+ mySpinBox.decimals)
+ }
+
+ valueFromText: function (text, locale) {
+ return Number.fromLocaleString(locale, text) * mySpinBox.factor
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: mySpinBox.enabled && !mySpinBox.hover
+ && !mySpinBox.edit && !mySpinBox.drag
+ PropertyChanges {
+ target: mySpinBox
+ __wheelEnabled: false
+ }
+ PropertyChanges {
+ target: spinBoxInput
+ selectByMouse: false
+ }
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutline
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: mySpinBox.edit
+ PropertyChanges {
+ target: mySpinBox
+ __wheelEnabled: true
+ }
+ PropertyChanges {
+ target: spinBoxInput
+ selectByMouse: true
+ }
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "drag"
+ when: mySpinBox.drag
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeInteraction
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !mySpinBox.enabled
+ PropertyChanges {
+ target: spinBoxBackground
+ color: StudioTheme.Values.themeControlOutlineDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ }
+ ]
+
+ Timer {
+ id: myTimer
+ repeat: false
+ running: false
+ interval: 100
+ onTriggered: mySpinBox.compressedValueModified()
+ }
+
+ onValueModified: myTimer.restart()
+ onFocusChanged: mySpinBox.setValueFromInput()
+ onDisplayTextChanged: spinBoxInput.text = mySpinBox.displayText
+ onActiveFocusChanged: {
+ if (mySpinBox.activeFocus)
+ // QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
+ spinBoxInput.selectAll()
+
+ if (sliderPopup.opened && !mySpinBox.activeFocus)
+ sliderPopup.close()
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
+ event.accepted = true
+
+ // Store current step size
+ var currStepSize = mySpinBox.stepSize
+
+ if (event.modifiers & Qt.ControlModifier)
+ mySpinBox.stepSize = mySpinBox.minStepSize
+
+ if (event.modifiers & Qt.ShiftModifier)
+ mySpinBox.stepSize = mySpinBox.maxStepSize
+
+ // Check if value is in sync with text input, if not sync it!
+ var val = mySpinBox.valueFromText(spinBoxInput.text,
+ mySpinBox.locale)
+ if (mySpinBox.value !== val)
+ mySpinBox.value = val
+
+ var currValue = mySpinBox.value
+
+ if (event.key === Qt.Key_Up)
+ mySpinBox.increase()
+ else
+ mySpinBox.decrease()
+
+ if (currValue !== mySpinBox.value)
+ mySpinBox.valueModified()
+
+ // Reset step size
+ mySpinBox.stepSize = currStepSize
+ }
+
+ if (event.key === Qt.Key_Escape)
+ mySpinBox.focus = false
+
+ // FIX: This is a temporary fix for QTBUG-74239
+ if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
+ mySpinBox.setValueFromInput()
+ }
+
+ function clamp(v, lo, hi) {
+ if (v < lo || v > hi)
+ return Math.min(Math.max(lo, v), hi)
+
+ return v
+ }
+
+ function setValueFromInput() {
+ // FIX: This is a temporary fix for QTBUG-74239
+ var currValue = mySpinBox.value
+
+ if (!spinBoxInput.acceptableInput)
+ mySpinBox.value = clamp(valueFromText(spinBoxInput.text,
+ mySpinBox.locale),
+ mySpinBox.validator.bottom * mySpinBox.factor,
+ mySpinBox.validator.top * mySpinBox.factor)
+ else
+ mySpinBox.value = valueFromText(spinBoxInput.text,
+ mySpinBox.locale)
+
+ if (spinBoxInput.text !== mySpinBox.displayText)
+ spinBoxInput.text = mySpinBox.displayText
+
+ if (mySpinBox.value !== currValue)
+ mySpinBox.valueModified()
+ }
+}
diff --git a/src/imports/StudioControls/SpinBoxIndicator.qml b/src/imports/StudioControls/SpinBoxIndicator.qml
new file mode 100644
index 0000000..3f27286
--- /dev/null
+++ b/src/imports/StudioControls/SpinBoxIndicator.qml
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Rectangle {
+ id: spinBoxIndicator
+
+ property T.Control myControl
+
+ property bool hover: false
+ property bool pressed: false
+
+ property alias iconFlip: spinBoxIndicatorIconScale.yScale
+
+ color: StudioTheme.Values.themeControlBackground
+ border.width: 0
+
+ // This MouseArea is a workaround to avoid some hover state related bugs
+ // when using the actual signal 'up.hovered'. QTBUG-74688
+ MouseArea {
+ id: spinBoxIndicatorMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onContainsMouseChanged: spinBoxIndicator.hover = containsMouse
+ onPressed: {
+ myControl.forceActiveFocus()
+ mouse.accepted = false
+ }
+ }
+
+ T.Label {
+ id: spinBoxIndicatorIcon
+ text: StudioTheme.Constants.upDownSquare2
+ color: StudioTheme.Values.themeTextColor
+ renderType: Text.NativeRendering
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.pixelSize: StudioTheme.Values.spinControlIconSizeMulti
+ font.family: StudioTheme.Constants.iconFont.family
+ anchors.fill: parent
+ transform: Scale {
+ id: spinBoxIndicatorIconScale
+ origin.x: 0
+ origin.y: spinBoxIndicatorIcon.height / 2
+ yScale: 1
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !(spinBoxIndicator.hover
+ || myControl.hover)
+ && !spinBoxIndicator.pressed && !myControl.edit
+ && !myControl.drag && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeControlBackground
+ }
+ },
+ State {
+ name: "hovered"
+ when: (spinBoxIndicator.hover || myControl.hover)
+ && !spinBoxIndicator.pressed && !myControl.edit
+ && !myControl.drag && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeHoverHighlight
+ }
+ },
+ State {
+ name: "pressed"
+ when: spinBoxIndicator.pressed && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "edit"
+ when: myControl.edit && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeFocusEdit
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag && spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeFocusDrag
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled || !spinBoxIndicator.enabled
+ PropertyChanges {
+ target: spinBoxIndicator
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ }
+ PropertyChanges {
+ target: spinBoxIndicatorIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/SpinBoxInput.qml b/src/imports/StudioControls/SpinBoxInput.qml
new file mode 100644
index 0000000..50b4a06
--- /dev/null
+++ b/src/imports/StudioControls/SpinBoxInput.qml
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+TextInput {
+ id: textInput
+
+ property T.Control myControl
+
+ property bool edit: textInput.activeFocus
+ property bool drag: false
+
+ z: 2
+ font: myControl.font
+ color: StudioTheme.Values.themeTextColor
+ selectionColor: StudioTheme.Values.themeTextSelectionColor
+ selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
+
+ horizontalAlignment: Qt.AlignRight
+ verticalAlignment: Qt.AlignVCenter
+ leftPadding: StudioTheme.Values.inputHorizontalPadding
+ rightPadding: StudioTheme.Values.inputHorizontalPadding
+
+ readOnly: !myControl.editable
+ validator: myControl.validator
+ inputMethodHints: myControl.inputMethodHints
+ selectByMouse: false
+ activeFocusOnPress: false
+ clip: true
+
+ // TextInput focus needs to be set to activeFocus whenever it changes,
+ // otherwise TextInput will get activeFocus whenever the parent SpinBox gets
+ // activeFocus. This will lead to weird side effects.
+ onActiveFocusChanged: textInput.focus = activeFocus
+
+ Rectangle {
+ id: textInputArea
+
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+
+ x: 0
+ y: 0
+ z: -1
+ width: textInput.width
+ height: StudioTheme.Values.height
+ }
+
+ DragHandler {
+ id: dragHandler
+ target: null
+ acceptedDevices: PointerDevice.Mouse
+ enabled: true
+
+ property int initialValue: 0
+
+ onActiveChanged: {
+ if (active) {
+ initialValue = myControl.value
+ mouseArea.cursorShape = Qt.ClosedHandCursor
+ myControl.drag = true
+ } else {
+ mouseArea.cursorShape = Qt.PointingHandCursor
+ myControl.drag = false
+ }
+ }
+ onTranslationChanged: {
+ var currValue = myControl.value
+ myControl.value = initialValue + translation.x
+
+ if (currValue !== myControl.value)
+ myControl.valueModified()
+ }
+ }
+
+ TapHandler {
+ id: tapHandler
+ acceptedDevices: PointerDevice.Mouse
+ enabled: true
+ onTapped: {
+ textInput.forceActiveFocus()
+ textInput.deselect() // QTBUG-75862
+ }
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ enabled: true
+ hoverEnabled: true
+ propagateComposedEvents: true
+ acceptedButtons: Qt.LeftButton
+ cursorShape: Qt.PointingHandCursor
+ // Sets the global hover
+ onContainsMouseChanged: myControl.hover = containsMouse
+ onPressed: mouse.accepted = false
+ onWheel: {
+ if (!myControl.__wheelEnabled)
+ return
+
+ var val = myControl.valueFromText(textInput.text, myControl.locale)
+ if (myControl.value !== val)
+ myControl.value = val
+
+ var currValue = myControl.value
+ myControl.value += wheel.angleDelta.y / 120
+
+ if (currValue !== myControl.value)
+ myControl.valueModified()
+ }
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !textInput.edit
+ && !mouseArea.containsMouse && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ PropertyChanges {
+ target: dragHandler
+ enabled: true
+ }
+ PropertyChanges {
+ target: tapHandler
+ enabled: true
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.PointingHandCursor
+ }
+ },
+ State {
+ name: "hovered"
+ when: myControl.hover && !textInput.edit && !myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: textInput.edit
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ PropertyChanges {
+ target: dragHandler
+ enabled: false
+ }
+ PropertyChanges {
+ target: tapHandler
+ enabled: false
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.IBeamCursor
+ }
+ },
+ State {
+ name: "drag"
+ when: myControl.drag
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeFocusDrag
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: textInputArea
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: textInput
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/TextArea.qml b/src/imports/StudioControls/TextArea.qml
new file mode 100644
index 0000000..1af1758
--- /dev/null
+++ b/src/imports/StudioControls/TextArea.qml
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+TextField {
+ id: myTextField
+
+ property real relativePopupX: 0 // TODO Maybe call it leftPadding
+ property real popupWidth: myTextField.width
+ property string txtStorage
+
+ property int temp: 0
+
+ T.Popup {
+ id: popup
+ x: myTextField.relativePopupX
+ y: myTextField.height - StudioTheme.Values.border
+ width: myTextField.popupWidth
+ height: scrollView.height
+ background: Rectangle {
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ border.width: StudioTheme.Values.border
+ }
+
+ contentItem: TextAreaScrollView {
+ id: scrollView
+ padding: 0
+ height: Math.min(textAreaPopup.contentHeight + scrollView.topPadding
+ + scrollView.bottomPadding,
+ StudioTheme.Values.maxTextAreaPopupHeight)
+ ScrollBar.horizontal.policy: ScrollBar.AlwaysOn
+ ScrollBar.vertical.policy: ScrollBar.AlwaysOn
+
+ T.TextArea {
+ id: textAreaPopup
+ padding: 10
+ width: textAreaPopup.contentWidth + textAreaPopup.leftPadding
+ + textAreaPopup.rightPadding
+ anchors.fill: parent
+ font.pixelSize: StudioTheme.Values.myFontSize
+ color: StudioTheme.Values.themeTextColor
+ selectionColor: StudioTheme.Values.themeTextSelectionColor
+ selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
+ selectByMouse: true
+ persistentSelection: textAreaPopup.focus
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ enabled: true
+ cursorShape: Qt.IBeamCursor
+ acceptedButtons: Qt.RightButton
+ onPressed: contextMenu.popup(textAreaPopup)
+ }
+ }
+ }
+
+ ContextMenu {
+ id: contextMenu
+ myTextEdit: textAreaPopup
+ }
+
+ AbstractButton {
+ id: acceptButton
+ x: popup.width - acceptButton.width
+ y: popup.height - StudioTheme.Values.border
+ width: Math.round(StudioTheme.Values.smallRectWidth)
+ height: Math.round(StudioTheme.Values.smallRectWidth)
+ buttonIcon: StudioTheme.Constants.tickIcon
+ }
+
+ AbstractButton {
+ id: discardButton
+ x: popup.width - acceptButton.width - discardButton.width + StudioTheme.Values.border
+ y: popup.height - StudioTheme.Values.border
+ width: Math.round(StudioTheme.Values.smallRectWidth)
+ height: Math.round(StudioTheme.Values.smallRectWidth)
+ buttonIcon: StudioTheme.Constants.closeCross
+ }
+
+ Component.onCompleted: {
+ storeAndFormatTextInput(myTextField.text)
+ }
+
+ onOpened: {
+ textAreaPopup.text = txtStorage
+ myTextField.clear()
+ }
+
+ onClosed: {
+ storeAndFormatTextInput(textAreaPopup.text)
+ myTextField.forceActiveFocus()
+ textAreaPopup.deselect()
+ }
+ }
+
+ function storeAndFormatTextInput(inputText) {
+ txtStorage = inputText
+ var pos = txtStorage.search(/\n/g)
+ var sliceAt = Math.min(pos, 15)
+ myTextField.text = txtStorage.slice(0, sliceAt).padEnd(sliceAt + 3, '.')
+ }
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Escape)
+ popup.opened ? popup.close() : myTextField.focus = false
+
+ if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
+ && !popup.opened) {
+ popup.open()
+ textAreaPopup.forceActiveFocus()
+ }
+ }
+}
diff --git a/src/imports/StudioControls/TextAreaScrollView.qml b/src/imports/StudioControls/TextAreaScrollView.qml
new file mode 100644
index 0000000..2975622
--- /dev/null
+++ b/src/imports/StudioControls/TextAreaScrollView.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.ScrollView {
+ id: control
+
+ property alias horizontalThickness: horizontalScrollBar.height
+ property alias verticalThickness: verticalScrollBar.width
+ property bool bothVisible: verticalScrollBar.visible
+ && horizontalScrollBar.visible
+
+ implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
+ contentWidth + leftPadding + rightPadding)
+ implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
+ contentHeight + topPadding + bottomPadding)
+
+ ScrollBar.vertical: ControlScrollBar {
+ id: verticalScrollBar
+ parent: control
+ x: control.width - verticalScrollBar.width - StudioTheme.Values.border
+ y: StudioTheme.Values.border
+ height: control.availableHeight - (2 * StudioTheme.Values.border)
+ - (control.bothVisible ? control.horizontalThickness : 0)
+ active: control.ScrollBar.horizontal.active
+ }
+
+ ScrollBar.horizontal: ControlScrollBar {
+ id: horizontalScrollBar
+ parent: control
+ x: StudioTheme.Values.border
+ y: control.height - horizontalScrollBar.height - StudioTheme.Values.border
+ width: control.availableWidth - (2 * StudioTheme.Values.border)
+ - (control.bothVisible ? control.verticalThickness : 0)
+ active: control.ScrollBar.vertical.active
+ }
+}
diff --git a/src/imports/StudioControls/TextField.qml b/src/imports/StudioControls/TextField.qml
new file mode 100644
index 0000000..7c14e83
--- /dev/null
+++ b/src/imports/StudioControls/TextField.qml
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+T.TextField {
+ id: myTextField
+
+ property alias actionIndicator: actionIndicator
+ property alias translationIndicator: translationIndicator
+
+ property bool edit: myTextField.activeFocus
+ property bool hover: false // This property is used to indicate the global hover state
+
+ property alias actionIndicatorVisible: actionIndicator.visible
+ property real __actionIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __actionIndicatorHeight: StudioTheme.Values.height
+
+ property alias translationIndicatorVisible: translationIndicator.visible
+ property real __translationIndicatorWidth: StudioTheme.Values.squareComponentWidth
+ property real __translationIndicatorHeight: StudioTheme.Values.height
+
+ horizontalAlignment: Qt.AlignLeft
+ verticalAlignment: Qt.AlignVCenter
+
+ font.pixelSize: StudioTheme.Values.myFontSize
+
+ color: StudioTheme.Values.themeTextColor
+ selectionColor: StudioTheme.Values.themeTextSelectionColor
+ selectedTextColor: StudioTheme.Values.themeTextSelectedTextColor
+
+ readOnly: false
+ selectByMouse: true
+ persistentSelection: focus // QTBUG-73807
+ clip: true
+
+ width: StudioTheme.Values.height * 5
+ height: StudioTheme.Values.height
+ implicitHeight: StudioTheme.Values.height
+
+ leftPadding: StudioTheme.Values.inputHorizontalPadding + actionIndicator.width
+ - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ rightPadding: StudioTheme.Values.inputHorizontalPadding + translationIndicator.width
+ - (translationIndicatorVisible ? StudioTheme.Values.border : 0)
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ enabled: true
+ hoverEnabled: true
+ propagateComposedEvents: true
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ cursorShape: Qt.PointingHandCursor
+ onContainsMouseChanged: myTextField.hover = containsMouse // Sets the global hover
+ onPressed: {
+ if (mouse.button === Qt.RightButton)
+ contextMenu.popup(myTextField)
+
+ mouse.accepted = false
+ }
+ }
+
+ onPersistentSelectionChanged: {
+ if (!persistentSelection)
+ myTextField.deselect()
+ }
+
+ ContextMenu {
+ id: contextMenu
+ myTextEdit: myTextField
+ }
+
+ ActionIndicator {
+ id: actionIndicator
+ myControl: myTextField
+ x: 0
+ y: 0
+ width: actionIndicator.visible ? __actionIndicatorWidth : 0
+ height: actionIndicator.visible ? __actionIndicatorHeight : 0
+ }
+
+ background: Rectangle {
+ id: textFieldBackground
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ border.width: StudioTheme.Values.border
+ x: actionIndicator.width - (actionIndicatorVisible ? StudioTheme.Values.border : 0)
+ width: myTextField.width - actionIndicator.width
+ height: myTextField.height
+ }
+
+ TranslationIndicator {
+ id: translationIndicator
+ myControl: myTextField
+ x: myTextField.width - translationIndicator.width
+ width: translationIndicator.visible ? __translationIndicatorWidth : 0
+ height: translationIndicator.visible ? __translationIndicatorHeight : 0
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myTextField.enabled && !myTextField.hover
+ && !myTextField.edit
+ PropertyChanges {
+ target: textFieldBackground
+ color: StudioTheme.Values.themeControlBackground
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.PointingHandCursor
+ }
+ },
+ State {
+ name: "hovered"
+ when: myTextField.hover && !myTextField.edit
+ PropertyChanges {
+ target: textFieldBackground
+ color: StudioTheme.Values.themeHoverHighlight
+ border.color: StudioTheme.Values.themeControlOutline
+ }
+ },
+ State {
+ name: "edit"
+ when: myTextField.edit
+ PropertyChanges {
+ target: textFieldBackground
+ color: StudioTheme.Values.themeFocusEdit
+ border.color: StudioTheme.Values.themeInteraction
+ }
+ PropertyChanges {
+ target: mouseArea
+ cursorShape: Qt.IBeamCursor
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myTextField.enabled
+ PropertyChanges {
+ target: textFieldBackground
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ }
+ ]
+
+ Keys.onPressed: {
+ if (event.key === Qt.Key_Escape)
+ myTextField.focus = false
+ }
+}
diff --git a/src/imports/StudioControls/TranslationIndicator.qml b/src/imports/StudioControls/TranslationIndicator.qml
new file mode 100644
index 0000000..7c4e0c9
--- /dev/null
+++ b/src/imports/StudioControls/TranslationIndicator.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Templates 2.12 as T
+import StudioTheme 1.0 as StudioTheme
+
+Item {
+ id: translationIndicator
+
+ property Item myControl
+
+ property bool hover: false
+ property bool pressed: false
+ property bool checked: false
+
+ signal clicked
+
+ state: "default"
+
+ Rectangle {
+ id: translationIndicatorBackground
+ color: StudioTheme.Values.themeColumnBackground // TODO create extra variable, this one is used
+ border.color: StudioTheme.Values.themeTranslationIndicatorBorder
+
+ anchors.centerIn: parent
+
+ width: matchParity(translationIndicator.height,
+ StudioTheme.Values.smallRectWidth)
+ height: matchParity(translationIndicator.height,
+ StudioTheme.Values.smallRectWidth)
+
+ function matchParity(root, value) {
+ // TODO maybe not necessary
+ var v = Math.round(value)
+
+ if (root % 2 == 0)
+ // even
+ return (v % 2 == 0) ? v : v - 1
+ else
+ // odd
+ return (v % 2 == 0) ? v - 1 : v
+ }
+
+ MouseArea {
+ id: translationIndicatorMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onContainsMouseChanged: translationIndicator.hover = containsMouse
+ onPressed: mouse.accepted = true // TODO
+ onClicked: {
+ translationIndicator.checked = !translationIndicator.checked
+ translationIndicator.clicked()
+ }
+ }
+ }
+
+ T.Label {
+ id: translationIndicatorIcon
+ text: "tr"
+ color: StudioTheme.Values.themeTextColor
+ font.family: StudioTheme.Constants.font.family
+ font.pixelSize: StudioTheme.Values.myIconFontSize
+ font.italic: true
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+
+ states: [
+ State {
+ name: "default"
+ when: myControl.enabled && !translationIndicator.hover
+ && !translationIndicator.pressed && !myControl.hover
+ && !myControl.edit && !myControl.drag
+ && !translationIndicator.checked
+ PropertyChanges {
+ target: translationIndicatorBackground
+ color: StudioTheme.Values.themeColumnBackground
+ border.color: StudioTheme.Values.themeTranslationIndicatorBorder
+ }
+ },
+ State {
+ name: "checked"
+ when: translationIndicator.checked
+
+ PropertyChanges {
+ target: translationIndicatorBackground
+ color: StudioTheme.Values.themeInteraction // TODO
+ }
+ },
+ State {
+ name: "hovered"
+ when: translationIndicator.hover && !translationIndicator.pressed
+ && !myControl.edit && !myControl.drag && !myControl.drag
+ PropertyChanges {
+ target: translationIndicatorBackground
+ color: StudioTheme.Values.themeFocusDrag // TODO
+ }
+ },
+ State {
+ name: "disabled"
+ when: !myControl.enabled
+ PropertyChanges {
+ target: translationIndicatorBackground
+ color: StudioTheme.Values.themeControlBackgroundDisabled
+ border.color: StudioTheme.Values.themeControlOutlineDisabled
+ }
+ PropertyChanges {
+ target: translationIndicatorIcon
+ color: StudioTheme.Values.themeTextColorDisabled
+ }
+ }
+ ]
+}
diff --git a/src/imports/StudioControls/qmldir b/src/imports/StudioControls/qmldir
new file mode 100644
index 0000000..02e83ed
--- /dev/null
+++ b/src/imports/StudioControls/qmldir
@@ -0,0 +1,35 @@
+AbstractButton 1.0 AbstractButton.qml
+ActionIndicator 1.0 ActionIndicator.qml
+Button 1.0 Button.qml
+ButtonGroup 1.0 ButtonGroup.qml
+ButtonRow 1.0 ButtonRow.qml
+CheckBox 1.0 CheckBox.qml
+CheckIndicator 1.0 CheckIndicator.qml
+ComboBox 1.0 ComboBox.qml
+ComboBoxInput 1.0 ComboBoxInput.qml
+ContextMenu 1.0 ContextMenu.qml
+ControlScrollBar 1.0 ControlScrollBar.qml
+ExpandingSpacer 1.0 ExpandingSpacer.qml
+ItemDelegate 1.0 ItemDelegate.qml
+Menu 1.0 Menu.qml
+MenuItem 1.0 MenuItem.qml
+MenuSeparator 1.0 MenuSeparator.qml
+RealSliderPopup 1.0 RealSliderPopup.qml
+RealSpinBox 1.0 RealSpinBox.qml
+RealSpinBoxIndicator 1.0 RealSpinBoxIndicator.qml
+RealSpinBoxInput 1.0 RealSpinBoxInput.qml
+ScrollBar 1.0 ScrollBar.qml
+ScrollView 1.0 ScrollView.qml
+SecondColumnLayout 1.0 SecondColumnLayout.qml
+Section 1.0 Section.qml
+SectionLabel 1.0 SectionLabel.qml
+SectionLayout 1.0 SectionLayout.qml
+Slider 1.0 Slider.qml
+SliderPopup 1.0 SliderPopup.qml
+SpinBox 1.0 SpinBox.qml
+SpinBoxIndicator 1.0 SpinBoxIndicator.qml
+SpinBoxInput 1.0 SpinBoxInput.qml
+TextArea 1.0 TextArea.qml
+TextAreaScrollView 1.0 TextAreaScrollView.qml
+TextField 1.0 TextField.qml
+TranslationIndicator 1.0 TranslationIndicator.qml
diff --git a/src/imports/StudioTheme/Constants.qml b/src/imports/StudioTheme/Constants.qml
new file mode 100644
index 0000000..207a154
--- /dev/null
+++ b/src/imports/StudioTheme/Constants.qml
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.10
+
+QtObject {
+ readonly property int width: 1920
+ readonly property int height: 1080
+ readonly property FontLoader mySystemFont: FontLoader {
+ name: "Arial"
+ }
+ readonly property FontLoader controlIcons: FontLoader {
+ source: "icons.ttf"
+ }
+
+ readonly property string actionIcon: "\u0021"
+ readonly property string actionIconBinding: "\u0022"
+ readonly property string anchorBaseline: "\u0023"
+ readonly property string anchorBottom: "\u0024"
+ readonly property string anchorFill: "\u0025"
+ readonly property string anchorLeft: "\u0026"
+ readonly property string anchorRight: "\u0027"
+ readonly property string anchorTop: "\u0028"
+ readonly property string centerHorizontal: "\u0029"
+ readonly property string centerVertical: "\u002A"
+ readonly property string closeCross: "\u002B"
+ readonly property string fontStyleBold: "\u002C"
+ readonly property string fontStyleItalic: "\u002D"
+ readonly property string fontStyleStrikethrough: "\u002E"
+ readonly property string fontStyleUnderline: "\u002F"
+ readonly property string textAlignBottom: "\u0030"
+ readonly property string textAlignCenter: "\u0031"
+ readonly property string textAlignLeft: "\u0032"
+ readonly property string textAlignMiddle: "\u0033"
+ readonly property string textAlignRight: "\u0034"
+ readonly property string textAlignTop: "\u0035"
+ readonly property string tickIcon: "\u0036"
+ readonly property string triState: "\u0037"
+ readonly property string upDownIcon: "\u0038"
+ readonly property string upDownSquare2: "\u0039"
+
+ readonly property font iconFont: Qt.font({
+ "family": controlIcons.name,
+ "pixelSize": 12
+ })
+
+ readonly property font font: Qt.font({
+ "family": mySystemFont.name,
+ "pointSize": Qt.application.font.pixelSize
+ })
+
+ readonly property font largeFont: Qt.font({
+ "family": mySystemFont.name,
+ "pointSize": Qt.application.font.pixelSize * 1.6
+ })
+
+ readonly property color backgroundColor: "#c2c2c2"
+}
diff --git a/src/imports/StudioTheme/Values.qml b/src/imports/StudioTheme/Values.qml
new file mode 100644
index 0000000..67438bc
--- /dev/null
+++ b/src/imports/StudioTheme/Values.qml
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+pragma Singleton
+import QtQuick 2.12
+
+QtObject {
+ id: values
+
+ property real baseHeight: 20
+ property real baseFont: 12
+ property real baseIconFont: 10
+
+ property real scaleFactor: 1.1
+
+ property real height: Math.round(values.baseHeight * values.scaleFactor)
+ property real myFontSize: Math.round(values.baseFont * values.scaleFactor)
+ property real myIconFontSize: Math.round(values.baseIconFont * values.scaleFactor)
+
+ property real squareComponentWidth: values.height
+ property real smallRectWidth: values.height / 2 * 1.5
+
+ property real inputWidth: values.height * 4
+
+ property real sliderHeight: values.height / 2 * 1.5 // TODO:Have a look at -> sliderAreaHeight: Data.Values.height/2*1.5
+
+ property real sliderControlSize: 12
+ property real sliderControlSizeMulti: values.sliderControlSize * values.scaleFactor
+
+ property int dragLength: 400 // px
+ property real spinControlIconSize: 8
+ property real spinControlIconSizeMulti: values.spinControlIconSize * values.scaleFactor
+
+ property real sliderTrackHeight: values.height / 4
+ property real sliderHandleHeight: values.sliderTrackHeight * 2
+ property real sliderHandleWidth: values.sliderTrackHeight
+ property real sliderFontSize: Math.round(8 * values.scaleFactor)
+ property real sliderPadding: Math.round(6 * values.scaleFactor)
+ property real sliderMargin: Math.round(3 * values.scaleFactor)
+
+ property real sliderPointerWidth: Math.round(7 * values.scaleFactor)
+ property real sliderPointerHeight: Math.round(2 * values.scaleFactor)
+
+ property real checkBoxSpacing: Math.round(6 * values.scaleFactor)
+
+ property real columnWidth: 225 + (175 * (values.scaleFactor * 2))
+
+ property real marginTopBottom: 4
+ property real border: 1
+
+ property real maxComboBoxPopupHeight: Math.round(300 * values.scaleFactor)
+ property real maxTextAreaPopupHeight: Math.round(150 * values.scaleFactor)
+
+ property real contextMenuLabelSpacing: Math.round(30 * values.scaleFactor)
+ property real contextMenuHorizontalPadding: Math.round(6 * values.scaleFactor)
+
+ property real inputHorizontalPadding: Math.round(4 * values.scaleFactor)
+
+ // Theme Colors
+
+ // Dark Theme Defaults
+ property string themeControlBackground: "#242424"
+ property string themeControlOutline: "#404040"
+ property string themeTextColor: "#ffffff"
+
+ property string themePanelBackground: "#2a2a2a"
+ property string themeHoverHighlight: "#313131"
+ property string themeColumnBackground: "#363636"
+ property string themeFocusEdit: "#444444"
+ property string themeFocusDrag: "#565656"
+
+ property string themeControlBackgroundPressed: "#606060"
+ property string themeControlBackgroundChecked: "#565656"
+
+ property string themeInteraction: "#029de0"
+
+ property string themeSliderActiveTrack: "#606060"
+ property string themeSliderInactiveTrack: "#404040"
+ property string themeSliderHandle: "#505050"
+
+ property string themeSliderActiveTrackHover: "#7f7f7f"
+ property string themeSliderInactiveTrackHover: "#505050"
+ property string themeSliderHandleHover: "#606060"
+
+ property string themeSliderActiveTrackFocus: "#aaaaaa"
+ property string themeSliderInactiveTrackFocus: "#606060"
+ property string themeSliderHandleFocus: values.themeInteraction
+
+ // NEW NEW NEW NEW NEW
+ property string themeControlBackgroundDisabled: "#363636"
+ property string themeControlOutlineDisabled: "#404040"
+ property string themeTextColorDisabled: "#606060"
+
+ property string themeTextSelectionColor: "#029de0"
+ property string themeTextSelectedTextColor: "#ffffff"
+
+ property string themeScrollBarTrack: "#404040"
+ property string themeScrollBarHandle: "#505050"
+
+ property string themeControlBackgroundInteraction: "#404040" // TODO Name. Right now themeFocusEdit is used for all 'edit' states. Is that correct? Different color!
+
+ property string themeTranslationIndicatorBorder: "#7f7f7f"
+}
diff --git a/src/imports/StudioTheme/icons.ttf b/src/imports/StudioTheme/icons.ttf
new file mode 100644
index 0000000..9658c01
--- /dev/null
+++ b/src/imports/StudioTheme/icons.ttf
Binary files differ
diff --git a/src/imports/StudioTheme/qmldir b/src/imports/StudioTheme/qmldir
new file mode 100644
index 0000000..b768fe6
--- /dev/null
+++ b/src/imports/StudioTheme/qmldir
@@ -0,0 +1,2 @@
+singleton Values 1.0 Values.qml
+singleton Constants 1.0 Constants.qml