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 colorMode: 0 // 0->None; 1->White; 2->Green; 3->Yellow property color backLightColor: getColorMode() property var specialScale: 1 property var visibleGlow: true signal pressed signal released onPressed: { button.down = true } onReleased: { button.down = false } implicitWidth: Const.macroButton implicitHeight: Const.macroButton function getColorMode() { 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 } } contentItem: Item { id: content anchors.fill: parent z: 1 Item { property var factor: specialScale * (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: Rectangle{ id: background width: parent.implicitWidth height: parent.implicitHeight radius: button.radius color: Theme.current.button anchors.fill: parent // Rectangle { // anchors.fill: parent // layer.enabled: true // layer.effect: OpacityMask { // maskSource: parent // } // color: Theme.current.button // opacity: Theme.current.mergeOpacity // RadialGradient { // anchors.fill: parent // gradient: Gradient { // GradientStop { position: 0.0; color: backLightColor } // GradientStop { position: 0.3; color: backLightColor } // GradientStop { position: 0.5; color: "transparent" } // GradientStop { position: 1.0; color: "transparent" } // } // } // } 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 = "" } } } DropShadow { id: dropDown anchors.fill: background source: background horizontalOffset: 6 verticalOffset: 6 radius: 10 samples: 16 color: Theme.current.shadow } DropShadow { id: dropUp anchors.fill: background source: background horizontalOffset: -4 verticalOffset: -4 radius: 5 samples: 10 color: Theme.current.light } InnerShadow { id: innerUp anchors.fill: background source: background horizontalOffset: 3 verticalOffset: 3 radius: 2 samples: 6 smooth: true color: Theme.current.shadow } Glow { id: glow anchors.fill: background source: background radius: 10 samples: 20 color: backLightColor transparentBorder: true visible: visibleGlow } 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: dropDown horizontalOffset: 0 verticalOffset: 0 radius: 0 samples: 0 } PropertyChanges { target: dropUp horizontalOffset: 0 verticalOffset: 0 radius: 0 samples: 0 } PropertyChanges { target: innerUp horizontalOffset: 6 verticalOffset: 6 radius: 6 samples: 12 } // PropertyChanges { // target: innerDown // horizontalOffset: - 4 // verticalOffset: - 4 // radius: 4 // samples: 8 // } } ] transitions: [ Transition { from: ""; to: "Hovering" NumberAnimation { properties: "x" duration: 500 easing.type: Easing.OutQuad } }, Transition { from: "*"; to: "Pressed" ColorAnimation { properties: "color" duration: timeToPress } NumberAnimation { properties: "horizontalOffset, verticalOffset, radius, samples" duration: timeToPress easing.type: Easing.InOutQuad } }, Transition { from: "Pressed"; to: "*" ColorAnimation { properties: "color" duration: timeToPress } NumberAnimation { properties: "horizontalOffset, verticalOffset, radius, samples" duration: timeToPress easing.type: Easing.InOutQuad } } ] }