Делегат QML ListView Изменение размера пользовательского виджета - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть следующая проблема:

У меня есть ListView с такими фильмами: enter image description here

Мне бы хотелось, чтобы в тот момент, когда я нажму на MOV ie, чтобы получить немного больше и выше, независимо от остальных, но по некоторым причинам, я получаю это.

enter image description here

Я значительно увеличил размер ширины, чтобы показать мою проблему, на самом деле она не должна быть такой большой.

Не могли бы вы объяснить, почему она сохраняет форму этой кнопки? даже те, которые масштабируются правильно, за исключением фактической формы?


Вот как я использую свой пользовательский виджет (это делегат для 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)
    }
}

А вот и актуальный код от 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
    }
}

Кто-нибудь из вас, что я делаю не так, и если да, то как я могу Я чиню это? Я провел так много часов, и у меня не возникло проблем, потому что, насколько я знаю, все разрешения были установлены прямо внутри этой кнопки.

...