aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/qmldesigner/connectionseditor/Pill.qml
blob: 1a6d2681f50a8e63d9ae36115dfc80338aa55b51 (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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

import QtQuick
import StudioControls as StudioControls
import StudioTheme as StudioTheme

FocusScope {
    id: root

    required property int index
    required property string value
    required property int type

    function setCursorBegin() { textInput.cursorPosition = 0 }
    function setCursorEnd() { textInput.cursorPosition = textInput.text.length }

    function isEditable() { return root.type === ConditionListModel.Intermediate
                                   || root.type === ConditionListModel.Literal
                                   || root.type === ConditionListModel.Invalid }

    function isIntermediate() { return root.type === ConditionListModel.Intermediate }
    function isLiteral() { return root.type === ConditionListModel.Literal }
    function isOperator() { return root.type === ConditionListModel.Operator }
    function isProperty() { return root.type === ConditionListModel.Variable }
    function isShadow() { return root.type === ConditionListModel.Shadow }
    function isInvalid() { return root.type === ConditionListModel.Invalid }

    signal remove()
    signal update(var value)
    signal submit(int cursorPosition)

    readonly property int margin: StudioTheme.Values.flowPillMargin
    property var operatorModel

    property bool hovered: rootMouseArea.containsMouse
    property bool selected: root.focus

    property int maxTextWidth: 600

    width: row.width
    height: StudioTheme.Values.flowPillHeight

    onActiveFocusChanged: {
        if (root.activeFocus && root.isEditable())
            textInput.forceActiveFocus()
    }

    Keys.onPressed: function (event) {
        if (root.isEditable())
            return

        if (event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete)
            root.remove()
    }

    MouseArea {
        id: rootMouseArea
        anchors.fill: parent
        hoverEnabled: true
        cursorShape: root.isEditable() ? Qt.IBeamCursor : Qt.ArrowCursor
        onClicked: root.forceActiveFocus()
    }

    Rectangle {
        id: pill
        anchors.fill: parent
        color: {
            if (root.isIntermediate())
                return "transparent"

            if (root.isShadow())
                return StudioTheme.Values.themePillShadowBackground

            if (root.isInvalid() && root.selected)
                return StudioTheme.Values.themeWarning

            if (root.hovered) {
                if (root.isOperator())
                    return StudioTheme.Values.themePillOperatorBackgroundHover
                if (root.isLiteral())
                    return StudioTheme.Values.themePillLiteralBackgroundHover

                return StudioTheme.Values.themePillDefaultBackgroundHover
            }

            if (root.isLiteral())
                return StudioTheme.Values.themePillLiteralBackgroundIdle

            if (root.isOperator())
                return StudioTheme.Values.themePillOperatorBackgroundIdle

            return StudioTheme.Values.themePillDefaultBackgroundIdle
        }
        border.color: root.isInvalid() ? StudioTheme.Values.themeWarning
                                       : StudioTheme.Values.themePillOutline
        border.width: {
            if (root.isShadow())
                return 0
            if (root.isInvalid())
                 return 1
            if (root.isEditable())
                return 0
            if (root.selected)
                return 1

            return 0
        }
        radius: StudioTheme.Values.flowPillRadius

        Row {
            id: row
            leftPadding: root.margin
            rightPadding: icon.visible ? 0 : root.margin

            property int textWidth: Math.min(textMetrics.width,
                                             root.maxTextWidth - row.leftPadding
                                             - (icon.visible ? icon.width : root.margin))

            TextMetrics {
                id: textMetrics
                text: textItem.visible ? textItem.text : textInput.text
                font: textItem.font
            }

            Text {
                id: textItem
                width: row.textWidth
                height: StudioTheme.Values.flowPillHeight
                verticalAlignment: Text.AlignVCenter
                textFormat: Text.PlainText
                elide: Text.ElideMiddle
                font.pixelSize: StudioTheme.Values.baseFontSize
                color: root.isShadow() ? StudioTheme.Values.themePillTextSelected
                                       : StudioTheme.Values.themePillText
                text: root.isOperator() ? root.operatorModel.convertValueToName(root.value)
                                        : root.value
                visible: root.isOperator() || root.isProperty() || root.isShadow()
            }

            TextInput {
                id: textInput
                x: root.isInvalid() ? root.margin : 0
                width: row.textWidth
                height: StudioTheme.Values.flowPillHeight
                topPadding: 1
                clip: true
                font.pixelSize: StudioTheme.Values.baseFontSize
                color: {
                    if (root.isIntermediate())
                        return StudioTheme.Values.themePillTextEdit
                    if (root.isInvalid() && root.selected)
                        return StudioTheme.Values.themePillTextSelected
                    return StudioTheme.Values.themePillText
                }

                selectedTextColor:StudioTheme.Values.themePillTextSelected
                selectionColor: StudioTheme.Values.themeInteraction

                text: root.value
                visible: !textItem.visible
                enabled: root.isEditable()

                onEditingFinished: {
                    root.update(textInput.text) // emit
                    root.submit(textInput.cursorPosition) // emit
                }

                Keys.onReleased: function (event) {
                    if (event.key === Qt.Key_Backspace) {
                        if (textInput.text !== "")
                            return

                        root.remove() // emit
                    }
                }
            }

            Item {
                id: icon
                width: StudioTheme.Values.flowPillHeight
                height: StudioTheme.Values.flowPillHeight
                visible: !root.isShadow() && !root.isIntermediate()

                Text {
                    font.family: StudioTheme.Constants.iconFont.family
                    font.pixelSize: StudioTheme.Values.smallIconFontSize
                    color: root.isInvalid() && root.selected ? StudioTheme.Values.themePillTextSelected
                                                             : StudioTheme.Values.themePillText
                    text: StudioTheme.Constants.close_small
                    anchors.centerIn: parent
                }

                MouseArea {
                    id: mouseArea
                    anchors.fill: parent
                    onClicked: root.remove()
                }
            }
        }
    }
}