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: 6 property var colorMode: 0 // 0->None; 1->White; 2->Green; 3->Yellow property color lightColor: getColor() property color lightGlow: getColorGlow() signal pressed signal released implicitWidth: width implicitHeight: height onPressed: { button.down = true } onReleased: { button.down = false } function getColor() { switch(colorMode) { case(0): return Theme.current.none case(1): return Theme.current.white case(2): return Theme.current.green case(3): return Theme.current.yellow } } function getColorGlow() { switch(colorMode) { case(0): return Theme.current.noneGlow case(1): return Theme.current.whiteGlow case(2): return Theme.current.greenGlow case(3): return Theme.current.yellowGlow } } width: Const.macroButton height: 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.width height: parent.height Rectangle { id: backLightGlow property var diffusion: Theme.current.glowRaduis width: backLight.width + diffusion height: backLight.height + diffusion radius: width / 2 anchors.horizontalCenter: backLight.horizontalCenter y: - diffusion / 4 color: Theme.current.background border { width: diffusion / 2 color: Theme.current.background } } Rectangle { anchors.fill: backLightGlow color: "transparent" layer.enabled: true layer.effect: OpacityMask { maskSource: backLightGlow } Rectangle { width: parent.width height: parent.height radius: parent.radius color: "transparent" RadialGradient { anchors.fill: parent gradient: Gradient { GradientStop { position: 0.0; color: lightGlow } GradientStop { position: 0.5 * (backLight.width - backLightGlow.diffusion / backLightGlow.width) color: lightGlow } GradientStop { position: 0.5; color: "transparent" } GradientStop { position: 1.0; color: "transparent" } } } } } Rectangle { id: backLight width: parent.width + 4 height: parent.height + 4 radius: width / 2 color: lightColor anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter } 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.width implicitHeight: parent.height anchors.fill: parent layer.enabled: true layer.effect: OpacityMask { maskSource: lightRing } Rectangle { width: parent.width height: parent.height color: background.color 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.width implicitHeight: parent.height 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 } } ] }