QmlDesigner: Add RGB und HSV picker

* Add modes to color picker
* Add color picker for RGBA mode
* Add color picker for HSVA mode
* Add luminance slider for RGBA mode

Change-Id: I0bb1dbb67b7c18d156eee0d4e07cfa942162f832
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Henning Gruendl
2021-07-16 15:55:28 +02:00
committed by Henning Gründl
parent 4895eb346a
commit 6fef74a8cb
4 changed files with 426 additions and 121 deletions

View File

@@ -413,7 +413,7 @@ SecondColumnLayout {
id: transparentIndicator id: transparentIndicator
icon: StudioTheme.Constants.transparent icon: StudioTheme.Constants.transparent
pixelSize: StudioTheme.Values.myIconFontSize * 1.4 pixelSize: StudioTheme.Values.myIconFontSize * 1.4
tooltip: qsTr("Transparent TODO") tooltip: qsTr("Transparent")
onClicked: { onClicked: {
colorPicker.alpha = 0 colorPicker.alpha = 0
colorPicker.updateColor() colorPicker.updateColor()
@@ -575,22 +575,29 @@ SecondColumnLayout {
onRightMouseButtonClicked: contextMenu.popup(colorPicker) onRightMouseButtonClicked: contextMenu.popup(colorPicker)
onColorInvalidated: { onColorInvalidated: {
if (colorPicker.saturation > 0.0 && colorPicker.lightness > 0.0) { switch (colorPicker.mode) {
hueSpinBox.value = colorPicker.hue case ColorPicker.Mode.HSLA:
hslHueSpinBox.value = colorPicker.hue
hslSaturationSpinBox.value = colorPicker.saturationHSL
hslLightnessSpinBox.value = colorPicker.lightness
hslAlphaSpinBox.value = colorPicker.alpha
break
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
case ColorPicker.Mode.HSVA:
default:
hsvHueSpinBox.value = colorPicker.hue
hsvSaturationSpinBox.value = colorPicker.saturationHSV
hsvValueSpinBox.value = colorPicker.value
hsvAlphaSpinBox.value = colorPicker.alpha
break
} }
if (colorPicker.lightness > 0.0)
saturationSpinBox.value = colorPicker.saturation
else
colorPicker.saturation = saturationSpinBox.value
lightnessSpinBox.value = colorPicker.lightness
hslaAlphaSpinBox.value = colorPicker.alpha
redSpinBox.value = (colorPicker.color.r * 255)
greenSpinBox.value = (colorPicker.color.g * 255)
blueSpinBox.value = (colorPicker.color.b * 255)
rgbaAlphaSpinBox.value = (colorPicker.alpha * 255)
} }
} }
@@ -766,29 +773,22 @@ SecondColumnLayout {
+ 4 * StudioTheme.Values.colorEditorPopupSpinBoxWidth + 4 * StudioTheme.Values.colorEditorPopupSpinBoxWidth
width: implicitWidth width: implicitWidth
actionIndicatorVisible: false actionIndicatorVisible: false
model: ["RGBA", "HSLA"] textRole: "text"
onActivated: { valueRole: "value"
switch (colorMode.currentText) { model: [
case "RGBA": { value: ColorPicker.Mode.HSVA, text: "HSVA" },
rgbaRow.visible = true { value: ColorPicker.Mode.RGBA, text: "RGBA" },
hslaRow.visible = false { value: ColorPicker.Mode.HSLA, text: "HSLA" }
break ]
case "HSLA":
rgbaRow.visible = false onActivated: colorPicker.mode = colorMode.currentValue
hslaRow.visible = true
break
default:
console.log("Unknown color mode selected.")
rgbaRow.visible = true
hslaRow.visible = false
}
}
} }
} }
RowLayout { RowLayout {
id: rgbaRow id: rgbaRow
visible: colorPicker.mode === ColorPicker.Mode.RGBA
Layout.fillWidth: true Layout.fillWidth: true
spacing: StudioTheme.Values.controlGap spacing: StudioTheme.Values.controlGap
@@ -847,7 +847,7 @@ SecondColumnLayout {
} }
DoubleSpinBox { DoubleSpinBox {
id: rgbaAlphaSpinBox id: rgbAlphaSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
stepSize: 1 stepSize: 1
@@ -856,7 +856,7 @@ SecondColumnLayout {
decimals: 0 decimals: 0
onValueModified: { onValueModified: {
var tmp = rgbaAlphaSpinBox.value / 255.0 var tmp = rgbAlphaSpinBox.value / 255.0
if (colorPicker.alpha !== tmp && !colorPicker.block) { if (colorPicker.alpha !== tmp && !colorPicker.block) {
colorPicker.alpha = tmp colorPicker.alpha = tmp
colorPicker.updateColor() colorPicker.updateColor()
@@ -868,49 +868,109 @@ SecondColumnLayout {
RowLayout { RowLayout {
id: hslaRow id: hslaRow
visible: false visible: colorPicker.mode === ColorPicker.Mode.HSLA
Layout.fillWidth: true Layout.fillWidth: true
spacing: StudioTheme.Values.controlGap spacing: StudioTheme.Values.controlGap
DoubleSpinBox { DoubleSpinBox {
id: hueSpinBox id: hslHueSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: { onValueModified: {
if (colorPicker.hue !== hueSpinBox.value && !colorPicker.block) { if (colorPicker.hue !== hslHueSpinBox.value
colorPicker.hue = hueSpinBox.value && !colorPicker.block) {
colorPicker.hue = hslHueSpinBox.value
colorPicker.updateColor() colorPicker.updateColor()
} }
} }
} }
DoubleSpinBox { DoubleSpinBox {
id: saturationSpinBox id: hslSaturationSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: { onValueModified: {
if (colorPicker.saturation !== saturationSpinBox.value && !colorPicker.block) { if (colorPicker.saturationHSL !== hslSaturationSpinBox.value
colorPicker.saturation = saturationSpinBox.value && !colorPicker.block) {
colorPicker.saturationHSL = hslSaturationSpinBox.value
colorPicker.updateColor() colorPicker.updateColor()
} }
} }
} }
DoubleSpinBox { DoubleSpinBox {
id: lightnessSpinBox id: hslLightnessSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: { onValueModified: {
if (colorPicker.lightness !== lightnessSpinBox.value && !colorPicker.block) { if (colorPicker.lightness !== hslLightnessSpinBox.value
colorPicker.lightness = lightnessSpinBox.value && !colorPicker.block) {
colorPicker.lightness = hslLightnessSpinBox.value
colorPicker.updateColor() colorPicker.updateColor()
} }
} }
} }
DoubleSpinBox { DoubleSpinBox {
id: hslaAlphaSpinBox id: hslAlphaSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: { onValueModified: {
if (colorPicker.alpha !== hslaAlphaSpinBox.value && !colorPicker.block) { if (colorPicker.alpha !== hslAlphaSpinBox.value
colorPicker.alpha = hslaAlphaSpinBox.value && !colorPicker.block) {
colorPicker.alpha = hslAlphaSpinBox.value
colorPicker.updateColor()
}
}
}
}
RowLayout {
id: hsvaRow
visible: colorPicker.mode === ColorPicker.Mode.HSVA
Layout.fillWidth: true
spacing: StudioTheme.Values.controlGap
DoubleSpinBox {
id: hsvHueSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: {
if (colorPicker.hue !== hsvHueSpinBox.value
&& !colorPicker.block) {
colorPicker.hue = hsvHueSpinBox.value
colorPicker.updateColor()
}
}
}
DoubleSpinBox {
id: hsvSaturationSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: {
if (colorPicker.saturationHSV !== hsvSaturationSpinBox.value
&& !colorPicker.block) {
colorPicker.saturationHSV = hsvSaturationSpinBox.value
colorPicker.updateColor()
}
}
}
DoubleSpinBox {
id: hsvValueSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: {
if (colorPicker.value !== hsvValueSpinBox.value
&& !colorPicker.block) {
colorPicker.value = hsvValueSpinBox.value
colorPicker.updateColor()
}
}
}
DoubleSpinBox {
id: hsvAlphaSpinBox
width: StudioTheme.Values.colorEditorPopupSpinBoxWidth
onValueModified: {
if (colorPicker.alpha !== hsvAlphaSpinBox.value
&& !colorPicker.block) {
colorPicker.alpha = hsvAlphaSpinBox.value
colorPicker.updateColor() colorPicker.updateColor()
} }
} }

View File

@@ -29,15 +29,26 @@ import StudioTheme 1.0 as StudioTheme
Column { Column {
id: root id: root
enum Mode {
HSVA,
RGBA,
HSLA
}
property int mode: ColorPicker.Mode.HSVA
property color color property color color
property real alpha: 1
property real hue: 0 property real hue: 0
property real saturation: 0 property real saturationHSL: 0
property real saturationHSV: 0
property real lightness: 0 property real lightness: 0
property real value: 0
property real alpha: 1
property bool achromatic: false
property int sliderMargins: 6 property int sliderMargins: 6
property bool block: false property bool block: false
signal updateColor signal updateColor
@@ -46,30 +57,84 @@ Column {
spacing: 10 spacing: 10
onAlphaChanged: invalidateColor() onModeChanged: {
onSaturationChanged: invalidateColor() switch (root.mode) {
onLightnessChanged: invalidateColor() case ColorPicker.Mode.RGBA:
onHueChanged: invalidateColor() root.color = Qt.rgba(root.color.r, root.color.g, root.color.b, root.alpha)
onColorChanged: { break
var myAlpha = root.color.a case ColorPicker.Mode.HSLA:
rgbToHsl(root.color) root.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
root.alpha = myAlpha break
case ColorPicker.Mode.HSVA:
default:
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
break
}
gradientOverlay.requestPaint()
} }
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() { function invalidateColor() {
if (root.block) if (root.block)
return return
root.block = true root.block = true
root.color = Qt.hsla(root.hue, if (root.color.hsvSaturation > 0.0
root.saturation, && root.color.hsvValue > 0.0
root.lightness, && root.color.hsvHue !== -1.0)
root.alpha) root.hue = root.color.hsvHue
if (root.saturation > 0.0 && root.lightness > 0.0) if (root.color.hslSaturation > 0.0
hueSlider.value = root.hue && 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.achromatic)
root.saturationHSL = root.color.hslSaturation
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.color = Qt.hsla(root.hue, root.saturationHSL, root.lightness, root.alpha)
else
root.color = Qt.hsva(root.hue, root.saturationHSV, root.value, root.alpha)
luminanceSlider.value = (1.0 - root.value)
hueSlider.value = root.hue
opacitySlider.value = (1.0 - root.alpha) opacitySlider.value = (1.0 - root.alpha)
root.colorInvalidated() root.colorInvalidated()
@@ -77,39 +142,51 @@ Column {
root.block = false root.block = false
} }
function rgbToHsl(color) { function drawHSVA(ctx) {
var r = color.r for (var row = 0; row < gradientOverlay.height; row++) {
var g = color.g var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width, 0)
var b = color.b var v = Math.abs(row - gradientOverlay.height) / gradientOverlay.height
var max = Math.max(r, g, b), min = Math.min(r, g, b) gradient.addColorStop(0, Qt.hsva(root.hue, 0, v, 1))
var h, s, l = (max + min) / 2 gradient.addColorStop(1, Qt.hsva(root.hue, 1, v, 1))
if (max === min) { ctx.fillStyle = gradient
h = 0 ctx.fillRect(0, row, gradientOverlay.width, 1)
s = 0
} else {
var d = max - min
s = l > 0.5 ? d / (2 - max - min) : d / (max + min)
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6
} }
}
root.block = true function drawRGBA(ctx) {
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.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))
gradient.addColorStop(0.500, Qt.rgba(0, 1, 1, 1))
gradient.addColorStop(0.667, Qt.rgba(0, 0, 1, 1))
gradient.addColorStop(0.833, Qt.rgba(1, 0, 1, 1))
gradient.addColorStop(1.000, Qt.rgba(1, 0, 0, 1))
if (s > 0) ctx.fillStyle = gradient
root.hue = h ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.height)
root.saturation = s gradient = ctx.createLinearGradient(0, 0, 0, gradientOverlay.height)
root.lightness = l gradient.addColorStop(0.000, Qt.rgba(0, 0, 0, 0))
gradient.addColorStop(1.000, Qt.rgba(1, 1, 1, 1))
root.block = false ctx.fillStyle = gradient
invalidateColor() ctx.fillRect(0, 0, gradientOverlay.width, gradientOverlay.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
gradient.addColorStop(0, Qt.hsla(root.hue, 0, l, 1))
gradient.addColorStop(1, Qt.hsla(root.hue, 1, l, 1))
ctx.fillStyle = gradient
ctx.fillRect(0, row, gradientOverlay.width, 1)
}
} }
Rectangle { Rectangle {
@@ -133,26 +210,30 @@ Column {
Canvas { Canvas {
id: gradientOverlay id: gradientOverlay
property real hue: root.hue
anchors.fill: parent anchors.fill: parent
opacity: root.alpha opacity: root.color.a
Connections {
target: root
function onHueChanged() { gradientOverlay.requestPaint() }
}
onHueChanged: requestPaint()
onPaint: { onPaint: {
var ctx = gradientOverlay.getContext('2d') var ctx = gradientOverlay.getContext('2d')
ctx.save() ctx.save()
ctx.clearRect(0, 0, gradientOverlay.width, gradientOverlay.height) ctx.clearRect(0, 0, gradientOverlay.width, gradientOverlay.height)
for (var row = 0; row < gradientOverlay.height; row++) { switch (root.mode) {
var gradient = ctx.createLinearGradient(0, 0, gradientOverlay.width,0) case ColorPicker.Mode.RGBA:
var l = Math.abs(row - gradientOverlay.height) / gradientOverlay.height root.drawRGBA(ctx)
break
gradient.addColorStop(0, Qt.hsla(gradientOverlay.hue, 0, l, 1)) case ColorPicker.Mode.HSLA:
gradient.addColorStop(1, Qt.hsla(gradientOverlay.hue, 1, l, 1)) root.drawHSLA(ctx)
break
ctx.fillStyle = gradient case ColorPicker.Mode.HSVA:
ctx.fillRect(0, row, gradientOverlay.width, 1) default:
root.drawHSVA(ctx)
break
} }
ctx.restore() ctx.restore()
@@ -162,25 +243,41 @@ Column {
Canvas { Canvas {
id: pickerCross id: pickerCross
property real cavnasSaturation: root.saturation
property real canvasLightness: root.lightness
property color strokeStyle: "lightGray" property color strokeStyle: "lightGray"
opacity: 0.8 opacity: 0.8
anchors.fill: parent anchors.fill: parent
antialiasing: true antialiasing: true
onCavnasSaturationChanged: requestPaint(); Connections {
onCanvasLightnessChanged: requestPaint(); target: root
function onColorInvalidated() { pickerCross.requestPaint() }
function onColorChanged() { pickerCross.requestPaint() }
function onModeChanged() { pickerCross.requestPaint() }
}
onPaint: { onPaint: {
var ctx = pickerCross.getContext('2d') var ctx = pickerCross.getContext('2d')
ctx.save() ctx.save()
ctx.clearRect(0, 0, pickerCross.width, pickerCross.height) ctx.clearRect(0, 0, pickerCross.width, pickerCross.height)
var yy = pickerCross.height -root.lightness * pickerCross.height var yy, xx = 0
var xx = root.saturation * pickerCross.width
switch (root.mode) {
case ColorPicker.Mode.RGBA:
yy = pickerCross.height - root.saturationHSV * pickerCross.height
xx = root.hue * pickerCross.width
break
case ColorPicker.Mode.HSLA:
yy = pickerCross.height - root.lightness * pickerCross.height
xx = root.saturationHSL * pickerCross.width
break
case ColorPicker.Mode.HSVA:
default:
yy = pickerCross.height - root.value * pickerCross.height
xx = root.saturationHSV * pickerCross.width
break
}
ctx.strokeStyle = pickerCross.strokeStyle ctx.strokeStyle = pickerCross.strokeStyle
ctx.lineWidth = 1 ctx.lineWidth = 1
@@ -200,24 +297,37 @@ Column {
} }
MouseArea { MouseArea {
id: mapMouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
preventStealing: true preventStealing: true
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton
onPositionChanged: function(mouse) { onPositionChanged: function(mouse) {
if (pressed && mouse.buttons === Qt.LeftButton) { if (mouseArea.pressed && mouse.buttons === Qt.LeftButton) {
var xx = Math.max(0, Math.min(mouse.x, parent.width)) var xx = Math.max(0, Math.min(mouse.x, parent.width))
var yy = Math.max(0, Math.min(mouse.y, parent.height)) var yy = Math.max(0, Math.min(mouse.y, parent.height))
root.lightness = 1.0 - yy / parent.height switch (root.mode) {
root.saturation = xx / parent.width case ColorPicker.Mode.RGBA:
root.saturationHSV = 1.0 - yy / parent.height
root.hue = xx / parent.width
break
case ColorPicker.Mode.HSLA:
root.saturationHSL = xx / parent.width
root.lightness = 1.0 - yy / parent.height
break
case ColorPicker.Mode.HSVA:
default:
root.saturationHSV = xx / parent.width
root.value = 1.0 - yy / parent.height
break
}
} }
} }
onPressed: function(mouse) { onPressed: function(mouse) {
if (mouse.button === Qt.LeftButton) if (mouse.button === Qt.LeftButton)
positionChanged(mouse) mouseArea.positionChanged(mouse)
} }
onReleased: function(mouse) { onReleased: function(mouse) {
if (mouse.button === Qt.LeftButton) if (mouse.button === Qt.LeftButton)
@@ -233,10 +343,23 @@ Column {
HueSlider { HueSlider {
id: hueSlider id: hueSlider
visible: root.mode !== ColorPicker.Mode.RGBA
width: parent.width width: parent.width
onValueChanged: { onValueChanged: {
if (root.hue !== value) if (root.hue !== hueSlider.value)
root.hue = value root.hue = hueSlider.value
}
onClicked: root.updateColor()
}
LuminanceSlider {
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)
root.value = (1.0 - luminanceSlider.value)
} }
onClicked: root.updateColor() onClicked: root.updateColor()
} }
@@ -246,8 +369,8 @@ Column {
width: parent.width width: parent.width
color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1) color: Qt.rgba(root.color.r, root.color.g, root.color.b, 1)
onValueChanged: { onValueChanged: {
if (root.alpha !== value) if (root.alpha !== opacitySlider.value)
root.alpha = (1.0 - value) root.alpha = (1.0 - opacitySlider.value)
} }
onClicked: root.updateColor() onClicked: root.updateColor()
} }

View File

@@ -0,0 +1,121 @@
/****************************************************************************
**
** 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 StudioTheme 1.0 as StudioTheme
Item {
id: root
property real value: 1
property real minimum: 0
property real maximum: 1
property bool pressed: mouseArea.pressed
property bool integer: false
property color color
signal clicked
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)
} else {
return 0
}
}
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
border.width: StudioTheme.Values.border
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop { position: 0.000; color: root.color }
GradientStop { position: 1.000; color: "black" }
}
}
Rectangle {
id: handle
width: StudioTheme.Values.hueSliderHandleWidth
height: track.height - 4
anchors.verticalCenter: parent.verticalCenter
smooth: true
color: "transparent"
radius: 2
border.color: "black"
border.width: 1
x: root.updatePos()
y: 2
z: 1
Rectangle {
anchors.fill: parent
anchors.margins: 1
color: "transparent"
radius: 1
border.color: "white"
border.width: 1
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
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
root.value = root.integer ? Math.round(realValue) : realValue
}
onPressed: calculateValue()
onReleased: root.clicked()
onPositionChanged: {
if (pressed)
calculateValue()
}
}
}
}

View File

@@ -45,6 +45,7 @@ Label 2.0 Label.qml
LineEdit 2.0 LineEdit.qml LineEdit 2.0 LineEdit.qml
LinkIndicator2D 2.0 LinkIndicator2D.qml LinkIndicator2D 2.0 LinkIndicator2D.qml
ListViewComboBox 2.0 ListViewComboBox.qml ListViewComboBox 2.0 ListViewComboBox.qml
LuminanceSlider 2.0 LuminanceSlider.qml
MarginSection 2.0 MarginSection.qml MarginSection 2.0 MarginSection.qml
MultiIconLabel 2.0 MultiIconLabel.qml MultiIconLabel 2.0 MultiIconLabel.qml
OpacitySlider 2.0 OpacitySlider.qml OpacitySlider 2.0 OpacitySlider.qml