// One tile in the power menu: big glyph, label underneath. // // Anything that ends the session arms on the first press and only fires on the // second — an accidental Ctrl+Alt+Delete should never be one click away from // losing everything that is open. // // Armed, the tile turns red and names the thing it is about to do ("Power off") // rather than saying "Confirm". Six tiles could all say "Confirm"; only one of // them is about to take the machine down, and the press that does it should say // which one it is. import QtQuick import qs.config Rectangle { id: root property string glyph: "" property string label: "" // Tint red on hover and require the two-step confirm. property bool destructive: false // Highlighted by keyboard navigation. property bool selected: false signal activated readonly property bool armed: confirmTimer.running // The tile's own label, said as a sentence rather than as a title: "Power // Off" is the name of a menu entry, "Power off" is the thing the next press // does. Derived, so an entry added to the menu cannot forget to name itself. readonly property string armedLabel: root.label === "" ? "Confirm" : root.label.charAt(0) + root.label.slice(1).toLowerCase() implicitWidth: 136 implicitHeight: 136 radius: Theme.cardRadius + 6 border.width: 0 readonly property color accentFor: root.destructive ? Theme.danger : Theme.accent color: { if (root.armed) return Theme.alpha(Theme.danger, 0.32); if (mouse.pressed) return Theme.alpha(root.accentFor, 0.3); if (mouse.containsMouse || root.selected) return Theme.alpha(root.accentFor, 0.18); return Theme.alpha(Theme.fg, 0.07); } Behavior on color { ColorAnimation { duration: Theme.durFast } } // Keyboard focus ring. Rectangle { anchors.fill: parent radius: parent.radius color: "transparent" border.width: root.selected ? 2 : 0 border.color: root.accentFor visible: root.selected } Column { anchors.centerIn: parent spacing: 10 Text { anchors.horizontalCenter: parent.horizontalCenter text: root.glyph color: root.armed ? Theme.danger : Theme.fg font.family: Theme.fontMono font.pixelSize: 40 } Text { anchors.horizontalCenter: parent.horizontalCenter text: root.armed ? root.armedLabel : root.label color: root.armed ? Theme.danger : Theme.fg font.family: Theme.fontFamily font.pixelSize: Theme.fontSize font.weight: Font.Medium } } // Trigger from a click or from Enter while keyboard-selected. function trigger(): void { if (root.destructive && !root.armed) { confirmTimer.restart(); return; } confirmTimer.stop(); root.activated(); } function disarm(): void { confirmTimer.stop(); } // Arming is not sticky: walk away and the button forgets. Timer { id: confirmTimer interval: 4000 } MouseArea { id: mouse anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: root.trigger() } }