1/* 2 * Copyright (C) 2017-2020 3 * Jean-Luc Barriere <jlbarriere68@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; version 3. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18import QtQuick 2.9 19import QtQuick.Controls 2.2 20import QtGraphicalEffects 1.0 21 22MouseArea { 23 id: area 24 property alias source: icon.source 25 property alias label: label 26 property color color: styleMusic.view.foregroundColor 27 property color backgroundColor: "transparent" 28 property color pressedColor: styleMusic.view.highlightedColor 29 property alias animationRunning: icon.animationRunning 30 property int animationInterval: 500 // slow flashing 31 property alias iconSize: icon.height 32 property real borderPadding: units.gu(1) 33 readonly property real implicitWidth: row.width + 2 * borderPadding 34 width: implicitWidth 35 height: units.gu(5) 36 enabled: true 37 visible: true 38 hoverEnabled: enabled && visible 39 40 Rectangle { 41 id: background 42 anchors.fill: parent 43 color: backgroundColor 44 radius: height / 2 45 } 46 47 Row { 48 id: row 49 spacing: label.text !== "" ? units.gu(0.5) : 0 50 height: parent.height 51 visible: false 52 anchors.centerIn: parent 53 54 Image { 55 id: icon 56 anchors.verticalCenter: parent.verticalCenter 57 height: parent.height < units.gu(3) ? parent.height : parent.height - 2 * borderPadding 58 width: area.visible ? height : 0 59 sourceSize.height: height 60 sourceSize.width: width 61 source: "qrc:/images/delete.svg" 62 63 property bool animationRunning: false 64 65 onAnimationRunningChanged: { 66 if (animationRunning) 67 animator.start(); 68 else 69 animator.stop(); 70 } 71 72 Timer { 73 id: animator 74 interval: area.animationInterval 75 repeat: true 76 onTriggered: { 77 opacity = (opacity === 0.0 ? 1.0 : 0.0); 78 } 79 onRunningChanged: opacity = 1.0 // reset opacity on stop 80 } 81 82 Behavior on opacity { 83 NumberAnimation { duration: area.animationInterval / 2 } 84 } 85 } 86 87 Label { 88 id: label 89 anchors.verticalCenter: parent.verticalCenter 90 width: text !== "" && area.visible ? implicitWidth + units.gu(0.5) : 0 91 } 92 } 93 94 Rectangle { 95 id: iconFill 96 visible: false 97 anchors.fill: row 98 color: parent.pressed ? parent.pressedColor : parent.color 99 } 100 101 OpacityMask { 102 anchors.fill: iconFill 103 source: iconFill 104 maskSource: row 105 } 106 107 Rectangle { 108 id: ripple 109 readonly property bool square: area.implicitWidth <= area.implicitHeight 110 x: (parent.width - width) / 2 111 y: (parent.height - height) / 2 112 clip: !square 113 width: parent.width 114 height: parent.height 115 radius: height / 2 116 color: area.color 117 opacity: 0 118 119 Behavior on opacity { 120 NumberAnimation { duration: 100 } 121 } 122 } 123 124 onEntered: ripple.opacity = 0.1 125 onExited: ripple.opacity = 0 126} 127