101 lines
3.5 KiB
QML
101 lines
3.5 KiB
QML
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
|
|
}
|
|
}
|