quickshell: uniform panelGap token + card-style notifications/toast
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
0342cbe59a
commit
1158a36d1a
1 changed files with 71 additions and 65 deletions
|
|
@ -184,6 +184,7 @@ in
|
||||||
readonly property int radiusSmall: 6 // workspace dots, pill buttons
|
readonly property int radiusSmall: 6 // workspace dots, pill buttons
|
||||||
readonly property int radiusTiny: 4 // hover rows, action chips
|
readonly property int radiusTiny: 4 // hover rows, action chips
|
||||||
readonly property int cardPad: 8 // card inner padding (inset = 2×)
|
readonly property int cardPad: 8 // card inner padding (inset = 2×)
|
||||||
|
readonly property int panelGap: 8 // gap between panel border and cards (all dropdowns/menus/toast)
|
||||||
|
|
||||||
// ── Animation duration tokens (ms) ──
|
// ── Animation duration tokens (ms) ──
|
||||||
readonly property int animMorph: 280 // panel grow / slide (OutExpo)
|
readonly property int animMorph: 280 // panel grow / slide (OutExpo)
|
||||||
|
|
@ -949,8 +950,8 @@ in
|
||||||
// Both axes animate so the panel expands from a small
|
// Both axes animate so the panel expands from a small
|
||||||
// point on the column (like the top dropdowns' stub seed)
|
// point on the column (like the top dropdowns' stub seed)
|
||||||
// instead of rolling out at full height.
|
// instead of rolling out at full height.
|
||||||
property real openW: open ? 64 : 0
|
property real openW: open ? sessionCard.width + 2 * Theme.panelGap : 0
|
||||||
property real openH: open ? sessionCard.height + 24 : 36
|
property real openH: open ? sessionCard.height + 2 * Theme.panelGap : 36
|
||||||
Behavior on openW {
|
Behavior on openW {
|
||||||
NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo }
|
NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo }
|
||||||
}
|
}
|
||||||
|
|
@ -1009,7 +1010,7 @@ in
|
||||||
id: sessionCard
|
id: sessionCard
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 8
|
anchors.rightMargin: Theme.panelGap
|
||||||
width: 48
|
width: 48
|
||||||
height: sessionCol.height + 8
|
height: sessionCol.height + 8
|
||||||
radius: Theme.radius
|
radius: Theme.radius
|
||||||
|
|
@ -2048,8 +2049,8 @@ in
|
||||||
id: contextMenu
|
id: contextMenu
|
||||||
alignRight: true
|
alignRight: true
|
||||||
property var trayItem: null
|
property var trayItem: null
|
||||||
fullWidth: menuItems.width + 24
|
fullWidth: menuItems.width + 2 * Theme.panelGap
|
||||||
fullHeight: menuItems.height + 16
|
fullHeight: menuItems.height + 2 * Theme.panelGap
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (!visible) menuOpener.menu = null;
|
if (!visible) menuOpener.menu = null;
|
||||||
|
|
@ -2132,8 +2133,8 @@ in
|
||||||
BarDropdown {
|
BarDropdown {
|
||||||
id: volDropdown
|
id: volDropdown
|
||||||
alignRight: true
|
alignRight: true
|
||||||
fullWidth: volDropdownCol.width + 28
|
fullWidth: volDropdownCol.width + 2 * Theme.panelGap
|
||||||
fullHeight: volDropdownCol.height + 20
|
fullHeight: volDropdownCol.height + 2 * Theme.panelGap
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: volDropdownCol
|
id: volDropdownCol
|
||||||
|
|
@ -2289,8 +2290,8 @@ in
|
||||||
BarDropdown {
|
BarDropdown {
|
||||||
id: netDropdown
|
id: netDropdown
|
||||||
alignRight: true
|
alignRight: true
|
||||||
fullWidth: netDropdownCol.width + 28
|
fullWidth: netDropdownCol.width + 2 * Theme.panelGap
|
||||||
fullHeight: netDropdownCol.height + 20
|
fullHeight: netDropdownCol.height + 2 * Theme.panelGap
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: netDropdownCol
|
id: netDropdownCol
|
||||||
|
|
@ -2424,8 +2425,8 @@ in
|
||||||
BarDropdown {
|
BarDropdown {
|
||||||
id: batteryDropdown
|
id: batteryDropdown
|
||||||
alignRight: true
|
alignRight: true
|
||||||
fullWidth: batteryDropdownCol.width + 28
|
fullWidth: batteryDropdownCol.width + 2 * Theme.panelGap
|
||||||
fullHeight: batteryDropdownCol.height + 20
|
fullHeight: batteryDropdownCol.height + 2 * Theme.panelGap
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: batteryDropdownCol
|
id: batteryDropdownCol
|
||||||
|
|
@ -2624,8 +2625,8 @@ in
|
||||||
BarDropdown {
|
BarDropdown {
|
||||||
id: qsDropdown
|
id: qsDropdown
|
||||||
alignRight: true
|
alignRight: true
|
||||||
fullWidth: qsCol.width + 28
|
fullWidth: qsCol.width + 2 * Theme.panelGap
|
||||||
fullHeight: qsCol.height + 20
|
fullHeight: qsCol.height + 2 * Theme.panelGap
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: qsCol
|
id: qsCol
|
||||||
|
|
@ -2645,8 +2646,8 @@ in
|
||||||
dropdownX: bar.width / 2
|
dropdownX: bar.width / 2
|
||||||
// ceil: Text metrics give fractional sizes; fractional rect
|
// ceil: Text metrics give fractional sizes; fractional rect
|
||||||
// edges render as soft 2px lines
|
// edges render as soft 2px lines
|
||||||
fullWidth: Math.ceil(calRow.width) + 24
|
fullWidth: Math.ceil(calRow.width) + 2 * Theme.panelGap
|
||||||
fullHeight: Math.ceil(calRow.height + 8 + notifCard.height) + 24
|
fullHeight: Math.ceil(calRow.height + 8 + notifCard.height) + 2 * Theme.panelGap
|
||||||
|
|
||||||
// Month being viewed; reset to today when the popup opens
|
// Month being viewed; reset to today when the popup opens
|
||||||
// (via the setup function passed to bar.toggleDropdown).
|
// (via the setup function passed to bar.toggleDropdown).
|
||||||
|
|
@ -3060,27 +3061,31 @@ in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Notifications: spans both columns, below the panes ──
|
// ── Notifications: spans both columns, below the panes.
|
||||||
Card {
|
// Header + one Card per notification, matching the media
|
||||||
|
// cards instead of base02 blocks nested inside a big card.
|
||||||
|
Column {
|
||||||
id: notifCard
|
id: notifCard
|
||||||
anchors.top: calRow.bottom
|
anchors.top: calRow.bottom
|
||||||
anchors.topMargin: 8
|
anchors.topMargin: 8
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
width: calRow.width
|
width: calRow.width
|
||||||
opacity: calRow.opacity
|
opacity: calRow.opacity
|
||||||
cardSpacing: 6
|
spacing: 8
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 20
|
height: 20
|
||||||
SText {
|
SText {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Theme.cardPad
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "Notifications"
|
text: "Notifications"
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
}
|
}
|
||||||
SText {
|
SText {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Theme.cardPad
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: bar.notifServer.trackedNotifications.values.length > 0 ? "Clear all" : ""
|
text: bar.notifServer.trackedNotifications.values.length > 0 ? "Clear all" : ""
|
||||||
color: Theme.base04
|
color: Theme.base04
|
||||||
|
|
@ -3109,14 +3114,15 @@ in
|
||||||
Repeater {
|
Repeater {
|
||||||
model: bar.notifServer.trackedNotifications
|
model: bar.notifServer.trackedNotifications
|
||||||
|
|
||||||
Rectangle {
|
Card {
|
||||||
id: notifItem
|
id: notifItem
|
||||||
required property var modelData
|
required property var modelData
|
||||||
readonly property string previewSource: bar.notifPreviewSource(notifItem.modelData)
|
readonly property string previewSource: bar.notifPreviewSource(notifItem.modelData)
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: Math.max(notifPreview.visible ? 48 : 0, ncBody.height) + 16
|
|
||||||
radius: Theme.radiusSmall
|
Item {
|
||||||
color: Theme.base02
|
width: parent.width
|
||||||
|
height: Math.max(notifPreview.visible ? 48 : 0, ncBody.height)
|
||||||
|
|
||||||
// Image preview (album art, screenshot thumb…)
|
// Image preview (album art, screenshot thumb…)
|
||||||
ClippingRectangle {
|
ClippingRectangle {
|
||||||
|
|
@ -3124,7 +3130,6 @@ in
|
||||||
visible: notifItem.previewSource !== ""
|
visible: notifItem.previewSource !== ""
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: 8
|
|
||||||
width: 48; height: 48
|
width: 48; height: 48
|
||||||
radius: Theme.radiusTiny
|
radius: Theme.radiusTiny
|
||||||
color: Theme.base01
|
color: Theme.base01
|
||||||
|
|
@ -3139,16 +3144,16 @@ in
|
||||||
id: ncBody
|
id: ncBody
|
||||||
notif: notifItem.modelData
|
notif: notifItem.modelData
|
||||||
anchors.left: notifPreview.visible ? notifPreview.right : parent.left
|
anchors.left: notifPreview.visible ? notifPreview.right : parent.left
|
||||||
|
anchors.leftMargin: notifPreview.visible ? 8 : 0
|
||||||
anchors.right: dismissBtn.left
|
anchors.right: dismissBtn.left
|
||||||
|
anchors.rightMargin: 8
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: 8
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SIcon {
|
SIcon {
|
||||||
id: dismissBtn
|
id: dismissBtn
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.margins: 8
|
|
||||||
text: "close"
|
text: "close"
|
||||||
color: dismissMa.containsMouse ? Theme.base05 : Theme.base03
|
color: dismissMa.containsMouse ? Theme.base05 : Theme.base03
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
|
|
@ -3164,6 +3169,7 @@ in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Notification Toast (only on primary screen) ──
|
// ── Notification Toast (only on primary screen) ──
|
||||||
Item {
|
Item {
|
||||||
|
|
@ -3248,24 +3254,24 @@ in
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
width: 320
|
width: 320
|
||||||
height: toastItem.toastOpen ? toastCard.height + 12 : 0
|
height: toastItem.toastOpen ? toastCard.height + 2 * Theme.panelGap : 0
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Behavior on height {
|
Behavior on height {
|
||||||
NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo }
|
NumberAnimation { duration: Theme.animMorph; easing.type: Easing.OutExpo }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notification sits in a base02 rounded card, matching
|
// Notification sits in a cardBg card like every other
|
||||||
// the calendar list. Inset 6px so the melt panel frames it.
|
// dropdown surface, inset panelGap from the melt panel.
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: toastCard
|
id: toastCard
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.margins: 6
|
anchors.margins: Theme.panelGap
|
||||||
height: Math.max(toastPreview.visible ? 48 : 0, toastCol.height) + 16
|
height: Math.max(toastPreview.visible ? 48 : 0, toastCol.height) + 16
|
||||||
radius: Theme.radiusSmall
|
radius: Theme.radius
|
||||||
color: Theme.base02
|
color: Theme.cardBg
|
||||||
|
|
||||||
property string previewSource: bar.notifPreviewSource(toastItem.currentNotif)
|
property string previewSource: bar.notifPreviewSource(toastItem.currentNotif)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue