5import QtQuick.Templates as T
6import QtQuick.Controls.impl as TImpl
8import "../core/UiMetrics.js" as UiMetrics
9import "../internal/MotionAnimation.js" as MotionAnimation
27 component IconData: QtObject {
31 property bool fill:
false
94 property int widthVariant:
IconButton.Width.Default
102 property IconData checkedIcon: IconData {}
105 property bool mirrorIconInRtl:
false
111 property bool tintSourceIcon:
true
117 property color contentColor: {
120 return checked ? MD.Style.onPrimaryColor : MD.Style.onSurfaceVariantColor;
122 return checked ? MD.Style.onSecondaryColor : MD.Style.onSecondaryContainerColor;
124 return checked ? MD.Style.inverseOnSurfaceColor : MD.Style.onSurfaceVariantColor;
126 return checked ? MD.Style.primaryColor : MD.Style.onSurfaceVariantColor;
134 property color containerColor: {
137 return checked ? MD.Style.primaryColor : MD.Style.surfaceContainerColor;
139 return checked ? MD.Style.secondaryColor : MD.Style.secondaryContainerColor;
141 return checked ? MD.Style.inverseSurfaceColor :
"transparent";
143 return "transparent";
148 property color disabledContentColor: MD.Style.onSurfaceColor
151 property color disabledContainerColor: MD.Style.onSurfaceColor
154 property color outlineColor: MD.Style.outlineVariantColor
157 readonly
property color effectiveContentColor: state.contentColor
160 readonly
property real effectiveContentOpacity: state.contentOpacity
163 readonly
property color effectiveContainerColor: state.containerColor
166 readonly
property bool usingCheckedIcon: checked && (checkedIcon.name.length > 0 || checkedIcon.source.toString().length > 0)
169 readonly property
string effectiveIconName: usingCheckedIcon ? checkedIcon.name : icon.name
172 readonly property url effectiveIconSource: usingCheckedIcon ? checkedIcon.source : icon.source
175 readonly property color effectiveIconColor: {
176 const explicitColor = usingCheckedIcon ? checkedIcon.color : icon.color;
177 return explicitColor.a > 0 ? explicitColor : effectiveContentColor;
181 readonly
property bool effectiveIconFill: checked && (usingCheckedIcon ? checkedIcon.fill :
true)
184 readonly property
bool effectiveIconMirrored: mirrorIconInRtl && mirrored
186 icon.width: state.iconSize.width
187 icon.height: state.iconSize.height
189 implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding)
190 implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding)
192 leftInset: state.inset.width / 2
193 rightInset: state.inset.width / 2
194 topInset: state.inset.height / 2
195 bottomInset: state.inset.height / 2
202 focusPolicy: Qt.StrongFocus
207 readonly property real currentContainerHeight: {
208 switch (control.size) {
216 readonly
property real currentIconSize: {
217 switch (control.size) {
225 readonly
property real currentLeadingSpace: {
226 if (control.widthVariant ===
IconButton.Width.Narrow) {
227 switch (control.size) {
235 if (control.widthVariant ===
IconButton.Width.Wide) {
236 switch (control.size) {
244 switch (control.size) {
252 readonly
property real currentTrailingSpace: {
253 if (control.widthVariant ===
IconButton.Width.Narrow) {
254 switch (control.size) {
262 if (control.widthVariant ===
IconButton.Width.Wide) {
263 switch (control.size) {
271 switch (control.size) {
279 readonly
property real outlineWidth: {
280 switch (control.size) {
288 property size buttonSize: Qt.size(currentIconSize + currentLeadingSpace + currentTrailingSpace, currentContainerHeight)
289 property size iconSize: Qt.size(currentIconSize, currentIconSize)
291 property size inset: {
292 const minimum = MD.Tokens.iconButton.minimumInteractiveSize;
293 return Qt.size(Math.max(minimum, state.buttonSize.width) - state.buttonSize.width,
294 Math.max(minimum, state.buttonSize.height) - state.buttonSize.height);
297 property MD.shapeValue containerShape: {
298 const tokens = MD.Tokens.iconButton;
299 if (control.pressed) {
300 switch (control.size) {
308 if (control.checked) {
309 if (control.shape ===
IconButton.Shape.Square)
310 return tokens.selectedContainerShapeSquare;
311 switch (control.size) {
320 return tokens.containerShapeRound;
321 switch (control.size) {
330 property color containerColor: control.containerColor
331 property color contentColor: control.contentColor
332 property color stateLayerColor:
"transparent"
334 property real contentOpacity: 1.0
335 property real containerOpacity: 1.0
336 property real stateLayerOpacity: 0.0
342 when: !control.enabled
345 state.containerColor: control.type ===
IconButton.Type.Standard ?
"transparent" : control.disabledContainerColor
346 state.contentColor: control.disabledContentColor
348 state.contentOpacity: MD.Tokens.iconButton.disabledIconOpacity
353 when: control.down && control.enabled
356 state.stateLayerColor: control.effectiveIconColor
357 state.stateLayerOpacity: MD.Tokens.iconButton.pressedStateLayerOpacity
362 when: control.visualFocus && control.enabled
365 state.stateLayerColor: control.effectiveIconColor
366 state.stateLayerOpacity: MD.Tokens.iconButton.focusStateLayerOpacity
371 when: control.hovered && control.enabled
374 state.stateLayerColor: control.effectiveIconColor
375 state.stateLayerOpacity: MD.Tokens.iconButton.hoverStateLayerOpacity
383 implicitWidth: control.icon.width
384 implicitHeight: control.icon.height
387 origin.x: iconContent.width / 2
388 origin.y: iconContent.height / 2
389 xScale: control.effectiveIconMirrored ? -1 : 1
395 objectName:
"iconButtonSourceImage"
396 anchors.centerIn: parent
397 width: control.icon.width
398 height: control.icon.height
399 source: control.effectiveIconSource
400 sourceSize: Qt.size(control.icon.width, control.icon.height)
401 fillMode: Image.PreserveAspectFit
402 color: control.tintSourceIcon ? control.effectiveIconColor :
"transparent"
403 opacity: state.contentOpacity
404 visible: control.effectiveIconSource.toString().length > 0
408 objectName:
"iconButtonSymbol"
409 anchors.centerIn: parent
410 name: control.effectiveIconName
411 iconWidth: control.icon.width
412 iconHeight: control.icon.height
413 color: control.effectiveIconColor
414 opacity: state.contentOpacity
415 fill: control.effectiveIconFill
416 visible: control.effectiveIconSource.toString().length === 0 && name.length > 0
420 background: Rectangle {
421 implicitWidth: state.buttonSize.width
422 implicitHeight: state.buttonSize.height
424 topLeftRadius: UiMetrics.resolveShapeRadius(state.containerShape.topLeft, width, height)
425 topRightRadius: UiMetrics.resolveShapeRadius(state.containerShape.topRight, width, height)
426 bottomLeftRadius: UiMetrics.resolveShapeRadius(state.containerShape.bottomLeft, width, height)
427 bottomRightRadius: UiMetrics.resolveShapeRadius(state.containerShape.bottomRight, width, height)
429 Behavior on topLeftRadius {
431 easing.type: Easing.BezierSpline
432 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
433 duration: MotionAnimation.expressiveFastSpatialDuration
436 Behavior on topRightRadius {
438 easing.type: Easing.BezierSpline
439 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
440 duration: MotionAnimation.expressiveFastSpatialDuration
443 Behavior on bottomLeftRadius {
445 easing.type: Easing.BezierSpline
446 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
447 duration: MotionAnimation.expressiveFastSpatialDuration
450 Behavior on bottomRightRadius {
452 easing.type: Easing.BezierSpline
453 easing.bezierCurve: MotionAnimation.expressiveFastSpatialCurve
454 duration: MotionAnimation.expressiveFastSpatialDuration
458 border.width: control.type ===
IconButton.Type.Outlined && !control.checked ? state.outlineWidth : 0
459 border.color: control.outlineColor
461 opacity: state.containerOpacity
462 color: state.containerColor
467 topLeftRadius: parent.topLeftRadius
468 topRightRadius: parent.topRightRadius
469 bottomLeftRadius: parent.bottomLeftRadius
470 bottomRightRadius: parent.bottomRightRadius
472 pressed: control.pressed
473 pressX: control.pressX
474 pressY: control.pressY
476 stateOpacity: state.stateLayerOpacity
477 color: state.stateLayerColor