I'm trying to achieve a simple Sliding Bar in QML. Here's a prerequisite I have to follow: no SVG images ( for some BR I cannot discuss here ).
Rectangle {
id: backgroundPower
anchors.fill: parent
color: "#a2aaae"
radius: 50
MouseArea {
id: progressArea
anchors.fill: parent
onPositionChanged: {
updateValue(progressArea.mouseX)
}
onReleased: {
updateValue(progressArea.mouseX)
}
onClicked: updateValue(progressArea.mouseX)
}
Rectangle {
id: powerImage
width: calculateWidth()
radius: 100
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.top: parent.top
LinearGradient {
id: defaultGradient
anchors.fill: parent
source: powerImage
start: Qt.point(0, 0)
end: Qt.point(0, powerImage.height)
gradient: Gradient {
GradientStop { position: 0.0; color: "#46c0e4" }
GradientStop { position: 0.50; color: "#0583ca" }
GradientStop { position: 0.95; color: "#fbffff" }
GradientStop { position: 1.0; color: "#fbffff" }
}
}
Here's what I obtain with this code when the bar is at 100%:

When I update the value ( mouse area events ) I change the width of the powerImage with the function:
var maxWidth = powerImage.parent.width
var currentWidth = (maxWidth * barPercentage) / 100
if (currentWidth >= maxWidth){
currentWidth = maxWidth
}
PROBLEM
When the percentage of the bar reaches a low value ( like 10% ) I cannot fit the bar into the background, like this:

you can see how the bar doesn't fin anymore. I know the problem is linked to the rectangle ( powerImage ) and its radius. But I don't know how to fix this. Clearly with a SVG it's really simple but in this case, I cannot use this. Is there a way to show the bar when it's only inside the background rectangle?
Unfortunately it is not possible to use clip: true on non-rectangular regions.
But following this answer, you can use an OpacityMask:
Rectangle {
id: backgroundPower
anchors.fill: parent
color: "#a2aaae"
radius: 50
MouseArea {
// ...
}
}
Item {
anchors.fill: backgroundPower
layer.enabled: true
layer.effect: OpacityMask {
maskSource: backgroundPower
}
Rectangle {
id: powerImage
// ...
}
}
Result:

But as mentionned in the answer:
But using it will be GPU consuming task as the inner item and mask have to be drawn on buffer first and then redrawn on window, so not very good for old mobile or weak embedded devices.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With