Łukasz Przeniosło
Łukasz Przeniosło

Reputation: 2959

Cast a shadow with Popup

Here is my MWE:

import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick 2.0
import QtGraphicalEffects 1.0

ApplicationWindow
{
    id: window
    width: 400
    height: 400
    visible: true

    Button
    {
        text: "Open"
        onClicked: popup.open()
    }

    Popup
    {
        id: popup

        x: 100
        y: 100
        width: 200
        height: 300
        modal: true
        focus: true
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

        Rectangle
        {
            id: popRect;
            color: "red";

            //anchors.centerIn: parent
            width: parent.width;
            height: parent.height;
        }
    }

    DropShadow
    {
        id: theShadow;

        visible: true;
        anchors.fill: popup;
        horizontalOffset: 0;
        verticalOffset: 5;
        radius: 3;
        samples: 7;
        color: "black";
        source: popup;
    }
}

What I am trying to do is to cast a shadow by the popup on the window underneath. The provided code does not work and I do not know how to work it out. The rectangle could also cover the whole Popup and cast the shadow, but I believe that in that case the shadow would be cast on the Popup, not underneath window.

Edit

This works after the answer given:

import QtQuick.Window 2.2
import QtQuick.Controls 2.1
import QtQuick 2.0
import QtGraphicalEffects 1.0

ApplicationWindow
{
    id: window
    width: 400
    height: 400
    visible: true

    Button
    {
        text: "Open"
        onClicked: popup.open()
    }

    Popup
    {
        id: popup

        x: 100
        y: 100
        width: 200
        height: 300
        modal: true
        focus: true
        closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

        leftPadding: 0;
        rightPadding: 0;
        topPadding: 0;
        bottomPadding: 0;

        Rectangle
        {
            id: popRect;
            color: "red";

            //anchors.centerIn: parent
            width: parent.width;
            height: parent.height;
        }

        DropShadow
        {
            width: popup.width;
            height: popup.height;

            source: popRect;

            horizontalOffset: 0;
            verticalOffset: 5;
            radius: 10;
            samples: 7;
            color: "black";
        }
    }
}

Upvotes: 0

Views: 1856

Answers (1)

Amfasis
Amfasis

Reputation: 4208

I struggled with the same situation the other day. Here is my solution:

Popup {
    id: popup

    background: Corner{   //custom control I made, which has a slanted corner
        id: backCorner
    }

    DropShadow {
        width: popup.width
        height: popup.height
        x: -leftPadding
        y: -topPadding

        source: backCorner
        color: "#80000000"
        verticalOffset: 10
        samples: 30
    }
}

It is a bit uggly, because you would want to use the anchoring, but I think it cannot work out the correct size of the popup anymore (I think I found a solution for that as well, but still have to try, will update if working)

Edit

Yes, the other solution would be to combine the background with the DropShadow

background: Item {
    IOSCorner{
        anchors.fill: parent
        id: backCorner
    }

    DropShadow {
        anchors.fill: parent
        source: backCorner
        color: "#80000000"
        verticalOffset: 10
        samples: 30
    }
}

It looks like the size calculations of the popup can now handle the shadow. If you look at the code of the popup you might understand; the DropShadow becomes a child and since it is the first child it will lead the size calculation

implicitWidth: Math.max(background ? background.implicitWidth : 0, contentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(background ? background.implicitHeight : 0, contentHeight + topPadding + bottomPadding)

contentWidth: contentItem.implicitWidth || (contentChildren.length === 1 ? contentChildren[0].implicitWidth : 0)
contentHeight: contentItem.implicitHeight || (contentChildren.length === 1 ? contentChildren[0].implicitHeight : 0)

Upvotes: 2

Related Questions