import QtQuick 2.0 import QtQuick.Controls 2.13 import QtGraphicalEffects 1.13 import "qrc:/theme" import "qrc:/const" Button { id: button property var image: "" property var radius: Math.min(width / 2, height / 2) property var timeToPress: 100 property var border: 4 signal pressed signal released onPressed: { button.down = true } onReleased: { button.down = false } implicitWidth: Const.macroButton implicitHeight: Const.macroButton contentItem: Item { id: content anchors.fill: parent z: 1 Item { property var factor: button.state == "Pressed" ? Const.imageScalePressed : Const.imageScale property var elevator: button.state == "Pressed" ? 3 : 0 anchors.horizontalCenter: parent.horizontalCenter y: (parent.height * (1-factor)) / 2 + elevator width: parent.width * factor height: parent.height * factor Behavior on y { NumberAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } Behavior on width { NumberAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } Behavior on height { NumberAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } Image { id: img anchors.fill: parent source: image fillMode: Image.PreserveAspectFit antialiasing: true smooth: true } ColorOverlay { anchors.fill: img source: img color: button.state == "Pressed" ? Theme.current.textSelected : Theme.current.text antialiasing: true smooth: true } } } background: Item{ width: parent.implicitWidth height: parent.implicitHeight Rectangle { id: background anchors.fill: parent radius: button.radius color: Theme.current.button Behavior on color { ColorAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } } Item { id: coloredRing width: parent.width height: parent.height Rectangle { id: lightRing width: parent.width height: parent.height radius: width / 2 color: "transparent" border{ color: background.color width: button.border } } Item { id: borderGrad implicitWidth: parent.implicitWidth implicitHeight: parent.implicitHeight anchors.fill: parent layer.enabled: true layer.effect: OpacityMask { maskSource: lightRing } Rectangle { width: parent.width height: parent.height color: "transparent" LinearGradient { id: linGrad anchors.fill: parent start: Qt.point(0, parent.height) end: Qt.point(0, 0) gradient: Gradient { GradientStop { id: buttonDown position: 0 color: Theme.current.shadow Behavior on color { ColorAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } } GradientStop { id: buttonUp position: 1 color: Theme.current.light Behavior on color { ColorAnimation { duration: timeToPress easing.type: Easing.InOutQuad } } } } } } } } MouseArea { hoverEnabled: true anchors.fill: background onEntered: { button.state = "Hovering" } onExited: { button.state = "" } onPressed: { button.state = "Pressed" button.pressed() } onReleased: { button.released() if (containsMouse) button.state = "Hovering" else button.state = "" } } } Item { id: hoverLight implicitWidth: parent.implicitWidth implicitHeight: parent.implicitHeight anchors.fill: parent layer.enabled: true layer.effect: OpacityMask { maskSource: background } Rectangle { id: hoverGlow width: 2 * parent.width height: parent.height x: - 2 * parent.width color: "transparent" HoverGlow {} } } states: [ State { name: "Hovering" PropertyChanges { target: hoverGlow x: 0 } }, State { name: "Pressed" PropertyChanges { target: background color: Theme.current.buttonSelected } PropertyChanges { target: buttonUp color: Theme.current.shadow } PropertyChanges { target: buttonDown color: Theme.current.light } } ] transitions: [ Transition { from: ""; to: "Hovering" NumberAnimation { properties: "x" duration: 500 easing.type: Easing.OutQuad } } ] }