blob: 7181192407d7976c0d82178a3120e7f32f325d31 [file] [log] [blame]
/*****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Add-On Graphical Effects module.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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.
**
** $QT_END_LICENSE$
**
*****************************************************************************/
import QtQuick 2.12
Item {
id: root
property color color: Qt.hsla(hue, saturation, lightness, alpha)
property alias hue: hueSlider.value
property alias saturation: saturationSlider.value
property alias lightness: lightnessSlider.value
property alias alpha: alphaSlider.value
property bool showAlphaSlider: true
width: parent.width
height: 100
Image {
anchors.fill: map
source: "images/background.png"
fillMode: Image.Tile
}
Rectangle {
id: colorBox
anchors.fill: map
color: root.color
}
ShaderEffect {
id: map
anchors.left: parent.left
anchors.leftMargin: 10
anchors.top: parent.top
anchors.topMargin: 5
width: 68
height: width
opacity: 0.01
property real hue: root.hue
fragmentShader: "
varying mediump vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform highp float hue;
highp float hueToIntensity(highp float v1, highp float v2, highp float h) {
h = fract(h);
if (h < 1.0 / 6.0)
return v1 + (v2 - v1) * 6.0 * h;
else if (h < 1.0 / 2.0)
return v2;
else if (h < 2.0 / 3.0)
return v1 + (v2 - v1) * 6.0 * (2.0 / 3.0 - h);
return v1;
}
highp vec3 HSLtoRGB(highp vec3 color) {
highp float h = color.x;
highp float l = color.z;
highp float s = color.y;
if (s < 1.0 / 256.0)
return vec3(l, l, l);
highp float v1;
highp float v2;
if (l < 0.5)
v2 = l * (1.0 + s);
else
v2 = (l + s) - (s * l);
v1 = 2.0 * l - v2;
highp float d = 1.0 / 3.0;
highp float r = hueToIntensity(v1, v2, h + d);
highp float g = hueToIntensity(v1, v2, h);
highp float b = hueToIntensity(v1, v2, h - d);
return vec3(r, g, b);
}
void main() {
lowp vec4 c = vec4(1.0);
c.rgb = HSLtoRGB(vec3(hue, 1.0 - qt_TexCoord0.t, qt_TexCoord0.s));
gl_FragColor = c * qt_Opacity;
}
"
MouseArea {
id: mapMouseArea
anchors.fill: parent
hoverEnabled: true
preventStealing: true
onPositionChanged: {
if (pressed) {
var xx = Math.max(0, Math.min(mouse.x, parent.width))
var yy = Math.max(0, Math.min(mouse.y, parent.height))
root.saturation = 1.0 - yy / parent.height
root.lightness = xx / parent.width
}
}
onPressed: positionChanged(mouse)
onEntered: map.opacity = 1
onReleased: {
if (mouse.x < 0 || mouse.x > parent.width || mouse.y < 0 || mouse.y > parent.height) {
map.opacity = 0.01;
}
}
onExited: {
if (!pressed) {
map.opacity = 0.01;
}
}
}
Image {
id: crosshair
source: "images/slider_handle.png"
x: root.lightness * parent.width - width / 2
y: (1.0 - root.saturation) * parent.height - height / 2
}
}
Column {
anchors.left: parent.left
anchors.right: parent.right
ColorSlider {
id: hueSlider
minimum: 0.0
maximum: 1.0
value: 0.5
caption: "H"
trackItem: Rectangle {
width: parent.height
height: parent.width - 10
color: "red"
rotation: -90
transformOrigin: Item.TopLeft
y: width
x: 5
gradient: Gradient {
GradientStop {position: 0.000; color: Qt.rgba(1, 0, 0, 1)}
GradientStop {position: 0.167; color: Qt.rgba(1, 1, 0, 1)}
GradientStop {position: 0.333; color: Qt.rgba(0, 1, 0, 1)}
GradientStop {position: 0.500; color: Qt.rgba(0, 1, 1, 1)}
GradientStop {position: 0.667; color: Qt.rgba(0, 0, 1, 1)}
GradientStop {position: 0.833; color: Qt.rgba(1, 0, 1, 1)}
GradientStop {position: 1.000; color: Qt.rgba(1, 0, 0, 1)}
}
}
}
ColorSlider {
id: saturationSlider
minimum: 0.0
maximum: 1.0
value: 1.0
caption: "S"
handleOpacity: 1.5 - map.opacity
trackItem: Rectangle {
width: parent.height
height: parent.width - 10
color: "red"
rotation: -90
transformOrigin: Item.TopLeft
y: width
x: 5
gradient: Gradient {
GradientStop { position: 0; color: Qt.hsla(root.hue, 0.0, root.lightness, 1.0) }
GradientStop { position: 1; color: Qt.hsla(root.hue, 1.0, root.lightness, 1.0) }
}
}
}
ColorSlider {
id: lightnessSlider
minimum: 0.0
maximum: 1.0
value: 0.5
caption: "L"
handleOpacity: 1.5 - map.opacity
trackItem: Rectangle {
width: parent.height
height: parent.width - 10
color: "red"
rotation: -90
transformOrigin: Item.TopLeft
y: width
x: 5
gradient: Gradient {
GradientStop { position: 0; color: 'black' }
GradientStop { position: 0.5; color: Qt.hsla(root.hue, root.saturation, 0.5, 1.0) }
GradientStop { position: 1; color: 'white' }
}
}
}
ColorSlider {
id: alphaSlider
minimum: 0.0
maximum: 1.0
value: 1.0
caption: "A"
opacity: showAlphaSlider ? 1.0 : 0.0
trackItem:Item {
anchors.fill: parent
Image {
anchors {fill: parent; leftMargin: 5; rightMargin: 5}
source: "images/background.png"
fillMode: Image.TileHorizontally
}
Rectangle {
width: parent.height
height: parent.width - 10
color: "red"
rotation: -90
transformOrigin: Item.TopLeft
y: width
x: 5
gradient: Gradient {
GradientStop { position: 0; color: "transparent" }
GradientStop { position: 1; color: Qt.hsla(root.hue, root.saturation, root.lightness, 1.0) }
}
}
}
}
Label {
caption: "ARGB"
text: "#" + ((Math.ceil(root.alpha * 255) + 256).toString(16).substr(1, 2) + root.color.toString().substr(1, 6)).toUpperCase();
}
}
}