Unsolved QML ListView Resize Custom Widget delegate
-
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 actual 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.