Fluid 1.3.0
Material Design for QtQuick and Qml
Loading...
Searching...
No Matches
IconLabel.qml
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
2// SPDX-License-Identifier: MPL-2.0
3
4import QtQuick
5import Fluid as MD
6
18Item {
19 id: root
20 Accessible.ignored: true
21
25 enum Display {
26 IconOnly,
27 TextOnly,
28 TextBesideIcon,
29 TextUnderIcon
30 }
31
32 component IconData: QtObject {
33 property string name
34 property real width: -1
35 property real height: -1
36 property color color
37 }
38
40 property IconData icon: IconData {}
41
43 property alias text: label.text
44
46 property alias typescale: label.typescale
47
49 property alias lineHeight: label.lineHeight
50
52 property alias color: label.color
53
55 property bool mirrored: false
56
60 readonly property bool hasIcon: icon.name.length > 0
61
65 readonly property bool showIcon: hasIcon && display !== IconLabel.TextOnly
66
70 readonly property bool showText: display !== IconLabel.IconOnly
71
75 property int display: IconLabel.TextBesideIcon
76
80 readonly property int effectiveDisplay: {
81 switch (display) {
82 case IconLabel.TextBesideIcon:
83 return showIcon ? display : IconLabel.TextOnly;
84 case IconLabel.TextUnderIcon:
85 return showIcon ? display : IconLabel.TextOnly;
86 default:
87 return display;
88 }
89 }
90
94 property real spacing: MD.Tokens.measurement.space100
95
99 readonly property real effectiveSpacing: showIcon && showText ? spacing : 0
100
101 implicitWidth: {
102 switch (effectiveDisplay) {
103 case IconLabel.IconOnly:
104 return iconItem.implicitWidth;
105 case IconLabel.TextOnly:
106 return label.implicitWidth;
107 case IconLabel.TextBesideIcon:
108 return iconItem.implicitWidth + label.implicitWidth + effectiveSpacing;
109 case IconLabel.TextUnderIcon:
110 return Math.max(iconItem.implicitWidth, label.implicitWidth);
111 }
112 }
113 implicitHeight: {
114 switch (effectiveDisplay) {
115 case IconLabel.IconOnly:
116 return iconItem.implicitHeight;
117 case IconLabel.TextOnly:
118 return label.implicitHeight;
119 case IconLabel.TextBesideIcon:
120 return Math.max(iconItem.implicitHeight, label.implicitHeight);
121 case IconLabel.TextUnderIcon:
122 return iconItem.implicitHeight + label.implicitHeight + effectiveSpacing;
123 }
124 }
125
126 LayoutMirroring.enabled: mirrored
127 LayoutMirroring.childrenInherit: true
128
129 MD.Symbol {
130 id: iconItem
131
132 name: root.icon.name
133 iconWidth: root.icon.width
134 iconHeight: root.icon.height
135 color: root.icon.color.a > 0 ? root.icon.color : label.color
136 visible: root.showIcon
137 }
138
139 MD.Label {
140 id: label
141
142 font.pixelSize: typescale.fontSize
143 font.weight: typescale.fontWeight
144 //font.letterSpacing: typescale.tracking
145
146 wrapMode: MD.Label.NoWrap
147 elide: MD.Label.ElideRight
148 visible: root.showText
149 }
150
151 states: [
152 State {
153 name: "iconOnly"
154 when: root.effectiveDisplay === IconLabel.IconOnly
155
156 AnchorChanges {
157 target: iconItem
158 anchors.left: undefined
159 anchors.right: undefined
160 anchors.top: undefined
161 anchors.bottom: undefined
162 anchors.horizontalCenter: root.horizontalCenter
163 anchors.verticalCenter: root.verticalCenter
164 }
165
166 AnchorChanges {
167 target: label
168 anchors.left: undefined
169 anchors.right: undefined
170 anchors.top: undefined
171 anchors.bottom: undefined
172 anchors.horizontalCenter: undefined
173 anchors.verticalCenter: undefined
174 }
175 },
176 State {
177 name: "textOnly"
178 when: root.effectiveDisplay === IconLabel.TextOnly
179
180 AnchorChanges {
181 target: label
182 anchors.left: undefined
183 anchors.right: undefined
184 anchors.top: undefined
185 anchors.bottom: undefined
186 anchors.horizontalCenter: root.horizontalCenter
187 anchors.verticalCenter: root.verticalCenter
188 }
189
190 AnchorChanges {
191 target: iconItem
192 anchors.left: undefined
193 anchors.right: undefined
194 anchors.top: undefined
195 anchors.bottom: undefined
196 anchors.horizontalCenter: undefined
197 anchors.verticalCenter: undefined
198 }
199 },
200 State {
201 name: "textBesideIcon"
202 when: root.effectiveDisplay === IconLabel.TextBesideIcon && !root.mirrored
203
204 AnchorChanges {
205 target: iconItem
206 anchors.left: root.left
207 anchors.right: undefined
208 anchors.top: undefined
209 anchors.bottom: undefined
210 anchors.horizontalCenter: undefined
211 anchors.verticalCenter: root.verticalCenter
212 }
213
214 AnchorChanges {
215 target: label
216 anchors.left: iconItem.right
217 anchors.right: undefined
218 anchors.top: undefined
219 anchors.bottom: undefined
220 anchors.horizontalCenter: undefined
221 anchors.verticalCenter: root.verticalCenter
222 }
223
224 PropertyChanges {
225 target: label
226 anchors.leftMargin: root.effectiveSpacing
227 anchors.rightMargin: 0
228 anchors.topMargin: 0
229 anchors.bottomMargin: 0
230 }
231 },
232 State {
233 name: "textBesideIconMirrored"
234 when: root.effectiveDisplay === IconLabel.TextBesideIcon && root.mirrored
235
236 AnchorChanges {
237 target: iconItem
238 anchors.left: undefined
239 anchors.right: root.right
240 anchors.top: undefined
241 anchors.bottom: undefined
242 anchors.horizontalCenter: undefined
243 anchors.verticalCenter: root.verticalCenter
244 }
245
246 AnchorChanges {
247 target: label
248 anchors.left: undefined
249 anchors.right: iconItem.left
250 anchors.top: undefined
251 anchors.bottom: undefined
252 anchors.horizontalCenter: undefined
253 anchors.verticalCenter: root.verticalCenter
254 }
255
256 PropertyChanges {
257 target: label
258 anchors.leftMargin: 0
259 anchors.rightMargin: root.effectiveSpacing
260 anchors.topMargin: 0
261 anchors.bottomMargin: 0
262 }
263 },
264 State {
265 name: "textUnderIcon"
266 when: root.effectiveDisplay === IconLabel.TextUnderIcon
267
268 AnchorChanges {
269 target: iconItem
270 anchors.left: undefined
271 anchors.right: undefined
272 anchors.top: root.top
273 anchors.bottom: undefined
274 anchors.horizontalCenter: root.horizontalCenter
275 anchors.verticalCenter: undefined
276 }
277
278 AnchorChanges {
279 target: label
280 anchors.left: undefined
281 anchors.right: undefined
282 anchors.top: iconItem.bottom
283 anchors.bottom: undefined
284 anchors.horizontalCenter: root.horizontalCenter
285 anchors.verticalCenter: undefined
286 }
287
288 PropertyChanges {
289 target: label
290 anchors.leftMargin: 0
291 anchors.rightMargin: 0
292 anchors.topMargin: root.effectiveSpacing
293 anchors.bottomMargin: 0
294 }
295 }
296 ]
297}
Lays out an icon and text as a single reusable visual.
Definition IconLabel.qml:16