Merge remote-tracking branch 'origin/4.10'

Change-Id: Ie1861bb221a9974d78938e9a2078c1f6aa207210
This commit is contained in:
Eike Ziller
2019-06-06 07:01:06 +02:00
114 changed files with 6384 additions and 505 deletions

View File

@@ -165,18 +165,14 @@
the \QC Manual, observe the guidelines listed in this section when taking
screen shots.
To make the images look similar regardless of the operating system they were
taken on, you are asked to adjust their size to 75%. This makes the screen
shots hard to read, but they are provided more as reassurance for users that
they are in the correct place in the UI than as an actual source of
information. To make sure that no important information is lost, always
place example values also in the text.
\note Do not rely on screen shots present reasonable example values to
users, but always place example values also in the text.
\list
\li Use the screen resolution of 1024x768 (this is available on all
screens).
\li Use the screen resolution of 1366x768 (available on the most
commonly used screens, as of this writing).
\li Use the aspect ratio of 4:3.
\li Use the aspect ratio of 16:9.
\li Open the application in the maximum size on full screen.
@@ -185,9 +181,6 @@
\li Include only the part of the screen that you need (you can crop the
image also in the screen capture tool).
\li In the screen capture tool, open the screen shot and adjust its size
to 75%.
\li To highlight parts of the screen shot, use the images of numbers
that are stored in \c{doc\images\numbers} in the \QC repository.
@@ -212,13 +205,8 @@
\c doc\images\numbers directory (or in the \c qtdoc module sources in
\c doc\images\numbers).
To use the numbers:
\list
\li Take a screenshot as described above.
\li After resizing the screenshot, copy-paste the number images on
the screenshot to the places that you want to refer to from text.
\endlist
To use the numbers, copy-paste the number images on the screenshot to the
places that you want to refer to from text.
\section2 Optimizing Images
@@ -234,8 +222,8 @@
You can use a web service, such as \l{https://tinypng.com}, or an image
optimization tool to shrink the images. For example, you can use the Radical
Image Optimization Tool (RIOT) on Windows (very efficient) or ImageOptim on
\macos (much less efficient), or some other tool available on Linux.
Image Optimization Tool (RIOT) or OptiPNG on Windows, ImageOptim on
\macos, or some other tool available on Linux.
With ImageOptim, you simply drag and drop the image files to the
application. The following section describes the settings to use for RIOT.

View File

@@ -196,16 +196,6 @@
files, as well as compare the selected file with the currently open file
in the diff editor. For more information, see \l{Comparing Files}.
\section1 Viewing Open Documents
To see a list of open documents, switch to the \uicontrol {Open Documents}
view. By right-clicking an open document, you can:
\list
\li Pin files to ensure they stay at the top of the list and are not
closed when \uicontrol {Close All} is used.
\endlist
\section1 Viewing the File System
If you cannot see a file in the \uicontrol Projects view, switch to the
@@ -274,6 +264,22 @@
\endlist
\section1 Viewing Open Documents
To see a list of open documents, switch to the \uicontrol {Open Documents}
view. You can use the context-menu to perform some of the functions also
available in the \uicontrol File menu and in the context menu in the
\uicontrol {File System} view.
In addition, you can:
\list
\li Copy the full path of the file or just the filename to the
clipboard.
\li Pin files to ensure they stay at the top of the list and are not
closed when \uicontrol {Close All} is used.
\endlist
\section1 Viewing Defined Types and Symbols
The \uicontrol Outline view shows an overview of defined types and other

View File

@@ -55,7 +55,7 @@ Section {
minimumValue: 0.01
stepSize: 0.1
maximumValue: 10
Layout.preferredWidth: 80
Layout.preferredWidth: 100
}
ExpandingSpacer {
}
@@ -70,7 +70,7 @@ Section {
decimals: 2
minimumValue: -360
maximumValue: 360
Layout.preferredWidth: 80
Layout.preferredWidth: 100
}
ExpandingSpacer {
}
@@ -84,7 +84,7 @@ Section {
hasSlider: true
minimumValue: -100
maximumValue: 100
Layout.preferredWidth: 80
Layout.preferredWidth: 100
}
ExpandingSpacer {
}

View File

@@ -76,6 +76,7 @@ Rectangle {
typeLineEdit.forceActiveFocus()
}
tooltip: qsTr("Change the type of this item.")
enabled: !modelNodeBackend.multiSelection
}
ExpressionTextField {
@@ -118,15 +119,18 @@ Rectangle {
Layout.fillWidth: true
showTranslateCheckBox: false
showExtendedFunctionButton: false
enabled: !modelNodeBackend.multiSelection
}
// workaround: without this item the lineedit does not shrink to the
// right size after resizing to a wider width
Image {
visible: !modelNodeBackend.multiSelection
Layout.preferredWidth: 16
Layout.preferredHeight: 16
source: hasAliasExport ? "image://icons/alias-export-checked" : "image://icons/alias-export-unchecked"
ToolTipArea {
enabled: !modelNodeBackend.multiSelection
anchors.fill: parent
onClicked: toogleExportAlias()
tooltip: qsTr("Toggles whether this item is exported as an alias property of the root item.")

View File

@@ -73,7 +73,7 @@ Column {
SpinBox {
backendValue: backendValues.border_width
hasSlider: true
Layout.preferredWidth: 80
Layout.preferredWidth: 120
}
ExpandingSpacer {
@@ -86,7 +86,7 @@ Column {
SpinBox {
backendValue: backendValues.radius
hasSlider: true
Layout.preferredWidth: 80
Layout.preferredWidth: 120
minimumValue: 0
maximumValue: Math.min(backendValues.height.value, backendValues.width.value) / 2
}

View File

@@ -24,26 +24,25 @@
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.1 as Controls
import StudioControls 1.0 as Controls
import QtQuick.Controls.Styles 1.1
Controls.CheckBox {
id: checkBox
property color textColor: colorLogic.textColor
opacity: enabled ? 1 : 0.5
property variant backendValue
property string tooltip
ExtendedFunctionButton {
x: 22
anchors.verticalCenter: parent.verticalCenter
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: checkBox.backendValue
visible: checkBox.enabled
}
actionIndicator.icon.color: extFuncLogic.color
actionIndicator.icon.text: extFuncLogic.glyph
actionIndicator.onClicked: extFuncLogic.show()
labelColor: colorLogic.textColor
ColorLogic {
id: colorLogic
backendValue: checkBox.backendValue
@@ -58,8 +57,4 @@ Controls.CheckBox {
backendValue.value = checkBox.checked;
}
style: CustomCheckBoxStyle {
}
}

View File

@@ -82,6 +82,9 @@ Item {
lightnessSlider.value = lightness
alphaSlider.value = alpha
redSlider.value = (color.r * 255)
greenSlider.value = (color.g * 255)
blueSlider.value = (color.b * 255)
block = false
}
@@ -242,7 +245,6 @@ Item {
anchors.margins: 6
y: 4
height: parent.height - 8
//value: colorButton.hue
onValueChanged: {
if (colorButton.hue !== value)
colorButton.hue = value
@@ -250,101 +252,194 @@ Item {
onClicked: colorButton.clicked()
}
Column {
Row {
anchors.left: hueSlider.right
anchors.margins: colorButton.sliderMargins
spacing: 10
Row {
z: 3
spacing: 4
Label {
text: "H:"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
Column {
spacing: 10
Row {
z: 3
spacing: 1
Label {
text: "R"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: redSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.r !== value && !colorButton.block) {
color.r = (value / 255.0)
colorButton.clicked()
}
}
}
}
DoubleSpinBox {
id: hueSlider2
//value: colorButton.hue
onValueChanged: {
if (colorButton.hue !== value && !colorButton.block) {
colorButton.hue = value
colorButton.clicked()
Row {
z: 2
spacing: 1
Controls.Label {
text: "G"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: greenSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.g !== value && !colorButton.block) {
color.g = (value / 255.0)
colorButton.clicked()
}
}
}
}
Row {
z: 1
spacing: 1
Controls.Label {
text: "B"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: blueSlider
width: 64
stepSize: 1
minimumValue: 0
maximumValue: 255
decimals: 0
onValueChanged: {
if (color.b !== value && !colorButton.block) {
color.b = (value / 255.0)
colorButton.clicked()
}
}
}
}
Row {
z: 0
spacing: 1
Controls.Label {
text: "A"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: alphaSlider
width: 64
onValueChanged: {
if (colorButton.alpha !== value && !colorButton.block) {
colorButton.alpha = value
colorButton.clicked()
}
}
}
}
}
Row {
z: 2
spacing: 4
Controls.Label {
text: "S:"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
Column {
spacing: 10
Row {
z: 3
spacing: 1
Label {
text: "H"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: hueSlider2
width: 64
onValueChanged: {
if (colorButton.hue !== value && !colorButton.block) {
colorButton.hue = value
colorButton.clicked()
}
}
}
}
DoubleSpinBox {
id: saturationSlider
//value: colorButton.saturation
onValueChanged: {
if (colorButton.saturation !== value && !colorButton.block) {
colorButton.saturation = value
colorButton.clicked()
Row {
z: 2
spacing: 1
Controls.Label {
text: "S"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: saturationSlider
width: 64
onValueChanged: {
if (colorButton.saturation !== value && !colorButton.block) {
colorButton.saturation = value
colorButton.clicked()
}
}
}
}
Row {
z: 1
spacing: 1
Controls.Label {
text: "L"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: lightnessSlider
width: 64
onValueChanged: {
if (colorButton.lightness !== value && !colorButton.block) {
colorButton.lightness = value
colorButton.clicked()
}
}
}
}
}
Row {
z: 1
spacing: 4
Controls.Label {
text: "L:"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: lightnessSlider
//value: colorButton.lightness
onValueChanged: {
if (colorButton.lightness !== value && !colorButton.block) {
colorButton.lightness = value
colorButton.clicked()
}
}
}
}
Row {
z: 0
spacing: 4
Controls.Label {
text: "A:"
width: 16
color: "#eee"
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
}
DoubleSpinBox {
id: alphaSlider
//value: colorButton.alpha
onValueChanged: {
if (colorButton.alpha !== value && !colorButton.block) {
colorButton.alpha = value
colorButton.clicked()
}
}
}
}
}
}

View File

@@ -25,19 +25,54 @@
import QtQuick 2.1
Rectangle {
id: checkBox
width: 18
height: 18
border.color: "black"
border.width: 1
Item {
id: colorCheckButtonRoot
property bool checked: false
property alias buttonColor: checkBox.color
width: 30
height: 24
MouseArea {
anchors.fill: parent
onClicked: checkBox.checked = !checkBox.checked
Rectangle {
id: backgroundBox
width: 24
height: 24
anchors.right: parent.right
color: "white"
border.color: "white"
border.width: 1
Rectangle {
id: checkBox
width: 22
height: 22
anchors.centerIn: parent
border.color: "black"
border.width: 1
}
}
Image {
id: arrowImage
width: 8
height: 4
source: "image://icons/down-arrow"
anchors.verticalCenter: parent.verticalCenter
anchors.right: backgroundBox.left
anchors.rightMargin: 2
opacity: colorToolTip.containsMouse ? 1 : 0.8
rotation: colorCheckButtonRoot.checked ? 0.0 : 270.0
}
ToolTipArea {
id: colorToolTip
onClicked: checked = !checked
hoverEnabled: true
anchors.fill: parent
anchors.leftMargin: -arrowImage.width
tooltip: qsTr("Toggle color picker view")
}
}

View File

@@ -25,9 +25,7 @@
import QtQuick 2.1
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0 as Controls
import QtQuickDesignerTheme 1.0
import QtQuick.Controls.Styles 1.1
Column {
id: colorEditor
@@ -38,7 +36,7 @@ Column {
property bool supportGradient: false
property alias caption: label.text
property string caption: "Color"
property variant backendValue
@@ -50,8 +48,14 @@ Column {
property alias transparent: transparentButton.checked
property color originalColor
function isNotInGradientMode() {
return (buttonRow.checkedIndex !== 1)
return (buttonRow.checkedIndex === 0 || transparent)
}
function resetShapeColor() {
colorEditor.backendValue.resetValue()
}
onValueChanged: colorEditor.color = colorEditor.value
@@ -73,7 +77,7 @@ Column {
if (!gradientLine.isInValidState)
return;
if (supportGradient && gradientLine.hasGradient) {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
textField.text = convertColorToString(color)
gradientLine.currentColor = color
}
@@ -84,22 +88,27 @@ Column {
}
}
ColorLine {
visible: {
return (colorEditor.supportGradient && isNotInGradientMode())
}
currentColor: colorEditor.color
width: parent.width
}
GradientLine {
property bool isInValidState: false
visible: {
if (colorEditor.shapeGradients) {
return buttonRow.checkedIndex > 0 && buttonRow.checkedIndex < 4
} else {
return buttonRow.checkedIndex === 1
}
return !(isNotInGradientMode())
}
id: gradientLine
width: parent.width
onCurrentColorChanged: {
if (supportGradient && gradientLine.hasGradient)
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.color = gradientLine.currentColor
}
}
onHasGradientChanged: {
@@ -125,11 +134,21 @@ Column {
buttonRow.initalChecked = 1
}
colorEditor.color = gradientLine.currentColor
} else if (colorEditor.transparent) {
buttonRow.initalChecked = 4
} else {
buttonRow.initalChecked = 0
colorEditor.color = colorEditor.value
}
buttonRow.checkedIndex = buttonRow.initalChecked
colorEditor.originalColor = colorEditor.color
}
onSelectedNodeChanged: {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.originalColor = gradientLine.currentColor
}
}
Connections {
@@ -137,18 +156,26 @@ Column {
onSelectionToBeChanged: {
colorEditorTimer.stop()
gradientLine.isInValidState = false
if (colorEditor.originalColor !== colorEditor.color) {
if (colorEditor.color != "#ffffff"
&& colorEditor.color != "#000000"
&& colorEditor.color != "#00000000") {
colorPalette.addColorToPalette(colorEditor.color)
}
}
}
}
Connections {
target: modelNodeBackend
onSelectionChanged: {
if (supportGradient && gradientLine.hasGradient) {
if (colorEditor.supportGradient && gradientLine.hasGradient) {
colorEditor.color = gradientLine.currentColor
gradientLine.currentColor = color
textField.text = colorEditor.color
}
gradientLine.isInValidState = true
colorEditor.originalColor = colorEditor.color
}
}
@@ -156,29 +183,21 @@ Column {
SectionLayout {
width: parent.width
columnSpacing: 0
rowSpacing: checkButton.checked ? 8 : 2
rows: 5
//spacer 1
Item {
height: 0
width: 2
}
Item {
height: 0
width: 2
}
Label {
id: label
text: "Color"
height: 6
}
SecondColumnLayout {
ColorCheckButton {
id: checkButton
color: colorEditor.color
buttonColor: colorEditor.color
}
LineEdit {
@@ -217,64 +236,30 @@ Column {
iconSource: "images/icon_color_solid.png"
onClicked: {
if (colorEditor.supportGradient)
gradientLine.deleteGradient()
gradientLine.deleteGradient()
textField.text = colorEditor.color
colorEditor.backendValue.resetValue()
colorEditor.resetShapeColor()
}
tooltip: qsTr("Solid Color")
}
ButtonRowButton {
visible: supportGradient
visible: colorEditor.supportGradient
iconSource: "images/icon_color_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
if (colorEditor.shapeGradients)
gradientLine.gradientTypeName = "LinearGradient"
else
gradientLine.gradientTypeName = "Gradient"
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.addGradient()
}
gradientLine.addGradient()
}
GradientPresetList {
id: presetList
visible: false
function applyPreset() {
if (presetList.gradientData.presetType == 0) {
gradientLine.setPresetByID(presetList.gradientData.presetID);
}
else if (presetList.gradientData.presetType == 1) {
gradientLine.setPresetByStops(
presetList.gradientData.stops,
presetList.gradientData.colors,
presetList.gradientData.stopsCount);
}
else { console.log("INVALID GRADIENT TYPE: " + presetList.gradientData.presetType); }
}
onApply: {
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
onSaved: {
gradientLine.savePreset();
presetList.updatePresets();
}
onAccepted: { //return key
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
}
onDoubleClicked: {
presetList.open()
}
tooltip: qsTr("Linear Gradient")
@@ -345,15 +330,18 @@ Column {
}
}
ButtonRowButton {
visible: supportGradient && colorEditor.shapeGradients
visible: colorEditor.supportGradient && colorEditor.shapeGradients
iconSource: "images/icon_color_radial_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
colorEditor.resetShapeColor()
gradientLine.gradientTypeName = "RadialGradient"
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.gradientTypeName = "RadialGradient"
gradientLine.addGradient()
}
gradientLine.addGradient()
}
tooltip: qsTr("Radial Gradient")
@@ -442,18 +430,21 @@ Column {
}
}
ButtonRowButton {
visible: supportGradient && colorEditor.shapeGradients
visible: colorEditor.supportGradient && colorEditor.shapeGradients
iconSource: "images/icon_color_conical_gradient.png"
onClicked: {
colorEditor.backendValue.resetValue()
if (colorEditor.shapeGradients) {
colorEditor.resetShapeColor()
gradientLine.gradientTypeName = "ConicalGradient"
if (gradientLine.hasGradient)
gradientLine.updateGradient()
else {
gradientLine.deleteGradient()
gradientLine.gradientTypeName = "ConicalGradient"
gradientLine.addGradient()
}
gradientLine.addGradient()
}
tooltip: qsTr("Concial Gradient")
tooltip: qsTr("Conical Gradient")
GradientPopupIndicator {
@@ -513,18 +504,104 @@ Column {
id: transparentButton
iconSource: "images/icon_color_none.png"
onClicked: {
gradientLine.deleteGradient()
colorEditor.resetShapeColor()
colorEditor.color = "#00000000"
if (colorEditor.supportGradient)
gradientLine.deleteGradient()
}
tooltip: qsTr("Transparent")
}
}
Rectangle {
id: gradientPickerButton
width: 20
height: 20
visible: colorEditor.supportGradient
color: "white"
border.color: "white"
border.width: 1
ToolTipArea {
anchors.fill: parent
id: toolTipArea
tooltip: qsTr("Gradient Picker Dialog")
}
GradientPresetList {
id: presetList
visible: false
function applyPreset() {
if (presetList.gradientData.presetType == 0) {
gradientLine.setPresetByID(presetList.gradientData.presetID);
}
else if (presetList.gradientData.presetType == 1) {
gradientLine.setPresetByStops(
presetList.gradientData.stops,
presetList.gradientData.colors,
presetList.gradientData.stopsCount);
}
else {
console.log("INVALID GRADIENT TYPE: " +
presetList.gradientData.presetType);
}
}
onApply: {
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
onSaved: {
gradientLine.savePreset();
presetList.updatePresets();
}
onAccepted: { //return key
if (presetList.gradientData.stopsCount > 0) {
applyPreset();
}
}
}
Rectangle {
width: 18
height: 18
anchors.centerIn: parent
color: "steelblue"
border.color: "black"
border.width: 1
MouseArea {
anchors.fill: parent
onClicked: {
presetList.open()
}
}
}
}
ExpandingSpacer {
}
}
//empty spacer 2
Item {
height: 6
}
Item {
height: 6
}
//spacer 3
Item {
height: 6
}
ColorButton {
property color bindedColor: colorEditor.color
@@ -536,24 +613,101 @@ Column {
enabled: !colorEditor.transparent
opacity: checkButton.checked ? 1 : 0
id: colorButton
width: 116
height: checkButton.checked ? 116 : 0
Layout.preferredWidth: 116
Layout.preferredHeight: checkButton.checked ? 116 : 0
Layout.preferredWidth: 124
Layout.preferredHeight: checkButton.checked ? 124 : 0
sliderMargins: Math.max(0, label.width - colorButton.width) + 4
sliderMargins: 4
onClicked: colorEditor.color = colorButton.color
}
SecondColumnLayout {
//empty spacer 4
Item { height: 2 }
Item { height: 2 }
//spacer 5
Item {
height: 4
}
Item {
height: 4
width :4
}
id: colorBoxes
Layout.preferredWidth: 134
Layout.preferredHeight: checkButton.checked ? 70 : 0
visible: checkButton.checked
SecondColumnLayout {
spacing: 16
RowLayout {
spacing: 2
Column {
spacing: 5
Text {
text: qsTr("Original")
color: "#eee"
}
Rectangle {
id: originalColorRectangle
color: colorEditor.originalColor
height: 40
width: 67
border.width: 1
border.color: "#555555"
MouseArea {
anchors.fill: parent
onClicked: {
if (!colorEditor.transparent)
colorEditor.color = colorEditor.originalColor
}
}
}
}
Column {
spacing: 5
Text {
text: qsTr("New")
color: "#eee"
}
Rectangle {
id: newColorRectangle
color: colorEditor.color
height: 40
width: 67
border.width: 1
border.color: "#555555"
}
}
}
Column {
spacing: 5
Text {
text: qsTr("Recent")
color: "#eee"
elide: Text.ElideRight
}
SimpleColorPalette {
id: colorPalette
clickable: !colorEditor.transparent
onSelectedColorChanged: {
colorEditor.color = colorPalette.selectedColor;
}
}
}
ExpandingSpacer {
}
}
}
}
}

View File

@@ -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.1
import HelperWidgets 2.0
import QtQuick.Controls.Private 1.0 // showing a ToolTip
Item {
width: 300
height: 60
property alias currentColor : colorLine.color
Column {
anchors.fill: parent
Item {
width: 1
height: 40
}
Rectangle {
height: 16
width: parent.width
border.color: "#555555"
border.width: 1
id: colorLine
color: "white"
}
}
}

View File

@@ -24,7 +24,7 @@
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.1 as Controls
import StudioControls 1.0 as Controls
import QtQuick.Controls.Styles 1.1
Controls.ComboBox {
@@ -32,7 +32,7 @@ Controls.ComboBox {
property variant backendValue
property color textColor: colorLogic.textColor
labelColor: colorLogic.textColor
property string scope: "Qt"
property bool useInteger: false
@@ -45,6 +45,15 @@ Controls.ComboBox {
property bool block: false
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: comboBox.backendValue
}
actionIndicator.icon.color: extFuncLogic.color
actionIndicator.icon.text: extFuncLogic.glyph
actionIndicator.onClicked: extFuncLogic.show()
ColorLogic {
id: colorLogic
backendValue: comboBox.backendValue
@@ -84,7 +93,7 @@ Controls.ComboBox {
}
}
onCurrentTextChanged: {
onActivated: {
if (!__isCompleted)
return;
@@ -106,14 +115,4 @@ Controls.ComboBox {
__isCompleted = true;
}
style: CustomComboBoxStyle {
textColor: comboBox.textColor
}
ExtendedFunctionButton {
x: 2
anchors.verticalCenter: parent.verticalCenter
backendValue: comboBox.backendValue
visible: comboBox.enabled
}
}

View File

@@ -0,0 +1,207 @@
/****************************************************************************
**
** Copyright (C) 2016 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.1
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
import QtQuickDesignerTheme 1.0
Item {
id: extendedFunctionButton
property variant backendValue
property bool isBoundBackend: backendValue.isBound
property string backendExpression: backendValue.expression
property string glyph: StudioTheme.Constants.actionIcon
property string color: StudioTheme.Constants.themeTextColor
property alias menuLoader: menuLoader
signal reseted
function show() {
menuLoader.show()
}
function setIcon() {
extendedFunctionButton.color = StudioTheme.Values.themeTextColor
if (backendValue === null) {
extendedFunctionButton.glyph = StudioTheme.Constants.actionIcon
} else if (backendValue.isBound) {
if (backendValue.isTranslated) {
// translations are a special case
extendedFunctionButton.glyph = StudioTheme.Constants.actionIcon
} else {
extendedFunctionButton.glyph = StudioTheme.Constants.closeCross
extendedFunctionButton.color = StudioTheme.Values.themeInteraction
}
} else {
if (backendValue.complexNode !== null
&& backendValue.complexNode.exists) {
} else {
extendedFunctionButton.glyph = StudioTheme.Constants.actionIcon
}
}
}
onBackendValueChanged: {
setIcon()
}
onIsBoundBackendChanged: {
setIcon()
}
onBackendExpressionChanged: {
setIcon()
}
Loader {
id: menuLoader
active: false
function show() {
active = true
item.popup()
}
sourceComponent: Component {
StudioControls.Menu {
id: menu
onAboutToShow: {
exportMenuItem.checked = backendValue.hasPropertyAlias()
exportMenuItem.enabled = !backendValue.isAttachedProperty()
}
StudioControls.MenuItem {
text: qsTr("Reset")
onTriggered: {
transaction.start()
backendValue.resetValue()
backendValue.resetValue()
transaction.end()
extendedFunctionButton.reseted()
}
}
StudioControls.MenuItem {
text: qsTr("Set Binding")
onTriggered: expressionDialogLoader.show()
}
StudioControls.MenuItem {
id: exportMenuItem
text: qsTr("Export Property as Alias")
onTriggered: {
if (checked)
backendValue.exportPopertyAsAlias()
else
backendValue.removeAliasExport()
}
checkable: true
}
StudioControls.MenuItem {
text: qsTr("Insert Keyframe")
enabled: hasActiveTimeline
onTriggered: insertKeyframe(backendValue.name)
}
}
}
}
Loader {
id: expressionDialogLoader
parent: itemPane
anchors.fill: parent
visible: false
active: visible
function show() {
expressionDialogLoader.visible = true
}
sourceComponent: Component {
Item {
id: expressionDialog
anchors.fill: parent
Component.onCompleted: {
textField.text = backendValue.expression
textField.forceActiveFocus()
}
Rectangle {
anchors.fill: parent
color: Theme.qmlDesignerBackgroundColorDarker()
opacity: 0.6
}
MouseArea {
anchors.fill: parent
onDoubleClicked: expressionDialog.visible = false
}
Rectangle {
x: 4
Component.onCompleted: {
var pos = itemPane.mapFromItem(
extendedFunctionButton.parent, 0, 0)
y = pos.y + 2
}
width: parent.width - 8
height: 260
radius: 2
color: Theme.qmlDesignerBackgroundColorDarkAlternate()
border.color: Theme.qmlDesignerBorderColor()
Label {
x: 8
y: 6
font.bold: true
text: qsTr("Binding Editor")
}
ExpressionTextField {
id: textField
onRejected: expressionDialogLoader.visible = false
onAccepted: {
backendValue.expression = textField.text.trim()
expressionDialogLoader.visible = false
}
anchors.fill: parent
anchors.leftMargin: 8
anchors.rightMargin: 8
anchors.topMargin: 24
anchors.bottomMargin: 32
}
}
}
}
}
}

View File

@@ -40,6 +40,8 @@ Item {
property alias gradientPropertyName: gradientModel.gradientPropertyName
property alias gradientTypeName: gradientModel.gradientTypeName
signal selectedNodeChanged
onHasGradientChanged: {
colorLine.invalidate()
}
@@ -75,6 +77,10 @@ Item {
gradientModel.savePreset()
}
function updateGradient() {
gradientModel.updateGradient()
}
Connections {
target: modelNodeBackend
onSelectionChanged: {
@@ -105,6 +111,7 @@ Item {
gradientModel.lock()
currentColor = repeater.itemAt(index).item.color
gradientModel.unlock()
selectedNodeChanged()
}
function invalidate() {
@@ -134,6 +141,7 @@ Item {
height: 40
anchors.left: parent.left
anchors.right: parent.right
cursorShape: Qt.PointingHandCursor
onClicked: {
var currentPosition = mouseX / colorLine.effectiveWidth
@@ -321,6 +329,7 @@ Item {
drag.maximumX: colorLine.effectiveWidth
drag.minimumY: !readOnly ? 0 : 20
drag.maximumY: 20
cursorShape: Qt.PointingHandCursor
// using pressed property instead of drag.active which was not working
onExited: {

View File

@@ -28,6 +28,7 @@ import QtQuick.Controls 1.1 as Controls
import QtQuick.Layouts 1.0
import QtQuick.Controls.Private 1.0
import QtQuickDesignerTheme 1.0
import StudioTheme 1.0 as StudioTheme
Controls.Label {
id: label
@@ -40,6 +41,8 @@ Controls.Label {
color: Theme.color(Theme.PanelTextColorLight)
elide: Text.ElideRight
font.pixelSize: StudioTheme.Values.myFontSize
Layout.preferredWidth: width
Layout.minimumWidth: width
Layout.maximumWidth: width

View File

@@ -24,24 +24,20 @@
****************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.1 as Controls
import StudioControls 1.0 as Controls
import QtQuick.Controls.Styles 1.0
import QtQuickDesignerTheme 1.0
Controls.TextField {
Controls.Action {
//Workaround to avoid that "Delete" deletes the item.
shortcut: "Delete"
}
id: lineEdit
property variant backendValue
property color borderColor: "#222"
property color highlightColor: "orange"
property color textColor: colorLogic.textColor
color: colorLogic.textColor
property bool showTranslateCheckBox: true
translationIndicatorVisible: showTranslateCheckBox
property bool writeValueManually: false
@@ -58,19 +54,21 @@ Controls.TextField {
if (translateFunction() === "qsTranslate") {
backendValue.expression = translateFunction()
+ "(\"" + backendValue.getTranslationContext()
+ "\", " + "\"" + trCheckbox.escapeString(text) + "\")"
+ "\", " + "\"" + escapeString(text) + "\")"
} else {
backendValue.expression = translateFunction() + "(\"" + trCheckbox.escapeString(text) + "\")"
backendValue.expression = translateFunction() + "(\"" + escapeString(text) + "\")"
}
}
ExtendedFunctionButton {
x: 4
anchors.verticalCenter: parent.verticalCenter
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: lineEdit.backendValue
visible: lineEdit.enabled && showExtendedFunctionButton
}
actionIndicator.icon.color: extFuncLogic.color
actionIndicator.icon.text: extFuncLogic.glyph
actionIndicator.onClicked: extFuncLogic.show()
ColorLogic {
id: colorLogic
backendValue: lineEdit.backendValue
@@ -102,7 +100,6 @@ Controls.TextField {
}
onEditingFinished: {
if (writeValueManually)
return
@@ -118,87 +115,35 @@ Controls.TextField {
__dirty = false
}
style: TextFieldStyle {
property bool isTranslated: colorLogic.backendValue.isTranslated
selectionColor: Theme.color(Theme.PanelTextColorLight)
selectedTextColor: Theme.color(Theme.PanelTextColorMid)
textColor: lineEdit.textColor
placeholderTextColor: Theme.color(Theme.PanelTextColorMid)
padding.top: 2
padding.bottom: 2
padding.left: 18
padding.right: lineEdit.showTranslateCheckBox ? 16 : 1
background: Rectangle {
implicitWidth: 100
implicitHeight: 24
color: Theme.qmlDesignerBackgroundColorDarker()
border.color: Theme.qmlDesignerBorderColor()
translationIndicator.onClicked: {
if (translationIndicator.checked) {
setTranslateExpression()
} else {
var textValue = lineEdit.text
lineEdit.backendValue.value = textValue
}
colorLogic.evaluate();
}
Controls.CheckBox {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
id: trCheckbox
property bool isTranslated: colorLogic.backendValue.isTranslated
property bool backendValueValue: colorLogic.backendValue.value
onIsTranslatedChanged: {
checked = lineEdit.backendValue.isTranslated
}
onBackendValueValueChanged: {
checked = lineEdit.backendValue.isTranslated
}
onClicked: {
if (trCheckbox.checked) {
setTranslateExpression()
} else {
var textValue = lineEdit.text
lineEdit.backendValue.value = textValue
}
colorLogic.evaluate();
}
function escapeString(string) {
var str = string;
str = str.replace(/\\/g, "\\\\");
str.replace(/\"/g, "\\\"");
str = str.replace(/\t/g, "\\t");
str = str.replace(/\r/g, "\\r");
str = str.replace(/\n/g, '\\n');
return str;
}
visible: showTranslateCheckBox
style: CheckBoxStyle {
spacing: 8
indicator: Item {
implicitWidth: 15
implicitHeight: 15
x: 7
y: 1
Rectangle {
anchors.fill: parent
border.color: Theme.qmlDesignerBorderColor()
color: Theme.qmlDesignerBackgroundColorDarker()
opacity: control.hovered || control.pressed ? 1 : 0.75
}
Image {
x: 1
y: 1
width: 13
height: 13
source: "image://icons/tr"
opacity: control.checked ? 1 : 0.3;
}
}
}
property variant backendValueValueInternal: backendValue.value
onBackendValueValueInternalChanged: {
lineEdit.translationIndicator.checked = lineEdit.backendValue.isTranslated
}
onIsTranslatedChanged: {
lineEdit.translationIndicator.checked = lineEdit.backendValue.isTranslated
}
function escapeString(string) {
var str = string;
str = str.replace(/\\/g, "\\\\");
str.replace(/\"/g, "\\\"");
str = str.replace(/\t/g, "\\t");
str = str.replace(/\r/g, "\\r");
str = str.replace(/\n/g, '\\n');
return str;
}
}

View File

@@ -27,6 +27,7 @@ import QtQuick 2.1
import QtQuick.Controls 1.1 as Controls
import QtQuick.Layouts 1.0
import QtQuickDesignerTheme 1.0
import StudioTheme 1.0 as StudioTheme
Item {
id: section
@@ -54,6 +55,7 @@ Item {
color: Theme.color(Theme.PanelTextColorLight)
x: 22
font.bold: true
font.pixelSize: StudioTheme.Values.myFontSize
}
Image {

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** 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.1
import QtQuick.Controls 2.5
import HelperWidgets 2.0
import QtQuick.Controls.Private 1.0 // showing a ToolTip
Item {
property color selectedColor
property bool clickable : true
width: 200
height: 40
enabled: clickable
function addColorToPalette(colorCode)
{
paletteModel.addItem(colorCode)
}
Component {
id: colorItemDelegate
Rectangle {
id: backgroundColor
property var favorite : isFavorite
height: 27
width: 27
border.color: (backgroundColor.favorite ? "#ffd700" : "#555555")
border.width: (backgroundColor.favorite ? 2 : 1)
color: "white"
radius: 0
Rectangle {
id: colorRectangle
width: 25
height: 25
anchors.centerIn: parent
color: colorCode
border.color: "black"
border.width: 1
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if ((mouse.button === Qt.LeftButton) && clickable)
selectedColor = colorRectangle.color
}
onPressed: {
if (mouse.button === Qt.RightButton)
contextMenu.popup()
}
}
Menu {
id: contextMenu
modal: true
closePolicy: Popup.CloseOnPressOutside | Popup.CloseOnEscape
MenuItem {
text: (backgroundColor.favorite
? qsTr("Remove from Favorites")
: qsTr("Add to Favorites"))
onTriggered: {
paletteModel.toggleFavorite(index)
}
}
Overlay.modal: Rectangle {
color: "transparent"
}
}
}
}
SimpleColorPaletteModel { id: paletteModel }
ListView {
id: colorPaletteView
model: paletteModel
delegate: colorItemDelegate
orientation: Qt.Horizontal
anchors.fill: parent
clip: true
interactive: false
spacing: 2
}
}

View File

@@ -24,42 +24,77 @@
****************************************************************************/
import QtQuick 2.1
import QtQuick.Controls 1.1 as Controls
import QtQuick.Controls.Styles 1.1
import StudioControls 1.0 as StudioControls
Controls.SpinBox {
id: spinBox
Item {
id: wrapper
property color textColor: colorLogic.textColor
property variant backendValue;
property alias decimals: spinBox.decimals
property alias hasSlider: spinBox.hasSlider
implicitWidth: 74
property real minimumValue: 0.0
property real maximumValue: 99
property real stepSize: 1.0
ExtendedFunctionButton {
x: 4
anchors.verticalCenter: parent.verticalCenter
backendValue: spinBox.backendValue
visible: spinBox.enabled
property alias backendValue: spinBox.backendValue
width: 120
implicitHeight: spinBox.height
property bool __initialized: false
Component.onCompleted: {
wrapper.__initialized = true
convert("stepSize", stepSize)
convert("from", minimumValue)
convert("to", maximumValue)
}
ColorLogic {
id: colorLogic
backendValue: spinBox.backendValue
onValueFromBackendChanged: {
spinBox.value = valueFromBackend;
onStepSizeChanged: convert("stepSize", stepSize)
onMinimumValueChanged: convert("from", minimumValue)
onMaximumValueChanged: convert("to", maximumValue)
function convert(target, value) {
if (!wrapper.__initialized)
return
spinBox[target] = Math.round(value * spinBox.factor)
}
StudioControls.SpinBox {
id: spinBox
property real realValue: value / factor
property variant backendValue
property bool hasSlider: false
from: minimumValue * factor
to: maximumValue * factor
width: wrapper.width
ExtendedFunctionLogic {
id: extFuncLogic
backendValue: spinBox.backendValue
}
actionIndicator.icon.color: extFuncLogic.color
actionIndicator.icon.text: extFuncLogic.glyph
actionIndicator.onClicked: extFuncLogic.show()
ColorLogic {
id: colorLogic
backendValue: spinBox.backendValue
onValueFromBackendChanged: {
spinBox.value = valueFromBackend * spinBox.factor;
}
}
textColor: colorLogic.textColor
onCompressedValueModified: {
if (backendValue.value !== realValue)
backendValue.value = realValue;
}
}
property bool hasSlider: false
height: hasSlider ? 32 : implicitHeight
onValueChanged: {
if (backendValue.value !== value)
backendValue.value = value;
}
style: CustomSpinBoxStyle {
}
}

View File

@@ -27,6 +27,7 @@ import QtQuick 2.1
import QtQuick.Controls 1.0 as Controls
import QtQuick.Controls.Styles 1.1
import QtQuickDesignerTheme 1.0
import StudioTheme 1.0 as StudioTheme
Controls.TabView {
id: root
@@ -42,6 +43,7 @@ Controls.TabView {
Text {
id: text
font.bold: true
font.pixelSize: StudioTheme.Values.myFontSize
anchors.centerIn: parent
anchors.verticalCenterOffset: -1
text: styleData.title

View File

@@ -9,6 +9,7 @@ CheckBox 2.0 CheckBox.qml
ColorButton 2.0 ColorButton.qml
ColorCheckButton 2.0 ColorCheckButton.qml
ColorEditor 2.0 ColorEditor.qml
ColorLine 2.0 ColorLine.qml
ColorLogic 2.0 ColorLogic.qml
ComboBox 2.0 ComboBox.qml
CustomCheckBoxStyle 2.0 CustomCheckBoxStyle.qml
@@ -33,6 +34,7 @@ ScrollView 2.0 ScrollView.qml
SecondColumnLayout 2.0 SecondColumnLayout.qml
Section 2.0 Section.qml
SectionLayout 2.0 SectionLayout.qml
SimpleColorPalette 2.0 SimpleColorPalette.qml
DoubleSpinBox 2.0 DoubleSpinBox.qml
SpinBox 2.0 SpinBox.qml
StandardTextSection 2.0 StandardTextSection.qml

View File

@@ -0,0 +1,119 @@
/****************************************************************************
**
** 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 backgroundVisible: buttonBackground.visible
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 // TODO Decision pending. Focus for AbstractButtons?
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
}
}
]
}

View File

@@ -0,0 +1,132 @@
/****************************************************************************
**
** 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 alias icon: actionIndicatorIcon
property bool hover: false
property bool pressed: false
color: StudioTheme.Values.themeControlBackground
border.color: StudioTheme.Values.themeControlOutline
state: "default"
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
}
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.activeFocus && !myControl.drag
PropertyChanges {
target: actionIndicator
color: StudioTheme.Values.themeControlBackground
border.color: StudioTheme.Values.themeControlOutline
}
},
State {
name: "hovered"
when: actionIndicator.hover && !actionIndicator.pressed
&& !myControl.activeFocus && !myControl.drag
PropertyChanges {
target: actionIndicatorIcon
scale: 1.2
}
},
State {
name: "globalHover"
when: myControl.hover && !actionIndicator.hover
&& !actionIndicator.pressed && !myControl.activeFocus
&& !myControl.drag
PropertyChanges {
target: actionIndicator
color: StudioTheme.Values.themeHoverHighlight
border.color: StudioTheme.Values.themeControlOutline
}
},
State {
name: "edit"
when: myControl.activeFocus
PropertyChanges {
target: actionIndicator
color: StudioTheme.Values.themeFocusEdit
border.color: StudioTheme.Values.themeInteraction
}
},
State {
name: "drag"
when: myControl.drag
PropertyChanges {
target: actionIndicator
color: StudioTheme.Values.themeFocusDrag
border.color: StudioTheme.Values.themeInteraction
}
},
State {
name: "disabled"
when: !myControl.enabled
PropertyChanges {
target: actionIndicator
color: StudioTheme.Values.themeControlBackgroundDisabled
border.color: StudioTheme.Values.themeControlOutlineDisabled
}
PropertyChanges {
target: actionIndicatorIcon
color: StudioTheme.Values.themeTextColorDisabled
}
}
]
}

View File

@@ -0,0 +1,39 @@
/****************************************************************************
**
** 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 checkable: myAbstractButton.checkable
AbstractButton {
id: myAbstractButton
}
}

View File

@@ -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 {
}

View File

@@ -0,0 +1,52 @@
/****************************************************************************
**
** 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 actionIcon: actionIndicator.icon
//property bool hover: myCheckBox.hovered // TODO
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
}

View File

@@ -0,0 +1,160 @@
/****************************************************************************
**
** 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 // TODO two underscores
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
height: StudioTheme.Values.height
width: StudioTheme.Values.height * 5
spacing: StudioTheme.Values.checkBoxSpacing
hoverEnabled: true
activeFocusOnTab: false // TODO Decision pending. Focus for CheckBoxes?
contentItem: T.Label {
id: checkBoxLabel
leftPadding: 0
rightPadding: 0
width: 20 // TODO Not working
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
text: myCheckBox.text
font: myCheckBox.font
color: StudioTheme.Values.themeTextColor
}
ActionIndicator {
id: actionIndicator
myControl: myCheckBox // TODO global hover issue. Can be solved with extra property in ActionIndicator
x: checkBoxLabel.visible ? checkBoxLabel.contentWidth
+ (myCheckBox.spacing
* StudioTheme.Values.scaleFactor) : 0 // TODO scale factor
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: checkBoxIcon
x: (parent.width - width) / 2
y: (parent.height - 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
}
/*
// Tristate only
Rectangle {
x: (parent.width - width) / 2
y: (parent.height - height) / 2
width: 16
height: 3
color: myCheckBox.palette.text
visible: myCheckBox.checkState === Qt.PartiallyChecked
}
*/
}
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
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: checkBoxIcon
color: StudioTheme.Values.themeTextColorDisabled
}
PropertyChanges {
target: checkBoxLabel
color: StudioTheme.Values.themeTextColorDisabled
}
}
]
}

View File

@@ -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.activeFocus
&& !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.activeFocus
&& !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.activeFocus && !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
}
}
]
}

View File

@@ -0,0 +1,256 @@
/****************************************************************************
**
** 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 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 (!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
width: myComboBox.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: ScrollBar {
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.activeFocus
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.activeFocus && !myComboBox.editable
PropertyChanges {
target: myComboBox
wheelEnabled: true
}
PropertyChanges {
target: comboBoxInput
focus: true
}
},
State {
name: "edit"
when: myComboBox.activeFocus && 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
}
}

View File

@@ -0,0 +1,159 @@
/****************************************************************************
**
** 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: false
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.popup.open()
myControl.forceActiveFocus()
}
} 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.activeFocus
&& !mouseArea.containsMouse && !myControl.drag
PropertyChanges {
target: textInputArea
color: StudioTheme.Values.themeControlBackground
border.color: StudioTheme.Values.themeControlOutline
}
PropertyChanges {
target: mouseArea
cursorShape: Qt.PointingHandCursor
}
},
State {
name: "hovered"
when: myControl.hover && !textInput.activeFocus && !myControl.drag
PropertyChanges {
target: textInputArea
color: StudioTheme.Values.themeHoverHighlight
border.color: StudioTheme.Values.themeControlOutline
}
},
State {
name: "focus"
when: textInput.activeFocus && !myControl.editable
PropertyChanges {
target: textInputArea
color: StudioTheme.Values.themeFocusEdit
border.color: StudioTheme.Values.themeInteraction
}
},
State {
name: "edit"
when: textInput.activeFocus && 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
}
}
]
}

View File

@@ -0,0 +1,92 @@
/****************************************************************************
**
** 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.Controls 2.12 as Controls2
Menu {
id: contextMenu
property Item myTextEdit
Controls2.Action {
text: "Undo"
enabled: myTextEdit.canUndo
onTriggered: myTextEdit.undo()
shortcut: StandardKey.Undo
}
Controls2.Action {
text: "Redo"
enabled: myTextEdit.canRedo
onTriggered: myTextEdit.redo()
shortcut: StandardKey.Redo
}
MenuSeparator {
}
Controls2.Action {
text: "Copy"
enabled: myTextEdit.selectedText !== ""
onTriggered: myTextEdit.copy()
shortcut: StandardKey.Copy
}
Controls2.Action {
text: "Cut"
enabled: myTextEdit.selectedText !== "" && !myTextEdit.readOnly
onTriggered: myTextEdit.cut()
shortcut: StandardKey.Cut
}
Controls2.Action {
text: "Paste"
enabled: myTextEdit.canPaste
onTriggered: myTextEdit.paste()
shortcut: StandardKey.Paste
}
Controls2.Action {
text: "Delete"
enabled: myTextEdit.selectedText !== ""
onTriggered: myTextEdit.remove(myTextEdit.selectionStart,
myTextEdit.selectionEnd)
shortcut: StandardKey.Delete
}
Controls2.Action {
text: "Clear"
enabled: myTextEdit.text !== ""
onTriggered: myTextEdit.clear()
shortcut: StandardKey.DeleteCompleteLine
}
MenuSeparator {
}
Controls2.Action {
text: "Select All"
enabled: myTextEdit.text !== ""
&& myTextEdit.selectedText !== myTextEdit.text
onTriggered: myTextEdit.selectAll()
shortcut: StandardKey.SelectAll
}
}

View File

@@ -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
}

View File

@@ -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 {
}

View File

@@ -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.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
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
}
}

View File

@@ -0,0 +1,88 @@
/****************************************************************************
**
** 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 {
id: menuItem
width: control.menu.width
height: StudioTheme.Values.height
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 // TODO
implicitHeight: StudioTheme.Values.height
x: StudioTheme.Values.border
y: StudioTheme.Values.border
width: control.width - (StudioTheme.Values.border * 2)
height: control.height - (StudioTheme.Values.border * 2)
color: control.down ? control.palette.midlight : control.highlighted ? StudioTheme.Values.themeInteraction : "transparent"
}
}

View File

@@ -0,0 +1,46 @@
/****************************************************************************
**
** 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
verticalPadding: padding
contentItem: Rectangle {
implicitWidth: 10
implicitHeight: StudioTheme.Values.border
color: StudioTheme.Values.themeControlOutline
}
}

View File

@@ -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
}
}

View File

@@ -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: ScrollBar {
id: verticalScrollBar
parent: control
x: control.width - width - StudioTheme.Values.border
y: StudioTheme.Values.border
height: control.availableHeight - 2 * StudioTheme.Values.border
- (bothVisible ? horizontalThickness : 0)
active: control.ScrollBar.horizontal.active
}
ScrollBar.horizontal: ScrollBar {
id: horizontalScrollBar
parent: control
x: StudioTheme.Values.border
y: control.height - height - StudioTheme.Values.border
width: control.availableWidth - 2 * StudioTheme.Values.border
- (bothVisible ? verticalThickness : 0)
active: control.ScrollBar.vertical.active
}
}

View File

@@ -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
}

View File

@@ -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
}
}
]
}

View File

@@ -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
}
*/
}

View File

@@ -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
}

View File

@@ -0,0 +1,293 @@
/****************************************************************************
**
** 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 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.activeFocus
PropertyChanges {
target: slider
wheelEnabled: false
}
},
State {
name: "hovered"
when: slider.enabled && slider.hover && !slider.activeFocus
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.activeFocus
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
}
}
]
}

View File

@@ -0,0 +1,89 @@
/****************************************************************************
**
** 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: {
myControl.value = value
myControl.valueModified()
}
}
}

View File

@@ -0,0 +1,343 @@
/****************************************************************************
**
** 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 textColor: spinBoxInput.color
property alias actionIndicator: actionIndicator
property int decimals: 0
property int factor: Math.pow(10, decimals)
property real defaultStepSize: 1
property real minStepSize: 1
property real maxStepSize: 10
property bool edit: false
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) / factor
top: Math.max(mySpinBox.from, mySpinBox.to) / factor
}
IntValidator {
id: intValidator
locale: mySpinBox.locale.name
bottom: Math.min(mySpinBox.from, mySpinBox.to)
top: Math.max(mySpinBox.from, mySpinBox.to)
}
Connections {
target: spinBoxInput
onActiveFocusChanged: mySpinBox.edit = spinBoxInput.activeFocus
}
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 + (actionIndicator.visible ? 0 : StudioTheme.Values.border)
y: StudioTheme.Values.border
width: spinBoxIndicatorVisible ? __spinBoxIndicatorWidth : 0
height: spinBoxIndicatorVisible ? __spinBoxIndicatorHeight : 0
}
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
}
contentItem: SpinBoxInput {
id: spinBoxInput
myControl: mySpinBox
}
background: Rectangle {
id: spinBoxBackground
color: StudioTheme.Values.themeControlOutline
border.color: StudioTheme.Values.themeControlOutline
border.width: StudioTheme.Values.border
width: mySpinBox.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 / factor).toLocaleString(locale, 'f',
mySpinBox.decimals)
}
valueFromText: function (text, locale) {
return Number.fromLocaleString(locale, text) * factor
}
states: [
State {
name: "default"
when: mySpinBox.enabled && !mySpinBox.hover
&& !mySpinBox.activeFocus && !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: spinBoxInput.activeFocus
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
}
}
]
onActiveFocusChanged: {
if (mySpinBox.activeFocus)
// QTBUG-75862 && mySpinBox.focusReason === Qt.TabFocusReason)
spinBoxInput.selectAll()
if (sliderPopup.opened && !activeFocus)
sliderPopup.close()
}
onFocusChanged: {
// 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 * factor,
mySpinBox.validator.top * factor)
else
mySpinBox.value = valueFromText(spinBoxInput.text, mySpinBox.locale)
if (spinBoxInput.text !== mySpinBox.displayText)
spinBoxInput.text = mySpinBox.displayText
if (mySpinBox.value !== currValue)
mySpinBox.valueModified()
}
onDisplayTextChanged: {
spinBoxInput.text = mySpinBox.displayText
}
Timer {
id: myTimer
repeat: false
running: false
interval: 100
onTriggered: mySpinBox.compressedValueModified()
}
onValueModified: myTimer.restart()
Keys.onPressed: {
if (event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
event.accepted = true
mySpinBox.stepSize = defaultStepSize
if (event.modifiers & Qt.ControlModifier)
mySpinBox.stepSize = minStepSize
if (event.modifiers & Qt.ShiftModifier)
mySpinBox.stepSize = maxStepSize
var val = mySpinBox.valueFromText(spinBoxInput.text,
mySpinBox.locale)
if (mySpinBox.value !== val)
mySpinBox.value = val
var curValue = mySpinBox.value
if (event.key === Qt.Key_Up)
mySpinBox.increase()
else
mySpinBox.decrease()
if (curValue !== mySpinBox.value)
mySpinBox.valueModified()
}
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) {
var currValue = mySpinBox.value
if (!spinBoxInput.spinBoxInput)
mySpinBox.value = clamp(valueFromText(spinBoxInput.text,
mySpinBox.locale),
mySpinBox.validator.bottom * factor,
mySpinBox.validator.top * factor)
else
mySpinBox.value = valueFromText(spinBoxInput.text,
mySpinBox.locale)
if (spinBoxInput.text !== mySpinBox.displayText)
spinBoxInput.text = mySpinBox.displayText
if (mySpinBox.value !== currValue)
mySpinBox.valueModified()
}
}
function clamp(v, lo, hi) {
if (v < lo || v > hi)
return Math.min(Math.max(lo, v), hi)
return v
}
}

View File

@@ -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.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: 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
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
}
PropertyChanges {
target: spinBoxIndicatorIcon
color: StudioTheme.Values.themeTextColorDisabled
}
}
]
}

View File

@@ -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: false
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 foucs 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 curValue = myControl.value
myControl.value = initialValue + translation.x
if (curValue !== 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 curValue = myControl.value
myControl.value += wheel.angleDelta.y / 120
if (curValue !== myControl.value)
myControl.valueModified()
}
}
states: [
State {
name: "default"
when: myControl.enabled && !textInput.activeFocus
&& !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.activeFocus && !myControl.drag
PropertyChanges {
target: textInputArea
color: StudioTheme.Values.themeHoverHighlight
border.color: StudioTheme.Values.themeControlOutline
}
},
State {
name: "edit"
when: textInput.activeFocus
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
}
}
]
}

View File

@@ -0,0 +1,144 @@
/****************************************************************************
**
** 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: relativePopupX
y: myTextField.height - StudioTheme.Values.border
width: popupWidth
height: scrollView.height
background: Rectangle {
color: StudioTheme.Values.themeFocusEdit
border.color: StudioTheme.Values.themeInteraction
border.width: StudioTheme.Values.border
}
contentItem: ScrollView {
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) {
if (popup.opened)
popup.close()
else
myTextField.focus = false
}
if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter)
&& !popup.opened) {
popup.open()
textAreaPopup.forceActiveFocus()
}
}
}

View File

@@ -0,0 +1,177 @@
/****************************************************************************
**
** 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: false
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
height: StudioTheme.Values.height
implicitHeight: StudioTheme.Values.height
width: StudioTheme.Values.height * 5
leftPadding: StudioTheme.Values.inputHorizontalPadding + actionIndicator.width
- (actionIndicatorVisible ? StudioTheme.Values.border : 0)
rightPadding: StudioTheme.Values.inputHorizontalPadding + translationIndicator.width
- (translationIndicatorVisible ? StudioTheme.Values.border : 0)
onActiveFocusChanged: myTextField.edit = myTextField.activeFocus
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
anchors.fill: parent
}
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.activeFocus
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.activeFocus
PropertyChanges {
target: textFieldBackground
color: StudioTheme.Values.themeHoverHighlight
border.color: StudioTheme.Values.themeControlOutline
}
},
State {
name: "edit"
when: myTextField.activeFocus
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
}
}

View File

@@ -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
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.themeFocusDrag // TODO
color: "red"
}
},
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
}
}
]
}

View File

@@ -0,0 +1,29 @@
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
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
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
TextField 1.0 TextField.qml
TranslationIndicator 1.0 TranslationIndicator.qml

View File

@@ -0,0 +1,75 @@
/****************************************************************************
**
** 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 anchorBottom: "\u0022"
readonly property string anchorFill: "\u0023"
readonly property string anchorLeft: "\u0024"
readonly property string anchorRight: "\u0025"
readonly property string anchorTop: "\u0026"
readonly property string centerHorizontal: "\u0027"
readonly property string centerVertical: "\u0028"
readonly property string closeCross: "\u0029"
readonly property string fontStyleBold: "\u002A"
readonly property string fontStyleItalic: "\u002B"
readonly property string fontStyleStrikethrough: "\u002C"
readonly property string fontStyleUnderline: "\u002D"
readonly property string textAlignCenter: "\u002E"
readonly property string textAlignLeft: "\u002F"
readonly property string textAlignRight: "\u0030"
readonly property string tickIcon: "\u0031"
readonly property string upDownIcon: "\u0032"
readonly property string upDownSquare2: "\u0033"
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"
}

View File

@@ -0,0 +1,124 @@
/****************************************************************************
**
** 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
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: sliderControlSize * scaleFactor
property real spinControlIconSize: 8
property real spinControlIconSizeMulti: spinControlIconSize * 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: 6 // TODO Does look strange with scale factor applied
property real columnWidth: 225 + (175 * (values.scaleFactor * 2))
property real marginTopBottom: 4
property real border: 1
property real maxComboBoxPopupHeight: 300
property real maxTextAreaPopupHeight: 150
property real contextMenuLabelSpacing: 30
property real contextMenuHorizontalPadding: 6
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: "#606060"
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"
}

View File

@@ -0,0 +1,2 @@
singleton Values 1.0 Values.qml
singleton Constants 1.0 Constants.qml

View File

@@ -228,8 +228,7 @@ public:
if (fileName != doc->fileName())
return;
QString message;
message.vsprintf(format, ap);
const QString message = QString::vasprintf(format, ap);
#ifndef DO_NOT_DUMP_ALL_PARSER_ERRORS
{

View File

@@ -348,8 +348,10 @@ void SshConnection::doConnectToHost()
.arg(sshBinary.toUserOutput()));
return;
}
if (!d->sharingEnabled)
if (!d->sharingEnabled) {
emitConnected();
return;
}
d->masterSocketDir.reset(new QTemporaryDir);
if (!d->masterSocketDir->isValid()) {
emitError(tr("Cannot establish SSH connection: Failed to create temporary "

View File

@@ -117,9 +117,6 @@ void BoostTestOutputReader::sendCompleteInformation()
void BoostTestOutputReader::handleMessageMatch(const QRegularExpressionMatch &match)
{
if (m_result != ResultType::Invalid)
sendCompleteInformation();
m_fileName = constructSourceFilePath(m_buildDir, match.captured(1));
m_lineNumber = match.captured(2).toInt();
@@ -176,6 +173,9 @@ void BoostTestOutputReader::handleMessageMatch(const QRegularExpressionMatch &ma
m_result = ResultType::Skip;
m_description = content;
}
if (m_result != ResultType::Invalid) // we got a new result
sendCompleteInformation();
}
void BoostTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLine)

View File

@@ -99,7 +99,10 @@ signals:
protected:
void setupFilterUi(const QString &historyKey);
QString filterText() const;
bool filterUsesRegexp() const { return m_filterRegexp; }
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
void setFilteringEnabled(bool enable);
QWidget *filterWidget() const { return m_filterOutputLineEdit; }
void setZoomButtonsEnabled(bool enabled);
@@ -118,7 +121,7 @@ private:
QAction *m_filterActionCaseSensitive = nullptr;
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
bool m_filterRegexp = false;
bool m_filterCaseSensitive = false;
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
};
} // namespace Core

View File

@@ -146,7 +146,7 @@ bool MessageOutputWindow::canNavigate() const
void MessageOutputWindow::updateFilter()
{
m_widget->setFilterText(filterText());
m_widget->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp());
}
} // namespace Internal

View File

@@ -195,6 +195,7 @@ void IOutputPane::filterOutputButtonClicked()
void IOutputPane::setRegularExpressions(bool regularExpressions)
{
m_filterRegexp = regularExpressions;
updateFilter();
}
Id IOutputPane::filterRegexpActionId() const
@@ -209,7 +210,8 @@ Id IOutputPane::filterCaseSensitivityActionId() const
void IOutputPane::setCaseSensitive(bool caseSensitive)
{
m_filterCaseSensitive = caseSensitive;
m_filterCaseSensitivity = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
updateFilter();
}
namespace Internal {

View File

@@ -284,15 +284,16 @@ void OutputWindow::setHighlightTextColor(const QColor &textColor)
d->highlightTextColor = textColor;
}
QString OutputWindow::filterText() const
{
return d->filterText;
}
void OutputWindow::setFilterText(const QString &filterText)
void OutputWindow::updateFilterProperties(const QString &filterText,
Qt::CaseSensitivity caseSensitivity, bool isRegexp)
{
FilterModeFlags flags;
flags.setFlag(FilterModeFlag::CaseSensitive, caseSensitivity == Qt::CaseSensitive)
.setFlag(FilterModeFlag::RegExp, isRegexp);
if (d->filterMode == flags && d->filterText == filterText)
return;
d->lastFilteredBlock = {};
if (d->filterText != filterText) {
d->lastFilteredBlock = {};
const bool filterTextWasEmpty = d->filterText.isEmpty();
d->filterText = filterText;
@@ -313,23 +314,9 @@ void OutputWindow::setFilterText(const QString &filterText)
setPalette(pal);
setReadOnly(true);
}
filterNewContent();
}
}
OutputWindow::FilterModeFlags OutputWindow::filterMode() const
{
return d->filterMode;
}
void OutputWindow::setFilterMode(OutputWindow::FilterModeFlag filterMode, bool enabled)
{
if (d->filterMode.testFlag(filterMode) != enabled) {
d->filterMode.setFlag(filterMode, enabled);
d->lastFilteredBlock = {};
filterNewContent();
}
d->filterMode = flags;
filterNewContent();
}
void OutputWindow::filterNewContent()

View File

@@ -79,11 +79,7 @@ public:
void setHighlightBgColor(const QColor &bgColor);
void setHighlightTextColor(const QColor &textColor);
QString filterText() const;
void setFilterText(const QString &filterText);
FilterModeFlags filterMode() const;
void setFilterMode(FilterModeFlag filterMode, bool enabled);
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity, bool regexp);
signals:
void wheelZoom();

View File

@@ -161,6 +161,9 @@ public:
QList<QPointer<Perspective>> m_perspectives;
QSet<QString> m_persistentChangedDocks;
QHash<QString, QByteArray> m_lastPerspectiveStates;
QHash<QString, QByteArray> m_lastTypePerspectiveStates;
};
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
@@ -431,10 +434,11 @@ void DebuggerMainWindow::restorePersistentSettings()
qCDebug(perspectivesLog) << "RESTORE PERSISTENT";
QSettings *settings = ICore::settings();
settings->beginGroup(MAINWINDOW_KEY);
const bool res = theMainWindow->restoreState(settings->value(STATE_KEY).toByteArray(),
SettingsVersion);
if (!res)
qCDebug(perspectivesLog) << "NO READABLE PERSISTENT SETTINGS FOUND, ASSUMING NEW CLEAN SETTINGS";
const QHash<QString, QVariant> states = settings->value(STATE_KEY).toHash();
theMainWindow->d->m_lastTypePerspectiveStates.clear();
for (const QString &type : states.keys())
theMainWindow->d->m_lastTypePerspectiveStates.insert(type, states.value(type).toByteArray());
theMainWindow->setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool());
theMainWindow->showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool());
@@ -497,10 +501,14 @@ void DebuggerMainWindow::savePersistentSettings()
theMainWindow->d->m_persistentChangedDocks = changedDocks;
qCDebug(perspectivesLog) << "CHANGED DOCKS:" << changedDocks;
QVariantHash states;
for (const QString &type : theMainWindow->d->m_lastTypePerspectiveStates.keys())
states.insert(type, QVariant::fromValue(theMainWindow->d->m_lastTypePerspectiveStates.value(type)));
QSettings *settings = ICore::settings();
settings->beginGroup(MAINWINDOW_KEY);
settings->setValue(CHANGED_DOCK_KEY, QStringList(changedDocks.toList()));
settings->setValue(STATE_KEY, theMainWindow->saveState(SettingsVersion));
settings->setValue(STATE_KEY, states);
settings->setValue(AUTOHIDE_TITLEBARS_KEY, theMainWindow->autoHideTitleBars());
settings->setValue(SHOW_CENTRALWIDGET_KEY, theMainWindow->isCentralWidgetShown());
settings->endGroup();
@@ -941,6 +949,13 @@ void PerspectivePrivate::restoreLayout()
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
}
}
QByteArray state;
if (theMainWindow->d->m_lastTypePerspectiveStates.contains(settingsId()))
state = theMainWindow->d->m_lastTypePerspectiveStates.value(settingsId());
if (theMainWindow->d->m_lastPerspectiveStates.contains(m_id))
state = theMainWindow->d->m_lastPerspectiveStates.value(m_id);
theMainWindow->restoreState(state);
}
void PerspectivePrivate::saveLayout()
@@ -960,6 +975,8 @@ void PerspectivePrivate::saveLayout()
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
}
}
theMainWindow->d->m_lastPerspectiveStates.insert(m_id, theMainWindow->saveState());
theMainWindow->d->m_lastTypePerspectiveStates.insert(settingsId(), theMainWindow->saveState());
}
QString PerspectivePrivate::settingsId() const

View File

@@ -372,8 +372,10 @@ void AppOutputPane::setFocus()
void AppOutputPane::updateFilter()
{
const int index = currentIndex();
if (index != -1)
m_runControlTabs.at(index).window->setFilterText(filterText());
if (index != -1) {
m_runControlTabs.at(index).window->updateFilterProperties(
filterText(), filterCaseSensitivity(), filterUsesRegexp());
}
}
void AppOutputPane::createNewOutputWindow(RunControl *rc)
@@ -703,7 +705,8 @@ void AppOutputPane::tabChanged(int i)
const int index = indexOf(m_tabWidget->widget(i));
if (i != -1 && index != -1) {
const RunControlTab &controlTab = m_runControlTabs[index];
controlTab.window->setFilterText(filterText());
controlTab.window->updateFilterProperties(filterText(), filterCaseSensitivity(),
filterUsesRegexp());
enableButtons(controlTab.runControl);
} else {
enableDefaultButtons();

View File

@@ -356,7 +356,8 @@ void CompileOutputWindow::setSettings(const CompileOutputSettings &settings)
void CompileOutputWindow::updateFilter()
{
m_outputWindow->setFilterText(filterText());
m_outputWindow->updateFilterProperties(filterText(), filterCaseSensitivity(),
filterUsesRegexp());
}
void CompileOutputWindow::loadSettings()

View File

@@ -141,11 +141,6 @@ WorkingDirectoryAspect::WorkingDirectoryAspect()
void WorkingDirectoryAspect::addToConfigurationLayout(QFormLayout *layout)
{
QTC_CHECK(!m_chooser);
m_resetButton = new QToolButton(layout->parentWidget());
m_resetButton->setToolTip(tr("Reset to Default"));
m_resetButton->setIcon(Utils::Icons::RESET.icon());
connect(m_resetButton.data(), &QAbstractButton::clicked, this, &WorkingDirectoryAspect::resetPath);
m_chooser = new PathChooser(layout->parentWidget());
m_chooser->setHistoryCompleter(settingsKey());
m_chooser->setExpectedKind(Utils::PathChooser::Directory);
@@ -158,6 +153,10 @@ void WorkingDirectoryAspect::addToConfigurationLayout(QFormLayout *layout)
m_resetButton->setEnabled(m_workingDirectory != m_defaultWorkingDirectory);
});
m_resetButton = new QToolButton(layout->parentWidget());
m_resetButton->setToolTip(tr("Reset to Default"));
m_resetButton->setIcon(Utils::Icons::RESET.icon());
connect(m_resetButton.data(), &QAbstractButton::clicked, this, &WorkingDirectoryAspect::resetPath);
m_resetButton->setEnabled(m_workingDirectory != m_defaultWorkingDirectory);
if (m_envAspect) {

View File

@@ -341,6 +341,25 @@ void TaskFilterModel::setFilterIncludesWarnings(bool b)
invalidateFilter();
}
void TaskFilterModel::updateFilterProperties(const QString &filterText,
Qt::CaseSensitivity caseSensitivity, bool isRegexp)
{
if (filterText == m_filterText && m_filterCaseSensitivity == caseSensitivity
&& m_filterStringIsRegexp == isRegexp) {
return;
}
m_filterText = filterText;
m_filterCaseSensitivity = caseSensitivity;
m_filterStringIsRegexp = isRegexp;
if (m_filterStringIsRegexp) {
m_filterRegexp.setPattern(m_filterText);
m_filterRegexp.setPatternOptions(m_filterCaseSensitivity == Qt::CaseInsensitive
? QRegularExpression::CaseInsensitiveOption
: QRegularExpression::NoPatternOption);
}
invalidateFilter();
}
bool TaskFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent);
@@ -362,9 +381,18 @@ bool TaskFilterModel::filterAcceptsTask(const Task &task) const
break;
}
if (m_categoryIds.contains(task.category))
if (accept && m_categoryIds.contains(task.category))
accept = false;
if (accept && !m_filterText.isEmpty()) {
const auto accepts = [this](const QString &s) {
return m_filterStringIsRegexp ? m_filterRegexp.isValid() && s.contains(m_filterRegexp)
: s.contains(m_filterText, m_filterCaseSensitivity);
};
if (!accepts(task.file.toString()) && !accepts(task.description))
accept = false;
}
return accept;
}

View File

@@ -28,6 +28,7 @@
#include <QSortFilterProxyModel>
#include <QIcon>
#include <QRegularExpression>
#include "task.h"
@@ -143,6 +144,9 @@ public:
bool hasFile(const QModelIndex &index) const
{ return taskModel()->hasFile(mapToSource(index)); }
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity,
bool isRegex);
private:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
bool filterAcceptsTask(const Task &task) const;
@@ -151,7 +155,11 @@ private:
bool m_includeUnknowns;
bool m_includeWarnings;
bool m_includeErrors;
bool m_filterStringIsRegexp = false;
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
QList<Core::Id> m_categoryIds;
QString m_filterText;
QRegularExpression m_filterRegexp;
};
} // namespace Internal

View File

@@ -289,6 +289,9 @@ TaskWindow::TaskWindow() : d(std::make_unique<TaskWindowPrivate>())
d->m_categoriesButton->setMenu(d->m_categoriesMenu);
setupFilterUi("IssuesPane.Filter");
setFilteringEnabled(true);
TaskHub *hub = TaskHub::instance();
connect(hub, &TaskHub::categoryAdded, this, &TaskWindow::addCategory);
connect(hub, &TaskHub::taskAdded, this, &TaskWindow::addTask);
@@ -355,7 +358,7 @@ void TaskWindow::delayedInitialization()
QList<QWidget*> TaskWindow::toolBarWidgets() const
{
return {d->m_filterWarningsButton, d->m_categoriesButton};
return {d->m_filterWarningsButton, d->m_categoriesButton, filterWidget()};
}
QWidget *TaskWindow::outputWidget(QWidget *)
@@ -664,6 +667,11 @@ void TaskWindow::goToPrev()
triggerDefaultHandler(currentIndex);
}
void TaskWindow::updateFilter()
{
d->m_filter->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp());
}
bool TaskWindow::canNavigate() const
{
return true;

View File

@@ -82,6 +82,8 @@ signals:
void tasksCleared();
private:
void updateFilter() override;
void addCategory(Core::Id categoryId, const QString &displayName, bool visible);
void addTask(const ProjectExplorer::Task &task);
void removeTask(const ProjectExplorer::Task &task);

View File

@@ -181,7 +181,7 @@ void GradientModel::addGradient()
setupModel();
if (m_gradientTypeName != "Gradient")
QTimer::singleShot(100, [this](){ view()->resetPuppet(); }); /*Unfortunately required */
resetPuppet(); /*Unfortunately required */
emit hasGradientChanged();
emit gradientTypeChanged();
}
@@ -437,6 +437,11 @@ QmlDesigner::AbstractView *GradientModel::view() const
return m_itemNode.view();
}
void GradientModel::resetPuppet()
{
QTimer::singleShot(1000, [this]() { view()->resetPuppet(); });
}
QmlDesigner::ModelNode GradientModel::createGradientNode()
{
QByteArray fullTypeName = m_gradientTypeName.toUtf8();
@@ -534,19 +539,20 @@ void GradientModel::setPresetByStops(const QList<qreal> &stopsPositions,
QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(
QByteArrayLiteral("GradientModel::setCustomPreset"));
//delete an old gradient without rewriter transaction
deleteGradientNode(false);
//create a new gradient:
if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
try {
if (m_gradientTypeName != "Gradient")
ensureShapesImport();
QmlDesigner::ModelNode gradientNode = createGradientNode();
m_itemNode.modelNode()
.nodeProperty(gradientPropertyName().toUtf8())
.reparentHere(gradientNode);
//create stops and give them positions and colors based on value
for (int i = 0; i < stopsCount; i++) {
QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
gradientStopNode.variantProperty("position").setValue(stopsPositions.at(i));
@@ -560,6 +566,9 @@ void GradientModel::setPresetByStops(const QList<qreal> &stopsPositions,
}
setupModel();
if (m_gradientTypeName != "Gradient")
resetPuppet(); /*Unfortunately required */
emit hasGradientChanged();
emit gradientTypeChanged();
}
@@ -586,3 +595,16 @@ void GradientModel::savePreset()
items.append(item);
GradientPresetCustomListModel::storePresets(filename, items);
}
void GradientModel::updateGradient()
{
QList<qreal> stops;
QList<QString> colors;
int stopsCount = rowCount();
for (int i = 0; i < stopsCount; i++) {
stops.append(getPosition(i));
colors.append(getColor(i).name(QColor::HexArgb));
}
setPresetByStops(stops, colors, stopsCount);
}

View File

@@ -77,6 +77,8 @@ public:
Q_INVOKABLE void savePreset();
Q_INVOKABLE void updateGradient();
signals:
void anchorBackendChanged();
void hasGradientChanged();
@@ -106,6 +108,7 @@ private:
void setupGradientProperties(const QmlDesigner::ModelNode &gradient);
QmlDesigner::Model *model() const;
QmlDesigner::AbstractView *view() const;
void resetPuppet();
};
QML_DECLARE_TYPE(GradientModel)

View File

@@ -15,7 +15,10 @@ SOURCES += propertyeditorview.cpp \
gradientpresetitem.cpp \
gradientpresetlistmodel.cpp \
gradientpresetdefaultlistmodel.cpp \
gradientpresetcustomlistmodel.cpp
gradientpresetcustomlistmodel.cpp \
simplecolorpalette.cpp \
simplecolorpalettemodel.cpp \
simplecolorpalettesingleton.cpp
HEADERS += propertyeditorview.h \
qmlanchorbindingproxy.h \
@@ -32,6 +35,9 @@ HEADERS += propertyeditorview.h \
gradientpresetitem.h \
gradientpresetlistmodel.h \
gradientpresetdefaultlistmodel.h \
gradientpresetcustomlistmodel.h
gradientpresetcustomlistmodel.h \
simplecolorpalette.h \
simplecolorpalettemodel.h \
simplecolorpalettesingleton.h
QT += qml quick

View File

@@ -40,6 +40,7 @@
#include <coreplugin/icore.h>
#include <qmljs/qmljssimplereader.h>
#include <utils/qtcassert.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
@@ -281,13 +282,17 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
// model node
m_backendModelNode.setup(qmlObjectNode.modelNode());
context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
// className
auto valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className"))));
if (!valueObject)
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
valueObject->setName("className");
valueObject->setModelNode(qmlObjectNode.modelNode());
valueObject->setValue(qmlObjectNode.modelNode().simplifiedTypeName());
valueObject->setValue(m_backendModelNode.simplifiedTypeName());
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
m_backendValuesPropertyMap.insert(QLatin1String("className"), QVariant::fromValue(valueObject));
@@ -296,7 +301,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
if (!valueObject)
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
valueObject->setName("id");
valueObject->setValue(qmlObjectNode.id());
valueObject->setValue(m_backendModelNode.nodeId());
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
m_backendValuesPropertyMap.insert(QLatin1String("id"), QVariant::fromValue(valueObject));
@@ -310,10 +315,6 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
qCInfo(propertyEditorBenchmark) << "anchors:" << time.elapsed();
// model node
m_backendModelNode.setup(qmlObjectNode.modelNode());
context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
qCInfo(propertyEditorBenchmark) << "context:" << time.elapsed();
contextObject()->setSpecificsUrl(qmlSpecificsFile);
@@ -402,7 +403,7 @@ QString PropertyEditorQmlBackend::propertyEditorResourcesPath() {
QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
const NodeMetaInfo &superType,
const QmlObjectNode &objectNode)
const QmlObjectNode &node)
{
if (!templateConfiguration() || !templateConfiguration()->isValid())
return QString();
@@ -411,7 +412,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
QString qmlTemplate = imports.join(QLatin1Char('\n')) + QLatin1Char('\n');
qmlTemplate += QStringLiteral("Section {\n");
qmlTemplate += QStringLiteral("caption: \"%1\"\n").arg(objectNode.modelNode().simplifiedTypeName());
qmlTemplate += QStringLiteral("caption: \"%1\"\n").arg(QString::fromUtf8(type.simplifiedTypeName()));
qmlTemplate += QStringLiteral("SectionLayout {\n");
QList<PropertyName> orderedList = type.propertyNames();
@@ -429,8 +430,8 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
TypeName typeName = type.propertyTypeName(name);
//alias resolution only possible with instance
if (typeName == "alias" && objectNode.isValid())
typeName = objectNode.instanceType(name);
if (typeName == "alias" && node.isValid())
typeName = node.instanceType(name);
if (!superType.hasProperty(name) && type.propertyIsWritable(name) && !name.contains(".")) {
foreach (const QmlJS::SimpleReaderNode::Ptr &node, templateConfiguration()->children())
@@ -469,6 +470,34 @@ TypeName PropertyEditorQmlBackend::fixTypeNameForPanes(const TypeName &typeName)
return fixedTypeName;
}
static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMetaInfo &second)
{
for (const NodeMetaInfo &info : first.superClasses()) {
if (second.isSubclassOf(info.typeName()))
return info;
}
return first;
}
NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node)
{
QTC_ASSERT(node.isValid(), return {});
QTC_ASSERT(node.metaInfo().isValid(), return {});
AbstractView *view = node.view();
if (view->selectedModelNodes().count() > 1) {
NodeMetaInfo commonClass = node.metaInfo();
for (const ModelNode &currentNode : view->selectedModelNodes()) {
if (currentNode.metaInfo().isValid() && !currentNode.isSubclassOf(commonClass.typeName(), -1, -1))
commonClass = findCommonSuperClass(currentNode.metaInfo(), commonClass);
}
return commonClass;
}
return node.metaInfo();
}
TypeName PropertyEditorQmlBackend::qmlFileName(const NodeMetaInfo &nodeInfo)
{
const TypeName fixedTypeName = fixTypeNameForPanes(nodeInfo.typeName());
@@ -526,10 +555,10 @@ void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObje
setValue(qmlObjectNode, name, properDefaultLayoutAttachedProperties(qmlObjectNode, propertyName));
}
QUrl PropertyEditorQmlBackend::getQmlUrlForModelNode(const ModelNode &modelNode, TypeName &className)
QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className)
{
if (modelNode.isValid()) {
foreach (const NodeMetaInfo &info, modelNode.metaInfo().classHierarchy()) {
if (metaInfo.isValid()) {
foreach (const NodeMetaInfo &info, metaInfo.classHierarchy()) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) {
className = info.typeName();

View File

@@ -68,11 +68,10 @@ public:
PropertyEditorValue *propertyValueForName(const QString &propertyName);
static QString propertyEditorResourcesPath();
static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType,
const QmlObjectNode &objectNode);
static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node);
static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info = NodeMetaInfo());
static QUrl getQmlUrlForModelNode(const ModelNode &modelNode, TypeName &className);
static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className);
static bool checkIfUrlExists(const QUrl &url);
@@ -83,6 +82,8 @@ public:
void setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, PropertyEditorView *propertyEditor);
static NodeMetaInfo findCommonAncestor(const ModelNode &node);
private:
void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
const PropertyName &name, const QVariant &value,

View File

@@ -213,20 +213,13 @@ void PropertyEditorView::changeValue(const QString &name)
castedValue = QVariant(newColor);
}
try {
if (!value->value().isValid()) { //reset
qmlObjectNode.removeProperty(propertyName);
} else {
if (castedValue.isValid() && !castedValue.isNull()) {
m_locked = true;
qmlObjectNode.setVariantProperty(propertyName, castedValue);
m_locked = false;
}
if (!value->value().isValid()) { //reset
removePropertyFromModel(propertyName);
} else {
if (castedValue.isValid() && !castedValue.isNull()) {
commitVariantValueToModel(propertyName, castedValue);
}
}
catch (const RewritingException &e) {
e.showException();
}
}
void PropertyEditorView::changeExpression(const QString &propertyName)
@@ -446,13 +439,16 @@ void PropertyEditorView::resetView()
void PropertyEditorView::setupQmlBackend()
{
TypeName specificsClassName;
QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForModelNode(m_selectedNode, specificsClassName));
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
const QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForMetaInfo(commonAncestor, specificsClassName));
QUrl qmlSpecificsFile;
TypeName diffClassName;
if (m_selectedNode.isValid()) {
diffClassName = m_selectedNode.metaInfo().typeName();
foreach (const NodeMetaInfo &metaInfo, m_selectedNode.metaInfo().classHierarchy()) {
if (commonAncestor.isValid()) {
diffClassName = commonAncestor.typeName();
foreach (const NodeMetaInfo &metaInfo, commonAncestor.classHierarchy()) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break;
qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + "Specifics", metaInfo);
@@ -465,8 +461,8 @@ void PropertyEditorView::setupQmlBackend()
QString specificQmlData;
if (m_selectedNode.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type())
specificQmlData = PropertyEditorQmlBackend::templateGeneration(m_selectedNode.metaInfo(), model()->metaInfo(diffClassName), m_selectedNode);
if (commonAncestor.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type())
specificQmlData = PropertyEditorQmlBackend::templateGeneration(commonAncestor, model()->metaInfo(diffClassName), m_selectedNode);
PropertyEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlFile.toString());
@@ -515,14 +511,51 @@ void PropertyEditorView::setupQmlBackend()
}
void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
{
m_locked = true;
try {
RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::commitVariantValueToMode");
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
if (QmlObjectNode::isValidQmlObjectNode(node))
QmlObjectNode(node).setVariantProperty(propertyName, value);
}
transaction.commit();
}
catch (const RewritingException &e) {
e.showException();
}
m_locked = false;
}
void PropertyEditorView::removePropertyFromModel(const PropertyName &propertyName)
{
m_locked = true;
try {
RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::removePropertyFromModel");
for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
if (QmlObjectNode::isValidQmlObjectNode(node))
QmlObjectNode(node).removeProperty(propertyName);
}
transaction.commit();
}
catch (const RewritingException &e) {
e.showException();
}
m_locked = false;
}
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList)
{
Q_UNUSED(lastSelectedNodeList);
if (selectedNodeList.isEmpty() || selectedNodeList.count() > 1)
if (selectedNodeList.isEmpty())
select(ModelNode());
else if (m_selectedNode != selectedNodeList.constFirst())
else
select(selectedNodeList.constFirst());
}

View File

@@ -110,6 +110,9 @@ private: //functions
void delayedResetView();
void setupQmlBackend();
void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value);
void removePropertyFromModel(const PropertyName &propertyName);
private: //variables
ModelNode m_selectedNode;
QWidget *m_parent;

View File

@@ -23,6 +23,7 @@
**
****************************************************************************/
#include "abstractview.h"
#include "qmlmodelnodeproxy.h"
#include <QtQml>
@@ -66,4 +67,34 @@ ModelNode QmlModelNodeProxy::modelNode() const
return m_qmlItemNode.modelNode();
}
bool QmlModelNodeProxy::multiSelection() const
{
if (!m_qmlItemNode.isValid())
return false;
return m_qmlItemNode.view()->selectedModelNodes().count() > 1;
}
QString QmlModelNodeProxy::nodeId() const
{
if (!m_qmlItemNode.isValid())
return {};
if (multiSelection())
return tr("multiselection");
return m_qmlItemNode.id();
}
QString QmlModelNodeProxy::simplifiedTypeName() const
{
if (!m_qmlItemNode.isValid())
return {};
if (multiSelection())
return tr("multiselection");
return m_qmlItemNode.simplifiedTypeName();
}
}

View File

@@ -35,7 +35,8 @@ class QmlModelNodeProxy : public QObject
{
Q_OBJECT
Q_PROPERTY(QmlDesigner::ModelNode modelNode READ modelNode NOTIFY modelNodeChanged)
Q_PROPERTY(QmlDesigner::ModelNode modelNode READ modelNode NOTIFY modelNodeChanged)
Q_PROPERTY(bool multiSelection READ multiSelection NOTIFY modelNodeChanged)
public:
explicit QmlModelNodeProxy(QObject *parent = nullptr);
@@ -51,6 +52,12 @@ public:
ModelNode modelNode() const;
bool multiSelection() const;
QString nodeId() const;
QString simplifiedTypeName() const;
signals:
void modelNodeChanged();
void selectionToBeChanged();

View File

@@ -30,6 +30,7 @@
#include "gradientmodel.h"
#include "gradientpresetdefaultlistmodel.h"
#include "gradientpresetcustomlistmodel.h"
#include "simplecolorpalettemodel.h"
#include "qmlanchorbindingproxy.h"
#include "theme.h"
@@ -52,6 +53,7 @@ void Quick2PropertyEditorView::registerQmlTypes()
GradientModel::registerDeclarativeType();
GradientPresetDefaultListModel::registerDeclarativeType();
GradientPresetCustomListModel::registerDeclarativeType();
SimpleColorPaletteModel::registerDeclarativeType();
Internal::QmlAnchorBindingProxy::registerDeclarativeType();
}
}

View File

@@ -0,0 +1,113 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#include "simplecolorpalette.h"
#include "designersettings.h"
#include <QDebug>
namespace QmlDesigner {
PaletteColor::PaletteColor()
: m_color(QColor())
, m_colorCode(QColor().name())
, m_isFavorite(false)
{}
PaletteColor::PaletteColor(const QString &colorCode)
: m_color(colorCode)
, m_colorCode(colorCode)
, m_isFavorite(false)
{}
PaletteColor::PaletteColor(const QColor &color)
: m_color(color)
, m_colorCode(color.name(QColor::HexArgb))
, m_isFavorite(false)
{}
QVariant PaletteColor::getProperty(Property id) const
{
QVariant out;
switch (id) {
case objectNameRole:
out.setValue(QString());
break;
case colorRole:
out.setValue(color());
break;
case colorCodeRole:
out.setValue(colorCode());
break;
case isFavoriteRole:
out.setValue(isFavorite());
break;
default:
qWarning() << "PaletteColor Property switch default case";
break; //replace with assert before switch?
}
return out;
}
QColor PaletteColor::color() const
{
return m_color;
}
void PaletteColor::setColor(const QColor &value)
{
m_color = value;
m_colorCode = m_color.name(QColor::HexArgb);
}
QString PaletteColor::colorCode() const
{
return m_colorCode;
}
bool PaletteColor::isFavorite() const
{
return m_isFavorite;
}
void PaletteColor::setFavorite(bool favorite)
{
m_isFavorite = favorite;
}
bool PaletteColor::toggleFavorite()
{
return m_isFavorite = !m_isFavorite;
}
bool PaletteColor::operator==(const PaletteColor &other) const
{
return (m_color == other.m_color);
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,75 @@
/****************************************************************************
**
** 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 once
#include <QObject>
#include <QtQml/qqml.h>
#include <QColor>
namespace QmlDesigner {
class PaletteColor
{
Q_GADGET
Q_PROPERTY(QColor color READ color FINAL)
Q_PROPERTY(QString colorCode READ colorCode FINAL)
Q_PROPERTY(bool isFavorite READ isFavorite FINAL)
public:
PaletteColor();
PaletteColor(const QString &colorCode);
PaletteColor(const QColor &value);
~PaletteColor() = default;
enum Property {
objectNameRole = 0,
colorRole = 1,
colorCodeRole = 2,
isFavoriteRole = 3
};
QVariant getProperty(Property id) const;
QColor color() const;
void setColor(const QColor &value);
QString colorCode() const;
bool isFavorite() const;
void setFavorite(bool favorite);
bool toggleFavorite();
bool operator==(const PaletteColor &other) const;
private:
QColor m_color;
QString m_colorCode;
bool m_isFavorite;
};
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlDesigner::PaletteColor)

View File

@@ -0,0 +1,146 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#include "simplecolorpalettemodel.h"
#include "simplecolorpalette.h"
#include "simplecolorpalettesingleton.h"
#include "designersettings.h"
#include <QHash>
#include <QByteArray>
#include <QDebug>
#include <QSettings>
namespace QmlDesigner {
SimpleColorPaletteModel::SimpleColorPaletteModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&SimpleColorPaletteSingleton::getInstance(),
&SimpleColorPaletteSingleton::paletteChanged,
this,
&SimpleColorPaletteModel::setPalette);
m_roleNames = {{static_cast<int>(PaletteColor::Property::objectNameRole), "objectName"},
{static_cast<int>(PaletteColor::Property::colorRole), "color"},
{static_cast<int>(PaletteColor::Property::colorCodeRole), "colorCode"},
{static_cast<int>(PaletteColor::Property::isFavoriteRole), "isFavorite"}};
setPalette();
}
SimpleColorPaletteModel::~SimpleColorPaletteModel()
{
clearItems();
}
int SimpleColorPaletteModel::rowCount(const QModelIndex & /*parent*/) const
{
return m_items.count();
}
QVariant SimpleColorPaletteModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && (index.row() >= 0) && (index.row() < m_items.count())) {
if (m_roleNames.contains(role)) {
QVariant value = m_items.at(index.row())
.getProperty(static_cast<PaletteColor::Property>(role));
if (auto model = qobject_cast<SimpleColorPaletteModel *>(value.value<QObject *>()))
return QVariant::fromValue(model);
return value;
}
qWarning() << Q_FUNC_INFO << "invalid role requested";
return QVariant();
}
qWarning() << Q_FUNC_INFO << "invalid index requested";
return QVariant();
}
QHash<int, QByteArray> SimpleColorPaletteModel::roleNames() const
{
return m_roleNames;
}
void SimpleColorPaletteModel::clearItems()
{
beginResetModel();
m_items.clear();
endResetModel();
}
void SimpleColorPaletteModel::addItem(const QString &item)
{
PaletteColor palette(item);
addItem(palette);
}
void SimpleColorPaletteModel::addItem(const PaletteColor &item)
{
SimpleColorPaletteSingleton::getInstance().addItem(item);
}
const QList<PaletteColor> &SimpleColorPaletteModel::items() const
{
return m_items;
}
void SimpleColorPaletteModel::sortItems()
{
SimpleColorPaletteSingleton::getInstance().sortItems();
}
void SimpleColorPaletteModel::registerDeclarativeType()
{
qmlRegisterType<SimpleColorPaletteModel>("HelperWidgets", 2, 0, "SimpleColorPaletteModel");
}
void SimpleColorPaletteModel::toggleFavorite(int id)
{
SimpleColorPaletteSingleton::getInstance().toggleFavorite(id);
}
void SimpleColorPaletteModel::setPalette()
{
beginResetModel();
m_items = SimpleColorPaletteSingleton::getInstance().getItems();
m_favoriteOffset = SimpleColorPaletteSingleton::getInstance().getFavoriteOffset();
m_paletteSize = SimpleColorPaletteSingleton::getInstance().getPaletteSize();
endResetModel();
}
bool SimpleColorPaletteModel::read()
{
return SimpleColorPaletteSingleton::getInstance().readPalette();
}
void SimpleColorPaletteModel::write()
{
SimpleColorPaletteSingleton::getInstance().writePalette();
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** 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 once
#include <QAbstractListModel>
#include <QtQml/qqml.h>
#include <QList>
namespace QmlDesigner {
class PaletteColor;
class SimpleColorPaletteModel : public QAbstractListModel
{
Q_OBJECT
public:
explicit SimpleColorPaletteModel(QObject *parent = nullptr);
~SimpleColorPaletteModel() override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
void clearItems();
Q_INVOKABLE void addItem(const QString &item);
void addItem(const PaletteColor &item);
const QList<PaletteColor> &items() const;
void sortItems();
static void registerDeclarativeType();
Q_INVOKABLE void toggleFavorite(int id);
bool read();
void write();
private slots:
void setPalette();
private:
void enqueue(const PaletteColor &item);
private:
int m_paletteSize;
int m_favoriteOffset;
QList<PaletteColor> m_items;
QHash<int, QByteArray> m_roleNames;
};
} // namespace QmlDesigner
QML_DECLARE_TYPE(QmlDesigner::SimpleColorPaletteModel)

View File

@@ -0,0 +1,185 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#include "simplecolorpalettesingleton.h"
#include "simplecolorpalette.h"
#include "designersettings.h"
#include <QDebug>
#include <QSettings>
namespace QmlDesigner {
SimpleColorPaletteSingleton::SimpleColorPaletteSingleton()
: m_items()
, m_favoriteOffset(0)
{
if (!readPalette()) {
for (int i = 0; i < m_paletteSize; i++)
m_items.append(PaletteColor());
}
}
SimpleColorPaletteSingleton &SimpleColorPaletteSingleton::getInstance()
{
static SimpleColorPaletteSingleton singleton;
return singleton;
}
void SimpleColorPaletteSingleton::addItem(const PaletteColor &item)
{
if (m_favoriteOffset >= m_paletteSize)
return;
if (item.isFavorite()) {
int contains = m_items.indexOf(item);
if (contains != -1) {
if (m_items.at(contains).isFavorite())
return;
else
m_items.removeAt(contains);
}
m_items.insert(0, item);
m_favoriteOffset++;
} else if (m_items.contains(item))
return;
else
m_items.insert(m_favoriteOffset, item);
while (m_items.size() > m_paletteSize) {
m_items.removeLast();
}
writePalette();
emit paletteChanged();
}
QList<PaletteColor> SimpleColorPaletteSingleton::getItems() const
{
return m_items;
}
int SimpleColorPaletteSingleton::getPaletteSize() const
{
return m_paletteSize;
}
int SimpleColorPaletteSingleton::getFavoriteOffset() const
{
return m_favoriteOffset;
}
void SimpleColorPaletteSingleton::sortItems()
{
auto itemSort = [](const PaletteColor &first, const PaletteColor &second) {
return (static_cast<int>(first.isFavorite()) < static_cast<int>(second.isFavorite()));
};
std::sort(m_items.begin(), m_items.end(), itemSort);
emit paletteChanged();
}
void SimpleColorPaletteSingleton::toggleFavorite(int id)
{
bool toggleResult = m_items[id].toggleFavorite();
if (toggleResult) {
m_favoriteOffset++;
m_items.move(id, 0);
} else {
m_favoriteOffset--;
m_items.move(id, m_favoriteOffset);
}
if (m_favoriteOffset < 0)
m_favoriteOffset = 0;
else if (m_favoriteOffset > m_paletteSize)
m_favoriteOffset = m_paletteSize;
emit paletteChanged();
}
bool SimpleColorPaletteSingleton::readPalette()
{
QList<PaletteColor> proxy;
const QStringList stringData = QmlDesigner::DesignerSettings::getValue(
QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT)
.toStringList();
int favCounter = 0;
for (int i = 0; i < stringData.size(); i++) {
const QStringList strsep = stringData.at(i).split(";");
if (strsep.size() != 2) {
continue;
}
PaletteColor colorItem(strsep.at(0));
bool isFav = static_cast<bool>(strsep.at(1).toInt());
colorItem.setFavorite(isFav);
if (isFav)
favCounter++;
proxy.append(colorItem);
}
if (proxy.size() == 0) {
return false;
}
while (proxy.size() > m_paletteSize) {
proxy.removeLast();
}
while (proxy.size() < m_paletteSize) {
proxy.append(PaletteColor());
}
m_items.clear();
m_items = proxy;
m_favoriteOffset = favCounter;
return true;
}
void SimpleColorPaletteSingleton::writePalette()
{
QStringList output;
QString subres;
for (int i = 0; i < m_items.size(); i++) {
subres = m_items.at(i).color().name(QColor::HexArgb);
subres += ";";
subres += QString::number(static_cast<int>(m_items.at(i).isFavorite()));
output.push_back(subres);
subres.clear();
}
QmlDesigner::DesignerSettings::setValue(
QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, output);
}
} // namespace QmlDesigner

View File

@@ -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.
**
****************************************************************************/
#pragma once
#include <QObject>
#include <QAbstractListModel>
#include <QtQml/qqml.h>
#include <QList>
#include <QColor>
#include <simplecolorpalette.h>
namespace QmlDesigner {
class SimpleColorPaletteSingleton : public QObject
{
Q_OBJECT
public:
static SimpleColorPaletteSingleton &getInstance();
bool readPalette();
void writePalette();
void addItem(const PaletteColor &item);
QList<PaletteColor> getItems() const;
int getPaletteSize() const;
int getFavoriteOffset() const;
void sortItems();
void toggleFavorite(int id);
SimpleColorPaletteSingleton(const SimpleColorPaletteSingleton &) = delete;
void operator=(const SimpleColorPaletteSingleton &) = delete;
signals:
void paletteChanged();
private:
SimpleColorPaletteSingleton();
private:
QList<PaletteColor> m_items;
const int m_paletteSize = 6;
int m_favoriteOffset;
};
} // namespace QmlDesigner

View File

@@ -372,6 +372,13 @@ bool smartVeryFuzzyCompare(const QVariant &value1, const QVariant &value2)
return false;
}
bool smartColorCompare(const QVariant &value1, const QVariant &value2)
{
if ((value1.type() == QVariant::Color) || (value2.type() == QVariant::Color))
return value1.value<QColor>().rgba() == value2.value<QColor>().rgba();
return false;
}
bool equals(const QVariant &a, const QVariant &b)
{
if (a.canConvert<QmlDesigner::Enumeration>() && b.canConvert<QmlDesigner::Enumeration>())
@@ -380,6 +387,8 @@ bool equals(const QVariant &a, const QVariant &b)
return true;
if (smartVeryFuzzyCompare(a, b))
return true;
if (smartColorCompare(a, b))
return true;
return false;
}

View File

@@ -76,6 +76,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
restoreValue(settings, DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, true);
restoreValue(settings, DesignerSettingsKey::STANDALONE_MODE, false);
restoreValue(settings, DesignerSettingsKey::ENABLE_TIMELINEVIEW, false);
restoreValue(settings, DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, QStringList());
settings->endGroup();
settings->endGroup();

View File

@@ -65,6 +65,7 @@ const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These setti
const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */
const char STANDALONE_MODE[] = "StandAloneMode";
const char ENABLE_TIMELINEVIEW[] = "EnableTimelineView";
const char SIMPLE_COLOR_PALETTE_CONTENT[] = "SimpleColorPaletteContent";
}
class DesignerSettings : public QHash<QByteArray, QVariant>

View File

@@ -1,4 +1,4 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = qmldesignerplugin.pro qtquickplugin componentsplugin
SUBDIRS = qmldesignerplugin.pro qtquickplugin componentsplugin qmlpreviewplugin

View File

@@ -588,6 +588,12 @@ Project {
"propertyeditor/qmlanchorbindingproxy.h",
"propertyeditor/qmlmodelnodeproxy.cpp",
"propertyeditor/qmlmodelnodeproxy.h",
"propertyeditor/simplecolorpalette.cpp",
"propertyeditor/simplecolorpalette.h",
"propertyeditor/simplecolorpalettemodel.cpp",
"propertyeditor/simplecolorpalettemodel.h",
"propertyeditor/simplecolorpalettesingleton.cpp",
"propertyeditor/simplecolorpalettesingleton.h",
"resources/resources.qrc",
"stateseditor/stateseditorimageprovider.cpp",
"stateseditor/stateseditorimageprovider.h",

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 B

View File

@@ -0,0 +1,2 @@
MetaInfo {
}

View File

@@ -0,0 +1,303 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#include "qmlpreviewplugin.h"
#include "qmlpreviewactions.h"
#include <zoomaction.h>
#include <utils/utilsicons.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/project.h>
#include <QLabel>
#include <QComboBox>
#include <QPointer>
namespace QmlDesigner {
using namespace ProjectExplorer;
const Utils::Icon previewIcon({
{":/qmlpreviewplugin/images/live_preview.png", Utils::Theme::IconsBaseColor}});
static void handleAction(const SelectionContext &context)
{
if (context.view()->isAttached()) {
if (context.toggled()) {
ProjectExplorerPlugin::runStartupProject(Constants::QML_PREVIEW_RUN_MODE);
QmlPreviewPlugin::setQmlFile();
} else {
QmlPreviewPlugin::stopAllRunControls();
}
}
}
QmlPreviewAction::QmlPreviewAction() : ModelNodeAction("LivePreview",
"Live Preview",
previewIcon.icon(),
QmlPreviewPlugin::tr("Show Live Preview"),
ComponentCoreConstants::qmlPreviewCategory,
QKeySequence("Alt+p"),
20,
&handleAction,
&SelectionContextFunctors::always)
{
if (!QmlPreviewPlugin::getPreviewPlugin())
defaultAction()->setVisible(false);
defaultAction()->setCheckable(true);
}
void QmlPreviewAction::updateContext()
{
if (selectionContext().view()->isAttached())
QmlPreviewPlugin::setQmlFile();
defaultAction()->setSelectionContext(selectionContext());
}
ActionInterface::Type QmlPreviewAction::type() const
{
return ToolBarAction;
}
ZoomPreviewAction::ZoomPreviewAction()
: m_zoomAction(new ZoomAction(nullptr))
{
QObject::connect(m_zoomAction.get(), &ZoomAction::zoomLevelChanged, [=](float d) {
QmlPreviewPlugin::setZoomFactor(d);
});
if (!QmlPreviewPlugin::getPreviewPlugin())
m_zoomAction->setVisible(false);
}
ZoomPreviewAction::~ZoomPreviewAction()
= default;
QAction *ZoomPreviewAction::action() const
{
return m_zoomAction.get();
}
QByteArray ZoomPreviewAction::category() const
{
return ComponentCoreConstants::qmlPreviewCategory;
}
QByteArray ZoomPreviewAction::menuId() const
{
return QByteArray();
}
int ZoomPreviewAction::priority() const
{
return 19;
}
ActionInterface::Type ZoomPreviewAction::type() const
{
return ToolBarAction;
}
void ZoomPreviewAction::currentContextChanged(const SelectionContext &)
{}
quint16 FpsLabelAction::lastValidFrames = 0;
QList<QPointer<QLabel>> FpsLabelAction::fpsHandlerLabelList;
FpsLabelAction::FpsLabelAction(QObject *parent)
: QWidgetAction(parent)
{
}
void FpsLabelAction::fpsHandler(quint16 fpsValues[8])
{
quint16 frames = fpsValues[0];
if (frames != 0)
lastValidFrames = frames;
QString fpsText("%1 FPS");
if (lastValidFrames == 0 || (frames == 0 && lastValidFrames < 2))
fpsText = fpsText.arg("--");
else
fpsText = fpsText.arg(lastValidFrames);
for (QPointer<QLabel> label : fpsHandlerLabelList) {
if (label)
label->setText(fpsText);
}
}
void FpsLabelAction::cleanFpsCounter()
{
lastValidFrames = 0;
quint16 nullInitialized[8] = {0};
fpsHandler(nullInitialized);
}
QWidget *FpsLabelAction::createWidget(QWidget *parent)
{
auto label = new QLabel(parent);
auto originList = fpsHandlerLabelList;
fpsHandlerLabelList.clear();
fpsHandlerLabelList.append(label);
for (const auto &labelPointer : originList) {
if (labelPointer)
fpsHandlerLabelList.append(labelPointer);
}
return label;
}
void FpsLabelAction::refreshFpsLabel(quint16 frames)
{
for (const auto &labelPointer : fpsHandlerLabelList) {
if (labelPointer)
labelPointer->setText(QString("%1 FPS").arg(frames));
}
}
FpsAction::FpsAction() : m_fpsLabelAction(new FpsLabelAction(nullptr))
{}
QAction *FpsAction::action() const
{
return m_fpsLabelAction.get();
}
QByteArray FpsAction::category() const
{
return ComponentCoreConstants::qmlPreviewCategory;
}
QByteArray FpsAction::menuId() const
{
return QByteArray();
}
int FpsAction::priority() const
{
return 19;
}
ActionInterface::Type FpsAction::type() const
{
return ToolBarAction;
}
void FpsAction::currentContextChanged(const SelectionContext &)
{}
SwitchLanguageComboboxAction::SwitchLanguageComboboxAction(QObject *parent)
: QWidgetAction(parent)
{
connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::startupProjectChanged,
this,
&SwitchLanguageComboboxAction::refreshProjectLocales);
}
QWidget *SwitchLanguageComboboxAction::createWidget(QWidget *parent)
{
QPointer<QComboBox> comboBox = new QComboBox(parent);
comboBox->setToolTip(tr("Switch the language used by preview."));
connect(comboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this, comboBox](int index) {
if (index == 0)
emit currentLocaleChanged("");
else
emit currentLocaleChanged(comboBox->currentText());
});
auto refreshComboBoxFunction = [this, comboBox] (ProjectExplorer::Project *project) {
if (comboBox) {
refreshProjectLocales(project);
comboBox->clear();
comboBox->addItem(tr("Default"));
comboBox->addItems(m_localeStrings);
}
};
connect(ProjectExplorer::SessionManager::instance(),
&ProjectExplorer::SessionManager::startupProjectChanged,
refreshComboBoxFunction);
if (auto project = SessionManager::startupProject())
refreshComboBoxFunction(project);
return comboBox;
}
void SwitchLanguageComboboxAction::refreshProjectLocales(Project *project)
{
if (!project)
return;
m_localeStrings.clear();
const auto projectDirectory = project->rootProjectDirectory().toFileInfo().absoluteFilePath();
const QDir languageDirectory(projectDirectory + "/i18n");
const auto qmFiles = languageDirectory.entryList({"qml_*.qm"});
m_localeStrings = Utils::transform(qmFiles, [](const QString &qmFile) {
const int localeStartPosition = qmFile.lastIndexOf("_") + 1;
const int localeEndPosition = qmFile.size() - QString(".qm").size();
const QString locale = qmFile.left(localeEndPosition).mid(localeStartPosition);
return locale;
});
}
SwitchLanguageAction::SwitchLanguageAction()
: m_switchLanguageAction(new SwitchLanguageComboboxAction(nullptr))
{
QObject::connect(m_switchLanguageAction.get(), &SwitchLanguageComboboxAction::currentLocaleChanged,
&QmlPreviewPlugin::setLanguageLocale);
}
QAction *SwitchLanguageAction::action() const
{
return m_switchLanguageAction.get();
}
QByteArray SwitchLanguageAction::category() const
{
return ComponentCoreConstants::qmlPreviewCategory;
}
QByteArray SwitchLanguageAction::menuId() const
{
return QByteArray();
}
int SwitchLanguageAction::priority() const
{
return 10;
}
ActionInterface::Type SwitchLanguageAction::type() const
{
return ToolBarAction;
}
void SwitchLanguageAction::currentContextChanged(const SelectionContext &)
{}
} // namespace QmlDesigner

View File

@@ -0,0 +1,135 @@
/****************************************************************************
**
** 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 once
#include <actioninterface.h>
#include <modelnodecontextmenu_helper.h>
#include <QByteArray>
#include <QWidgetAction>
#include <memory>
QT_FORWARD_DECLARE_CLASS(QAction)
QT_FORWARD_DECLARE_CLASS(QLabel)
namespace QmlPreview {
using QmlPreviewFpsHandler = void (*)(quint16 *);
}
namespace ProjectExplorer {
class Project;
}
namespace QmlDesigner {
class ZoomAction;
class QmlPreviewAction : public ModelNodeAction
{
public:
QmlPreviewAction();
void updateContext() override;
Type type() const override;
};
class ZoomPreviewAction : public ActionInterface
{
public:
ZoomPreviewAction();
~ZoomPreviewAction() override;
QAction *action() const override;
QByteArray category() const override;
QByteArray menuId() const override;
int priority() const override;
Type type() const override;
void currentContextChanged(const SelectionContext &) override;
private:
std::unique_ptr<ZoomAction> m_zoomAction;
};
class FpsLabelAction : public QWidgetAction
{
public:
explicit FpsLabelAction(QObject *parent = nullptr);
static void fpsHandler(quint16 fpsValues[8]);
static void cleanFpsCounter();
protected:
QWidget *createWidget(QWidget *parent) override;
private:
static void refreshFpsLabel(quint16 frames);
static QPointer<QLabel> m_labelInstance;
static QList<QPointer<QLabel>> fpsHandlerLabelList;
static quint16 lastValidFrames;
};
class FpsAction : public ActionInterface
{
public:
FpsAction();
QAction *action() const override;
QByteArray category() const override;
QByteArray menuId() const override;
int priority() const override;
Type type() const override;
void currentContextChanged(const SelectionContext &) override;
private:
std::unique_ptr<FpsLabelAction> m_fpsLabelAction;
};
class SwitchLanguageComboboxAction : public QWidgetAction
{
Q_OBJECT
public:
explicit SwitchLanguageComboboxAction(QObject *parent = nullptr);
signals:
void currentLocaleChanged(const QString& string);
protected:
QWidget *createWidget(QWidget *parent) override;
private:
void refreshProjectLocales(ProjectExplorer::Project *project);
QStringList m_localeStrings;
};
class SwitchLanguageAction : public ActionInterface
{
public:
SwitchLanguageAction();
QAction *action() const override;
QByteArray category() const override;
QByteArray menuId() const override;
int priority() const override;
Type type() const override;
void currentContextChanged(const SelectionContext &) override;
private:
std::unique_ptr<SwitchLanguageComboboxAction> m_switchLanguageAction;
};
} // namespace QmlDesigner
Q_DECLARE_METATYPE(QmlPreview::QmlPreviewFpsHandler);

View File

@@ -0,0 +1,173 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
#include "qmlpreviewplugin.h"
#include "qmlpreviewactions.h"
#include <modelnodecontextmenu_helper.h>
#include <componentcore_constants.h>
#include <qmldesignerplugin.h>
#include <viewmanager.h>
#include <actioninterface.h>
#include <zoomaction.h>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runcontrol.h>
namespace QmlPreview {
using QmlPreviewRunControlList = QList<ProjectExplorer::RunControl *>;
}
Q_DECLARE_METATYPE(QmlPreview::QmlPreviewRunControlList)
namespace QmlDesigner {
static QObject *s_previewPlugin = nullptr;
QmlPreviewPlugin::QmlPreviewPlugin()
{
DesignerActionManager &designerActionManager =
QmlDesignerPlugin::instance()->designerActionManager();
auto previewAction = new QmlPreviewAction();
designerActionManager.addDesignerAction(new ActionGroup(
QString(),
ComponentCoreConstants::qmlPreviewCategory,
ComponentCoreConstants::priorityQmlPreviewCategory,
&SelectionContextFunctors::always));
s_previewPlugin = getPreviewPlugin();
if (s_previewPlugin) {
bool connected = connect(s_previewPlugin, SIGNAL(runningPreviewsChanged(const QmlPreviewRunControlList &)),
this, SLOT(handleRunningPreviews()));
QTC_ASSERT(connected, qWarning() << "something wrong with the runningPreviewsChanged signal");
}
designerActionManager.addDesignerAction(previewAction);
auto zoomAction = new ZoomPreviewAction;
designerActionManager.addDesignerAction(zoomAction);
auto separator = new SeperatorDesignerAction(ComponentCoreConstants::qmlPreviewCategory, 0);
designerActionManager.addDesignerAction(separator);
m_previewToggleAction = previewAction->defaultAction();
if (s_previewPlugin) {
auto fpsAction = new FpsAction;
designerActionManager.addDesignerAction(fpsAction);
s_previewPlugin->setProperty("fpsHandler", QVariant::fromValue<QmlPreview::QmlPreviewFpsHandler>(FpsLabelAction::fpsHandler));
auto switchLanguageAction = new SwitchLanguageAction;
designerActionManager.addDesignerAction(switchLanguageAction);
}
}
QString QmlPreviewPlugin::pluginName() const
{
return QLatin1String("QmlPreviewPlugin");
}
void QmlPreviewPlugin::stopAllRunControls()
{
QTC_ASSERT(s_previewPlugin, return);
const QVariant variant = s_previewPlugin->property("runningPreviews");
auto runControls = variant.value<QmlPreview::QmlPreviewRunControlList>();
for (ProjectExplorer::RunControl *runControl : runControls)
runControl->initiateStop();
}
void QmlPreviewPlugin::handleRunningPreviews()
{
QTC_ASSERT(s_previewPlugin, return);
const QVariant variant = s_previewPlugin->property("runningPreviews");
if (variant.isValid()) {
// the QmlPreview::QmlPreviewRunControlList type have to be available and used in the qmlpreview plugin
QTC_ASSERT(variant.canConvert<QmlPreview::QmlPreviewRunControlList>(), return);
auto runControls = variant.value<QmlPreview::QmlPreviewRunControlList>();
m_previewToggleAction->setChecked(!runControls.isEmpty());
if (runControls.isEmpty())
FpsLabelAction::cleanFpsCounter();
}
}
QString QmlPreviewPlugin::metaInfo() const
{
return QLatin1String(":/qmlpreviewplugin/qmlpreview.metainfo");
}
void QmlPreviewPlugin::setQmlFile()
{
if (s_previewPlugin) {
const Utils::FileName qmlFileName =
QmlDesignerPlugin::instance()->currentDesignDocument()->fileName();
s_previewPlugin->setProperty("previewedFile", qmlFileName.toString());
}
}
float QmlPreviewPlugin::zoomFactor()
{
QVariant zoomFactorVariant = 1.0;
if (s_previewPlugin && !s_previewPlugin->property("zoomFactor").isNull())
zoomFactorVariant = s_previewPlugin->property("zoomFactor");
return zoomFactorVariant.toFloat();
}
void QmlPreviewPlugin::setZoomFactor(float zoomFactor)
{
if (s_previewPlugin)
s_previewPlugin->setProperty("zoomFactor", zoomFactor);
}
void QmlPreviewPlugin::setLanguageLocale(const QString &locale)
{
if (s_previewPlugin)
s_previewPlugin->setProperty("locale", locale);
}
QObject *QmlPreviewPlugin::getPreviewPlugin()
{
auto pluginIt = std::find_if(ExtensionSystem::PluginManager::plugins().begin(),
ExtensionSystem::PluginManager::plugins().end(),
[](const ExtensionSystem::PluginSpec *p) {
return p->name() == "QmlPreview";
});
if (pluginIt != ExtensionSystem::PluginManager::plugins().constEnd())
return (*pluginIt)->plugin();
return nullptr;
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,69 @@
/****************************************************************************
**
** 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 once
#include <iwidgetplugin.h>
#include <QMetaType>
QT_FORWARD_DECLARE_CLASS(QAction)
namespace QmlDesigner {
class QmlPreviewPlugin : public QObject, QmlDesigner::IWidgetPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QmlDesignerPlugin" FILE "qmlpreviewplugin.json")
Q_DISABLE_COPY(QmlPreviewPlugin)
Q_INTERFACES(QmlDesigner::IWidgetPlugin)
public:
QmlPreviewPlugin();
~QmlPreviewPlugin() override = default;
QString metaInfo() const override;
QString pluginName() const override;
static void stopAllRunControls();
static void setQmlFile();
static QObject *getPreviewPlugin();
static float zoomFactor();
static void setZoomFactor(float zoomFactor);
static void setLanguageLocale(const QString &locale);
signals:
void fpsChanged(quint16 frames);
private slots:
void handleRunningPreviews();
private:
QAction *m_previewToggleAction = nullptr;
};
} // namespace QmlDesigner

View File

@@ -0,0 +1,6 @@
{
"Vendor" : "The Qt Company Ltd",
"Category" : "Qt Quick",
"Description" : "Plugin for integrating QmlPreview into QmlDesigner",
"Url" : "http://www.qt.io"
}

View File

@@ -0,0 +1,10 @@
QT *= qml quick core
VPATH += $$PWD
SOURCES += qmlpreviewplugin.cpp
HEADERS += qmlpreviewplugin.h
SOURCES += qmlpreviewactions.cpp
HEADERS += qmlpreviewactions.h
RESOURCES += qmlpreviewplugin.qrc

Some files were not shown because too many files have changed in this diff Show More