import QtQuick import QtQuick.Templates as QQCT import Weave.Controls import Weave.Templates as T T.SplitButton { id: root // The dropdown button is square, so have even padding around it. The effective padding will be larger because the caret graphic is also padded. leftPadding: mirrored ? Theme.component.button.paddingTop : Theme.component.button.paddingLeft rightPadding: mirrored ? Theme.component.button.paddingRight : Theme.component.button.paddingTop topPadding: Theme.component.button.paddingTop bottomPadding: Theme.component.button.paddingBottom implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) + Theme.component.button.borderWidth + dropdownButton.implicitWidth implicitHeight: display === QQCT.Button.TextUnderIcon ? implicitContentHeight + topPadding + bottomPadding : Theme.component.button.height icon.color: _styleAttributes.icon.fill font.family: Theme.component.button.fontFamily font.pixelSize: Theme.component.button.fontSize font.weight: Theme.component.button.fontWeight icon.width: Theme.component.button.icon.width icon.height: Theme.component.button.icon.height style: flat ? Button.Flat : Button.Outline opacity: enabled ? 1 : Theme.component.button.opacity.disabled layer.enabled: !enabled && style == Button.Solid // The Solid style has overlapping items so they need to be merged before applying opacity or they will interblend. hoverEnabled: enabled menuPosition: Qt.point( !menu || menu.horizontalAlignment === undefined || menu.horizontalAlignment === Menu.AlignLeft ? 0 : (menu.horizontalAlignment == Menu.AlignRight ? dropdownButton.width - menu.width : (dropdownButton.width - menu.width) / 2), height + (menu ? menu.topMargin + menu.verticalPadding : 0)) contentItem: Item { // ensure equidistant padding between LHS and RHS/DropdownButton // by increasing the content item width by the difference between // the root.leftPadding and root.rightPadding. implicitWidth: (root.display === QQCT.MenuItem.IconOnly ? icon.width : label.implicitWidth) + (Theme.component.button.paddingLeft - Theme.component.button.paddingTop) implicitHeight: root.display === QQCT.MenuItem.IconOnly ? icon.height : label.implicitHeight Text { id: label x: root.mirrored ? (Theme.component.button.paddingLeft - Theme.component.button.paddingTop) + root.dropdownButton.implicitWidth + Theme.component.button.borderWidth : 0 width: parent.width - (Theme.component.button.paddingLeft - Theme.component.button.paddingTop) - root.dropdownButton.implicitWidth - Theme.component.button.borderWidth height: parent.height horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: root.text font: root.font color: root._styleAttributes.textColor elide: Text.ElideRight lineHeight: Theme.component.button.lineHeight lineHeightMode: Text.FixedHeight leftPadding: ((!root.mirrored ^ (root.iconAlignment === T.Button.AlignRight)) && root.display == QQCT.Button.TextBesideIcon && icon.status === Image.Ready ? icon.width + (root.text ? Theme.component.button.iconLeft.iconContainer.marginRight : 0) : 0) rightPadding: ((root.mirrored ^ (root.iconAlignment === T.Button.AlignRight)) && root.display == QQCT.Button.TextBesideIcon && icon.status === Image.Ready ? icon.width + (root.text ? Theme.component.button.iconRight.iconContainer.marginLeft : 0) : 0) topPadding: root.display == QQCT.Button.TextUnderIcon && icon.status === Image.Ready // For vertical case, use marginRight as padding, because there is no vertical-orientation-specific paddingBottom token. ? icon.height + Theme.component.button.iconLeft.iconContainer.marginRight : 0 } T.IconImage { id: icon width: Theme.component.button.iconContainer.width height: Theme.component.button.iconContainer.height name: root.icon.name url: root.icon.source color: root.icon.color sourceSize: Qt.size(root.icon.width, root.icon.height) x: { if (root.display === QQCT.Button.TextUnderIcon || root.display == QQCT.Button.IconOnly) { return label.x + ((label.width - width) / 2) } else if (root.mirrored ^ (root.iconAlignment === T.Button.AlignRight)) { return label.x + label.width - label.rightPadding + (root.text ? Theme.component.button.iconRight.iconContainer.marginLeft : 0) - ((label.width - label.implicitWidth) / 2) } else { return label.x + label.leftPadding - width - (root.text ? Theme.component.button.iconLeft.iconContainer.marginRight : 0) + ((label.width - label.implicitWidth) / 2) } } y: root.display === QQCT.Button.TextUnderIcon ? parent.height - height : (parent.height - height) / 2 } } dropdownButton { x: root.mirrored ? 0 : (root.width - dropdownButton.width) height: root.height implicitWidth: dropdownButton.implicitContentWidth + dropdownButton.leftPadding + dropdownButton.rightPadding implicitHeight: dropdownButton.implicitContentHeight + dropdownButton.topPadding + dropdownButton.bottomPadding leftPadding: Theme.component.button.paddingTop rightPadding: Theme.component.button.paddingTop topPadding: root.topPadding bottomPadding: root.bottomPadding rightInset: root.rightInset leftInset: root.leftInset topInset: root.topInset bottomInset: root.bottomInset contentItem: Item { implicitWidth: Math.max(implicitHeight, indicatorIcon.implicitWidth) implicitHeight: Theme.component.button.lineHeight T.IconImage { id: indicatorIcon anchors.fill: parent name: root.menu && root.menu.opened ? Theme.icon.medium("caret-up") : Theme.icon.medium("caret-down") color: root._styleAttributes.icon.fill } } } background: Item { id: backgroundItem implicitWidth: Theme.component.button.minWidth Item { id: leftBackground x: root.mirrored ? root.dropdownButton.implicitWidth + Theme.component.button.borderWidth : 0 width: backgroundItem.width - root.dropdownButton.implicitWidth - Theme.component.button.borderWidth height: backgroundItem.height clip: true Rectangle { visible: root.style === T.Button.Solid x: root.mirrored ? -radius : 0 width: leftBackground.width + radius height: leftBackground.height radius: Theme.component.button.borderRadius color: Theme.component.button.solid.backgroundColor } Rectangle { visible: root.style !== T.Button.Flat x: root.mirrored ? -radius : 0 width: leftBackground.width + radius height: leftBackground.height radius: Theme.component.button.borderRadius color: "transparent" border.width: Theme.component.button.borderWidth border.color: root.style === T.Button.Flat ? Theme.component.button.flat.borderColor : root.style === T.Button.Solid ? Theme.component.button.solid.borderColor : root.pressed ? Theme.component.button.outline.borderColor.pressed : root.visualFocus && !root.hovered ? Theme.component.button.outline.borderColor.focus : Theme.component.button.outline.borderColor.default } } Rectangle { id: separator visible: root.style === T.Button.Outline x: root.mirrored ? rightBackground.width : leftBackground.width width: Theme.component.button.borderWidth height: backgroundItem.height color: (root.pressed || root.dropdownButton.pressed) ? Theme.component.button.outline.borderColor.pressed : ((root.visualFocus && !root.hovered) || (root.dropdownButton.visualFocus && !root.dropdownButton.hovered)) ? Theme.component.button.outline.borderColor.focus : Theme.component.button.outline.borderColor.default } Item { id: rightBackground x: root.mirrored ? 0 : backgroundItem.width - width width: root.dropdownButton.implicitWidth height: backgroundItem.height clip: true Rectangle { visible: root.style === T.Button.Solid x: root.mirrored ? 0 : -radius width: rightBackground.width + radius height: rightBackground.height radius: Theme.component.button.borderRadius color: Theme.component.button.solid.backgroundColor } Rectangle { visible: root.style !== T.Button.Flat x: root.mirrored ? 0 : -radius width: rightBackground.width + radius height: rightBackground.height radius: Theme.component.button.borderRadius color: "transparent" border.width: Theme.component.button.borderWidth border.color: root.style === T.Button.Solid ? Theme.component.button.solid.borderColor : root.dropdownButton.pressed ? Theme.component.button.outline.borderColor.pressed : root.dropdownButton.visualFocus && !root.dropdownButton.hovered ? Theme.component.button.outline.borderColor.focus : Theme.component.button.outline.borderColor.default } } BoxShadow { anchors.fill: leftBackground radius: Theme.component.button.borderRadius topLeftRadius: root.mirrored ? 0 : undefined bottomLeftRadius: root.mirrored ? 0 : undefined topRightRadius: root.mirrored ? undefined : 0 bottomRightRadius: root.mirrored ? undefined : 0 source: root.pressed ? Theme.component.button.boxShadow.pressed : (root.enabled && root.hovered && !root.dropdownButton.hovered) ? Theme.component.button.boxShadow.hover : root.visualFocus && !root.hovered ? Theme.component.button.boxShadow.focus : "none" } BoxShadow { anchors.fill: rightBackground radius: Theme.component.button.borderRadius topLeftRadius: root.mirrored ? undefined : 0 bottomLeftRadius: root.mirrored ? undefined : 0 topRightRadius: root.mirrored ? 0 : undefined bottomRightRadius: root.mirrored ? 0 : undefined source: (root.dropdownButton.pressed || (root.menu && root.menu.opened)) ? Theme.component.button.boxShadow.pressed : (root.enabled && root.dropdownButton.enabled && root.dropdownButton.hovered) ? Theme.component.button.boxShadow.hover : root.dropdownButton.visualFocus && !root.dropdownButton.hovered ? Theme.component.button.boxShadow.focus : "none" } } }