import QtQuick 2.12 import QtQuick.Controls 2.12 import QtGraphicalEffects 1.12 Item { id: delegateRoot property bool showLabel: true property bool darkMode: settingsContainer.darkMode // Resolved feedback colour/width for the current status (ok / error). readonly property color okColor: settingsContainer.feedbackOkColor readonly property color errorColor: settingsContainer.feedbackErrorColor readonly property color feedbackColor: status === 1 ? okColor : status === 2 ? errorColor : "#ffffff" readonly property int feedbackWidth: status === 1 ? settingsContainer.feedbackOkWidth : status === 2 ? settingsContainer.feedbackErrorWidth : 2 // Glow: white=in-progress, ok/error use configured colours Rectangle { id: glowRect anchors.centerIn: parent width: circle.width * glowScale height: width radius: width / 2 color: delegateRoot.feedbackColor opacity: status === 0 ? 0 : 0.5 visible: status !== 0 && settingsContainer.feedbackGlowRadius > 0 property real glowScale: 1.0 Behavior on opacity { NumberAnimation { duration: 300 } } Behavior on color { ColorAnimation { duration: 200 } } SequentialAnimation on glowScale { running: status === 3 loops: Animation.Infinite NumberAnimation { to: 1.4; duration: 700; easing.type: Easing.InOutSine } NumberAnimation { to: 1.0; duration: 700; easing.type: Easing.InOutSine } } NumberAnimation on glowScale { running: status !== 3 to: 1.0; duration: 300 } layer.enabled: true layer.effect: Glow { radius: settingsContainer.feedbackGlowRadius samples: 24 color: delegateRoot.feedbackColor transparentBorder: true } } // Circle button — fixed color from config; only the ring reacts to status. Rectangle { id: circle anchors.centerIn: parent width: Math.min(parent.width, parent.height) * 0.82 height: width radius: width / 2 color: btnColor || "#7b007b" border.color: status === 1 ? delegateRoot.okColor : status === 2 ? delegateRoot.errorColor : Qt.lighter(btnColor || "#7b007b", 1.5) border.width: status === 1 || status === 2 ? delegateRoot.feedbackWidth : 1 Behavior on border.width { NumberAnimation { duration: 200 } } Behavior on border.color { ColorAnimation { duration: 200 } } Image { anchors.centerIn: parent width: parent.width * 0.8 height: width fillMode: Image.PreserveAspectFit source: iconPath visible: iconPath !== "" asynchronous: true } MouseArea { anchors.fill: parent onClicked: btnController.invokeButton(btnId) } } Text { anchors.top: circle.bottom anchors.topMargin: 4 anchors.horizontalCenter: parent.horizontalCenter width: parent.width visible: showLabel text: statusText !== "" ? statusText : label color: darkMode ? "white" : "black" font.pixelSize: Math.max(10, parent.width * 0.1) horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } }