forked from qt-creator/qt-creator
qmljs: tests of the import architecture
First tests using the new qmljs testing architecture Change-Id: Id88fe53dddbb720c56cd0473e74f476862feb803 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
This commit is contained in:
@@ -207,7 +207,11 @@ public:
|
|||||||
void joinAllThreads();
|
void joinAllThreads();
|
||||||
|
|
||||||
QmlJS::Document::Ptr ensuredGetDocumentForPath(const QString &filePath);
|
QmlJS::Document::Ptr ensuredGetDocumentForPath(const QString &filePath);
|
||||||
|
static void importScan(QFutureInterface<void> &future,
|
||||||
|
WorkingCopy workingCopyInternal,
|
||||||
|
PathsAndLanguages paths,
|
||||||
|
ModelManagerInterface *modelManager,
|
||||||
|
bool emitDocChangedOnDisk);
|
||||||
public slots:
|
public slots:
|
||||||
virtual void resetCodeModel();
|
virtual void resetCodeModel();
|
||||||
void removeProjectInfo(ProjectExplorer::Project *project);
|
void removeProjectInfo(ProjectExplorer::Project *project);
|
||||||
@@ -243,11 +247,6 @@ protected:
|
|||||||
ModelManagerInterface *modelManager,
|
ModelManagerInterface *modelManager,
|
||||||
QmlJS::Dialect mainLanguage,
|
QmlJS::Dialect mainLanguage,
|
||||||
bool emitDocChangedOnDisk);
|
bool emitDocChangedOnDisk);
|
||||||
static void importScan(QFutureInterface<void> &future,
|
|
||||||
WorkingCopy workingCopyInternal,
|
|
||||||
PathsAndLanguages paths,
|
|
||||||
ModelManagerInterface *modelManager,
|
|
||||||
bool emitDocChangedOnDisk);
|
|
||||||
static void updateCppQmlTypes(QFutureInterface<void> &interface,
|
static void updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||||
ModelManagerInterface *qmlModelManager,
|
ModelManagerInterface *qmlModelManager,
|
||||||
CPlusPlus::Snapshot snapshot,
|
CPlusPlus::Snapshot snapshot,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS += check
|
SUBDIRS += check \
|
||||||
|
importscheck
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ import qbs
|
|||||||
|
|
||||||
Project {
|
Project {
|
||||||
name: "QML code model autotests"
|
name: "QML code model autotests"
|
||||||
references: ["check/check.qbs"]
|
references: ["check/check.qbs", "importscheck/importscheck.qbs"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real deviation: (radius + 1) / 3.3333
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real horizontalStep: 0.0
|
||||||
|
property real verticalStep: 0.0
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
property bool enableColor: false
|
||||||
|
property color color: "white"
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
property bool enableMask: false
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: rootItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real deviation: Math.max(0.1, rootItem.deviation)
|
||||||
|
property real radius: rootItem.radius
|
||||||
|
property int maxRadius: rootItem.maximumRadius
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real gaussianSum: 0.0
|
||||||
|
property real startIndex: 0.0
|
||||||
|
property real deltaFactor: (2 * radius - 1) / (maxRadius * 2 - 1)
|
||||||
|
property real expandX: transparentBorder && rootItem.horizontalStep > 0 ? maxRadius / width : 0.0
|
||||||
|
property real expandY: transparentBorder && rootItem.verticalStep > 0 ? maxRadius / height : 0.0
|
||||||
|
property variant gwts: []
|
||||||
|
property variant delta: Qt.vector3d(rootItem.horizontalStep * deltaFactor, rootItem.verticalStep * deltaFactor, startIndex);
|
||||||
|
property variant factor_0_2: Qt.vector3d(gwts[0], gwts[1], gwts[2]);
|
||||||
|
property variant factor_3_5: Qt.vector3d(gwts[3], gwts[4], gwts[5]);
|
||||||
|
property variant factor_6_8: Qt.vector3d(gwts[6], gwts[7], gwts[8]);
|
||||||
|
property variant factor_9_11: Qt.vector3d(gwts[9], gwts[10], gwts[11]);
|
||||||
|
property variant factor_12_14: Qt.vector3d(gwts[12], gwts[13], gwts[14]);
|
||||||
|
property variant factor_15_17: Qt.vector3d(gwts[15], gwts[16], gwts[17]);
|
||||||
|
property variant factor_18_20: Qt.vector3d(gwts[18], gwts[19], gwts[20]);
|
||||||
|
property variant factor_21_23: Qt.vector3d(gwts[21], gwts[22], gwts[23]);
|
||||||
|
property variant factor_24_26: Qt.vector3d(gwts[24], gwts[25], gwts[26]);
|
||||||
|
property variant factor_27_29: Qt.vector3d(gwts[27], gwts[28], gwts[29]);
|
||||||
|
property variant factor_30_32: Qt.vector3d(gwts[30], gwts[31], gwts[32]);
|
||||||
|
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
|
||||||
|
anchors.fill: rootItem
|
||||||
|
|
||||||
|
function gausFunc(x){
|
||||||
|
//Gaussian function = h(x):=(1/sqrt(2*3.14159*(D^2))) * %e^(-(x^2)/(2*(D^2)));
|
||||||
|
return (1.0 / Math.sqrt(2 * Math.PI * (Math.pow(shaderItem.deviation, 2)))) * Math.pow(Math.E, -((Math.pow(x, 2)) / (2 * (Math.pow(shaderItem.deviation, 2)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateGaussianWeights() {
|
||||||
|
gaussianSum = 0.0;
|
||||||
|
startIndex = -maxRadius + 0.5
|
||||||
|
|
||||||
|
var n = new Array(32);
|
||||||
|
for (var j = 0; j < 32; j++)
|
||||||
|
n[j] = 0;
|
||||||
|
|
||||||
|
var max = maxRadius * 2
|
||||||
|
var delta = (2 * radius - 1) / (max - 1);
|
||||||
|
for (var i = 0; i < max; i++) {
|
||||||
|
n[i] = gausFunc(-radius + 0.5 + i * delta);
|
||||||
|
gaussianSum += n[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
gwts = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
|
||||||
|
var shaderSteps = [
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.z; texCoord += shift;"
|
||||||
|
]
|
||||||
|
|
||||||
|
var shader = fragmentShaderBegin
|
||||||
|
var samples = maxRadius * 2
|
||||||
|
if (samples > 32) {
|
||||||
|
console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!")
|
||||||
|
samples = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < samples; i++) {
|
||||||
|
shader += shaderSteps[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
shader += fragmentShaderEnd
|
||||||
|
|
||||||
|
var colorizeSteps = ""
|
||||||
|
var colorizeUniforms = ""
|
||||||
|
|
||||||
|
var maskSteps = ""
|
||||||
|
var maskUniforms = ""
|
||||||
|
|
||||||
|
if (enableColor) {
|
||||||
|
colorizeSteps += "gl_FragColor = mix(vec4(0), color, clamp((gl_FragColor.a - 0.0) / (spread - 0.0), 0.0, 1.0));\n"
|
||||||
|
colorizeUniforms += "uniform highp vec4 color;\n"
|
||||||
|
colorizeUniforms += "uniform highp float spread;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableMask) {
|
||||||
|
maskSteps += "shift *= texture2D(maskSource, qt_TexCoord0).a;\n"
|
||||||
|
maskUniforms += "uniform sampler2D maskSource;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_STEPS", colorizeSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_UNIFORMS", colorizeUniforms)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_STEPS", maskSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_UNIFORMS", maskUniforms)
|
||||||
|
|
||||||
|
fragmentShader = shader
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeviationChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onRadiusChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onTransparentBorderChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMaxRadiusChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
property string fragmentShaderBegin: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec3 delta;
|
||||||
|
uniform highp vec3 factor_0_2;
|
||||||
|
uniform highp vec3 factor_3_5;
|
||||||
|
uniform highp vec3 factor_6_8;
|
||||||
|
uniform highp vec3 factor_9_11;
|
||||||
|
uniform highp vec3 factor_12_14;
|
||||||
|
uniform highp vec3 factor_15_17;
|
||||||
|
uniform highp vec3 factor_18_20;
|
||||||
|
uniform highp vec3 factor_21_23;
|
||||||
|
uniform highp vec3 factor_24_26;
|
||||||
|
uniform highp vec3 factor_27_29;
|
||||||
|
uniform highp vec3 factor_30_32;
|
||||||
|
uniform highp float gaussianSum;
|
||||||
|
uniform highp float expandX;
|
||||||
|
uniform highp float expandY;
|
||||||
|
PLACEHOLDER_MASK_UNIFORMS
|
||||||
|
PLACEHOLDER_COLORIZE_UNIFORMS
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 shift = vec2(delta.x, delta.y);
|
||||||
|
|
||||||
|
PLACEHOLDER_MASK_STEPS
|
||||||
|
|
||||||
|
highp float index = delta.z;
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
|
||||||
|
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
|
||||||
|
texCoord += (shift * index);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
"
|
||||||
|
|
||||||
|
property string fragmentShaderEnd: "
|
||||||
|
|
||||||
|
gl_FragColor /= gaussianSum;
|
||||||
|
|
||||||
|
PLACEHOLDER_COLORIZE_STEPS
|
||||||
|
|
||||||
|
gl_FragColor *= qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,478 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Blend
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blend
|
||||||
|
\brief Merges two source items by using a blend mode.
|
||||||
|
|
||||||
|
Blend mode can be selected with the \l{Blend::mode}{mode} property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li source
|
||||||
|
\li foregroundSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image Blend_bug_and_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Blend-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be the base when
|
||||||
|
\l{Blend::foregroundSource}{foregroundSource} is blended over it.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be blended over the
|
||||||
|
\l{Blend::source}{source}.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting foregroundSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant foregroundSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the mode which is used when foregroundSource is
|
||||||
|
blended over source. Values are case insensitive.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li mode
|
||||||
|
\li description
|
||||||
|
\row
|
||||||
|
\li normal
|
||||||
|
\li The pixel component values from foregroundSource are written
|
||||||
|
over source by using alpha blending.
|
||||||
|
\row
|
||||||
|
\li addition
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
added together and written.
|
||||||
|
\row
|
||||||
|
\li average
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
averaged and written.
|
||||||
|
\row
|
||||||
|
\li color
|
||||||
|
\li The lightness value from source is combined with hue and
|
||||||
|
saturation from foregroundSource and written.
|
||||||
|
\row
|
||||||
|
\li colorBurn
|
||||||
|
\li The darker pixels from source are darkened more, if both source
|
||||||
|
and foregroundSource pixels are light the result is light.
|
||||||
|
\row
|
||||||
|
\li colorDodge
|
||||||
|
\li The lighter pixels from source are lightened more, if both
|
||||||
|
source and foregroundSource pixels are dark the result is dark.
|
||||||
|
\row
|
||||||
|
\li darken
|
||||||
|
\li The darker pixel component value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li darkerColor
|
||||||
|
\li The lower luminance pixel rgb-value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li difference
|
||||||
|
\li The absolute pixel component value difference between source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li divide
|
||||||
|
\li The pixel component values from source is divided by the value
|
||||||
|
from foregroundSource and written.
|
||||||
|
\row
|
||||||
|
\li exclusion
|
||||||
|
\li The pixel component value difference with reduced contrast
|
||||||
|
between source and foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li hardLight
|
||||||
|
\li The pixel component values from source are lightened or darkened
|
||||||
|
according to foregroundSource values and written.
|
||||||
|
\row
|
||||||
|
\li hue
|
||||||
|
\li The hue value from foregroundSource is combined with saturation
|
||||||
|
and lightness from source and written.
|
||||||
|
\row
|
||||||
|
\li lighten
|
||||||
|
\li The lightest pixel component value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li lighterColor
|
||||||
|
\li The higher luminance pixel rgb-value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li lightness
|
||||||
|
\li The lightness value from foregroundSource is combined with hue
|
||||||
|
and saturation from source and written.
|
||||||
|
\row
|
||||||
|
\li multiply
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
multiplied together and written.
|
||||||
|
\row
|
||||||
|
\li negation
|
||||||
|
\li The inverted absolute pixel component value difference between
|
||||||
|
source and foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li saturation
|
||||||
|
\li The saturation value from foregroundSource is combined with hue
|
||||||
|
and lightness from source and written.
|
||||||
|
\row
|
||||||
|
\li screen
|
||||||
|
\li The pixel values from source and foregroundSource are negated,
|
||||||
|
then multiplied, negated again, and written.
|
||||||
|
\row
|
||||||
|
\li subtract
|
||||||
|
\li Pixel value from foregroundSource is subracted from source and
|
||||||
|
written.
|
||||||
|
\row
|
||||||
|
\li softLight
|
||||||
|
\li The pixel component values from source are lightened or darkened
|
||||||
|
slightly according to foregroundSource values and written.
|
||||||
|
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Example source
|
||||||
|
\li Example foregroundSource
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different mode values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode1.png
|
||||||
|
\li \image Blend_mode2.png
|
||||||
|
\li \image Blend_mode3.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: normal }
|
||||||
|
\li \b { mode: addition }
|
||||||
|
\li \b { mode: average }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode4.png
|
||||||
|
\li \image Blend_mode5.png
|
||||||
|
\li \image Blend_mode6.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: color }
|
||||||
|
\li \b { mode: colorBurn }
|
||||||
|
\li \b { mode: colorDodge }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode7.png
|
||||||
|
\li \image Blend_mode8.png
|
||||||
|
\li \image Blend_mode9.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: darken }
|
||||||
|
\li \b { mode: darkerColor }
|
||||||
|
\li \b { mode: difference }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode10.png
|
||||||
|
\li \image Blend_mode11.png
|
||||||
|
\li \image Blend_mode12.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: divide }
|
||||||
|
\li \b { mode: exclusion }
|
||||||
|
\li \b { mode: hardlight }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode13.png
|
||||||
|
\li \image Blend_mode14.png
|
||||||
|
\li \image Blend_mode15.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: hue }
|
||||||
|
\li \b { mode: lighten }
|
||||||
|
\li \b { mode: lighterColor }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode16.png
|
||||||
|
\li \image Blend_mode17.png
|
||||||
|
\li \image Blend_mode18.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: lightness }
|
||||||
|
\li \b { mode: negation }
|
||||||
|
\li \b { mode: multiply }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode19.png
|
||||||
|
\li \image Blend_mode20.png
|
||||||
|
\li \image Blend_mode21.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: saturation }
|
||||||
|
\li \b { mode: screen }
|
||||||
|
\li \b { mode: subtract }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode22.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: softLight }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property string mode: "normal"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in the
|
||||||
|
cache must be updated. Memory consumption is increased, because an extra
|
||||||
|
buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: backgroundSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: foregroundSourceProxy
|
||||||
|
input: rootItem.foregroundSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant backgroundSource: backgroundSourceProxy.output
|
||||||
|
property variant foregroundSource: foregroundSourceProxy.output
|
||||||
|
property string mode: rootItem.mode
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: fragmentShaderBegin + blendModeNormal + fragmentShaderEnd
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderBegin
|
||||||
|
|
||||||
|
switch (mode.toLowerCase()) {
|
||||||
|
case "addition" : shader += blendModeAddition; break;
|
||||||
|
case "average" : shader += blendModeAverage; break;
|
||||||
|
case "color" : shader += blendModeColor; break;
|
||||||
|
case "colorburn" : shader += blendModeColorBurn; break;
|
||||||
|
case "colordodge" : shader += blendModeColorDodge; break;
|
||||||
|
case "darken" : shader += blendModeDarken; break;
|
||||||
|
case "darkercolor" : shader += blendModeDarkerColor; break;
|
||||||
|
case "difference" : shader += blendModeDifference; break;
|
||||||
|
case "divide" : shader += blendModeDivide; break;
|
||||||
|
case "exclusion" : shader += blendModeExclusion; break;
|
||||||
|
case "hardlight" : shader += blendModeHardLight; break;
|
||||||
|
case "hue" : shader += blendModeHue; break;
|
||||||
|
case "lighten" : shader += blendModeLighten; break;
|
||||||
|
case "lightercolor" : shader += blendModeLighterColor; break;
|
||||||
|
case "lightness" : shader += blendModeLightness; break;
|
||||||
|
case "negation" : shader += blendModeNegation; break;
|
||||||
|
case "normal" : shader += blendModeNormal; break;
|
||||||
|
case "multiply" : shader += blendModeMultiply; break;
|
||||||
|
case "saturation" : shader += blendModeSaturation; break;
|
||||||
|
case "screen" : shader += blendModeScreen; break;
|
||||||
|
case "subtract" : shader += blendModeSubtract; break;
|
||||||
|
case "softlight" : shader += blendModeSoftLight; break;
|
||||||
|
default: shader += "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader += fragmentShaderEnd
|
||||||
|
fragmentShader = shader
|
||||||
|
|
||||||
|
// Workaraound for a bug just to make sure display gets updated when the mode changes.
|
||||||
|
backgroundSourceChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
buildFragmentShader()
|
||||||
|
}
|
||||||
|
|
||||||
|
onModeChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
}
|
||||||
|
|
||||||
|
property string blendModeAddition: "result.rgb = min(rgb1 + rgb2, 1.0);"
|
||||||
|
property string blendModeAverage: "result.rgb = 0.5 * (rgb1 + rgb2);"
|
||||||
|
property string blendModeColor: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).xy, RGBtoL(rgb1)));"
|
||||||
|
property string blendModeColorBurn: "result.rgb = clamp(1.0 - ((1.0 - rgb1) / max(vec3(1.0 / 256.0), rgb2)), vec3(0.0), vec3(1.0));"
|
||||||
|
property string blendModeColorDodge: "result.rgb = clamp(rgb1 / max(vec3(1.0 / 256.0), (1.0 - rgb2)), vec3(0.0), vec3(1.0));"
|
||||||
|
property string blendModeDarken: "result.rgb = min(rgb1, rgb2);"
|
||||||
|
property string blendModeDarkerColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb2 : rgb1;"
|
||||||
|
property string blendModeDifference: "result.rgb = abs(rgb1 - rgb2);"
|
||||||
|
property string blendModeDivide: "result.rgb = clamp(rgb1 / rgb2, 0.0, 1.0);"
|
||||||
|
property string blendModeExclusion: "result.rgb = rgb1 + rgb2 - 2.0 * rgb1 * rgb2;"
|
||||||
|
property string blendModeHardLight: "result.rgb = vec3(channelBlendHardLight(rgb1.r, rgb2.r), channelBlendHardLight(rgb1.g, rgb2.g), channelBlendHardLight(rgb1.b, rgb2.b));"
|
||||||
|
property string blendModeHue: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).x, RGBtoHSL(rgb1).yz));"
|
||||||
|
property string blendModeLighten: "result.rgb = max(rgb1, rgb2);"
|
||||||
|
property string blendModeLighterColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb1 : rgb2;"
|
||||||
|
property string blendModeLightness: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb1).xy, RGBtoL(rgb2)));"
|
||||||
|
property string blendModeMultiply: "result.rgb = rgb1 * rgb2;"
|
||||||
|
property string blendModeNegation: "result.rgb = 1.0 - abs(1.0 - rgb1 - rgb2);"
|
||||||
|
property string blendModeNormal: "result.rgb = rgb2; a = max(color1.a, color2.a);"
|
||||||
|
property string blendModeSaturation: "lowp vec3 hsl1 = RGBtoHSL(rgb1); result.rgb = HSLtoRGB(vec3(hsl1.x, RGBtoHSL(rgb2).y, hsl1.z));"
|
||||||
|
property string blendModeScreen: "result.rgb = 1.0 - (vec3(1.0) - rgb1) * (vec3(1.0) - rgb2);"
|
||||||
|
property string blendModeSubtract: "result.rgb = max(rgb1 - rgb2, vec3(0.0));"
|
||||||
|
property string blendModeSoftLight: "result.rgb = rgb1 * ((1.0 - rgb1) * rgb2 + (1.0 - (1.0 - rgb1) * (1.0 - rgb2)));"
|
||||||
|
|
||||||
|
property string fragmentShaderBegin: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D backgroundSource;
|
||||||
|
uniform lowp sampler2D foregroundSource;
|
||||||
|
|
||||||
|
highp float RGBtoL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
highp vec3 RGBtoHSL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float h = 0.0;
|
||||||
|
highp float s = 0.0;
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
highp float diff = cmax - cmin;
|
||||||
|
|
||||||
|
if (diff > 1.0 / 256.0) {
|
||||||
|
if (l < 0.5)
|
||||||
|
s = diff / (cmin + cmax);
|
||||||
|
else
|
||||||
|
s = diff / (2.0 - (cmin + cmax));
|
||||||
|
|
||||||
|
if (color.r == cmax)
|
||||||
|
h = (color.g - color.b) / diff;
|
||||||
|
else if (color.g == cmax)
|
||||||
|
h = 2.0 + (color.b - color.r) / diff;
|
||||||
|
else
|
||||||
|
h = 4.0 + (color.r - color.g) / diff;
|
||||||
|
|
||||||
|
h /= 6.0;
|
||||||
|
}
|
||||||
|
return vec3(h, s, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
lowp float channelBlendHardLight(lowp float c1, lowp float c2) {
|
||||||
|
return c2 > 0.5 ? (1.0 - (1.0 - 2.0 * (c2 - 0.5)) * (1.0 - c1)) : (2.0 * c1 * c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 result = vec4(0.0);
|
||||||
|
lowp vec4 color1 = texture2D(backgroundSource, qt_TexCoord0);
|
||||||
|
lowp vec4 color2 = texture2D(foregroundSource, qt_TexCoord0);
|
||||||
|
lowp vec3 rgb1 = color1.rgb / max(1.0/256.0, color1.a);
|
||||||
|
lowp vec3 rgb2 = color2.rgb / max(1.0/256.0, color2.a);
|
||||||
|
highp float a = max(color1.a, color1.a * color2.a);
|
||||||
|
"
|
||||||
|
|
||||||
|
property string fragmentShaderEnd: "
|
||||||
|
gl_FragColor.rgb = mix(rgb1, result.rgb, color2.a);
|
||||||
|
gl_FragColor.rbg *= a;
|
||||||
|
gl_FragColor.a = a;
|
||||||
|
gl_FragColor *= qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype BrightnessContrast
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Adjusts brightness and contrast.
|
||||||
|
|
||||||
|
This effect adjusts the source item colors.
|
||||||
|
Brightness adjustment changes the perceived luminance of the source item.
|
||||||
|
Contrast adjustment increases or decreases the color
|
||||||
|
and brightness variations.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image BrightnessContrast_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet BrightnessContrast-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source brightness is increased or
|
||||||
|
decreased.
|
||||||
|
|
||||||
|
The value ranges from -1.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different brightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_brightness1.png
|
||||||
|
\li \image BrightnessContrast_brightness2.png
|
||||||
|
\li \image BrightnessContrast_brightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { brightness: -0.25 }
|
||||||
|
\li \b { brightness: 0 }
|
||||||
|
\li \b { brightness: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l contrast: 0
|
||||||
|
\li \l contrast: 0
|
||||||
|
\li \l contrast: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real brightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source contrast is increased or
|
||||||
|
decreased. The decrease of the contrast is linear, but the increase is
|
||||||
|
applied with a non-linear curve to allow very high contrast adjustment at
|
||||||
|
the high end of the value range.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Contrast adjustment curve
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_contrast_graph.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
The value ranges from -1.0 to 1.0. By default, the property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different contrast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_contrast1.png
|
||||||
|
\li \image BrightnessContrast_contrast2.png
|
||||||
|
\li \image BrightnessContrast_contrast3.png
|
||||||
|
\row
|
||||||
|
\li \b { contrast: -0.5 }
|
||||||
|
\li \b { contrast: 0 }
|
||||||
|
\li \b { contrast: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l brightness: 0
|
||||||
|
\li \l brightness: 0
|
||||||
|
\li \l brightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real contrast: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real brightness: rootItem.brightness
|
||||||
|
property real contrast: rootItem.contrast
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
blending: !rootItem.cached
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float brightness;
|
||||||
|
uniform highp float contrast;
|
||||||
|
void main() {
|
||||||
|
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
|
||||||
|
pixelColor.rgb /= max(1.0/256.0, pixelColor.a);
|
||||||
|
highp float c = 1.0 + contrast;
|
||||||
|
highp float contrastGainFactor = 1.0 + c * c * c * c * step(0.0, contrast);
|
||||||
|
pixelColor.rgb = ((pixelColor.rgb - 0.5) * (contrastGainFactor * contrast + 1.0)) + 0.5;
|
||||||
|
pixelColor.rgb = mix(pixelColor.rgb, vec3(step(0.0, brightness)), abs(brightness));
|
||||||
|
gl_FragColor = vec4(pixelColor.rgb * pixelColor.a, pixelColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ColorOverlay
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the colors of the source item by applying an overlay color.
|
||||||
|
|
||||||
|
The effect is similar to what happens when a colorized glass is put on top
|
||||||
|
of a grayscale image. The color for the overlay is given in the RGBA format.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image ColorOverlay_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ColorOverlay-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
By default, the property is set to \c "transparent".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ColorOverlay_color1.png
|
||||||
|
\li \image ColorOverlay_color2.png
|
||||||
|
\li \image ColorOverlay_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #80ff0000 }
|
||||||
|
\li \b { color: #8000ff00 }
|
||||||
|
\li \b { color: #800000ff }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "transparent"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
void main() {
|
||||||
|
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
|
||||||
|
gl_FragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Colorize
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Sets the color in the HSL color space.
|
||||||
|
|
||||||
|
The effect is similar to what happens when a colorized glass is put on top
|
||||||
|
of a grayscale image. Colorize uses the hue, saturation, and lightness (HSL)
|
||||||
|
color space. You can specify a desired value for each property. You can
|
||||||
|
shift all HSL values with the
|
||||||
|
\l{QtGraphicalEffects1::HueSaturation}{HueSaturation} effect.
|
||||||
|
|
||||||
|
Alternatively, you can use the
|
||||||
|
\l{QtGraphicalEffects1::ColorOverlay}{ColorOverlay} effect to colorize the
|
||||||
|
source item in the RGBA color space.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Colorize_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Colorize-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the hue value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.0, which produces a slightly red color.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Allowed hue values
|
||||||
|
\row
|
||||||
|
\li \image Colorize_hue_scale.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different hue values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_hue1.png
|
||||||
|
\li \image Colorize_hue2.png
|
||||||
|
\li \image Colorize_hue3.png
|
||||||
|
\row
|
||||||
|
\li \b { hue: 0.2 }
|
||||||
|
\li \b { hue: 0.5 }
|
||||||
|
\li \b { hue: 0.8 }
|
||||||
|
\row
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real hue: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the saturation value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (desaturated) to 1.0 (saturated). By default,
|
||||||
|
the property is set to \c 1.0 (saturated).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different saturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_saturation1.png
|
||||||
|
\li \image Colorize_saturation2.png
|
||||||
|
\li \image Colorize_saturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { saturation: 0 }
|
||||||
|
\li \b { saturation: 0.5 }
|
||||||
|
\li \b { saturation: 1 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real saturation: 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source lightness value is increased
|
||||||
|
or decreased.
|
||||||
|
|
||||||
|
Unlike hue and saturation properties, lightness does not set the used
|
||||||
|
value, but it shifts the existing source pixel lightness value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decreased) to 1.0 (increased). By default,
|
||||||
|
the property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different lightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_lightness1.png
|
||||||
|
\li \image Colorize_lightness2.png
|
||||||
|
\li \image Colorize_lightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { lightness: -0.75 }
|
||||||
|
\li \b { lightness: 0 }
|
||||||
|
\li \b { lightness: 0.75 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real lightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real hue: rootItem.hue
|
||||||
|
property real saturation: rootItem.saturation
|
||||||
|
property real lightness: rootItem.lightness
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float hue;
|
||||||
|
uniform highp float saturation;
|
||||||
|
uniform highp float lightness;
|
||||||
|
|
||||||
|
highp float RGBtoL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 sample = texture2D(source, qt_TexCoord0);
|
||||||
|
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
|
||||||
|
highp float light = RGBtoL(sample.rgb);
|
||||||
|
highp float c = step(0.0, lightness);
|
||||||
|
sample.rgb = HSLtoRGB(vec3(hue, saturation, mix(light, c, abs(lightness))));
|
||||||
|
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ConicalGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a conical gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the specified angle and end at 360 degrees larger
|
||||||
|
angle value.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ConicalGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the starting angle where the color at the gradient
|
||||||
|
position of 0.0 is rendered. Colors at larger position values are
|
||||||
|
rendered into larger angle values and blended seamlessly. Angle values
|
||||||
|
increase clockwise.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_angle1.png
|
||||||
|
\li \image ConicalGradient_angle2.png
|
||||||
|
\li \image ConicalGradient_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0 }
|
||||||
|
\li \b { angle: 45 }
|
||||||
|
\li \b { angle: 185 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ConicalGradient::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ConicalGradient::verticalOffset
|
||||||
|
|
||||||
|
The horizontalOffset and verticalOffset properties define the offset in
|
||||||
|
pixels for the center point of the gradient compared to the item center.
|
||||||
|
|
||||||
|
The value ranges from -inf to inf. By default, the properties are set to \c
|
||||||
|
0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_horizontalOffset1.png
|
||||||
|
\li \image ConicalGradient_horizontalOffset2.png
|
||||||
|
\li \image ConicalGradient_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -50 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 50 }
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_maskSource1.png
|
||||||
|
\li \image ConicalGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: }
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors are specified as a set of GradientStop child items, each of which
|
||||||
|
defines a position on the gradient (from 0.0 to 1.0), and a color.
|
||||||
|
The position of each GradientStop is defined by the position property.
|
||||||
|
The color is defined by the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_gradient1.png
|
||||||
|
\li \image ConicalGradient_gradient2.png
|
||||||
|
\li \image ConicalGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: gradientRect
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
rotation: shaderItem.rotation
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant gradientSource: ShaderEffectSource {
|
||||||
|
sourceItem: gradientRect
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property real startAngle: (rootItem.angle - 90) * Math.PI/180
|
||||||
|
property variant center: Qt.point(0.5 + horizontalOffset / width, 0.5 + verticalOffset / height)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: startAngleChanged()
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform lowp sampler2D gradientSource;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp float startAngle;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const highp float PI = 3.14159265;
|
||||||
|
const highp float PIx2inv = 0.1591549;
|
||||||
|
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
|
||||||
|
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform lowp sampler2D gradientSource;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp float startAngle;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
const highp float PI = 3.14159265;
|
||||||
|
const highp float PIx2inv = 0.1591549;
|
||||||
|
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
|
||||||
|
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Desaturate
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Reduces the saturation of the colors.
|
||||||
|
|
||||||
|
Desaturated pixel values are calculated as averages of the original RGB
|
||||||
|
component values of the source item.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Desaturate_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Desaturate-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels to
|
||||||
|
the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source colors are desaturated.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no change) to 1.0 (desaturated). By default,
|
||||||
|
the property is set to \c 0.0 (no chnage).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different desaturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Desaturate_desaturation1.png
|
||||||
|
\li \image Desaturate_desaturation2.png
|
||||||
|
\li \image Desaturate_desaturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { desaturation: 0.0 }
|
||||||
|
\li \b { desaturation: 0.5 }
|
||||||
|
\li \b { desaturation: 1.0 }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real desaturation: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real desaturation: rootItem.desaturation
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float desaturation;
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
lowp float grayColor = (textureColor.r + textureColor.g + textureColor.b) / 3.0;
|
||||||
|
gl_FragColor = mix(textureColor, vec4(vec3(grayColor), textureColor.a), desaturation) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype DirectionalBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies blur effect to the specified direction.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
moving in the direction of the blur. Blur is applied to both sides of
|
||||||
|
each pixel, therefore setting the direction to 0 and 180 provides the
|
||||||
|
same result.
|
||||||
|
|
||||||
|
Other available motionblur effects are \l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
|
||||||
|
\l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image DirectionalBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet DirectionalBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the percieved amount of movement for each pixel.
|
||||||
|
The movement is divided evenly to both sides of each pixel.
|
||||||
|
|
||||||
|
The quality of the blur depends on \l{DirectionalBlur::samples}{samples}
|
||||||
|
property. If length value is large, more samples are needed to keep the
|
||||||
|
visual quality at high level.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to inf.
|
||||||
|
By default the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different length values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DirectionalBlur_length1.png
|
||||||
|
\li \image DirectionalBlur_length2.png
|
||||||
|
\li \image DirectionalBlur_length3.png
|
||||||
|
\row
|
||||||
|
\li \b { length: 0.0 }
|
||||||
|
\li \b { length: 32.0 }
|
||||||
|
\li \b { length: 48.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real length: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the direction for the blur. Blur is applied to
|
||||||
|
both sides of each pixel, therefore setting the direction to 0 and 180
|
||||||
|
produces the same result.
|
||||||
|
|
||||||
|
The value ranges from -180.0 to 180.0.
|
||||||
|
By default the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DirectionalBlur_angle1.png
|
||||||
|
\li \image DirectionalBlur_angle2.png
|
||||||
|
\li \image DirectionalBlur_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0.0 }
|
||||||
|
\li \b { angle: 45.0 }
|
||||||
|
\li \b { angle: 90.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real len: rootItem.length
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width * Math.cos((rootItem.angle + 90) * Math.PI/180), 1.0 / rootItem.height * Math.sin((rootItem.angle + 90) * Math.PI/180))
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1: 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float len;
|
||||||
|
uniform highp float samples;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 shift = delta * len / max(1.0, samples - 1.0);
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
texCoord -= shift * max(0.0, samples - 1.0) * 0.5;
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Displace
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-distortion
|
||||||
|
\brief Moves the pixels of the source item according to the given
|
||||||
|
displacement map.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li DisplacementSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Displace_map.png
|
||||||
|
\li \image Displace_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Displace-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item for the pixels that are going to
|
||||||
|
be displaced according to the data from
|
||||||
|
\l{Displace::displacementSource}{displacementSource}.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the
|
||||||
|
displacement map. The displacementSource item gets rendered into the
|
||||||
|
intermediate pixel buffer. The red and green component values from the
|
||||||
|
result determine the displacement of the pixels from the source item.
|
||||||
|
|
||||||
|
The format for the displacement map is similar to the tangent space
|
||||||
|
normal maps, which can be created with most 3D-modeling tools. Many
|
||||||
|
image processing tools include the support for generating normal maps.
|
||||||
|
Alternatively, the displacement map for this effect can also be a QML
|
||||||
|
element which is colored appropriately. Like any QML element, it can be
|
||||||
|
animated. It is recommended that the size of the diplacement map matches
|
||||||
|
the size of the \l{Displace::source}{source}.
|
||||||
|
|
||||||
|
The displace data is interpreted in the RGBA format. For every pixel:
|
||||||
|
the red channel stores the x-axis displacement, and the green channel
|
||||||
|
stores the y-axis displacement. Blue and alpha channels are ignored for
|
||||||
|
this effect.
|
||||||
|
|
||||||
|
Assuming that red channel value 1.0 is fully red (0.0 having no red at
|
||||||
|
all), this effect considers pixel component value 0.5 to cause no
|
||||||
|
displacement at all. Values above 0.5 shift pixels to the left, values
|
||||||
|
below 0.5 do the shift to the right. In a similar way, green channel
|
||||||
|
values above 0.5 displace the pixels upwards, and values below 0.5 shift
|
||||||
|
the pixels downwards. The actual amount of displacement in pixels
|
||||||
|
depends on the \l displacement property.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant displacementSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the scale for the displacement. The bigger scale,
|
||||||
|
the bigger the displacement of the pixels. The value set to 0.0 causes
|
||||||
|
no displacement.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (inverted maximum shift, according to
|
||||||
|
displacementSource) to 1.0 (maximum shift, according to
|
||||||
|
displacementSource). By default, the property is set to \c 0.0 (no
|
||||||
|
displacement).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different displacement values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Displace_displacement1.png
|
||||||
|
\li \image Displace_displacement2.png
|
||||||
|
\li \image Displace_displacement3.png
|
||||||
|
\row
|
||||||
|
\li \b { displacement: -0.2 }
|
||||||
|
\li \b { displacement: 0.0 }
|
||||||
|
\li \b { displacement: 0.2 }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real displacement: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: displacementSourceProxy
|
||||||
|
input: rootItem.displacementSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant displacementSource: displacementSourceProxy.output
|
||||||
|
property real displacement: rootItem.displacement
|
||||||
|
property real xPixel: 1.0/width
|
||||||
|
property real yPixel: 1.0/height
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D displacementSource;
|
||||||
|
uniform highp float displacement;
|
||||||
|
uniform highp float xPixel;
|
||||||
|
uniform highp float yPixel;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 offset = texture2D(displacementSource, qt_TexCoord0);
|
||||||
|
offset.xy -= vec2(0.5, 0.5);
|
||||||
|
offset.xy = offset.xy * step(vec2(1.0/256.0), abs(offset.xy));
|
||||||
|
highp vec2 tx = qt_TexCoord0 + (vec2(-offset.x, offset.y) * displacement);
|
||||||
|
|
||||||
|
lowp float e1 = linearstep(0.0, xPixel, tx.x);
|
||||||
|
lowp float e2 = linearstep(0.0, yPixel, tx.y);
|
||||||
|
lowp float e3 = 1.0 - linearstep(1.0, 1.0 + xPixel, tx.x);
|
||||||
|
lowp float e4 = 1.0 - linearstep(1.0, 1.0 + yPixel, tx.y);
|
||||||
|
|
||||||
|
lowp vec4 sample = texture2D(source, tx);
|
||||||
|
sample.rgb *= e1 * e2 * e3 * e4;
|
||||||
|
gl_FragColor = sample * qt_Opacity * offset.a;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,403 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype DropShadow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-drop-shadow
|
||||||
|
\brief Generates a colorized and blurred shadow image of the
|
||||||
|
source and places it behind the original, giving the impression that
|
||||||
|
source item is raised from the background.
|
||||||
|
|
||||||
|
By default the effect produces a high quality shadow image, thus the
|
||||||
|
rendering speed of the shadow might not be the highest possible. The
|
||||||
|
rendering speed is reduced especially if the shadow edges are heavily
|
||||||
|
softened.
|
||||||
|
|
||||||
|
For use cases that require faster rendering speed and for which the highest
|
||||||
|
possible visual quality is not necessary, property
|
||||||
|
\l{DropShadow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image DropShadow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet DropShadow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as the
|
||||||
|
source for the generated shadow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the shadow. A larger radius causes the
|
||||||
|
edges of the shadow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{DropShadow::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_radius1.png
|
||||||
|
\li \image DropShadow_radius2.png
|
||||||
|
\li \image DropShadow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{DropShadow::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the shadow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "black".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_color1.png
|
||||||
|
\li \image DropShadow_color2.png
|
||||||
|
\li \image DropShadow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #000000 }
|
||||||
|
\li \b { color: #0000ff }
|
||||||
|
\li \b { color: #aa000000 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "black"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::DropShadow::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::DropShadow::verticalOffset
|
||||||
|
|
||||||
|
HorizontalOffset and verticalOffset properties define the offset for the
|
||||||
|
rendered shadow compared to the DropShadow item position. Often, the
|
||||||
|
DropShadow item is anchored so that it fills the source element. In this
|
||||||
|
case, if the HorizontalOffset and verticalOffset properties are set to
|
||||||
|
0, the shadow is rendered exactly under the source item. By changing the
|
||||||
|
offset properties, the shadow can be positioned relatively to the source
|
||||||
|
item.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, the properties are set to
|
||||||
|
\c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_horizontalOffset1.png
|
||||||
|
\li \image DropShadow_horizontalOffset2.png
|
||||||
|
\li \image DropShadow_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -20 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 20 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 4
|
||||||
|
\li \l radius: 4
|
||||||
|
\li \l radius: 4
|
||||||
|
\row
|
||||||
|
\li \l samples: 8
|
||||||
|
\li \l samples: 8
|
||||||
|
\li \l samples: 8
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the shadow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_spread1.png
|
||||||
|
\li \image DropShadow_spread2.png
|
||||||
|
\li \image DropShadow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_fast1.png
|
||||||
|
\li \image DropShadow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
x: rootItem.horizontalOffset
|
||||||
|
y: rootItem.verticalOffset
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianGlow
|
||||||
|
GaussianGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastGlow
|
||||||
|
FastGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
ShaderEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,496 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype FastBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a fast blur effect to one or more source items.
|
||||||
|
|
||||||
|
FastBlur offers lower blur quality than
|
||||||
|
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur}, but it is faster to
|
||||||
|
render. The FastBlur effect softens the source content by blurring it with
|
||||||
|
algorithm which uses the source content downscaling and bilinear filtering.
|
||||||
|
Use this effect in situations where the source content is rapidly changing
|
||||||
|
and the highest possible blur quality is not
|
||||||
|
needed.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image FastBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet FastBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which affect
|
||||||
|
the blurring of an individual pixel. A larger radius increases the blur
|
||||||
|
effect. FastBlur algorithm may internally reduce the accuracy of the radius in order to
|
||||||
|
provide good rendering performance.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. Visual quality of the blur is reduced when
|
||||||
|
radius exceeds value 64. By default, the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different blur values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image FastBlur_radius1.png
|
||||||
|
\li \image FastBlur_radius2.png
|
||||||
|
\li \image FastBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 32 }
|
||||||
|
\li \b { radius: 64 }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image FastBlur_transparentBorder1.png
|
||||||
|
\li \image FastBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 64
|
||||||
|
\li \l radius: 64
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
smooth: rootItem.radius > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.radius > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: Math.sqrt(rootItem.radius / 64.0) * 1.2 - 0.2
|
||||||
|
property real weight1
|
||||||
|
property real weight2
|
||||||
|
property real weight3
|
||||||
|
property real weight4
|
||||||
|
property real weight5
|
||||||
|
property real weight6
|
||||||
|
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1.0
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
return 1.0 - v * 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype GammaAdjust
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the luminance of the source item.
|
||||||
|
|
||||||
|
GammaAdjust is applied to each pixel according to the curve which is
|
||||||
|
pre-defined as a power-law expression, where the property gamma is used as the
|
||||||
|
reciprocal scaling exponent. Refer to the property documentation of \l{GammaAdjust::gamma}{gamma}
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image GammaAdjust_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet GammaAdjust-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item for which the luminance is going to be
|
||||||
|
adjusted.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the change factor for how the luminance of each pixel
|
||||||
|
is altered according to the equation:
|
||||||
|
|
||||||
|
\code
|
||||||
|
luminance = pow(original_luminance, 1.0 / gamma); // The luminance is assumed to be between 0.0 and 1.0
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Setting the gamma values under 1.0 makes the image darker, the values
|
||||||
|
above 1.0 lighten it.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (darkest) to inf (lightest). By default, the
|
||||||
|
property is set to \c 1.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gamma values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GammaAdjust_gamma1.png
|
||||||
|
\li \image GammaAdjust_gamma2.png
|
||||||
|
\li \image GammaAdjust_gamma3.png
|
||||||
|
\row
|
||||||
|
\li \b { gamma: 0.5 }
|
||||||
|
\li \b { gamma: 1.0 }
|
||||||
|
\li \b { gamma: 2.0 }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GammaAdjust_gamma1_graph.png
|
||||||
|
\li \image GammaAdjust_gamma2_graph.png
|
||||||
|
\li \image GammaAdjust_gamma3_graph.png
|
||||||
|
\row
|
||||||
|
\li Red curve: default gamma (1.0)
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Yellow curve: effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: pixel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real gamma: 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real gamma: 1.0 / Math.max(rootItem.gamma, 0.0001)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float gamma;
|
||||||
|
void main(void) {
|
||||||
|
highp vec4 originalColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
|
||||||
|
highp vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
|
||||||
|
gl_FragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype GaussianBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a higher quality blur effect.
|
||||||
|
|
||||||
|
GaussianBlur effect softens the image by blurring it with an algorithm that
|
||||||
|
uses the Gaussian function to calculate the effect. The effect produces
|
||||||
|
higher quality than \l{QtGraphicalEffects1::FastBlur}{FastBlur}, but is
|
||||||
|
slower to render.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image GaussianBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet GaussianBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which
|
||||||
|
affect the blurring of an individual pixel. A larger radius increases
|
||||||
|
the blur effect.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{GaussianBlur::samples}{samples} should be set to sufficiently large
|
||||||
|
to ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_radius1.png
|
||||||
|
\li \image GaussianBlur_radius2.png
|
||||||
|
\li \image GaussianBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 4 }
|
||||||
|
\li \b { radius: 8 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l deviation: 3
|
||||||
|
\li \l deviation: 3
|
||||||
|
\li \l deviation: 3
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property is a parameter to the gaussian function that is used when
|
||||||
|
calculating neighboring pixel weights for the blurring. A larger
|
||||||
|
deviation causes image to appear more blurry, but it also reduces the
|
||||||
|
quality of the blur. A very large deviation value causes the effect to
|
||||||
|
look a bit similar to what, for exmple, a box blur algorithm produces. A
|
||||||
|
too small deviation values makes the effect insignificant for the pixels
|
||||||
|
near the radius.
|
||||||
|
|
||||||
|
\inlineimage GaussianBlur_deviation_graph.png
|
||||||
|
\caption The image above shows the Gaussian function with two different
|
||||||
|
deviation values, yellow (1) and cyan (2.7). The y-axis shows the
|
||||||
|
weights, the x-axis shows the pixel distance.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no deviation) to inf (maximum deviation). By
|
||||||
|
default, devaition is binded to radius. When radius increases, deviation
|
||||||
|
is automatically increased linearly. With the radius value of 8, the
|
||||||
|
deviation default value becomes approximately 2.7034. This value
|
||||||
|
produces a compromise between the blur quality and overall blurriness.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different deviation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_deviation1.png
|
||||||
|
\li \image GaussianBlur_deviation2.png
|
||||||
|
\li \image GaussianBlur_deviation3.png
|
||||||
|
\row
|
||||||
|
\li \b { deviation: 1 }
|
||||||
|
\li \b { deviation: 2 }
|
||||||
|
\li \b { deviation: 4 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real deviation: (radius + 1) / 3.3333
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_transparentBorder1.png
|
||||||
|
\li \image GaussianBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l deviation: 2.7
|
||||||
|
\li \l deviation: 2.7
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: verticalBlur
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: verticalBlur
|
||||||
|
x: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
|
||||||
|
source: ShaderEffectSource {
|
||||||
|
id: horizontalBlurSource
|
||||||
|
sourceItem: horizontalBlur
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
deviation: rootItem.deviation
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
|
||||||
|
source: sourceProxy.output
|
||||||
|
deviation: rootItem.deviation
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples / 2.0
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Glow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-glow
|
||||||
|
\brief Generates a blurred and colorized image of the source and places it
|
||||||
|
behind the original, giving impression that the source is glowing.
|
||||||
|
|
||||||
|
By default effect produces a high quality glow image, thus the rendering
|
||||||
|
speed of the effect may not be the highest possible. The rendering speed is
|
||||||
|
reduced especially if the glow edges are heavily softened. For use cases
|
||||||
|
that require faster rendering speed and the highest possible visual quality
|
||||||
|
is not necessary, property \l{Glow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly_black.png
|
||||||
|
\li \image Glow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Glow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as source
|
||||||
|
for the generated glow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the glow. A larger radius causes the
|
||||||
|
edges of the glow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the \l{Glow::samples}{samples}
|
||||||
|
should be set to sufficiently large to ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_radius1.png
|
||||||
|
\li \image Glow_radius2.png
|
||||||
|
\li \image Glow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l fast property is set to true, this property has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the glow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The values range from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_spread1.png
|
||||||
|
\li \image Glow_spread2.png
|
||||||
|
\li \image Glow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the glow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "white".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_color1.png
|
||||||
|
\li \image Glow_color2.png
|
||||||
|
\li \image Glow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #00ff00 }
|
||||||
|
\li \b { color: #aa00ff00 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "white"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_fast1.png
|
||||||
|
\li \image Glow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.3
|
||||||
|
\li \l spread: 0.3
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianGlow
|
||||||
|
GaussianGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastGlow
|
||||||
|
FastGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
ShaderEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype HueSaturation
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the source item colors in the HSL color space.
|
||||||
|
|
||||||
|
HueSaturation is similar to the \l{QtGraphicalEffects1::Colorize}{Colorize}
|
||||||
|
effect, but the hue and saturation property values are handled differently.
|
||||||
|
The HueSaturation effect always shifts the hue, saturation, and lightness
|
||||||
|
from the original, instead of setting them.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image HueSaturation_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet HueSaturation-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the hue value which is added to the source hue
|
||||||
|
value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different hue values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_hue1.png
|
||||||
|
\li \image HueSaturation_hue2.png
|
||||||
|
\li \image HueSaturation_hue3.png
|
||||||
|
\row
|
||||||
|
\li \b { hue: -0.3 }
|
||||||
|
\li \b { hue: 0.0 }
|
||||||
|
\li \b { hue: 0.3 }
|
||||||
|
\row
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real hue: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the saturation value value which is added to the
|
||||||
|
source saturation value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different saturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_saturation1.png
|
||||||
|
\li \image HueSaturation_saturation2.png
|
||||||
|
\li \image HueSaturation_saturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { saturation: -0.8 }
|
||||||
|
\li \b { saturation: 0.0 }
|
||||||
|
\li \b { saturation: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real saturation: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the lightness value which is added to the source
|
||||||
|
saturation value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different lightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_lightness1.png
|
||||||
|
\li \image HueSaturation_lightness2.png
|
||||||
|
\li \image HueSaturation_lightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { lightness: -0.5 }
|
||||||
|
\li \b { lightness: 0.0 }
|
||||||
|
\li \b { lightness: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real lightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant hsl: Qt.vector3d(rootItem.hue, rootItem.saturation, rootItem.lightness)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp sampler2D source;
|
||||||
|
uniform highp vec3 hsl;
|
||||||
|
|
||||||
|
highp vec3 RGBtoHSL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float h = 0.0;
|
||||||
|
highp float s = 0.0;
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
highp float diff = cmax - cmin;
|
||||||
|
|
||||||
|
if (diff > 1.0 / 256.0) {
|
||||||
|
if (l < 0.5)
|
||||||
|
s = diff / (cmin + cmax);
|
||||||
|
else
|
||||||
|
s = diff / (2.0 - (cmin + cmax));
|
||||||
|
|
||||||
|
if (color.r == cmax)
|
||||||
|
h = (color.g - color.b) / diff;
|
||||||
|
else if (color.g == cmax)
|
||||||
|
h = 2.0 + (color.b - color.r) / diff;
|
||||||
|
else
|
||||||
|
h = 4.0 + (color.r - color.g) / diff;
|
||||||
|
|
||||||
|
h /= 6.0;
|
||||||
|
}
|
||||||
|
return vec3(h, s, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 sample = texture2D(source, qt_TexCoord0);
|
||||||
|
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
|
||||||
|
sample.rgb = mix(vec3(dot(sample.rgb, vec3(0.2125, 0.7154, 0.0721))), sample.rgb, 1.0 + hsl.y);
|
||||||
|
sample.xyz = RGBtoHSL(sample.rgb);
|
||||||
|
sample.rgb = HSLtoRGB(vec3(sample.x + hsl.x, sample.y, sample.z));
|
||||||
|
highp float c = step(0.0, hsl.z);
|
||||||
|
sample.rgb = mix(sample.rgb, vec3(c), abs(hsl.z));
|
||||||
|
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,385 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype InnerShadow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-drop-shadow
|
||||||
|
\brief Generates a colorized and blurred shadow inside the
|
||||||
|
source.
|
||||||
|
|
||||||
|
By default the effect produces a high quality shadow image, thus the
|
||||||
|
rendering speed of the shadow might not be the highest possible. The
|
||||||
|
rendering speed is reduced especially if the shadow edges are heavily
|
||||||
|
softened. For use cases that require faster rendering speed and for which
|
||||||
|
the highest possible visual quality is not necessary, property
|
||||||
|
\l{InnerShadow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image InnerShadow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet InnerShadow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as the
|
||||||
|
source for the generated shadow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the shadow. A larger radius causes the
|
||||||
|
edges of the shadow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{InnerShadow::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_radius1.png
|
||||||
|
\li \image InnerShadow_radius2.png
|
||||||
|
\li \image InnerShadow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{InnerShadow::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the shadow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_spread1.png
|
||||||
|
\li \image InnerShadow_spread2.png
|
||||||
|
\li \image InnerShadow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.3 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the shadow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "black".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_color1.png
|
||||||
|
\li \image InnerShadow_color2.png
|
||||||
|
\li \image InnerShadow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #000000 }
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #ff0000 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color color: "black"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::InnerShadow::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::InnerShadow::verticalOffset
|
||||||
|
|
||||||
|
HorizontalOffset and verticalOffset properties define the offset for the
|
||||||
|
rendered shadow compared to the InnerShadow item position. Often, the
|
||||||
|
InnerShadow item is anchored so that it fills the source element. In
|
||||||
|
this case, if the HorizontalOffset and verticalOffset properties are set
|
||||||
|
to 0, the shadow is rendered fully inside the source item. By changing
|
||||||
|
the offset properties, the shadow can be positioned relatively to the
|
||||||
|
source item.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, the properties are set to
|
||||||
|
\c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_horizontalOffset1.png
|
||||||
|
\li \image InnerShadow_horizontalOffset2.png
|
||||||
|
\li \image InnerShadow_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -20 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 20 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_fast1.png
|
||||||
|
\li \image InnerShadow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? innerShadow : gaussianInnerShadow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianInnerShadow
|
||||||
|
GaussianInnerShadow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
horizontalOffset: rootItem.horizontalOffset
|
||||||
|
verticalOffset: rootItem.verticalOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: innerShadow
|
||||||
|
FastInnerShadow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
horizontalOffset: rootItem.horizontalOffset
|
||||||
|
verticalOffset: rootItem.verticalOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,472 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Add-On Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype LevelAdjust
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Adjusts color levels in the RGBA color space.
|
||||||
|
|
||||||
|
This effect adjusts the source item colors separately for each color
|
||||||
|
channel. Source item contrast can be adjusted and color balance altered.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image LevelAdjust_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet LevelAdjust-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the change factor for how the value of each pixel
|
||||||
|
color channel is altered according to the equation:
|
||||||
|
|
||||||
|
\code result.rgb = pow(original.rgb, 1.0 / gamma.rgb); \endcode
|
||||||
|
|
||||||
|
Setting the gamma values under QtVector3d(1.0, 1.0, 1.0) makes the image
|
||||||
|
darker, the values above QtVector3d(1.0, 1.0, 1.0) lighten it.
|
||||||
|
|
||||||
|
The value ranges from QtVector3d(0.0, 0.0, 0.0) (darkest) to inf
|
||||||
|
(lightest). By default, the property is set to \c QtVector3d(1.0, 1.0,
|
||||||
|
1.0) (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gamma values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_gamma1.png
|
||||||
|
\li \image LevelAdjust_gamma2.png
|
||||||
|
\li \image LevelAdjust_gamma3.png
|
||||||
|
\row
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 1.0, 1.0) }
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 0.4, 2.0) }
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 0.1, 4.0) }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_gamma2_curve.png
|
||||||
|
\li \image LevelAdjust_gamma3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property variant gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the minimum input level for each color channel. It
|
||||||
|
sets the black-point, all pixels having lower value than this property
|
||||||
|
are rendered as black (per color channel). Increasing the value darkens
|
||||||
|
the dark areas.
|
||||||
|
|
||||||
|
The value ranges from "#00000000" to "#ffffffff". By default, the
|
||||||
|
property is set to \c "#00000000" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different minimumInput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_minimumInput1.png
|
||||||
|
\li \image LevelAdjust_minimumInput2.png
|
||||||
|
\li \image LevelAdjust_minimumInput3.png
|
||||||
|
\row
|
||||||
|
\li \b { minimumInput: #00000000 }
|
||||||
|
\li \b { minimumInput: #00000040 }
|
||||||
|
\li \b { minimumInput: #00000070 }
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_minimumInput2_curve.png
|
||||||
|
\li \image LevelAdjust_minimumInput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color minimumInput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum input level for each color channel.
|
||||||
|
It sets the white-point, all pixels having higher value than this
|
||||||
|
property are rendered as white (per color channel).
|
||||||
|
Decreasing the value lightens the light areas.
|
||||||
|
|
||||||
|
The value ranges from "#ffffffff" to "#00000000". By default, the
|
||||||
|
property is set to \c "#ffffffff" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different maximumInput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_maximumInput1.png
|
||||||
|
\li \image LevelAdjust_maximumInput2.png
|
||||||
|
\li \image LevelAdjust_maximumInput3.png
|
||||||
|
\row
|
||||||
|
\li \b { maximumInput: #FFFFFFFF }
|
||||||
|
\li \b { maximumInput: #FFFFFF80 }
|
||||||
|
\li \b { maximumInput: #FFFFFF30 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_maximumInput2_curve.png
|
||||||
|
\li \image LevelAdjust_maximumInput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color maximumInput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the minimum output level for each color channel.
|
||||||
|
Increasing the value lightens the dark areas, reducing the contrast.
|
||||||
|
|
||||||
|
The value ranges from "#00000000" to "#ffffffff". By default, the
|
||||||
|
property is set to \c "#00000000" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different minimumOutput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_minimumOutput1.png
|
||||||
|
\li \image LevelAdjust_minimumOutput2.png
|
||||||
|
\li \image LevelAdjust_minimumOutput3.png
|
||||||
|
\row
|
||||||
|
\li \b { minimumOutput: #00000000 }
|
||||||
|
\li \b { minimumOutput: #00000070 }
|
||||||
|
\li \b { minimumOutput: #000000A0 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_minimumOutput2_curve.png
|
||||||
|
\li \image LevelAdjust_minimumOutput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color minimumOutput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum output level for each color channel.
|
||||||
|
Decreasing the value darkens the light areas, reducing the contrast.
|
||||||
|
|
||||||
|
The value ranges from "#ffffffff" to "#00000000". By default, the
|
||||||
|
property is set to \c "#ffffffff" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different maximumOutput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_maximumOutput1.png
|
||||||
|
\li \image LevelAdjust_maximumOutput2.png
|
||||||
|
\li \image LevelAdjust_maximumOutput3.png
|
||||||
|
\row
|
||||||
|
\li \b { maximumOutput: #FFFFFFFF }
|
||||||
|
\li \b { maximumOutput: #FFFFFF80 }
|
||||||
|
\li \b { maximumOutput: #FFFFFF30 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_maximumOutput2_curve.png
|
||||||
|
\li \image LevelAdjust_maximumOutput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color maximumOutput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant minimumInputRGB: Qt.vector3d(rootItem.minimumInput.r, rootItem.minimumInput.g, rootItem.minimumInput.b)
|
||||||
|
property variant maximumInputRGB: Qt.vector3d(rootItem.maximumInput.r, rootItem.maximumInput.g, rootItem.maximumInput.b)
|
||||||
|
property real minimumInputAlpha: rootItem.minimumInput.a
|
||||||
|
property real maximumInputAlpha: rootItem.maximumInput.a
|
||||||
|
property variant minimumOutputRGB: Qt.vector3d(rootItem.minimumOutput.r, rootItem.minimumOutput.g, rootItem.minimumOutput.b)
|
||||||
|
property variant maximumOutputRGB: Qt.vector3d(rootItem.maximumOutput.r, rootItem.maximumOutput.g, rootItem.maximumOutput.b)
|
||||||
|
property real minimumOutputAlpha: rootItem.minimumOutput.a
|
||||||
|
property real maximumOutputAlpha: rootItem.maximumOutput.a
|
||||||
|
property variant gamma: Qt.vector3d(1.0 / Math.max(rootItem.gamma.x, 0.0001), 1.0 / Math.max(rootItem.gamma.y, 0.0001), 1.0 / Math.max(rootItem.gamma.z, 0.0001))
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec3 minimumInputRGB;
|
||||||
|
uniform highp vec3 maximumInputRGB;
|
||||||
|
uniform highp float minimumInputAlpha;
|
||||||
|
uniform highp float maximumInputAlpha;
|
||||||
|
uniform highp vec3 minimumOutputRGB;
|
||||||
|
uniform highp vec3 maximumOutputRGB;
|
||||||
|
uniform highp float minimumOutputAlpha;
|
||||||
|
uniform highp float maximumOutputAlpha;
|
||||||
|
uniform highp vec3 gamma;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
highp vec4 color = vec4(textureColor.rgb / max(1.0/256.0, textureColor.a), textureColor.a);
|
||||||
|
|
||||||
|
color.r = linearstep(minimumInputRGB.r, maximumInputRGB.r, color.r);
|
||||||
|
color.g = linearstep(minimumInputRGB.g, maximumInputRGB.g, color.g);
|
||||||
|
color.b = linearstep(minimumInputRGB.b, maximumInputRGB.b, color.b);
|
||||||
|
color.a = linearstep(minimumInputAlpha, maximumInputAlpha, color.a);
|
||||||
|
|
||||||
|
color.rgb = pow(color.rgb, gamma);
|
||||||
|
|
||||||
|
color.r = minimumOutputRGB.r + color.r * (maximumOutputRGB.r - minimumOutputRGB.r);
|
||||||
|
color.g = minimumOutputRGB.g + color.g * (maximumOutputRGB.g - minimumOutputRGB.g);
|
||||||
|
color.b = minimumOutputRGB.b + color.b * (maximumOutputRGB.b - minimumOutputRGB.b);
|
||||||
|
color.a = minimumOutputAlpha + color.a * (maximumOutputAlpha - minimumOutputAlpha);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color.rgb * color.a, color.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype LinearGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a linear gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the given start point and end to the given end point.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet LinearGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the starting point where the color at gradient
|
||||||
|
position of 0.0 is rendered. Colors at larger position values are
|
||||||
|
rendered linearly towards the end point. The point is given in pixels
|
||||||
|
and the default value is Qt.point(0, 0). Setting the default values for
|
||||||
|
the start and \l{LinearGradient::end}{end} results in a full height
|
||||||
|
linear gradient on the y-axis.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different start values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_start1.png
|
||||||
|
\li \image LinearGradient_start2.png
|
||||||
|
\li \image LinearGradient_start3.png
|
||||||
|
\row
|
||||||
|
\li \b { start: QPoint(0, 0) }
|
||||||
|
\li \b { start: QPoint(150, 150) }
|
||||||
|
\li \b { start: QPoint(300, 0) }
|
||||||
|
\row
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant start: Qt.point(0, 0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the ending point where the color at gradient
|
||||||
|
position of 1.0 is rendered. Colors at smaller position values are
|
||||||
|
rendered linearly towards the start point. The point is given in pixels
|
||||||
|
and the default value is Qt.point(0, height). Setting the default values
|
||||||
|
for the \l{LinearGradient::start}{start} and end results in a full
|
||||||
|
height linear gradient on the y-axis.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different end values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_end1.png
|
||||||
|
\li \image LinearGradient_end2.png
|
||||||
|
\li \image LinearGradient_end3.png
|
||||||
|
\row
|
||||||
|
\li \b { end: Qt.point(300, 300) }
|
||||||
|
\li \b { end: Qt.point(150, 150) }
|
||||||
|
\li \b { end: Qt.point(300, 0) }
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant end: Qt.point(0, height)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_maskSource1.png
|
||||||
|
\li \image LinearGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: Image { source: images/butterfly.png } }
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\row
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended
|
||||||
|
seamlessly. The colors are specified as a set of GradientStop child
|
||||||
|
items, each of which defines a position on the gradient from 0.0 to 1.0
|
||||||
|
and a color. The position of each GradientStop is defined by the
|
||||||
|
position property, and the color is definded by the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_gradient1.png
|
||||||
|
\li \image LinearGradient_gradient2.png
|
||||||
|
\li \image LinearGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\row
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: gradientSource
|
||||||
|
sourceItem: Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant source: gradientSource
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property variant startPoint: Qt.point(start.x / width, start.y / height)
|
||||||
|
property real dx: end.x - start.x
|
||||||
|
property real dy: end.y - start.y
|
||||||
|
property real l: 1.0 / Math.sqrt(Math.pow(dx / width, 2.0) + Math.pow(dy / height, 2.0))
|
||||||
|
property real angle: Math.atan2(dx, dy)
|
||||||
|
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
uniform highp vec2 startPoint;
|
||||||
|
uniform highp float l;
|
||||||
|
uniform highp vec2 matrixData;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
|
||||||
|
matrixData.x, matrixData.y);
|
||||||
|
|
||||||
|
qt_TexCoord0 = qt_MultiTexCoord0;
|
||||||
|
|
||||||
|
qt_TexCoord1 = qt_MultiTexCoord0 * l;
|
||||||
|
qt_TexCoord1 -= startPoint * l;
|
||||||
|
qt_TexCoord1 *= rot;
|
||||||
|
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: lChanged()
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(source, qt_TexCoord1);
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord1) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype MaskedBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a blur effect with a varying intesity.
|
||||||
|
|
||||||
|
MaskedBlur effect softens the image by blurring it. The intensity of the
|
||||||
|
blur can be controlled for each pixel using maskSource so that some parts of
|
||||||
|
the source are blurred more than others. By default the effect produces a
|
||||||
|
high quality result, thus the rendering speed may not be the highest
|
||||||
|
possible. The rendering speed is reduced especially if the
|
||||||
|
\l{MaskedBlur::samples}{samples} is large. For use cases that require faster
|
||||||
|
rendering speed and the highest possible visual quality is not necessary,
|
||||||
|
property \l{MaskedBlur::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image MaskedBlur_mask.png
|
||||||
|
\li \image MaskedBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet MaskedBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is controlling the final intensity
|
||||||
|
of the blur. The pixel alpha channel value from maskSource defines the
|
||||||
|
actual blur radius that is going to be used for blurring the
|
||||||
|
corresponding source pixel.
|
||||||
|
|
||||||
|
Opaque maskSource pixels produce blur with specified
|
||||||
|
\l{MaskedBlur::radius}{radius}, while transparent pixels suppress the
|
||||||
|
blur completely. Semitransparent maskSource pixels produce blur with a
|
||||||
|
radius that is interpolated according to the pixel transparency level.
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which
|
||||||
|
affect the blurring of an individual pixel. A larger radius increases
|
||||||
|
the blur effect.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{MaskedBlur::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_radius1.png
|
||||||
|
\li \image MaskedBlur_radius2.png
|
||||||
|
\li \image MaskedBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 8 }
|
||||||
|
\li \b { radius: 16 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\row
|
||||||
|
\li \l fast: false
|
||||||
|
\li \l fast: false
|
||||||
|
\li \l fast: false
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{MaskedBlur::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
blur. Setting this to true enables fast algorithm, setting value to
|
||||||
|
false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_fast1.png
|
||||||
|
\li \image MaskedBlur_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_transparentBorder1.png
|
||||||
|
\li \image MaskedBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 64
|
||||||
|
\li \l radius: 64
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l fast: true
|
||||||
|
\li \l fast: true
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loaderItem
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? fastBlur : gaussianBlur
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianBlur
|
||||||
|
GaussianMaskedBlur {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
maskSource: rootItem.maskSource
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
cached: rootItem.cached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastBlur
|
||||||
|
FastMaskedBlur {
|
||||||
|
anchors.fill: parent
|
||||||
|
source:rootItem. source
|
||||||
|
maskSource: rootItem.maskSource
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
cached: rootItem.cached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype OpacityMask
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-mask
|
||||||
|
\brief Masks the source item with another item.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image OpacityMask_mask.png
|
||||||
|
\li \image OpacityMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet OpacityMask-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be masked.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the mask. The
|
||||||
|
mask item gets rendered into an intermediate pixel buffer and the alpha
|
||||||
|
values from the result are used to determine the source item's pixels
|
||||||
|
visibility in the display.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Original
|
||||||
|
\li Mask
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image OpacityMask_mask.png
|
||||||
|
\li \image OpacityMask_bug.png
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting maskSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
void main(void) {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord0.st) * (texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RadialBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies directional blur in a circular direction around the items
|
||||||
|
center point.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
rotating to the direction of the blur.
|
||||||
|
|
||||||
|
Other available motionblur effects are
|
||||||
|
\l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
|
||||||
|
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image RadialBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example Usage
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RadialBlur-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the direction for the blur and at the same time
|
||||||
|
the level of blurring. The larger the angle, the more the result becomes
|
||||||
|
blurred. The quality of the blur depends on
|
||||||
|
\l{RadialBlur::samples}{samples} property. If angle value is large, more
|
||||||
|
samples are needed to keep the visual quality at high level.
|
||||||
|
|
||||||
|
Allowed values are between 0.0 and 360.0. By default the property is set
|
||||||
|
to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialBlur_angle1.png
|
||||||
|
\li \image RadialBlur_angle2.png
|
||||||
|
\li \image RadialBlur_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0.0 }
|
||||||
|
\li \b { angle: 15.0 }
|
||||||
|
\li \b { angle: 30.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::RadialBlur::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::RadialBlur::verticalOffset
|
||||||
|
|
||||||
|
These properties define the offset in pixels for the perceived center
|
||||||
|
point of the rotation.
|
||||||
|
|
||||||
|
Allowed values are between -inf and inf.
|
||||||
|
By default these properties are set to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialBlur_horizontalOffset1.png
|
||||||
|
\li \image RadialBlur_horizontalOffset2.png
|
||||||
|
\li \image RadialBlur_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: 75.0 }
|
||||||
|
\li \b { horizontalOffset: 0.0 }
|
||||||
|
\li \b { horizontalOffset: -75.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l angle: 20
|
||||||
|
\li \l angle: 20
|
||||||
|
\li \l angle: 20
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: shaderItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / parent.width, 0.5 + rootItem.verticalOffset / parent.height)
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder && rootItem.samples > 1
|
||||||
|
property int samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property real angleSin: Math.sin(rootItem.angle/2 * Math.PI/180)
|
||||||
|
property real angleCos: Math.cos(rootItem.angle/2 * Math.PI/180)
|
||||||
|
property real angleSinStep: Math.sin(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
|
||||||
|
property real angleCosStep: Math.cos(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(0.5 * parent.height, 0.5 * parent.width) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
|
||||||
|
property real w: parent.width
|
||||||
|
property real h: parent.height
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1 : 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + expandPixels.width * 2.0 + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + expandPixels.height * 2.0 + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float angleSin;
|
||||||
|
uniform highp float angleCos;
|
||||||
|
uniform highp float angleSinStep;
|
||||||
|
uniform highp float angleCosStep;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
uniform highp float w;
|
||||||
|
uniform highp float h;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp mat2 m;
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
highp vec2 dir = vec2(texCoord.s * w - w * center.x, texCoord.t * h - h * center.y);
|
||||||
|
m[0] = vec2(angleCos, -angleSin);
|
||||||
|
m[1] = vec2(angleSin, angleCos);
|
||||||
|
dir *= m;
|
||||||
|
|
||||||
|
m[0] = vec2(angleCosStep, -angleSinStep);
|
||||||
|
m[1] = vec2(angleSinStep, angleCosStep);
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, center + dir * delta); dir *= m;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,439 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RadialGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a radial gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the middle of the item and end at the borders.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RadialGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The HorizontalOffset and verticalOffset properties define the offset in
|
||||||
|
pixels for the center point of the gradient compared to the item center.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, these properties are set
|
||||||
|
to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_horizontalOffset1.png
|
||||||
|
\li \image RadialGradient_horizontalOffset2.png
|
||||||
|
\li \image RadialGradient_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -150 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 150 }
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The HorizontalRadius and verticalRadius properties define the shape and
|
||||||
|
size of the radial gradient. If the radiuses are equal, the shape of the
|
||||||
|
gradient is a circle. If the horizontal and vertical radiuses differ,
|
||||||
|
the shape is elliptical. The radiuses are given in pixels.
|
||||||
|
|
||||||
|
The value ranges from -inf to inf. By default, horizontalRadius is bound
|
||||||
|
to width and verticalRadius is bound to height.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_horizontalRadius1.png
|
||||||
|
\li \image RadialGradient_horizontalRadius2.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalRadius: 300 }
|
||||||
|
\li \b { horizontalRadius: 100 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l gradient: QQuickGradient(0xa05fb10)
|
||||||
|
\li \l gradient: QQuickGradient(0xa05fb10)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalRadius: width
|
||||||
|
property real verticalRadius: height
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the rotation of the gradient around its center
|
||||||
|
point. The rotation is only visible when the
|
||||||
|
\l{RadialGradient::horizontalRadius}{horizontalRadius} and
|
||||||
|
\l{RadialGradient::verticalRadius}{verticalRadius} properties are not
|
||||||
|
equal. The angle is given in degrees and the default value is \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_angle1.png
|
||||||
|
\li \image RadialGradient_angle2.png
|
||||||
|
\li \image RadialGradient_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0 }
|
||||||
|
\li \b { angle: 45 }
|
||||||
|
\li \b { angle: 90 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_maskSource1.png
|
||||||
|
\li \image RadialGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: Image { source: images/butterfly.png } }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended
|
||||||
|
seamlessly. The colors are specified as a set of GradientStop child
|
||||||
|
items, each of which defines a position on the gradient from 0.0 to 1.0
|
||||||
|
and a color. The position of each GradientStop is defined by setting the
|
||||||
|
position property. The color is defined by setting the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_gradient1.png
|
||||||
|
\li \image RadialGradient_gradient2.png
|
||||||
|
\li \image RadialGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:}
|
||||||
|
\code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: gradientSource
|
||||||
|
sourceItem: Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant gradientImage: gradientSource
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
|
||||||
|
property real horizontalRatio: rootItem.horizontalRadius > 0 ? width / (2 * rootItem.horizontalRadius) : width * 16384
|
||||||
|
property real verticalRatio: rootItem.verticalRadius > 0 ? height / (2 * rootItem.verticalRadius) : height * 16384
|
||||||
|
property real angle: -rootItem.angle / 360 * 2 * Math.PI
|
||||||
|
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp vec2 matrixData;
|
||||||
|
uniform highp float horizontalRatio;
|
||||||
|
uniform highp float verticalRatio;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 ratio = vec2(horizontalRatio, verticalRatio);
|
||||||
|
|
||||||
|
// Rotation matrix
|
||||||
|
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
|
||||||
|
matrixData.x, matrixData.y);
|
||||||
|
|
||||||
|
qt_TexCoord0 = qt_MultiTexCoord0;
|
||||||
|
|
||||||
|
qt_TexCoord1 = qt_MultiTexCoord0;
|
||||||
|
qt_TexCoord1 -= center;
|
||||||
|
qt_TexCoord1 *= rot;
|
||||||
|
qt_TexCoord1 += center;
|
||||||
|
qt_TexCoord1 *= ratio;
|
||||||
|
|
||||||
|
centerPoint = center * ratio;
|
||||||
|
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: horizontalRatioChanged()
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
uniform lowp sampler2D gradientImage;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
uniform lowp sampler2D gradientImage;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
|
||||||
|
gl_FragColor = gradientColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RectangularGlow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-glow
|
||||||
|
\brief Generates a blurred and colorized rectangle, which gives
|
||||||
|
the impression that the source is glowing.
|
||||||
|
|
||||||
|
This effect is intended to have good performance. The shape of the glow is
|
||||||
|
limited to a rectangle with a custom corner radius. For situations where
|
||||||
|
custom shapes are required, consider \l {QtGraphicalEffects1::Glow} {Glow}
|
||||||
|
effect.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_applied.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RectangularGlow-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many pixels outside the item area are reached
|
||||||
|
by the glow.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no glow) to inf (infinite glow). By default,
|
||||||
|
the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different glowRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_glowRadius1.png
|
||||||
|
\li \image RectangularGlow_glowRadius2.png
|
||||||
|
\li \image RectangularGlow_glowRadius3.png
|
||||||
|
\row
|
||||||
|
\li \b { glowRadius: 10 }
|
||||||
|
\li \b { glowRadius: 20 }
|
||||||
|
\li \b { glowRadius: 40 }
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real glowRadius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the glow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no strenght increase) to 1.0 (maximum
|
||||||
|
strenght increase). By default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_spread1.png
|
||||||
|
\li \image RectangularGlow_spread2.png
|
||||||
|
\li \image RectangularGlow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the glow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "white".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_color1.png
|
||||||
|
\li \image RectangularGlow_color2.png
|
||||||
|
\li \image RectangularGlow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #55ff55 }
|
||||||
|
\li \b { color: #5555ff }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color color: "white"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the corner radius that is used to draw a glow with
|
||||||
|
rounded corners.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to half of the effective width or height of
|
||||||
|
the glow, whichever is smaller. This can be calculated with: \c{
|
||||||
|
min(width, height) / 2.0 + glowRadius}
|
||||||
|
|
||||||
|
By default, the property is bound to glowRadius property. The glow
|
||||||
|
behaves as if the rectangle was blurred when adjusting the glowRadius
|
||||||
|
property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different cornerRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_cornerRadius1.png
|
||||||
|
\li \image RectangularGlow_cornerRadius2.png
|
||||||
|
\li \image RectangularGlow_cornerRadius3.png
|
||||||
|
\row
|
||||||
|
\li \b { cornerRadius: 0 }
|
||||||
|
\li \b { cornerRadius: 25 }
|
||||||
|
\li \b { cornerRadius: 50 }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real cornerRadius: glowRadius
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2.0
|
||||||
|
y: (parent.height - height) / 2.0
|
||||||
|
width: parent.width + rootItem.glowRadius * 2 + cornerRadius * 2
|
||||||
|
height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2
|
||||||
|
|
||||||
|
function clampedCornerRadius() {
|
||||||
|
var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + glowRadius;
|
||||||
|
return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius))
|
||||||
|
}
|
||||||
|
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real inverseSpread: 1.0 - rootItem.spread
|
||||||
|
property real relativeSizeX: ((inverseSpread * inverseSpread) * rootItem.glowRadius + cornerRadius * 2.0) / width
|
||||||
|
property real relativeSizeY: relativeSizeX * (width / height)
|
||||||
|
property real spread: rootItem.spread / 2.0
|
||||||
|
property real cornerRadius: clampedCornerRadius()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform mediump float relativeSizeX;
|
||||||
|
uniform mediump float relativeSizeY;
|
||||||
|
uniform mediump float spread;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp float alpha =
|
||||||
|
smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) *
|
||||||
|
smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y));
|
||||||
|
|
||||||
|
highp float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha);
|
||||||
|
gl_FragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,350 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RecursiveBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Blurs repeatedly, providing a strong blur effect.
|
||||||
|
|
||||||
|
The RecursiveBlur effect softens the image by blurring it with an algorithm
|
||||||
|
that uses a recursive feedback loop to blur the source multiple times. The
|
||||||
|
effect may give more blurry results than
|
||||||
|
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur} or
|
||||||
|
\l{QtGraphicalEffects1::FastBlur}{FastBlur}, but the result is produced
|
||||||
|
asynchronously and takes more time.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image RecursiveBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RecursiveBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of neighboring pixels which influence
|
||||||
|
the blurring of individual pixels. A larger radius provides better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
\b Note: The radius value in this effect is not intended to be changed
|
||||||
|
or animated frequently. The correct way to use it is to set the correct
|
||||||
|
value and keep it unchanged for the whole duration of the iterative blur
|
||||||
|
sequence.
|
||||||
|
|
||||||
|
The value ranges from (no blur) to 16.0 (maximum blur step). By default,
|
||||||
|
the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_radius1.png
|
||||||
|
\li \image RecursiveBlur_radius2.png
|
||||||
|
\li \image RecursiveBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 2.5 }
|
||||||
|
\li \b { radius: 4.5 }
|
||||||
|
\li \b { radius: 7.5 }
|
||||||
|
\row
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_transparentBorder1.png
|
||||||
|
\li \image RecursiveBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\row
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the amount of blur iterations that are going to be
|
||||||
|
performed for the source. When the property changes, the iterative
|
||||||
|
blurring process starts. If the value is decreased or if the value
|
||||||
|
changes from zero to non-zero, a snapshot is taken from the source. The
|
||||||
|
snapshot is used as a starting point for the process.
|
||||||
|
|
||||||
|
The iteration loop tries to run as fast as possible. The speed might be
|
||||||
|
limited by the VSYNC or the time needed for one blur step, or both.
|
||||||
|
Sometimes it may be desirable to perform the blurring with a slower
|
||||||
|
pace. In that case, it may be convenient to control the property with
|
||||||
|
Animation which increases the value.
|
||||||
|
|
||||||
|
The value ranges from 0 to inf. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different loops values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_loops1.png
|
||||||
|
\li \image RecursiveBlur_loops2.png
|
||||||
|
\li \image RecursiveBlur_loops3.png
|
||||||
|
\row
|
||||||
|
\li \b { loops: 4 }
|
||||||
|
\li \b { loops: 20 }
|
||||||
|
\li \b { loops: 70 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int loops: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds the progress of asynchronous source blurring
|
||||||
|
process, from 0.0 (nothing blurred) to 1.0 (finished).
|
||||||
|
*/
|
||||||
|
property real progress: loops > 0.0 ? Math.min(1.0, recursionTimer.counter / loops) : 0.0
|
||||||
|
|
||||||
|
onLoopsChanged: recursiveSource.scheduleUpdate()
|
||||||
|
onSourceChanged: recursionTimer.reset()
|
||||||
|
onRadiusChanged: recursionTimer.reset()
|
||||||
|
onTransparentBorderChanged: recursionTimer.reset()
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2, parent.height + 2) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
smooth: true
|
||||||
|
visible: rootItem.cached
|
||||||
|
hideSource: visible
|
||||||
|
live: true
|
||||||
|
sourceItem: inputItem.visible ? inputItem : verticalBlur
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: recursionTimer
|
||||||
|
property int counter: 0
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
counter = 0
|
||||||
|
recursiveSource.scheduleUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextFrame() {
|
||||||
|
if (loops < counter)
|
||||||
|
recursionTimer.counter = 0
|
||||||
|
|
||||||
|
if (counter > 0)
|
||||||
|
recursiveSource.sourceItem = verticalBlur
|
||||||
|
else
|
||||||
|
recursiveSource.sourceItem = inputItem
|
||||||
|
|
||||||
|
if (counter < loops) {
|
||||||
|
recursiveSource.scheduleUpdate()
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: inputItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real expandX: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.width : 0.0
|
||||||
|
property real expandY: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.height : 0.0
|
||||||
|
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
visible: !verticalBlur.visible
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float expandX;
|
||||||
|
uniform highp float expandY;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mediump vec2 texCoord = qt_MultiTexCoord0;
|
||||||
|
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
|
||||||
|
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
|
||||||
|
qt_TexCoord0 = texCoord;
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: recursiveSource
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
hideSource: false
|
||||||
|
live: false
|
||||||
|
sourceItem: inputItem
|
||||||
|
recursive: true
|
||||||
|
onSourceItemChanged: scheduleUpdate()
|
||||||
|
onScheduledUpdateCompleted: recursionTimer.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: verticalBlur
|
||||||
|
x: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
|
||||||
|
y: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width + 2
|
||||||
|
height: horizontalBlur.height + 2
|
||||||
|
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
|
||||||
|
source: ShaderEffectSource {
|
||||||
|
sourceItem: horizontalBlur
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
deviation: (radius + 1) / 2.3333
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: Math.ceil(rootItem.radius)
|
||||||
|
transparentBorder: false
|
||||||
|
visible: loops > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: rootItem.transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: rootItem.transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
|
||||||
|
source: recursiveSource
|
||||||
|
deviation: (radius + 1) / 2.3333
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: Math.ceil(rootItem.radius)
|
||||||
|
transparentBorder: false
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ThresholdMask
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-mask
|
||||||
|
\brief Masks the source item with another item and applies a threshold
|
||||||
|
value.
|
||||||
|
|
||||||
|
The masking behavior can be controlled with the \l threshold value for the
|
||||||
|
mask pixels.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ThresholdMask_mask.png
|
||||||
|
\li \image ThresholdMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ThresholdMask-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be masked.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the mask.
|
||||||
|
Mask item gets rendered into an intermediate pixel buffer and the alpha
|
||||||
|
values from the result are used to determine the source item's pixels
|
||||||
|
visibility in the display.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Original
|
||||||
|
\li Mask
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ThresholdMask_mask.png
|
||||||
|
\li \image ThresholdMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting maskSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines a threshold value for the mask pixels. The mask
|
||||||
|
pixels that have an alpha value below this property are used to
|
||||||
|
completely mask away the corresponding pixels from the source item. The
|
||||||
|
mask pixels that have a higher alpha value are used to alphablend the
|
||||||
|
source item to the display.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (alpha value 0) to 1.0 (alpha value 255). By
|
||||||
|
default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different threshold values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ThresholdMask_threshold1.png
|
||||||
|
\li \image ThresholdMask_threshold2.png
|
||||||
|
\li \image ThresholdMask_threshold3.png
|
||||||
|
\row
|
||||||
|
\li \b { threshold: 0.0 }
|
||||||
|
\li \b { threshold: 0.5 }
|
||||||
|
\li \b { threshold: 0.7 }
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real threshold: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the smoothness of the mask edges near the
|
||||||
|
\l{ThresholdMask::threshold}{threshold} alpha value. Setting spread to
|
||||||
|
0.0 uses mask normally with the specified threshold. Setting higher
|
||||||
|
spread values softens the transition from the transparent mask pixels
|
||||||
|
towards opaque mask pixels by adding interpolated values between them.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (sharp mask edge) to 1.0 (smooth mask edge).
|
||||||
|
By default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ThresholdMask_spread1.png
|
||||||
|
\li \image ThresholdMask_spread2.png
|
||||||
|
\li \image ThresholdMask_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.2 }
|
||||||
|
\li \b { spread: 0.8 }
|
||||||
|
\row
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property real threshold: rootItem.threshold
|
||||||
|
property real spread: rootItem.spread
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform highp float threshold;
|
||||||
|
uniform highp float spread;
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 colorFragment = texture2D(source, qt_TexCoord0.st);
|
||||||
|
lowp vec4 maskFragment = texture2D(maskSource, qt_TexCoord0.st);
|
||||||
|
gl_FragColor = colorFragment * smoothstep(threshold * (1.0 + spread) - spread, threshold * (1.0 + spread), maskFragment.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ZoomBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies directional blur effect towards source items center point.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
moving towards the center point in Z-direction or that the camera appears
|
||||||
|
to be zooming rapidly. Other available motion blur effects are
|
||||||
|
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}
|
||||||
|
and \l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ZoomBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ZoomBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum perceived amount of movement for each
|
||||||
|
pixel. The amount is smaller near the center and reaches the specified
|
||||||
|
value at the edges.
|
||||||
|
|
||||||
|
The quality of the blur depends on \l{ZoomBlur::samples}{samples}
|
||||||
|
property. If length value is large, more samples are needed to keep the
|
||||||
|
visual quality at high level.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to inf. By default the property is set to \c
|
||||||
|
0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different length values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ZoomBlur_length1.png
|
||||||
|
\li \image ZoomBlur_length2.png
|
||||||
|
\li \image ZoomBlur_length3.png
|
||||||
|
\row
|
||||||
|
\li \b { length: 0.0 }
|
||||||
|
\li \b { length: 32.0 }
|
||||||
|
\li \b { length: 48.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real length: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ZoomBlur::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ZoomBlur::verticalOffset
|
||||||
|
|
||||||
|
These properties define an offset in pixels for the blur direction
|
||||||
|
center point.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default these properties are set
|
||||||
|
to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ZoomBlur_horizontalOffset1.png
|
||||||
|
\li \image ZoomBlur_horizontalOffset2.png
|
||||||
|
\li \image ZoomBlur_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: 100.0 }
|
||||||
|
\li \b { horizontalOffset: 0.0 }
|
||||||
|
\li \b { horizontalOffset: -100.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
|
||||||
|
property real len: rootItem.length
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1 : 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float len;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp float samples;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
mediump vec2 centerCoord = center;
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
highp vec2 dir = vec2(centerCoord.x - texCoord.s, centerCoord.y - texCoord.t);
|
||||||
|
dir /= max(1.0, length(dir) * 2.0);
|
||||||
|
highp vec2 shift = delta * len * dir * 2.0 / max(1.0, samples - 1.0);
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "centerCoord = (centerCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real spread: 0.0
|
||||||
|
property real blur: 0.0
|
||||||
|
property color color: "white"
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: rootItem.blur
|
||||||
|
|
||||||
|
property real weight1;
|
||||||
|
property real weight2;
|
||||||
|
property real weight3;
|
||||||
|
property real weight4;
|
||||||
|
property real weight5;
|
||||||
|
property real weight6;
|
||||||
|
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property alias color: rootItem.color
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1.0 - v / 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,413 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real blur: 0.0
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
property real spread: 0.0
|
||||||
|
property color color: "black"
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
|
||||||
|
property real verticalOffset: rootItem.verticalOffset / rootItem.width
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform highp sampler2D source;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
uniform highp float horizontalOffset;
|
||||||
|
uniform highp float verticalOffset;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
|
||||||
|
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
|
||||||
|
lowp float eb = 1.0 - ea;
|
||||||
|
gl_FragColor = (eb * color + ea * color * (1.0 - texture2D(source, pos).a)) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: rootItem.blur
|
||||||
|
|
||||||
|
property real weight1;
|
||||||
|
property real weight2;
|
||||||
|
property real weight3;
|
||||||
|
property real weight4;
|
||||||
|
property real weight5;
|
||||||
|
property real weight6;
|
||||||
|
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1.0 - v / 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D original;
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 shadowColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
shadowColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
shadowColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
shadowColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
shadowColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
|
||||||
|
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
|
||||||
|
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property variant maskSource
|
||||||
|
property real blur: 0.0
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: mask0
|
||||||
|
property variant source: maskSourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: masklevel1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: mask0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant mask: masklevel1
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: Math.sqrt(rootItem.blur) * 1.2 - 0.2
|
||||||
|
property real weight1
|
||||||
|
property real weight2
|
||||||
|
property real weight3
|
||||||
|
property real weight4
|
||||||
|
property real weight5
|
||||||
|
property real weight6
|
||||||
|
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D mask;
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform lowp sampler2D source6;
|
||||||
|
uniform lowp float lod;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
mediump float weight(mediump float v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
return 1.0 - v * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
lowp vec4 maskColor = texture2D(mask, qt_TexCoord0);
|
||||||
|
mediump float l = lod * maskColor.a;
|
||||||
|
|
||||||
|
mediump float w1 = weight(abs(l - 0.100));
|
||||||
|
mediump float w2 = weight(abs(l - 0.300));
|
||||||
|
mediump float w3 = weight(abs(l - 0.500));
|
||||||
|
mediump float w4 = weight(abs(l - 0.700));
|
||||||
|
mediump float w5 = weight(abs(l - 0.900));
|
||||||
|
mediump float w6 = weight(abs(l - 1.100));
|
||||||
|
|
||||||
|
mediump float sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
mediump float weight1 = w1 / sum;
|
||||||
|
mediump float weight2 = w2 / sum;
|
||||||
|
mediump float weight3 = w3 / sum;
|
||||||
|
mediump float weight4 = w4 / sum;
|
||||||
|
mediump float weight5 = w5 / sum;
|
||||||
|
mediump float weight6 = w6 / sum;
|
||||||
|
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
sourceColor += texture2D(source6, qt_TexCoord0) * weight6;
|
||||||
|
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real deviation: (radius + 1) / 3.3333
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real horizontalStep: 0.0
|
||||||
|
property real verticalStep: 0.0
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
property bool enableColor: false
|
||||||
|
property color color: "white"
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
property bool enableMask: false
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: rootItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real deviation: Math.max(0.1, rootItem.deviation)
|
||||||
|
property real radius: rootItem.radius
|
||||||
|
property int maxRadius: rootItem.maximumRadius
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real gaussianSum: 0.0
|
||||||
|
property real startIndex: 0.0
|
||||||
|
property real deltaFactor: (2 * radius - 1) / (maxRadius * 2 - 1)
|
||||||
|
property real expandX: transparentBorder && rootItem.horizontalStep > 0 ? maxRadius / width : 0.0
|
||||||
|
property real expandY: transparentBorder && rootItem.verticalStep > 0 ? maxRadius / height : 0.0
|
||||||
|
property variant gwts: []
|
||||||
|
property variant delta: Qt.vector3d(rootItem.horizontalStep * deltaFactor, rootItem.verticalStep * deltaFactor, startIndex);
|
||||||
|
property variant factor_0_2: Qt.vector3d(gwts[0], gwts[1], gwts[2]);
|
||||||
|
property variant factor_3_5: Qt.vector3d(gwts[3], gwts[4], gwts[5]);
|
||||||
|
property variant factor_6_8: Qt.vector3d(gwts[6], gwts[7], gwts[8]);
|
||||||
|
property variant factor_9_11: Qt.vector3d(gwts[9], gwts[10], gwts[11]);
|
||||||
|
property variant factor_12_14: Qt.vector3d(gwts[12], gwts[13], gwts[14]);
|
||||||
|
property variant factor_15_17: Qt.vector3d(gwts[15], gwts[16], gwts[17]);
|
||||||
|
property variant factor_18_20: Qt.vector3d(gwts[18], gwts[19], gwts[20]);
|
||||||
|
property variant factor_21_23: Qt.vector3d(gwts[21], gwts[22], gwts[23]);
|
||||||
|
property variant factor_24_26: Qt.vector3d(gwts[24], gwts[25], gwts[26]);
|
||||||
|
property variant factor_27_29: Qt.vector3d(gwts[27], gwts[28], gwts[29]);
|
||||||
|
property variant factor_30_32: Qt.vector3d(gwts[30], gwts[31], gwts[32]);
|
||||||
|
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
|
||||||
|
anchors.fill: rootItem
|
||||||
|
|
||||||
|
function gausFunc(x){
|
||||||
|
//Gaussian function = h(x):=(1/sqrt(2*3.14159*(D^2))) * %e^(-(x^2)/(2*(D^2)));
|
||||||
|
return (1.0 / Math.sqrt(2 * Math.PI * (Math.pow(shaderItem.deviation, 2)))) * Math.pow(Math.E, -((Math.pow(x, 2)) / (2 * (Math.pow(shaderItem.deviation, 2)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateGaussianWeights() {
|
||||||
|
gaussianSum = 0.0;
|
||||||
|
startIndex = -maxRadius + 0.5
|
||||||
|
|
||||||
|
var n = new Array(32);
|
||||||
|
for (var j = 0; j < 32; j++)
|
||||||
|
n[j] = 0;
|
||||||
|
|
||||||
|
var max = maxRadius * 2
|
||||||
|
var delta = (2 * radius - 1) / (max - 1);
|
||||||
|
for (var i = 0; i < max; i++) {
|
||||||
|
n[i] = gausFunc(-radius + 0.5 + i * delta);
|
||||||
|
gaussianSum += n[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
gwts = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
|
||||||
|
var shaderSteps = [
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.z; texCoord += shift;"
|
||||||
|
]
|
||||||
|
|
||||||
|
var shader = fragmentShaderBegin
|
||||||
|
var samples = maxRadius * 2
|
||||||
|
if (samples > 32) {
|
||||||
|
console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!")
|
||||||
|
samples = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < samples; i++) {
|
||||||
|
shader += shaderSteps[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
shader += fragmentShaderEnd
|
||||||
|
|
||||||
|
var colorizeSteps = ""
|
||||||
|
var colorizeUniforms = ""
|
||||||
|
|
||||||
|
var maskSteps = ""
|
||||||
|
var maskUniforms = ""
|
||||||
|
|
||||||
|
if (enableColor) {
|
||||||
|
colorizeSteps += "gl_FragColor = mix(vec4(0), color, clamp((gl_FragColor.a - 0.0) / (spread - 0.0), 0.0, 1.0));\n"
|
||||||
|
colorizeUniforms += "uniform highp vec4 color;\n"
|
||||||
|
colorizeUniforms += "uniform highp float spread;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableMask) {
|
||||||
|
maskSteps += "shift *= texture2D(maskSource, qt_TexCoord0).a;\n"
|
||||||
|
maskUniforms += "uniform sampler2D maskSource;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_STEPS", colorizeSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_UNIFORMS", colorizeUniforms)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_STEPS", maskSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_UNIFORMS", maskUniforms)
|
||||||
|
|
||||||
|
fragmentShader = shader
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeviationChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onRadiusChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onTransparentBorderChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMaxRadiusChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
property string fragmentShaderBegin: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec3 delta;
|
||||||
|
uniform highp vec3 factor_0_2;
|
||||||
|
uniform highp vec3 factor_3_5;
|
||||||
|
uniform highp vec3 factor_6_8;
|
||||||
|
uniform highp vec3 factor_9_11;
|
||||||
|
uniform highp vec3 factor_12_14;
|
||||||
|
uniform highp vec3 factor_15_17;
|
||||||
|
uniform highp vec3 factor_18_20;
|
||||||
|
uniform highp vec3 factor_21_23;
|
||||||
|
uniform highp vec3 factor_24_26;
|
||||||
|
uniform highp vec3 factor_27_29;
|
||||||
|
uniform highp vec3 factor_30_32;
|
||||||
|
uniform highp float gaussianSum;
|
||||||
|
uniform highp float expandX;
|
||||||
|
uniform highp float expandY;
|
||||||
|
PLACEHOLDER_MASK_UNIFORMS
|
||||||
|
PLACEHOLDER_COLORIZE_UNIFORMS
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 shift = vec2(delta.x, delta.y);
|
||||||
|
|
||||||
|
PLACEHOLDER_MASK_STEPS
|
||||||
|
|
||||||
|
highp float index = delta.z;
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
|
||||||
|
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
|
||||||
|
texCoord += (shift * index);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
"
|
||||||
|
|
||||||
|
property string fragmentShaderEnd: "
|
||||||
|
|
||||||
|
gl_FragColor /= gaussianSum;
|
||||||
|
|
||||||
|
PLACEHOLDER_COLORIZE_STEPS
|
||||||
|
|
||||||
|
gl_FragColor *= qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real spread: 0.0
|
||||||
|
property color color: "white"
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: shaderItem
|
||||||
|
x: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
enableColor: true
|
||||||
|
color: rootItem.color
|
||||||
|
spread: rootItem.spread
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
property real spread: 0
|
||||||
|
property color color: "black"
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect{
|
||||||
|
id: shadowItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
|
||||||
|
property real verticalOffset: rootItem.verticalOffset / rootItem.height
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp sampler2D original;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
uniform highp float horizontalOffset;
|
||||||
|
uniform highp float verticalOffset;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
|
||||||
|
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
|
||||||
|
lowp float eb = 1.0 - ea;
|
||||||
|
gl_FragColor = eb * color + ea * color * (1.0 - texture2D(original, pos).a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: blurItem
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius : parent.width
|
||||||
|
height: parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: shadowItem
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: blurredSource
|
||||||
|
sourceItem: blurItem
|
||||||
|
live: true
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property variant shadow: blurredSource
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp sampler2D original;
|
||||||
|
uniform highp sampler2D shadow;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
|
||||||
|
lowp vec4 shadowColor = texture2D(shadow, qt_TexCoord0);
|
||||||
|
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
|
||||||
|
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property variant maskSource
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: blur
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: blur
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: blur
|
||||||
|
x: transparentBorder ? -maximumRadius - 1: 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1: 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
enableMask: true
|
||||||
|
maskSource: maskSourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: sourceProxy.output
|
||||||
|
enableMask: true
|
||||||
|
maskSource: maskSourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant input
|
||||||
|
property variant output
|
||||||
|
property variant sourceRect
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Component.onCompleted: evaluateInput()
|
||||||
|
|
||||||
|
onInputChanged: evaluateInput()
|
||||||
|
|
||||||
|
onSourceRectChanged: evaluateInput()
|
||||||
|
|
||||||
|
function evaluateInput() {
|
||||||
|
if (input == undefined) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = sourceRect
|
||||||
|
}
|
||||||
|
else if (isQQuickItemLayerEnabled(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (isQQuickShaderEffectSource(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickItemLayerEnabled(item) {
|
||||||
|
if (item.hasOwnProperty("layer")) {
|
||||||
|
var l = item["layer"]
|
||||||
|
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickImage(item) {
|
||||||
|
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
|
||||||
|
return hasProperties(item, imageProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickShaderEffectSource(item) {
|
||||||
|
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
|
||||||
|
return hasProperties(item, shaderEffectSourceProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasProperties(item, properties) {
|
||||||
|
var counter = 0
|
||||||
|
for (var j = 0; j < properties.length; j++) {
|
||||||
|
if (item.hasOwnProperty(properties [j]))
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
return properties.length == counter
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasChildren(item) {
|
||||||
|
if (item.hasOwnProperty("childrenRect")) {
|
||||||
|
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTileMode(item) {
|
||||||
|
if (item.hasOwnProperty("fillMode")) {
|
||||||
|
if (item["fillMode"].toString() != "0")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: proxySource
|
||||||
|
live: rootItem.input != rootItem.output
|
||||||
|
hideSource: false
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,478 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Blend
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blend
|
||||||
|
\brief Merges two source items by using a blend mode.
|
||||||
|
|
||||||
|
Blend mode can be selected with the \l{Blend::mode}{mode} property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li source
|
||||||
|
\li foregroundSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image Blend_bug_and_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Blend-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be the base when
|
||||||
|
\l{Blend::foregroundSource}{foregroundSource} is blended over it.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be blended over the
|
||||||
|
\l{Blend::source}{source}.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting foregroundSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant foregroundSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the mode which is used when foregroundSource is
|
||||||
|
blended over source. Values are case insensitive.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li mode
|
||||||
|
\li description
|
||||||
|
\row
|
||||||
|
\li normal
|
||||||
|
\li The pixel component values from foregroundSource are written
|
||||||
|
over source by using alpha blending.
|
||||||
|
\row
|
||||||
|
\li addition
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
added together and written.
|
||||||
|
\row
|
||||||
|
\li average
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
averaged and written.
|
||||||
|
\row
|
||||||
|
\li color
|
||||||
|
\li The lightness value from source is combined with hue and
|
||||||
|
saturation from foregroundSource and written.
|
||||||
|
\row
|
||||||
|
\li colorBurn
|
||||||
|
\li The darker pixels from source are darkened more, if both source
|
||||||
|
and foregroundSource pixels are light the result is light.
|
||||||
|
\row
|
||||||
|
\li colorDodge
|
||||||
|
\li The lighter pixels from source are lightened more, if both
|
||||||
|
source and foregroundSource pixels are dark the result is dark.
|
||||||
|
\row
|
||||||
|
\li darken
|
||||||
|
\li The darker pixel component value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li darkerColor
|
||||||
|
\li The lower luminance pixel rgb-value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li difference
|
||||||
|
\li The absolute pixel component value difference between source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li divide
|
||||||
|
\li The pixel component values from source is divided by the value
|
||||||
|
from foregroundSource and written.
|
||||||
|
\row
|
||||||
|
\li exclusion
|
||||||
|
\li The pixel component value difference with reduced contrast
|
||||||
|
between source and foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li hardLight
|
||||||
|
\li The pixel component values from source are lightened or darkened
|
||||||
|
according to foregroundSource values and written.
|
||||||
|
\row
|
||||||
|
\li hue
|
||||||
|
\li The hue value from foregroundSource is combined with saturation
|
||||||
|
and lightness from source and written.
|
||||||
|
\row
|
||||||
|
\li lighten
|
||||||
|
\li The lightest pixel component value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li lighterColor
|
||||||
|
\li The higher luminance pixel rgb-value from source and
|
||||||
|
foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li lightness
|
||||||
|
\li The lightness value from foregroundSource is combined with hue
|
||||||
|
and saturation from source and written.
|
||||||
|
\row
|
||||||
|
\li multiply
|
||||||
|
\li The pixel component values from source and foregroundSource are
|
||||||
|
multiplied together and written.
|
||||||
|
\row
|
||||||
|
\li negation
|
||||||
|
\li The inverted absolute pixel component value difference between
|
||||||
|
source and foregroundSource is written.
|
||||||
|
\row
|
||||||
|
\li saturation
|
||||||
|
\li The saturation value from foregroundSource is combined with hue
|
||||||
|
and lightness from source and written.
|
||||||
|
\row
|
||||||
|
\li screen
|
||||||
|
\li The pixel values from source and foregroundSource are negated,
|
||||||
|
then multiplied, negated again, and written.
|
||||||
|
\row
|
||||||
|
\li subtract
|
||||||
|
\li Pixel value from foregroundSource is subracted from source and
|
||||||
|
written.
|
||||||
|
\row
|
||||||
|
\li softLight
|
||||||
|
\li The pixel component values from source are lightened or darkened
|
||||||
|
slightly according to foregroundSource values and written.
|
||||||
|
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Example source
|
||||||
|
\li Example foregroundSource
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different mode values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode1.png
|
||||||
|
\li \image Blend_mode2.png
|
||||||
|
\li \image Blend_mode3.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: normal }
|
||||||
|
\li \b { mode: addition }
|
||||||
|
\li \b { mode: average }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode4.png
|
||||||
|
\li \image Blend_mode5.png
|
||||||
|
\li \image Blend_mode6.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: color }
|
||||||
|
\li \b { mode: colorBurn }
|
||||||
|
\li \b { mode: colorDodge }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode7.png
|
||||||
|
\li \image Blend_mode8.png
|
||||||
|
\li \image Blend_mode9.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: darken }
|
||||||
|
\li \b { mode: darkerColor }
|
||||||
|
\li \b { mode: difference }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode10.png
|
||||||
|
\li \image Blend_mode11.png
|
||||||
|
\li \image Blend_mode12.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: divide }
|
||||||
|
\li \b { mode: exclusion }
|
||||||
|
\li \b { mode: hardlight }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode13.png
|
||||||
|
\li \image Blend_mode14.png
|
||||||
|
\li \image Blend_mode15.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: hue }
|
||||||
|
\li \b { mode: lighten }
|
||||||
|
\li \b { mode: lighterColor }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode16.png
|
||||||
|
\li \image Blend_mode17.png
|
||||||
|
\li \image Blend_mode18.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: lightness }
|
||||||
|
\li \b { mode: negation }
|
||||||
|
\li \b { mode: multiply }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode19.png
|
||||||
|
\li \image Blend_mode20.png
|
||||||
|
\li \image Blend_mode21.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: saturation }
|
||||||
|
\li \b { mode: screen }
|
||||||
|
\li \b { mode: subtract }
|
||||||
|
\row
|
||||||
|
\li \image Blend_mode22.png
|
||||||
|
\row
|
||||||
|
\li \b { mode: softLight }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property string mode: "normal"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in the
|
||||||
|
cache must be updated. Memory consumption is increased, because an extra
|
||||||
|
buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: backgroundSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: foregroundSourceProxy
|
||||||
|
input: rootItem.foregroundSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant backgroundSource: backgroundSourceProxy.output
|
||||||
|
property variant foregroundSource: foregroundSourceProxy.output
|
||||||
|
property string mode: rootItem.mode
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: fragmentShaderBegin + blendModeNormal + fragmentShaderEnd
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderBegin
|
||||||
|
|
||||||
|
switch (mode.toLowerCase()) {
|
||||||
|
case "addition" : shader += blendModeAddition; break;
|
||||||
|
case "average" : shader += blendModeAverage; break;
|
||||||
|
case "color" : shader += blendModeColor; break;
|
||||||
|
case "colorburn" : shader += blendModeColorBurn; break;
|
||||||
|
case "colordodge" : shader += blendModeColorDodge; break;
|
||||||
|
case "darken" : shader += blendModeDarken; break;
|
||||||
|
case "darkercolor" : shader += blendModeDarkerColor; break;
|
||||||
|
case "difference" : shader += blendModeDifference; break;
|
||||||
|
case "divide" : shader += blendModeDivide; break;
|
||||||
|
case "exclusion" : shader += blendModeExclusion; break;
|
||||||
|
case "hardlight" : shader += blendModeHardLight; break;
|
||||||
|
case "hue" : shader += blendModeHue; break;
|
||||||
|
case "lighten" : shader += blendModeLighten; break;
|
||||||
|
case "lightercolor" : shader += blendModeLighterColor; break;
|
||||||
|
case "lightness" : shader += blendModeLightness; break;
|
||||||
|
case "negation" : shader += blendModeNegation; break;
|
||||||
|
case "normal" : shader += blendModeNormal; break;
|
||||||
|
case "multiply" : shader += blendModeMultiply; break;
|
||||||
|
case "saturation" : shader += blendModeSaturation; break;
|
||||||
|
case "screen" : shader += blendModeScreen; break;
|
||||||
|
case "subtract" : shader += blendModeSubtract; break;
|
||||||
|
case "softlight" : shader += blendModeSoftLight; break;
|
||||||
|
default: shader += "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader += fragmentShaderEnd
|
||||||
|
fragmentShader = shader
|
||||||
|
|
||||||
|
// Workaraound for a bug just to make sure display gets updated when the mode changes.
|
||||||
|
backgroundSourceChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
buildFragmentShader()
|
||||||
|
}
|
||||||
|
|
||||||
|
onModeChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
}
|
||||||
|
|
||||||
|
property string blendModeAddition: "result.rgb = min(rgb1 + rgb2, 1.0);"
|
||||||
|
property string blendModeAverage: "result.rgb = 0.5 * (rgb1 + rgb2);"
|
||||||
|
property string blendModeColor: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).xy, RGBtoL(rgb1)));"
|
||||||
|
property string blendModeColorBurn: "result.rgb = clamp(1.0 - ((1.0 - rgb1) / max(vec3(1.0 / 256.0), rgb2)), vec3(0.0), vec3(1.0));"
|
||||||
|
property string blendModeColorDodge: "result.rgb = clamp(rgb1 / max(vec3(1.0 / 256.0), (1.0 - rgb2)), vec3(0.0), vec3(1.0));"
|
||||||
|
property string blendModeDarken: "result.rgb = min(rgb1, rgb2);"
|
||||||
|
property string blendModeDarkerColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb2 : rgb1;"
|
||||||
|
property string blendModeDifference: "result.rgb = abs(rgb1 - rgb2);"
|
||||||
|
property string blendModeDivide: "result.rgb = clamp(rgb1 / rgb2, 0.0, 1.0);"
|
||||||
|
property string blendModeExclusion: "result.rgb = rgb1 + rgb2 - 2.0 * rgb1 * rgb2;"
|
||||||
|
property string blendModeHardLight: "result.rgb = vec3(channelBlendHardLight(rgb1.r, rgb2.r), channelBlendHardLight(rgb1.g, rgb2.g), channelBlendHardLight(rgb1.b, rgb2.b));"
|
||||||
|
property string blendModeHue: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb2).x, RGBtoHSL(rgb1).yz));"
|
||||||
|
property string blendModeLighten: "result.rgb = max(rgb1, rgb2);"
|
||||||
|
property string blendModeLighterColor: "result.rgb = 0.3 * rgb1.r + 0.59 * rgb1.g + 0.11 * rgb1.b > 0.3 * rgb2.r + 0.59 * rgb2.g + 0.11 * rgb2.b ? rgb1 : rgb2;"
|
||||||
|
property string blendModeLightness: "result.rgb = HSLtoRGB(vec3(RGBtoHSL(rgb1).xy, RGBtoL(rgb2)));"
|
||||||
|
property string blendModeMultiply: "result.rgb = rgb1 * rgb2;"
|
||||||
|
property string blendModeNegation: "result.rgb = 1.0 - abs(1.0 - rgb1 - rgb2);"
|
||||||
|
property string blendModeNormal: "result.rgb = rgb2; a = max(color1.a, color2.a);"
|
||||||
|
property string blendModeSaturation: "lowp vec3 hsl1 = RGBtoHSL(rgb1); result.rgb = HSLtoRGB(vec3(hsl1.x, RGBtoHSL(rgb2).y, hsl1.z));"
|
||||||
|
property string blendModeScreen: "result.rgb = 1.0 - (vec3(1.0) - rgb1) * (vec3(1.0) - rgb2);"
|
||||||
|
property string blendModeSubtract: "result.rgb = max(rgb1 - rgb2, vec3(0.0));"
|
||||||
|
property string blendModeSoftLight: "result.rgb = rgb1 * ((1.0 - rgb1) * rgb2 + (1.0 - (1.0 - rgb1) * (1.0 - rgb2)));"
|
||||||
|
|
||||||
|
property string fragmentShaderBegin: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D backgroundSource;
|
||||||
|
uniform lowp sampler2D foregroundSource;
|
||||||
|
|
||||||
|
highp float RGBtoL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
highp vec3 RGBtoHSL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float h = 0.0;
|
||||||
|
highp float s = 0.0;
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
highp float diff = cmax - cmin;
|
||||||
|
|
||||||
|
if (diff > 1.0 / 256.0) {
|
||||||
|
if (l < 0.5)
|
||||||
|
s = diff / (cmin + cmax);
|
||||||
|
else
|
||||||
|
s = diff / (2.0 - (cmin + cmax));
|
||||||
|
|
||||||
|
if (color.r == cmax)
|
||||||
|
h = (color.g - color.b) / diff;
|
||||||
|
else if (color.g == cmax)
|
||||||
|
h = 2.0 + (color.b - color.r) / diff;
|
||||||
|
else
|
||||||
|
h = 4.0 + (color.r - color.g) / diff;
|
||||||
|
|
||||||
|
h /= 6.0;
|
||||||
|
}
|
||||||
|
return vec3(h, s, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
lowp float channelBlendHardLight(lowp float c1, lowp float c2) {
|
||||||
|
return c2 > 0.5 ? (1.0 - (1.0 - 2.0 * (c2 - 0.5)) * (1.0 - c1)) : (2.0 * c1 * c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 result = vec4(0.0);
|
||||||
|
lowp vec4 color1 = texture2D(backgroundSource, qt_TexCoord0);
|
||||||
|
lowp vec4 color2 = texture2D(foregroundSource, qt_TexCoord0);
|
||||||
|
lowp vec3 rgb1 = color1.rgb / max(1.0/256.0, color1.a);
|
||||||
|
lowp vec3 rgb2 = color2.rgb / max(1.0/256.0, color2.a);
|
||||||
|
highp float a = max(color1.a, color1.a * color2.a);
|
||||||
|
"
|
||||||
|
|
||||||
|
property string fragmentShaderEnd: "
|
||||||
|
gl_FragColor.rgb = mix(rgb1, result.rgb, color2.a);
|
||||||
|
gl_FragColor.rbg *= a;
|
||||||
|
gl_FragColor.a = a;
|
||||||
|
gl_FragColor *= qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype BrightnessContrast
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Adjusts brightness and contrast.
|
||||||
|
|
||||||
|
This effect adjusts the source item colors.
|
||||||
|
Brightness adjustment changes the perceived luminance of the source item.
|
||||||
|
Contrast adjustment increases or decreases the color
|
||||||
|
and brightness variations.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image BrightnessContrast_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet BrightnessContrast-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source brightness is increased or
|
||||||
|
decreased.
|
||||||
|
|
||||||
|
The value ranges from -1.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different brightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_brightness1.png
|
||||||
|
\li \image BrightnessContrast_brightness2.png
|
||||||
|
\li \image BrightnessContrast_brightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { brightness: -0.25 }
|
||||||
|
\li \b { brightness: 0 }
|
||||||
|
\li \b { brightness: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l contrast: 0
|
||||||
|
\li \l contrast: 0
|
||||||
|
\li \l contrast: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real brightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source contrast is increased or
|
||||||
|
decreased. The decrease of the contrast is linear, but the increase is
|
||||||
|
applied with a non-linear curve to allow very high contrast adjustment at
|
||||||
|
the high end of the value range.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Contrast adjustment curve
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_contrast_graph.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
The value ranges from -1.0 to 1.0. By default, the property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different contrast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image BrightnessContrast_contrast1.png
|
||||||
|
\li \image BrightnessContrast_contrast2.png
|
||||||
|
\li \image BrightnessContrast_contrast3.png
|
||||||
|
\row
|
||||||
|
\li \b { contrast: -0.5 }
|
||||||
|
\li \b { contrast: 0 }
|
||||||
|
\li \b { contrast: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l brightness: 0
|
||||||
|
\li \l brightness: 0
|
||||||
|
\li \l brightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real contrast: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real brightness: rootItem.brightness
|
||||||
|
property real contrast: rootItem.contrast
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
blending: !rootItem.cached
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float brightness;
|
||||||
|
uniform highp float contrast;
|
||||||
|
void main() {
|
||||||
|
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
|
||||||
|
pixelColor.rgb /= max(1.0/256.0, pixelColor.a);
|
||||||
|
highp float c = 1.0 + contrast;
|
||||||
|
highp float contrastGainFactor = 1.0 + c * c * c * c * step(0.0, contrast);
|
||||||
|
pixelColor.rgb = ((pixelColor.rgb - 0.5) * (contrastGainFactor * contrast + 1.0)) + 0.5;
|
||||||
|
pixelColor.rgb = mix(pixelColor.rgb, vec3(step(0.0, brightness)), abs(brightness));
|
||||||
|
gl_FragColor = vec4(pixelColor.rgb * pixelColor.a, pixelColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ColorOverlay
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the colors of the source item by applying an overlay color.
|
||||||
|
|
||||||
|
The effect is similar to what happens when a colorized glass is put on top
|
||||||
|
of a grayscale image. The color for the overlay is given in the RGBA format.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image ColorOverlay_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ColorOverlay-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
By default, the property is set to \c "transparent".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ColorOverlay_color1.png
|
||||||
|
\li \image ColorOverlay_color2.png
|
||||||
|
\li \image ColorOverlay_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #80ff0000 }
|
||||||
|
\li \b { color: #8000ff00 }
|
||||||
|
\li \b { color: #800000ff }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "transparent"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
void main() {
|
||||||
|
highp vec4 pixelColor = texture2D(source, qt_TexCoord0);
|
||||||
|
gl_FragColor = vec4(mix(pixelColor.rgb/max(pixelColor.a, 0.00390625), color.rgb/max(color.a, 0.00390625), color.a) * pixelColor.a, pixelColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Colorize
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Sets the color in the HSL color space.
|
||||||
|
|
||||||
|
The effect is similar to what happens when a colorized glass is put on top
|
||||||
|
of a grayscale image. Colorize uses the hue, saturation, and lightness (HSL)
|
||||||
|
color space. You can specify a desired value for each property. You can
|
||||||
|
shift all HSL values with the
|
||||||
|
\l{QtGraphicalEffects1::HueSaturation}{HueSaturation} effect.
|
||||||
|
|
||||||
|
Alternatively, you can use the
|
||||||
|
\l{QtGraphicalEffects1::ColorOverlay}{ColorOverlay} effect to colorize the
|
||||||
|
source item in the RGBA color space.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Colorize_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Colorize-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the hue value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.0, which produces a slightly red color.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Allowed hue values
|
||||||
|
\row
|
||||||
|
\li \image Colorize_hue_scale.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different hue values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_hue1.png
|
||||||
|
\li \image Colorize_hue2.png
|
||||||
|
\li \image Colorize_hue3.png
|
||||||
|
\row
|
||||||
|
\li \b { hue: 0.2 }
|
||||||
|
\li \b { hue: 0.5 }
|
||||||
|
\li \b { hue: 0.8 }
|
||||||
|
\row
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real hue: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the saturation value which is used to colorize the
|
||||||
|
source.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (desaturated) to 1.0 (saturated). By default,
|
||||||
|
the property is set to \c 1.0 (saturated).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different saturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_saturation1.png
|
||||||
|
\li \image Colorize_saturation2.png
|
||||||
|
\li \image Colorize_saturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { saturation: 0 }
|
||||||
|
\li \b { saturation: 0.5 }
|
||||||
|
\li \b { saturation: 1 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real saturation: 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source lightness value is increased
|
||||||
|
or decreased.
|
||||||
|
|
||||||
|
Unlike hue and saturation properties, lightness does not set the used
|
||||||
|
value, but it shifts the existing source pixel lightness value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decreased) to 1.0 (increased). By default,
|
||||||
|
the property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different lightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Colorize_lightness1.png
|
||||||
|
\li \image Colorize_lightness2.png
|
||||||
|
\li \image Colorize_lightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { lightness: -0.75 }
|
||||||
|
\li \b { lightness: 0 }
|
||||||
|
\li \b { lightness: 0.75 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\li \l saturation: 1
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real lightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real hue: rootItem.hue
|
||||||
|
property real saturation: rootItem.saturation
|
||||||
|
property real lightness: rootItem.lightness
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float hue;
|
||||||
|
uniform highp float saturation;
|
||||||
|
uniform highp float lightness;
|
||||||
|
|
||||||
|
highp float RGBtoL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 sample = texture2D(source, qt_TexCoord0);
|
||||||
|
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
|
||||||
|
highp float light = RGBtoL(sample.rgb);
|
||||||
|
highp float c = step(0.0, lightness);
|
||||||
|
sample.rgb = HSLtoRGB(vec3(hue, saturation, mix(light, c, abs(lightness))));
|
||||||
|
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ConicalGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a conical gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the specified angle and end at 360 degrees larger
|
||||||
|
angle value.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ConicalGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the starting angle where the color at the gradient
|
||||||
|
position of 0.0 is rendered. Colors at larger position values are
|
||||||
|
rendered into larger angle values and blended seamlessly. Angle values
|
||||||
|
increase clockwise.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_angle1.png
|
||||||
|
\li \image ConicalGradient_angle2.png
|
||||||
|
\li \image ConicalGradient_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0 }
|
||||||
|
\li \b { angle: 45 }
|
||||||
|
\li \b { angle: 185 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ConicalGradient::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ConicalGradient::verticalOffset
|
||||||
|
|
||||||
|
The horizontalOffset and verticalOffset properties define the offset in
|
||||||
|
pixels for the center point of the gradient compared to the item center.
|
||||||
|
|
||||||
|
The value ranges from -inf to inf. By default, the properties are set to \c
|
||||||
|
0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_horizontalOffset1.png
|
||||||
|
\li \image ConicalGradient_horizontalOffset2.png
|
||||||
|
\li \image ConicalGradient_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -50 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 50 }
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_maskSource1.png
|
||||||
|
\li \image ConicalGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: }
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors are specified as a set of GradientStop child items, each of which
|
||||||
|
defines a position on the gradient (from 0.0 to 1.0), and a color.
|
||||||
|
The position of each GradientStop is defined by the position property.
|
||||||
|
The color is defined by the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ConicalGradient_gradient1.png
|
||||||
|
\li \image ConicalGradient_gradient2.png
|
||||||
|
\li \image ConicalGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: gradientRect
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
rotation: shaderItem.rotation
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant gradientSource: ShaderEffectSource {
|
||||||
|
sourceItem: gradientRect
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property real startAngle: (rootItem.angle - 90) * Math.PI/180
|
||||||
|
property variant center: Qt.point(0.5 + horizontalOffset / width, 0.5 + verticalOffset / height)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: startAngleChanged()
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform lowp sampler2D gradientSource;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp float startAngle;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
const highp float PI = 3.14159265;
|
||||||
|
const highp float PIx2inv = 0.1591549;
|
||||||
|
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
|
||||||
|
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform lowp sampler2D gradientSource;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp float startAngle;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
const highp float PI = 3.14159265;
|
||||||
|
const highp float PIx2inv = 0.1591549;
|
||||||
|
highp float a = (atan((center.y - qt_TexCoord0.t), (center.x - qt_TexCoord0.s)) + PI - startAngle) * PIx2inv;
|
||||||
|
gl_FragColor = texture2D(gradientSource, vec2(0.0, fract(a))) * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Desaturate
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Reduces the saturation of the colors.
|
||||||
|
|
||||||
|
Desaturated pixel values are calculated as averages of the original RGB
|
||||||
|
component values of the source item.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Desaturate_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Desaturate-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels to
|
||||||
|
the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how much the source colors are desaturated.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no change) to 1.0 (desaturated). By default,
|
||||||
|
the property is set to \c 0.0 (no chnage).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different desaturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Desaturate_desaturation1.png
|
||||||
|
\li \image Desaturate_desaturation2.png
|
||||||
|
\li \image Desaturate_desaturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { desaturation: 0.0 }
|
||||||
|
\li \b { desaturation: 0.5 }
|
||||||
|
\li \b { desaturation: 1.0 }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real desaturation: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real desaturation: rootItem.desaturation
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float desaturation;
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
lowp float grayColor = (textureColor.r + textureColor.g + textureColor.b) / 3.0;
|
||||||
|
gl_FragColor = mix(textureColor, vec4(vec3(grayColor), textureColor.a), desaturation) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,289 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype DirectionalBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies blur effect to the specified direction.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
moving in the direction of the blur. Blur is applied to both sides of
|
||||||
|
each pixel, therefore setting the direction to 0 and 180 provides the
|
||||||
|
same result.
|
||||||
|
|
||||||
|
Other available motionblur effects are \l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
|
||||||
|
\l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image DirectionalBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet DirectionalBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the percieved amount of movement for each pixel.
|
||||||
|
The movement is divided evenly to both sides of each pixel.
|
||||||
|
|
||||||
|
The quality of the blur depends on \l{DirectionalBlur::samples}{samples}
|
||||||
|
property. If length value is large, more samples are needed to keep the
|
||||||
|
visual quality at high level.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to inf.
|
||||||
|
By default the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different length values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DirectionalBlur_length1.png
|
||||||
|
\li \image DirectionalBlur_length2.png
|
||||||
|
\li \image DirectionalBlur_length3.png
|
||||||
|
\row
|
||||||
|
\li \b { length: 0.0 }
|
||||||
|
\li \b { length: 32.0 }
|
||||||
|
\li \b { length: 48.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real length: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the direction for the blur. Blur is applied to
|
||||||
|
both sides of each pixel, therefore setting the direction to 0 and 180
|
||||||
|
produces the same result.
|
||||||
|
|
||||||
|
The value ranges from -180.0 to 180.0.
|
||||||
|
By default the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DirectionalBlur_angle1.png
|
||||||
|
\li \image DirectionalBlur_angle2.png
|
||||||
|
\li \image DirectionalBlur_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0.0 }
|
||||||
|
\li \b { angle: 45.0 }
|
||||||
|
\li \b { angle: 90.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real len: rootItem.length
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width * Math.cos((rootItem.angle + 90) * Math.PI/180), 1.0 / rootItem.height * Math.sin((rootItem.angle + 90) * Math.PI/180))
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1: 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float len;
|
||||||
|
uniform highp float samples;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 shift = delta * len / max(1.0, samples - 1.0);
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
texCoord -= shift * max(0.0, samples - 1.0) * 0.5;
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,217 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Displace
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-distortion
|
||||||
|
\brief Moves the pixels of the source item according to the given
|
||||||
|
displacement map.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li DisplacementSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image Displace_map.png
|
||||||
|
\li \image Displace_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Displace-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item for the pixels that are going to
|
||||||
|
be displaced according to the data from
|
||||||
|
\l{Displace::displacementSource}{displacementSource}.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the
|
||||||
|
displacement map. The displacementSource item gets rendered into the
|
||||||
|
intermediate pixel buffer. The red and green component values from the
|
||||||
|
result determine the displacement of the pixels from the source item.
|
||||||
|
|
||||||
|
The format for the displacement map is similar to the tangent space
|
||||||
|
normal maps, which can be created with most 3D-modeling tools. Many
|
||||||
|
image processing tools include the support for generating normal maps.
|
||||||
|
Alternatively, the displacement map for this effect can also be a QML
|
||||||
|
element which is colored appropriately. Like any QML element, it can be
|
||||||
|
animated. It is recommended that the size of the diplacement map matches
|
||||||
|
the size of the \l{Displace::source}{source}.
|
||||||
|
|
||||||
|
The displace data is interpreted in the RGBA format. For every pixel:
|
||||||
|
the red channel stores the x-axis displacement, and the green channel
|
||||||
|
stores the y-axis displacement. Blue and alpha channels are ignored for
|
||||||
|
this effect.
|
||||||
|
|
||||||
|
Assuming that red channel value 1.0 is fully red (0.0 having no red at
|
||||||
|
all), this effect considers pixel component value 0.5 to cause no
|
||||||
|
displacement at all. Values above 0.5 shift pixels to the left, values
|
||||||
|
below 0.5 do the shift to the right. In a similar way, green channel
|
||||||
|
values above 0.5 displace the pixels upwards, and values below 0.5 shift
|
||||||
|
the pixels downwards. The actual amount of displacement in pixels
|
||||||
|
depends on the \l displacement property.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant displacementSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the scale for the displacement. The bigger scale,
|
||||||
|
the bigger the displacement of the pixels. The value set to 0.0 causes
|
||||||
|
no displacement.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (inverted maximum shift, according to
|
||||||
|
displacementSource) to 1.0 (maximum shift, according to
|
||||||
|
displacementSource). By default, the property is set to \c 0.0 (no
|
||||||
|
displacement).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different displacement values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Displace_displacement1.png
|
||||||
|
\li \image Displace_displacement2.png
|
||||||
|
\li \image Displace_displacement3.png
|
||||||
|
\row
|
||||||
|
\li \b { displacement: -0.2 }
|
||||||
|
\li \b { displacement: 0.0 }
|
||||||
|
\li \b { displacement: 0.2 }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real displacement: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: displacementSourceProxy
|
||||||
|
input: rootItem.displacementSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant displacementSource: displacementSourceProxy.output
|
||||||
|
property real displacement: rootItem.displacement
|
||||||
|
property real xPixel: 1.0/width
|
||||||
|
property real yPixel: 1.0/height
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D displacementSource;
|
||||||
|
uniform highp float displacement;
|
||||||
|
uniform highp float xPixel;
|
||||||
|
uniform highp float yPixel;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 offset = texture2D(displacementSource, qt_TexCoord0);
|
||||||
|
offset.xy -= vec2(0.5, 0.5);
|
||||||
|
offset.xy = offset.xy * step(vec2(1.0/256.0), abs(offset.xy));
|
||||||
|
highp vec2 tx = qt_TexCoord0 + (vec2(-offset.x, offset.y) * displacement);
|
||||||
|
|
||||||
|
lowp float e1 = linearstep(0.0, xPixel, tx.x);
|
||||||
|
lowp float e2 = linearstep(0.0, yPixel, tx.y);
|
||||||
|
lowp float e3 = 1.0 - linearstep(1.0, 1.0 + xPixel, tx.x);
|
||||||
|
lowp float e4 = 1.0 - linearstep(1.0, 1.0 + yPixel, tx.y);
|
||||||
|
|
||||||
|
lowp vec4 sample = texture2D(source, tx);
|
||||||
|
sample.rgb *= e1 * e2 * e3 * e4;
|
||||||
|
gl_FragColor = sample * qt_Opacity * offset.a;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,403 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype DropShadow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-drop-shadow
|
||||||
|
\brief Generates a colorized and blurred shadow image of the
|
||||||
|
source and places it behind the original, giving the impression that
|
||||||
|
source item is raised from the background.
|
||||||
|
|
||||||
|
By default the effect produces a high quality shadow image, thus the
|
||||||
|
rendering speed of the shadow might not be the highest possible. The
|
||||||
|
rendering speed is reduced especially if the shadow edges are heavily
|
||||||
|
softened.
|
||||||
|
|
||||||
|
For use cases that require faster rendering speed and for which the highest
|
||||||
|
possible visual quality is not necessary, property
|
||||||
|
\l{DropShadow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image DropShadow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet DropShadow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as the
|
||||||
|
source for the generated shadow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the shadow. A larger radius causes the
|
||||||
|
edges of the shadow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{DropShadow::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_radius1.png
|
||||||
|
\li \image DropShadow_radius2.png
|
||||||
|
\li \image DropShadow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{DropShadow::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the shadow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "black".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_color1.png
|
||||||
|
\li \image DropShadow_color2.png
|
||||||
|
\li \image DropShadow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #000000 }
|
||||||
|
\li \b { color: #0000ff }
|
||||||
|
\li \b { color: #aa000000 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "black"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::DropShadow::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::DropShadow::verticalOffset
|
||||||
|
|
||||||
|
HorizontalOffset and verticalOffset properties define the offset for the
|
||||||
|
rendered shadow compared to the DropShadow item position. Often, the
|
||||||
|
DropShadow item is anchored so that it fills the source element. In this
|
||||||
|
case, if the HorizontalOffset and verticalOffset properties are set to
|
||||||
|
0, the shadow is rendered exactly under the source item. By changing the
|
||||||
|
offset properties, the shadow can be positioned relatively to the source
|
||||||
|
item.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, the properties are set to
|
||||||
|
\c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_horizontalOffset1.png
|
||||||
|
\li \image DropShadow_horizontalOffset2.png
|
||||||
|
\li \image DropShadow_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -20 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 20 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 4
|
||||||
|
\li \l radius: 4
|
||||||
|
\li \l radius: 4
|
||||||
|
\row
|
||||||
|
\li \l samples: 8
|
||||||
|
\li \l samples: 8
|
||||||
|
\li \l samples: 8
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the shadow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_spread1.png
|
||||||
|
\li \image DropShadow_spread2.png
|
||||||
|
\li \image DropShadow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image DropShadow_fast1.png
|
||||||
|
\li \image DropShadow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\li \l verticalOffset: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
x: rootItem.horizontalOffset
|
||||||
|
y: rootItem.verticalOffset
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianGlow
|
||||||
|
GaussianGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastGlow
|
||||||
|
FastGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
ShaderEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,496 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype FastBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a fast blur effect to one or more source items.
|
||||||
|
|
||||||
|
FastBlur offers lower blur quality than
|
||||||
|
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur}, but it is faster to
|
||||||
|
render. The FastBlur effect softens the source content by blurring it with
|
||||||
|
algorithm which uses the source content downscaling and bilinear filtering.
|
||||||
|
Use this effect in situations where the source content is rapidly changing
|
||||||
|
and the highest possible blur quality is not
|
||||||
|
needed.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image FastBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet FastBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which affect
|
||||||
|
the blurring of an individual pixel. A larger radius increases the blur
|
||||||
|
effect. FastBlur algorithm may internally reduce the accuracy of the radius in order to
|
||||||
|
provide good rendering performance.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. Visual quality of the blur is reduced when
|
||||||
|
radius exceeds value 64. By default, the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different blur values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image FastBlur_radius1.png
|
||||||
|
\li \image FastBlur_radius2.png
|
||||||
|
\li \image FastBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 32 }
|
||||||
|
\li \b { radius: 64 }
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image FastBlur_transparentBorder1.png
|
||||||
|
\li \image FastBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 64
|
||||||
|
\li \l radius: 64
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
smooth: rootItem.radius > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.radius > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: Math.sqrt(rootItem.radius / 64.0) * 1.2 - 0.2
|
||||||
|
property real weight1
|
||||||
|
property real weight2
|
||||||
|
property real weight3
|
||||||
|
property real weight4
|
||||||
|
property real weight5
|
||||||
|
property real weight6
|
||||||
|
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1.0
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
return 1.0 - v * 2.0
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype GammaAdjust
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the luminance of the source item.
|
||||||
|
|
||||||
|
GammaAdjust is applied to each pixel according to the curve which is
|
||||||
|
pre-defined as a power-law expression, where the property gamma is used as the
|
||||||
|
reciprocal scaling exponent. Refer to the property documentation of \l{GammaAdjust::gamma}{gamma}
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image GammaAdjust_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet GammaAdjust-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item for which the luminance is going to be
|
||||||
|
adjusted.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the change factor for how the luminance of each pixel
|
||||||
|
is altered according to the equation:
|
||||||
|
|
||||||
|
\code
|
||||||
|
luminance = pow(original_luminance, 1.0 / gamma); // The luminance is assumed to be between 0.0 and 1.0
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
Setting the gamma values under 1.0 makes the image darker, the values
|
||||||
|
above 1.0 lighten it.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (darkest) to inf (lightest). By default, the
|
||||||
|
property is set to \c 1.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gamma values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GammaAdjust_gamma1.png
|
||||||
|
\li \image GammaAdjust_gamma2.png
|
||||||
|
\li \image GammaAdjust_gamma3.png
|
||||||
|
\row
|
||||||
|
\li \b { gamma: 0.5 }
|
||||||
|
\li \b { gamma: 1.0 }
|
||||||
|
\li \b { gamma: 2.0 }
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GammaAdjust_gamma1_graph.png
|
||||||
|
\li \image GammaAdjust_gamma2_graph.png
|
||||||
|
\li \image GammaAdjust_gamma3_graph.png
|
||||||
|
\row
|
||||||
|
\li Red curve: default gamma (1.0)
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Yellow curve: effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: pixel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real gamma: 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real gamma: 1.0 / Math.max(rootItem.gamma, 0.0001)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float gamma;
|
||||||
|
void main(void) {
|
||||||
|
highp vec4 originalColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
originalColor.rgb = originalColor.rgb / max(1.0/256.0, originalColor.a);
|
||||||
|
highp vec3 adjustedColor = pow(originalColor.rgb, vec3(gamma));
|
||||||
|
gl_FragColor = vec4(adjustedColor * originalColor.a, originalColor.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype GaussianBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a higher quality blur effect.
|
||||||
|
|
||||||
|
GaussianBlur effect softens the image by blurring it with an algorithm that
|
||||||
|
uses the Gaussian function to calculate the effect. The effect produces
|
||||||
|
higher quality than \l{QtGraphicalEffects1::FastBlur}{FastBlur}, but is
|
||||||
|
slower to render.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image GaussianBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet GaussianBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which
|
||||||
|
affect the blurring of an individual pixel. A larger radius increases
|
||||||
|
the blur effect.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{GaussianBlur::samples}{samples} should be set to sufficiently large
|
||||||
|
to ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_radius1.png
|
||||||
|
\li \image GaussianBlur_radius2.png
|
||||||
|
\li \image GaussianBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 4 }
|
||||||
|
\li \b { radius: 8 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l deviation: 3
|
||||||
|
\li \l deviation: 3
|
||||||
|
\li \l deviation: 3
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property is a parameter to the gaussian function that is used when
|
||||||
|
calculating neighboring pixel weights for the blurring. A larger
|
||||||
|
deviation causes image to appear more blurry, but it also reduces the
|
||||||
|
quality of the blur. A very large deviation value causes the effect to
|
||||||
|
look a bit similar to what, for exmple, a box blur algorithm produces. A
|
||||||
|
too small deviation values makes the effect insignificant for the pixels
|
||||||
|
near the radius.
|
||||||
|
|
||||||
|
\inlineimage GaussianBlur_deviation_graph.png
|
||||||
|
\caption The image above shows the Gaussian function with two different
|
||||||
|
deviation values, yellow (1) and cyan (2.7). The y-axis shows the
|
||||||
|
weights, the x-axis shows the pixel distance.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no deviation) to inf (maximum deviation). By
|
||||||
|
default, devaition is binded to radius. When radius increases, deviation
|
||||||
|
is automatically increased linearly. With the radius value of 8, the
|
||||||
|
deviation default value becomes approximately 2.7034. This value
|
||||||
|
produces a compromise between the blur quality and overall blurriness.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different deviation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_deviation1.png
|
||||||
|
\li \image GaussianBlur_deviation2.png
|
||||||
|
\li \image GaussianBlur_deviation3.png
|
||||||
|
\row
|
||||||
|
\li \b { deviation: 1 }
|
||||||
|
\li \b { deviation: 2 }
|
||||||
|
\li \b { deviation: 4 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real deviation: (radius + 1) / 3.3333
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image GaussianBlur_transparentBorder1.png
|
||||||
|
\li \image GaussianBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l deviation: 2.7
|
||||||
|
\li \l deviation: 2.7
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: verticalBlur
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: verticalBlur
|
||||||
|
x: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
|
||||||
|
source: ShaderEffectSource {
|
||||||
|
id: horizontalBlurSource
|
||||||
|
sourceItem: horizontalBlur
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
deviation: rootItem.deviation
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
|
||||||
|
source: sourceProxy.output
|
||||||
|
deviation: rootItem.deviation
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples / 2.0
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Glow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-glow
|
||||||
|
\brief Generates a blurred and colorized image of the source and places it
|
||||||
|
behind the original, giving impression that the source is glowing.
|
||||||
|
|
||||||
|
By default effect produces a high quality glow image, thus the rendering
|
||||||
|
speed of the effect may not be the highest possible. The rendering speed is
|
||||||
|
reduced especially if the glow edges are heavily softened. For use cases
|
||||||
|
that require faster rendering speed and the highest possible visual quality
|
||||||
|
is not necessary, property \l{Glow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly_black.png
|
||||||
|
\li \image Glow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet Glow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as source
|
||||||
|
for the generated glow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the glow. A larger radius causes the
|
||||||
|
edges of the glow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the \l{Glow::samples}{samples}
|
||||||
|
should be set to sufficiently large to ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_radius1.png
|
||||||
|
\li \image Glow_radius2.png
|
||||||
|
\li \image Glow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l fast property is set to true, this property has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the glow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The values range from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_spread1.png
|
||||||
|
\li \image Glow_spread2.png
|
||||||
|
\li \image Glow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the glow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "white".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_color1.png
|
||||||
|
\li \image Glow_color2.png
|
||||||
|
\li \image Glow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #00ff00 }
|
||||||
|
\li \b { color: #aa00ff00 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\li \l radius: 8
|
||||||
|
\row
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\li \l samples: 16
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\li \l spread: 0.5
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color color: "white"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image Glow_fast1.png
|
||||||
|
\li \image Glow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.3
|
||||||
|
\li \l spread: 0.3
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? fastGlow : gaussianGlow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianGlow
|
||||||
|
GaussianGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastGlow
|
||||||
|
FastGlow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: sourceProxy.output
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
ShaderEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,300 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype HueSaturation
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Alters the source item colors in the HSL color space.
|
||||||
|
|
||||||
|
HueSaturation is similar to the \l{QtGraphicalEffects1::Colorize}{Colorize}
|
||||||
|
effect, but the hue and saturation property values are handled differently.
|
||||||
|
The HueSaturation effect always shifts the hue, saturation, and lightness
|
||||||
|
from the original, instead of setting them.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image HueSaturation_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet HueSaturation-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the hue value which is added to the source hue
|
||||||
|
value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different hue values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_hue1.png
|
||||||
|
\li \image HueSaturation_hue2.png
|
||||||
|
\li \image HueSaturation_hue3.png
|
||||||
|
\row
|
||||||
|
\li \b { hue: -0.3 }
|
||||||
|
\li \b { hue: 0.0 }
|
||||||
|
\li \b { hue: 0.3 }
|
||||||
|
\row
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real hue: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the saturation value value which is added to the
|
||||||
|
source saturation value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different saturation values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_saturation1.png
|
||||||
|
\li \image HueSaturation_saturation2.png
|
||||||
|
\li \image HueSaturation_saturation3.png
|
||||||
|
\row
|
||||||
|
\li \b { saturation: -0.8 }
|
||||||
|
\li \b { saturation: 0.0 }
|
||||||
|
\li \b { saturation: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\li \l lightness: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real saturation: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the lightness value which is added to the source
|
||||||
|
saturation value.
|
||||||
|
|
||||||
|
The value ranges from -1.0 (decrease) to 1.0 (increase). By default, the
|
||||||
|
property is set to \c 0.0 (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different lightness values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image HueSaturation_lightness1.png
|
||||||
|
\li \image HueSaturation_lightness2.png
|
||||||
|
\li \image HueSaturation_lightness3.png
|
||||||
|
\row
|
||||||
|
\li \b { lightness: -0.5 }
|
||||||
|
\li \b { lightness: 0.0 }
|
||||||
|
\li \b { lightness: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\li \l hue: 0
|
||||||
|
\row
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\li \l saturation: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real lightness: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant hsl: Qt.vector3d(rootItem.hue, rootItem.saturation, rootItem.lightness)
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform highp sampler2D source;
|
||||||
|
uniform highp vec3 hsl;
|
||||||
|
|
||||||
|
highp vec3 RGBtoHSL(highp vec3 color) {
|
||||||
|
highp float cmin = min(color.r, min(color.g, color.b));
|
||||||
|
highp float cmax = max(color.r, max(color.g, color.b));
|
||||||
|
highp float h = 0.0;
|
||||||
|
highp float s = 0.0;
|
||||||
|
highp float l = (cmin + cmax) / 2.0;
|
||||||
|
highp float diff = cmax - cmin;
|
||||||
|
|
||||||
|
if (diff > 1.0 / 256.0) {
|
||||||
|
if (l < 0.5)
|
||||||
|
s = diff / (cmin + cmax);
|
||||||
|
else
|
||||||
|
s = diff / (2.0 - (cmin + cmax));
|
||||||
|
|
||||||
|
if (color.r == cmax)
|
||||||
|
h = (color.g - color.b) / diff;
|
||||||
|
else if (color.g == cmax)
|
||||||
|
h = 2.0 + (color.b - color.r) / diff;
|
||||||
|
else
|
||||||
|
h = 4.0 + (color.r - color.g) / diff;
|
||||||
|
|
||||||
|
h /= 6.0;
|
||||||
|
}
|
||||||
|
return vec3(h, s, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 sample = texture2D(source, qt_TexCoord0);
|
||||||
|
sample = vec4(sample.rgb / max(1.0/256.0, sample.a), sample.a);
|
||||||
|
sample.rgb = mix(vec3(dot(sample.rgb, vec3(0.2125, 0.7154, 0.0721))), sample.rgb, 1.0 + hsl.y);
|
||||||
|
sample.xyz = RGBtoHSL(sample.rgb);
|
||||||
|
sample.rgb = HSLtoRGB(vec3(sample.x + hsl.x, sample.y, sample.z));
|
||||||
|
highp float c = step(0.0, hsl.z);
|
||||||
|
sample.rgb = mix(sample.rgb, vec3(c), abs(hsl.z));
|
||||||
|
gl_FragColor = vec4(sample.rgb * sample.a, sample.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,385 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype InnerShadow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-drop-shadow
|
||||||
|
\brief Generates a colorized and blurred shadow inside the
|
||||||
|
source.
|
||||||
|
|
||||||
|
By default the effect produces a high quality shadow image, thus the
|
||||||
|
rendering speed of the shadow might not be the highest possible. The
|
||||||
|
rendering speed is reduced especially if the shadow edges are heavily
|
||||||
|
softened. For use cases that require faster rendering speed and for which
|
||||||
|
the highest possible visual quality is not necessary, property
|
||||||
|
\l{InnerShadow::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image InnerShadow_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet InnerShadow-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be used as the
|
||||||
|
source for the generated shadow.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Radius defines the softness of the shadow. A larger radius causes the
|
||||||
|
edges of the shadow to appear more blurry.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{InnerShadow::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_radius1.png
|
||||||
|
\li \image InnerShadow_radius2.png
|
||||||
|
\li \image InnerShadow_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 6 }
|
||||||
|
\li \b { radius: 12 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when edge
|
||||||
|
softening blur calculation is done. Larger value produces better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{InnerShadow::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the shadow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to 1.0. By default, the property is set to \c
|
||||||
|
0.5.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_spread1.png
|
||||||
|
\li \image InnerShadow_spread2.png
|
||||||
|
\li \image InnerShadow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.3 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the shadow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "black".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_color1.png
|
||||||
|
\li \image InnerShadow_color2.png
|
||||||
|
\li \image InnerShadow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #000000 }
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #ff0000 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color color: "black"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::InnerShadow::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::InnerShadow::verticalOffset
|
||||||
|
|
||||||
|
HorizontalOffset and verticalOffset properties define the offset for the
|
||||||
|
rendered shadow compared to the InnerShadow item position. Often, the
|
||||||
|
InnerShadow item is anchored so that it fills the source element. In
|
||||||
|
this case, if the HorizontalOffset and verticalOffset properties are set
|
||||||
|
to 0, the shadow is rendered fully inside the source item. By changing
|
||||||
|
the offset properties, the shadow can be positioned relatively to the
|
||||||
|
source item.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, the properties are set to
|
||||||
|
\c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_horizontalOffset1.png
|
||||||
|
\li \image InnerShadow_horizontalOffset2.png
|
||||||
|
\li \image InnerShadow_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -20 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 20 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
softness for the effect. Setting this to true enables fast algorithm,
|
||||||
|
setting value to false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image InnerShadow_fast1.png
|
||||||
|
\li \image InnerShadow_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l color: #000000
|
||||||
|
\li \l color: #000000
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? innerShadow : gaussianInnerShadow
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianInnerShadow
|
||||||
|
GaussianInnerShadow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
horizontalOffset: rootItem.horizontalOffset
|
||||||
|
verticalOffset: rootItem.verticalOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: innerShadow
|
||||||
|
FastInnerShadow {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
color: rootItem.color
|
||||||
|
cached: rootItem.cached
|
||||||
|
spread: rootItem.spread
|
||||||
|
horizontalOffset: rootItem.horizontalOffset
|
||||||
|
verticalOffset: rootItem.verticalOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,472 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Add-On Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype LevelAdjust
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-color
|
||||||
|
\brief Adjusts color levels in the RGBA color space.
|
||||||
|
|
||||||
|
This effect adjusts the source item colors separately for each color
|
||||||
|
channel. Source item contrast can be adjusted and color balance altered.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_butterfly.png
|
||||||
|
\li \image LevelAdjust_butterfly.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet LevelAdjust-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that provides the source pixels
|
||||||
|
for the effect.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the change factor for how the value of each pixel
|
||||||
|
color channel is altered according to the equation:
|
||||||
|
|
||||||
|
\code result.rgb = pow(original.rgb, 1.0 / gamma.rgb); \endcode
|
||||||
|
|
||||||
|
Setting the gamma values under QtVector3d(1.0, 1.0, 1.0) makes the image
|
||||||
|
darker, the values above QtVector3d(1.0, 1.0, 1.0) lighten it.
|
||||||
|
|
||||||
|
The value ranges from QtVector3d(0.0, 0.0, 0.0) (darkest) to inf
|
||||||
|
(lightest). By default, the property is set to \c QtVector3d(1.0, 1.0,
|
||||||
|
1.0) (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gamma values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_gamma1.png
|
||||||
|
\li \image LevelAdjust_gamma2.png
|
||||||
|
\li \image LevelAdjust_gamma3.png
|
||||||
|
\row
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 1.0, 1.0) }
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 0.4, 2.0) }
|
||||||
|
\li \b { gamma: Qt.vector3d(1.0, 0.1, 4.0) }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_gamma2_curve.png
|
||||||
|
\li \image LevelAdjust_gamma3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property variant gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the minimum input level for each color channel. It
|
||||||
|
sets the black-point, all pixels having lower value than this property
|
||||||
|
are rendered as black (per color channel). Increasing the value darkens
|
||||||
|
the dark areas.
|
||||||
|
|
||||||
|
The value ranges from "#00000000" to "#ffffffff". By default, the
|
||||||
|
property is set to \c "#00000000" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different minimumInput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_minimumInput1.png
|
||||||
|
\li \image LevelAdjust_minimumInput2.png
|
||||||
|
\li \image LevelAdjust_minimumInput3.png
|
||||||
|
\row
|
||||||
|
\li \b { minimumInput: #00000000 }
|
||||||
|
\li \b { minimumInput: #00000040 }
|
||||||
|
\li \b { minimumInput: #00000070 }
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_minimumInput2_curve.png
|
||||||
|
\li \image LevelAdjust_minimumInput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color minimumInput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum input level for each color channel.
|
||||||
|
It sets the white-point, all pixels having higher value than this
|
||||||
|
property are rendered as white (per color channel).
|
||||||
|
Decreasing the value lightens the light areas.
|
||||||
|
|
||||||
|
The value ranges from "#ffffffff" to "#00000000". By default, the
|
||||||
|
property is set to \c "#ffffffff" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different maximumInput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_maximumInput1.png
|
||||||
|
\li \image LevelAdjust_maximumInput2.png
|
||||||
|
\li \image LevelAdjust_maximumInput3.png
|
||||||
|
\row
|
||||||
|
\li \b { maximumInput: #FFFFFFFF }
|
||||||
|
\li \b { maximumInput: #FFFFFF80 }
|
||||||
|
\li \b { maximumInput: #FFFFFF30 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_maximumInput2_curve.png
|
||||||
|
\li \image LevelAdjust_maximumInput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color maximumInput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the minimum output level for each color channel.
|
||||||
|
Increasing the value lightens the dark areas, reducing the contrast.
|
||||||
|
|
||||||
|
The value ranges from "#00000000" to "#ffffffff". By default, the
|
||||||
|
property is set to \c "#00000000" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different minimumOutput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_minimumOutput1.png
|
||||||
|
\li \image LevelAdjust_minimumOutput2.png
|
||||||
|
\li \image LevelAdjust_minimumOutput3.png
|
||||||
|
\row
|
||||||
|
\li \b { minimumOutput: #00000000 }
|
||||||
|
\li \b { minimumOutput: #00000070 }
|
||||||
|
\li \b { minimumOutput: #000000A0 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\li \l maximumOutput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_minimumOutput2_curve.png
|
||||||
|
\li \image LevelAdjust_minimumOutput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property color minimumOutput: Qt.rgba(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum output level for each color channel.
|
||||||
|
Decreasing the value darkens the light areas, reducing the contrast.
|
||||||
|
|
||||||
|
The value ranges from "#ffffffff" to "#00000000". By default, the
|
||||||
|
property is set to \c "#ffffffff" (no change).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different maximumOutput values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_maximumOutput1.png
|
||||||
|
\li \image LevelAdjust_maximumOutput2.png
|
||||||
|
\li \image LevelAdjust_maximumOutput3.png
|
||||||
|
\row
|
||||||
|
\li \b { maximumOutput: #FFFFFFFF }
|
||||||
|
\li \b { maximumOutput: #FFFFFF80 }
|
||||||
|
\li \b { maximumOutput: #FFFFFF30 }
|
||||||
|
\row
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\li \l minimumInput: #000000
|
||||||
|
\row
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\li \l maximumInput: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\li \l minimumOutput: #000000
|
||||||
|
\row
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\li \l gamma: Qt.vector3d(1.0, 1.0, 1.0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Pixel color channel luminance curves of the above images.
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LevelAdjust_default_curve.png
|
||||||
|
\li \image LevelAdjust_maximumOutput2_curve.png
|
||||||
|
\li \image LevelAdjust_maximumOutput3_curve.png
|
||||||
|
\row
|
||||||
|
\li X-axis: pixel original luminance
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li Y-axis: color channel luminance with effect applied
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color maximumOutput: Qt.rgba(1.0, 1.0, 1.0, 1.0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant minimumInputRGB: Qt.vector3d(rootItem.minimumInput.r, rootItem.minimumInput.g, rootItem.minimumInput.b)
|
||||||
|
property variant maximumInputRGB: Qt.vector3d(rootItem.maximumInput.r, rootItem.maximumInput.g, rootItem.maximumInput.b)
|
||||||
|
property real minimumInputAlpha: rootItem.minimumInput.a
|
||||||
|
property real maximumInputAlpha: rootItem.maximumInput.a
|
||||||
|
property variant minimumOutputRGB: Qt.vector3d(rootItem.minimumOutput.r, rootItem.minimumOutput.g, rootItem.minimumOutput.b)
|
||||||
|
property variant maximumOutputRGB: Qt.vector3d(rootItem.maximumOutput.r, rootItem.maximumOutput.g, rootItem.maximumOutput.b)
|
||||||
|
property real minimumOutputAlpha: rootItem.minimumOutput.a
|
||||||
|
property real maximumOutputAlpha: rootItem.maximumOutput.a
|
||||||
|
property variant gamma: Qt.vector3d(1.0 / Math.max(rootItem.gamma.x, 0.0001), 1.0 / Math.max(rootItem.gamma.y, 0.0001), 1.0 / Math.max(rootItem.gamma.z, 0.0001))
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec3 minimumInputRGB;
|
||||||
|
uniform highp vec3 maximumInputRGB;
|
||||||
|
uniform highp float minimumInputAlpha;
|
||||||
|
uniform highp float maximumInputAlpha;
|
||||||
|
uniform highp vec3 minimumOutputRGB;
|
||||||
|
uniform highp vec3 maximumOutputRGB;
|
||||||
|
uniform highp float minimumOutputAlpha;
|
||||||
|
uniform highp float maximumOutputAlpha;
|
||||||
|
uniform highp vec3 gamma;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec4 textureColor = texture2D(source, qt_TexCoord0.st);
|
||||||
|
highp vec4 color = vec4(textureColor.rgb / max(1.0/256.0, textureColor.a), textureColor.a);
|
||||||
|
|
||||||
|
color.r = linearstep(minimumInputRGB.r, maximumInputRGB.r, color.r);
|
||||||
|
color.g = linearstep(minimumInputRGB.g, maximumInputRGB.g, color.g);
|
||||||
|
color.b = linearstep(minimumInputRGB.b, maximumInputRGB.b, color.b);
|
||||||
|
color.a = linearstep(minimumInputAlpha, maximumInputAlpha, color.a);
|
||||||
|
|
||||||
|
color.rgb = pow(color.rgb, gamma);
|
||||||
|
|
||||||
|
color.r = minimumOutputRGB.r + color.r * (maximumOutputRGB.r - minimumOutputRGB.r);
|
||||||
|
color.g = minimumOutputRGB.g + color.g * (maximumOutputRGB.g - minimumOutputRGB.g);
|
||||||
|
color.b = minimumOutputRGB.b + color.b * (maximumOutputRGB.b - minimumOutputRGB.b);
|
||||||
|
color.a = minimumOutputAlpha + color.a * (maximumOutputAlpha - minimumOutputAlpha);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(color.rgb * color.a, color.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,346 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype LinearGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a linear gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the given start point and end to the given end point.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet LinearGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the starting point where the color at gradient
|
||||||
|
position of 0.0 is rendered. Colors at larger position values are
|
||||||
|
rendered linearly towards the end point. The point is given in pixels
|
||||||
|
and the default value is Qt.point(0, 0). Setting the default values for
|
||||||
|
the start and \l{LinearGradient::end}{end} results in a full height
|
||||||
|
linear gradient on the y-axis.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different start values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_start1.png
|
||||||
|
\li \image LinearGradient_start2.png
|
||||||
|
\li \image LinearGradient_start3.png
|
||||||
|
\row
|
||||||
|
\li \b { start: QPoint(0, 0) }
|
||||||
|
\li \b { start: QPoint(150, 150) }
|
||||||
|
\li \b { start: QPoint(300, 0) }
|
||||||
|
\row
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\li \l end: QPoint(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant start: Qt.point(0, 0)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the ending point where the color at gradient
|
||||||
|
position of 1.0 is rendered. Colors at smaller position values are
|
||||||
|
rendered linearly towards the start point. The point is given in pixels
|
||||||
|
and the default value is Qt.point(0, height). Setting the default values
|
||||||
|
for the \l{LinearGradient::start}{start} and end results in a full
|
||||||
|
height linear gradient on the y-axis.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different end values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_end1.png
|
||||||
|
\li \image LinearGradient_end2.png
|
||||||
|
\li \image LinearGradient_end3.png
|
||||||
|
\row
|
||||||
|
\li \b { end: Qt.point(300, 300) }
|
||||||
|
\li \b { end: Qt.point(150, 150) }
|
||||||
|
\li \b { end: Qt.point(300, 0) }
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property variant end: Qt.point(0, height)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_maskSource1.png
|
||||||
|
\li \image LinearGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: Image { source: images/butterfly.png } }
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\row
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended
|
||||||
|
seamlessly. The colors are specified as a set of GradientStop child
|
||||||
|
items, each of which defines a position on the gradient from 0.0 to 1.0
|
||||||
|
and a color. The position of each GradientStop is defined by the
|
||||||
|
position property, and the color is definded by the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image LinearGradient_gradient1.png
|
||||||
|
\li \image LinearGradient_gradient2.png
|
||||||
|
\li \image LinearGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\li \l start: Qt.point(0, 0)
|
||||||
|
\row
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\li \l end: Qt.point(300, 300)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: gradientSource
|
||||||
|
sourceItem: Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant source: gradientSource
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property variant startPoint: Qt.point(start.x / width, start.y / height)
|
||||||
|
property real dx: end.x - start.x
|
||||||
|
property real dy: end.y - start.y
|
||||||
|
property real l: 1.0 / Math.sqrt(Math.pow(dx / width, 2.0) + Math.pow(dy / height, 2.0))
|
||||||
|
property real angle: Math.atan2(dx, dy)
|
||||||
|
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
uniform highp vec2 startPoint;
|
||||||
|
uniform highp float l;
|
||||||
|
uniform highp vec2 matrixData;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
|
||||||
|
matrixData.x, matrixData.y);
|
||||||
|
|
||||||
|
qt_TexCoord0 = qt_MultiTexCoord0;
|
||||||
|
|
||||||
|
qt_TexCoord1 = qt_MultiTexCoord0 * l;
|
||||||
|
qt_TexCoord1 -= startPoint * l;
|
||||||
|
qt_TexCoord1 *= rot;
|
||||||
|
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: lChanged()
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(source, qt_TexCoord1);
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord1) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,282 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype MaskedBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Applies a blur effect with a varying intesity.
|
||||||
|
|
||||||
|
MaskedBlur effect softens the image by blurring it. The intensity of the
|
||||||
|
blur can be controlled for each pixel using maskSource so that some parts of
|
||||||
|
the source are blurred more than others. By default the effect produces a
|
||||||
|
high quality result, thus the rendering speed may not be the highest
|
||||||
|
possible. The rendering speed is reduced especially if the
|
||||||
|
\l{MaskedBlur::samples}{samples} is large. For use cases that require faster
|
||||||
|
rendering speed and the highest possible visual quality is not necessary,
|
||||||
|
property \l{MaskedBlur::fast}{fast} can be set to true.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image MaskedBlur_mask.png
|
||||||
|
\li \image MaskedBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet MaskedBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is controlling the final intensity
|
||||||
|
of the blur. The pixel alpha channel value from maskSource defines the
|
||||||
|
actual blur radius that is going to be used for blurring the
|
||||||
|
corresponding source pixel.
|
||||||
|
|
||||||
|
Opaque maskSource pixels produce blur with specified
|
||||||
|
\l{MaskedBlur::radius}{radius}, while transparent pixels suppress the
|
||||||
|
blur completely. Semitransparent maskSource pixels produce blur with a
|
||||||
|
radius that is interpolated according to the pixel transparency level.
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of the neighboring pixels which
|
||||||
|
affect the blurring of an individual pixel. A larger radius increases
|
||||||
|
the blur effect.
|
||||||
|
|
||||||
|
Depending on the radius value, value of the
|
||||||
|
\l{MaskedBlur::samples}{samples} should be set to sufficiently large to
|
||||||
|
ensure the visual quality.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no blur) to inf. By default, the property is
|
||||||
|
set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_radius1.png
|
||||||
|
\li \image MaskedBlur_radius2.png
|
||||||
|
\li \image MaskedBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 0 }
|
||||||
|
\li \b { radius: 8 }
|
||||||
|
\li \b { radius: 16 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\row
|
||||||
|
\li \l fast: false
|
||||||
|
\li \l fast: false
|
||||||
|
\li \l fast: false
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
Ideally, this value should be twice as large as the highest required
|
||||||
|
radius value, for example, if the radius is animated between 0.0 and
|
||||||
|
4.0, samples should be set to 8.
|
||||||
|
|
||||||
|
The value ranges from 0 to 32. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
When \l{MaskedBlur::fast}{fast} property is set to true, this property
|
||||||
|
has no effect.
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance. Every time the source or effect
|
||||||
|
properties are changed, the pixels in the cache must be updated. Memory
|
||||||
|
consumption is increased, because an extra buffer of memory is required
|
||||||
|
for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property selects the blurring algorithm that is used to produce the
|
||||||
|
blur. Setting this to true enables fast algorithm, setting value to
|
||||||
|
false produces higher quality result.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different fast values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_fast1.png
|
||||||
|
\li \image MaskedBlur_fast2.png
|
||||||
|
\row
|
||||||
|
\li \b { fast: false }
|
||||||
|
\li \b { fast: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 16
|
||||||
|
\li \l radius: 16
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\li \l transparentBorder: false
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool fast: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image MaskedBlur_transparentBorder1.png
|
||||||
|
\li \image MaskedBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l radius: 64
|
||||||
|
\li \l radius: 64
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l fast: true
|
||||||
|
\li \l fast: true
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loaderItem
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: rootItem.fast ? fastBlur : gaussianBlur
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: gaussianBlur
|
||||||
|
GaussianMaskedBlur {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: rootItem.source
|
||||||
|
maskSource: rootItem.maskSource
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.samples * 0.5
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
cached: rootItem.cached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: fastBlur
|
||||||
|
FastMaskedBlur {
|
||||||
|
anchors.fill: parent
|
||||||
|
source:rootItem. source
|
||||||
|
maskSource: rootItem.maskSource
|
||||||
|
blur: Math.pow(rootItem.radius / 64.0, 0.4)
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
cached: rootItem.cached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype OpacityMask
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-mask
|
||||||
|
\brief Masks the source item with another item.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image OpacityMask_mask.png
|
||||||
|
\li \image OpacityMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet OpacityMask-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be masked.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the mask. The
|
||||||
|
mask item gets rendered into an intermediate pixel buffer and the alpha
|
||||||
|
values from the result are used to determine the source item's pixels
|
||||||
|
visibility in the display.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Original
|
||||||
|
\li Mask
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image OpacityMask_mask.png
|
||||||
|
\li \image OpacityMask_bug.png
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting maskSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
void main(void) {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord0.st) * (texture2D(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RadialBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies directional blur in a circular direction around the items
|
||||||
|
center point.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
rotating to the direction of the blur.
|
||||||
|
|
||||||
|
Other available motionblur effects are
|
||||||
|
\l{QtGraphicalEffects1::ZoomBlur}{ZoomBlur} and
|
||||||
|
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image RadialBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example Usage
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RadialBlur-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the direction for the blur and at the same time
|
||||||
|
the level of blurring. The larger the angle, the more the result becomes
|
||||||
|
blurred. The quality of the blur depends on
|
||||||
|
\l{RadialBlur::samples}{samples} property. If angle value is large, more
|
||||||
|
samples are needed to keep the visual quality at high level.
|
||||||
|
|
||||||
|
Allowed values are between 0.0 and 360.0. By default the property is set
|
||||||
|
to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialBlur_angle1.png
|
||||||
|
\li \image RadialBlur_angle2.png
|
||||||
|
\li \image RadialBlur_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0.0 }
|
||||||
|
\li \b { angle: 15.0 }
|
||||||
|
\li \b { angle: 30.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::RadialBlur::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::RadialBlur::verticalOffset
|
||||||
|
|
||||||
|
These properties define the offset in pixels for the perceived center
|
||||||
|
point of the rotation.
|
||||||
|
|
||||||
|
Allowed values are between -inf and inf.
|
||||||
|
By default these properties are set to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialBlur_horizontalOffset1.png
|
||||||
|
\li \image RadialBlur_horizontalOffset2.png
|
||||||
|
\li \image RadialBlur_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: 75.0 }
|
||||||
|
\li \b { horizontalOffset: 0.0 }
|
||||||
|
\li \b { horizontalOffset: -75.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l angle: 20
|
||||||
|
\li \l angle: 20
|
||||||
|
\li \l angle: 20
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: shaderItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / parent.width, 0.5 + rootItem.verticalOffset / parent.height)
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder && rootItem.samples > 1
|
||||||
|
property int samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property real angleSin: Math.sin(rootItem.angle/2 * Math.PI/180)
|
||||||
|
property real angleCos: Math.cos(rootItem.angle/2 * Math.PI/180)
|
||||||
|
property real angleSinStep: Math.sin(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
|
||||||
|
property real angleCosStep: Math.cos(-rootItem.angle * Math.PI/180 / Math.max(1.0, rootItem.samples - 1))
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(0.5 * parent.height, 0.5 * parent.width) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
|
||||||
|
property real w: parent.width
|
||||||
|
property real h: parent.height
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1 : 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + expandPixels.width * 2.0 + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + expandPixels.height * 2.0 + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float angleSin;
|
||||||
|
uniform highp float angleCos;
|
||||||
|
uniform highp float angleSinStep;
|
||||||
|
uniform highp float angleCosStep;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
uniform highp float w;
|
||||||
|
uniform highp float h;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp mat2 m;
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
highp vec2 dir = vec2(texCoord.s * w - w * center.x, texCoord.t * h - h * center.y);
|
||||||
|
m[0] = vec2(angleCos, -angleSin);
|
||||||
|
m[1] = vec2(angleSin, angleCos);
|
||||||
|
dir *= m;
|
||||||
|
|
||||||
|
m[0] = vec2(angleCosStep, -angleSinStep);
|
||||||
|
m[1] = vec2(angleSinStep, angleCosStep);
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, center + dir * delta); dir *= m;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,439 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RadialGradient
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-gradient
|
||||||
|
\brief Draws a radial gradient.
|
||||||
|
|
||||||
|
A gradient is defined by two or more colors, which are blended seamlessly.
|
||||||
|
The colors start from the middle of the item and end at the borders.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RadialGradient-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The HorizontalOffset and verticalOffset properties define the offset in
|
||||||
|
pixels for the center point of the gradient compared to the item center.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default, these properties are set
|
||||||
|
to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_horizontalOffset1.png
|
||||||
|
\li \image RadialGradient_horizontalOffset2.png
|
||||||
|
\li \image RadialGradient_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: -150 }
|
||||||
|
\li \b { horizontalOffset: 0 }
|
||||||
|
\li \b { horizontalOffset: 150 }
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The HorizontalRadius and verticalRadius properties define the shape and
|
||||||
|
size of the radial gradient. If the radiuses are equal, the shape of the
|
||||||
|
gradient is a circle. If the horizontal and vertical radiuses differ,
|
||||||
|
the shape is elliptical. The radiuses are given in pixels.
|
||||||
|
|
||||||
|
The value ranges from -inf to inf. By default, horizontalRadius is bound
|
||||||
|
to width and verticalRadius is bound to height.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_horizontalRadius1.png
|
||||||
|
\li \image RadialGradient_horizontalRadius2.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalRadius: 300 }
|
||||||
|
\li \b { horizontalRadius: 100 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\row
|
||||||
|
\li \l gradient: QQuickGradient(0xa05fb10)
|
||||||
|
\li \l gradient: QQuickGradient(0xa05fb10)
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real horizontalRadius: width
|
||||||
|
property real verticalRadius: height
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the rotation of the gradient around its center
|
||||||
|
point. The rotation is only visible when the
|
||||||
|
\l{RadialGradient::horizontalRadius}{horizontalRadius} and
|
||||||
|
\l{RadialGradient::verticalRadius}{verticalRadius} properties are not
|
||||||
|
equal. The angle is given in degrees and the default value is \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different angle values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_angle1.png
|
||||||
|
\li \image RadialGradient_angle2.png
|
||||||
|
\li \image RadialGradient_angle3.png
|
||||||
|
\row
|
||||||
|
\li \b { angle: 0 }
|
||||||
|
\li \b { angle: 45 }
|
||||||
|
\li \b { angle: 90 }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\li \l horizontalRadius: 100
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real angle: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be filled with gradient.
|
||||||
|
Source item gets rendered into an intermediate pixel buffer and the
|
||||||
|
alpha values from the result are used to determine the gradient's pixels
|
||||||
|
visibility in the display. The default value for source is undefined and
|
||||||
|
in that case whole effect area is filled with gradient.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different source values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_maskSource1.png
|
||||||
|
\li \image RadialGradient_maskSource2.png
|
||||||
|
\row
|
||||||
|
\li \b { source: undefined }
|
||||||
|
\li \b { source: Image { source: images/butterfly.png } }
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A gradient is defined by two or more colors, which are blended
|
||||||
|
seamlessly. The colors are specified as a set of GradientStop child
|
||||||
|
items, each of which defines a position on the gradient from 0.0 to 1.0
|
||||||
|
and a color. The position of each GradientStop is defined by setting the
|
||||||
|
position property. The color is defined by setting the color property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different gradient values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RadialGradient_gradient1.png
|
||||||
|
\li \image RadialGradient_gradient2.png
|
||||||
|
\li \image RadialGradient_gradient3.png
|
||||||
|
\row
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:} \code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
GradientStop { position: 0.5
|
||||||
|
color: "#000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#F0F0F0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\li \b {gradient:}
|
||||||
|
\code
|
||||||
|
Gradient {
|
||||||
|
GradientStop { position: 0.0
|
||||||
|
color: "#00000000"
|
||||||
|
}
|
||||||
|
GradientStop { position: 1.0
|
||||||
|
color: "#FF000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\li \l horizontalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\li \l verticalRadius: 300
|
||||||
|
\row
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\li \l angle: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property Gradient gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "white" }
|
||||||
|
GradientStop { position: 1.0; color: "black" }
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: gradientSource
|
||||||
|
sourceItem: Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 256
|
||||||
|
gradient: rootItem.gradient
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant gradientImage: gradientSource
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
|
||||||
|
property real horizontalRatio: rootItem.horizontalRadius > 0 ? width / (2 * rootItem.horizontalRadius) : width * 16384
|
||||||
|
property real verticalRatio: rootItem.verticalRadius > 0 ? height / (2 * rootItem.verticalRadius) : height * 16384
|
||||||
|
property real angle: -rootItem.angle / 360 * 2 * Math.PI
|
||||||
|
property variant matrixData: Qt.point(Math.sin(angle), Math.cos(angle))
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp vec2 matrixData;
|
||||||
|
uniform highp float horizontalRatio;
|
||||||
|
uniform highp float verticalRatio;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 ratio = vec2(horizontalRatio, verticalRatio);
|
||||||
|
|
||||||
|
// Rotation matrix
|
||||||
|
highp mat2 rot = mat2(matrixData.y, -matrixData.x,
|
||||||
|
matrixData.x, matrixData.y);
|
||||||
|
|
||||||
|
qt_TexCoord0 = qt_MultiTexCoord0;
|
||||||
|
|
||||||
|
qt_TexCoord1 = qt_MultiTexCoord0;
|
||||||
|
qt_TexCoord1 -= center;
|
||||||
|
qt_TexCoord1 *= rot;
|
||||||
|
qt_TexCoord1 += center;
|
||||||
|
qt_TexCoord1 *= ratio;
|
||||||
|
|
||||||
|
centerPoint = center * ratio;
|
||||||
|
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: maskSource == undefined ? noMaskShader : maskShader
|
||||||
|
|
||||||
|
onFragmentShaderChanged: horizontalRatioChanged()
|
||||||
|
|
||||||
|
property string maskShader: "
|
||||||
|
uniform lowp sampler2D gradientImage;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
|
||||||
|
lowp float maskAlpha = texture2D(maskSource, qt_TexCoord0).a;
|
||||||
|
gl_FragColor = gradientColor * maskAlpha * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string noMaskShader: "
|
||||||
|
uniform lowp sampler2D gradientImage;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 centerPoint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 gradientColor = texture2D(gradientImage, vec2(0.0, 2.0 * distance(qt_TexCoord1, centerPoint)));
|
||||||
|
gl_FragColor = gradientColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RectangularGlow
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-glow
|
||||||
|
\brief Generates a blurred and colorized rectangle, which gives
|
||||||
|
the impression that the source is glowing.
|
||||||
|
|
||||||
|
This effect is intended to have good performance. The shape of the glow is
|
||||||
|
limited to a rectangle with a custom corner radius. For situations where
|
||||||
|
custom shapes are required, consider \l {QtGraphicalEffects1::Glow} {Glow}
|
||||||
|
effect.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_applied.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RectangularGlow-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many pixels outside the item area are reached
|
||||||
|
by the glow.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no glow) to inf (infinite glow). By default,
|
||||||
|
the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different glowRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_glowRadius1.png
|
||||||
|
\li \image RectangularGlow_glowRadius2.png
|
||||||
|
\li \image RectangularGlow_glowRadius3.png
|
||||||
|
\row
|
||||||
|
\li \b { glowRadius: 10 }
|
||||||
|
\li \b { glowRadius: 20 }
|
||||||
|
\li \b { glowRadius: 40 }
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real glowRadius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how large part of the glow color is strenghtened
|
||||||
|
near the source edges.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (no strenght increase) to 1.0 (maximum
|
||||||
|
strenght increase). By default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_spread1.png
|
||||||
|
\li \image RectangularGlow_spread2.png
|
||||||
|
\li \image RectangularGlow_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.5 }
|
||||||
|
\li \b { spread: 1.0 }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the RGBA color value which is used for the glow.
|
||||||
|
|
||||||
|
By default, the property is set to \c "white".
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different color values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_color1.png
|
||||||
|
\li \image RectangularGlow_color2.png
|
||||||
|
\li \image RectangularGlow_color3.png
|
||||||
|
\row
|
||||||
|
\li \b { color: #ffffff }
|
||||||
|
\li \b { color: #55ff55 }
|
||||||
|
\li \b { color: #5555ff }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\li \l cornerRadius: 25
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property color color: "white"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the corner radius that is used to draw a glow with
|
||||||
|
rounded corners.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to half of the effective width or height of
|
||||||
|
the glow, whichever is smaller. This can be calculated with: \c{
|
||||||
|
min(width, height) / 2.0 + glowRadius}
|
||||||
|
|
||||||
|
By default, the property is bound to glowRadius property. The glow
|
||||||
|
behaves as if the rectangle was blurred when adjusting the glowRadius
|
||||||
|
property.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different cornerRadius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RectangularGlow_cornerRadius1.png
|
||||||
|
\li \image RectangularGlow_cornerRadius2.png
|
||||||
|
\li \image RectangularGlow_cornerRadius3.png
|
||||||
|
\row
|
||||||
|
\li \b { cornerRadius: 0 }
|
||||||
|
\li \b { cornerRadius: 25 }
|
||||||
|
\li \b { cornerRadius: 50 }
|
||||||
|
\row
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\li \l glowRadius: 20
|
||||||
|
\row
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\li \l spread: 0
|
||||||
|
\row
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\li \l color: #ffffff
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real cornerRadius: glowRadius
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
|
||||||
|
x: (parent.width - width) / 2.0
|
||||||
|
y: (parent.height - height) / 2.0
|
||||||
|
width: parent.width + rootItem.glowRadius * 2 + cornerRadius * 2
|
||||||
|
height: parent.height + rootItem.glowRadius * 2 + cornerRadius * 2
|
||||||
|
|
||||||
|
function clampedCornerRadius() {
|
||||||
|
var maxCornerRadius = Math.min(rootItem.width, rootItem.height) / 2 + glowRadius;
|
||||||
|
return Math.max(0, Math.min(rootItem.cornerRadius, maxCornerRadius))
|
||||||
|
}
|
||||||
|
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real inverseSpread: 1.0 - rootItem.spread
|
||||||
|
property real relativeSizeX: ((inverseSpread * inverseSpread) * rootItem.glowRadius + cornerRadius * 2.0) / width
|
||||||
|
property real relativeSizeY: relativeSizeX * (width / height)
|
||||||
|
property real spread: rootItem.spread / 2.0
|
||||||
|
property real cornerRadius: clampedCornerRadius()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform mediump float relativeSizeX;
|
||||||
|
uniform mediump float relativeSizeY;
|
||||||
|
uniform mediump float spread;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp float alpha =
|
||||||
|
smoothstep(0.0, relativeSizeX, 0.5 - abs(0.5 - qt_TexCoord0.x)) *
|
||||||
|
smoothstep(0.0, relativeSizeY, 0.5 - abs(0.5 - qt_TexCoord0.y));
|
||||||
|
|
||||||
|
highp float spreadMultiplier = linearstep(spread, 1.0 - spread, alpha);
|
||||||
|
gl_FragColor = color * qt_Opacity * spreadMultiplier * spreadMultiplier;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,350 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype RecursiveBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-blur
|
||||||
|
\brief Blurs repeatedly, providing a strong blur effect.
|
||||||
|
|
||||||
|
The RecursiveBlur effect softens the image by blurring it with an algorithm
|
||||||
|
that uses a recursive feedback loop to blur the source multiple times. The
|
||||||
|
effect may give more blurry results than
|
||||||
|
\l{QtGraphicalEffects1::GaussianBlur}{GaussianBlur} or
|
||||||
|
\l{QtGraphicalEffects1::FastBlur}{FastBlur}, but the result is produced
|
||||||
|
asynchronously and takes more time.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image RecursiveBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet RecursiveBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the distance of neighboring pixels which influence
|
||||||
|
the blurring of individual pixels. A larger radius provides better
|
||||||
|
quality, but is slower to render.
|
||||||
|
|
||||||
|
\b Note: The radius value in this effect is not intended to be changed
|
||||||
|
or animated frequently. The correct way to use it is to set the correct
|
||||||
|
value and keep it unchanged for the whole duration of the iterative blur
|
||||||
|
sequence.
|
||||||
|
|
||||||
|
The value ranges from (no blur) to 16.0 (maximum blur step). By default,
|
||||||
|
the property is set to \c 0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different radius values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_radius1.png
|
||||||
|
\li \image RecursiveBlur_radius2.png
|
||||||
|
\li \image RecursiveBlur_radius3.png
|
||||||
|
\row
|
||||||
|
\li \b { radius: 2.5 }
|
||||||
|
\li \b { radius: 4.5 }
|
||||||
|
\li \b { radius: 7.5 }
|
||||||
|
\row
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real radius: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different transparentBorder values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_transparentBorder1.png
|
||||||
|
\li \image RecursiveBlur_transparentBorder2.png
|
||||||
|
\row
|
||||||
|
\li \b { transparentBorder: false }
|
||||||
|
\li \b { transparentBorder: true }
|
||||||
|
\row
|
||||||
|
\li \l loops: 20
|
||||||
|
\li \l loops: 20
|
||||||
|
\row
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the amount of blur iterations that are going to be
|
||||||
|
performed for the source. When the property changes, the iterative
|
||||||
|
blurring process starts. If the value is decreased or if the value
|
||||||
|
changes from zero to non-zero, a snapshot is taken from the source. The
|
||||||
|
snapshot is used as a starting point for the process.
|
||||||
|
|
||||||
|
The iteration loop tries to run as fast as possible. The speed might be
|
||||||
|
limited by the VSYNC or the time needed for one blur step, or both.
|
||||||
|
Sometimes it may be desirable to perform the blurring with a slower
|
||||||
|
pace. In that case, it may be convenient to control the property with
|
||||||
|
Animation which increases the value.
|
||||||
|
|
||||||
|
The value ranges from 0 to inf. By default, the property is set to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different loops values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image RecursiveBlur_loops1.png
|
||||||
|
\li \image RecursiveBlur_loops2.png
|
||||||
|
\li \image RecursiveBlur_loops3.png
|
||||||
|
\row
|
||||||
|
\li \b { loops: 4 }
|
||||||
|
\li \b { loops: 20 }
|
||||||
|
\li \b { loops: 70 }
|
||||||
|
\row
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\li \l radius: 7.5
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int loops: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds the progress of asynchronous source blurring
|
||||||
|
process, from 0.0 (nothing blurred) to 1.0 (finished).
|
||||||
|
*/
|
||||||
|
property real progress: loops > 0.0 ? Math.min(1.0, recursionTimer.counter / loops) : 0.0
|
||||||
|
|
||||||
|
onLoopsChanged: recursiveSource.scheduleUpdate()
|
||||||
|
onSourceChanged: recursionTimer.reset()
|
||||||
|
onRadiusChanged: recursionTimer.reset()
|
||||||
|
onTransparentBorderChanged: recursionTimer.reset()
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2, parent.height + 2) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
smooth: true
|
||||||
|
visible: rootItem.cached
|
||||||
|
hideSource: visible
|
||||||
|
live: true
|
||||||
|
sourceItem: inputItem.visible ? inputItem : verticalBlur
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: recursionTimer
|
||||||
|
property int counter: 0
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
counter = 0
|
||||||
|
recursiveSource.scheduleUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextFrame() {
|
||||||
|
if (loops < counter)
|
||||||
|
recursionTimer.counter = 0
|
||||||
|
|
||||||
|
if (counter > 0)
|
||||||
|
recursiveSource.sourceItem = verticalBlur
|
||||||
|
else
|
||||||
|
recursiveSource.sourceItem = inputItem
|
||||||
|
|
||||||
|
if (counter < loops) {
|
||||||
|
recursiveSource.scheduleUpdate()
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: inputItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real expandX: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.width : 0.0
|
||||||
|
property real expandY: rootItem.transparentBorder ? (horizontalBlur.maximumRadius) / horizontalBlur.height : 0.0
|
||||||
|
|
||||||
|
anchors.fill: verticalBlur
|
||||||
|
visible: !verticalBlur.visible
|
||||||
|
|
||||||
|
vertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float expandX;
|
||||||
|
uniform highp float expandY;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
mediump vec2 texCoord = qt_MultiTexCoord0;
|
||||||
|
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
|
||||||
|
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
|
||||||
|
qt_TexCoord0 = texCoord;
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: recursiveSource
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
hideSource: false
|
||||||
|
live: false
|
||||||
|
sourceItem: inputItem
|
||||||
|
recursive: true
|
||||||
|
onSourceItemChanged: scheduleUpdate()
|
||||||
|
onScheduledUpdateCompleted: recursionTimer.nextFrame()
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: verticalBlur
|
||||||
|
x: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
|
||||||
|
y: rootItem.transparentBorder ? -horizontalBlur.maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width + 2
|
||||||
|
height: horizontalBlur.height + 2
|
||||||
|
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
|
||||||
|
source: ShaderEffectSource {
|
||||||
|
sourceItem: horizontalBlur
|
||||||
|
hideSource: true
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
deviation: (radius + 1) / 2.3333
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: Math.ceil(rootItem.radius)
|
||||||
|
transparentBorder: false
|
||||||
|
visible: loops > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: rootItem.transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: rootItem.transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
|
||||||
|
source: recursiveSource
|
||||||
|
deviation: (radius + 1) / 2.3333
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: Math.ceil(rootItem.radius)
|
||||||
|
transparentBorder: false
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ThresholdMask
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-mask
|
||||||
|
\brief Masks the source item with another item and applies a threshold
|
||||||
|
value.
|
||||||
|
|
||||||
|
The masking behavior can be controlled with the \l threshold value for the
|
||||||
|
mask pixels.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li MaskSource
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ThresholdMask_mask.png
|
||||||
|
\li \image ThresholdMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ThresholdMask-example.qml example
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be masked.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the item that is going to be used as the mask.
|
||||||
|
Mask item gets rendered into an intermediate pixel buffer and the alpha
|
||||||
|
values from the result are used to determine the source item's pixels
|
||||||
|
visibility in the display.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Original
|
||||||
|
\li Mask
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ThresholdMask_mask.png
|
||||||
|
\li \image ThresholdMask_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting maskSource to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines a threshold value for the mask pixels. The mask
|
||||||
|
pixels that have an alpha value below this property are used to
|
||||||
|
completely mask away the corresponding pixels from the source item. The
|
||||||
|
mask pixels that have a higher alpha value are used to alphablend the
|
||||||
|
source item to the display.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (alpha value 0) to 1.0 (alpha value 255). By
|
||||||
|
default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different threshold values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ThresholdMask_threshold1.png
|
||||||
|
\li \image ThresholdMask_threshold2.png
|
||||||
|
\li \image ThresholdMask_threshold3.png
|
||||||
|
\row
|
||||||
|
\li \b { threshold: 0.0 }
|
||||||
|
\li \b { threshold: 0.5 }
|
||||||
|
\li \b { threshold: 0.7 }
|
||||||
|
\row
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\li \l spread: 0.2
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real threshold: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the smoothness of the mask edges near the
|
||||||
|
\l{ThresholdMask::threshold}{threshold} alpha value. Setting spread to
|
||||||
|
0.0 uses mask normally with the specified threshold. Setting higher
|
||||||
|
spread values softens the transition from the transparent mask pixels
|
||||||
|
towards opaque mask pixels by adding interpolated values between them.
|
||||||
|
|
||||||
|
The value ranges from 0.0 (sharp mask edge) to 1.0 (smooth mask edge).
|
||||||
|
By default, the property is set to \c 0.0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different spread values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ThresholdMask_spread1.png
|
||||||
|
\li \image ThresholdMask_spread2.png
|
||||||
|
\li \image ThresholdMask_spread3.png
|
||||||
|
\row
|
||||||
|
\li \b { spread: 0.0 }
|
||||||
|
\li \b { spread: 0.2 }
|
||||||
|
\li \b { spread: 0.8 }
|
||||||
|
\row
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\li \l threshold: 0.4
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
property real threshold: rootItem.threshold
|
||||||
|
property real spread: rootItem.spread
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp sampler2D maskSource;
|
||||||
|
uniform highp float threshold;
|
||||||
|
uniform highp float spread;
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 colorFragment = texture2D(source, qt_TexCoord0.st);
|
||||||
|
lowp vec4 maskFragment = texture2D(maskSource, qt_TexCoord0.st);
|
||||||
|
gl_FragColor = colorFragment * smoothstep(threshold * (1.0 + spread) - spread, threshold * (1.0 + spread), maskFragment.a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "private"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ZoomBlur
|
||||||
|
\inqmlmodule QtGraphicalEffects 1.0
|
||||||
|
\since QtGraphicalEffects 1.0
|
||||||
|
\inherits QtQuick2::Item
|
||||||
|
\ingroup qtgraphicaleffects-motion-blur
|
||||||
|
\brief Applies directional blur effect towards source items center point.
|
||||||
|
|
||||||
|
Effect creates perceived impression that the source item appears to be
|
||||||
|
moving towards the center point in Z-direction or that the camera appears
|
||||||
|
to be zooming rapidly. Other available motion blur effects are
|
||||||
|
\l{QtGraphicalEffects1::DirectionalBlur}{DirectionalBlur}
|
||||||
|
and \l{QtGraphicalEffects1::RadialBlur}{RadialBlur}.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Source
|
||||||
|
\li Effect applied
|
||||||
|
\row
|
||||||
|
\li \image Original_bug.png
|
||||||
|
\li \image ZoomBlur_bug.png
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
\section1 Example
|
||||||
|
|
||||||
|
The following example shows how to apply the effect.
|
||||||
|
\snippet ZoomBlur-example.qml example
|
||||||
|
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the source item that is going to be blurred.
|
||||||
|
|
||||||
|
\note It is not supported to let the effect include itself, for
|
||||||
|
instance by setting source to the effect's parent.
|
||||||
|
*/
|
||||||
|
property variant source
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the maximum perceived amount of movement for each
|
||||||
|
pixel. The amount is smaller near the center and reaches the specified
|
||||||
|
value at the edges.
|
||||||
|
|
||||||
|
The quality of the blur depends on \l{ZoomBlur::samples}{samples}
|
||||||
|
property. If length value is large, more samples are needed to keep the
|
||||||
|
visual quality at high level.
|
||||||
|
|
||||||
|
The value ranges from 0.0 to inf. By default the property is set to \c
|
||||||
|
0.0 (no blur).
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different length values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ZoomBlur_length1.png
|
||||||
|
\li \image ZoomBlur_length2.png
|
||||||
|
\li \image ZoomBlur_length3.png
|
||||||
|
\row
|
||||||
|
\li \b { length: 0.0 }
|
||||||
|
\li \b { length: 32.0 }
|
||||||
|
\li \b { length: 48.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\li \l horizontalOffset: 0
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
*/
|
||||||
|
property real length: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines how many samples are taken per pixel when blur
|
||||||
|
calculation is done. Larger value produces better quality, but is slower
|
||||||
|
to render.
|
||||||
|
|
||||||
|
This property is not intended to be animated. Changing this property may
|
||||||
|
cause the underlying OpenGL shaders to be recompiled.
|
||||||
|
|
||||||
|
Allowed values are between 0 and inf (practical maximum depends on GPU).
|
||||||
|
By default the property is set to \c 0 (no samples).
|
||||||
|
|
||||||
|
*/
|
||||||
|
property int samples: 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ZoomBlur::horizontalOffset
|
||||||
|
\qmlproperty real QtGraphicalEffects1::ZoomBlur::verticalOffset
|
||||||
|
|
||||||
|
These properties define an offset in pixels for the blur direction
|
||||||
|
center point.
|
||||||
|
|
||||||
|
The values range from -inf to inf. By default these properties are set
|
||||||
|
to \c 0.
|
||||||
|
|
||||||
|
\table
|
||||||
|
\header
|
||||||
|
\li Output examples with different horizontalOffset values
|
||||||
|
\li
|
||||||
|
\li
|
||||||
|
\row
|
||||||
|
\li \image ZoomBlur_horizontalOffset1.png
|
||||||
|
\li \image ZoomBlur_horizontalOffset2.png
|
||||||
|
\li \image ZoomBlur_horizontalOffset3.png
|
||||||
|
\row
|
||||||
|
\li \b { horizontalOffset: 100.0 }
|
||||||
|
\li \b { horizontalOffset: 0.0 }
|
||||||
|
\li \b { horizontalOffset: -100.0 }
|
||||||
|
\row
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\li \l samples: 24
|
||||||
|
\row
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\li \l length: 32
|
||||||
|
\row
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\li \l verticalOffset: 0
|
||||||
|
\endtable
|
||||||
|
*/
|
||||||
|
property real horizontalOffset: 0.0
|
||||||
|
property real verticalOffset: 0.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property defines the blur behavior near the edges of the item,
|
||||||
|
where the pixel blurring is affected by the pixels outside the source
|
||||||
|
edges.
|
||||||
|
|
||||||
|
If the property is set to \c true, the pixels outside the source are
|
||||||
|
interpreted to be transparent, which is similar to OpenGL
|
||||||
|
clamp-to-border extension. The blur is expanded slightly outside the
|
||||||
|
effect item area.
|
||||||
|
|
||||||
|
If the property is set to \c false, the pixels outside the source are
|
||||||
|
interpreted to contain the same color as the pixels at the edge of the
|
||||||
|
item, which is similar to OpenGL clamp-to-edge behavior. The blur does
|
||||||
|
not expand outside the effect item area.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
|
||||||
|
*/
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property allows the effect output pixels to be cached in order to
|
||||||
|
improve the rendering performance.
|
||||||
|
|
||||||
|
Every time the source or effect properties are changed, the pixels in
|
||||||
|
the cache must be updated. Memory consumption is increased, because an
|
||||||
|
extra buffer of memory is required for storing the effect output.
|
||||||
|
|
||||||
|
It is recommended to disable the cache when the source or the effect
|
||||||
|
properties are animated.
|
||||||
|
|
||||||
|
By default, the property is set to \c false.
|
||||||
|
*/
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property variant center: Qt.point(0.5 + rootItem.horizontalOffset / width, 0.5 + rootItem.verticalOffset / height)
|
||||||
|
property real len: rootItem.length
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real samples: rootItem.samples
|
||||||
|
property real weight: 1.0 / Math.max(1.0, rootItem.samples)
|
||||||
|
property variant expandPixels: transparentBorder ? Qt.size(rootItem.samples, rootItem.samples) : Qt.size(0,0)
|
||||||
|
property variant expand: transparentBorder ? Qt.size(expandPixels.width / width, expandPixels.height / height) : Qt.size(0,0)
|
||||||
|
property variant delta: Qt.size(1.0 / rootItem.width, 1.0 / rootItem.height)
|
||||||
|
|
||||||
|
x: transparentBorder ? -expandPixels.width - 1 : 0
|
||||||
|
y: transparentBorder ? -expandPixels.height - 1 : 0
|
||||||
|
width: transparentBorder ? parent.width + 2.0 * expandPixels.width + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2.0 * expandPixels.height + 2 : parent.height
|
||||||
|
|
||||||
|
property string fragmentShaderSkeleton: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp float len;
|
||||||
|
uniform highp float weight;
|
||||||
|
uniform highp float samples;
|
||||||
|
uniform highp vec2 center;
|
||||||
|
uniform highp vec2 expand;
|
||||||
|
uniform highp vec2 delta;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
mediump vec2 centerCoord = center;
|
||||||
|
|
||||||
|
PLACEHOLDER_EXPAND_STEPS
|
||||||
|
|
||||||
|
highp vec2 dir = vec2(centerCoord.x - texCoord.s, centerCoord.y - texCoord.t);
|
||||||
|
dir /= max(1.0, length(dir) * 2.0);
|
||||||
|
highp vec2 shift = delta * len * dir * 2.0 / max(1.0, samples - 1.0);
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
|
||||||
|
PLACEHOLDER_UNROLLED_LOOP
|
||||||
|
|
||||||
|
gl_FragColor *= weight * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
var shader = fragmentShaderSkeleton
|
||||||
|
var expandSteps = ""
|
||||||
|
|
||||||
|
if (transparentBorder) {
|
||||||
|
expandSteps += "centerCoord = (centerCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
expandSteps += "texCoord = (texCoord - expand) / (1.0 - 2.0 * expand);"
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrolledLoop = "gl_FragColor += texture2D(source, texCoord);\n"
|
||||||
|
|
||||||
|
if (rootItem.samples > 1) {
|
||||||
|
unrolledLoop = ""
|
||||||
|
for (var i = 0; i < rootItem.samples; i++)
|
||||||
|
unrolledLoop += "gl_FragColor += texture2D(source, texCoord); texCoord += shift;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_EXPAND_STEPS", expandSteps)
|
||||||
|
fragmentShader = shader.replace("PLACEHOLDER_UNROLLED_LOOP", unrolledLoop)
|
||||||
|
}
|
||||||
|
|
||||||
|
onFragmentShaderChanged: sourceChanged()
|
||||||
|
onSamplesChanged: buildFragmentShader()
|
||||||
|
onTransparentBorderChanged: buildFragmentShader()
|
||||||
|
Component.onCompleted: buildFragmentShader()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real spread: 0.0
|
||||||
|
property real blur: 0.0
|
||||||
|
property color color: "white"
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: rootItem.blur
|
||||||
|
|
||||||
|
property real weight1;
|
||||||
|
property real weight2;
|
||||||
|
property real weight3;
|
||||||
|
property real weight4;
|
||||||
|
property real weight5;
|
||||||
|
property real weight6;
|
||||||
|
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property alias color: rootItem.color
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1.0 - v / 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,413 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real blur: 0.0
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
property real spread: 0.0
|
||||||
|
property color color: "black"
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
|
||||||
|
property real verticalOffset: rootItem.verticalOffset / rootItem.width
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
fragmentShader: "
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform highp sampler2D source;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
uniform highp float horizontalOffset;
|
||||||
|
uniform highp float verticalOffset;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
|
||||||
|
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
|
||||||
|
lowp float eb = 1.0 - ea;
|
||||||
|
gl_FragColor = (eb * color + ea * color * (1.0 - texture2D(source, pos).a)) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: rootItem.blur
|
||||||
|
|
||||||
|
property real weight1;
|
||||||
|
property real weight2;
|
||||||
|
property real weight3;
|
||||||
|
property real weight4;
|
||||||
|
property real weight5;
|
||||||
|
property real weight6;
|
||||||
|
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1.0 - v / 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D original;
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 shadowColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
shadowColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
shadowColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
shadowColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
shadowColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
|
||||||
|
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
|
||||||
|
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,332 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property variant maskSource
|
||||||
|
property real blur: 0.0
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: mask0
|
||||||
|
property variant source: maskSourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: masklevel1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: mask0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0, 0, 0, 0)
|
||||||
|
visible: false
|
||||||
|
smooth: rootItem.blur > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant mask: masklevel1
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: Math.sqrt(rootItem.blur) * 1.2 - 0.2
|
||||||
|
property real weight1
|
||||||
|
property real weight2
|
||||||
|
property real weight3
|
||||||
|
property real weight4
|
||||||
|
property real weight5
|
||||||
|
property real weight6
|
||||||
|
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D mask;
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform lowp sampler2D source6;
|
||||||
|
uniform lowp float lod;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
mediump float weight(mediump float v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
return 1.0 - v * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
lowp vec4 maskColor = texture2D(mask, qt_TexCoord0);
|
||||||
|
mediump float l = lod * maskColor.a;
|
||||||
|
|
||||||
|
mediump float w1 = weight(abs(l - 0.100));
|
||||||
|
mediump float w2 = weight(abs(l - 0.300));
|
||||||
|
mediump float w3 = weight(abs(l - 0.500));
|
||||||
|
mediump float w4 = weight(abs(l - 0.700));
|
||||||
|
mediump float w5 = weight(abs(l - 0.900));
|
||||||
|
mediump float w6 = weight(abs(l - 1.100));
|
||||||
|
|
||||||
|
mediump float sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
mediump float weight1 = w1 / sum;
|
||||||
|
mediump float weight2 = w2 / sum;
|
||||||
|
mediump float weight3 = w3 / sum;
|
||||||
|
mediump float weight4 = w4 / sum;
|
||||||
|
mediump float weight5 = w5 / sum;
|
||||||
|
mediump float weight6 = w6 / sum;
|
||||||
|
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
sourceColor += texture2D(source6, qt_TexCoord0) * weight6;
|
||||||
|
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real deviation: (radius + 1) / 3.3333
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real horizontalStep: 0.0
|
||||||
|
property real verticalStep: 0.0
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
property bool enableColor: false
|
||||||
|
property color color: "white"
|
||||||
|
property real spread: 0.0
|
||||||
|
|
||||||
|
property bool enableMask: false
|
||||||
|
property variant maskSource
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: rootItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
property real deviation: Math.max(0.1, rootItem.deviation)
|
||||||
|
property real radius: rootItem.radius
|
||||||
|
property int maxRadius: rootItem.maximumRadius
|
||||||
|
property bool transparentBorder: rootItem.transparentBorder
|
||||||
|
property real gaussianSum: 0.0
|
||||||
|
property real startIndex: 0.0
|
||||||
|
property real deltaFactor: (2 * radius - 1) / (maxRadius * 2 - 1)
|
||||||
|
property real expandX: transparentBorder && rootItem.horizontalStep > 0 ? maxRadius / width : 0.0
|
||||||
|
property real expandY: transparentBorder && rootItem.verticalStep > 0 ? maxRadius / height : 0.0
|
||||||
|
property variant gwts: []
|
||||||
|
property variant delta: Qt.vector3d(rootItem.horizontalStep * deltaFactor, rootItem.verticalStep * deltaFactor, startIndex);
|
||||||
|
property variant factor_0_2: Qt.vector3d(gwts[0], gwts[1], gwts[2]);
|
||||||
|
property variant factor_3_5: Qt.vector3d(gwts[3], gwts[4], gwts[5]);
|
||||||
|
property variant factor_6_8: Qt.vector3d(gwts[6], gwts[7], gwts[8]);
|
||||||
|
property variant factor_9_11: Qt.vector3d(gwts[9], gwts[10], gwts[11]);
|
||||||
|
property variant factor_12_14: Qt.vector3d(gwts[12], gwts[13], gwts[14]);
|
||||||
|
property variant factor_15_17: Qt.vector3d(gwts[15], gwts[16], gwts[17]);
|
||||||
|
property variant factor_18_20: Qt.vector3d(gwts[18], gwts[19], gwts[20]);
|
||||||
|
property variant factor_21_23: Qt.vector3d(gwts[21], gwts[22], gwts[23]);
|
||||||
|
property variant factor_24_26: Qt.vector3d(gwts[24], gwts[25], gwts[26]);
|
||||||
|
property variant factor_27_29: Qt.vector3d(gwts[27], gwts[28], gwts[29]);
|
||||||
|
property variant factor_30_32: Qt.vector3d(gwts[30], gwts[31], gwts[32]);
|
||||||
|
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property variant maskSource: maskSourceProxy.output
|
||||||
|
|
||||||
|
anchors.fill: rootItem
|
||||||
|
|
||||||
|
function gausFunc(x){
|
||||||
|
//Gaussian function = h(x):=(1/sqrt(2*3.14159*(D^2))) * %e^(-(x^2)/(2*(D^2)));
|
||||||
|
return (1.0 / Math.sqrt(2 * Math.PI * (Math.pow(shaderItem.deviation, 2)))) * Math.pow(Math.E, -((Math.pow(x, 2)) / (2 * (Math.pow(shaderItem.deviation, 2)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateGaussianWeights() {
|
||||||
|
gaussianSum = 0.0;
|
||||||
|
startIndex = -maxRadius + 0.5
|
||||||
|
|
||||||
|
var n = new Array(32);
|
||||||
|
for (var j = 0; j < 32; j++)
|
||||||
|
n[j] = 0;
|
||||||
|
|
||||||
|
var max = maxRadius * 2
|
||||||
|
var delta = (2 * radius - 1) / (max - 1);
|
||||||
|
for (var i = 0; i < max; i++) {
|
||||||
|
n[i] = gausFunc(-radius + 0.5 + i * delta);
|
||||||
|
gaussianSum += n[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
gwts = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFragmentShader() {
|
||||||
|
|
||||||
|
var shaderSteps = [
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_0_2.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_3_5.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_6_8.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_9_11.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_12_14.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_15_17.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_18_20.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_21_23.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_24_26.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_27_29.z; texCoord += shift;",
|
||||||
|
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.x; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.y; texCoord += shift;",
|
||||||
|
"gl_FragColor += texture2D(source, texCoord) * factor_30_32.z; texCoord += shift;"
|
||||||
|
]
|
||||||
|
|
||||||
|
var shader = fragmentShaderBegin
|
||||||
|
var samples = maxRadius * 2
|
||||||
|
if (samples > 32) {
|
||||||
|
console.log("DirectionalGaussianBlur.qml WARNING: Maximum of blur radius (16) exceeded!")
|
||||||
|
samples = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < samples; i++) {
|
||||||
|
shader += shaderSteps[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
shader += fragmentShaderEnd
|
||||||
|
|
||||||
|
var colorizeSteps = ""
|
||||||
|
var colorizeUniforms = ""
|
||||||
|
|
||||||
|
var maskSteps = ""
|
||||||
|
var maskUniforms = ""
|
||||||
|
|
||||||
|
if (enableColor) {
|
||||||
|
colorizeSteps += "gl_FragColor = mix(vec4(0), color, clamp((gl_FragColor.a - 0.0) / (spread - 0.0), 0.0, 1.0));\n"
|
||||||
|
colorizeUniforms += "uniform highp vec4 color;\n"
|
||||||
|
colorizeUniforms += "uniform highp float spread;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableMask) {
|
||||||
|
maskSteps += "shift *= texture2D(maskSource, qt_TexCoord0).a;\n"
|
||||||
|
maskUniforms += "uniform sampler2D maskSource;\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_STEPS", colorizeSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_COLORIZE_UNIFORMS", colorizeUniforms)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_STEPS", maskSteps)
|
||||||
|
shader = shader.replace("PLACEHOLDER_MASK_UNIFORMS", maskUniforms)
|
||||||
|
|
||||||
|
fragmentShader = shader
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeviationChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onRadiusChanged: updateGaussianWeights()
|
||||||
|
|
||||||
|
onTransparentBorderChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMaxRadiusChanged: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
buildFragmentShader()
|
||||||
|
updateGaussianWeights()
|
||||||
|
}
|
||||||
|
|
||||||
|
property string fragmentShaderBegin: "
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
uniform highp float qt_Opacity;
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform highp vec3 delta;
|
||||||
|
uniform highp vec3 factor_0_2;
|
||||||
|
uniform highp vec3 factor_3_5;
|
||||||
|
uniform highp vec3 factor_6_8;
|
||||||
|
uniform highp vec3 factor_9_11;
|
||||||
|
uniform highp vec3 factor_12_14;
|
||||||
|
uniform highp vec3 factor_15_17;
|
||||||
|
uniform highp vec3 factor_18_20;
|
||||||
|
uniform highp vec3 factor_21_23;
|
||||||
|
uniform highp vec3 factor_24_26;
|
||||||
|
uniform highp vec3 factor_27_29;
|
||||||
|
uniform highp vec3 factor_30_32;
|
||||||
|
uniform highp float gaussianSum;
|
||||||
|
uniform highp float expandX;
|
||||||
|
uniform highp float expandY;
|
||||||
|
PLACEHOLDER_MASK_UNIFORMS
|
||||||
|
PLACEHOLDER_COLORIZE_UNIFORMS
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec2 shift = vec2(delta.x, delta.y);
|
||||||
|
|
||||||
|
PLACEHOLDER_MASK_STEPS
|
||||||
|
|
||||||
|
highp float index = delta.z;
|
||||||
|
mediump vec2 texCoord = qt_TexCoord0;
|
||||||
|
texCoord.s = (texCoord.s - expandX) / (1.0 - 2.0 * expandX);
|
||||||
|
texCoord.t = (texCoord.t - expandY) / (1.0 - 2.0 * expandY);
|
||||||
|
texCoord += (shift * index);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
|
"
|
||||||
|
|
||||||
|
property string fragmentShaderEnd: "
|
||||||
|
|
||||||
|
gl_FragColor /= gaussianSum;
|
||||||
|
|
||||||
|
PLACEHOLDER_COLORIZE_STEPS
|
||||||
|
|
||||||
|
gl_FragColor *= qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real spread: 0.0
|
||||||
|
property color color: "white"
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: shaderItem
|
||||||
|
x: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1 : 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
enableColor: true
|
||||||
|
color: rootItem.color
|
||||||
|
spread: rootItem.spread
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: sourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property real horizontalOffset: 0
|
||||||
|
property real verticalOffset: 0
|
||||||
|
property real spread: 0
|
||||||
|
property color color: "black"
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect{
|
||||||
|
id: shadowItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property color color: rootItem.color
|
||||||
|
property real horizontalOffset: rootItem.horizontalOffset / rootItem.width
|
||||||
|
property real verticalOffset: rootItem.verticalOffset / rootItem.height
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp sampler2D original;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
uniform highp float horizontalOffset;
|
||||||
|
uniform highp float verticalOffset;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
highp vec2 pos = qt_TexCoord0 - vec2(horizontalOffset, verticalOffset);
|
||||||
|
lowp float ea = step(0.0, pos.x) * step(0.0, pos.y) * step(pos.x, 1.0) * step(pos.y, 1.0);
|
||||||
|
lowp float eb = 1.0 - ea;
|
||||||
|
gl_FragColor = eb * color + ea * color * (1.0 - texture2D(original, pos).a) * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: blurItem
|
||||||
|
anchors.fill: parent
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius : parent.width
|
||||||
|
height: parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: shadowItem
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: blurredSource
|
||||||
|
sourceItem: blurItem
|
||||||
|
live: true
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property variant original: sourceProxy.output
|
||||||
|
property variant shadow: blurredSource
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property color color: rootItem.color
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform highp sampler2D original;
|
||||||
|
uniform highp sampler2D shadow;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp vec4 color;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
lowp vec4 originalColor = texture2D(original, qt_TexCoord0);
|
||||||
|
lowp vec4 shadowColor = texture2D(shadow, qt_TexCoord0);
|
||||||
|
shadowColor.rgb = mix(originalColor.rgb, color.rgb * originalColor.a, linearstep(0.0, spread, shadowColor.a));
|
||||||
|
gl_FragColor = vec4(shadowColor.rgb, originalColor.a) * originalColor.a * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property variant maskSource
|
||||||
|
property real radius: 0.0
|
||||||
|
property int maximumRadius: 0
|
||||||
|
property bool cached: false
|
||||||
|
property bool transparentBorder: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: maskSourceProxy
|
||||||
|
input: rootItem.maskSource
|
||||||
|
sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: blur
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: blur
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: blur
|
||||||
|
x: transparentBorder ? -maximumRadius - 1: 0
|
||||||
|
y: transparentBorder ? -maximumRadius - 1: 0
|
||||||
|
width: horizontalBlur.width
|
||||||
|
height: horizontalBlur.height
|
||||||
|
horizontalStep: 0.0
|
||||||
|
verticalStep: 1.0 / parent.height
|
||||||
|
source: horizontalBlur
|
||||||
|
enableMask: true
|
||||||
|
maskSource: maskSourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianDirectionalBlur {
|
||||||
|
id: horizontalBlur
|
||||||
|
width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 2 * maximumRadius + 2 : parent.height
|
||||||
|
horizontalStep: 1.0 / parent.width
|
||||||
|
verticalStep: 0.0
|
||||||
|
source: sourceProxy.output
|
||||||
|
enableMask: true
|
||||||
|
maskSource: maskSourceProxy.output
|
||||||
|
radius: rootItem.radius
|
||||||
|
maximumRadius: rootItem.maximumRadius
|
||||||
|
transparentBorder: rootItem.transparentBorder
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant input
|
||||||
|
property variant output
|
||||||
|
property variant sourceRect
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Component.onCompleted: evaluateInput()
|
||||||
|
|
||||||
|
onInputChanged: evaluateInput()
|
||||||
|
|
||||||
|
onSourceRectChanged: evaluateInput()
|
||||||
|
|
||||||
|
function evaluateInput() {
|
||||||
|
if (input == undefined) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = sourceRect
|
||||||
|
}
|
||||||
|
else if (isQQuickItemLayerEnabled(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (isQQuickShaderEffectSource(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickItemLayerEnabled(item) {
|
||||||
|
if (item.hasOwnProperty("layer")) {
|
||||||
|
var l = item["layer"]
|
||||||
|
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickImage(item) {
|
||||||
|
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
|
||||||
|
return hasProperties(item, imageProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickShaderEffectSource(item) {
|
||||||
|
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
|
||||||
|
return hasProperties(item, shaderEffectSourceProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasProperties(item, properties) {
|
||||||
|
var counter = 0
|
||||||
|
for (var j = 0; j < properties.length; j++) {
|
||||||
|
if (item.hasOwnProperty(properties [j]))
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
return properties.length == counter
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasChildren(item) {
|
||||||
|
if (item.hasOwnProperty("childrenRect")) {
|
||||||
|
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTileMode(item) {
|
||||||
|
if (item.hasOwnProperty("fillMode")) {
|
||||||
|
if (item["fillMode"].toString() != "0")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: proxySource
|
||||||
|
live: rootItem.input != rootItem.output
|
||||||
|
hideSource: false
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Blend 1.0 Blend.qml
|
||||||
|
BrightnessContrast 1.0 BrightnessContrast.qml
|
||||||
|
Colorize 1.0 Colorize.qml
|
||||||
|
ColorOverlay 1.0 ColorOverlay.qml
|
||||||
|
ConicalGradient 1.0 ConicalGradient.qml
|
||||||
|
Desaturate 1.0 Desaturate.qml
|
||||||
|
DirectionalBlur 1.0 DirectionalBlur.qml
|
||||||
|
Displace 1.0 Displace.qml
|
||||||
|
DropShadow 1.0 DropShadow.qml
|
||||||
|
FastBlur 1.0 FastBlur.qml
|
||||||
|
GammaAdjust 1.0 GammaAdjust.qml
|
||||||
|
GaussianBlur 1.0 GaussianBlur.qml
|
||||||
|
Glow 1.0 Glow.qml
|
||||||
|
HueSaturation 1.0 HueSaturation.qml
|
||||||
|
InnerShadow 1.0 InnerShadow.qml
|
||||||
|
LevelAdjust 1.0 LevelAdjust.qml
|
||||||
|
LinearGradient 1.0 LinearGradient.qml
|
||||||
|
MaskedBlur 1.0 MaskedBlur.qml
|
||||||
|
OpacityMask 1.0 OpacityMask.qml
|
||||||
|
RadialBlur 1.0 RadialBlur.qml
|
||||||
|
RadialGradient 1.0 RadialGradient.qml
|
||||||
|
RecursiveBlur 1.0 RecursiveBlur.qml
|
||||||
|
RectangularGlow 1.0 RectangularGlow.qml
|
||||||
|
ThresholdMask 1.0 ThresholdMask.qml
|
||||||
|
ZoomBlur 1.0 ZoomBlur.qml
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
|||||||
|
module QtQuick
|
||||||
|
plugin qtquick2plugin
|
||||||
|
classname QtQuick2Plugin
|
||||||
|
typeinfo plugins.qmltypes
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window 2.1
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ApplicationWindow
|
||||||
|
\since 5.1
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\ingroup applicationwindow
|
||||||
|
\brief Provides a top-level application window.
|
||||||
|
|
||||||
|
ApplicationWindow is a \l Window that adds convenience for positioning items,
|
||||||
|
such as \l MenuBar, \l ToolBar, and \l StatusBar in a platform independent
|
||||||
|
manner.
|
||||||
|
|
||||||
|
\code
|
||||||
|
ApplicationWindow {
|
||||||
|
id: window
|
||||||
|
menuBar: MenuBar {
|
||||||
|
Menu { MenuItem {...} }
|
||||||
|
Menu { MenuItem {...} }
|
||||||
|
}
|
||||||
|
|
||||||
|
toolBar: ToolBar {
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
ToolButton {...}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TabView {
|
||||||
|
id: myContent
|
||||||
|
anchors.fill: parent
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty MenuBar ApplicationWindow::menuBar
|
||||||
|
|
||||||
|
This property holds the \l MenuBar.
|
||||||
|
|
||||||
|
By default, this value is not set.
|
||||||
|
*/
|
||||||
|
property MenuBar menuBar: null
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty Item ApplicationWindow::toolBar
|
||||||
|
|
||||||
|
This property holds the toolbar \l Item.
|
||||||
|
|
||||||
|
It can be set to any Item type, but is generally used with \l ToolBar.
|
||||||
|
|
||||||
|
By default, this value is not set. When you set the toolbar item, it will
|
||||||
|
be anchored automatically into the application window.
|
||||||
|
*/
|
||||||
|
property Item toolBar
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty Item ApplicationWindow::statusBar
|
||||||
|
|
||||||
|
This property holds the status bar \l Item.
|
||||||
|
|
||||||
|
It can be set to any Item type, but is generally used with \l StatusBar.
|
||||||
|
|
||||||
|
By default, this value is not set. When you set the status bar item, it
|
||||||
|
will be anchored automatically into the application window.
|
||||||
|
*/
|
||||||
|
property Item statusBar
|
||||||
|
|
||||||
|
onToolBarChanged: { if (toolBar) { toolBar.parent = toolBarArea } }
|
||||||
|
|
||||||
|
onStatusBarChanged: { if (statusBar) { statusBar.parent = statusBarArea } }
|
||||||
|
|
||||||
|
onVisibleChanged: { if (visible && menuBar) { menuBar.__parentWindow = root } }
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
default property alias data: contentArea.data
|
||||||
|
|
||||||
|
color: syspal.window
|
||||||
|
|
||||||
|
flags: Qt.Window | Qt.WindowFullscreenButtonHint |
|
||||||
|
Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint |
|
||||||
|
Qt.WindowCloseButtonHint | Qt.WindowFullscreenButtonHint
|
||||||
|
// QTBUG-35049: Windows is removing features we didn't ask for, even though Qt::CustomizeWindowHint is not set
|
||||||
|
// Otherwise Qt.Window | Qt.WindowFullscreenButtonHint would be enough
|
||||||
|
|
||||||
|
SystemPalette {id: syspal}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: backgroundItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Keys.forwardTo: menuBar ? [menuBar.__contentItem] : []
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentArea
|
||||||
|
anchors.top: toolBarArea.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: statusBarArea.top
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: toolBarArea
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
implicitHeight: childrenRect.height
|
||||||
|
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: statusBarArea
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
implicitHeight: childrenRect.height
|
||||||
|
height: visibleChildren.length > 0 ? implicitHeight: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: if (visible && menuBar) menuBar.__parentWindow = root
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "hasMenuBar"
|
||||||
|
when: menuBar && !menuBar.__isNative
|
||||||
|
|
||||||
|
ParentChange {
|
||||||
|
target: menuBar.__contentItem
|
||||||
|
parent: backgroundItem
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: menuBar.__contentItem
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: backgroundItem.width
|
||||||
|
}
|
||||||
|
|
||||||
|
AnchorChanges {
|
||||||
|
target: toolBarArea
|
||||||
|
anchors.top: menuBar.__contentItem.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype BusyIndicator
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.2
|
||||||
|
\ingroup controls
|
||||||
|
\brief A busy indicator.
|
||||||
|
|
||||||
|
The busy indicator should be used to indicate activity while content is
|
||||||
|
being loaded or the UI is blocked waiting for a resource to become available.
|
||||||
|
|
||||||
|
You can create a custom appearance for a Busy Indicator by
|
||||||
|
assigning a \l {QtQuick.Controls.Styles::BusyIndicatorStyle}{BusyIndicatorStyle}.
|
||||||
|
*/
|
||||||
|
Control {
|
||||||
|
id: indicator
|
||||||
|
|
||||||
|
/*! \qmlproperty bool BusyIndicator::running
|
||||||
|
|
||||||
|
This property holds whether the busy indicator is currently indicating
|
||||||
|
activity.
|
||||||
|
|
||||||
|
\note The indicator is only visible when this property is set to \c true.
|
||||||
|
|
||||||
|
The default value is \c true.
|
||||||
|
*/
|
||||||
|
property bool running: true
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Indicator
|
||||||
|
Accessible.name: "busy"
|
||||||
|
|
||||||
|
style: Qt.createComponent(Settings.style + "/BusyIndicatorStyle.qml", indicator)
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Button
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup controls
|
||||||
|
\brief A push button with a text label.
|
||||||
|
|
||||||
|
The push button is perhaps the most commonly used widget in any graphical
|
||||||
|
user interface. Pushing (or clicking) a button commands the computer to
|
||||||
|
perform some action or answer a question. Common examples of buttons are
|
||||||
|
OK, Apply, Cancel, Close, Yes, No, and Help buttons.
|
||||||
|
|
||||||
|
Button is similar to the QPushButton widget.
|
||||||
|
|
||||||
|
You can create a custom appearance for a Button by
|
||||||
|
assigning a \l {QtQuick.Controls.Styles::ButtonStyle}{ButtonStyle}.
|
||||||
|
*/
|
||||||
|
BasicButton {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
/*! This property holds whether the push button is the default button.
|
||||||
|
Default buttons decide what happens when the user presses enter in a
|
||||||
|
dialog without giving a button explicit focus. \note This property only
|
||||||
|
changes the appearance of the button. The expected behavior needs to be
|
||||||
|
implemented by the user.
|
||||||
|
|
||||||
|
The default value is \c false.
|
||||||
|
*/
|
||||||
|
property bool isDefault: false
|
||||||
|
|
||||||
|
/*! Assign a \l Menu to this property to get a pull-down menu button.
|
||||||
|
|
||||||
|
The default value is \c null.
|
||||||
|
*/
|
||||||
|
property Menu menu: null
|
||||||
|
|
||||||
|
__effectivePressed: __behavior.effectivePressed || menu && menu.__popupVisible
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Accessible.name: text
|
||||||
|
|
||||||
|
style: Qt.createComponent(Settings.style + "/ButtonStyle.qml", button)
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: menu
|
||||||
|
property: "__minimumWidth"
|
||||||
|
value: button.__panel.width
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: menu
|
||||||
|
property: "__visualItem"
|
||||||
|
value: button
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: __behavior
|
||||||
|
onEffectivePressedChanged: {
|
||||||
|
if (__behavior.effectivePressed && menu)
|
||||||
|
popupMenuTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: popupMenuTimer
|
||||||
|
interval: 10
|
||||||
|
onTriggered: {
|
||||||
|
__behavior.keyPressed = false
|
||||||
|
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||||
|
menu.__popup(button.width, button.height, 0)
|
||||||
|
else
|
||||||
|
menu.__popup(0, button.height, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype CheckBox
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup controls
|
||||||
|
\brief A checkbox with a text label.
|
||||||
|
|
||||||
|
A CheckBox is an option button that can be toggled on (checked) or off
|
||||||
|
(unchecked). Checkboxes are typically used to represent features in an
|
||||||
|
application that can be enabled or disabled without affecting others.
|
||||||
|
|
||||||
|
The state of the checkbox can be set with the \l {AbstractCheckable::checked}{checked} property.
|
||||||
|
|
||||||
|
In addition to the checked and unchecked states, there is a third state:
|
||||||
|
partially checked. This state indicates that the
|
||||||
|
regular checked/unchecked state can not be determined; generally because of
|
||||||
|
other states that affect the checkbox. This state is useful when several
|
||||||
|
child nodes are selected in a treeview, for example.
|
||||||
|
|
||||||
|
The partially checked state can be made available to the user by setting
|
||||||
|
\l partiallyCheckedEnabled to \c true, or set directly by setting
|
||||||
|
\l checkedState to \c Qt.PartiallyChecked. \l checkedState behaves
|
||||||
|
identically to \l {AbstractCheckable::checked}{checked} when \l partiallyCheckedEnabled
|
||||||
|
is \c false; setting one will appropriately set the other.
|
||||||
|
|
||||||
|
The label is shown next to the checkbox, and you can set the label text using its
|
||||||
|
\l {AbstractCheckable::text}{text} property.
|
||||||
|
|
||||||
|
\qml
|
||||||
|
Column {
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Breakfast")
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Lunch")
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Dinner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
Whenever a CheckBox is clicked, it emits the \l {AbstractCheckable::clicked}{clicked()} signal.
|
||||||
|
|
||||||
|
You can create a custom appearance for a CheckBox by
|
||||||
|
assigning a \l {QtQuick.Controls.Styles::CheckBoxStyle}{CheckBoxStyle}.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractCheckable {
|
||||||
|
id: checkBox
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty enumeration CheckBox::checkedState
|
||||||
|
|
||||||
|
This property indicates the current checked state of the checkbox.
|
||||||
|
|
||||||
|
Possible values:
|
||||||
|
\c Qt.UnChecked - The checkbox is not checked (default).
|
||||||
|
\c Qt.Checked - The checkbox is checked.
|
||||||
|
\c Qt.PartiallyChecked - The checkbox is in a partially checked (or
|
||||||
|
"mixed") state.
|
||||||
|
|
||||||
|
The \l {AbstractCheckable::checked}{checked} property also determines whether
|
||||||
|
this property is \c Qt.Checked or \c Qt.UnChecked, and vice versa.
|
||||||
|
*/
|
||||||
|
property int checkedState: checked ? Qt.Checked : Qt.Unchecked
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property determines whether the \c Qt.PartiallyChecked state is
|
||||||
|
available.
|
||||||
|
|
||||||
|
A checkbox may be in a partially checked state when the regular checked
|
||||||
|
state can not be determined.
|
||||||
|
|
||||||
|
Setting \l checkedState to \c Qt.PartiallyChecked will implicitly set
|
||||||
|
this property to \c true.
|
||||||
|
|
||||||
|
If this property is \c true, \l {AbstractCheckable::checked}{checked} will be \c false.
|
||||||
|
|
||||||
|
By default, this property is \c false.
|
||||||
|
*/
|
||||||
|
property bool partiallyCheckedEnabled: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
True if onCheckedChanged should be ignored because we were reacting
|
||||||
|
to onCheckedStateChanged.
|
||||||
|
*/
|
||||||
|
property bool __ignoreChecked: false
|
||||||
|
|
||||||
|
style: Qt.createComponent(Settings.style + "/CheckBoxStyle.qml", checkBox)
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Accessible.role: Accessible.CheckBox
|
||||||
|
Accessible.name: text
|
||||||
|
|
||||||
|
__cycleStatesHandler: __cycleCheckBoxStates
|
||||||
|
|
||||||
|
onCheckedChanged: {
|
||||||
|
if (!__ignoreChecked)
|
||||||
|
checkedState = checked ? Qt.Checked : Qt.Unchecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
onCheckedStateChanged: {
|
||||||
|
__ignoreChecked = true;
|
||||||
|
if (checkedState === Qt.PartiallyChecked) {
|
||||||
|
partiallyCheckedEnabled = true;
|
||||||
|
checked = false;
|
||||||
|
} else {
|
||||||
|
checked = checkedState === Qt.Checked;
|
||||||
|
}
|
||||||
|
__ignoreChecked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onPartiallyCheckedEnabledChanged: {
|
||||||
|
if (exclusiveGroup && partiallyCheckedEnabled) {
|
||||||
|
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExclusiveGroupChanged: {
|
||||||
|
if (exclusiveGroup && partiallyCheckedEnabled) {
|
||||||
|
console.warn("Cannot have partially checked boxes in an ExclusiveGroup.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
function __cycleCheckBoxStates() {
|
||||||
|
if (!partiallyCheckedEnabled) {
|
||||||
|
checked = !checked;
|
||||||
|
} else {
|
||||||
|
switch (checkedState) {
|
||||||
|
case Qt.Unchecked: checkedState = Qt.Checked; break;
|
||||||
|
case Qt.Checked: checkedState = Qt.PartiallyChecked; break;
|
||||||
|
case Qt.PartiallyChecked: checkedState = Qt.Unchecked; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,562 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ComboBox
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup controls
|
||||||
|
\brief Provides a drop-down list functionality.
|
||||||
|
|
||||||
|
Add items to the comboBox by assigning it a ListModel, or a list of strings to the \l model property.
|
||||||
|
|
||||||
|
\qml
|
||||||
|
ComboBox {
|
||||||
|
width: 200
|
||||||
|
model: [ "Banana", "Apple", "Coconut" ]
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
In this example we are demonstrating how to use a ListModel with a combo box.
|
||||||
|
|
||||||
|
\qml
|
||||||
|
ComboBox {
|
||||||
|
currentIndex: 2
|
||||||
|
model: ListModel {
|
||||||
|
id: cbItems
|
||||||
|
ListElement { text: "Banana"; color: "Yellow" }
|
||||||
|
ListElement { text: "Apple"; color: "Green" }
|
||||||
|
ListElement { text: "Coconut"; color: "Brown" }
|
||||||
|
}
|
||||||
|
width: 200
|
||||||
|
onCurrentIndexChanged: console.debug(cbItems.get(currentIndex).text + ", " + cbItems.get(currentIndex).color)
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
You can make a combo box editable by setting the \l editable property. An editable combo box will
|
||||||
|
autocomplete its text based on what is available in the model.
|
||||||
|
|
||||||
|
In the next example we demonstrate how you can append content to an editable combo box by
|
||||||
|
reacting to the \l accepted signal. Note that you have to explicitly prevent duplicates.
|
||||||
|
|
||||||
|
\qml
|
||||||
|
ComboBox {
|
||||||
|
editable: true
|
||||||
|
model: ListModel {
|
||||||
|
id: model
|
||||||
|
ListElement { text: "Banana"; color: "Yellow" }
|
||||||
|
ListElement { text: "Apple"; color: "Green" }
|
||||||
|
ListElement { text: "Coconut"; color: "Brown" }
|
||||||
|
}
|
||||||
|
onAccepted: {
|
||||||
|
if (editableCombo.find(currentText) === -1) {
|
||||||
|
model.append({text: editText})
|
||||||
|
currentIndex = editableCombo.find(editText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
|
||||||
|
You can create a custom appearance for a ComboBox by
|
||||||
|
assigning a \l {QtQuick.Controls.Styles::ComboBoxStyle}{ComboBoxStyle}.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: comboBox
|
||||||
|
|
||||||
|
/*! \qmlproperty model ComboBox::model
|
||||||
|
The model to populate the ComboBox from.
|
||||||
|
|
||||||
|
Changing the model after initialization will reset \l currentIndex to \c 0.
|
||||||
|
*/
|
||||||
|
property alias model: popupItems.model
|
||||||
|
|
||||||
|
/*! The model role used for populating the ComboBox. */
|
||||||
|
property string textRole: ""
|
||||||
|
|
||||||
|
/*! \qmlproperty int ComboBox::currentIndex
|
||||||
|
The index of the currently selected item in the ComboBox.
|
||||||
|
|
||||||
|
\sa model
|
||||||
|
*/
|
||||||
|
property alias currentIndex: popup.__selectedIndex
|
||||||
|
|
||||||
|
/*! \qmlproperty string ComboBox::currentText
|
||||||
|
The text of the currently selected item in the ComboBox.
|
||||||
|
|
||||||
|
\note Since \c currentText depends on \c currentIndex, there's no way to ensure \c currentText
|
||||||
|
will be up to date whenever a \c onCurrentIndexChanged handler is called.
|
||||||
|
*/
|
||||||
|
readonly property alias currentText: popup.currentText
|
||||||
|
|
||||||
|
/*! This property holds whether the combo box can be edited by the user.
|
||||||
|
The default value is \c false.
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
*/
|
||||||
|
property bool editable: false
|
||||||
|
|
||||||
|
/*! \qmlproperty string ComboBox::editText
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
This property specifies text being manipulated by the user for an editable combo box.
|
||||||
|
*/
|
||||||
|
property alias editText: input.text
|
||||||
|
|
||||||
|
/*! This property specifies whether the combobox should gain active focus when pressed.
|
||||||
|
The default value is \c false. */
|
||||||
|
property bool activeFocusOnPress: false
|
||||||
|
|
||||||
|
/*! \qmlproperty bool ComboBox::pressed
|
||||||
|
|
||||||
|
This property holds whether the button is being pressed. */
|
||||||
|
readonly property bool pressed: mouseArea.pressed && mouseArea.containsMouse || popup.__popupVisible
|
||||||
|
|
||||||
|
/*! \qmlproperty bool ComboBox::hovered
|
||||||
|
|
||||||
|
This property indicates whether the control is being hovered.
|
||||||
|
*/
|
||||||
|
readonly property alias hovered: mouseArea.containsMouse
|
||||||
|
|
||||||
|
/*! \qmlproperty int ComboBox::count
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
This property holds the number of items in the combo box.
|
||||||
|
*/
|
||||||
|
readonly property alias count: popupItems.count
|
||||||
|
|
||||||
|
/*! Returns the text for a given \a index.
|
||||||
|
If an invalid index is provided, \c null is returned
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
*/
|
||||||
|
function textAt (index) {
|
||||||
|
if (index >= count || index < 0)
|
||||||
|
return null;
|
||||||
|
return popupItems.objectAt(index).text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Finds and returns the index of a given \a text
|
||||||
|
If no match is found, \c -1 is returned. The search is case sensitive.
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
*/
|
||||||
|
function find (text) {
|
||||||
|
return input.find(text, Qt.MatchExactly)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty Validator ComboBox::validator
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
Allows you to set a text validator for an editable ComboBox.
|
||||||
|
When a validator is set,
|
||||||
|
the text field will only accept input which leaves the text property in
|
||||||
|
an intermediate state. The accepted signal will only be sent
|
||||||
|
if the text is in an acceptable state when enter is pressed.
|
||||||
|
|
||||||
|
Currently supported validators are \l{QtQuick2::IntValidator},
|
||||||
|
\l{QtQuick2::DoubleValidator}, and \l{QtQuick2::RegExpValidator}. An
|
||||||
|
example of using validators is shown below, which allows input of
|
||||||
|
integers between 11 and 31 into the text field:
|
||||||
|
|
||||||
|
\note This property is only applied when \l editable is \c true
|
||||||
|
|
||||||
|
\qml
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
editable: true
|
||||||
|
model: 10
|
||||||
|
validator: IntValidator {bottom: 0; top: 10;}
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
\sa acceptableInput, accepted, editable
|
||||||
|
*/
|
||||||
|
property alias validator: input.validator
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty bool ComboBox::acceptableInput
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
Returns \c true if the combo box contains acceptable
|
||||||
|
text in the editable text field.
|
||||||
|
|
||||||
|
If a validator was set, this property will return \c
|
||||||
|
true if the current text satisfies the validator or mask as
|
||||||
|
a final string (not as an intermediate string).
|
||||||
|
|
||||||
|
\sa validator, accepted
|
||||||
|
|
||||||
|
*/
|
||||||
|
readonly property alias acceptableInput: input.acceptableInput
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlsignal ComboBox::accepted()
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
This signal is emitted when the Return or Enter key is pressed on an
|
||||||
|
\l editable combo box. If the confirmed string is not currently in the model,
|
||||||
|
the currentIndex will be set to -1 and the \l currentText will be updated
|
||||||
|
accordingly.
|
||||||
|
|
||||||
|
\note If there is a \l validator set on the combobox,
|
||||||
|
the signal will only be emitted if the input is in an acceptable state.
|
||||||
|
*/
|
||||||
|
signal accepted
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlsignal ComboBox::activated(int index)
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
\a index is the triggered model index or -1 if a new string is accepted
|
||||||
|
|
||||||
|
This signal is similar to currentIndex changed, but will only
|
||||||
|
be emitted if the combo box index was changed by the user and not
|
||||||
|
when set programatically.
|
||||||
|
*/
|
||||||
|
signal activated(int index)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlmethod ComboBox::selectAll()
|
||||||
|
\since QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
Causes all \l editText to be selected.
|
||||||
|
*/
|
||||||
|
function selectAll() {
|
||||||
|
input.selectAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var __popup: popup
|
||||||
|
|
||||||
|
style: Qt.createComponent(Settings.style + "/ComboBoxStyle.qml", comboBox)
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Accessible.role: Accessible.ComboBox
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onPressed: {
|
||||||
|
if (comboBox.activeFocusOnPress)
|
||||||
|
forceActiveFocus()
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (currentIndex === -1)
|
||||||
|
currentIndex = 0
|
||||||
|
|
||||||
|
popup.ready = true
|
||||||
|
popup.resolveTextValue(textRole)
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
// Perform one-character based lookup for non-editable combo box
|
||||||
|
if (!editable && event.text.length > 0) {
|
||||||
|
var index = input.find(event.text, Qt.MatchStartsWith);
|
||||||
|
if (index >= 0 && index !== currentIndex) {
|
||||||
|
currentIndex = index;
|
||||||
|
activated(currentIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput {
|
||||||
|
id: input
|
||||||
|
|
||||||
|
visible: editable
|
||||||
|
enabled: editable
|
||||||
|
focus: true
|
||||||
|
clip: contentWidth > width
|
||||||
|
text: currentText
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.leftMargin: 8
|
||||||
|
anchors.rightMargin: __style.drowDownButtonWidth
|
||||||
|
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
selectByMouse: true
|
||||||
|
selectionColor: syspal.highlight
|
||||||
|
selectedTextColor: syspal.highlightedText
|
||||||
|
onAccepted: {
|
||||||
|
var idx = input.find(editText)
|
||||||
|
if (idx > -1) {
|
||||||
|
var string = textAt(idx);
|
||||||
|
if (string.length === editText.length) {
|
||||||
|
currentIndex = idx;
|
||||||
|
editText = string;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
currentIndex = -1;
|
||||||
|
popup.currentText = editText;
|
||||||
|
}
|
||||||
|
comboBox.accepted();
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemPalette { id: syspal }
|
||||||
|
|
||||||
|
property bool blockUpdate: false
|
||||||
|
property string prevText
|
||||||
|
|
||||||
|
function find (text, searchType) {
|
||||||
|
for (var i = 0 ; i < popupItems.count ; ++i) {
|
||||||
|
var currentString = popupItems.objectAt(i).text
|
||||||
|
if (searchType === Qt.MatchExactly) {
|
||||||
|
if (text === currentString)
|
||||||
|
return i;
|
||||||
|
} else if (searchType === Qt.CaseSensitive) {
|
||||||
|
if (currentString.indexOf(text) === 0)
|
||||||
|
return i;
|
||||||
|
} else if (currentString.toLowerCase().indexOf(text.toLowerCase()) === 0) {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finds first entry and shortest entry. Used by editable combo
|
||||||
|
function tryComplete (inputText) {
|
||||||
|
var candidate = "";
|
||||||
|
var shortestString = "";
|
||||||
|
for (var i = 0 ; i < popupItems.count ; ++i) {
|
||||||
|
var currentString = popupItems.objectAt(i).text;
|
||||||
|
|
||||||
|
if (currentString.toLowerCase().indexOf(inputText.toLowerCase()) === 0) {
|
||||||
|
if (candidate.length) { // Find smallest possible match
|
||||||
|
var cmp = 0;
|
||||||
|
|
||||||
|
// We try to complete the shortest string that matches our search
|
||||||
|
if (currentString.length < candidate.length)
|
||||||
|
candidate = currentString
|
||||||
|
|
||||||
|
while (cmp < Math.min(currentString.length, shortestString.length)
|
||||||
|
&& shortestString[cmp].toLowerCase() === currentString[cmp].toLowerCase())
|
||||||
|
cmp++;
|
||||||
|
shortestString = shortestString.substring(0, cmp);
|
||||||
|
} else { // First match, select as current index and find other matches
|
||||||
|
candidate = currentString;
|
||||||
|
shortestString = currentString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (candidate.length)
|
||||||
|
return inputText + candidate.substring(inputText.length, candidate.length);
|
||||||
|
return inputText;
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool allowComplete: false
|
||||||
|
Keys.onPressed: allowComplete = (event.key !== Qt.Key_Backspace && event.key !== Qt.Key_Delete);
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
if (editable && !blockUpdate && allowComplete) {
|
||||||
|
var completed = input.tryComplete(text)
|
||||||
|
if (completed.length > text.length) {
|
||||||
|
var oldtext = input.text;
|
||||||
|
input.text = completed;
|
||||||
|
input.select(text.length, oldtext.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prevText = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextRoleChanged: popup.resolveTextValue(textRole)
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
id: popup
|
||||||
|
objectName: "popup"
|
||||||
|
|
||||||
|
style: isPopup ? __style.__popupStyle : __style.__dropDownStyle
|
||||||
|
|
||||||
|
property string currentText: selectedText
|
||||||
|
onSelectedTextChanged: if (selectedText) popup.currentText = selectedText
|
||||||
|
|
||||||
|
property string selectedText
|
||||||
|
on__SelectedIndexChanged: updateSelectedText()
|
||||||
|
property string textRole: ""
|
||||||
|
|
||||||
|
property bool ready: false
|
||||||
|
property bool isPopup: !editable && !!__panel && __panel.popup
|
||||||
|
|
||||||
|
property int y: isPopup ? (comboBox.__panel.height - comboBox.__panel.implicitHeight) / 2.0 : comboBox.__panel.height
|
||||||
|
__minimumWidth: comboBox.width
|
||||||
|
__visualItem: comboBox
|
||||||
|
|
||||||
|
property ExclusiveGroup eg: ExclusiveGroup { id: eg }
|
||||||
|
|
||||||
|
property bool __modelIsArray: popupItems.model ? popupItems.model.constructor === Array : false
|
||||||
|
|
||||||
|
Instantiator {
|
||||||
|
id: popupItems
|
||||||
|
active: false
|
||||||
|
|
||||||
|
property bool updatingModel: false
|
||||||
|
onModelChanged: {
|
||||||
|
if (active) {
|
||||||
|
if (updatingModel && popup.__selectedIndex === 0) {
|
||||||
|
// We still want to update the currentText
|
||||||
|
popup.updateSelectedText()
|
||||||
|
} else {
|
||||||
|
updatingModel = true
|
||||||
|
popup.__selectedIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: popup.textRole === '' ?
|
||||||
|
modelData :
|
||||||
|
((popup.__modelIsArray ? modelData[popup.textRole] : model[popup.textRole]) || '')
|
||||||
|
onTriggered: {
|
||||||
|
if (index !== currentIndex)
|
||||||
|
activated(index)
|
||||||
|
comboBox.editText = text
|
||||||
|
}
|
||||||
|
checkable: true
|
||||||
|
exclusiveGroup: eg
|
||||||
|
}
|
||||||
|
onObjectAdded: {
|
||||||
|
popup.insertItem(index, object)
|
||||||
|
if (!updatingModel && index === popup.__selectedIndex)
|
||||||
|
popup.selectedText = object["text"]
|
||||||
|
}
|
||||||
|
onObjectRemoved: popup.removeItem(object)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTextValue(initialTextRole) {
|
||||||
|
if (!ready || !model) {
|
||||||
|
popupItems.active = false
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var get = model['get'];
|
||||||
|
if (!get && popup.__modelIsArray) {
|
||||||
|
if (model[0].constructor !== String && model[0].constructor !== Number)
|
||||||
|
get = function(i) { return model[i]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var modelMayHaveRoles = get !== undefined
|
||||||
|
textRole = initialTextRole
|
||||||
|
if (textRole === "" && modelMayHaveRoles && get(0)) {
|
||||||
|
// No text role set, check whether model has a suitable role
|
||||||
|
// If 'text' is found, or there's only one role, pick that.
|
||||||
|
var listElement = get(0)
|
||||||
|
var roleName = ""
|
||||||
|
var roleCount = 0
|
||||||
|
for (var role in listElement) {
|
||||||
|
if (listElement[role].constructor === Function)
|
||||||
|
continue;
|
||||||
|
if (role === "text") {
|
||||||
|
roleName = role
|
||||||
|
break
|
||||||
|
} else if (!roleName) {
|
||||||
|
roleName = role
|
||||||
|
}
|
||||||
|
++roleCount
|
||||||
|
}
|
||||||
|
if (roleCount > 1 && roleName !== "text") {
|
||||||
|
console.warn("No suitable 'textRole' found for ComboBox.")
|
||||||
|
} else {
|
||||||
|
textRole = roleName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!popupItems.active)
|
||||||
|
popupItems.active = true
|
||||||
|
else
|
||||||
|
updateSelectedText()
|
||||||
|
}
|
||||||
|
|
||||||
|
function show() {
|
||||||
|
if (items[__selectedIndex])
|
||||||
|
items[__selectedIndex].checked = true
|
||||||
|
__currentIndex = comboBox.currentIndex
|
||||||
|
if (Qt.application.layoutDirection === Qt.RightToLeft)
|
||||||
|
__popup(comboBox.width, y, isPopup ? __selectedIndex : 0)
|
||||||
|
else
|
||||||
|
__popup(0, y, isPopup ? __selectedIndex : 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelectedText() {
|
||||||
|
var selectedItem;
|
||||||
|
if (__selectedIndex !== -1 && (selectedItem = items[__selectedIndex]))
|
||||||
|
selectedText = selectedItem.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The key bindings below will only be in use when popup is
|
||||||
|
// not visible. Otherwise, native popup key handling will take place:
|
||||||
|
Keys.onSpacePressed: {
|
||||||
|
if (!popup.popupVisible)
|
||||||
|
popup.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onUpPressed: {
|
||||||
|
input.blockUpdate = true
|
||||||
|
if (currentIndex > 0) {
|
||||||
|
currentIndex--;
|
||||||
|
input.text = popup.currentText;
|
||||||
|
activated(currentIndex);
|
||||||
|
}
|
||||||
|
input.blockUpdate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onDownPressed: {
|
||||||
|
input.blockUpdate = true;
|
||||||
|
if (currentIndex < popupItems.count - 1) {
|
||||||
|
currentIndex++;
|
||||||
|
input.text = popup.currentText;
|
||||||
|
activated(currentIndex);
|
||||||
|
}
|
||||||
|
input.blockUpdate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype GroupBox
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup controls
|
||||||
|
\brief GroupBox provides a group box frame with a title.
|
||||||
|
|
||||||
|
A group box provides a frame, a title on top and displays various other controls inside itself. Group boxes can also be checkable.
|
||||||
|
|
||||||
|
Child controls in checkable group boxes are enabled or disabled depending on whether or not the group box is checked.
|
||||||
|
|
||||||
|
You can minimize the space consumption of a group box by enabling the flat property.
|
||||||
|
In most styles, enabling this property results in the removal of the left, right and bottom edges of the frame.
|
||||||
|
|
||||||
|
To add content to a group box, you can reparent it to its contentItem property.
|
||||||
|
|
||||||
|
The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
|
||||||
|
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
|
||||||
|
|
||||||
|
The following example shows how we use a GroupBox with a column:
|
||||||
|
|
||||||
|
\qml
|
||||||
|
GroupBox {
|
||||||
|
title: qsTr("Package selection")
|
||||||
|
Column {
|
||||||
|
spacing: 2
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Update system")
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Update applications")
|
||||||
|
}
|
||||||
|
CheckBox {
|
||||||
|
text: qsTr("Update documentation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
\sa CheckBox, RadioButton, Layout
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: groupbox
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds the group box title text.
|
||||||
|
|
||||||
|
There is no default title text.
|
||||||
|
*/
|
||||||
|
property string title
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds whether the group box is painted flat or has a frame.
|
||||||
|
|
||||||
|
A group box usually consists of a surrounding frame with a title at the top.
|
||||||
|
If this property is enabled, only the top part of the frame is drawn in most styles;
|
||||||
|
otherwise, the whole frame is drawn.
|
||||||
|
|
||||||
|
By default, this property is disabled, so group boxes are not flat unless explicitly specified.
|
||||||
|
|
||||||
|
\note In some styles, flat and non-flat group boxes have similar representations and may not be as
|
||||||
|
distinguishable as they are in other styles.
|
||||||
|
*/
|
||||||
|
property bool flat: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds whether the group box has a checkbox in its title.
|
||||||
|
|
||||||
|
If this property is true, the group box displays its title using a checkbox in place of an ordinary label.
|
||||||
|
If the checkbox is checked, the group box's children are enabled; otherwise, they are disabled and inaccessible.
|
||||||
|
|
||||||
|
By default, group boxes are not checkable.
|
||||||
|
*/
|
||||||
|
property bool checkable: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty bool GroupBox::checked
|
||||||
|
|
||||||
|
This property holds whether the group box is checked.
|
||||||
|
|
||||||
|
If the group box is checkable, it is displayed with a check box. If the check box is checked, the group
|
||||||
|
box's children are enabled; otherwise, the children are disabled and are inaccessible to the user.
|
||||||
|
|
||||||
|
By default, checkable group boxes are also checked.
|
||||||
|
*/
|
||||||
|
property alias checked: check.checked
|
||||||
|
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
default property alias __content: container.data
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty Item GroupBox::contentItem
|
||||||
|
|
||||||
|
This property holds the content Item of the group box.
|
||||||
|
|
||||||
|
Items declared as children of a GroupBox are automatically parented to the GroupBox's contentItem.
|
||||||
|
Items created dynamically need to be explicitly parented to the contentItem:
|
||||||
|
|
||||||
|
\note The implicit size of the GroupBox is calculated based on the size of its content. If you want to anchor
|
||||||
|
items inside the group box, you must specify an explicit width and height on the GroupBox itself.
|
||||||
|
*/
|
||||||
|
readonly property alias contentItem: container
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Component style: Qt.createComponent(Settings.style + "/GroupBoxStyle.qml", groupbox)
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property alias __checkbox: check
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property alias __style: styleLoader.item
|
||||||
|
|
||||||
|
implicitWidth: Math.max((!anchors.fill ? container.calcWidth() : 0) + loader.leftMargin + loader.rightMargin,
|
||||||
|
sizeHint.implicitWidth + (checkable ? 24 : 6))
|
||||||
|
implicitHeight: (!anchors.fill ? container.calcHeight() : 0) + loader.topMargin + loader.bottomMargin
|
||||||
|
|
||||||
|
Layout.minimumWidth: implicitWidth
|
||||||
|
Layout.minimumHeight: implicitHeight
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Grouping
|
||||||
|
Accessible.name: title
|
||||||
|
|
||||||
|
activeFocusOnTab: false
|
||||||
|
|
||||||
|
|
||||||
|
data: [
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
anchors.fill: parent
|
||||||
|
property int topMargin: __style ? __style.padding.top : 0
|
||||||
|
property int bottomMargin: __style ? __style.padding.bottom : 0
|
||||||
|
property int leftMargin: __style ? __style.padding.left : 0
|
||||||
|
property int rightMargin: __style ? __style.padding.right : 0
|
||||||
|
sourceComponent: styleLoader.item ? styleLoader.item.panel : null
|
||||||
|
onLoaded: item.z = -1
|
||||||
|
Text { id: sizeHint ; visible: false ; text: title }
|
||||||
|
Loader {
|
||||||
|
id: styleLoader
|
||||||
|
property alias __control: groupbox
|
||||||
|
sourceComponent: groupbox.style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
CheckBox {
|
||||||
|
id: check
|
||||||
|
objectName: "check"
|
||||||
|
checked: true
|
||||||
|
text: groupbox.title
|
||||||
|
visible: checkable
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: loader.topMargin
|
||||||
|
activeFocusOnTab: groupbox.checkable
|
||||||
|
style: CheckBoxStyle { panel: Item{} }
|
||||||
|
},
|
||||||
|
Item {
|
||||||
|
id: container
|
||||||
|
objectName: "container"
|
||||||
|
z: 1
|
||||||
|
focus: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
anchors.topMargin: loader.topMargin
|
||||||
|
anchors.leftMargin: loader.leftMargin
|
||||||
|
anchors.rightMargin: loader.rightMargin
|
||||||
|
anchors.bottomMargin: loader.bottomMargin
|
||||||
|
enabled: (!groupbox.checkable || groupbox.checked)
|
||||||
|
|
||||||
|
property Item layoutItem: container.children.length === 1 ? container.children[0] : null
|
||||||
|
function calcWidth () { return (layoutItem ? (layoutItem.implicitWidth || layoutItem.width) +
|
||||||
|
(layoutItem.anchors.fill ? layoutItem.anchors.leftMargin +
|
||||||
|
layoutItem.anchors.rightMargin : 0) : container.childrenRect.width) }
|
||||||
|
function calcHeight () { return (layoutItem ? (layoutItem.implicitHeight || layoutItem.height) +
|
||||||
|
(layoutItem.anchors.fill ? layoutItem.anchors.topMargin +
|
||||||
|
layoutItem.anchors.bottomMargin : 0) : container.childrenRect.height) }
|
||||||
|
}]
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Label
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup controls
|
||||||
|
\brief A text label.
|
||||||
|
|
||||||
|
In addition to the normal \l Text element, Label follows the font and
|
||||||
|
color scheme of the system.
|
||||||
|
Use the \c text property to assign a text to the label. For other properties
|
||||||
|
check \l Text.
|
||||||
|
|
||||||
|
A simple label looks like this:
|
||||||
|
\qml
|
||||||
|
Label {
|
||||||
|
text: "Hello world"
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
You can use the properties of \l Text to change the appearance
|
||||||
|
of the text as desired:
|
||||||
|
\qml
|
||||||
|
Label {
|
||||||
|
text: "Hello world"
|
||||||
|
font.pixelSize: 22
|
||||||
|
font.italic: true
|
||||||
|
color: "steelblue"
|
||||||
|
}
|
||||||
|
\endqml
|
||||||
|
|
||||||
|
\sa Text, TextField, TextEdit
|
||||||
|
*/
|
||||||
|
|
||||||
|
Text {
|
||||||
|
/*!
|
||||||
|
\qmlproperty string Label::text
|
||||||
|
|
||||||
|
The text to display. Use this property to get and set it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
id: label
|
||||||
|
color: pal.text
|
||||||
|
activeFocusOnTab: false
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
SystemPalette {
|
||||||
|
id: pal
|
||||||
|
colorGroup: enabled ? SystemPalette.Active : SystemPalette.Disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Menu
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup menus
|
||||||
|
\brief Provides a menu component for use in menu bars, as context menu,
|
||||||
|
and other popup menus.
|
||||||
|
|
||||||
|
\code
|
||||||
|
Menu {
|
||||||
|
title: "Edit"
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Cut"
|
||||||
|
shortcut: "Ctrl+X"
|
||||||
|
onTriggered: ...
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Copy"
|
||||||
|
shortcut: "Ctrl+C"
|
||||||
|
onTriggered: ...
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Paste"
|
||||||
|
shortcut: "Ctrl+V"
|
||||||
|
onTriggered: ...
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuSeparator { }
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "More Stuff"
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Do Nothing"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
The main uses for menus:
|
||||||
|
\list
|
||||||
|
\li
|
||||||
|
as a \e top-level menu in a \l MenuBar
|
||||||
|
\li
|
||||||
|
as a \e submenu inside another menu
|
||||||
|
\li
|
||||||
|
as a standalone or \e context menu
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
Note that some properties, such as \c enabled, \c text, or \c iconSource,
|
||||||
|
only make sense in a particular use case of the menu.
|
||||||
|
|
||||||
|
\sa MenuBar, MenuItem, MenuSeparator
|
||||||
|
*/
|
||||||
|
|
||||||
|
MenuPrivate {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/*! \internal
|
||||||
|
\omit
|
||||||
|
Documented in qqquickmenu.cpp.
|
||||||
|
\endomit
|
||||||
|
*/
|
||||||
|
function addMenu(title) {
|
||||||
|
return root.insertMenu(items.length, title)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal
|
||||||
|
\omit
|
||||||
|
Documented in qquickmenu.cpp.
|
||||||
|
\endomit
|
||||||
|
*/
|
||||||
|
function insertMenu(index, title) {
|
||||||
|
if (!__selfComponent)
|
||||||
|
__selfComponent = Qt.createComponent("Menu.qml", root)
|
||||||
|
var submenu = __selfComponent.createObject(__selfComponent, { "title": title })
|
||||||
|
root.insertItem(index, submenu)
|
||||||
|
return submenu
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Component __selfComponent: null
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Component style: Qt.createComponent(Settings.style + "/MenuStyle.qml", root)
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var __parentContentItem: __parentMenu.__contentItem
|
||||||
|
/*! \internal */
|
||||||
|
property int __currentIndex: -1
|
||||||
|
/*! \internal */
|
||||||
|
on__MenuClosed: __currentIndex = -1
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
__contentItem: Loader {
|
||||||
|
sourceComponent: MenuContentItem {
|
||||||
|
menu: root
|
||||||
|
}
|
||||||
|
active: !root.__isNative && root.__popupVisible
|
||||||
|
focus: true
|
||||||
|
Keys.forwardTo: item ? [item, root.__parentContentItem] : []
|
||||||
|
property bool altPressed: root.__parentContentItem ? root.__parentContentItem.altPressed : false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype MenuBar
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\since 5.1
|
||||||
|
\ingroup applicationwindow
|
||||||
|
\brief Provides a horizontal menu bar.
|
||||||
|
|
||||||
|
\code
|
||||||
|
MenuBar {
|
||||||
|
Menu {
|
||||||
|
title: "File"
|
||||||
|
MenuItem { text: "Open..." }
|
||||||
|
MenuItem { text: "Close" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "Edit"
|
||||||
|
MenuItem { text: "Cut" }
|
||||||
|
MenuItem { text: "Copy" }
|
||||||
|
MenuItem { text: "Paste" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\endcode
|
||||||
|
|
||||||
|
\sa ApplicationWindow::menuBar
|
||||||
|
*/
|
||||||
|
|
||||||
|
MenuBarPrivate {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Component style: Qt.createComponent(Settings.style + "/MenuBarStyle.qml", root)
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
__contentItem: Loader {
|
||||||
|
id: topLoader
|
||||||
|
sourceComponent: __menuBarComponent
|
||||||
|
active: !root.__isNative
|
||||||
|
focus: true
|
||||||
|
Keys.forwardTo: [item]
|
||||||
|
property bool altPressed: item ? item.altPressed : false
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Component __menuBarComponent: Loader {
|
||||||
|
id: menuBarLoader
|
||||||
|
|
||||||
|
property Style __style: styleLoader.item
|
||||||
|
property Component menuItemStyle: __style ? __style.menuItem : null
|
||||||
|
|
||||||
|
property var control: root
|
||||||
|
onStatusChanged: if (status === Loader.Error) console.error("Failed to load panel for", root)
|
||||||
|
|
||||||
|
visible: status === Loader.Ready
|
||||||
|
sourceComponent: __style ? __style.frame : undefined
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: styleLoader
|
||||||
|
property alias __control: menuBarLoader
|
||||||
|
sourceComponent: root.style
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Loader.Error)
|
||||||
|
console.error("Failed to load Style for", root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property int openedMenuIndex: -1
|
||||||
|
property bool preselectMenuItem: false
|
||||||
|
property alias contentHeight: row.height
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
// Make sure the styled menu bar is in the background
|
||||||
|
target: menuBarLoader.item
|
||||||
|
property: "z"
|
||||||
|
value: menuMouseArea.z - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
property bool altPressed: false
|
||||||
|
property bool altPressedAgain: false
|
||||||
|
property var mnemonicsMap: ({})
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
var action = null
|
||||||
|
if (event.key === Qt.Key_Alt) {
|
||||||
|
if (!altPressed)
|
||||||
|
altPressed = true
|
||||||
|
else
|
||||||
|
altPressedAgain = true
|
||||||
|
} else if (altPressed && (action = mnemonicsMap[event.text.toUpperCase()])) {
|
||||||
|
preselectMenuItem = true
|
||||||
|
action.trigger()
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismissActiveFocus(event, reason) {
|
||||||
|
if (reason) {
|
||||||
|
altPressedAgain = false
|
||||||
|
altPressed = false
|
||||||
|
openedMenuIndex = -1
|
||||||
|
root.__contentItem.parent.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
event.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReleased: dismissActiveFocus(event, altPressedAgain && openedMenuIndex === -1)
|
||||||
|
Keys.onEscapePressed: dismissActiveFocus(event, openedMenuIndex === -1)
|
||||||
|
|
||||||
|
function maybeOpenFirstMenu(event) {
|
||||||
|
if (altPressed && openedMenuIndex === -1) {
|
||||||
|
preselectMenuItem = true
|
||||||
|
openedMenuIndex = 0
|
||||||
|
} else {
|
||||||
|
event.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onUpPressed: maybeOpenFirstMenu(event)
|
||||||
|
Keys.onDownPressed: maybeOpenFirstMenu(event)
|
||||||
|
|
||||||
|
Keys.onLeftPressed: {
|
||||||
|
if (openedMenuIndex > 0) {
|
||||||
|
preselectMenuItem = true
|
||||||
|
openedMenuIndex--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onRightPressed: {
|
||||||
|
if (openedMenuIndex !== -1 && openedMenuIndex < root.menus.length - 1) {
|
||||||
|
preselectMenuItem = true
|
||||||
|
openedMenuIndex++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: menuMouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onPositionChanged: updateCurrentItem(mouse, false)
|
||||||
|
onPressed: {
|
||||||
|
if (updateCurrentItem(mouse)) {
|
||||||
|
menuBarLoader.preselectMenuItem = false
|
||||||
|
menuBarLoader.openedMenuIndex = currentItem.menuItemIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: hoveredItem = null
|
||||||
|
|
||||||
|
property Item currentItem: null
|
||||||
|
property Item hoveredItem: null
|
||||||
|
function updateCurrentItem(mouse) {
|
||||||
|
var pos = mapToItem(row, mouse.x, mouse.y)
|
||||||
|
if (!hoveredItem || !hoveredItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
|
||||||
|
hoveredItem = row.childAt(pos.x, pos.y)
|
||||||
|
if (!hoveredItem)
|
||||||
|
return false;
|
||||||
|
currentItem = hoveredItem
|
||||||
|
if (menuBarLoader.openedMenuIndex !== -1) {
|
||||||
|
menuBarLoader.preselectMenuItem = false
|
||||||
|
menuBarLoader.openedMenuIndex = currentItem.menuItemIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: row
|
||||||
|
width: parent.width
|
||||||
|
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: itemsRepeater
|
||||||
|
model: root.menus
|
||||||
|
Loader {
|
||||||
|
id: menuItemLoader
|
||||||
|
|
||||||
|
property var menuItem: modelData
|
||||||
|
property bool selected: menuMouseArea.hoveredItem === menuItemLoader
|
||||||
|
property bool sunken: menuItem.__popupVisible || menuBarLoader.openedMenuIndex === index
|
||||||
|
property bool showUnderlined: menuBarLoader.altPressed
|
||||||
|
|
||||||
|
sourceComponent: menuBarLoader.menuItemStyle
|
||||||
|
property int menuItemIndex: index
|
||||||
|
visible: menuItem.visible
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: menuBarLoader
|
||||||
|
onOpenedMenuIndexChanged: {
|
||||||
|
if (menuBarLoader.openedMenuIndex === index) {
|
||||||
|
if (row.LayoutMirroring.enabled)
|
||||||
|
menuItem.__popup(menuItemLoader.width, menuBarLoader.height, 0)
|
||||||
|
else
|
||||||
|
menuItem.__popup(0, menuBarLoader.height, 0)
|
||||||
|
if (menuBarLoader.preselectMenuItem)
|
||||||
|
menuItem.__currentIndex = 0
|
||||||
|
} else {
|
||||||
|
menuItem.__closeMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: menuItem
|
||||||
|
onPopupVisibleChanged: {
|
||||||
|
if (!menuItem.__popupVisible && menuBarLoader.openedMenuIndex === index)
|
||||||
|
menuBarLoader.openedMenuIndex = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: menuItem.__action
|
||||||
|
onTriggered: menuBarLoader.openedMenuIndex = menuItemIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
menuItem.__visualItem = menuItemLoader
|
||||||
|
|
||||||
|
var title = menuItem.title
|
||||||
|
var ampersandPos = title.indexOf("&")
|
||||||
|
if (ampersandPos !== -1)
|
||||||
|
menuBarLoader.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItem.__action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype AbstractCheckable
|
||||||
|
\inqmlmodule QtQuick.Controls
|
||||||
|
\ingroup controls
|
||||||
|
\brief An abstract representation of a checkable control with a label
|
||||||
|
\qmlabstract
|
||||||
|
\internal
|
||||||
|
|
||||||
|
A checkable control is one that has two states: checked (on) and
|
||||||
|
unchecked (off). AbstractCheckable encapsulates the basic behavior and
|
||||||
|
states that are required by checkable controls.
|
||||||
|
|
||||||
|
Examples of checkable controls are RadioButton and
|
||||||
|
CheckBox. CheckBox extends AbstractCheckable's behavior by adding a third
|
||||||
|
state: partially checked.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: abstractCheckable
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Emitted whenever the control is clicked.
|
||||||
|
*/
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmlproperty bool AbstractCheckable::pressed
|
||||||
|
|
||||||
|
This property is \c true if the control is being pressed.
|
||||||
|
Set this property to manually invoke a mouse click.
|
||||||
|
*/
|
||||||
|
property alias pressed: mouseArea.effectivePressed
|
||||||
|
|
||||||
|
/*! \qmlproperty bool AbstractCheckcable::hovered
|
||||||
|
|
||||||
|
This property indicates whether the control is being hovered.
|
||||||
|
*/
|
||||||
|
readonly property alias hovered: mouseArea.containsMouse
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property is \c true if the control is checked.
|
||||||
|
*/
|
||||||
|
property bool checked: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property is \c true if the control takes the focus when it is
|
||||||
|
pressed; \l{QQuickItem::forceActiveFocus()}{forceActiveFocus()} will be
|
||||||
|
called on the control.
|
||||||
|
*/
|
||||||
|
property bool activeFocusOnPress: false
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property stores the ExclusiveGroup that the control belongs to.
|
||||||
|
*/
|
||||||
|
property ExclusiveGroup exclusiveGroup: null
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This property holds the text that the label should display.
|
||||||
|
*/
|
||||||
|
property string text
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var __cycleStatesHandler: cycleRadioButtonStates
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
focus: true
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
enabled: !keyPressed
|
||||||
|
|
||||||
|
property bool keyPressed: false
|
||||||
|
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||||
|
|
||||||
|
onClicked: abstractCheckable.clicked();
|
||||||
|
|
||||||
|
onPressed: if (activeFocusOnPress) forceActiveFocus();
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (containsMouse && (!exclusiveGroup || !checked))
|
||||||
|
__cycleStatesHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
onExclusiveGroupChanged: {
|
||||||
|
if (exclusiveGroup)
|
||||||
|
exclusiveGroup.bindCheckable(abstractCheckable)
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !mouseArea.pressed)
|
||||||
|
mouseArea.keyPressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReleased: {
|
||||||
|
if (event.key === Qt.Key_Space && !event.isAutoRepeat && mouseArea.keyPressed) {
|
||||||
|
mouseArea.keyPressed = false;
|
||||||
|
if (!exclusiveGroup || !checked)
|
||||||
|
__cycleStatesHandler();
|
||||||
|
clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype BasicButton
|
||||||
|
\internal
|
||||||
|
\qmlabstract
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: button
|
||||||
|
|
||||||
|
/*! This signal is emitted when the button is clicked. */
|
||||||
|
signal clicked
|
||||||
|
|
||||||
|
/*! \qmlproperty bool BasicButton::pressed
|
||||||
|
|
||||||
|
This property holds whether the button is being pressed. */
|
||||||
|
readonly property alias pressed: button.__effectivePressed
|
||||||
|
|
||||||
|
/*! \qmlproperty bool BasicButton::hovered
|
||||||
|
|
||||||
|
This property indicates whether the control is being hovered.
|
||||||
|
*/
|
||||||
|
readonly property alias hovered: behavior.containsMouse
|
||||||
|
|
||||||
|
/*! This property holds whether the button is checkable.
|
||||||
|
|
||||||
|
The default value is \c false. */
|
||||||
|
property bool checkable: false
|
||||||
|
|
||||||
|
/*! This property holds whether the button is checked.
|
||||||
|
|
||||||
|
Only checkable buttons can be checked.
|
||||||
|
|
||||||
|
The default value is \c false. */
|
||||||
|
property bool checked: false
|
||||||
|
|
||||||
|
/*! This property holds the ExclusiveGroup that the button belongs to.
|
||||||
|
|
||||||
|
The default value is \c null. */
|
||||||
|
property ExclusiveGroup exclusiveGroup: null
|
||||||
|
|
||||||
|
/*! This property holds the associated button action.
|
||||||
|
|
||||||
|
If a button has an action associated, the action defines the
|
||||||
|
button's properties like checked, text, tooltip etc.
|
||||||
|
|
||||||
|
When an action is set, it's still possible to override the \l text,
|
||||||
|
\l tooltip, \l iconSource, and \l iconName properties.
|
||||||
|
|
||||||
|
The default value is \c null. */
|
||||||
|
property Action action: null
|
||||||
|
|
||||||
|
/*! This property specifies whether the button should gain active focus when pressed.
|
||||||
|
|
||||||
|
The default value is \c false. */
|
||||||
|
property bool activeFocusOnPress: false
|
||||||
|
|
||||||
|
/*! This property holds the text shown on the button. If the button has no
|
||||||
|
text, the \l text property will be an empty string.
|
||||||
|
|
||||||
|
The default value is the empty string.
|
||||||
|
*/
|
||||||
|
property string text: action ? action.text : ""
|
||||||
|
|
||||||
|
/*! This property holds the button tooltip. */
|
||||||
|
property string tooltip: action ? (action.tooltip || StyleHelpers.removeMnemonics(action.text)) : ""
|
||||||
|
|
||||||
|
/*! This property holds the icon shown on the button. If the button has no
|
||||||
|
icon, the iconSource property will be an empty string.
|
||||||
|
|
||||||
|
The default value is the empty string.
|
||||||
|
*/
|
||||||
|
property url iconSource: action ? action.iconSource : ""
|
||||||
|
|
||||||
|
/*! The image label source as theme name.
|
||||||
|
When an icon from the platform icon theme is found, this takes
|
||||||
|
precedence over iconSource.
|
||||||
|
*/
|
||||||
|
property string iconName: action ? action.iconName : ""
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property color __textColor: syspal.text
|
||||||
|
/*! \internal */
|
||||||
|
property string __position: "only"
|
||||||
|
/*! \internal */
|
||||||
|
readonly property bool __iconOverriden: button.action && (button.action.iconSource !== button.iconSource || button.action.iconName !== button.iconName)
|
||||||
|
/*! \internal */
|
||||||
|
property Action __action: action || ownAction
|
||||||
|
/*! \internal */
|
||||||
|
readonly property Action __iconAction: __iconOverriden ? ownAction : __action
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
onExclusiveGroupChanged: {
|
||||||
|
if (exclusiveGroup)
|
||||||
|
exclusiveGroup.bindCheckable(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible.role: Accessible.Button
|
||||||
|
Accessible.description: tooltip
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
function accessiblePressAction() {
|
||||||
|
__action.trigger(button)
|
||||||
|
}
|
||||||
|
|
||||||
|
Action {
|
||||||
|
id: ownAction
|
||||||
|
iconSource: !button.action || __iconOverriden ? button.iconSource : ""
|
||||||
|
iconName: !button.action || __iconOverriden ? button.iconName : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: __action
|
||||||
|
onTriggered: button.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
if (event.key === Qt.Key_Space && !event.isAutoRepeat && !behavior.pressed)
|
||||||
|
behavior.keyPressed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusChanged: if (!focus) behavior.keyPressed = false
|
||||||
|
|
||||||
|
Keys.onReleased: {
|
||||||
|
if (event.key === Qt.Key_Space && !event.isAutoRepeat && behavior.keyPressed) {
|
||||||
|
behavior.keyPressed = false;
|
||||||
|
__action.trigger(button)
|
||||||
|
behavior.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: behavior
|
||||||
|
property bool keyPressed: false
|
||||||
|
property bool effectivePressed: pressed && containsMouse || keyPressed
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
enabled: !keyPressed
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (button.checkable && !button.action && !(button.checked && button.exclusiveGroup))
|
||||||
|
button.checked = !button.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
if (containsMouse) {
|
||||||
|
toggle()
|
||||||
|
__action.trigger(button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited: Tooltip.hideText()
|
||||||
|
onCanceled: Tooltip.hideText()
|
||||||
|
onPressed: {
|
||||||
|
if (activeFocusOnPress)
|
||||||
|
button.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1000
|
||||||
|
running: behavior.containsMouse && !pressed && tooltip.length
|
||||||
|
onTriggered: Tooltip.showText(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var __behavior: behavior
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property bool __effectivePressed: behavior.effectivePressed
|
||||||
|
|
||||||
|
SystemPalette { id: syspal }
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "boundAction"
|
||||||
|
when: action !== null
|
||||||
|
PropertyChanges {
|
||||||
|
target: button
|
||||||
|
enabled: action.enabled
|
||||||
|
checkable: action.checkable
|
||||||
|
checked: action.checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
property Component menuItemDelegate
|
||||||
|
property Component scrollerStyle
|
||||||
|
property var itemsModel
|
||||||
|
property int minWidth: 100
|
||||||
|
property real maxHeight: 800
|
||||||
|
property int margin: 1
|
||||||
|
|
||||||
|
signal triggered(var item)
|
||||||
|
|
||||||
|
function menuItemAt(index) {
|
||||||
|
list.currentIndex = index
|
||||||
|
return list.currentItem
|
||||||
|
}
|
||||||
|
|
||||||
|
width: Math.max(list.contentWidth, minWidth)
|
||||||
|
height: Math.min(list.contentHeight, fittedMaxHeight) + 2 * margin
|
||||||
|
|
||||||
|
readonly property int currentIndex: menu.__currentIndex
|
||||||
|
property Item currentItem: null
|
||||||
|
readonly property int itemHeight: (list.count > 0 && list.contentItem.children[0]) ? list.contentItem.children[0].height : 23
|
||||||
|
readonly property int fittingItems: Math.floor((maxHeight - downScroller.height) / itemHeight)
|
||||||
|
readonly property real fittedMaxHeight: itemHeight * fittingItems + downScroller.height
|
||||||
|
readonly property bool shouldUseScrollers: scrollView.__style.useScrollers && itemsModel.length > fittingItems
|
||||||
|
readonly property real upScrollerHeight: upScroller.visible ? upScroller.height : 0
|
||||||
|
readonly property real downScrollerHeight: downScroller.visible ? downScroller.height : 0
|
||||||
|
|
||||||
|
function updateCurrentItem(mouse) {
|
||||||
|
var pos = mapToItem(list.contentItem, mouse.x, mouse.y)
|
||||||
|
if (!currentItem || !currentItem.contains(Qt.point(pos.x - currentItem.x, pos.y - currentItem.y))) {
|
||||||
|
if (currentItem && !hoverArea.pressed && currentItem.isSubmenu)
|
||||||
|
currentItem.closeSubMenu()
|
||||||
|
currentItem = list.itemAt(pos.x, pos.y)
|
||||||
|
if (currentItem) {
|
||||||
|
menu.__currentIndex = currentItem.menuItemIndex
|
||||||
|
if (currentItem.isSubmenu && !currentItem.menuItem.__popupVisible)
|
||||||
|
currentItem.showSubMenu(false)
|
||||||
|
} else {
|
||||||
|
menu.__currentIndex = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollView {
|
||||||
|
id: scrollView
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
topMargin: content.margin + upScrollerHeight
|
||||||
|
bottomMargin: downScrollerHeight - content.margin - 1
|
||||||
|
rightMargin: -1
|
||||||
|
}
|
||||||
|
|
||||||
|
style: scrollerStyle
|
||||||
|
__wheelAreaScrollSpeed: itemHeight
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: list
|
||||||
|
model: itemsModel
|
||||||
|
delegate: menuItemDelegate
|
||||||
|
snapMode: ListView.SnapToItem
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
highlightFollowsCurrentItem: true
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: hoverArea
|
||||||
|
anchors.left: scrollView.left
|
||||||
|
width: scrollView.width - scrollView.__verticalScrollBar.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.AllButtons
|
||||||
|
|
||||||
|
onPositionChanged: updateCurrentItem(mouse)
|
||||||
|
onReleased: content.triggered(currentItem)
|
||||||
|
onExited: {
|
||||||
|
if (currentItem && !currentItem.menuItem.__popupVisible) {
|
||||||
|
currentItem = null
|
||||||
|
menu.__currentIndex = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuContentScroller {
|
||||||
|
id: upScroller
|
||||||
|
direction: "up"
|
||||||
|
visible: shouldUseScrollers && !list.atYBeginning
|
||||||
|
x: margin
|
||||||
|
function scrollABit() { list.contentY -= itemHeight }
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuContentScroller {
|
||||||
|
id: downScroller
|
||||||
|
direction: "down"
|
||||||
|
visible: shouldUseScrollers && !list.atYEnd
|
||||||
|
x: margin
|
||||||
|
function scrollABit() { list.contentY += itemHeight }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 1
|
||||||
|
running: true
|
||||||
|
repeat: false
|
||||||
|
onTriggered: list.positionViewAtIndex(currentIndex, scrollView.__style.useScrollers
|
||||||
|
? ListView.Center : ListView.Beginning)
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: scrollView.__verticalScrollBar
|
||||||
|
property: "singleStep"
|
||||||
|
value: itemHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Control
|
||||||
|
\internal
|
||||||
|
\qmlabstract
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
FocusScope {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/*! \qmlproperty Component Control::style
|
||||||
|
|
||||||
|
The style Component for this control.
|
||||||
|
\sa {Qt Quick Controls Styles QML Types}
|
||||||
|
|
||||||
|
*/
|
||||||
|
property Component style
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property QtObject __style: styleLoader.item
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property Item __panel: panelLoader.item
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var styleHints
|
||||||
|
|
||||||
|
implicitWidth: __panel ? __panel.implicitWidth: 0
|
||||||
|
implicitHeight: __panel ? __panel.implicitHeight: 0
|
||||||
|
baselineOffset: __panel ? __panel.baselineOffset: 0
|
||||||
|
activeFocusOnTab: false
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property alias __styleData: styleLoader.styleData
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: panelLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: __style ? __style.panel : null
|
||||||
|
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||||
|
Loader {
|
||||||
|
id: styleLoader
|
||||||
|
sourceComponent: style
|
||||||
|
property Item __control: root
|
||||||
|
property QtObject styleData: null
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Loader.Error)
|
||||||
|
console.error("Failed to load Style for", root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,393 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant source
|
||||||
|
property real spread: 0.0
|
||||||
|
property real blur: 0.0
|
||||||
|
property color color: "white"
|
||||||
|
property bool transparentBorder: false
|
||||||
|
property bool cached: false
|
||||||
|
|
||||||
|
SourceProxy {
|
||||||
|
id: sourceProxy
|
||||||
|
input: rootItem.source
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: cacheItem
|
||||||
|
anchors.fill: shaderItem
|
||||||
|
visible: rootItem.cached
|
||||||
|
smooth: true
|
||||||
|
sourceItem: shaderItem
|
||||||
|
live: true
|
||||||
|
hideSource: visible
|
||||||
|
}
|
||||||
|
|
||||||
|
property string __internalBlurVertexShader: "
|
||||||
|
attribute highp vec4 qt_Vertex;
|
||||||
|
attribute highp vec2 qt_MultiTexCoord0;
|
||||||
|
uniform highp mat4 qt_Matrix;
|
||||||
|
uniform highp float yStep;
|
||||||
|
uniform highp float xStep;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
qt_TexCoord0 = vec2(qt_MultiTexCoord0.x + xStep, qt_MultiTexCoord0.y + yStep * 0.36);
|
||||||
|
qt_TexCoord1 = vec2(qt_MultiTexCoord0.x + xStep * 0.36, qt_MultiTexCoord0.y - yStep);
|
||||||
|
qt_TexCoord2 = vec2(qt_MultiTexCoord0.x - xStep * 0.36, qt_MultiTexCoord0.y + yStep);
|
||||||
|
qt_TexCoord3 = vec2(qt_MultiTexCoord0.x - xStep, qt_MultiTexCoord0.y - yStep * 0.36);
|
||||||
|
gl_Position = qt_Matrix * qt_Vertex;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
property string __internalBlurFragmentShader: "
|
||||||
|
uniform lowp sampler2D source;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying highp vec2 qt_TexCoord0;
|
||||||
|
varying highp vec2 qt_TexCoord1;
|
||||||
|
varying highp vec2 qt_TexCoord2;
|
||||||
|
varying highp vec2 qt_TexCoord3;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
highp vec4 sourceColor = (texture2D(source, qt_TexCoord0) +
|
||||||
|
texture2D(source, qt_TexCoord1) +
|
||||||
|
texture2D(source, qt_TexCoord2) +
|
||||||
|
texture2D(source, qt_TexCoord3)) * 0.25;
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: level0
|
||||||
|
property variant source: sourceProxy.output
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level1
|
||||||
|
width: Math.ceil(shaderItem.width / 32) * 32
|
||||||
|
height: Math.ceil(shaderItem.height / 32) * 32
|
||||||
|
sourceItem: level0
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
sourceRect: transparentBorder ? Qt.rect(-64, -64, shaderItem.width, shaderItem.height) : Qt.rect(0,0,0,0)
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect1
|
||||||
|
property variant source: level1
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level2
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level2
|
||||||
|
width: level1.width / 2
|
||||||
|
height: level1.height / 2
|
||||||
|
sourceItem: effect1
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect2
|
||||||
|
property variant source: level2
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level3
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level3
|
||||||
|
width: level2.width / 2
|
||||||
|
height: level2.height / 2
|
||||||
|
sourceItem: effect2
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect3
|
||||||
|
property variant source: level3
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level4
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level4
|
||||||
|
width: level3.width / 2
|
||||||
|
height: level3.height / 2
|
||||||
|
sourceItem: effect3
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect4
|
||||||
|
property variant source: level4
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level5
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level5
|
||||||
|
width: level4.width / 2
|
||||||
|
height: level4.height / 2
|
||||||
|
sourceItem: effect4
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: effect5
|
||||||
|
property variant source: level5
|
||||||
|
property real yStep: 1/height
|
||||||
|
property real xStep: 1/width
|
||||||
|
anchors.fill: level6
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
vertexShader: __internalBlurVertexShader
|
||||||
|
fragmentShader: __internalBlurFragmentShader
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: level6
|
||||||
|
width: level5.width / 2
|
||||||
|
height: level5.height / 2
|
||||||
|
sourceItem: effect5
|
||||||
|
hideSource: rootItem.visible
|
||||||
|
visible: false
|
||||||
|
smooth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: dummysource
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: dummy
|
||||||
|
width: 1
|
||||||
|
height: 1
|
||||||
|
sourceItem: dummysource
|
||||||
|
visible: false
|
||||||
|
smooth: false
|
||||||
|
live: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffect {
|
||||||
|
id: shaderItem
|
||||||
|
x: transparentBorder ? -64 : 0
|
||||||
|
y: transparentBorder ? -64 : 0
|
||||||
|
width: transparentBorder ? parent.width + 128 : parent.width
|
||||||
|
height: transparentBorder ? parent.height + 128 : parent.height
|
||||||
|
|
||||||
|
property variant source1: level1
|
||||||
|
property variant source2: level2
|
||||||
|
property variant source3: level3
|
||||||
|
property variant source4: level4
|
||||||
|
property variant source5: level5
|
||||||
|
property variant source6: level6
|
||||||
|
property real lod: rootItem.blur
|
||||||
|
|
||||||
|
property real weight1;
|
||||||
|
property real weight2;
|
||||||
|
property real weight3;
|
||||||
|
property real weight4;
|
||||||
|
property real weight5;
|
||||||
|
property real weight6;
|
||||||
|
|
||||||
|
property real spread: 1.0 - (rootItem.spread * 0.98)
|
||||||
|
property alias color: rootItem.color
|
||||||
|
|
||||||
|
function weight(v) {
|
||||||
|
if (v <= 0.0)
|
||||||
|
return 1
|
||||||
|
if (v >= 0.5)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
return 1.0 - v / 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateWeights() {
|
||||||
|
|
||||||
|
var w1 = weight(Math.abs(lod - 0.100))
|
||||||
|
var w2 = weight(Math.abs(lod - 0.300))
|
||||||
|
var w3 = weight(Math.abs(lod - 0.500))
|
||||||
|
var w4 = weight(Math.abs(lod - 0.700))
|
||||||
|
var w5 = weight(Math.abs(lod - 0.900))
|
||||||
|
var w6 = weight(Math.abs(lod - 1.100))
|
||||||
|
|
||||||
|
var sum = w1 + w2 + w3 + w4 + w5 + w6;
|
||||||
|
weight1 = w1 / sum;
|
||||||
|
weight2 = w2 / sum;
|
||||||
|
weight3 = w3 / sum;
|
||||||
|
weight4 = w4 / sum;
|
||||||
|
weight5 = w5 / sum;
|
||||||
|
weight6 = w6 / sum;
|
||||||
|
|
||||||
|
upateSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function upateSources() {
|
||||||
|
var sources = new Array();
|
||||||
|
var weights = new Array();
|
||||||
|
|
||||||
|
if (weight1 > 0) {
|
||||||
|
sources.push(level1)
|
||||||
|
weights.push(weight1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight2 > 0) {
|
||||||
|
sources.push(level2)
|
||||||
|
weights.push(weight2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight3 > 0) {
|
||||||
|
sources.push(level3)
|
||||||
|
weights.push(weight3)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight4 > 0) {
|
||||||
|
sources.push(level4)
|
||||||
|
weights.push(weight4)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight5 > 0) {
|
||||||
|
sources.push(level5)
|
||||||
|
weights.push(weight5)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weight6 > 0) {
|
||||||
|
sources.push(level6)
|
||||||
|
weights.push(weight6)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = sources.length; j < 6; j++) {
|
||||||
|
sources.push(dummy)
|
||||||
|
weights.push(0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
source1 = sources[0]
|
||||||
|
source2 = sources[1]
|
||||||
|
source3 = sources[2]
|
||||||
|
source4 = sources[3]
|
||||||
|
source5 = sources[4]
|
||||||
|
source6 = sources[5]
|
||||||
|
|
||||||
|
weight1 = weights[0]
|
||||||
|
weight2 = weights[1]
|
||||||
|
weight3 = weights[2]
|
||||||
|
weight4 = weights[3]
|
||||||
|
weight5 = weights[4]
|
||||||
|
weight6 = weights[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: calculateWeights()
|
||||||
|
|
||||||
|
onLodChanged: calculateWeights()
|
||||||
|
|
||||||
|
fragmentShader: "
|
||||||
|
uniform lowp sampler2D source1;
|
||||||
|
uniform lowp sampler2D source2;
|
||||||
|
uniform lowp sampler2D source3;
|
||||||
|
uniform lowp sampler2D source4;
|
||||||
|
uniform lowp sampler2D source5;
|
||||||
|
uniform mediump float weight1;
|
||||||
|
uniform mediump float weight2;
|
||||||
|
uniform mediump float weight3;
|
||||||
|
uniform mediump float weight4;
|
||||||
|
uniform mediump float weight5;
|
||||||
|
uniform highp vec4 color;
|
||||||
|
uniform highp float spread;
|
||||||
|
uniform lowp float qt_Opacity;
|
||||||
|
varying mediump vec2 qt_TexCoord0;
|
||||||
|
|
||||||
|
highp float linearstep(highp float e0, highp float e1, highp float x) {
|
||||||
|
return clamp((x - e0) / (e1 - e0), 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
lowp vec4 sourceColor = texture2D(source1, qt_TexCoord0) * weight1;
|
||||||
|
sourceColor += texture2D(source2, qt_TexCoord0) * weight2;
|
||||||
|
sourceColor += texture2D(source3, qt_TexCoord0) * weight3;
|
||||||
|
sourceColor += texture2D(source4, qt_TexCoord0) * weight4;
|
||||||
|
sourceColor += texture2D(source5, qt_TexCoord0) * weight5;
|
||||||
|
sourceColor = mix(vec4(0), color, linearstep(0.0, spread, sourceColor.a));
|
||||||
|
gl_FragColor = sourceColor * qt_Opacity;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype FocusFrame
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
activeFocusOnTab: false
|
||||||
|
Accessible.role: Accessible.StatusBar
|
||||||
|
|
||||||
|
anchors.topMargin: focusMargin
|
||||||
|
anchors.leftMargin: focusMargin
|
||||||
|
anchors.rightMargin: focusMargin
|
||||||
|
anchors.bottomMargin: focusMargin
|
||||||
|
|
||||||
|
property int focusMargin: loader.item ? loader.item.margin : -3
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: loader
|
||||||
|
z: 2
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: Qt.createComponent(Settings.style + "/FocusFrameStyle.qml", root)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: menuFrameLoader
|
||||||
|
|
||||||
|
readonly property Style __style: styleLoader.item
|
||||||
|
readonly property Component menuItemStyle: __style ? __style.menuItem : null
|
||||||
|
|
||||||
|
property var menu: root
|
||||||
|
property alias contentWidth: content.width
|
||||||
|
property alias contentHeight: content.height
|
||||||
|
|
||||||
|
readonly property int subMenuXPos: width + (item && item["subMenuOverlap"] || 0)
|
||||||
|
|
||||||
|
visible: status === Loader.Ready
|
||||||
|
sourceComponent: __style ? __style.frame : undefined
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: styleLoader
|
||||||
|
active: !menu.isNative
|
||||||
|
sourceComponent: menu.style
|
||||||
|
property alias __control: menuFrameLoader
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Loader.Error)
|
||||||
|
console.error("Failed to load Style for", menu)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
property var mnemonicsMap: ({})
|
||||||
|
|
||||||
|
Keys.onPressed: {
|
||||||
|
var item = null
|
||||||
|
if (!(event.modifiers & Qt.AltModifier)
|
||||||
|
&& (item = mnemonicsMap[event.text.toUpperCase()])) {
|
||||||
|
if (item.isSubmenu) {
|
||||||
|
menu.__currentIndex = item.menuItemIndex
|
||||||
|
item.showSubMenu(true)
|
||||||
|
item.menuItem.__currentIndex = 0
|
||||||
|
} else {
|
||||||
|
triggerAndDismiss(item)
|
||||||
|
}
|
||||||
|
event.accepted = true
|
||||||
|
} else {
|
||||||
|
event.accepted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEscapePressed: menu.__dismissMenu()
|
||||||
|
|
||||||
|
Keys.onDownPressed: {
|
||||||
|
if (menu.__currentIndex < 0)
|
||||||
|
menu.__currentIndex = -1
|
||||||
|
|
||||||
|
for (var i = menu.__currentIndex + 1;
|
||||||
|
i < menu.items.length && !canBeHovered(i); i++)
|
||||||
|
;
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onUpPressed: {
|
||||||
|
for (var i = menu.__currentIndex - 1;
|
||||||
|
i >= 0 && !canBeHovered(i); i--)
|
||||||
|
;
|
||||||
|
event.accepted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function canBeHovered(index) {
|
||||||
|
var item = content.menuItemAt(index)
|
||||||
|
if (item && !item["isSeparator"] && item.enabled) {
|
||||||
|
menu.__currentIndex = index
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onLeftPressed: {
|
||||||
|
if ((event.accepted = menu.__parentMenu.hasOwnProperty("title")))
|
||||||
|
__closeMenu()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onRightPressed: {
|
||||||
|
var item = content.menuItemAt(menu.__currentIndex)
|
||||||
|
if ((event.accepted = (item && item.isSubmenu))) {
|
||||||
|
item.showSubMenu(true)
|
||||||
|
item.menuItem.__currentIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onSpacePressed: triggerCurrent()
|
||||||
|
Keys.onReturnPressed: triggerCurrent()
|
||||||
|
Keys.onEnterPressed: triggerCurrent()
|
||||||
|
|
||||||
|
function triggerCurrent() {
|
||||||
|
var item = content.menuItemAt(menu.__currentIndex)
|
||||||
|
if (item)
|
||||||
|
content.triggered(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerAndDismiss(item) {
|
||||||
|
if (item && !item.isSeparator) {
|
||||||
|
menu.__dismissMenu()
|
||||||
|
if (!item.isSubmenu)
|
||||||
|
item.menuItem.trigger()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
// Make sure the styled frame is in the background
|
||||||
|
target: item
|
||||||
|
property: "z"
|
||||||
|
value: content.z - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnMenuContent {
|
||||||
|
id: content
|
||||||
|
menuItemDelegate: menuItemComponent
|
||||||
|
scrollerStyle: __style ? __style.scrollerStyle : undefined
|
||||||
|
itemsModel: menu.items
|
||||||
|
margin: menuFrameLoader.item ? menuFrameLoader.item.margin : 0
|
||||||
|
minWidth: menu.__minimumWidth
|
||||||
|
maxHeight: menuFrameLoader.item ? menuFrameLoader.item.maxHeight : 0
|
||||||
|
onTriggered: triggerAndDismiss(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: menuItemComponent
|
||||||
|
Loader {
|
||||||
|
id: menuItemLoader
|
||||||
|
|
||||||
|
property var menuItem: modelData
|
||||||
|
readonly property bool isSeparator: !!menuItem && menuItem.type === MenuItemType.Separator
|
||||||
|
readonly property bool isSubmenu: !!menuItem && menuItem.type === MenuItemType.Menu
|
||||||
|
property bool selected: !(isSeparator || !!scrollerDirection) && menu.__currentIndex === index
|
||||||
|
property string text: isSubmenu ? menuItem.title : !(isSeparator || !!scrollerDirection) ? menuItem.text : ""
|
||||||
|
property bool showUnderlined: menu.__contentItem.altPressed
|
||||||
|
readonly property var scrollerDirection: menuItem["scrollerDirection"]
|
||||||
|
|
||||||
|
property int menuItemIndex: index
|
||||||
|
|
||||||
|
sourceComponent: menuFrameLoader.menuItemStyle
|
||||||
|
enabled: visible && !isSeparator && !!menuItem && menuItem.enabled
|
||||||
|
visible: !!menuItem && menuItem.visible
|
||||||
|
active: visible
|
||||||
|
|
||||||
|
function showSubMenu(immediately) {
|
||||||
|
if (immediately) {
|
||||||
|
if (menu.__currentIndex === menuItemIndex)
|
||||||
|
menuItem.__popup(menuFrameLoader.subMenuXPos, 0, -1)
|
||||||
|
} else {
|
||||||
|
openMenuTimer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: openMenuTimer
|
||||||
|
interval: 50
|
||||||
|
onTriggered: menuItemLoader.showSubMenu(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSubMenu() { closeMenuTimer.start() }
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: closeMenuTimer
|
||||||
|
interval: 1
|
||||||
|
onTriggered: {
|
||||||
|
if (menu.__currentIndex !== menuItemIndex)
|
||||||
|
menuItem.__closeMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
menuItem.__visualItem = menuItemLoader
|
||||||
|
|
||||||
|
if (content.width < item.implicitWidth)
|
||||||
|
content.width = item.implicitWidth
|
||||||
|
|
||||||
|
var title = text
|
||||||
|
var ampersandPos = title.indexOf("&")
|
||||||
|
if (ampersandPos !== -1)
|
||||||
|
menuFrameLoader.mnemonicsMap[title[ampersandPos + 1].toUpperCase()] = menuItemLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: menuItemLoader.item
|
||||||
|
property: "width"
|
||||||
|
property alias menuItem: menuItemLoader.item
|
||||||
|
value: menuItem ? Math.max(menu.__minimumWidth, content.width) - 2 * menuItem.x : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
property string direction
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
top: direction === "up" ? parent.top : undefined
|
||||||
|
bottom: direction === "down" ? parent.bottom : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
hoverEnabled: visible
|
||||||
|
height: scrollerLoader.item.height
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: scrollerLoader
|
||||||
|
|
||||||
|
sourceComponent: menuItemDelegate
|
||||||
|
property int index: -1
|
||||||
|
property var modelData: {
|
||||||
|
"visible": true,
|
||||||
|
"scrollerDirection": direction,
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 100
|
||||||
|
repeat: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
running: parent.containsMouse
|
||||||
|
onTriggered: scrollABit()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
// KNOWN ISSUES
|
||||||
|
// none
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ModalPopupBehavior
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: popupBehavior
|
||||||
|
|
||||||
|
property bool showing: false
|
||||||
|
property bool whenAlso: true // modifier to the "showing" property
|
||||||
|
property bool consumeCancelClick: true
|
||||||
|
property int delay: 0 // delay before popout becomes visible
|
||||||
|
property int deallocationDelay: 3000 // 3 seconds
|
||||||
|
|
||||||
|
property Component popupComponent
|
||||||
|
|
||||||
|
property alias popup: popupLoader.item // read-only
|
||||||
|
property alias window: popupBehavior.root // read-only
|
||||||
|
|
||||||
|
signal prepareToShow
|
||||||
|
signal prepareToHide
|
||||||
|
signal cancelledByClick
|
||||||
|
|
||||||
|
// implementation
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onShowingChanged: notifyChange()
|
||||||
|
onWhenAlsoChanged: notifyChange()
|
||||||
|
function notifyChange() {
|
||||||
|
if(showing && whenAlso) {
|
||||||
|
if(popupLoader.sourceComponent == undefined) {
|
||||||
|
popupLoader.sourceComponent = popupComponent;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mouseArea.enabled = false; // disable before opacity is changed in case it has fading behavior
|
||||||
|
if(Qt.isQtObject(popupLoader.item)) {
|
||||||
|
popupBehavior.prepareToHide();
|
||||||
|
popupLoader.item.opacity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property Item root: findRoot()
|
||||||
|
function findRoot() {
|
||||||
|
var p = parent;
|
||||||
|
while(p.parent != undefined)
|
||||||
|
p = p.parent;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseArea
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: false // enabled only when popout is showing
|
||||||
|
onPressed: {
|
||||||
|
popupBehavior.showing = false;
|
||||||
|
mouse.accepted = consumeCancelClick;
|
||||||
|
cancelledByClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: popupLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer { // visibility timer
|
||||||
|
running: Qt.isQtObject(popupLoader.item) && showing && whenAlso
|
||||||
|
interval: delay
|
||||||
|
onTriggered: {
|
||||||
|
popupBehavior.prepareToShow();
|
||||||
|
mouseArea.enabled = true;
|
||||||
|
popup.opacity = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer { // deallocation timer
|
||||||
|
running: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity == 0
|
||||||
|
interval: deallocationDelay
|
||||||
|
onTriggered: popupLoader.sourceComponent = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "active"
|
||||||
|
when: Qt.isQtObject(popupLoader.item) && popupLoader.item.opacity > 0
|
||||||
|
ParentChange { target: popupBehavior; parent: root }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,234 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ScrollBar
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: scrollbar
|
||||||
|
|
||||||
|
property bool isTransient: false
|
||||||
|
property bool active: false
|
||||||
|
property int orientation: Qt.Horizontal
|
||||||
|
property alias minimumValue: slider.minimumValue
|
||||||
|
property alias maximumValue: slider.maximumValue
|
||||||
|
property alias value: slider.value
|
||||||
|
property int singleStep: 20
|
||||||
|
|
||||||
|
activeFocusOnTab: false
|
||||||
|
|
||||||
|
Accessible.role: Accessible.ScrollBar
|
||||||
|
implicitWidth: panelLoader.implicitWidth
|
||||||
|
implicitHeight: panelLoader.implicitHeight
|
||||||
|
|
||||||
|
property bool upPressed
|
||||||
|
property bool downPressed
|
||||||
|
property bool pageUpPressed
|
||||||
|
property bool pageDownPressed
|
||||||
|
property bool handlePressed
|
||||||
|
|
||||||
|
|
||||||
|
property Item __panel: panelLoader.item
|
||||||
|
Loader {
|
||||||
|
id: panelLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: __style ? __style.__scrollbar : null
|
||||||
|
onStatusChanged: if (status === Loader.Error) console.error("Failed to load Style for", root)
|
||||||
|
property alias __control: scrollbar
|
||||||
|
property QtObject __styleData: QtObject {
|
||||||
|
readonly property alias horizontal: internal.horizontal
|
||||||
|
readonly property alias upPressed: scrollbar.upPressed
|
||||||
|
readonly property alias downPressed: scrollbar.downPressed
|
||||||
|
readonly property alias handlePressed: scrollbar.handlePressed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: internal
|
||||||
|
property bool horizontal: orientation === Qt.Horizontal
|
||||||
|
property int pageStep: internal.horizontal ? width : height
|
||||||
|
property bool scrollToClickposition: internal.scrollToClickPosition
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: __panel.visible ? Qt.ArrowCursor : Qt.IBeamCursor // forces a cursor change
|
||||||
|
|
||||||
|
property bool autoincrement: false
|
||||||
|
property bool scrollToClickPosition: __style ? __style.scrollToClickedPosition : 0
|
||||||
|
|
||||||
|
// Update hover item
|
||||||
|
onEntered: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||||
|
onExited: if (!pressed) __panel.activeControl = "none"
|
||||||
|
onMouseXChanged: if (!pressed) __panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
property var pressedX
|
||||||
|
property var pressedY
|
||||||
|
property int oldPosition
|
||||||
|
property int grooveSize
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: upPressed || downPressed || pageUpPressed || pageDownPressed
|
||||||
|
interval: 350
|
||||||
|
onTriggered: internal.autoincrement = true
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
running: internal.autoincrement
|
||||||
|
interval: 60
|
||||||
|
repeat: true
|
||||||
|
onTriggered: {
|
||||||
|
if (upPressed && internal.containsMouse)
|
||||||
|
internal.decrement();
|
||||||
|
else if (downPressed && internal.containsMouse)
|
||||||
|
internal.increment();
|
||||||
|
else if (pageUpPressed)
|
||||||
|
internal.decrementPage();
|
||||||
|
else if (pageDownPressed)
|
||||||
|
internal.incrementPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
if (handlePressed) {
|
||||||
|
if (!horizontal)
|
||||||
|
slider.position = oldPosition + (mouseY - pressedY)
|
||||||
|
else
|
||||||
|
slider.position = oldPosition + (mouseX - pressedX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
__panel.activeControl = __panel.hitTest(mouseX, mouseY)
|
||||||
|
scrollToClickposition = scrollToClickPosition
|
||||||
|
var handleRect = __panel.subControlRect("handle")
|
||||||
|
var grooveRect = __panel.subControlRect("groove")
|
||||||
|
grooveSize = horizontal ? grooveRect.width - handleRect.width:
|
||||||
|
grooveRect.height - handleRect.height;
|
||||||
|
if (__panel.activeControl === "handle") {
|
||||||
|
pressedX = mouseX;
|
||||||
|
pressedY = mouseY;
|
||||||
|
handlePressed = true;
|
||||||
|
oldPosition = slider.position;
|
||||||
|
} else if (__panel.activeControl === "up") {
|
||||||
|
decrement();
|
||||||
|
upPressed = Qt.binding(function() {return containsMouse});
|
||||||
|
} else if (__panel.activeControl === "down") {
|
||||||
|
increment();
|
||||||
|
downPressed = Qt.binding(function() {return containsMouse});
|
||||||
|
} else if (!scrollToClickposition){
|
||||||
|
if (__panel.activeControl === "upPage") {
|
||||||
|
decrementPage();
|
||||||
|
pageUpPressed = true;
|
||||||
|
} else if (__panel.activeControl === "downPage") {
|
||||||
|
incrementPage();
|
||||||
|
pageDownPressed = true;
|
||||||
|
}
|
||||||
|
} else { // scroll to click position
|
||||||
|
slider.position = horizontal ? mouseX - handleRect.width/2 - grooveRect.x
|
||||||
|
: mouseY - handleRect.height/2 - grooveRect.y
|
||||||
|
pressedX = mouseX;
|
||||||
|
pressedY = mouseY;
|
||||||
|
handlePressed = true;
|
||||||
|
oldPosition = slider.position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
__panel.activeControl = __panel.hitTest(mouseX, mouseY);
|
||||||
|
autoincrement = false;
|
||||||
|
upPressed = false;
|
||||||
|
downPressed = false;
|
||||||
|
handlePressed = false;
|
||||||
|
pageUpPressed = false;
|
||||||
|
pageDownPressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onWheel: {
|
||||||
|
var stepCount = -(wheel.angleDelta.x ? wheel.angleDelta.x : wheel.angleDelta.y) / 120
|
||||||
|
if (stepCount != 0) {
|
||||||
|
if (wheel.modifiers & Qt.ControlModifier || wheel.modifiers & Qt.ShiftModifier)
|
||||||
|
incrementPage(stepCount)
|
||||||
|
else
|
||||||
|
increment(stepCount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementPage(stepCount) {
|
||||||
|
value = boundValue(value + getSteps(pageStep, stepCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrementPage(stepCount) {
|
||||||
|
value = boundValue(value - getSteps(pageStep, stepCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
function increment(stepCount) {
|
||||||
|
value = boundValue(value + getSteps(singleStep, stepCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
function decrement(stepCount) {
|
||||||
|
value = boundValue(value - getSteps(singleStep, stepCount))
|
||||||
|
}
|
||||||
|
|
||||||
|
function boundValue(val) {
|
||||||
|
return Math.min(Math.max(val, minimumValue), maximumValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSteps(step, count) {
|
||||||
|
if (count)
|
||||||
|
step *= count
|
||||||
|
return step
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeModel {
|
||||||
|
id: slider
|
||||||
|
minimumValue: 0.0
|
||||||
|
maximumValue: 1.0
|
||||||
|
value: 0
|
||||||
|
stepSize: 0.0
|
||||||
|
inverted: false
|
||||||
|
positionAtMaximum: internal.grooveSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype ScrollViewHeader
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: wheelarea
|
||||||
|
|
||||||
|
property alias horizontalScrollBar: hscrollbar
|
||||||
|
property alias verticalScrollBar: vscrollbar
|
||||||
|
property bool blockUpdates: false
|
||||||
|
property int availableHeight
|
||||||
|
property int availableWidth
|
||||||
|
property int contentHeight
|
||||||
|
property int contentWidth
|
||||||
|
property real originX
|
||||||
|
property real originY
|
||||||
|
property bool active
|
||||||
|
|
||||||
|
property int leftMargin: outerFrame ? root.__style.padding.left : 0
|
||||||
|
property int rightMargin: outerFrame ? root.__style.padding.right : 0
|
||||||
|
property int topMargin: outerFrame ? root.__style.padding.top : 0
|
||||||
|
property int bottomMargin: outerFrame ? root.__style.padding.bottom : 0
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property bool recursionGuard: false
|
||||||
|
|
||||||
|
function doLayout() {
|
||||||
|
if (!recursionGuard) {
|
||||||
|
recursionGuard = true
|
||||||
|
wheelarea.availableWidth = viewport.width
|
||||||
|
wheelarea.availableHeight = viewport.height
|
||||||
|
wheelarea.contentWidth = flickableItem !== null ? flickableItem.contentWidth : 0
|
||||||
|
wheelarea.contentHeight = flickableItem !== null ? flickableItem.contentHeight : 0
|
||||||
|
wheelarea.originX = flickableItem !== null ? flickableItem.originX : 0
|
||||||
|
wheelarea.originY = flickableItem !== null ? flickableItem.originY : 0
|
||||||
|
recursionGuard = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: viewport
|
||||||
|
onWidthChanged: doLayout()
|
||||||
|
onHeightChanged: doLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: flickableItem
|
||||||
|
onContentWidthChanged: doLayout()
|
||||||
|
onContentHeightChanged: doLayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: flickableItem
|
||||||
|
onContentXChanged: {
|
||||||
|
hscrollbar.flash()
|
||||||
|
vscrollbar.flash()
|
||||||
|
}
|
||||||
|
onContentYChanged: {
|
||||||
|
hscrollbar.flash()
|
||||||
|
vscrollbar.flash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: cornerFill
|
||||||
|
z: 1
|
||||||
|
sourceComponent: __style.corner
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: bottomMargin
|
||||||
|
anchors.rightMargin: rightMargin
|
||||||
|
width: visible ? vscrollbar.width : 0
|
||||||
|
height: visible ? hscrollbar.height : 0
|
||||||
|
visible: hscrollbar.visible && !hscrollbar.isTransient && vscrollbar.visible && !vscrollbar.isTransient
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBar {
|
||||||
|
id: hscrollbar
|
||||||
|
isTransient: !!__panel && !!__panel.isTransient
|
||||||
|
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||||
|
enabled: !isTransient || __panel.visible
|
||||||
|
orientation: Qt.Horizontal
|
||||||
|
visible: contentWidth > availableWidth
|
||||||
|
height: visible ? implicitHeight : 0
|
||||||
|
z: 1
|
||||||
|
maximumValue: contentWidth > availableWidth ? originX + contentWidth - availableWidth : 0
|
||||||
|
minimumValue: originX
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: cornerFill.left
|
||||||
|
anchors.leftMargin: leftMargin
|
||||||
|
anchors.bottomMargin: bottomMargin
|
||||||
|
onValueChanged: {
|
||||||
|
if (!blockUpdates) {
|
||||||
|
flickableItem.contentX = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: hscrollbar.__panel
|
||||||
|
property: "raised"
|
||||||
|
value: vscrollbar.active || wheelarea.active
|
||||||
|
when: hscrollbar.isTransient
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: hscrollbar.__panel
|
||||||
|
property: "visible"
|
||||||
|
value: true
|
||||||
|
when: !hscrollbar.isTransient || wheelarea.active
|
||||||
|
}
|
||||||
|
function flash() {
|
||||||
|
if (hscrollbar.isTransient) {
|
||||||
|
hscrollbar.__panel.on = true
|
||||||
|
hscrollbar.__panel.visible = true
|
||||||
|
hFlasher.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: hFlasher
|
||||||
|
interval: 10
|
||||||
|
onTriggered: hscrollbar.__panel.on = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBar {
|
||||||
|
id: vscrollbar
|
||||||
|
isTransient: !!__panel && !!__panel.isTransient
|
||||||
|
active: !!__panel && (__panel.sunken || __panel.activeControl !== "none")
|
||||||
|
enabled: !isTransient || __panel.visible
|
||||||
|
orientation: Qt.Vertical
|
||||||
|
visible: contentHeight > availableHeight
|
||||||
|
width: visible ? implicitWidth : 0
|
||||||
|
z: 1
|
||||||
|
anchors.bottom: cornerFill.top
|
||||||
|
maximumValue: contentHeight > availableHeight ? originY + contentHeight - availableHeight + __viewTopMargin : 0
|
||||||
|
minimumValue: originY
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: __scrollBarTopMargin + topMargin
|
||||||
|
anchors.rightMargin: rightMargin
|
||||||
|
onValueChanged: {
|
||||||
|
if (flickableItem && !blockUpdates && enabled) {
|
||||||
|
flickableItem.contentY = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: vscrollbar.__panel
|
||||||
|
property: "raised"
|
||||||
|
value: hscrollbar.active || wheelarea.active
|
||||||
|
when: vscrollbar.isTransient
|
||||||
|
}
|
||||||
|
Binding {
|
||||||
|
target: vscrollbar.__panel
|
||||||
|
property: "visible"
|
||||||
|
value: true
|
||||||
|
when: !vscrollbar.isTransient || wheelarea.active
|
||||||
|
}
|
||||||
|
function flash() {
|
||||||
|
if (vscrollbar.isTransient) {
|
||||||
|
vscrollbar.__panel.on = true
|
||||||
|
vscrollbar.__panel.visible = true
|
||||||
|
vFlasher.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Timer {
|
||||||
|
id: vFlasher
|
||||||
|
interval: 10
|
||||||
|
onTriggered: vscrollbar.__panel.on = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Graphical Effects module.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
property variant input
|
||||||
|
property variant output
|
||||||
|
property variant sourceRect
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Component.onCompleted: evaluateInput()
|
||||||
|
|
||||||
|
onInputChanged: evaluateInput()
|
||||||
|
|
||||||
|
onSourceRectChanged: evaluateInput()
|
||||||
|
|
||||||
|
function evaluateInput() {
|
||||||
|
if (input == undefined) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (sourceRect != undefined && sourceRect != Qt.rect(0, 0, 0, 0) && !isQQuickShaderEffectSource(input)) {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = sourceRect
|
||||||
|
}
|
||||||
|
else if (isQQuickItemLayerEnabled(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if ((isQQuickImage(input) && !hasTileMode(input) && !hasChildren(input))) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else if (isQQuickShaderEffectSource(input)) {
|
||||||
|
output = input
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
proxySource.sourceItem = input
|
||||||
|
output = proxySource
|
||||||
|
proxySource.sourceRect = Qt.rect(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickItemLayerEnabled(item) {
|
||||||
|
if (item.hasOwnProperty("layer")) {
|
||||||
|
var l = item["layer"]
|
||||||
|
if (l.hasOwnProperty("enabled") && l["enabled"].toString() == "true")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickImage(item) {
|
||||||
|
var imageProperties = [ "fillMode", "progress", "asynchronous", "sourceSize", "status", "smooth" ]
|
||||||
|
return hasProperties(item, imageProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isQQuickShaderEffectSource(item) {
|
||||||
|
var shaderEffectSourceProperties = [ "hideSource", "format", "sourceItem", "mipmap", "wrapMode", "live", "recursive", "sourceRect" ]
|
||||||
|
return hasProperties(item, shaderEffectSourceProperties)
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasProperties(item, properties) {
|
||||||
|
var counter = 0
|
||||||
|
for (var j = 0; j < properties.length; j++) {
|
||||||
|
if (item.hasOwnProperty(properties [j]))
|
||||||
|
counter++
|
||||||
|
}
|
||||||
|
return properties.length == counter
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasChildren(item) {
|
||||||
|
if (item.hasOwnProperty("childrenRect")) {
|
||||||
|
if (item["childrenRect"].toString() != "QRectF(0, 0, 0, 0)")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasTileMode(item) {
|
||||||
|
if (item.hasOwnProperty("fillMode")) {
|
||||||
|
if (item["fillMode"].toString() != "0")
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderEffectSource {
|
||||||
|
id: proxySource
|
||||||
|
live: rootItem.input != rootItem.output
|
||||||
|
hideSource: false
|
||||||
|
smooth: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
var stackView = [];
|
||||||
|
|
||||||
|
function push(p)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
return
|
||||||
|
stackView.push(p)
|
||||||
|
__depth++
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
function pop()
|
||||||
|
{
|
||||||
|
if (stackView.length === 0)
|
||||||
|
return null
|
||||||
|
var p = stackView.pop()
|
||||||
|
__depth--
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
function current()
|
||||||
|
{
|
||||||
|
if (stackView.length === 0)
|
||||||
|
return null
|
||||||
|
return stackView[stackView.length-1]
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype StackViewSlideTransition
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
StackViewDelegate {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool horizontal: true
|
||||||
|
|
||||||
|
function getTransition(properties)
|
||||||
|
{
|
||||||
|
return root[horizontal ? "horizontalSlide" : "verticalSlide"][properties.name]
|
||||||
|
}
|
||||||
|
|
||||||
|
function transitionFinished(properties)
|
||||||
|
{
|
||||||
|
properties.exitItem.x = 0
|
||||||
|
properties.exitItem.y = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
property QtObject horizontalSlide: QtObject {
|
||||||
|
property Component pushTransition: StackViewTransition {
|
||||||
|
PropertyAnimation {
|
||||||
|
target: enterItem
|
||||||
|
property: "x"
|
||||||
|
from: target.width
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "x"
|
||||||
|
from: 0
|
||||||
|
to: -target.width
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property Component popTransition: StackViewTransition {
|
||||||
|
PropertyAnimation {
|
||||||
|
target: enterItem
|
||||||
|
property: "x"
|
||||||
|
from: -target.width
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "x"
|
||||||
|
from: 0
|
||||||
|
to: target.width
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
property Component replaceTransition: pushTransition
|
||||||
|
}
|
||||||
|
|
||||||
|
property QtObject verticalSlide: QtObject {
|
||||||
|
property Component pushTransition: StackViewTransition {
|
||||||
|
PropertyAnimation {
|
||||||
|
target: enterItem
|
||||||
|
property: "y"
|
||||||
|
from: target.height
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "y"
|
||||||
|
from: 0
|
||||||
|
to: -target.height
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property Component popTransition: StackViewTransition {
|
||||||
|
PropertyAnimation {
|
||||||
|
target: enterItem
|
||||||
|
property: "y"
|
||||||
|
from: -target.height
|
||||||
|
to: 0
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
PropertyAnimation {
|
||||||
|
target: exitItem
|
||||||
|
property: "y"
|
||||||
|
from: 0
|
||||||
|
to: target.height
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
property Component replaceTransition: pushTransition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
import QtQuick.Controls.Private 1.0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype Style
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
|
||||||
|
AbstractStyle {
|
||||||
|
/*! The control attached to this style */
|
||||||
|
readonly property Item control: __control
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
property var __syspal: SystemPalette {
|
||||||
|
colorGroup: control.enabled ?
|
||||||
|
SystemPalette.Active : SystemPalette.Disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,308 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
import QtQuick.Controls 1.1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\qmltype TabBar
|
||||||
|
\internal
|
||||||
|
\inqmlmodule QtQuick.Controls.Private
|
||||||
|
*/
|
||||||
|
FocusScope {
|
||||||
|
id: tabbar
|
||||||
|
height: Math.max(tabrow.height, Math.max(leftCorner.height, rightCorner.height))
|
||||||
|
width: tabView.width
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
|
||||||
|
Keys.onRightPressed: {
|
||||||
|
if (tabView && tabView.currentIndex < tabView.count - 1)
|
||||||
|
tabView.currentIndex = tabView.currentIndex + 1
|
||||||
|
}
|
||||||
|
Keys.onLeftPressed: {
|
||||||
|
if (tabView && tabView.currentIndex > 0)
|
||||||
|
tabView.currentIndex = tabView.currentIndex - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
onTabViewChanged: parent = tabView
|
||||||
|
visible: tabView ? tabView.tabsVisible : true
|
||||||
|
|
||||||
|
property var tabView
|
||||||
|
property var style
|
||||||
|
property var styleItem: tabView.__styleItem ? tabView.__styleItem : null
|
||||||
|
|
||||||
|
property bool tabsMovable: styleItem ? styleItem.tabsMovable : false
|
||||||
|
|
||||||
|
property int tabsAlignment: styleItem ? styleItem.tabsAlignment : Qt.AlignLeft
|
||||||
|
|
||||||
|
property int tabOverlap: styleItem ? styleItem.tabOverlap : 0
|
||||||
|
|
||||||
|
property int elide: Text.ElideRight
|
||||||
|
|
||||||
|
property real availableWidth: tabbar.width - leftCorner.width - rightCorner.width
|
||||||
|
|
||||||
|
property var __selectedTabRect
|
||||||
|
|
||||||
|
function tab(index) {
|
||||||
|
for (var i = 0; i < tabrow.children.length; ++i) {
|
||||||
|
if (tabrow.children[i].tabindex == index) {
|
||||||
|
return tabrow.children[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \internal */
|
||||||
|
function __isAncestorOf(item, child) {
|
||||||
|
//TODO: maybe removed from 5.2 if the function was merged in qtdeclarative
|
||||||
|
if (child === item)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
while (child) {
|
||||||
|
child = child.parent;
|
||||||
|
if (child === item)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
id: background
|
||||||
|
anchors.fill: parent
|
||||||
|
sourceComponent: styleItem ? styleItem.tabBar : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: tabrow
|
||||||
|
objectName: "tabrow"
|
||||||
|
Accessible.role: Accessible.PageTabList
|
||||||
|
LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
|
||||||
|
spacing: -tabOverlap
|
||||||
|
orientation: Qt.Horizontal
|
||||||
|
interactive: false
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
// Note this will silence the binding loop warnings caused by QTBUG-35038
|
||||||
|
// and should be removed when this issue is resolved.
|
||||||
|
property int contentWidthWorkaround: contentWidth > 0 ? contentWidth: 0
|
||||||
|
width: Math.min(availableWidth, count ? contentWidthWorkaround : availableWidth)
|
||||||
|
height: currentItem ? currentItem.height : 0
|
||||||
|
|
||||||
|
highlightMoveDuration: 0
|
||||||
|
currentIndex: tabView.currentIndex
|
||||||
|
onCurrentIndexChanged: tabrow.positionViewAtIndex(currentIndex, ListView.Contain)
|
||||||
|
|
||||||
|
moveDisplaced: Transition {
|
||||||
|
NumberAnimation {
|
||||||
|
property: "x"
|
||||||
|
duration: 125
|
||||||
|
easing.type: Easing.OutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "left"
|
||||||
|
when: tabsAlignment === Qt.AlignLeft
|
||||||
|
AnchorChanges { target:tabrow ; anchors.left: parent.left }
|
||||||
|
PropertyChanges { target:tabrow ; anchors.leftMargin: leftCorner.width }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "center"
|
||||||
|
when: tabsAlignment === Qt.AlignHCenter
|
||||||
|
AnchorChanges { target:tabrow ; anchors.horizontalCenter: tabbar.horizontalCenter }
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "right"
|
||||||
|
when: tabsAlignment === Qt.AlignRight
|
||||||
|
AnchorChanges { target:tabrow ; anchors.right: parent.right }
|
||||||
|
PropertyChanges { target:tabrow ; anchors.rightMargin: rightCorner.width }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
model: tabView.__tabs
|
||||||
|
|
||||||
|
delegate: MouseArea {
|
||||||
|
id: tabitem
|
||||||
|
objectName: "mousearea"
|
||||||
|
hoverEnabled: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: tabbar
|
||||||
|
when: selected
|
||||||
|
property: "__selectedTabRect"
|
||||||
|
value: Qt.rect(x, y, width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
drag.target: tabsMovable ? tabloader : null
|
||||||
|
drag.axis: Drag.XAxis
|
||||||
|
drag.minimumX: drag.active ? 0 : -Number.MAX_VALUE
|
||||||
|
drag.maximumX: tabrow.width - tabitem.width
|
||||||
|
|
||||||
|
property int tabindex: index
|
||||||
|
property bool selected : tabView.currentIndex === index
|
||||||
|
property string title: modelData.title
|
||||||
|
property bool nextSelected: tabView.currentIndex === index + 1
|
||||||
|
property bool previousSelected: tabView.currentIndex === index - 1
|
||||||
|
|
||||||
|
z: selected ? 1 : -index
|
||||||
|
implicitWidth: tabloader.implicitWidth
|
||||||
|
implicitHeight: tabloader.implicitHeight
|
||||||
|
|
||||||
|
function changeTab() {
|
||||||
|
tabView.currentIndex = index;
|
||||||
|
var next = tabbar.nextItemInFocusChain(true);
|
||||||
|
if (__isAncestorOf(tabView.getTab(currentIndex), next))
|
||||||
|
next.forceActiveFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (tabrow.interactive) {
|
||||||
|
changeTab()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPressed: {
|
||||||
|
if (!tabrow.interactive) {
|
||||||
|
changeTab()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: tabloader
|
||||||
|
|
||||||
|
property Item control: tabView
|
||||||
|
property int index: tabindex
|
||||||
|
|
||||||
|
property QtObject styleData: QtObject {
|
||||||
|
readonly property alias index: tabitem.tabindex
|
||||||
|
readonly property alias selected: tabitem.selected
|
||||||
|
readonly property alias title: tabitem.title
|
||||||
|
readonly property alias nextSelected: tabitem.nextSelected
|
||||||
|
readonly property alias previsousSelected: tabitem.previousSelected
|
||||||
|
readonly property alias hovered: tabitem.containsMouse
|
||||||
|
readonly property bool activeFocus: tabbar.activeFocus
|
||||||
|
readonly property real availableWidth: tabbar.availableWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceComponent: loader.item ? loader.item.tab : null
|
||||||
|
|
||||||
|
Drag.keys: "application/x-tabbartab"
|
||||||
|
Drag.active: tabitem.drag.active
|
||||||
|
Drag.source: tabitem
|
||||||
|
|
||||||
|
property real __prevX: 0
|
||||||
|
property real __dragX: 0
|
||||||
|
onXChanged: {
|
||||||
|
if (Drag.active) {
|
||||||
|
// keep track for the snap back animation
|
||||||
|
__dragX = tabitem.mapFromItem(tabrow, tabloader.x, 0).x
|
||||||
|
|
||||||
|
// when moving to the left, the hot spot is the left edge and vice versa
|
||||||
|
Drag.hotSpot.x = x < __prevX ? 0 : width
|
||||||
|
__prevX = x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width: tabitem.width
|
||||||
|
state: Drag.active ? "drag" : ""
|
||||||
|
|
||||||
|
transitions: [
|
||||||
|
Transition {
|
||||||
|
to: "drag"
|
||||||
|
PropertyAction { target: tabloader; property: "parent"; value: tabrow }
|
||||||
|
},
|
||||||
|
Transition {
|
||||||
|
from: "drag"
|
||||||
|
SequentialAnimation {
|
||||||
|
PropertyAction { target: tabloader; property: "parent"; value: tabitem }
|
||||||
|
NumberAnimation {
|
||||||
|
target: tabloader
|
||||||
|
duration: 50
|
||||||
|
easing.type: Easing.OutQuad
|
||||||
|
property: "x"
|
||||||
|
from: tabloader.__dragX
|
||||||
|
to: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible.role: Accessible.PageTab
|
||||||
|
Accessible.name: modelData.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: leftCorner
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
sourceComponent: styleItem ? styleItem.leftCorner : undefined
|
||||||
|
width: item ? item.implicitWidth : 0
|
||||||
|
height: item ? item.implicitHeight : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: rightCorner
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.right
|
||||||
|
sourceComponent: styleItem ? styleItem.rightCorner : undefined
|
||||||
|
width: item ? item.implicitWidth : 0
|
||||||
|
height: item ? item.implicitHeight : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
DropArea {
|
||||||
|
anchors.fill: tabrow
|
||||||
|
keys: "application/x-tabbartab"
|
||||||
|
onPositionChanged: {
|
||||||
|
var source = drag.source
|
||||||
|
var target = tabrow.itemAt(drag.x, drag.y)
|
||||||
|
if (source && target && source !== target) {
|
||||||
|
source = source.drag.target
|
||||||
|
target = target.drag.target
|
||||||
|
var center = target.parent.x + target.width / 2
|
||||||
|
if ((source.index > target.index && source.x < center)
|
||||||
|
|| (source.index < target.index && source.x + source.width > center))
|
||||||
|
tabView.moveTab(source.index, target.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:BSD$
|
||||||
|
** You may use this file under the terms of the BSD license as follows:
|
||||||
|
**
|
||||||
|
** "Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions are
|
||||||
|
** met:
|
||||||
|
** * Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** * Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in
|
||||||
|
** the documentation and/or other materials provided with the
|
||||||
|
** distribution.
|
||||||
|
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
|
||||||
|
** of its contributors may be used to endorse or promote products derived
|
||||||
|
** from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick 2.1
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
|
||||||
|
property int count: 0
|
||||||
|
signal selectionChanged
|
||||||
|
|
||||||
|
property bool __dirty: false
|
||||||
|
property var __ranges: new Array()
|
||||||
|
|
||||||
|
function forEach (callback) {
|
||||||
|
if (!(callback instanceof Function)) {
|
||||||
|
console.warn("TableViewSelection.forEach: argument is not a function")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__forEach(callback, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function contains(index) {
|
||||||
|
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||||
|
if (__ranges[i][0] <= index && index <= __ranges[i][1])
|
||||||
|
return true;
|
||||||
|
else if (__ranges[i][0] > index)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
__ranges = new Array()
|
||||||
|
__dirty = true
|
||||||
|
count = 0
|
||||||
|
selectionChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAll() { select(0, rowCount - 1) }
|
||||||
|
function select(first, last) { __select(true, first, last) }
|
||||||
|
function deselect(first, last) { __select(false, first, last) }
|
||||||
|
|
||||||
|
// --- private section ---
|
||||||
|
|
||||||
|
function __printRanges() {
|
||||||
|
var out = ""
|
||||||
|
for (var i = 0 ; i < __ranges.length ; ++ i)
|
||||||
|
out += ("{" + __ranges[i][0] + "," + __ranges[i][1] + "} ")
|
||||||
|
print(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
function __count() {
|
||||||
|
var sum = 0
|
||||||
|
for (var i = 0 ; i < __ranges.length ; ++i) {
|
||||||
|
sum += (1 + __ranges[i][1] - __ranges[i][0])
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
function __forEach (callback, startIndex) {
|
||||||
|
__dirty = false
|
||||||
|
var i, j
|
||||||
|
|
||||||
|
for (i = 0 ; i < __ranges.length && !__dirty ; ++i) {
|
||||||
|
for (j = __ranges[i][0] ; !__dirty && j <= __ranges[i][1] ; ++j) {
|
||||||
|
if (j >= startIndex)
|
||||||
|
callback.call(this, j)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restart iteration at last index if selection changed
|
||||||
|
if (__dirty)
|
||||||
|
return __forEach(callback, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
function __selectOne(index) {
|
||||||
|
__ranges = [[index, index]]
|
||||||
|
__dirty = true
|
||||||
|
count = 1
|
||||||
|
selectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
function __select(select, first, last) {
|
||||||
|
|
||||||
|
var i, range
|
||||||
|
var start = first
|
||||||
|
var stop = first
|
||||||
|
var startRangeIndex = -1
|
||||||
|
var stopRangeIndex = -1
|
||||||
|
var newRangePos = 0
|
||||||
|
|
||||||
|
if (first < 0 || last < 0 || first >= rowCount || last >=rowCount) {
|
||||||
|
console.warn("TableViewSelection: index out of range")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last !== undefined) {
|
||||||
|
start = first <= last ? first : last
|
||||||
|
stop = first <= last ? last : first
|
||||||
|
}
|
||||||
|
|
||||||
|
if (select) {
|
||||||
|
|
||||||
|
// Find beginning and end ranges
|
||||||
|
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||||
|
range = __ranges[i]
|
||||||
|
if (range[0] > stop + 1) continue; // above range
|
||||||
|
if (range[1] < start - 1) { // below range
|
||||||
|
newRangePos = i + 1
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (startRangeIndex == -1)
|
||||||
|
startRangeIndex = i
|
||||||
|
stopRangeIndex = i
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startRangeIndex !== -1)
|
||||||
|
start = Math.min(__ranges[startRangeIndex][0], start)
|
||||||
|
if (stopRangeIndex !== -1)
|
||||||
|
stop = Math.max(__ranges[stopRangeIndex][1], stop)
|
||||||
|
|
||||||
|
if (startRangeIndex == -1)
|
||||||
|
startRangeIndex = newRangePos
|
||||||
|
|
||||||
|
__ranges.splice(Math.max(0, startRangeIndex),
|
||||||
|
1 + stopRangeIndex - startRangeIndex, [start, stop])
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Find beginning and end ranges
|
||||||
|
for (i = 0 ; i < __ranges.length; ++ i) {
|
||||||
|
range = __ranges[i]
|
||||||
|
if (range[1] < start) continue; // below range
|
||||||
|
if (range[0] > stop) continue; // above range
|
||||||
|
if (startRangeIndex == -1)
|
||||||
|
startRangeIndex = i
|
||||||
|
stopRangeIndex = i
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slice ranges accordingly
|
||||||
|
if (startRangeIndex >= 0 && stopRangeIndex >= 0) {
|
||||||
|
var startRange = __ranges[startRangeIndex]
|
||||||
|
var stopRange = __ranges[stopRangeIndex]
|
||||||
|
var length = 1 + stopRangeIndex - startRangeIndex
|
||||||
|
if (start <= startRange[0] && stop >= stopRange[1]) { //remove
|
||||||
|
__ranges.splice(startRangeIndex, length)
|
||||||
|
} else if (start - 1 < startRange[0] && stop <= stopRange[1]) { //cut front
|
||||||
|
__ranges.splice(startRangeIndex, length, [stop + 1, stopRange[1]])
|
||||||
|
} else if (start - 1 < startRange[1] && stop >= stopRange[1]) { // cut back
|
||||||
|
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1])
|
||||||
|
} else { //split
|
||||||
|
__ranges.splice(startRangeIndex, length, [startRange[0], start - 1], [stop + 1, stopRange[1]])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
__dirty = true
|
||||||
|
count = __count() // forces a re-evaluation of indexes in the delegates
|
||||||
|
selectionChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU General Public License version 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
pragma Singleton
|
||||||
|
import QtQuick 2.1
|
||||||
|
Text {}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user