1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00
Files
DankMaterialShell/quickshell/Modals/Greeter/GreeterCompletePage.qml

493 lines
21 KiB
QML

import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: root
property var greeterRoot: parent ? parent.greeterRoot : null
readonly property real headerIconContainerSize: Math.round(Theme.iconSize * 2)
readonly property real sectionIconSize: Theme.iconSizeSmall + 2
readonly property real keybindRowHeight: Math.round(Theme.fontSizeMedium * 2)
readonly property real keyBadgeHeight: Math.round(Theme.fontSizeSmall * 1.83)
readonly property var featureNames: ({
"spotlight": "App Launcher",
"clipboard": "Clipboard",
"processlist": "Task Manager",
"settings": "Settings",
"notifications": "Notifications",
"notepad": "Notepad",
"hotkeys": "Keybinds",
"lock": "Lock Screen",
"dankdash": "Dashboard"
})
function getFeatureDesc(action) {
const match = action.match(/dms\s+ipc\s+call\s+(\w+)/);
if (match && featureNames[match[1]])
return featureNames[match[1]];
return null;
}
readonly property var dmsKeybinds: {
if (!greeterRoot || !greeterRoot.cheatsheetLoaded || !greeterRoot.cheatsheetData || !greeterRoot.cheatsheetData.binds)
return [];
const seen = new Set();
const binds = [];
const allBinds = greeterRoot.cheatsheetData.binds;
for (const category in allBinds) {
const categoryBinds = allBinds[category];
for (let i = 0; i < categoryBinds.length; i++) {
const bind = categoryBinds[i];
if (!bind.key || !bind.action)
continue;
if (!bind.action.includes("dms"))
continue;
if (!(bind.action.includes("spawn") || bind.action.includes("exec")))
continue;
const feature = getFeatureDesc(bind.action);
if (!feature)
continue;
if (seen.has(feature))
continue;
seen.add(feature);
binds.push({
key: bind.key,
desc: feature
});
}
}
return binds;
}
readonly property bool hasKeybinds: dmsKeybinds.length > 0
DankFlickable {
anchors.fill: parent
clip: true
contentHeight: mainColumn.height + Theme.spacingL * 2
contentWidth: width
Column {
id: mainColumn
anchors.horizontalCenter: parent.horizontalCenter
width: Math.min(640, parent.width - Theme.spacingXL * 2)
topPadding: Theme.spacingL
spacing: Theme.spacingL
Row {
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.spacingM
Rectangle {
width: root.headerIconContainerSize
height: root.headerIconContainerSize
radius: Math.round(root.headerIconContainerSize * 0.29)
color: Theme.withAlpha(Theme.success, 0.15)
anchors.verticalCenter: parent.verticalCenter
DankIcon {
anchors.centerIn: parent
name: "check_circle"
size: Theme.iconSize + 4
color: Theme.success
}
}
Column {
anchors.verticalCenter: parent.verticalCenter
spacing: 2
StyledText {
text: I18n.tr("You're All Set!", "greeter completion page title")
font.pixelSize: Theme.fontSizeXLarge
font.weight: Font.Bold
color: Theme.surfaceText
}
StyledText {
text: I18n.tr("DankMaterialShell is ready to use", "greeter completion page subtitle")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
}
}
}
Column {
width: parent.width
spacing: Theme.spacingS
visible: root.hasKeybinds
Row {
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: "keyboard"
size: root.sectionIconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("DMS Shortcuts", "greeter keybinds section header")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
id: keybindsRect
width: parent.width
height: keybindsGrid.height + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
readonly property bool useTwoColumns: width > 500
readonly property int columnCount: useTwoColumns ? 2 : 1
readonly property real itemWidth: useTwoColumns ? (width - Theme.spacingM * 3) / 2 : width - Theme.spacingM * 2
property real maxKeyWidth: 0
Grid {
id: keybindsGrid
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: Theme.spacingM
columns: keybindsRect.columnCount
rowSpacing: Theme.spacingS
columnSpacing: Theme.spacingM
Repeater {
model: root.dmsKeybinds
Row {
width: keybindsRect.itemWidth
height: root.keybindRowHeight
spacing: Theme.spacingS
Item {
width: keybindsRect.maxKeyWidth
height: parent.height
Row {
id: keysRow
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
property real naturalWidth: {
let w = 0;
for (let i = 0; i < children.length; i++) {
if (children[i].visible)
w += children[i].width + (i > 0 ? Theme.spacingXS : 0);
}
return w;
}
Component.onCompleted: {
Qt.callLater(() => {
if (naturalWidth > keybindsRect.maxKeyWidth)
keybindsRect.maxKeyWidth = naturalWidth;
});
}
Repeater {
model: (modelData.key || "").split("+")
Rectangle {
width: singleKeyText.implicitWidth + Theme.spacingM
height: root.keyBadgeHeight
radius: Theme.spacingXS
color: Theme.surfaceContainerHighest
border.width: 1
border.color: Theme.outline
StyledText {
id: singleKeyText
anchors.centerIn: parent
color: Theme.secondary
text: modelData
font.pixelSize: Theme.fontSizeSmall - 1
font.weight: Font.Medium
isMonospace: true
}
}
}
}
}
StyledText {
anchors.verticalCenter: parent.verticalCenter
width: parent.width - keybindsRect.maxKeyWidth - Theme.spacingS
text: modelData.desc || ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
elide: Text.ElideRight
}
}
}
}
}
}
Rectangle {
width: parent.width
height: noKeybindsColumn.height + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
visible: !root.hasKeybinds
Column {
id: noKeybindsColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: Theme.spacingM
spacing: Theme.spacingS
Row {
spacing: Theme.spacingS
DankIcon {
name: "keyboard"
size: root.sectionIconSize
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("No DMS shortcuts configured", "greeter no keybinds message")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
width: parent.width
height: Math.round(Theme.fontSizeMedium * 2.85)
radius: Theme.cornerRadius
color: Theme.surfaceContainerHighest
Rectangle {
anchors.fill: parent
radius: parent.radius
color: Theme.primary
opacity: noKeybindsLinkMouse.containsMouse ? 0.12 : 0
}
Row {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
name: "menu_book"
size: root.sectionIconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Configure Keybinds", "greeter configure keybinds link")
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
DankIcon {
name: "open_in_new"
size: Theme.iconSizeSmall - 2
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: noKeybindsLinkMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
let url = "https://danklinux.com/docs/dankmaterialshell/keybinds-ipc";
if (CompositorService.isNiri)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings";
else if (CompositorService.isHyprland)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-1";
else if (CompositorService.isDwl)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-2";
Qt.openUrlExternally(url);
}
}
}
}
}
Rectangle {
width: parent.width
height: 1
color: Theme.outlineMedium
opacity: 0.3
visible: root.hasKeybinds
}
Column {
width: parent.width
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: "settings"
size: root.sectionIconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Configure", "greeter settings section header")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Grid {
width: parent.width
columns: 2
rowSpacing: Theme.spacingS
columnSpacing: Theme.spacingS
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "display_settings"
title: I18n.tr("Displays", "greeter settings link")
description: I18n.tr("Resolution, position, scale", "greeter displays description")
onClicked: PopoutService.openSettingsWithTab("display_config")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "wallpaper"
title: I18n.tr("Wallpaper", "greeter settings link")
description: I18n.tr("Background image", "greeter wallpaper description")
onClicked: PopoutService.openSettingsWithTab("wallpaper")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "format_paint"
title: I18n.tr("Theme & Colors", "greeter settings link")
description: I18n.tr("Dynamic colors, presets", "greeter theme description")
onClicked: PopoutService.openSettingsWithTab("theme")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "notifications"
title: I18n.tr("Notifications", "greeter settings link")
description: I18n.tr("Popup behavior, position", "greeter notifications description")
onClicked: PopoutService.openSettingsWithTab("notifications")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "toolbar"
title: I18n.tr("DankBar", "greeter settings link")
description: I18n.tr("Widgets, layout, style", "greeter dankbar description")
onClicked: PopoutService.openSettingsWithTab("dankbar_settings")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "keyboard"
title: I18n.tr("Keybinds", "greeter settings link")
description: I18n.tr("niri shortcuts config", "greeter keybinds niri description")
visible: KeybindsService.available
onClicked: PopoutService.openSettingsWithTab("keybinds")
}
GreeterSettingsCard {
width: (parent.width - Theme.spacingS) / 2
iconName: "dock_to_bottom"
title: I18n.tr("Dock", "greeter settings link")
description: I18n.tr("Position, pinned apps", "greeter dock description")
visible: !KeybindsService.available
onClicked: PopoutService.openSettingsWithTab("dock")
}
}
}
Rectangle {
width: parent.width
height: 1
color: Theme.outlineMedium
opacity: 0.3
}
Column {
width: parent.width
spacing: Theme.spacingS
Row {
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: "explore"
size: root.sectionIconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Explore", "greeter explore section header")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Row {
width: parent.width
spacing: Theme.spacingS
GreeterQuickLink {
width: (parent.width - Theme.spacingS * 2) / 3
iconName: "menu_book"
title: I18n.tr("Docs", "greeter documentation link")
isExternal: true
onClicked: Qt.openUrlExternally("https://danklinux.com/docs")
}
GreeterQuickLink {
width: (parent.width - Theme.spacingS * 2) / 3
iconName: "extension"
title: I18n.tr("Plugins", "greeter plugins link")
isExternal: true
onClicked: Qt.openUrlExternally("https://danklinux.com/plugins")
}
GreeterQuickLink {
width: (parent.width - Theme.spacingS * 2) / 3
iconName: "palette"
title: I18n.tr("Themes", "greeter themes link")
isExternal: true
onClicked: Qt.openUrlExternally("https://danklinux.com/plugins?tab=themes")
}
}
}
}
}
}