I have the following problem:
I have a ListView with movies like this:
I would like at the moment when I will click into a movie to get a bit bigger on with and high independently the rest of them, but for some reason, I'm getting this.
I've increased the width size by a lot just to show my problem, in reality, it doesn't need to be that big.
Could you explain to me why it's keeping the shape of that button even those the scaling is right except for the actual shape?
Here is how I'm using my custom widget (it's a delegate for a ListView):
SideButtons {
id: imageButton
property int recDynamicHeight: listViewID.height/10 * 5
property int recOriginalHeight: listViewID.height/10 * 5
property int recDynamiclWidth: listViewID.width/10 * 1.2
property int recOriginalWidth: listViewID.width/10 * 1.2
roundedCorners: ['TL','TR']
clickable: false
radius: 20
width: recDynamiclWidth
height: recDynamicHeight
backgroundImage: model.imgUrl
Text {
property bool isVisible: false
color: "#ffffff"
anchors.fill: parent
visible: textid.isVisible
id: textid
text: model.title
font.bold: true
horizontalAlignment: Text.AlignLeft
font.pixelSize: listViewID.width/8/9
topPadding: listViewID.width/8/9
leftPadding: listViewID.width/8/9
}
Text {
anchors.topMargin: listViewID.width/8/9
color: "#ffffff"
anchors.fill: parent
visible: textid.isVisible
id: yearId
text: model.year
horizontalAlignment: Text.AlignLeft
font.pixelSize: listViewID.width/8/9
topPadding: listViewID.width/8/9*2
leftPadding: listViewID.width/8/9
}
onRelease: {
console.log("release")
imageButton.recDynamicHeight = imageButton.recOriginalHeight;
imageButton.recDynamiclWidth = imageButton.recOriginalWidth;
textid.isVisible = false;
textid.visible = textid.isVisible;
}
onPressed: {
console.log("pressed")
imageButton.recDynamicHeight = imageButton.recOriginalHeight;
imageButton.recDynamicHeight += imageButton.recDynamicHeight * 10/100;
imageButton.recDynamiclWidth += 400;
textid.isVisible = true;
textid.visible = textid.isVisible;
}
onClicked: {
load_page(PageType.movie_detailed_view, model.title, model.description, model.imgUrl, model.type, model.year)
}
}
And here it's the actuall code from SideButton:
Item {
id: sideButtonID
property var coordinates: generateButtonShapeCoordinates(width, height)
property bool hasRoundedCorners: true
property var roundedCorners: ['TL','TR','BR','BL']
property var backgroundImage: ""
property var clickable: true
property int radius: 10
property alias mouseX: mouseArea.mouseX
property alias mouseY: mouseArea.mouseY
readonly property bool pressedOnArea: containsMouse && mouseArea.pressed
onPressedOnAreaChanged: canvasID.requestPaint()
property point topLeftOffset: Qt.point(0, 0)
property point topRightOffset: Qt.point(0, 0)
property point bottomRightOffset: Qt.point(0, 0)
property point bottomLeftOffset: Qt.point(0, 0)
property var icon: ""
property var colorPressed: "green"
property var colorSelected: "#434343"
property var colorUnselected: "#434343"
signal clicked
signal release
signal pressed
function noRoundedCornersShapeCoordinates(width, height){
var topLeft = Qt.point(topLeftOffset.x, topLeftOffset.y)
var topRight = Qt.point(width - topRightOffset.x, topRightOffset.y)
var bottomRight = Qt.point(width - bottomRightOffset.x, height - bottomRightOffset.y)
var bottomLeft = Qt.point(bottomLeftOffset.x, height - bottomLeftOffset.y)
return {
topLeft : topLeft,
topRight : topRight,
bottomRight : bottomRight,
bottomLeft : bottomLeft
};
}
function roundedCornersShapeCoordinates(width, height){
var offset = radius
var topLeftOr = Qt.point(topLeftOffset.x, topLeftOffset.y)
var topLeftDown = Qt.point(topLeftOffset.x, topLeftOffset.y +offset)
var topLeftRight = Qt.point(topLeftOffset.x + offset, topLeftOffset.y)
var topRightOr = Qt.point(width - topRightOffset.x, topRightOffset.y)
var topRightLeft = Qt.point(width - topRightOffset.x - offset, topRightOffset.y)
var topRightDown = Qt.point(width - topRightOffset.x, topRightOffset.y + offset)
var bottomRightOr = Qt.point(width - bottomRightOffset.x, height - bottomRightOffset.y)
var bottomRightTop = Qt.point(width - bottomRightOffset.x, height - bottomRightOffset.y -offset)
var bottomRightLeft = Qt.point(width - bottomRightOffset.x - offset, height - bottomRightOffset.y)
var bottomLeftOr = Qt.point(bottomLeftOffset.x, height - bottomLeftOffset.y)
var bottomLeftDown = Qt.point(bottomLeftOffset.x + offset, height - bottomLeftOffset.y)
var bottomLeftLeft = Qt.point(bottomLeftOffset.x, height - bottomLeftOffset.y -offset)
return {
topLeftDown : topLeftDown,
topLeftOr : topLeftOr,
topLeftRight : topLeftRight,
topRightLeft : topRightLeft,
topRightOr : topRightOr,
topRightDown : topRightDown,
bottomRightTop : bottomRightTop,
bottomRightOr : bottomRightOr,
bottomRightLeft : bottomRightLeft,
bottomLeftDown : bottomLeftDown,
bottomLeftOr : bottomLeftOr,
bottomLeftLeft : bottomLeftLeft,
};
}
function generateButtonShapeCoordinates(width, height){
if(hasRoundedCorners){
return roundedCornersShapeCoordinates(width, height)
}
else{
return noRoundedCornersShapeCoordinates(width, height)
}
}
function inside(point, polygon) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
var xi = polygon[i][0], yi = polygon[i][1];
var xj = polygon[j][0], yj = polygon[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
property bool containsMouse: {
var corners = coordinates
var polygon =[[]]
for (const [key, value] of Object.entries(corners)) {
polygon.push([corners[key].x,corners[key].y])
}
var point = [mouseX, mouseY]
return inside(point, polygon)
}
MouseArea {
id: mouseArea
propagateComposedEvents: true
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (sideButtonID.containsMouse){
sideButtonID.clicked();
}
else{
mouse.accepted = false;
return;
}
}
onReleased : sideButtonID.release();
onPressed: {
if (sideButtonID.containsMouse){
sideButtonID.pressed();
}
else{
mouse.accepted = false;
return;
}
}
}
Shape {
id: shapeRootID
antialiasing: true
vendorExtensionsEnabled: true
asynchronous: true
anchors.fill: parent
Canvas {
id: canvasID
anchors.fill: parent
onImageLoaded: requestPaint()
onPaint: {
var ctx = getContext("2d");
if(clickable)
ctx.fillStyle = pressedOnArea ? colorPressed : (containsMouse ? colorSelected : colorUnselected)
ctx.lineWidth = 2;
ctx.beginPath();
var corners = coordinates
var firstTime = true
if(!hasRoundedCorners){
ctx.moveTo(corners['topLeft'].x,corners['topLeft'].y)
ctx.lineTo(corners['topRight'].x,corners['topRight'].y)
ctx.lineTo(corners['bottomRight'].x,corners['bottomRight'].y)
ctx.lineTo(corners['bottomLeft'].x,corners['bottomLeft'].y)
}
else{
//https://www.w3schools.com/tags/canvas_arcto.asp
var radius = sideButtonID.radius
if(roundedCorners.includes('TL')){
ctx.moveTo(corners['topLeftDown'].x,corners['topLeftDown'].y);
ctx.arcTo(corners['topLeftOr'].x,corners['topLeftOr'].y,
corners['topLeftRight'].x+radius, corners['topLeftRight'].y,
radius)
}
else{
ctx.moveTo(corners['topLeftOr'].x,corners['topLeftOr'].y);
}
if(roundedCorners.includes('TR')){
ctx.lineTo(corners['topRightLeft'].x, corners['topRightLeft'].y);
ctx.arcTo(corners['topRightOr'].x,corners['topRightOr'].y,
corners['topRightDown'].x, corners['topRightDown'].y+radius,
radius)
}
else{
ctx.lineTo(corners['topRightOr'].x, corners['topRightOr'].y);
}
if(roundedCorners.includes('BR')){
ctx.lineTo(corners['bottomRightTop'].x, corners['bottomRightTop'].y);
ctx.arcTo(corners['bottomRightOr'].x,corners['bottomRightOr'].y,
corners['bottomRightLeft'].x - radius, corners['bottomRightLeft'].y,
radius)
}
else{
ctx.lineTo(corners['bottomRightOr'].x, corners['bottomRightOr'].y)
}
if(roundedCorners.includes('BL')){
ctx.lineTo(corners['bottomLeftDown'].x, corners['bottomLeftDown'].y);
ctx.arcTo(corners['bottomLeftOr'].x,corners['bottomLeftOr'].y,
corners['bottomLeftLeft'].x, corners['bottomLeftLeft'].y - radius,
radius)
}
else{
ctx.lineTo(corners['bottomLeftOr'].x, corners['bottomLeftOr'].y)
}
}
ctx.fill()
if(backgroundImage != ""){
ctx.clip()
ctx.drawImage(backgroundImage,0,0, parent.width, parent.height);
}
}
}
}
Image {
x: 0
y: 0
anchors.right: parent.right
anchors.rightMargin: 3
anchors.left: parent.left
anchors.leftMargin: 6
clip: true
anchors.verticalCenterOffset: 0
anchors.verticalCenter: mouseArea.verticalCenter
fillMode: Image.PreserveAspectFit
source: sideButtonID.icon
}
}
Does any of you what I'm doing wrong and if so how can I fix it? I've spent so many hours and I didn't get the problem because so far as I know all the resolutions are been set right inside of that button.