How to create a Progress Bar in Qml with slant lines? - qt

Hello ,
I am looking for some solution to create a progress bar in qml having slant lines.
I dont having any snippet to share here, as I am not aware how to do so.
Can anyone please guide ??

I am going to solve the problem in stages. This is reflective of how I go about solving QML problems myself. The first goal is to create a 200x32 ProgressBar and to set it to 25% progress. First, I start with a blank Rectangle for my custom ProgressBar:
ProgressBar {
implicitWidth: 200
implicitHeight: 32
contentItem: Rectangle {
border.color: "black"
}
}
Next, I decide to craft a 32x32 SVG of a diagonal line and I repeat this line at 4 pixel intervals covering the whole width (i.e. 200 / 4 === 50).
ProgressBar {
implicitWidth: 200
implicitHeight: 32
contentItem: Rectangle {
border.color: "black"
Repeater {
model: 200 / 4
Image {
x: index * 4
y: 0
source: `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path fill="none" stroke="black" d="M 0 0 L 32 32" />
</svg>`
}
}
}
}
I observe two problems with the above:
The triangle gap at the left
The overshoot at the right
To fix these problems, (1) shift the lines 32 pixels to the left to cover the gap, (2) I extend the lines to be (200 + 32) / 4 === 58, (3) use clip to crop clean the diagonals that are outside my Rectangle.
ProgressBar {
implicitWidth: 200
implicitHeight: 32
contentItem: Rectangle {
border.color: "black"
clip: true
Repeater {
model: (200 + 32) / 4
Image {
x: index * 4 - 32
y: 0
source: `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path fill="none" stroke="black" d="M 0 0 L 32 32" />
</svg>`
}
}
}
}
Next, I want to represent 25%. I do this by drawing a 75% white Rectangle covering the slant lines on the right.
ProgressBar {
implicitWidth: 200
implicitHeight: 32
value: 0.25
contentItem: Rectangle {
border.color: "black"
clip: true
Repeater {
model: (200 + 32) / 4
Image {
x: index * 4 - 32
y: 0
source: `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path fill="none" stroke="black" d="M 0 0 L 32 32" />
</svg>`
}
}
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
implicitWidth: parent.width * 0.75
implicitHeight: parent.height
border.color: "black"
color: "white"
}
}
}
Finally, we try to generalize our solution:
ProgressBar {
id: progressBar
implicitWidth: 200
implicitHeight: 32
contentItem: Rectangle {
border.color: "black"
clip: true
Repeater {
model: (parent.width + parent.height) / 4
Image {
x: index * 4 - parent.height
y: 0
source: `data:image/svg+xml;utf8,
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${parent.height} ${parent.height}">
<path fill="none" stroke="black" d="M 0 0 L ${parent.height} ${parent.height}" />
</svg>`
}
}
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.bottom: parent.bottom
implicitWidth: parent.width * (1 - parent.parent.value)
implicitHeight: parent.height
border.color: "black"
color: "white"
}
}
}
There are assumptions that we made:
ProgressBar is 200x32
Color is white bar with a black outline with black diagonal lines
The bar to the right is filled white
A SVG image is used
To generalize further, we can consider (1) replacing the SVG Image with a more efficient equivalent, (2) allow the colours to be configurable.

I recommend using ShaderEffect to create a more efficient result.
So, as everyone else implemented their own code, I did as well.
The results are shown below.
SlantLines.qml
// SlantLines.qml
import QtQuick 2.12
ShaderEffect {
id: effect
property real seed: 0 // To animate the lines' x axis.
property real num: width / 6 // The number of lines changes with width and may even be fixed.
property color color: '#000' // Color of lines (background is transparent)
property vector2d ratio: {
const max = Math.max(width, height);
return Qt.vector2d(width/max, height/max);
}
fragmentShader: "
uniform lowp float qt_Opacity;
uniform lowp float seed;
uniform lowp float num;
uniform highp vec2 ratio;
uniform highp vec4 color;
varying highp vec2 qt_TexCoord0;
void main() {
vec2 uv = qt_TexCoord0*ratio/ ratio.x;
// Slope can be changed by multiplying 'y' by any number.
uv.x -= uv.y + seed/num;
vec2 grid = fract(uv * vec2(num,1.));
// You may also change the line width from 0.0 to 1.0. (change 0.5)
gl_FragColor = color * smoothstep(0.0,ratio.x*1e-1,grid.x - 0.5) * qt_Opacity;
}"
}
Preview
An example of how it works.
component SlantLinesColumn: Column {
property real xSeed: 0
spacing: 5
Repeater {
model: 12
SlantLines {
height: 10
width: (index + 1) * 20
color: Qt.hsva(index/13,1,1,1)
seed: xSeed
}
}
}
SlantLinesColumn { }
SlantLinesColumn {
y: 190
Timer {
running: true; repeat: true
interval: 50 // Almost 20Hz.
onTriggered: parent.xSeed -= 0.1
}
}
ProgressBar.qml
SlantLines can also be embedded in a progressbar.
This template is available from the Qt source code.
// ProgressBar.qml
import QtQuick 2.15
import QtQuick.Templates 2.15 as T
T.ProgressBar {
id: control
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
property int orientation: Qt.Vertical
readonly property bool vertical: orientation == Qt.Vertical
contentItem: Item {
SlantLines {
y: control.vertical ? parent.height - height : 0
width: !control.vertical && !control.indeterminate ?
parent.width * control.position : parent.width
height: control.vertical && !control.indeterminate ?
parent.height * control.position : parent.height
color: control.palette.dark
Timer {
running: control.visible && control.indeterminate
repeat: true; interval: 50
onTriggered: parent.seed -= 0.1
}
}
}
background: Rectangle {
implicitWidth: !control.vertical ? 200 : 18
implicitHeight: control.vertical ? 200 : 18
color: control.palette.midlight
}
}
Edit (NumberAnimation)
As #Mitch mentioned in the comments, Timer may also be replaced with NumberAnimation, as shown in the following code:
The Timer is just used to limit the animation refresh rate, which also reduces resource use.
SlantLines {
...
NumberAnimation on seed {
running: control.visible && control.indeterminate
loops: Animation.Infinite
from: 0; to: -1
duration: 500
}
}

Yet another solution.
ProgressBar {
id: control
property color contentItemColor: "white"
property color backgroundColor: "yellow"
property color borderColor: "red"
property int borderWidth: 1
property color stripColor: "green"
property int stripGap: 10
property int stripWidth: 2
property color indicatorColor: "red"
property int indicatorWidth: 2
property int indicatorRadius: 0
property int indicatorExtend: 0
value: 0.5
width: 600
height: 80
background: Rectangle {
color: control.backgroundColor
border.width: control.borderWidth
border.color: control.borderColor
Canvas {
x: control.borderWidth
y: control.borderWidth
width: control.width - (2 * control.borderWidth)
height: control.height - (2 * control.borderWidth)
onPaint: {
var ctx = getContext("2d");
ctx.strokeStyle = control.stripColor
ctx.lineWidth = control.stripWidth
ctx.lineCap = "square"
var p1, p2
let n = Math.ceil((control.width + control.height) / (control.stripGap)) + 1
for (let i = 0; i != n; ++i) {
let p = i * control.stripGap
p1 = Qt.vector2d(p - control.height, 0)
p2 = Qt.vector2d(p, control.height)
ctx.beginPath()
ctx.moveTo(p1.x, p1.y)
ctx.lineTo(p2.x, p2.y)
ctx.closePath()
ctx.stroke()
}
}
}
}
contentItem: Item {
Rectangle {
anchors.fill: parent
anchors.margins: control.borderWidth
anchors.leftMargin: Math.max(control.borderWidth,
control.visualPosition * control.width)
color: control.contentItemColor
}
Rectangle {
x: control.visualPosition * control.width - (control.indicatorWidth / 2)
y: -control.indicatorExtend
width: control.indicatorWidth
height: control.height + (2 * control.indicatorExtend)
color: control.indicatorColor
radius: control.indicatorRadius
visible: control.visualPosition > 0.0 && control.visualPosition < 1.0
}
}
}

The indeterminate Fusion style ProgressBar does something similar, where it has moving slanted lines.
Here's the code from that adjusted to show the lines for determinate bars as well, using only public APIs:
import QtQuick
import QtQuick.Controls
ApplicationWindow {
width: 640
height: 480
visible: true
ProgressBar {
id: control
value: 0.5
contentItem: Item {
implicitWidth: 120
implicitHeight: 24
Rectangle {
height: parent.height
width: control.position * parent.width
radius: 2
border.color: "steelblue"
gradient: Gradient {
GradientStop {
position: 0
color: Qt.lighter("steelblue", 1.2)
}
GradientStop {
position: 1
color: Qt.darker("steelblue", 1.2)
}
}
}
Item {
x: 1
y: 1
width: parent.width - 2
height: parent.height - 2
clip: true
Image {
width: Math.ceil(parent.width / implicitWidth + 1) * implicitWidth
height: parent.height
mirror: control.mirrored
fillMode: Image.TileHorizontally
source: "qrc:/qt-project.org/imports/QtQuick/Controls/Fusion/images/progressmask.png"
opacity: 0.25
NumberAnimation on x {
running: control.visible
from: -31 // progressmask.png width
to: 0
loops: Animation.Infinite
duration: 750
}
}
}
}
}
}
If you don't want the animation, just remove the NumberAnimation.
Note that since this example uses an image from the Fusion style (for convenience), it must be run with the Fusion style.
If you want to run it with another style, replace the image's URL with another, and make sure you're using a non-native style:
Note: The macOS and Windows styles are not suitable for customizing. It is instead recommended to always base a customized control on top of a single style that is available on all platforms, e.g Basic Style, Fusion Style, Imagine Style, Material Style, Universal Style. By doing so, you are guaranteed that it will always look the same, regardless of which style the application is run with. For example:

Related

Get color of element in the point | QML

I was able to write 'Color Wheel' in QML with Rectangle elements:
And now I'm wondering how to get color of the handler's position.
I have seen that it's should be possible to achieve with canvas, but may be there is a better solution?
Here the code:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.12
Item
{
id: colorWheel
Rectangle
{
id: ring
color: "transparent"
implicitWidth: 80
implicitHeight: implicitWidth
width: parent.width < parent.height ? parent.width : parent.height
height: width
radius: width / 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
border.width: width / 15
property double wheelRadius: ring.width / 2 - border.width /2
ConicalGradient
{
source: parent
anchors.fill: parent
gradient: Gradient
{
GradientStop { position: 0; color: "#7FFF00" }
GradientStop { position: 1; color: "#7FFF00" }
}
}
MouseArea
{
id: dragArea
anchors.fill: parent
drag.target: parent
onPositionChanged: {
[handler.x, handler.y] = calculatePos(mouseX, mouseY)
}
function calculatePos(x, y)
{
var vX = x - ring.wheelRadius
var vY = y - ring.wheelRadius
var magV = Math.sqrt((Math.pow(vX, 2) + Math.pow(vY, 2)))
var aX = ring.wheelRadius + vX / magV * ring.wheelRadius
var aY = ring.wheelRadius + vY / magV * ring.wheelRadius
return [aX, aY]
}
}
Rectangle
{
id: handler
width: ring.width / 15
height: width
radius: ring.width / 30
border.width: 1
color: "transparent"
}
}
}
I was asked to add some more details to be able to post the code:
As you can see I change handler position according mouse position. I want to grab ring's color under handler's position.
Finally I have used canvas and it seems that it works well, here the shorten version of the code(didn't include handler logic):
Canvas
{
id: ring
property double wheelFullRadius: width / 2
property double borderWidth: wheelFullRadius / 6
property double wheelInnerRadius: wheelFullRadius - borderWidth / 2
function getColor()
{
return context.getImageData(handler.x, handler.y, 1, 1)
}
onPaint:
{
var context = getContext('2d')
context.reset()
context.arc(ring.wheelFullRadius, ring.wheelFullRadius, ring.wheelInnerRadius,
0, 2*Math.PI)
var grd = context.createConicalGradient(
ring.wheelFullRadius, ring.wheelFullRadius, 0
)
grd.addColorStop(0, "#7FFF00" )
grd.addColorStop(1/12, "#FFFF00" )
grd.addColorStop(2/12, "#FF7F00" )
grd.addColorStop(3/12, "#FF0000" )
grd.addColorStop(4/12, "#FF007F" )
grd.addColorStop(5/12, "#FF00FF" )
grd.addColorStop(6/12, "#7F00FF" )
grd.addColorStop(7/12, "#0000FF" )
grd.addColorStop(8/12, "#007FFF" )
grd.addColorStop(9/12, "#00FFFF" )
grd.addColorStop(10/12, "#00FF7F" )
grd.addColorStop(11/12, "#00FF00" )
grd.addColorStop(1, "#7FFF00" )
context.strokeStyle = grd
context.lineWidth = ring.borderWidth
context.stroke()
handler.update()
}
....
}
I still have concerns about performance on mobile devices, but for now it works.
You can also use Math.arc2 to get mouse angle based on ring center, then use Qt.hsva or Qt.hsla methods to get the color at the mouse position.
property color color: Qt.hsva(mousearea.angle, 1.0, 1.0, 1.0);
MouseArea {
id: mousearea
anchors.fill: parent
// angle value is between 0 and 1
property real angle: Math.atan2(width/2 - mouseX, mouseY - height/2) / 6.2831 + 0.5
}
Preview
             
Here is a circular color picker which I wrote.
I used shader effect to create a perfect color wheel
ColorPicker.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
Control {
id: control
property real ringWidth: 25
property real hsvValue: 1.0
property real hsvSaturation: 1.0
readonly property color color: Qt.hsva(mousearea.angle, 1.0, 1.0, 1.0)
contentItem: Item {
implicitWidth: 175
implicitHeight: width
ShaderEffect {
id: shadereffect
width: parent.width; height: parent.height
readonly property real ringWidth: control.ringWidth / width / 2
readonly property real s: control.hsvSaturation
readonly property real v: control.hsvValue
fragmentShader: "
#version 330
varying highp vec2 qt_TexCoord0;
uniform highp float qt_Opacity;
uniform highp float ringWidth;
uniform highp float s;
uniform highp float v;
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void main() {
highp vec2 coord = qt_TexCoord0 - vec2(0.5);
highp float ring = smoothstep(0, 0.01, -abs(length(coord) - 0.5 + ringWidth) + ringWidth);
gl_FragColor = vec4(hsv2rgb(vec3(-atan(coord.x, coord.y) / 6.2831 + 0.5, s, v)),1);
gl_FragColor *= ring;
}"
}
Rectangle {
id: indicator
x: (parent.width - width)/2
y: control.ringWidth * 0.1
width: control.ringWidth * 0.8; height: width
radius: width/2
color: 'white'
border {
width: mousearea.containsPress ? 3 : 1
color: Qt.lighter(control.color)
Behavior on width { NumberAnimation { duration: 50 } }
}
transform: Rotation {
angle: mousearea.angle * 360
origin.x: indicator.width/2
origin.y: control.availableHeight/2 - indicator.y
}
}
Rectangle {
anchors.centerIn: parent
width: control.availableWidth * 0.3
height: width
radius: width
color: control.color
border {
width: 5
color: Qt.lighter(control.color, 1.8)
}
}
MouseArea {
id: mousearea
anchors.fill: parent
property real angle: Math.atan2(width/2 - mouseX, mouseY - height/2) / 6.2831 + 0.5
}
}
}

How do I create a ripple button effect in QML?

I'm using QtQuick/QML and I want to create a ripple effect when I click on a button. I do know that this is available in Material Style, but I think it's an inherent property when you change the theme and I don't want to change anything else in my project.
Is there a way to add ONLY the ripple effect onto my button, and change nothing else? If so, how do I do it?
As Kostia Hvorov said, QtQuick.Controls.Material.impl.Ripple is the easiest way to go.
I would like to add my trick to handle rectangular background with radius:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material.impl 2.12
import QtGraphicalEffects 1.12
Column
{
spacing: 20
Button
{
anchors.horizontalCenter: parent.horizontalCenter
id: button
text: "ripple demo"
}
Ripple {
id: ripple
anchors.horizontalCenter: parent.horizontalCenter
clipRadius: 4
width: 200
height: 64
pressed: button.pressed
active: button.down || button.visualFocus || button.hovered
color: "#20FFFFFF"
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Rectangle
{
width: ripple.width
height: ripple.height
radius: 4
}
}
}
}
Try it Online
Easiest way to do it - using Ripple from QtQuick.Controls.Material.impl
So just add Ripple to your background Rect:
Ripple {
clipRadius: height
width: parent.width
height: parent.height
pressed: control.pressed
anchor: control
active: control.down || control.visualFocus || control.hovered
color: control.flat && control.highlighted ? control.Material.highlightedRippleColor : control.Material.rippleColor
}
You can replace "control.Material.rippleColor" or/and "control.Material.highlightedRippleColor" to any color and get any ripple color effect.
But there is one problem, it will work only with rectangular background(without round) otherwise it will be looking bad.
I have made this with some PropertyAnimation. Here is how:
import QtQuick 2.15
import QtQuick.Controls 2.15
Button {
id: control
opacity: enabled ? 1.0 : 0.2
property int tripleWidth: width * 3
background: Rectangle {
border.width: 1
border.color: "black"
radius: 3
color: "white"
clip: true
Rectangle {
id: ripple
property int diameter: 0
property int pressX: 0
property int pressY: 0
x: pressX - radius
y: pressY - radius
color: "green"
radius: diameter / 2
width: diameter
height: diameter
opacity: 1 - diameter / control.tripleWidth
function animate(x, y, size) {
pressX = x
pressY = y
diameter = size
}
Behavior on diameter {
PropertyAnimation {
duration: 200
onRunningChanged: {
if(!running) {
duration = 0;
ripple.diameter = 0;
duration = 200;
}
}
}
}
}
}
onClicked: {
ripple.animate(pressX, pressY, control.tripleWidth)
}
contentItem: Item {
implicitWidth: txt.implicitWidth
implicitHeight: 20
Text {
id: txt
anchors.centerIn: parent
text: control.text
}
}
}
I Edit last Answer and its work.. Here is How:
import QtQuick 2.5
import QtQuick.Window 2.5
import QtQuick.Controls 2.5
RoundButton {
id: control
width: 93
height: 39
property int tripleWidth: width * 3
background: Rectangle {
border.width: 1
border.color: "black"
radius: 3
color: "white"
clip: true
Rectangle {
id: ripple
property int diameter: 0
property int pressX: 0
property int pressY: 0
x: pressX - radius
y: pressY - radius
color: "green"
radius: diameter / 2
width: diameter
height: diameter
opacity: 1
function animate(x, y, size) {
pressX = x
pressY = y
diameter = size
}
Behavior on diameter {
PropertyAnimation {
duration: 300
}
}
}
}
onHoveredChanged: {
ripple.opacity = 0
ripple.diameter = 0
}
onPressed: {
ripple.opacity = 0.8
ripple.animate(pressX, pressY, control.tripleWidth)
}
Timer {
id: timer
}
contentItem: Item {
implicitWidth: txt.implicitWidth
implicitHeight: 20
Text {
id: txt
font.pointSize: 15
anchors.centerIn: parent
}
}
onClicked: {
function delay(delayTime, cb) {
timer.interval = delayTime;
timer.repeat = false;
timer.triggered.connect(cb);
timer.start();
}
delay(10, function() {
ripple.opacity = 0
ripple.diameter = 0
})
}
}
Try it....

Spin box only works when up/down indicators are clicked, it does NOT works when it is edited by entering numbers

I have this Qt QML spinbox:
The problem is, it actually changes value only when up/down (+/-) indicators are clicked. When edited by entering numbers into spinbox, it does NOT change value. I have tried many things, but I cannot figure out why. Can anybody help?
QML code of the spinbox is this:
StyledSpinBox {
id: overhangAngleFactorSpinBox
implicitWidth: 120
implicitHeight: 30
to: 1 * 100
stepSize: 1
from: 0
Layout.leftMargin: 8
contentItem: StyledTextInput {
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
value: 70
property int decimals: 2
property real realValue: value / 100.0
validator: DoubleValidator {
bottom: Math.min(overhangAngleFactorSpinBox.from, overhangAngleFactorSpinBox.to)
top: Math.max(overhangAngleFactorSpinBox.from, overhangAngleFactorSpinBox.to)
}
textFromValue: function(value, locale) {
return Number(value / 100.0).toLocaleString(locale, 'f', overhangAngleFactorSpinBox.decimals)
}
valueFromText: function(text, locale) {
return Number.fromLocaleString(locale, text) * 100.0
}
onValueChanged: {
editorScene.overhangAngleFactor = value / 100.0
}
}
StyledSpinBox.qml contains:
import QtQuick 2.5
import QtQuick.Controls 2.0 as QQC2
QQC2.SpinBox {
id: control
font.family: editorContent.labelFontFamily
font.weight: editorContent.labelFontWeight
font.pixelSize: editorContent.labelFontPixelSize
background: Rectangle {
border.color: editorContent.listHighlightColor
color: editorContent.paneBackgroundColor
}
down.indicator: Rectangle {
x: control.mirrored ? parent.width - width : 0
height: parent.height
implicitWidth: 40
implicitHeight: 40
border.color: editorContent.listHighlightColor
color: editorContent.listHighlightColor
Image {
anchors.centerIn: parent
source: "images/spinbox_down.png"
}
}
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
border.color: editorContent.listHighlightColor
color: editorContent.listHighlightColor
Image {
anchors.centerIn: parent
source: "images/spinbox_up.png"
}
}
}
Problem solved by adding editable: true to spin box. According to documentation, the default value for editable is false:
editable : bool
This property holds whether the spinbox is editable. The default value is false.

QML Slider Handle is not moving

I am having issues in moving a slider handle when I try to style "handle:Rectangle" ,Below is the code:
Slider {
id: slider
x: 372
y: 70
width: 33
height: 457
spacing: 0
anchors.rightMargin: 395
rotation: 0
orientation: Qt.Vertical
font.family: "Arial"
value: 0.5
anchors.right: parent.right
background: Rectangle {
anchors.centerIn: parent
x: slider.topPadding + slider.availableWidth / 2 - width / 2
y: slider.leftPadding
implicitWidth: 200
implicitHeight: 4
width: slider.availableHeight
height: implicitHeight
radius: 2
rotation: 90
color: "#bdbebf"
}
handle: Rectangle {
anchors.centerIn: parent
color: slider.pressed ? "white" : "red"
border.color: "gray"
//border.width: 2
width: 20
height: 20
radius: 6
}
}
I am able to move the slider if i am not styling handle:Rectangle.
please Suggest.
That is, because you can't anchor it to the center. You need to specify the x and y values in dependance of the visualPosition.
See the example on how to customize a slider.
Be aware, that the customization provided there does not account for vertical sliders, so you need to adapt it:
y: slider.topPadding + slider.visualPosition * (slider.availableHeight - height)
x: slider.leftPadding + slider.availableWidth / 2 - width / 2
should do it for you. Remove the anchoring of course!

How to drag / slide a element in QML without changing its x,y position?

I am working on development of a UI where i am required to implement something similar effect of dragging the status bar in any smart phone.
This should slide the element downwards on click.(which means its height is increased)
I tried using the following code to take of " NO x,y values change " of the element
MouseArea{
id : zone2MouseArea
anchors.fill : parent
drag.target: zone2ID
drag.axis: Drag.YAxis
drag.minimumY: 0
drag.maximumY: 0.1
}
and onYChanged () i increased the height.
However this does not suffice my requirement. I need to slide the element changing its view interms of height without changing its x,y values
I have made a basic example. Hope it helps. I dont have an IDE with me as of now, so please check for syntax errors
import QtQuick 1.1
Rectangle
{
width: 560
height: 560
color: "blue"
Rectangle
{
id: slider
width: parent.width
height: parent.height
y: - parent.height * .90
color: "yellow"
property bool isAtTop: true
Behavior on y { NumberAnimation { duration: 300 } }
Text
{
text: qsTr("12:34 PM")
anchors.bottom: parent.bottom
color: "black"
}
Text
{
text: qsTr("Battery | Wifi | Updates")
anchors.centerIn: parent
color: "black"
font.pixelSize: 25
}
MouseArea
{
id: draggingMouse
anchors.fill : parent
drag.target: parent
drag.axis: Drag.YAxis
drag.minimumY: - parent.height * .90
drag.maximumY: 0
onReleased:
{
if ( true == slider.isAtTop )
{
if( slider.y < - parent.height * .80 )
slider.y = - parent.height * .90
else
{
slider.y = 0
slider.isAtTop = false
}
}
else
{
if( slider.y < - parent.height * .20 )
{
slider.y = - parent.height * .90
slider.isAtTop = true
}
else
{
slider.y = 0
}
}
}
}
}
}

Resources