import QtQuick import Weave.Controls import Weave.Templates as T T.StepNode { id: root implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding, implicitIndicatorWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding, implicitIndicatorHeight + topPadding + bottomPadding) // If we are part of a StepIndicator // and the StepIndicator's dimensions are larger than its implicit dimensions, // then "spread" the extra space equally between each StepNode. width: inAccordion ? Math.max(parent.width, implicitWidth) : (!!root.StepIndicator.stepIndicator) ? (orientation === Qt.Vertical ? parent.width : (implicitWidth + (root.StepIndicator.stepIndicator.width - root.StepIndicator.stepIndicator.implicitWidth)/root.StepIndicator.stepIndicator.count)) : implicitWidth height: inAccordion ? implicitHeight : (!!root.StepIndicator.stepIndicator) ? (orientation === Qt.Horizontal ? parent.height : (implicitHeight + (root.StepIndicator.stepIndicator.height - root.StepIndicator.stepIndicator.implicitHeight)/root.StepIndicator.stepIndicator.count)) : implicitHeight checkable: false hoverEnabled: root.enabled orientation: root.StepIndicator.stepIndicator ? root.StepIndicator.stepIndicator.orientation : Qt.Horizontal style: root.StepIndicator.stepIndicator ? root.StepIndicator.stepIndicator.nodeStyle : T.StepNode.Lightweight labelAlignment: inAccordion ? T.StepNode.AlignRight : root.StepIndicator.stepIndicator ? root.StepIndicator.stepIndicator.labelAlignment : orientation === Qt.Horizontal ? T.StepNode.AlignTop : T.StepNode.AlignRight spacing: labelAlignment === T.StepNode.AlignTop ? Theme.component.stepindicator.positionTop.label.marginBottom : labelAlignment === T.StepNode.AlignBottom ? Theme.component.stepindicator.positionBottom.label.marginTop : Theme.component.stepindicator.positionRight.label.marginLeft icon.color: Theme.component.stepindicator.node.icon.fill.complete icon.name: (style !== T.StepNode.Lightweight && checkState === Qt.Checked) ? "checkmark-s" : "" indicator: Rectangle { id: indicator implicitWidth: root.style === T.StepNode.Lightweight ? Theme.component.stepindicator.lightweight.node.width : Theme.component.stepindicator.node.width implicitHeight: root.style === T.StepNode.Lightweight ? Theme.component.stepindicator.lightweight.node.height : Theme.component.stepindicator.node.height x: root.inAccordion ? Theme.component.stepindicator.contentContainer.paddingLeft : root.labelAlignment === T.StepNode.AlignRight ? root.spacing : root.labelAlignment === T.StepNode.AlignLeft ? root.width - width - root.spacing : (root.width/2 - width/2) y: root.inAccordion ? Math.max(0, root.height - implicitHeight) / 2 : root.labelAlignment === T.StepNode.AlignBottom ? root.spacing : root.labelAlignment === T.StepNode.AlignTop ? root.height - height - root.spacing : root.spacing radius: width/2 color: root.style === T.StepNode.Lightweight ? root.checkState === Qt.Checked ? Theme.component.stepindicator.lightweight.node.backgroundColor.complete : root.checkState === Qt.PartiallyChecked ? Theme.component.stepindicator.lightweight.node.backgroundColor.selected : Theme.component.stepindicator.node.backgroundColor.default : root.checkState === Qt.Checked ? Theme.component.stepindicator.node.backgroundColor.complete : Theme.component.stepindicator.node.backgroundColor.default border.color: root.checkState === Qt.Unchecked ? Theme.component.stepindicator.node.borderColor.default : root.checkState === Qt.PartiallyChecked ? Theme.component.stepindicator.node.borderColor.selected : Theme.component.stepindicator.node.borderColor.complete border.width: Theme.component.stepindicator.node.borderWidth T.IconImage { id: nodeIcon visible: status === Image.Ready anchors.centerIn: indicator color: root.icon.color url: root.icon.source name: root.icon.name } Text { visible: !nodeIcon.visible && (root.style === T.StepNode.Numeric || root.inAccordion) anchors.centerIn: indicator color: root.checkState === Qt.Unchecked ? Theme.component.stepindicator.node.textColor.default : root.checkState === Qt.PartiallyChecked ? Theme.component.stepindicator.node.textColor.selected : nodeIcon.color text: (root.StepIndicator.index+1).toLocaleString() font.family: Theme.component.stepindicator.label.fontFamily font.pixelSize: Theme.component.stepindicator.node.fontSize font.weight: Theme.component.stepindicator.label.fontWeight.selected // TODO Theme.component.stepindicator.node.fontWeight lineHeight: Theme.component.stepindicator.node.lineHeight lineHeightMode: Text.FixedHeight verticalAlignment: Text.AlignVCenter } BoxShadow { anchors.fill: indicator visible: root.pressed || (root.enabled && root.hovered) || root.visualFocus radius: indicator.radius offsetX: root.pressed ? Theme.component.stepindicator.node.boxShadowX.pressed : (root.enabled && root.hovered) ? Theme.component.stepindicator.node.boxShadowX.hover : Theme.component.stepindicator.node.boxShadowX.focus offsetY: root.pressed ? Theme.component.stepindicator.node.boxShadowY.pressed : (root.enabled && root.hovered) ? Theme.component.stepindicator.node.boxShadowY.hover : Theme.component.stepindicator.node.boxShadowY.focus blurRadius: root.pressed ? Theme.component.stepindicator.node.boxShadowBlur.pressed : (root.enabled && root.hovered) ? Theme.component.stepindicator.node.boxShadowBlur.hover : Theme.component.stepindicator.node.boxShadowBlur.focus spreadRadius: root.pressed ? Theme.component.stepindicator.node.boxShadowSpread.pressed : (root.enabled && root.hovered) ? Theme.component.stepindicator.node.boxShadowSpread.hover : Theme.component.stepindicator.node.boxShadowSpread.focus color: root.pressed ? Theme.component.stepindicator.node.boxShadowColor.pressed : (root.enabled && root.hovered) ? Theme.component.stepindicator.node.boxShadowColor.hover : Theme.component.stepindicator.node.boxShadowColor.focus } } contentItem: Item { id: content // Note: implicit geometry doesn't include connector geometry implicitHeight: root.inAccordion ? label.implicitHeight : (root.labelAlignment === T.StepNode.AlignLeft || root.labelAlignment === T.StepNode.AlignRight || root.text.length === 0) ? Math.max(label.implicitHeight + Theme.component.stepindicator.node.borderWidth + textLink.implicitHeight, root.indicator.implicitHeight) + 2*root.spacing : (root.spacing + (label.implicitHeight > 0 ? label.implicitHeight + root.spacing : 0) + (textLink.implicitHeight > 0 ? textLink.implicitHeight + 2*Theme.component.stepindicator.node.borderWidth + root.spacing : 0) + root.indicator.implicitHeight + root.spacing) implicitWidth: root.inAccordion ? (root.indicator.x + root.indicator.implicitWidth + root.spacing + label.implicitWidth) : (root.labelAlignment === T.StepNode.AlignTop || root.labelAlignment === T.StepNode.AlignBottom || root.text.length === 0) ? (Math.max(label.implicitWidth, root.indicator.implicitWidth) + 2*root.spacing) : (label.implicitWidth + root.indicator.implicitWidth + 3*root.spacing) Rectangle { // Note: the connector exceeds the item bounds. id: connector visible: !root.inAccordion && !!root.StepIndicator.stepIndicator && root.StepIndicator.index > 0 property T.StepNode prevNode: visible ? root.StepIndicator.stepIndicator.itemAt(root.StepIndicator.index - 1) : null x: root.labelAlignment === T.StepNode.AlignRight || root.labelAlignment === T.StepNode.AlignLeft ? root.indicator.x + root.indicator.width/2 - width/2 : (root.indicator.x - width) y: root.labelAlignment === T.StepNode.AlignBottom || root.labelAlignment === T.StepNode.AlignTop ? root.indicator.y + root.indicator.height/2 - height/2 : (root.indicator.y - height) width: root.orientation === Qt.Horizontal && !!prevNode ? root.indicator.x + prevNode.width - prevNode.indicator.width - prevNode.indicator.x : Theme.component.stepindicator.connector.borderWidth height: root.orientation === Qt.Vertical && !!prevNode ? root.indicator.y + prevNode.height - prevNode.indicator.height - prevNode.indicator.y : Theme.component.stepindicator.connector.borderWidth // default color if this node or the previous node is unchecked color: (root.checkState === Qt.Unchecked || (!!prevNode && prevNode.checkState === Qt.Unchecked)) ? Theme.component.stepindicator.connector.borderColor.default : Theme.component.stepindicator.connector.borderColor.complete } Text { id: label property real rootHeight: root.height // shouldn't be necessary, but y binding wasn't re-evaluating on root.height change... x: root.inAccordion ? root.indicator.x + root.indicator.width + root.spacing : (root.labelAlignment === Qt.AlignTop || root.labelAlignment === Qt.AlignBottom) ? content.width/2 - width/2 : root.labelAlignment === Qt.AlignLeft ? root.width - root.spacing - root.indicator.width - root.spacing - width : (root.spacing + root.indicator.width + root.spacing) y: root.inAccordion ? ((2*root.indicator.y + root.indicator.height)/2 - label.height/2) : (root.labelAlignment === Qt.AlignLeft || root.labelAlignment === Qt.AlignRight) ? (content.height <= root.indicator.height ? content.height/2 - height/2 : (root.indicator.y + (root.indicator.height - label.lineHeight)/2)) : root.labelAlignment === Qt.AlignTop ? (rootHeight - root.spacing - root.indicator.height - root.spacing - textLink.height - height) : (root.spacing + root.indicator.height + root.spacing) width: { var maxWidth = 0 if (root.labelAlignment === Qt.AlignTop || root.labelAlignment === Qt.AlignBottom) { maxWidth = content.width } else if (root.labelAlignment === T.StepNode.AlignRight) { maxWidth = content.width - x - root.spacing } else { maxWidth = content.width - root.spacing - root.indicator.width - root.spacing } return implicitWidth < maxWidth ? implicitWidth : maxWidth } height: { var maxHeight = 0 if (root.labelAlignment === Qt.AlignLeft || root.labelAlignment === Qt.AlignRight) { maxHeight = (content.height <= root.indicator.height) ? content.height : (content.height - root.indicator.y) } else if (root.labelAlignment === Qt.AlignBottom) { maxHeight = content.height - y } else { maxHeight = content.height - root.spacing - root.indicator.height - root.spacing } return implicitHeight < maxHeight ? implicitHeight : maxHeight } text: root.text color: Theme.component.stepindicator.label.textColor font.family: Theme.component.stepindicator.label.fontFamily font.pixelSize: root.inAccordion ? Theme.component.stepindicator.headerContainer.label.fontSize : Theme.component.stepindicator.label.fontSize font.weight: root.checkState === Qt.PartiallyChecked ? Theme.component.stepindicator.label.fontWeight.selected : Theme.component.stepindicator.label.fontWeight.default lineHeight: root.inAccordion ? Theme.component.stepindicator.headerContainer.label.lineHeight : Theme.component.stepindicator.label.lineHeight lineHeightMode: Text.FixedHeight verticalAlignment: Text.AlignVCenter horizontalAlignment: root.labelAlignment === Qt.AlignLeft ? Qt.AlignRight : root.labelAlignment === Qt.AlignRight ? Qt.AlignLeft : Qt.AlignHCenter wrapMode: root.inAccordion ? Text.NoWrap : Text.Wrap elide: root.inAccordion ? Text.ElideRight : Text.ElideNone } TextLink { id: textLink visible: text.length > 0 && link.toString().length > 0 enabled: visible x: label.horizontalAlignment === Qt.AlignHCenter ? label.x + (label.width/2 - width/2) : label.horizontalAlignment === Qt.AlignRight ? label.x + (label.width - width) : label.x y: label.y + label.height + Theme.component.stepindicator.node.borderWidth width: { var maxWidth = 0 if (root.labelAlignment === Qt.AlignTop || root.labelAlignment === Qt.AlignBottom) { maxWidth = content.width } else if (root.labelAlignment === T.StepNode.AlignRight) { maxWidth = content.width - x - root.spacing } else { maxWidth = content.width - root.spacing - root.indicator.width - root.spacing } return implicitWidth < maxWidth ? implicitWidth : maxWidth } height: visible ? implicitHeight : 0 lineHeight: label.lineHeight text: root.linkText link: root.linkUrl onLinkActivated: root.linkActivated() } } background: Item {} }