repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
quickshell/nuguland/PopupButton.qml
Rawimport QtQuick
import QtQuick.Templates as T
import Quickshell.Widgets
FocusScope {
id: root
required property Theme theme
property string text: ""
property string icon: ""
property url iconSource: ""
property string role: "normal"
property bool showText: true
property string accessibleName: text
property string tooltip: accessibleName
property bool checked: false
property int iconSize: 14
property bool primary: role === "primary"
property bool interactive: true
property bool hoverable: interactive
property alias radius: background.radius
property alias color: background.color
property alias border: background.border
signal clicked
property bool destructive: role === "destructive"
readonly property color stateColor: destructive ? theme.error : (primary || checked ? theme.ui.accent : theme.ui.normal)
readonly property color foregroundColor: primary ? theme.content.backdrop : (destructive ? theme.error : theme.content.normal)
readonly property bool pressed: activation.down || activation.enterHeld
readonly property bool hovered: hover.hovered
readonly property bool visualFocus: activation.visualFocus
readonly property bool controlFocused: activation.activeFocus
readonly property bool tooltipVisible: tip.visible
implicitWidth: Math.min(320, (label.visible ? label.implicitWidth : 0) + (root.iconSource.toString().length > 0 ? iconSize : (glyph.visible ? glyph.implicitWidth : 0)) + (label.visible && (glyph.visible || root.iconSource.toString().length > 0) ? labelRow.spacing : 0) + 24)
implicitHeight: 34
activeFocusOnTab: interactive && enabled
opacity: enabled ? 1 : 0.48
Accessible.role: Accessible.Button
Accessible.name: accessibleName
Accessible.checked: checked
Accessible.focusable: interactive && enabled
Accessible.onPressAction: if (interactive && enabled)
activation.click()
Rectangle {
id: background
anchors.fill: parent
radius: 8
color: root.theme.withAlpha(root.stateColor, root.primary ? (root.pressed ? 0.7 : root.hovered ? 0.88 : 1) : (root.pressed ? 0.24 : (root.hovered ? 0.14 : (root.checked ? 0.16 : (root.role === "ghost" ? 0 : 0.06)))))
border.width: root.controlFocused ? 2 : (root.checked ? 1 : 0)
border.color: root.controlFocused ? root.theme.content.focus : root.theme.withAlpha(root.stateColor, 0.65)
Behavior on color {
ColorAnimation {
duration: root.theme.lowPowerMode ? 0 : 90
}
}
}
// Native pointer, Space activation and cancellation; the wrapper retains
// the caller's string icon, checked binding and Rectangle styling API.
T.Button {
id: activation
property bool enterHeld: false
anchors.fill: parent
enabled: root.interactive && root.enabled
focus: true
focusPolicy: Qt.ClickFocus
autoRepeat: false
Accessible.ignored: true
onClicked: root.clicked()
onActiveFocusChanged: if (!activeFocus)
enterHeld = false
onEnabledChanged: if (!enabled)
enterHeld = false
Keys.onPressed: event => {
const enter = event.key === Qt.Key_Return || event.key === Qt.Key_Enter;
if (enter || event.key === Qt.Key_Space && event.isAutoRepeat) {
event.accepted = true;
if (enter && !event.isAutoRepeat)
enterHeld = true;
}
}
Keys.onReleased: event => {
const enter = event.key === Qt.Key_Return || event.key === Qt.Key_Enter;
if (enter || event.key === Qt.Key_Space && event.isAutoRepeat) {
event.accepted = true;
if (enter && !event.isAutoRepeat) {
const activate = enterHeld && enabled;
enterHeld = false;
if (activate)
root.clicked();
}
}
}
}
Item {
anchors.fill: parent
anchors.margins: 4
clip: true
Row {
id: labelRow
anchors.centerIn: parent
spacing: 7
IconImage {
visible: root.iconSource.toString().length > 0
anchors.verticalCenter: parent.verticalCenter
width: root.iconSize
height: root.iconSize
source: root.iconSource
Accessible.ignored: true
}
Text {
id: glyph
visible: root.icon.length > 0 && root.iconSource.toString().length === 0
anchors.verticalCenter: parent.verticalCenter
color: root.foregroundColor
font.family: "Symbols Nerd Font Mono"
font.pixelSize: root.iconSize
text: root.icon
Accessible.ignored: true
}
NuguText {
id: label
visible: root.showText && root.text.length > 0
anchors.verticalCenter: parent.verticalCenter
width: Math.min(implicitWidth, Math.max(0, root.width - 24 - (root.iconSource.toString().length > 0 ? root.iconSize + labelRow.spacing : (glyph.visible ? glyph.implicitWidth + labelRow.spacing : 0))))
theme: root.theme
color: root.foregroundColor
text: root.text
Accessible.ignored: true
}
}
}
HoverHandler {
id: hover
enabled: root.hoverable
cursorShape: root.enabled && root.interactive ? Qt.PointingHandCursor : Qt.ArrowCursor
}
PopupToolTip {
id: tip
theme: root.theme
text: root.tooltip
visible: root.visible && text.length > 0 && !root.pressed && (root.visualFocus || (root.hovered && !root.activeFocus))
}
}