forked from qt-creator/qt-creator
QmlDesigner: Fix ColorEditor
* Change the look of the picker cross * Cleanup custom RGB, HSL, HSV and Alpha value storage and handling * Fix issue of alpha not updating when selecting gradient stops * Fix initial color not shown correctly * Fix ComboBox warning about parameter injection * Add checkerboard image to GradientLine * Remove GradientPopupIndicator * Add signals to RealSpinBox in order to react to user interaction * Cleanup code * Change how porperty editor value emits value if old and new color are equal Task-number: QDS-4755 Change-Id: I1a8095664fc8ed53c52659ac20557c03b89704c9 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
committed by
Henning Gründl
parent
74bfae6a4a
commit
04c36419f7
@@ -189,8 +189,20 @@ SecondColumnLayout {
|
||||
colorEditor.originalColor = colorEditor.color
|
||||
}
|
||||
|
||||
onValueChanged: colorEditor.color = colorEditor.value
|
||||
onBackendValueChanged: colorEditor.color = colorEditor.value
|
||||
Connections {
|
||||
id: backendConnection
|
||||
target: colorEditor
|
||||
|
||||
function onValueChanged() {
|
||||
if (isNotInGradientMode())
|
||||
colorEditor.color = colorEditor.value
|
||||
}
|
||||
|
||||
function onBackendValueChanged() {
|
||||
if (isNotInGradientMode())
|
||||
colorEditor.color = colorEditor.value
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: colorEditorTimer
|
||||
@@ -198,15 +210,18 @@ SecondColumnLayout {
|
||||
interval: 100
|
||||
running: false
|
||||
onTriggered: {
|
||||
backendConnection.enabled = false
|
||||
|
||||
if (colorEditor.backendValue !== undefined) {
|
||||
if (isVector3D) {
|
||||
if (colorEditor.isVector3D)
|
||||
colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r,
|
||||
colorEditor.color.g,
|
||||
colorEditor.color.b)
|
||||
} else {
|
||||
else
|
||||
colorEditor.backendValue.value = colorEditor.color
|
||||
}
|
||||
}
|
||||
|
||||
backendConnection.enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,8 +238,6 @@ SecondColumnLayout {
|
||||
|
||||
if (isNotInGradientMode())
|
||||
colorEditorTimer.restart() // Delay setting the color to keep ui responsive
|
||||
|
||||
colorPalette.selectedColor = colorEditor.color
|
||||
}
|
||||
|
||||
Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth }
|
||||
@@ -419,6 +432,7 @@ SecondColumnLayout {
|
||||
tooltip: qsTr("Transparent")
|
||||
onClicked: {
|
||||
colorPicker.alpha = 0
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
@@ -503,8 +517,10 @@ SecondColumnLayout {
|
||||
visible: !isNotInGradientMode()
|
||||
|
||||
onCurrentColorChanged: {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient)
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
colorEditor.color = gradientLine.currentColor
|
||||
colorPicker.color = colorEditor.color
|
||||
}
|
||||
}
|
||||
|
||||
onHasGradientChanged: {
|
||||
@@ -515,9 +531,8 @@ SecondColumnLayout {
|
||||
}
|
||||
|
||||
onSelectedNodeChanged: {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient)
|
||||
colorEditor.originalColor = gradientLine.currentColor
|
||||
}
|
||||
}
|
||||
|
||||
onInvalidated: colorEditor.updateThumbnail()
|
||||
@@ -546,13 +561,15 @@ SecondColumnLayout {
|
||||
function onSelectionChanged() {
|
||||
if (colorEditor.supportGradient && gradientLine.hasGradient) {
|
||||
colorEditor.color = gradientLine.currentColor
|
||||
gradientLine.currentColor = color
|
||||
gradientLine.currentColor = colorEditor.color
|
||||
hexTextField.text = colorEditor.color
|
||||
popupHexTextField.text = colorEditor.color
|
||||
}
|
||||
|
||||
gradientLine.isInValidState = true
|
||||
colorEditor.originalColor = colorEditor.color
|
||||
colorPalette.selectedColor = colorEditor.color
|
||||
colorPicker.color = colorEditor.color
|
||||
|
||||
colorEditor.createModel()
|
||||
colorEditor.determineActiveColorMode()
|
||||
@@ -563,44 +580,32 @@ SecondColumnLayout {
|
||||
ColorPicker {
|
||||
id: colorPicker
|
||||
|
||||
property color boundColor: colorEditor.color
|
||||
|
||||
width: parent.width
|
||||
sliderMargins: 4
|
||||
|
||||
// Prevent the binding to be deleted by assignment
|
||||
onBoundColorChanged: colorPicker.color = colorPicker.boundColor
|
||||
onUpdateColor: {
|
||||
colorEditor.color = colorPicker.color
|
||||
|
||||
if (contextMenu.opened)
|
||||
contextMenu.close()
|
||||
}
|
||||
onRightMouseButtonClicked: contextMenu.popup(colorPicker)
|
||||
|
||||
onColorInvalidated: {
|
||||
switch (colorPicker.mode) {
|
||||
case ColorPicker.Mode.HSLA:
|
||||
hslHueSpinBox.value = colorPicker.hue
|
||||
hslSaturationSpinBox.value = colorPicker.saturationHSL
|
||||
hslLightnessSpinBox.value = colorPicker.lightness
|
||||
hslAlphaSpinBox.value = colorPicker.alpha
|
||||
break
|
||||
hslHueSpinBox.value = colorPicker.hue
|
||||
hslSaturationSpinBox.value = colorPicker.saturationHSL
|
||||
hslLightnessSpinBox.value = colorPicker.lightness
|
||||
hslAlphaSpinBox.value = colorPicker.alpha
|
||||
|
||||
case ColorPicker.Mode.RGBA:
|
||||
redSpinBox.value = (colorPicker.color.r * 255)
|
||||
greenSpinBox.value = (colorPicker.color.g * 255)
|
||||
blueSpinBox.value = (colorPicker.color.b * 255)
|
||||
rgbAlphaSpinBox.value = (colorPicker.alpha * 255)
|
||||
break
|
||||
redSpinBox.value = (colorPicker.red * 255)
|
||||
greenSpinBox.value = (colorPicker.green * 255)
|
||||
blueSpinBox.value = (colorPicker.blue * 255)
|
||||
rgbAlphaSpinBox.value = (colorPicker.alpha * 255)
|
||||
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
hsvHueSpinBox.value = colorPicker.hue
|
||||
hsvSaturationSpinBox.value = colorPicker.saturationHSV
|
||||
hsvValueSpinBox.value = colorPicker.value
|
||||
hsvAlphaSpinBox.value = colorPicker.alpha
|
||||
break
|
||||
}
|
||||
hsvHueSpinBox.value = colorPicker.hue
|
||||
hsvSaturationSpinBox.value = colorPicker.saturationHSV
|
||||
hsvValueSpinBox.value = colorPicker.value
|
||||
hsvAlphaSpinBox.value = colorPicker.alpha
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +795,6 @@ SecondColumnLayout {
|
||||
|
||||
RowLayout {
|
||||
id: rgbaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.RGBA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -798,7 +802,6 @@ SecondColumnLayout {
|
||||
DoubleSpinBox {
|
||||
id: redSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -806,17 +809,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = redSpinBox.value / 255.0
|
||||
if (colorPicker.color.r !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.r = tmp
|
||||
if (colorPicker.red !== tmp && !colorPicker.block) {
|
||||
colorPicker.red = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: greenSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -824,17 +829,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = greenSpinBox.value / 255.0
|
||||
if (colorPicker.color.g !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.g = tmp
|
||||
if (colorPicker.green !== tmp && !colorPicker.block) {
|
||||
colorPicker.green = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: blueSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -842,17 +849,19 @@ SecondColumnLayout {
|
||||
|
||||
onValueModified: {
|
||||
var tmp = blueSpinBox.value / 255.0
|
||||
if (colorPicker.color.b !== tmp && !colorPicker.block) {
|
||||
colorPicker.color.b = tmp
|
||||
if (colorPicker.blue !== tmp && !colorPicker.block) {
|
||||
colorPicker.blue = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
id: rgbAlphaSpinBox
|
||||
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
|
||||
|
||||
stepSize: 1
|
||||
minimumValue: 0
|
||||
maximumValue: 255
|
||||
@@ -862,15 +871,17 @@ SecondColumnLayout {
|
||||
var tmp = rgbAlphaSpinBox.value / 255.0
|
||||
if (colorPicker.alpha !== tmp && !colorPicker.block) {
|
||||
colorPicker.alpha = tmp
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: hslaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.HSLA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -882,9 +893,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.hue !== hslHueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.hue = hslHueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -894,9 +908,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.saturationHSL !== hslSaturationSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.saturationHSL = hslSaturationSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -906,6 +923,7 @@ SecondColumnLayout {
|
||||
if (colorPicker.lightness !== hslLightnessSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.lightness = hslLightnessSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
@@ -918,15 +936,17 @@ SecondColumnLayout {
|
||||
if (colorPicker.alpha !== hslAlphaSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.alpha = hslAlphaSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: hsvaRow
|
||||
|
||||
visible: colorPicker.mode === ColorPicker.Mode.HSVA
|
||||
Layout.fillWidth: true
|
||||
spacing: StudioTheme.Values.controlGap
|
||||
@@ -938,9 +958,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.hue !== hsvHueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.hue = hsvHueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -950,9 +973,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.saturationHSV !== hsvSaturationSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.saturationHSV = hsvSaturationSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -962,9 +988,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.value !== hsvValueSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.value = hsvValueSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
|
||||
DoubleSpinBox {
|
||||
@@ -974,9 +1003,12 @@ SecondColumnLayout {
|
||||
if (colorPicker.alpha !== hsvAlphaSpinBox.value
|
||||
&& !colorPicker.block) {
|
||||
colorPicker.alpha = hsvAlphaSpinBox.value
|
||||
colorPicker.invalidateColor()
|
||||
colorPicker.updateColor()
|
||||
}
|
||||
}
|
||||
onDragStarted: colorEditorTimer.stop()
|
||||
onIndicatorPressed: colorEditorTimer.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,7 +1018,6 @@ SecondColumnLayout {
|
||||
caption: qsTr("Palette")
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
bottomPadding: 5
|
||||
@@ -994,8 +1025,14 @@ SecondColumnLayout {
|
||||
ColorPalette {
|
||||
id: colorPalette
|
||||
enableSingletonConnection: cePopup.opened
|
||||
onSelectedColorChanged: colorEditor.color = colorPalette.selectedColor
|
||||
onDialogColorChanged: colorEditor.color = colorPalette.selectedColor
|
||||
onSelectedColorChanged: {
|
||||
colorPicker.color = colorPalette.selectedColor
|
||||
colorEditor.color = colorPalette.selectedColor
|
||||
}
|
||||
onDialogColorChanged: {
|
||||
colorPicker.color = colorPalette.selectedColor
|
||||
colorEditor.color = colorPalette.selectedColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1005,7 +1042,6 @@ SecondColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
visible: !colorEditor.isNotInGradientMode()
|
||||
|
||||
leftPadding: 10
|
||||
rightPadding: 10
|
||||
|
||||
@@ -1039,12 +1075,10 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: defaultGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasLinearGradient() && !colorEditor.shapeGradients
|
||||
|
||||
RowLayout {
|
||||
id: defaultGradientOrientation
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
@@ -1055,9 +1089,9 @@ SecondColumnLayout {
|
||||
width: implicitWidth
|
||||
model: [{ value: Gradient.Vertical, text: qsTr("Vertical") },
|
||||
{ value: Gradient.Horizontal, text: qsTr("Horizontal") }]
|
||||
|
||||
textRole: "text"
|
||||
valueRole: "value"
|
||||
|
||||
onActivated: {
|
||||
gradientLine.model.setGradientOrientation(gradientOrientation.currentValue)
|
||||
colorEditor.updateThumbnail()
|
||||
@@ -1090,7 +1124,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: linearGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasLinearGradient() && colorEditor.shapeGradients
|
||||
|
||||
ControlsRow {
|
||||
@@ -1126,7 +1159,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: radialGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasRadialGradient()
|
||||
|
||||
ControlsRow {
|
||||
@@ -1170,7 +1202,6 @@ SecondColumnLayout {
|
||||
Column {
|
||||
id: concialGradientControls
|
||||
spacing: 10
|
||||
|
||||
visible: colorEditor.hasConicalGradient()
|
||||
|
||||
ControlsRow {
|
||||
|
@@ -36,18 +36,20 @@ Column {
|
||||
}
|
||||
|
||||
property int mode: ColorPicker.Mode.HSVA
|
||||
property color color
|
||||
property color color: "#303091"
|
||||
|
||||
property real red: 0
|
||||
property real green: 0
|
||||
property real blue: 0
|
||||
|
||||
property real hue: 0
|
||||
property real saturationHSL: 0
|
||||
property real saturationHSV: 0
|
||||
property real lightness: 0
|
||||
property real value: 0
|
||||
property real saturationHSL: 0.5
|
||||
property real saturationHSV: 0.5
|
||||
property real lightness: 0.5
|
||||
property real value: 0.5
|
||||
|
||||
property real alpha: 1
|
||||
|
||||
property bool achromatic: false
|
||||
|
||||
property int sliderMargins: 6
|
||||
property bool block: false
|
||||
|
||||
@@ -57,81 +59,90 @@ Column {
|
||||
|
||||
spacing: 10
|
||||
|
||||
onModeChanged: {
|
||||
onColorChanged: {
|
||||
if (root.block)
|
||||
return
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.color = Qt.rgba(root.color.r, root.color.g, root.color.b, root.alpha)
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
|
||||
if (root.color.hslHue !== -1)
|
||||
root.hue = root.color.hslHue
|
||||
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
root.lightness = root.color.hslLightness
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
if (root.color.hsvHue !== -1)
|
||||
root.hue = root.color.hsvHue
|
||||
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
root.value = root.color.hsvValue
|
||||
root.alpha = root.color.a
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
gradientOverlay.requestPaint()
|
||||
root.invalidateColor()
|
||||
}
|
||||
|
||||
onHueChanged: {
|
||||
if (root.mode === ColorPicker.Mode.HSLA)
|
||||
root.color.hslHue = root.hue
|
||||
else
|
||||
root.color.hsvHue = root.hue
|
||||
}
|
||||
onSaturationHSLChanged: {
|
||||
root.color.hslSaturation = root.saturationHSL
|
||||
invalidateColor()
|
||||
}
|
||||
onSaturationHSVChanged: {
|
||||
root.color.hsvSaturation = root.saturationHSV
|
||||
}
|
||||
onLightnessChanged: {
|
||||
root.color.hslLightness = root.lightness
|
||||
}
|
||||
onValueChanged: {
|
||||
root.color.hsvValue = root.value
|
||||
}
|
||||
onAlphaChanged: invalidateColor()
|
||||
onColorChanged: invalidateColor()
|
||||
|
||||
function invalidateColor() {
|
||||
if (root.block)
|
||||
return
|
||||
|
||||
root.block = true
|
||||
|
||||
if (root.color.hsvSaturation > 0.0
|
||||
&& root.color.hsvValue > 0.0
|
||||
&& root.color.hsvHue !== -1.0)
|
||||
root.hue = root.color.hsvHue
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.color = Qt.rgba(root.red, root.green, root.blue, root.alpha)
|
||||
// Set HSVA and HSLA
|
||||
if (root.color.hsvHue !== -1)
|
||||
root.hue = root.color.hsvHue // doesn't matter if hsvHue or hslHue
|
||||
|
||||
if (root.color.hslSaturation > 0.0
|
||||
&& root.color.hslLightness > 0.0
|
||||
&& root.color.hslHue !== -1.0)
|
||||
root.hue = root.color.hslHue
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0)
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0 && !root.achromatic)
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
if (root.color.hsvValue !== 0.0)
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
|
||||
if (root.color.hsvValue !== 0.0 && root.color.hsvValue !== 1.0 && !root.achromatic)
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
|
||||
root.lightness = root.color.hslLightness
|
||||
root.value = root.color.hsvValue
|
||||
|
||||
if (root.color.hslLightness === 0.0 || root.color.hslLightness === 1.0
|
||||
|| root.color.hsvValue === 0.0 || root.color.hsvValue === 1.0
|
||||
|| root.color.hsvHue === -1.0 || root.color.hslHue === -1.0)
|
||||
root.achromatic = true
|
||||
else
|
||||
root.achromatic = false
|
||||
|
||||
if (root.mode === ColorPicker.Mode.HSLA)
|
||||
root.lightness = root.color.hslLightness
|
||||
root.value = root.color.hsvValue
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
|
||||
else
|
||||
// Set RGBA and HSVA
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
|
||||
if (root.color.hsvValue !== 0.0)
|
||||
root.saturationHSV = root.color.hsvSaturation
|
||||
|
||||
root.value = root.color.hsvValue
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
// Set RGBA and HSLA
|
||||
root.red = root.color.r
|
||||
root.green = root.color.g
|
||||
root.blue = root.color.b
|
||||
|
||||
if (root.color.hslLightness !== 0.0 && root.color.hslLightness !== 1.0)
|
||||
root.saturationHSL = root.color.hslSaturation
|
||||
|
||||
root.lightness = root.color.hslLightness
|
||||
break
|
||||
}
|
||||
|
||||
luminanceSlider.value = (1.0 - root.value)
|
||||
hueSlider.value = root.hue
|
||||
@@ -142,21 +153,21 @@ Column {
|
||||
root.block = false
|
||||
}
|
||||
|
||||
function drawHSVA(ctx) {
|
||||
for (var row = 0; row < gradientOverlay.height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
var v = Math.abs(row - gradientOverlay.height) / gradientOverlay.height
|
||||
function drawHSVA(ctx, width, height, hue) {
|
||||
for (var row = 0; row < height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
var v = Math.abs(row - height) / height
|
||||
|
||||
gradient.addColorStop(0, Qt.hsva(root.hue, 0, v, 1))
|
||||
gradient.addColorStop(1, Qt.hsva(root.hue, 1, v, 1))
|
||||
gradient.addColorStop(0, Qt.hsva(hue, 0, v, 1))
|
||||
gradient.addColorStop(1, Qt.hsva(hue, 1, v, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, row, gradientOverlay.width, 1)
|
||||
ctx.fillRect(0, row, width, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function drawRGBA(ctx) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
function drawRGBA(ctx, width, height) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
gradient.addColorStop(0.000, Qt.rgba(1, 0, 0, 1))
|
||||
gradient.addColorStop(0.167, Qt.rgba(1, 1, 0, 1))
|
||||
gradient.addColorStop(0.333, Qt.rgba(0, 1, 0, 1))
|
||||
@@ -166,26 +177,26 @@ Column {
|
||||
gradient.addColorStop(1.000, Qt.rgba(1, 0, 0, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.height)
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
|
||||
gradient = ctx.createLinearGradient(0, 0, 0, gradientOverlay.height)
|
||||
gradient = ctx.createLinearGradient(0, 0, 0, height)
|
||||
gradient.addColorStop(0.000, Qt.rgba(0, 0, 0, 0))
|
||||
gradient.addColorStop(1.000, Qt.rgba(1, 1, 1, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.height)
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
}
|
||||
|
||||
function drawHSLA(ctx) {
|
||||
for (var row = 0; row < gradientOverlay.height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
|
||||
var l = Math.abs(row - gradientOverlay.height) / gradientOverlay.height
|
||||
function drawHSLA(ctx, width, height, hue) {
|
||||
for (var row = 0; row < height; row++) {
|
||||
var gradient = ctx.createLinearGradient(0, 0, width, 0)
|
||||
var l = Math.abs(row - height) / height
|
||||
|
||||
gradient.addColorStop(0, Qt.hsla(root.hue, 0, l, 1))
|
||||
gradient.addColorStop(1, Qt.hsla(root.hue, 1, l, 1))
|
||||
gradient.addColorStop(0, Qt.hsla(hue, 0, l, 1))
|
||||
gradient.addColorStop(1, Qt.hsla(hue, 1, l, 1))
|
||||
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillRect(0, row, gradientOverlay.width, 1)
|
||||
ctx.fillRect(0, row, width, 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,11 +222,12 @@ Column {
|
||||
id: gradientOverlay
|
||||
|
||||
anchors.fill: parent
|
||||
opacity: root.color.a
|
||||
opacity: root.alpha
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onHueChanged() { gradientOverlay.requestPaint() }
|
||||
function onModeChanged() { gradientOverlay.requestPaint() }
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
@@ -225,14 +237,14 @@ Column {
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.drawRGBA(ctx)
|
||||
root.drawRGBA(ctx, gradientOverlay.width, gradientOverlay.height)
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.drawHSLA(ctx)
|
||||
root.drawHSLA(ctx, gradientOverlay.width, gradientOverlay.height, root.hue)
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.drawHSVA(ctx)
|
||||
root.drawHSVA(ctx, gradientOverlay.width, gradientOverlay.height, root.hue)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -244,9 +256,14 @@ Column {
|
||||
id: pickerCross
|
||||
|
||||
property color strokeStyle: "lightGray"
|
||||
property string loadImageUrl: "images/checkers.png"
|
||||
property int radius: 10
|
||||
|
||||
Component.onCompleted: pickerCross.loadImage(pickerCross.loadImageUrl)
|
||||
onImageLoaded: pickerCross.requestPaint()
|
||||
|
||||
opacity: 0.8
|
||||
anchors.fill: parent
|
||||
anchors.margins: -pickerCross.radius
|
||||
antialiasing: true
|
||||
|
||||
Connections {
|
||||
@@ -261,35 +278,63 @@ Column {
|
||||
ctx.save()
|
||||
ctx.clearRect(0, 0, pickerCross.width, pickerCross.height)
|
||||
|
||||
var yy, xx = 0
|
||||
var normX, normY = 0
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
yy = pickerCross.height - root.saturationHSV * pickerCross.height
|
||||
xx = root.hue * pickerCross.width
|
||||
normX = root.hue
|
||||
normY = 1.0 - root.saturationHSV
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
yy = pickerCross.height - root.lightness * pickerCross.height
|
||||
xx = root.saturationHSL * pickerCross.width
|
||||
normX = root.saturationHSL
|
||||
normY = 1.0 - root.lightness
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
yy = pickerCross.height - root.value * pickerCross.height
|
||||
xx = root.saturationHSV * pickerCross.width
|
||||
normX = root.saturationHSV
|
||||
normY = 1.0 - root.value
|
||||
break
|
||||
}
|
||||
|
||||
ctx.strokeStyle = pickerCross.strokeStyle
|
||||
ctx.lineWidth = 1
|
||||
var width = pickerCross.width - pickerCross.radius * 2
|
||||
var height = pickerCross.height - pickerCross.radius * 2
|
||||
|
||||
var x = normX * width
|
||||
var y = normY * height
|
||||
|
||||
var centerX = pickerCross.radius + x
|
||||
var centerY = pickerCross.radius + y
|
||||
|
||||
// Draw checkerboard
|
||||
if (isImageLoaded(pickerCross.loadImageUrl)) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(centerX, centerY, pickerCross.radius, 0, 2 * Math.PI)
|
||||
ctx.clip()
|
||||
|
||||
var pattern = context.createPattern(pickerCross.loadImageUrl, 'repeat')
|
||||
context.fillStyle = pattern
|
||||
|
||||
ctx.fillRect(x, y, pickerCross.radius * 2, pickerCross.radius * 2)
|
||||
}
|
||||
|
||||
// Draw current color
|
||||
if (root.mode === ColorPicker.Mode.RGBA)
|
||||
ctx.fillStyle = Qt.hsva(root.hue, root.saturationHSV, 1, root.alpha)
|
||||
else
|
||||
ctx.fillStyle = root.color
|
||||
|
||||
ctx.fillRect(x, y, pickerCross.radius * 2, pickerCross.radius * 2)
|
||||
|
||||
// Draw black and white circle
|
||||
ctx.lineWidth = 2
|
||||
ctx.strokeStyle = "black"
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, yy)
|
||||
ctx.lineTo(pickerCross.width, yy)
|
||||
ctx.arc(centerX, centerY, pickerCross.radius, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.strokeStyle = "white"
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(xx, 0)
|
||||
ctx.lineTo(xx, pickerCross.height)
|
||||
ctx.arc(centerX, centerY, pickerCross.radius - 2, 0, 2 * Math.PI)
|
||||
ctx.stroke()
|
||||
|
||||
ctx.restore()
|
||||
@@ -298,31 +343,48 @@ Column {
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: -pickerCross.radius
|
||||
preventStealing: true
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||
|
||||
onPositionChanged: function(mouse) {
|
||||
if (mouseArea.pressed && mouse.buttons === Qt.LeftButton) {
|
||||
var xx = Math.max(0, Math.min(mouse.x, parent.width))
|
||||
var yy = Math.max(0, Math.min(mouse.y, parent.height))
|
||||
// Generate color values from mouse position
|
||||
|
||||
// Clip/limit to margin
|
||||
var x = Math.max(0, Math.min(mouse.x - pickerCross.radius, parent.width))
|
||||
var y = Math.max(0, Math.min(mouse.y - pickerCross.radius, parent.height))
|
||||
|
||||
var normX = x / parent.width
|
||||
var normY = y / parent.height
|
||||
|
||||
switch (root.mode) {
|
||||
case ColorPicker.Mode.RGBA:
|
||||
root.saturationHSV = 1.0 - yy / parent.height
|
||||
root.hue = xx / parent.width
|
||||
var tmpColor = Qt.hsva(normX, // hue
|
||||
1.0 - normY, // saturation
|
||||
root.value,
|
||||
root.alpha)
|
||||
|
||||
root.hue = normX
|
||||
root.saturationHSV = 1.0 - normY
|
||||
|
||||
root.red = tmpColor.r
|
||||
root.green = tmpColor.g
|
||||
root.blue = tmpColor.b
|
||||
break
|
||||
case ColorPicker.Mode.HSLA:
|
||||
root.saturationHSL = xx / parent.width
|
||||
root.lightness = 1.0 - yy / parent.height
|
||||
root.saturationHSL = normX
|
||||
root.lightness = 1.0 - normY
|
||||
break
|
||||
case ColorPicker.Mode.HSVA:
|
||||
default:
|
||||
root.saturationHSV = xx / parent.width
|
||||
root.value = 1.0 - yy / parent.height
|
||||
root.saturationHSV = normX
|
||||
root.value = 1.0 - normY
|
||||
break
|
||||
}
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
}
|
||||
onPressed: function(mouse) {
|
||||
@@ -345,9 +407,11 @@ Column {
|
||||
id: hueSlider
|
||||
visible: root.mode !== ColorPicker.Mode.RGBA
|
||||
width: parent.width
|
||||
onValueChanged: {
|
||||
onMoved: {
|
||||
if (root.hue !== hueSlider.value)
|
||||
root.hue = hueSlider.value
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
@@ -356,10 +420,21 @@ Column {
|
||||
id: luminanceSlider
|
||||
visible: root.mode === ColorPicker.Mode.RGBA
|
||||
width: parent.width
|
||||
color: Qt.hsva(root.hue, root.color.hsvSaturation, 1, 1)
|
||||
onValueChanged: {
|
||||
if (root.value !== luminanceSlider.value)
|
||||
color: Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
|
||||
onMoved: {
|
||||
if (root.value !== (1.0 - luminanceSlider.value))
|
||||
root.value = (1.0 - luminanceSlider.value)
|
||||
|
||||
var tmpColor = Qt.hsva(root.hue,
|
||||
root.saturationHSV,
|
||||
root.value,
|
||||
root.alpha)
|
||||
|
||||
root.red = tmpColor.r
|
||||
root.green = tmpColor.g
|
||||
root.blue = tmpColor.b
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
@@ -367,10 +442,12 @@ Column {
|
||||
OpacitySlider {
|
||||
id: opacitySlider
|
||||
width: parent.width
|
||||
color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1)
|
||||
onValueChanged: {
|
||||
if (root.alpha !== opacitySlider.value)
|
||||
color: root.color
|
||||
onMoved: {
|
||||
if (root.alpha !== (1.0 - opacitySlider.value))
|
||||
root.alpha = (1.0 - opacitySlider.value)
|
||||
|
||||
root.invalidateColor()
|
||||
}
|
||||
onClicked: root.updateColor()
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@ Item {
|
||||
property alias hover: spinBox.hover
|
||||
|
||||
signal valueModified
|
||||
signal dragStarted
|
||||
signal indicatorPressed
|
||||
|
||||
width: 90
|
||||
implicitHeight: spinBox.height
|
||||
@@ -48,9 +50,13 @@ Item {
|
||||
StudioControls.RealSpinBox {
|
||||
id: spinBox
|
||||
|
||||
onDragStarted: hideCursor()
|
||||
onDragStarted: {
|
||||
hideCursor()
|
||||
wrapper.dragStarted()
|
||||
}
|
||||
onDragEnded: restoreCursor()
|
||||
onDragging: holdCursorInPlace()
|
||||
onIndicatorPressed: wrapper.indicatorPressed()
|
||||
|
||||
property bool hasSlider: spinBox.sliderIndicatorVisible
|
||||
|
||||
|
@@ -96,13 +96,12 @@ Item {
|
||||
height: 80
|
||||
width: parent.width
|
||||
|
||||
property int effectiveWidth: width - 10
|
||||
property int effectiveWidth: colorLine.width - 10
|
||||
property int selectedIndex: 0
|
||||
|
||||
function select(index) {
|
||||
for (var i = 0; i < repeater.model.count; i++) {
|
||||
for (var i = 0; i < repeater.model.count; i++)
|
||||
repeater.itemAt(i).item.highlighted = false
|
||||
}
|
||||
|
||||
if (repeater.model.count < index + 1)
|
||||
return
|
||||
@@ -113,11 +112,12 @@ Item {
|
||||
gradientModel.lock()
|
||||
root.currentColor = repeater.itemAt(index).item.color
|
||||
gradientModel.unlock()
|
||||
|
||||
root.selectedNodeChanged()
|
||||
}
|
||||
|
||||
function invalidate() {
|
||||
var gradientString = "import QtQuick 2.15; Gradient {"
|
||||
var gradientString = "import QtQuick 2.15; Gradient { orientation: Gradient.Horizontal;"
|
||||
|
||||
for (var i = 0; i < gradientModel.count; i++) {
|
||||
gradientString += "GradientStop {}"
|
||||
@@ -209,21 +209,21 @@ Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: gradientRectangle
|
||||
smooth: true
|
||||
x: 0
|
||||
y: 16
|
||||
radius: 1
|
||||
border.color: "#555555"
|
||||
border.width: 1
|
||||
width: parent.height
|
||||
height: parent.width
|
||||
anchors.fill: parent
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
border.width: StudioTheme.Values.border
|
||||
gradient: Gradient {
|
||||
id: gradient
|
||||
}
|
||||
transformOrigin: Item.TopLeft
|
||||
rotation: 270
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,6 +270,13 @@ Item {
|
||||
|
||||
onXChanged: gradientStopHandle.refreshToolTip(gradientStopHandle.toolTipVisible)
|
||||
|
||||
Image {
|
||||
width: 10
|
||||
height: 10
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rectangle
|
||||
width: 10
|
||||
@@ -277,7 +284,6 @@ Item {
|
||||
color: "red"
|
||||
border.color: "gray"
|
||||
border.width: 1
|
||||
radius: 1
|
||||
}
|
||||
|
||||
Canvas {
|
||||
|
@@ -1,50 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Image {
|
||||
id: root
|
||||
signal clicked
|
||||
visible: colorEditor.shapeGradients && parent.checked
|
||||
width: 8
|
||||
height: 4
|
||||
source: "image://icons/down-arrow"
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.bottom
|
||||
anchors.topMargin: 2
|
||||
opacity: popupRegion.containsMouse ? 1 : 0.8
|
||||
|
||||
ToolTipArea {
|
||||
id: popupRegion
|
||||
|
||||
onClicked: root.clicked()
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
anchors.margins: -2
|
||||
tooltip: qsTr("Edit Gradient Properties")
|
||||
}
|
||||
}
|
@@ -36,13 +36,14 @@ Item {
|
||||
property bool integer: false
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -50,7 +51,6 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
@@ -74,21 +74,20 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: Qt.hsva(value, 1, 1, 1)
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -98,21 +97,23 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -37,13 +37,14 @@ Item {
|
||||
property color color
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -51,17 +52,9 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
border.color: StudioTheme.Values.themeControlOutline
|
||||
@@ -69,7 +62,7 @@ Item {
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.000; color: root.color }
|
||||
GradientStop { position: 0.000; color: Qt.hsva(root.color.hsvHue, root.color.hsvSaturation, 1, 1) }
|
||||
GradientStop { position: 1.000; color: "black" }
|
||||
}
|
||||
}
|
||||
@@ -77,21 +70,20 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: Qt.hsva(root.color.hsvHue, root.color.hsvSaturation, root.color.hsvValue, 1)
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -101,19 +93,22 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,13 +37,14 @@ Item {
|
||||
property color color
|
||||
|
||||
signal clicked
|
||||
signal moved
|
||||
|
||||
height: StudioTheme.Values.hueSliderHeight
|
||||
|
||||
function updatePos() {
|
||||
if (root.maximum > root.minimum) {
|
||||
var pos = (track.width - handle.width) * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width - handle.width)
|
||||
var pos = track.width * (root.value - root.minimum) / (root.maximum - root.minimum)
|
||||
return Math.min(Math.max(pos, 0), track.width)
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
@@ -51,12 +52,10 @@ Item {
|
||||
|
||||
Item {
|
||||
id: track
|
||||
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Image {
|
||||
id: checkerboard
|
||||
anchors.fill: parent
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
@@ -69,7 +68,7 @@ Item {
|
||||
|
||||
gradient: Gradient {
|
||||
orientation: Gradient.Horizontal
|
||||
GradientStop { position: 0.000; color: root.color }
|
||||
GradientStop { position: 0.000; color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1) }
|
||||
GradientStop { position: 1.000; color: "transparent" }
|
||||
}
|
||||
}
|
||||
@@ -77,21 +76,27 @@ Item {
|
||||
Rectangle {
|
||||
id: handle
|
||||
width: StudioTheme.Values.hueSliderHandleWidth
|
||||
height: track.height - 4
|
||||
height: track.height + 4
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
smooth: true
|
||||
color: "transparent"
|
||||
radius: 2
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
x: root.updatePos()
|
||||
x: root.updatePos() - handle.width * 0.5
|
||||
y: 2
|
||||
z: 1
|
||||
|
||||
Image {
|
||||
anchors.fill: handleInside
|
||||
source: "images/checkers.png"
|
||||
fillMode: Image.Tile
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: handleInside
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
color: "transparent"
|
||||
color: root.color
|
||||
radius: 1
|
||||
border.color: "white"
|
||||
border.width: 1
|
||||
@@ -101,19 +106,22 @@ Item {
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
preventStealing: true
|
||||
|
||||
function calculateValue() {
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX, mouseArea.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / mouseArea.width + root.minimum
|
||||
var halfHandle = StudioTheme.Values.hueSliderHandleWidth * 0.5
|
||||
var handleX = Math.max(0, Math.min(mouseArea.mouseX - halfHandle, parent.width))
|
||||
var realValue = (root.maximum - root.minimum) * handleX / parent.width + root.minimum
|
||||
root.value = root.integer ? Math.round(realValue) : realValue
|
||||
root.moved()
|
||||
}
|
||||
|
||||
onPressed: calculateValue()
|
||||
onPressed: mouseArea.calculateValue()
|
||||
onReleased: root.clicked()
|
||||
onPositionChanged: {
|
||||
if (pressed)
|
||||
calculateValue()
|
||||
if (mouseArea.pressed)
|
||||
mouseArea.calculateValue()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,6 @@ FontExtrasSection 2.0 FontExtrasSection.qml
|
||||
FontSection 2.0 FontSection.qml
|
||||
FontStyleButtons 2.0 FontStyleButtons.qml
|
||||
GradientLine 2.0 GradientLine.qml
|
||||
GradientPopupIndicator 2.0 GradientPopupIndicator.qml
|
||||
GradientPresetList 2.0 GradientPresetList.qml
|
||||
GradientPresetTabContent 2.0 GradientPresetTabContent.qml
|
||||
GradientPropertySpinBox 2.0 GradientPropertySpinBox.qml
|
||||
|
@@ -121,7 +121,7 @@ T.ComboBox {
|
||||
ComboBox.ActivatedReason.Other)
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
onActivated: function(index) {
|
||||
myTimer.activatedIndex = index
|
||||
myTimer.restart()
|
||||
}
|
||||
|
@@ -81,6 +81,7 @@ T.SpinBox {
|
||||
signal dragStarted
|
||||
signal dragEnded
|
||||
signal dragging
|
||||
signal indicatorPressed
|
||||
|
||||
// Use custom wheel handling due to bugs
|
||||
property bool __wheelEnabled: false
|
||||
@@ -124,6 +125,7 @@ T.SpinBox {
|
||||
myControl: mySpinBox
|
||||
iconFlip: -1
|
||||
visible: mySpinBox.spinBoxIndicatorVisible
|
||||
onRealPressed: mySpinBox.indicatorPressed()
|
||||
onRealReleased: mySpinBox.realIncrease()
|
||||
onRealPressAndHold: mySpinBox.realIncrease()
|
||||
x: actionIndicator.width + StudioTheme.Values.border
|
||||
@@ -139,6 +141,7 @@ T.SpinBox {
|
||||
id: spinBoxIndicatorDown
|
||||
myControl: mySpinBox
|
||||
visible: mySpinBox.spinBoxIndicatorVisible
|
||||
onRealPressed: mySpinBox.indicatorPressed()
|
||||
onRealReleased: mySpinBox.realDecrease()
|
||||
onRealPressAndHold: mySpinBox.realDecrease()
|
||||
x: actionIndicator.width + StudioTheme.Values.border
|
||||
|
@@ -155,15 +155,17 @@ void PropertyEditorValue::setValueWithEmit(const QVariant &value)
|
||||
|
||||
void PropertyEditorValue::setValue(const QVariant &value)
|
||||
{
|
||||
const bool colorsEqual = cleverColorCompare(value, m_value);
|
||||
|
||||
if (!compareVariants(m_value, value) &&
|
||||
!cleverDoubleCompare(value, m_value) &&
|
||||
!cleverColorCompare(value, m_value))
|
||||
!colorsEqual)
|
||||
m_value = value;
|
||||
|
||||
fixAmbigousColorNames(modelNode(), name(), &m_value);
|
||||
fixUrl(modelNode(), name(), &m_value);
|
||||
|
||||
if (m_value.isValid())
|
||||
if (m_value.isValid() && !colorsEqual)
|
||||
emit valueChangedQml();
|
||||
|
||||
emit isExplicitChanged();
|
||||
|
Reference in New Issue
Block a user