import QtQuick import Weave.Controls import Weave.Templates as T T.SplitIconButton { id: root implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, implicitContentWidth + leftPadding + rightPadding) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, implicitContentHeight + topPadding + bottomPadding, dropdownButton.implicitHeight) // padding includes the dropdown indicator item as well as the normal padding. rightPadding: mirrored ? Theme.component.iconbutton.icon.paddingRight // TODO: fix paddingLeft token, currently it's generic not semantic. : (Theme.component.iconbutton.icon.paddingRight + dropdownButton.implicitWidth) leftPadding: mirrored ? (Theme.component.iconbutton.icon.paddingRight + dropdownButton.implicitWidth) : Theme.component.iconbutton.icon.paddingRight // TODO: fix paddingLeft token, currently it's generic not semantic. bottomPadding: Theme.component.iconbutton.icon.paddingBottom topPadding: Theme.component.iconbutton.icon.paddingTop // the contentItem is just the main icon button. // the dropdownButton fits within the rightInset/rightPadding. rightInset: mirrored ? 0 : dropdownButton.implicitWidth leftInset: mirrored ? dropdownButton.implicitWidth : 0 dynamicColor: false swellOnPress: true icon.width: Theme.component.button.icon.width icon.height: Theme.component.button.icon.height icon.color: Theme.component.iconbutton.icon.fill.default opacity: enabled ? 1 : Theme.component.iconbutton.opacity.disabled popupOpened: popup ? popup.opened : false hoverEnabled: root.enabled popupPosition: Qt.point( !popup || popup.horizontalAlignment === undefined || popup.horizontalAlignment === Menu.AlignLeft ? 0 : (popup.horizontalAlignment == Menu.AlignRight ? dropdownButton.width - popup.width : (dropdownButton.width - popup.width) / 2), height + (popup ? popup.topMargin + popup.verticalPadding : 0)) surfaceLevel: T.Surface.level contentItem: Item { implicitWidth: dynamicIcon.width implicitHeight: dynamicIcon.height T.IconImage { id: dynamicIcon anchors.centerIn: parent url: root.icon.source name: root.icon.name sourceSize: Qt.size(root.icon.width, root.icon.height) color: { if (!root.dynamicColor) { return root.icon.color } else { var state = (root.pressed || root.popupOpened) ? "pressed" : (root.enabled && root.hovered && !root.dropdownButton.hovered) ? "hover" : root.visualFocus ? "focus" : "default" return root.checked ? Theme.component.iconbutton.icon.fill.selected[state] : Theme.component.iconbutton.icon.fill[state] } } } } background: Item { implicitWidth: Theme.component.iconbutton.width.default implicitHeight: Theme.component.iconbutton.height BoxShadow { anchors.fill: parent topLeftRadius: root.mirrored ? 0 : Theme.component.iconbutton.borderRadius bottomLeftRadius: root.mirrored ? 0 : Theme.component.iconbutton.borderRadius topRightRadius: root.mirrored ? Theme.component.iconbutton.borderRadius : 0 bottomRightRadius: root.mirrored ? Theme.component.iconbutton.borderRadius : 0 source: root.visualFocus && !root.pressed && (!root.hovered || root.dropdownButton.hovered) ? Theme.component.iconbutton.boxShadow.focus : "" } Item { id: clipRect anchors.fill: parent anchors.margins: -bgRect.swell clip: true Rectangle { id: bgRect anchors { left: parent.left top: parent.top bottom: parent.bottom } width: parent.width + 2*radius radius: Theme.component.iconbutton.borderRadius color: { var state = root.pressed ? "pressed" : (root.enabled && root.hovered && !root.dropdownButton.hovered) ? "hover" : root.visualFocus ? "focus" : "default" if (root.dynamicColor && state != "pressed") { // default background color only exists for static + selected case return "transparent" } else if (root.checked) { return Theme.component.iconbutton.backgroundColor.selected[state] } else if ((root.enabled && root.hovered && !root.dropdownButton.hovered) || root.pressed) { return root.surfaceLevel < 300 ? Theme.component.iconbutton.surfaceHigh.backgroundColor[state] : Theme.component.iconbutton.surfaceLow.backgroundColor[state] } else { return Theme.component.iconbutton.backgroundColor.default } } property real swell: root.swellOnPress && root.pressed ? Theme.component.iconbutton.swell.outlineWidth.pressed : 0 Behavior on swell { enabled: bgSwellAnim.duration > 0 NumberAnimation { id: bgSwellAnim duration: Theme.component.iconbutton.swell.transitionDuration } } } Rectangle { id: borderRect anchors { left: parent.left top: parent.top bottom: parent.bottom topMargin: bgRect.swell leftMargin: bgRect.swell bottomMargin: bgRect.swell } width: Theme.component.iconbutton.width.default radius: Theme.component.iconbutton.borderRadius color: "transparent" border.color: { if (root.dynamicColor) { return "transparent" } else if (root.pressed || root.popupOpened) { return root.checked ? Theme.component.iconbutton.borderColor.selected.pressed : Theme.component.iconbutton.borderColor.default } else if (root.checked) { return (root.visualFocus && !root.hovered) ? Theme.component.iconbutton.borderColor.selected.focus : Theme.component.iconbutton.borderColor.selected.default } else { return "transparent" } } border.width: staticAndCheckedOrFocused ? Theme.component.iconbutton.borderWidth : 0 property bool staticAndCheckedOrFocused: !root.dynamicColor && (root.checked || root.visualFocus) } } } dropdownButton { x: (root.mirrored ? 0 : (root.width - root.dropdownButton.width)) height: root.height implicitHeight: root.dropdownButton.topPadding + root.dropdownButton.implicitContentHeight + root.dropdownButton.bottomPadding implicitWidth: root.dropdownButton.leftPadding + root.dropdownButton.implicitContentWidth + root.dropdownButton.rightPadding leftPadding: Theme.component.iconbutton.caret.icon.paddingLeft rightPadding: Theme.component.iconbutton.caret.icon.paddingRight topPadding: Theme.component.iconbutton.caret.icon.paddingTop bottomPadding: Theme.component.iconbutton.caret.icon.paddingBottom contentItem: Item { implicitHeight: Theme.component.iconbutton.caret.iconContainer.height implicitWidth: Theme.component.iconbutton.caret.iconContainer.width T.IconImage { id: dropdownIcon anchors.centerIn: parent name: Theme.icon.medium("caret-down") color: !root.dynamicColor ? root.icon.color : !root.enabled ? Theme.component.iconbutton.icon.fill.default : root.dropdownButton.pressed || (root.popup && root.popup.opened) ? Theme.component.iconbutton.icon.fill.pressed : (root.enabled && root.dropdownButton.hovered) ? Theme.component.iconbutton.icon.fill.hover : root.dropdownButton.visualFocus ? Theme.component.iconbutton.icon.fill.focus : Theme.component.iconbutton.icon.fill.default } } background: Item { BoxShadow { anchors.fill: parent topLeftRadius: root.mirrored ? Theme.component.iconbutton.borderRadius : 0 bottomLeftRadius: root.mirrored ? Theme.component.iconbutton.borderRadius : 0 topRightRadius: root.mirrored ? 0 : Theme.component.iconbutton.borderRadius bottomRightRadius: root.mirrored ? 0 : Theme.component.iconbutton.borderRadius source: (root.dropdownButton.visualFocus && !root.dropdownButton.hovered) ? Theme.component.iconbutton.boxShadow.focus : "" } Item { id: dropdownClipItem anchors.fill: parent anchors.margins: -dropdownBgRect.swell clip: true Rectangle { id: dropdownBgRect anchors { right: parent.right top: parent.top bottom: parent.bottom } width: parent.width + 2*radius radius: Theme.component.iconbutton.borderRadius color: { var state = (root.dropdownButton.pressed || root.popupOpened) ? "pressed" : (root.enabled && root.dropdownButton.hovered) ? "hover" : root.dropdownButton.visualFocus ? "focus" : "default" if (root.dynamicColor && state != "pressed") { // default background color only exists for static + selected case return "transparent" } else if ((root.dropdownButton.enabled && (root.dropdownButton.hovered || root.dropdownButton.pressed)) || root.popupOpened) { // The checked state of the icon side of the button is NOT // applied to the split button caret return root.surfaceLevel < 300 ? Theme.component.iconbutton.surfaceHigh.backgroundColor[state] : Theme.component.iconbutton.surfaceLow.backgroundColor[state] } else { return Theme.component.iconbutton.backgroundColor.default } } property real swell: root.swellOnPress && root.dropdownButton.pressed ? Theme.component.iconbutton.swell.outlineWidth.pressed : 0 Behavior on swell { enabled: swellAnim.duration > 0 NumberAnimation { id: swellAnim duration: Theme.component.iconbutton.swell.transitionDuration } } } } } } }