aboutsummaryrefslogtreecommitdiffstats
path: root/src/labs/stylekit/impl/DelegateContainer.qml
blob: 496b4f9f5ef7813a97f75245561436d12c24174e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default

import QtQuick
import QtQuick.Effects
import QtQuick.Controls.impl
import QtQuick.Templates as T
import Qt.labs.StyleKit
import Qt.labs.StyleKit.impl

// This container takes care of loading, positioning, and resizing the delegate.
Item {
    id: root

    /* If an implicit size has been set the style, it wins.
     * Otherwise we use the implicit size of the instantiated delegate. */
    implicitWidth: delegateProperties.implicitWidth > 0
                      ? delegateProperties.implicitWidth
                      : delegateInstance
                        ? delegateInstance.implicitWidth
                        : 0

    implicitHeight: delegateProperties.implicitHeight > 0
                       ? delegateProperties.implicitHeight
                       : delegateInstance
                         ? delegateInstance.implicitHeight
                         : 0

    scale: delegateProperties.scale
    rotation: delegateProperties.rotation
    visible: delegateProperties.visible

    required property QtObject parentControl
    required property StyleKitDelegateProperties delegateProperties

    property real leftMargin: delegateProperties.leftMargin
    property real rightMargin: delegateProperties.rightMargin
    property real topMargin: delegateProperties.topMargin
    property real bottomMargin: delegateProperties.bottomMargin

    readonly property real marginWidth: leftMargin + rightMargin
    readonly property real marginHeight: topMargin + bottomMargin
    readonly property real subDelegateWidth: width
    readonly property real subDelegateHeight: height

    onDelegatePropertiesChanged: {
        instantiateDelegate()
        instantiateShadowDelegate();
    }

    onVisibleChanged: {
        instantiateDelegate()
        instantiateShadowDelegate();
     }

    Connections {
        target: delegateProperties
        function onDelegateChanged() { instantiateDelegate() }
    }

    Connections {
        target: delegateProperties.shadow
        function onDelegateChanged() { instantiateShadowDelegate() }
        function onColorChanged() { instantiateShadowDelegate() }
        function onOpacityChanged() { instantiateShadowDelegate() }
        function onVisibleChanged() { instantiateShadowDelegate() }
    }

    Item {
        id: centerContainer
        width: root.subDelegateWidth
        height: root.subDelegateHeight
    }

    // Uncomment to draw overlay:
    // Rectangle {
    //     id: debugRectForMargins
    //     x: centerContainer.x
    //     y: centerContainer.y
    //     z: 5
    //     width: root.subDelegateWidth
    //     height: root.subDelegateHeight
    //     color: "transparent"
    //     border.color: "limegreen"
    //     border.width: 1
    // }

    // Rectangle {
    //     id: debugRectForDelegate
    //     z: 5
    //     width: root.width
    //     height: root.height
    //     color: "transparent"
    //     border.color: "magenta"
    //     border.width: 1
    // }

    // ------------------------------------------

    property Item delegateInstance: null
    property Component effectiveDelegate: null

    // onImplicitWidthChanged: {
    //     if (parentControl && parentControl instanceof T.CheckBox) {
    //         print("DelegateContainer delegateInstance changed to " + delegateInstance)
    //         print("delegate instance implicitWidth: " + (delegateInstance ? delegateInstance.implicitWidth : "N/A"))
    //     }
    // }
    // onWidthChanged: {
    //     if (parentControl && parentControl instanceof T.CheckBox) {
    //         print("DelegateContainer width changed to " + width)
    //         print("delegate instance width: " + (delegateInstance ? delegateInstance.width : "N/A"))
    //     }
    // }

    function instantiateDelegate() {
        if (!visible || !StyleKit.styleLoaded())
            return

        let delegate = root.delegateProperties.delegate
        if (!delegate)
            delegate = DelegateSingleton.defaultDelegate
        if (delegate === effectiveDelegate)
            return

        effectiveDelegate = delegate
        let prevInstance = delegateInstance
        if (delegate)
            delegateInstance = delegate
                    ? delegate.createObject(
                          centerContainer,
                          { delegateProperties: root.delegateProperties, control: root.parentControl })
                    : null

        if (prevInstance)
            prevInstance.destroy()
    }

    // ------------------------------------------

    property Item shadowInstance: null
    property Component effectiveShadowDelegate: null

    function instantiateShadowDelegate() {
        if (!visible || !StyleKit.styleLoaded())
            return

        const shadowProps = root.delegateProperties.shadow
        const delegate = shadowProps.delegate
                       ? shadowProps.delegate : DelegateSingleton.defaultShadowDelegate
        if (delegate === effectiveShadowDelegate)
            return

        // Delay instantiating delegate until needed
        if (!shadowProps.visible || shadowProps.color.a === 0 || shadowProps.opacity === 0)
            return

        let prevDelegateInstance = shadowInstance
        effectiveShadowDelegate = delegate
        shadowInstance = delegate
                ? delegate.createObject(
                      root,
                      { z: -1, delegateProperties: root.delegateProperties, control: root.parentControl })
                : null

        if (prevDelegateInstance)
            prevDelegateInstance.destroy()
    }

}