summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Gruendl <henning.gruendl@qt.io>2019-07-05 14:58:20 +0200
committerThomas Hartmann <thomas.hartmann@qt.io>2019-08-05 14:43:03 +0000
commit98085e69a6d250321b3012671c6b4ba50be4370a (patch)
tree848309d3bf0b6b8f12ce4c23640d2f3a012c77dd
parentbb54345474c928250f65f778fcfc2fb061f72406 (diff)
Add new controls for property editorHEADmaster
Adds new controls for the property editor based on Controls 2. The included controls are SpinBox (RealSpinBox), ComboBox, TextField, TextArea (experimental), CheckBox (with tri-state), Button (ButtonRow), ContextMenu, ScrollView and ScrollBar. Each control contains an ActionIndicator which can be hidden on demand. The ActionIndicator itself can also be used standalone. It also a flag to draw it without borders and background. The reason for two SpinBox implementations is the following bug QDS-806. Usage of SpinBox should be avoided rather use RealSpinBox. Change-Id: Ie647f05d02e8de8d31da9556126ce2cabe9009e9 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-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