mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
Allow solid colored wallpaper, fix fzf search
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
@@ -53,19 +54,13 @@ Singleton {
|
||||
var settings = JSON.parse(content)
|
||||
isLightMode = settings.isLightMode !== undefined ? settings.isLightMode : false
|
||||
wallpaperPath = settings.wallpaperPath !== undefined ? settings.wallpaperPath : ""
|
||||
wallpaperLastPath = settings.wallpaperLastPath
|
||||
!== undefined ? settings.wallpaperLastPath : ""
|
||||
profileLastPath = settings.profileLastPath
|
||||
!== undefined ? settings.profileLastPath : ""
|
||||
wallpaperLastPath = settings.wallpaperLastPath !== undefined ? settings.wallpaperLastPath : ""
|
||||
profileLastPath = settings.profileLastPath !== undefined ? settings.profileLastPath : ""
|
||||
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false
|
||||
nightModeEnabled = settings.nightModeEnabled
|
||||
!== undefined ? settings.nightModeEnabled : false
|
||||
nightModeTemperature = settings.nightModeTemperature
|
||||
!== undefined ? settings.nightModeTemperature : 4500
|
||||
nightModeAutoEnabled = settings.nightModeAutoEnabled
|
||||
!== undefined ? settings.nightModeAutoEnabled : false
|
||||
nightModeAutoMode = settings.nightModeAutoMode
|
||||
!== undefined ? settings.nightModeAutoMode : "time"
|
||||
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false
|
||||
nightModeTemperature = settings.nightModeTemperature !== undefined ? settings.nightModeTemperature : 4500
|
||||
nightModeAutoEnabled = settings.nightModeAutoEnabled !== undefined ? settings.nightModeAutoEnabled : false
|
||||
nightModeAutoMode = settings.nightModeAutoMode !== undefined ? settings.nightModeAutoMode : "time"
|
||||
// Handle legacy time format
|
||||
if (settings.nightModeStartTime !== undefined) {
|
||||
const parts = settings.nightModeStartTime.split(":")
|
||||
@@ -87,24 +82,15 @@ Singleton {
|
||||
longitude = settings.longitude !== undefined ? settings.longitude : 0.0
|
||||
nightModeLocationProvider = settings.nightModeLocationProvider !== undefined ? settings.nightModeLocationProvider : ""
|
||||
pinnedApps = settings.pinnedApps !== undefined ? settings.pinnedApps : []
|
||||
selectedGpuIndex = settings.selectedGpuIndex
|
||||
!== undefined ? settings.selectedGpuIndex : 0
|
||||
nvidiaGpuTempEnabled = settings.nvidiaGpuTempEnabled
|
||||
!== undefined ? settings.nvidiaGpuTempEnabled : false
|
||||
nonNvidiaGpuTempEnabled = settings.nonNvidiaGpuTempEnabled
|
||||
!== undefined ? settings.nonNvidiaGpuTempEnabled : false
|
||||
enabledGpuPciIds = settings.enabledGpuPciIds
|
||||
!== undefined ? settings.enabledGpuPciIds : []
|
||||
wallpaperCyclingEnabled = settings.wallpaperCyclingEnabled
|
||||
!== undefined ? settings.wallpaperCyclingEnabled : false
|
||||
wallpaperCyclingMode = settings.wallpaperCyclingMode
|
||||
!== undefined ? settings.wallpaperCyclingMode : "interval"
|
||||
wallpaperCyclingInterval = settings.wallpaperCyclingInterval
|
||||
!== undefined ? settings.wallpaperCyclingInterval : 300
|
||||
wallpaperCyclingTime = settings.wallpaperCyclingTime
|
||||
!== undefined ? settings.wallpaperCyclingTime : "06:00"
|
||||
lastBrightnessDevice = settings.lastBrightnessDevice
|
||||
!== undefined ? settings.lastBrightnessDevice : ""
|
||||
selectedGpuIndex = settings.selectedGpuIndex !== undefined ? settings.selectedGpuIndex : 0
|
||||
nvidiaGpuTempEnabled = settings.nvidiaGpuTempEnabled !== undefined ? settings.nvidiaGpuTempEnabled : false
|
||||
nonNvidiaGpuTempEnabled = settings.nonNvidiaGpuTempEnabled !== undefined ? settings.nonNvidiaGpuTempEnabled : false
|
||||
enabledGpuPciIds = settings.enabledGpuPciIds !== undefined ? settings.enabledGpuPciIds : []
|
||||
wallpaperCyclingEnabled = settings.wallpaperCyclingEnabled !== undefined ? settings.wallpaperCyclingEnabled : false
|
||||
wallpaperCyclingMode = settings.wallpaperCyclingMode !== undefined ? settings.wallpaperCyclingMode : "interval"
|
||||
wallpaperCyclingInterval = settings.wallpaperCyclingInterval !== undefined ? settings.wallpaperCyclingInterval : 300
|
||||
wallpaperCyclingTime = settings.wallpaperCyclingTime !== undefined ? settings.wallpaperCyclingTime : "06:00"
|
||||
lastBrightnessDevice = settings.lastBrightnessDevice !== undefined ? settings.lastBrightnessDevice : ""
|
||||
notepadContent = settings.notepadContent !== undefined ? settings.notepadContent : ""
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -218,22 +204,41 @@ Singleton {
|
||||
}
|
||||
|
||||
function setWallpaper(imagePath) {
|
||||
console.log("SessionData.setWallpaper called with:", imagePath)
|
||||
wallpaperPath = imagePath
|
||||
saveSettings()
|
||||
|
||||
if (typeof Theme !== "undefined") {
|
||||
console.log("Theme is available, current theme:", Theme.currentTheme)
|
||||
// Always extract colors for shell UI if dynamic theming is enabled
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.wallpaperDynamicTheming) {
|
||||
console.log("Dynamic theming enabled, extracting colors")
|
||||
Theme.switchTheme("dynamic")
|
||||
Theme.extractColors()
|
||||
}
|
||||
// Always generate system themes (matugen templates) when wallpaper changes
|
||||
console.log("Calling generateSystemThemesFromCurrentTheme")
|
||||
Theme.generateSystemThemesFromCurrentTheme()
|
||||
} else {
|
||||
console.log("Theme is undefined!")
|
||||
}
|
||||
}
|
||||
|
||||
function setWallpaperColor(color) {
|
||||
wallpaperPath = color
|
||||
saveSettings()
|
||||
|
||||
if (typeof Theme !== "undefined") {
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.wallpaperDynamicTheming) {
|
||||
Theme.switchTheme("dynamic")
|
||||
Theme.extractColors()
|
||||
}
|
||||
Theme.generateSystemThemesFromCurrentTheme()
|
||||
}
|
||||
}
|
||||
|
||||
function clearWallpaper() {
|
||||
wallpaperPath = ""
|
||||
saveSettings()
|
||||
|
||||
if (typeof Theme !== "undefined") {
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.theme) {
|
||||
Theme.switchTheme(SettingsData.theme)
|
||||
} else {
|
||||
Theme.switchTheme("blue")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -321,8 +326,7 @@ Singleton {
|
||||
FileView {
|
||||
id: settingsFile
|
||||
|
||||
path: StandardPaths.writableLocation(
|
||||
StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json"
|
||||
path: StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json"
|
||||
blockLoading: true
|
||||
blockWrites: true
|
||||
watchChanges: true
|
||||
@@ -344,9 +348,7 @@ Singleton {
|
||||
return "ERROR: No path provided"
|
||||
}
|
||||
|
||||
var absolutePath = path.startsWith(
|
||||
"/") ? path : StandardPaths.writableLocation(
|
||||
StandardPaths.HomeLocation) + "/" + path
|
||||
var absolutePath = path.startsWith("/") ? path : StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/" + path
|
||||
|
||||
try {
|
||||
root.setWallpaper(absolutePath)
|
||||
|
||||
217
Common/Theme.qml
217
Common/Theme.qml
@@ -1,4 +1,5 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtCore
|
||||
@@ -14,7 +15,7 @@ Singleton {
|
||||
|
||||
property string currentTheme: "blue"
|
||||
property bool isLightMode: false
|
||||
|
||||
|
||||
readonly property string dynamic: "dynamic"
|
||||
|
||||
readonly property string homeDir: {
|
||||
@@ -27,7 +28,7 @@ Singleton {
|
||||
}
|
||||
readonly property string shellDir: Qt.resolvedUrl(".").toString().replace("file://", "").replace("/Common/", "")
|
||||
readonly property string wallpaperPath: typeof SessionData !== "undefined" ? SessionData.wallpaperPath : ""
|
||||
|
||||
|
||||
property bool matugenAvailable: false
|
||||
property bool gtkThemingEnabled: typeof SettingsData !== "undefined" ? SettingsData.gtkAvailable : false
|
||||
property bool qtThemingEnabled: typeof SettingsData !== "undefined" ? (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) : false
|
||||
@@ -36,7 +37,7 @@ Singleton {
|
||||
property bool extractionRequested: false
|
||||
property int colorUpdateTrigger: 0
|
||||
property var customThemeData: null
|
||||
|
||||
|
||||
readonly property string stateDir: {
|
||||
const cacheHome = StandardPaths.writableLocation(StandardPaths.CacheLocation).toString()
|
||||
const path = cacheHome.startsWith("file://") ? cacheHome.substring(7) : cacheHome
|
||||
@@ -60,24 +61,24 @@ Singleton {
|
||||
return customThemeData || StockThemes.getThemeByName("blue", isLightMode)
|
||||
} else if (currentTheme === dynamic) {
|
||||
return {
|
||||
primary: getMatugenColor("primary", "#42a5f5"),
|
||||
primaryText: getMatugenColor("on_primary", "#ffffff"),
|
||||
primaryContainer: getMatugenColor("primary_container", "#1976d2"),
|
||||
secondary: getMatugenColor("secondary", "#8ab4f8"),
|
||||
surface: getMatugenColor("surface", "#1a1c1e"),
|
||||
surfaceText: getMatugenColor("on_background", "#e3e8ef"),
|
||||
surfaceVariant: getMatugenColor("surface_variant", "#44464f"),
|
||||
surfaceVariantText: getMatugenColor("on_surface_variant", "#c4c7c5"),
|
||||
surfaceTint: getMatugenColor("surface_tint", "#8ab4f8"),
|
||||
background: getMatugenColor("background", "#1a1c1e"),
|
||||
backgroundText: getMatugenColor("on_background", "#e3e8ef"),
|
||||
outline: getMatugenColor("outline", "#8e918f"),
|
||||
surfaceContainer: getMatugenColor("surface_container", "#1e2023"),
|
||||
surfaceContainerHigh: getMatugenColor("surface_container_high", "#292b2f"),
|
||||
error: "#F2B8B5",
|
||||
warning: "#FF9800",
|
||||
info: "#2196F3",
|
||||
success: "#4CAF50"
|
||||
"primary": getMatugenColor("primary", "#42a5f5"),
|
||||
"primaryText": getMatugenColor("on_primary", "#ffffff"),
|
||||
"primaryContainer": getMatugenColor("primary_container", "#1976d2"),
|
||||
"secondary": getMatugenColor("secondary", "#8ab4f8"),
|
||||
"surface": getMatugenColor("surface", "#1a1c1e"),
|
||||
"surfaceText": getMatugenColor("on_background", "#e3e8ef"),
|
||||
"surfaceVariant": getMatugenColor("surface_variant", "#44464f"),
|
||||
"surfaceVariantText": getMatugenColor("on_surface_variant", "#c4c7c5"),
|
||||
"surfaceTint": getMatugenColor("surface_tint", "#8ab4f8"),
|
||||
"background": getMatugenColor("background", "#1a1c1e"),
|
||||
"backgroundText": getMatugenColor("on_background", "#e3e8ef"),
|
||||
"outline": getMatugenColor("outline", "#8e918f"),
|
||||
"surfaceContainer": getMatugenColor("surface_container", "#1e2023"),
|
||||
"surfaceContainerHigh": getMatugenColor("surface_container_high", "#292b2f"),
|
||||
"error": "#F2B8B5",
|
||||
"warning": "#FF9800",
|
||||
"info": "#2196F3",
|
||||
"success": "#4CAF50"
|
||||
}
|
||||
} else {
|
||||
return StockThemes.getThemeByName(currentTheme, isLightMode)
|
||||
@@ -175,7 +176,7 @@ Singleton {
|
||||
}
|
||||
if (savePrefs && typeof SettingsData !== "undefined")
|
||||
SettingsData.setTheme(currentTheme)
|
||||
|
||||
|
||||
generateSystemThemesFromCurrentTheme()
|
||||
}
|
||||
|
||||
@@ -183,14 +184,14 @@ Singleton {
|
||||
isLightMode = light
|
||||
if (savePrefs && typeof SessionData !== "undefined")
|
||||
SessionData.setLightMode(isLightMode)
|
||||
PortalService.setLightMode(isLightMode)
|
||||
PortalService.setLightMode(isLightMode)
|
||||
generateSystemThemesFromCurrentTheme()
|
||||
}
|
||||
|
||||
function toggleLightMode(savePrefs = true) {
|
||||
setLightMode(!isLightMode, savePrefs)
|
||||
}
|
||||
|
||||
|
||||
function forceGenerateSystemThemes() {
|
||||
if (!matugenAvailable) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
@@ -225,7 +226,7 @@ Singleton {
|
||||
} else {
|
||||
customThemeData = themeData
|
||||
}
|
||||
|
||||
|
||||
generateSystemThemesFromCurrentTheme()
|
||||
}
|
||||
|
||||
@@ -237,7 +238,6 @@ Singleton {
|
||||
readonly property var _availableThemeNames: StockThemes.getAllThemeNames()
|
||||
property string currentThemeName: currentTheme
|
||||
|
||||
|
||||
function popupBackground() {
|
||||
return Qt.rgba(surfaceContainer.r, surfaceContainer.g, surfaceContainer.b, popupTransparency)
|
||||
}
|
||||
@@ -271,21 +271,34 @@ Singleton {
|
||||
return _getBatteryPowerProfileIcon()
|
||||
|
||||
if (isCharging) {
|
||||
if (level >= 90) return "battery_charging_full"
|
||||
if (level >= 80) return "battery_charging_90"
|
||||
if (level >= 60) return "battery_charging_80"
|
||||
if (level >= 50) return "battery_charging_60"
|
||||
if (level >= 30) return "battery_charging_50"
|
||||
if (level >= 20) return "battery_charging_30"
|
||||
if (level >= 90)
|
||||
return "battery_charging_full"
|
||||
if (level >= 80)
|
||||
return "battery_charging_90"
|
||||
if (level >= 60)
|
||||
return "battery_charging_80"
|
||||
if (level >= 50)
|
||||
return "battery_charging_60"
|
||||
if (level >= 30)
|
||||
return "battery_charging_50"
|
||||
if (level >= 20)
|
||||
return "battery_charging_30"
|
||||
return "battery_charging_20"
|
||||
} else {
|
||||
if (level >= 95) return "battery_full"
|
||||
if (level >= 85) return "battery_6_bar"
|
||||
if (level >= 70) return "battery_5_bar"
|
||||
if (level >= 55) return "battery_4_bar"
|
||||
if (level >= 40) return "battery_3_bar"
|
||||
if (level >= 25) return "battery_2_bar"
|
||||
if (level >= 10) return "battery_1_bar"
|
||||
if (level >= 95)
|
||||
return "battery_full"
|
||||
if (level >= 85)
|
||||
return "battery_6_bar"
|
||||
if (level >= 70)
|
||||
return "battery_5_bar"
|
||||
if (level >= 55)
|
||||
return "battery_4_bar"
|
||||
if (level >= 40)
|
||||
return "battery_3_bar"
|
||||
if (level >= 25)
|
||||
return "battery_2_bar"
|
||||
if (level >= 10)
|
||||
return "battery_1_bar"
|
||||
return "battery_alert"
|
||||
}
|
||||
}
|
||||
@@ -355,11 +368,11 @@ Singleton {
|
||||
if (matugenColors && Object.keys(matugenColors).length > 0) {
|
||||
colorUpdateTrigger++
|
||||
}
|
||||
|
||||
|
||||
if (currentTheme === "custom" && customThemeFileView.path) {
|
||||
customThemeFileView.reload()
|
||||
}
|
||||
|
||||
|
||||
generateSystemThemesFromCurrentTheme()
|
||||
}
|
||||
|
||||
@@ -368,38 +381,39 @@ Singleton {
|
||||
console.warn("matugen not available - cannot set system theme")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
const desired = {
|
||||
"kind": kind,
|
||||
"value": value,
|
||||
"mode": isLight ? "light" : "dark",
|
||||
"iconTheme": iconTheme || "System Default"
|
||||
}
|
||||
|
||||
|
||||
const json = JSON.stringify(desired)
|
||||
const desiredPath = stateDir + "/matugen.desired.json"
|
||||
|
||||
Quickshell.execDetached([
|
||||
"sh", "-c",
|
||||
`mkdir -p '${stateDir}' && cat > '${desiredPath}' << 'EOF'\n${json}\nEOF`
|
||||
])
|
||||
|
||||
Quickshell.execDetached(["sh", "-c", `mkdir -p '${stateDir}' && cat > '${desiredPath}' << 'EOF'\n${json}\nEOF`])
|
||||
workerRunning = true
|
||||
systemThemeGenerator.command = [shellDir + "/scripts/matugen-worker.sh", stateDir, shellDir, "--run"]
|
||||
systemThemeGenerator.running = true
|
||||
}
|
||||
|
||||
|
||||
function generateSystemThemesFromCurrentTheme() {
|
||||
if (!matugenAvailable)
|
||||
return
|
||||
|
||||
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
||||
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
||||
|
||||
|
||||
if (currentTheme === dynamic) {
|
||||
if (!wallpaperPath) {
|
||||
return
|
||||
}
|
||||
setDesiredTheme("image", wallpaperPath, isLight, iconTheme)
|
||||
if (wallpaperPath.startsWith("#")) {
|
||||
setDesiredTheme("hex", wallpaperPath, isLight, iconTheme)
|
||||
} else {
|
||||
setDesiredTheme("image", wallpaperPath, isLight, iconTheme)
|
||||
}
|
||||
} else {
|
||||
let primaryColor
|
||||
if (currentTheme === "custom") {
|
||||
@@ -411,7 +425,7 @@ Singleton {
|
||||
} else {
|
||||
primaryColor = currentThemeData.primary
|
||||
}
|
||||
|
||||
|
||||
if (!primaryColor) {
|
||||
console.warn("No primary color available for theme:", currentTheme)
|
||||
return
|
||||
@@ -445,17 +459,22 @@ Singleton {
|
||||
qtApplier.running = true
|
||||
}
|
||||
|
||||
|
||||
function extractJsonFromText(text) {
|
||||
if (!text) return null
|
||||
if (!text)
|
||||
return null
|
||||
|
||||
const start = text.search(/[{\[]/)
|
||||
if (start === -1) return null
|
||||
if (start === -1)
|
||||
return null
|
||||
|
||||
const open = text[start]
|
||||
const pairs = { "{": '}', "[": ']' }
|
||||
const pairs = {
|
||||
"{": '}',
|
||||
"[": ']'
|
||||
}
|
||||
const close = pairs[open]
|
||||
if (!close) return null
|
||||
if (!close)
|
||||
return null
|
||||
|
||||
let inString = false
|
||||
let escape = false
|
||||
@@ -511,17 +530,18 @@ Singleton {
|
||||
if (extractionRequested) {
|
||||
fileChecker.running = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
||||
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
||||
|
||||
|
||||
if (currentTheme === dynamic) {
|
||||
if (wallpaperPath) {
|
||||
// Clear cache on startup to force regeneration
|
||||
Quickshell.execDetached(["rm", "-f", stateDir + "/matugen.key"])
|
||||
setDesiredTheme("image", wallpaperPath, isLight, iconTheme)
|
||||
} else {
|
||||
if (wallpaperPath.startsWith("#")) {
|
||||
setDesiredTheme("hex", wallpaperPath, isLight, iconTheme)
|
||||
} else {
|
||||
setDesiredTheme("image", wallpaperPath, isLight, iconTheme)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let primaryColor
|
||||
@@ -532,12 +552,10 @@ Singleton {
|
||||
} else {
|
||||
primaryColor = currentThemeData.primary
|
||||
}
|
||||
|
||||
|
||||
if (primaryColor) {
|
||||
// Clear cache on startup to force regeneration
|
||||
Quickshell.execDetached(["rm", "-f", stateDir + "/matugen.key"])
|
||||
setDesiredTheme("hex", primaryColor, isLight, iconTheme)
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -549,6 +567,8 @@ Singleton {
|
||||
onExited: code => {
|
||||
if (code === 0) {
|
||||
matugenProcess.running = true
|
||||
} else if (wallpaperPath.startsWith("#")) {
|
||||
colorMatugenProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,18 +621,65 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: colorMatugenProcess
|
||||
command: ["matugen", "color", "hex", wallpaperPath, "--json", "hex"]
|
||||
|
||||
stdout: StdioCollector {
|
||||
id: colorMatugenCollector
|
||||
onStreamFinished: {
|
||||
if (!colorMatugenCollector.text) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.wallpaperErrorStatus = "error"
|
||||
ToastService.showError("Color Processing Failed: Empty JSON extracted from matugen output.")
|
||||
}
|
||||
return
|
||||
}
|
||||
const extractedJson = extractJsonFromText(colorMatugenCollector.text)
|
||||
if (!extractedJson) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.wallpaperErrorStatus = "error"
|
||||
ToastService.showError("Color Processing Failed: Invalid JSON extracted from matugen output.")
|
||||
}
|
||||
console.log("Raw matugen output:", colorMatugenCollector.text)
|
||||
return
|
||||
}
|
||||
try {
|
||||
root.matugenColors = JSON.parse(extractedJson)
|
||||
root.colorUpdateTrigger++
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.clearWallpaperError()
|
||||
}
|
||||
} catch (e) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.wallpaperErrorStatus = "error"
|
||||
ToastService.showError("Color processing failed (JSON parse error after extraction)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: code => {
|
||||
if (code !== 0) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.wallpaperErrorStatus = "error"
|
||||
ToastService.showError("Matugen color command failed with exit code " + code)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: ensureStateDir
|
||||
}
|
||||
|
||||
|
||||
|
||||
Process {
|
||||
id: systemThemeGenerator
|
||||
running: false
|
||||
|
||||
onExited: exitCode => {
|
||||
workerRunning = false
|
||||
|
||||
|
||||
if (exitCode === 2) {
|
||||
// Exit code 2 means wallpaper/color not found - this is expected on first run
|
||||
console.log("Theme worker: wallpaper/color not found, skipping theme generation")
|
||||
@@ -675,14 +742,10 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Component.onCompleted: {
|
||||
matugenCheck.running = true
|
||||
if (typeof SessionData !== "undefined")
|
||||
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
||||
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
||||
}
|
||||
|
||||
FileView {
|
||||
@@ -697,7 +760,7 @@ Singleton {
|
||||
ToastService.showError("Invalid JSON format: " + e.message)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onLoaded: {
|
||||
parseAndLoadTheme()
|
||||
}
|
||||
@@ -706,7 +769,7 @@ Singleton {
|
||||
customThemeFileView.reload()
|
||||
}
|
||||
|
||||
onLoadFailed: function(error) {
|
||||
onLoadFailed: function (error) {
|
||||
if (typeof ToastService !== "undefined") {
|
||||
ToastService.showError("Failed to read theme file: " + error)
|
||||
}
|
||||
@@ -735,4 +798,4 @@ Singleton {
|
||||
return root.isLightMode ? "light" : "dark"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
@@ -23,7 +23,7 @@ Item {
|
||||
property string powerDialogMessage: ""
|
||||
property string powerDialogConfirmText: ""
|
||||
property color powerDialogConfirmColor: Theme.primary
|
||||
property var powerDialogOnConfirm: function() {}
|
||||
property var powerDialogOnConfirm: function () {}
|
||||
|
||||
function showPowerDialog(title, message, confirmText, confirmColor, onConfirm) {
|
||||
powerDialogTitle = title
|
||||
@@ -57,7 +57,7 @@ Item {
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: !SessionData.wallpaperPath
|
||||
active: !SessionData.wallpaperPath || (SessionData.wallpaperPath && SessionData.wallpaperPath.startsWith("#"))
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: DankBackdrop {}
|
||||
@@ -67,7 +67,7 @@ Item {
|
||||
id: wallpaperBackground
|
||||
|
||||
anchors.fill: parent
|
||||
source: SessionData.wallpaperPath || ""
|
||||
source: (SessionData.wallpaperPath && !SessionData.wallpaperPath.startsWith("#")) ? SessionData.wallpaperPath : ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
smooth: true
|
||||
asynchronous: false
|
||||
@@ -802,7 +802,7 @@ Item {
|
||||
if (demoMode) {
|
||||
console.log("Demo: Power")
|
||||
} else {
|
||||
showPowerDialog("Power Off", "Power off this computer?", "Power Off", Theme.error, function() {
|
||||
showPowerDialog("Power Off", "Power off this computer?", "Power Off", Theme.error, function () {
|
||||
SessionService.poweroff()
|
||||
})
|
||||
}
|
||||
@@ -816,7 +816,7 @@ Item {
|
||||
if (demoMode) {
|
||||
console.log("Demo: Reboot")
|
||||
} else {
|
||||
showPowerDialog("Restart", "Restart this computer?", "Restart", Theme.primary, function() {
|
||||
showPowerDialog("Restart", "Restart this computer?", "Restart", Theme.primary, function () {
|
||||
SessionService.reboot()
|
||||
})
|
||||
}
|
||||
@@ -830,7 +830,7 @@ Item {
|
||||
if (demoMode) {
|
||||
console.log("Demo: Logout")
|
||||
} else {
|
||||
showPowerDialog("Log Out", "End this session?", "Log Out", Theme.primary, function() {
|
||||
showPowerDialog("Log Out", "End this session?", "Log Out", Theme.primary, function () {
|
||||
SessionService.logout()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,56 +18,58 @@ Item {
|
||||
property bool fontsEnumerated: false
|
||||
|
||||
function enumerateFonts() {
|
||||
var fonts = ["Default"];
|
||||
var availableFonts = Qt.fontFamilies();
|
||||
var rootFamilies = [];
|
||||
var seenFamilies = new Set();
|
||||
var fonts = ["Default"]
|
||||
var availableFonts = Qt.fontFamilies()
|
||||
var rootFamilies = []
|
||||
var seenFamilies = new Set()
|
||||
for (var i = 0; i < availableFonts.length; i++) {
|
||||
var fontName = availableFonts[i];
|
||||
var fontName = availableFonts[i]
|
||||
if (fontName.startsWith("."))
|
||||
continue;
|
||||
continue
|
||||
|
||||
if (fontName === SettingsData.defaultFontFamily)
|
||||
continue;
|
||||
continue
|
||||
|
||||
var rootName = fontName.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").replace(/ (UI|Display|Text|Mono|Sans|Serif)$/i, function(match, suffix) {
|
||||
return match;
|
||||
}).trim();
|
||||
var rootName = fontName.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i,
|
||||
"").replace(/ (UI|Display|Text|Mono|Sans|Serif)$/i, function (match, suffix) {
|
||||
return match
|
||||
}).trim()
|
||||
if (!seenFamilies.has(rootName) && rootName !== "") {
|
||||
seenFamilies.add(rootName);
|
||||
rootFamilies.push(rootName);
|
||||
seenFamilies.add(rootName)
|
||||
rootFamilies.push(rootName)
|
||||
}
|
||||
}
|
||||
cachedFontFamilies = fonts.concat(rootFamilies.sort());
|
||||
var monoFonts = ["Default"];
|
||||
var monoFamilies = [];
|
||||
var seenMonoFamilies = new Set();
|
||||
cachedFontFamilies = fonts.concat(rootFamilies.sort())
|
||||
var monoFonts = ["Default"]
|
||||
var monoFamilies = []
|
||||
var seenMonoFamilies = new Set()
|
||||
for (var j = 0; j < availableFonts.length; j++) {
|
||||
var fontName2 = availableFonts[j];
|
||||
var fontName2 = availableFonts[j]
|
||||
if (fontName2.startsWith("."))
|
||||
continue;
|
||||
continue
|
||||
|
||||
if (fontName2 === SettingsData.defaultMonoFontFamily)
|
||||
continue;
|
||||
continue
|
||||
|
||||
var lowerName = fontName2.toLowerCase();
|
||||
if (lowerName.includes("mono") || lowerName.includes("code") || lowerName.includes("console") || lowerName.includes("terminal") || lowerName.includes("courier") || lowerName.includes("dejavu sans mono") || lowerName.includes("jetbrains") || lowerName.includes("fira") || lowerName.includes("hack") || lowerName.includes("source code") || lowerName.includes("ubuntu mono") || lowerName.includes("cascadia")) {
|
||||
var rootName2 = fontName2.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").trim();
|
||||
var lowerName = fontName2.toLowerCase()
|
||||
if (lowerName.includes("mono") || lowerName.includes("code") || lowerName.includes("console") || lowerName.includes("terminal") || lowerName.includes("courier") || lowerName.includes("dejavu sans mono") || lowerName.includes(
|
||||
"jetbrains") || lowerName.includes("fira") || lowerName.includes("hack") || lowerName.includes("source code") || lowerName.includes("ubuntu mono") || lowerName.includes("cascadia")) {
|
||||
var rootName2 = fontName2.replace(/ (Thin|Extra Light|Light|Regular|Medium|Semi Bold|Demi Bold|Bold|Extra Bold|Black|Heavy)$/i, "").replace(/ (Italic|Oblique|Condensed|Extended|Narrow|Wide)$/i, "").trim()
|
||||
if (!seenMonoFamilies.has(rootName2) && rootName2 !== "") {
|
||||
seenMonoFamilies.add(rootName2);
|
||||
monoFamilies.push(rootName2);
|
||||
seenMonoFamilies.add(rootName2)
|
||||
monoFamilies.push(rootName2)
|
||||
}
|
||||
}
|
||||
}
|
||||
cachedMonoFamilies = monoFonts.concat(monoFamilies.sort());
|
||||
cachedMonoFamilies = monoFonts.concat(monoFamilies.sort())
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// Access WallpaperCyclingService to ensure it's initialized
|
||||
WallpaperCyclingService.cyclingActive;
|
||||
WallpaperCyclingService.cyclingActive
|
||||
if (!fontsEnumerated) {
|
||||
enumerateFonts();
|
||||
fontsEnumerated = true;
|
||||
enumerateFonts()
|
||||
fontsEnumerated = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +120,6 @@ Item {
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Row {
|
||||
@@ -136,9 +137,9 @@ Item {
|
||||
CachingImage {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
source: SessionData.wallpaperPath !== "" ? "file://" + SessionData.wallpaperPath : ""
|
||||
source: (SessionData.wallpaperPath !== "" && !SessionData.wallpaperPath.startsWith("#")) ? "file://" + SessionData.wallpaperPath : ""
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
visible: SessionData.wallpaperPath !== ""
|
||||
visible: SessionData.wallpaperPath !== "" && !SessionData.wallpaperPath.startsWith("#")
|
||||
maxCacheSize: 160
|
||||
layer.enabled: true
|
||||
|
||||
@@ -148,7 +149,14 @@ Item {
|
||||
maskThresholdMin: 0.5
|
||||
maskSpreadAtMin: 1
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
radius: Theme.cornerRadius - 1
|
||||
color: SessionData.wallpaperPath.startsWith("#") ? SessionData.wallpaperPath : "transparent"
|
||||
visible: SessionData.wallpaperPath !== "" && SessionData.wallpaperPath.startsWith("#")
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -199,13 +207,34 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (parentModal) {
|
||||
parentModal.allowFocusOverride = true;
|
||||
parentModal.shouldHaveFocus = false;
|
||||
parentModal.allowFocusOverride = true
|
||||
parentModal.shouldHaveFocus = false
|
||||
}
|
||||
wallpaperBrowser.open();
|
||||
wallpaperBrowser.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 32
|
||||
height: 32
|
||||
radius: 16
|
||||
color: Qt.rgba(255, 255, 255, 0.9)
|
||||
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: "palette"
|
||||
size: 18
|
||||
color: "black"
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
colorPicker.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -227,16 +256,13 @@ Item {
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (Theme.currentTheme === Theme.dynamic)
|
||||
Theme.switchTheme("blue");
|
||||
Theme.switchTheme("blue")
|
||||
|
||||
SessionData.setWallpaper("");
|
||||
SessionData.clearWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -248,7 +274,6 @@ Item {
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Column {
|
||||
@@ -283,12 +308,12 @@ Item {
|
||||
buttonSize: 32
|
||||
iconName: "skip_previous"
|
||||
iconSize: Theme.iconSizeSmall
|
||||
enabled: SessionData.wallpaperPath
|
||||
opacity: SessionData.wallpaperPath ? 1 : 0.5
|
||||
enabled: SessionData.wallpaperPath && !SessionData.wallpaperPath.startsWith("#")
|
||||
opacity: (SessionData.wallpaperPath && !SessionData.wallpaperPath.startsWith("#")) ? 1 : 0.5
|
||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
WallpaperCyclingService.cyclePrevManually();
|
||||
WallpaperCyclingService.cyclePrevManually()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,19 +321,16 @@ Item {
|
||||
buttonSize: 32
|
||||
iconName: "skip_next"
|
||||
iconSize: Theme.iconSizeSmall
|
||||
enabled: SessionData.wallpaperPath
|
||||
opacity: SessionData.wallpaperPath ? 1 : 0.5
|
||||
enabled: SessionData.wallpaperPath && !SessionData.wallpaperPath.startsWith("#")
|
||||
opacity: (SessionData.wallpaperPath && !SessionData.wallpaperPath.startsWith("#")) ? 1 : 0.5
|
||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.5)
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: {
|
||||
WallpaperCyclingService.cycleNextManually();
|
||||
WallpaperCyclingService.cycleNextManually()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Wallpaper Cycling Section - Full Width
|
||||
@@ -354,7 +376,6 @@ Item {
|
||||
color: Theme.surfaceVariantText
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -362,11 +383,10 @@ Item {
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: SessionData.wallpaperCyclingEnabled
|
||||
onToggled: (toggled) => {
|
||||
return SessionData.setWallpaperCyclingEnabled(toggled);
|
||||
}
|
||||
onToggled: toggled => {
|
||||
return SessionData.setWallpaperCyclingEnabled(toggled)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Cycling mode and settings
|
||||
@@ -393,18 +413,17 @@ Item {
|
||||
width: 200
|
||||
height: 32
|
||||
model: [{
|
||||
"text": "Interval",
|
||||
"icon": "schedule"
|
||||
}, {
|
||||
"text": "Time",
|
||||
"icon": "access_time"
|
||||
}]
|
||||
"text": "Interval",
|
||||
"icon": "schedule"
|
||||
}, {
|
||||
"text": "Time",
|
||||
"icon": "access_time"
|
||||
}]
|
||||
currentIndex: SessionData.wallpaperCyclingMode === "time" ? 1 : 0
|
||||
onTabClicked: (index) => {
|
||||
SessionData.setWallpaperCyclingMode(index === 1 ? "time" : "interval");
|
||||
}
|
||||
onTabClicked: index => {
|
||||
SessionData.setWallpaperCyclingMode(index === 1 ? "time" : "interval")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Interval settings
|
||||
@@ -418,16 +437,15 @@ Item {
|
||||
description: "How often to change wallpaper"
|
||||
options: intervalOptions
|
||||
currentValue: {
|
||||
const currentSeconds = SessionData.wallpaperCyclingInterval;
|
||||
const index = intervalValues.indexOf(currentSeconds);
|
||||
return index >= 0 ? intervalOptions[index] : "5 minutes";
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
const index = intervalOptions.indexOf(value);
|
||||
if (index >= 0)
|
||||
SessionData.setWallpaperCyclingInterval(intervalValues[index]);
|
||||
|
||||
const currentSeconds = SessionData.wallpaperCyclingInterval
|
||||
const index = intervalValues.indexOf(currentSeconds)
|
||||
return index >= 0 ? intervalOptions[index] : "5 minutes"
|
||||
}
|
||||
onValueChanged: value => {
|
||||
const index = intervalOptions.indexOf(value)
|
||||
if (index >= 0)
|
||||
SessionData.setWallpaperCyclingInterval(intervalValues[index])
|
||||
}
|
||||
}
|
||||
|
||||
// Time settings
|
||||
@@ -452,25 +470,24 @@ Item {
|
||||
topPadding: Theme.spacingS
|
||||
bottomPadding: Theme.spacingS
|
||||
onAccepted: {
|
||||
var isValid = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/.test(text);
|
||||
var isValid = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/.test(text)
|
||||
if (isValid)
|
||||
SessionData.setWallpaperCyclingTime(text);
|
||||
SessionData.setWallpaperCyclingTime(text)
|
||||
else
|
||||
text = SessionData.wallpaperCyclingTime;
|
||||
text = SessionData.wallpaperCyclingTime
|
||||
}
|
||||
onEditingFinished: {
|
||||
var isValid = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/.test(text);
|
||||
var isValid = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/.test(text)
|
||||
if (isValid)
|
||||
SessionData.setWallpaperCyclingTime(text);
|
||||
SessionData.setWallpaperCyclingTime(text)
|
||||
else
|
||||
text = SessionData.wallpaperCyclingTime;
|
||||
text = SessionData.wallpaperCyclingTime
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -479,15 +496,10 @@ Item {
|
||||
color: Theme.surfaceVariantText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Dynamic Theme Section
|
||||
@@ -536,7 +548,6 @@ Item {
|
||||
wrapMode: Text.WordWrap
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -545,14 +556,13 @@ Item {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: Theme.wallpaperPath !== "" && Theme.currentTheme === Theme.dynamic
|
||||
enabled: ToastService.wallpaperErrorStatus !== "matugen_missing" && Theme.wallpaperPath !== ""
|
||||
onToggled: (toggled) => {
|
||||
if (toggled)
|
||||
Theme.switchTheme(Theme.dynamic);
|
||||
else
|
||||
Theme.switchTheme("blue");
|
||||
}
|
||||
onToggled: toggled => {
|
||||
if (toggled)
|
||||
Theme.switchTheme(Theme.dynamic)
|
||||
else
|
||||
Theme.switchTheme("blue")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -563,9 +573,7 @@ Item {
|
||||
width: parent.width
|
||||
leftPadding: Theme.iconSize + Theme.spacingM
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Display Settings
|
||||
@@ -602,7 +610,6 @@ Item {
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -610,9 +617,9 @@ Item {
|
||||
text: "Light Mode"
|
||||
description: "Use light theme instead of dark theme"
|
||||
checked: SessionData.isLightMode
|
||||
onToggled: (checked) => {
|
||||
Theme.setLightMode(checked);
|
||||
}
|
||||
onToggled: checked => {
|
||||
Theme.setLightMode(checked)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -629,13 +636,13 @@ Item {
|
||||
text: "Night Mode"
|
||||
description: "Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates."
|
||||
checked: DisplayService.nightModeEnabled
|
||||
onToggled: (checked) => {
|
||||
DisplayService.toggleNightMode();
|
||||
}
|
||||
onToggled: checked => {
|
||||
DisplayService.toggleNightMode()
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onNightModeEnabledChanged() {
|
||||
nightModeToggle.checked = DisplayService.nightModeEnabled;
|
||||
nightModeToggle.checked = DisplayService.nightModeEnabled
|
||||
}
|
||||
|
||||
target: DisplayService
|
||||
@@ -648,16 +655,16 @@ Item {
|
||||
description: "Color temperature for night mode"
|
||||
currentValue: SessionData.nightModeTemperature + "K"
|
||||
options: {
|
||||
var temps = [];
|
||||
var temps = []
|
||||
for (var i = 2500; i <= 6000; i += 500) {
|
||||
temps.push(i + "K");
|
||||
temps.push(i + "K")
|
||||
}
|
||||
return temps;
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
var temp = parseInt(value.replace("K", ""));
|
||||
SessionData.setNightModeTemperature(temp);
|
||||
return temps
|
||||
}
|
||||
onValueChanged: value => {
|
||||
var temp = parseInt(value.replace("K", ""))
|
||||
SessionData.setNightModeTemperature(temp)
|
||||
}
|
||||
}
|
||||
|
||||
DankToggle {
|
||||
@@ -666,19 +673,19 @@ Item {
|
||||
text: "Automatic Control"
|
||||
description: "Only adjust gamma based on time or location rules."
|
||||
checked: SessionData.nightModeAutoEnabled
|
||||
onToggled: (checked) => {
|
||||
if (checked && !DisplayService.nightModeEnabled) {
|
||||
DisplayService.toggleNightMode();
|
||||
} else if (!checked && DisplayService.nightModeEnabled) {
|
||||
DisplayService.toggleNightMode();
|
||||
}
|
||||
SessionData.setNightModeAutoEnabled(checked);
|
||||
}
|
||||
onToggled: checked => {
|
||||
if (checked && !DisplayService.nightModeEnabled) {
|
||||
DisplayService.toggleNightMode()
|
||||
} else if (!checked && DisplayService.nightModeEnabled) {
|
||||
DisplayService.toggleNightMode()
|
||||
}
|
||||
SessionData.setNightModeAutoEnabled(checked)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SessionData
|
||||
function onNightModeAutoEnabledChanged() {
|
||||
automaticToggle.checked = SessionData.nightModeAutoEnabled;
|
||||
automaticToggle.checked = SessionData.nightModeAutoEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,7 +700,7 @@ Item {
|
||||
Connections {
|
||||
target: SessionData
|
||||
function onNightModeAutoEnabledChanged() {
|
||||
automaticSettings.visible = SessionData.nightModeAutoEnabled;
|
||||
automaticSettings.visible = SessionData.nightModeAutoEnabled
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,22 +709,22 @@ Item {
|
||||
width: 200
|
||||
height: 32
|
||||
model: [{
|
||||
"text": "Time",
|
||||
"icon": "access_time"
|
||||
}, {
|
||||
"text": "Location",
|
||||
"icon": "place"
|
||||
}]
|
||||
|
||||
"text": "Time",
|
||||
"icon": "access_time"
|
||||
}, {
|
||||
"text": "Location",
|
||||
"icon": "place"
|
||||
}]
|
||||
|
||||
Component.onCompleted: {
|
||||
currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0;
|
||||
}
|
||||
|
||||
onTabClicked: (index) => {
|
||||
console.log("Tab clicked:", index, "Setting mode to:", index === 1 ? "location" : "time");
|
||||
DisplayService.setNightModeAutomationMode(index === 1 ? "location" : "time");
|
||||
currentIndex = index;
|
||||
currentIndex = SessionData.nightModeAutoMode === "location" ? 1 : 0
|
||||
}
|
||||
|
||||
onTabClicked: index => {
|
||||
console.log("Tab clicked:", index, "Setting mode to:", index === 1 ? "location" : "time")
|
||||
DisplayService.setNightModeAutomationMode(index === 1 ? "location" : "time")
|
||||
currentIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
@@ -770,15 +777,15 @@ Item {
|
||||
text: ""
|
||||
currentValue: SessionData.nightModeStartHour.toString()
|
||||
options: {
|
||||
var hours = [];
|
||||
var hours = []
|
||||
for (var i = 0; i < 24; i++) {
|
||||
hours.push(i.toString());
|
||||
hours.push(i.toString())
|
||||
}
|
||||
return hours;
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
SessionData.setNightModeStartHour(parseInt(value));
|
||||
return hours
|
||||
}
|
||||
onValueChanged: value => {
|
||||
SessionData.setNightModeStartHour(parseInt(value))
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -787,15 +794,15 @@ Item {
|
||||
text: ""
|
||||
currentValue: SessionData.nightModeStartMinute.toString().padStart(2, '0')
|
||||
options: {
|
||||
var minutes = [];
|
||||
var minutes = []
|
||||
for (var i = 0; i < 60; i += 5) {
|
||||
minutes.push(i.toString().padStart(2, '0'));
|
||||
minutes.push(i.toString().padStart(2, '0'))
|
||||
}
|
||||
return minutes;
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
SessionData.setNightModeStartMinute(parseInt(value));
|
||||
return minutes
|
||||
}
|
||||
onValueChanged: value => {
|
||||
SessionData.setNightModeStartMinute(parseInt(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,15 +825,15 @@ Item {
|
||||
text: ""
|
||||
currentValue: SessionData.nightModeEndHour.toString()
|
||||
options: {
|
||||
var hours = [];
|
||||
var hours = []
|
||||
for (var i = 0; i < 24; i++) {
|
||||
hours.push(i.toString());
|
||||
hours.push(i.toString())
|
||||
}
|
||||
return hours;
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
SessionData.setNightModeEndHour(parseInt(value));
|
||||
return hours
|
||||
}
|
||||
onValueChanged: value => {
|
||||
SessionData.setNightModeEndHour(parseInt(value))
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -835,15 +842,15 @@ Item {
|
||||
text: ""
|
||||
currentValue: SessionData.nightModeEndMinute.toString().padStart(2, '0')
|
||||
options: {
|
||||
var minutes = [];
|
||||
var minutes = []
|
||||
for (var i = 0; i < 60; i += 5) {
|
||||
minutes.push(i.toString().padStart(2, '0'));
|
||||
minutes.push(i.toString().padStart(2, '0'))
|
||||
}
|
||||
return minutes;
|
||||
}
|
||||
onValueChanged: (value) => {
|
||||
SessionData.setNightModeEndMinute(parseInt(value));
|
||||
return minutes
|
||||
}
|
||||
onValueChanged: value => {
|
||||
SessionData.setNightModeEndMinute(parseInt(value))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -860,15 +867,15 @@ Item {
|
||||
description: DisplayService.geoclueAvailable ? "Use automatic location detection (geoclue2)" : "Geoclue service not running - cannot auto-detect location"
|
||||
checked: SessionData.nightModeLocationProvider === "geoclue2"
|
||||
enabled: DisplayService.geoclueAvailable
|
||||
onToggled: (checked) => {
|
||||
if (checked && DisplayService.geoclueAvailable) {
|
||||
SessionData.setNightModeLocationProvider("geoclue2")
|
||||
SessionData.setLatitude(0.0)
|
||||
SessionData.setLongitude(0.0)
|
||||
} else {
|
||||
SessionData.setNightModeLocationProvider("")
|
||||
}
|
||||
}
|
||||
onToggled: checked => {
|
||||
if (checked && DisplayService.geoclueAvailable) {
|
||||
SessionData.setNightModeLocationProvider("geoclue2")
|
||||
SessionData.setLatitude(0.0)
|
||||
SessionData.setLongitude(0.0)
|
||||
} else {
|
||||
SessionData.setNightModeLocationProvider("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -937,13 +944,8 @@ Item {
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Font Settings
|
||||
@@ -980,7 +982,6 @@ Item {
|
||||
color: Theme.surfaceText
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -989,20 +990,20 @@ Item {
|
||||
description: "Select system font family"
|
||||
currentValue: {
|
||||
if (SettingsData.fontFamily === SettingsData.defaultFontFamily)
|
||||
return "Default";
|
||||
return "Default"
|
||||
else
|
||||
return SettingsData.fontFamily || "Default";
|
||||
return SettingsData.fontFamily || "Default"
|
||||
}
|
||||
enableFuzzySearch: true
|
||||
popupWidthOffset: 100
|
||||
maxPopupHeight: 400
|
||||
options: cachedFontFamilies
|
||||
onValueChanged: (value) => {
|
||||
if (value.startsWith("Default"))
|
||||
SettingsData.setFontFamily(SettingsData.defaultFontFamily);
|
||||
else
|
||||
SettingsData.setFontFamily(value);
|
||||
}
|
||||
onValueChanged: value => {
|
||||
if (value.startsWith("Default"))
|
||||
SettingsData.setFontFamily(SettingsData.defaultFontFamily)
|
||||
else
|
||||
SettingsData.setFontFamily(value)
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -1012,64 +1013,64 @@ Item {
|
||||
currentValue: {
|
||||
switch (SettingsData.fontWeight) {
|
||||
case Font.Thin:
|
||||
return "Thin";
|
||||
return "Thin"
|
||||
case Font.ExtraLight:
|
||||
return "Extra Light";
|
||||
return "Extra Light"
|
||||
case Font.Light:
|
||||
return "Light";
|
||||
return "Light"
|
||||
case Font.Normal:
|
||||
return "Regular";
|
||||
return "Regular"
|
||||
case Font.Medium:
|
||||
return "Medium";
|
||||
return "Medium"
|
||||
case Font.DemiBold:
|
||||
return "Demi Bold";
|
||||
return "Demi Bold"
|
||||
case Font.Bold:
|
||||
return "Bold";
|
||||
return "Bold"
|
||||
case Font.ExtraBold:
|
||||
return "Extra Bold";
|
||||
return "Extra Bold"
|
||||
case Font.Black:
|
||||
return "Black";
|
||||
return "Black"
|
||||
default:
|
||||
return "Regular";
|
||||
return "Regular"
|
||||
}
|
||||
}
|
||||
options: ["Thin", "Extra Light", "Light", "Regular", "Medium", "Demi Bold", "Bold", "Extra Bold", "Black"]
|
||||
onValueChanged: (value) => {
|
||||
var weight;
|
||||
switch (value) {
|
||||
case "Thin":
|
||||
weight = Font.Thin;
|
||||
break;
|
||||
case "Extra Light":
|
||||
weight = Font.ExtraLight;
|
||||
break;
|
||||
case "Light":
|
||||
weight = Font.Light;
|
||||
break;
|
||||
case "Regular":
|
||||
weight = Font.Normal;
|
||||
break;
|
||||
case "Medium":
|
||||
weight = Font.Medium;
|
||||
break;
|
||||
case "Demi Bold":
|
||||
weight = Font.DemiBold;
|
||||
break;
|
||||
case "Bold":
|
||||
weight = Font.Bold;
|
||||
break;
|
||||
case "Extra Bold":
|
||||
weight = Font.ExtraBold;
|
||||
break;
|
||||
case "Black":
|
||||
weight = Font.Black;
|
||||
break;
|
||||
default:
|
||||
weight = Font.Normal;
|
||||
break;
|
||||
}
|
||||
SettingsData.setFontWeight(weight);
|
||||
}
|
||||
onValueChanged: value => {
|
||||
var weight
|
||||
switch (value) {
|
||||
case "Thin":
|
||||
weight = Font.Thin
|
||||
break
|
||||
case "Extra Light":
|
||||
weight = Font.ExtraLight
|
||||
break
|
||||
case "Light":
|
||||
weight = Font.Light
|
||||
break
|
||||
case "Regular":
|
||||
weight = Font.Normal
|
||||
break
|
||||
case "Medium":
|
||||
weight = Font.Medium
|
||||
break
|
||||
case "Demi Bold":
|
||||
weight = Font.DemiBold
|
||||
break
|
||||
case "Bold":
|
||||
weight = Font.Bold
|
||||
break
|
||||
case "Extra Bold":
|
||||
weight = Font.ExtraBold
|
||||
break
|
||||
case "Black":
|
||||
weight = Font.Black
|
||||
break
|
||||
default:
|
||||
weight = Font.Normal
|
||||
break
|
||||
}
|
||||
SettingsData.setFontWeight(weight)
|
||||
}
|
||||
}
|
||||
|
||||
DankDropdown {
|
||||
@@ -1078,28 +1079,24 @@ Item {
|
||||
description: "Select monospace font for process list and technical displays"
|
||||
currentValue: {
|
||||
if (SettingsData.monoFontFamily === SettingsData.defaultMonoFontFamily)
|
||||
return "Default";
|
||||
return "Default"
|
||||
|
||||
return SettingsData.monoFontFamily || "Default";
|
||||
return SettingsData.monoFontFamily || "Default"
|
||||
}
|
||||
enableFuzzySearch: true
|
||||
popupWidthOffset: 100
|
||||
maxPopupHeight: 400
|
||||
options: cachedMonoFamilies
|
||||
onValueChanged: (value) => {
|
||||
if (value === "Default")
|
||||
SettingsData.setMonoFontFamily(SettingsData.defaultMonoFontFamily);
|
||||
else
|
||||
SettingsData.setMonoFontFamily(value);
|
||||
}
|
||||
onValueChanged: value => {
|
||||
if (value === "Default")
|
||||
SettingsData.setMonoFontFamily(SettingsData.defaultMonoFontFamily)
|
||||
else
|
||||
SettingsData.setMonoFontFamily(value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FileBrowserModal {
|
||||
@@ -1109,18 +1106,26 @@ Item {
|
||||
browserIcon: "wallpaper"
|
||||
browserType: "wallpaper"
|
||||
fileExtensions: ["*.jpg", "*.jpeg", "*.png", "*.bmp", "*.gif", "*.webp"]
|
||||
onFileSelected: (path) => {
|
||||
SessionData.setWallpaper(path);
|
||||
close();
|
||||
}
|
||||
onFileSelected: path => {
|
||||
SessionData.setWallpaper(path)
|
||||
close()
|
||||
}
|
||||
onDialogClosed: {
|
||||
if (parentModal) {
|
||||
parentModal.allowFocusOverride = false;
|
||||
parentModal.allowFocusOverride = false
|
||||
parentModal.shouldHaveFocus = Qt.binding(() => {
|
||||
return parentModal.shouldBeVisible;
|
||||
});
|
||||
return parentModal.shouldBeVisible
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DankColorPicker {
|
||||
id: colorPicker
|
||||
|
||||
pickerTitle: "Choose Wallpaper Color"
|
||||
onColorSelected: selectedColor => {
|
||||
SessionData.setWallpaperColor(selectedColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,20 +33,42 @@ LazyLoader {
|
||||
anchors.fill: parent
|
||||
|
||||
property string source: SessionData.wallpaperPath || ""
|
||||
property bool isColorSource: source.startsWith("#")
|
||||
property Image current: one
|
||||
|
||||
onSourceChanged: {
|
||||
if (!source)
|
||||
if (!source) {
|
||||
current = null
|
||||
else if (current === one)
|
||||
two.update()
|
||||
else
|
||||
one.update()
|
||||
one.source = ""
|
||||
two.source = ""
|
||||
} else if (isColorSource) {
|
||||
current = null
|
||||
one.source = ""
|
||||
two.source = ""
|
||||
} else {
|
||||
if (current === one)
|
||||
two.update()
|
||||
else
|
||||
one.update()
|
||||
}
|
||||
}
|
||||
|
||||
onIsColorSourceChanged: {
|
||||
if (isColorSource) {
|
||||
current = null
|
||||
one.source = ""
|
||||
two.source = ""
|
||||
} else if (source) {
|
||||
if (current === one)
|
||||
two.update()
|
||||
else
|
||||
one.update()
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
active: !root.source
|
||||
active: !root.source || root.isColorSource
|
||||
asynchronous: true
|
||||
|
||||
sourceComponent: DankBackdrop {}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
@@ -29,56 +29,56 @@ Singleton {
|
||||
let score = 0
|
||||
let matched = false
|
||||
|
||||
// Exact name match - highest priority
|
||||
const nameWords = name.trim().split(/\s+/).filter(w => w.length > 0)
|
||||
const containsAsWord = nameWords.includes(queryLower)
|
||||
const startsWithAsWord = nameWords.some(word => word.startsWith(queryLower))
|
||||
|
||||
if (name === queryLower) {
|
||||
score = 1000
|
||||
score = 10000
|
||||
matched = true
|
||||
}
|
||||
else if (containsAsWord) {
|
||||
score = 9500 + (100 - Math.min(name.length, 100))
|
||||
matched = true
|
||||
}
|
||||
// Name starts with query
|
||||
else if (name.startsWith(queryLower)) {
|
||||
score = 900 - name.length
|
||||
score = 9000 + (100 - Math.min(name.length, 100))
|
||||
matched = true
|
||||
}
|
||||
// Name contains query as a word
|
||||
else if (name.includes(" " + queryLower) || name.includes(queryLower + " ")) {
|
||||
score = 800 - name.length
|
||||
else if (startsWithAsWord) {
|
||||
score = 8500 + (100 - Math.min(name.length, 100))
|
||||
matched = true
|
||||
}
|
||||
// Name contains query substring
|
||||
else if (name.includes(queryLower)) {
|
||||
score = 700 - name.length
|
||||
score = 8000 + (100 - Math.min(name.length, 100))
|
||||
matched = true
|
||||
}
|
||||
// Check individual keywords
|
||||
else if (keywords.length > 0) {
|
||||
for (const keyword of keywords) {
|
||||
if (keyword === queryLower) {
|
||||
score = 650 // Exact keyword match
|
||||
score = 6000
|
||||
matched = true
|
||||
break
|
||||
} else if (keyword.startsWith(queryLower)) {
|
||||
score = 620 // Keyword starts with query
|
||||
score = 5500
|
||||
matched = true
|
||||
break
|
||||
} else if (keyword.includes(queryLower)) {
|
||||
score = 600 // Keyword contains query
|
||||
score = 5000
|
||||
matched = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generic name matches
|
||||
if (!matched && genericName.includes(queryLower)) {
|
||||
score = 500
|
||||
score = 4000
|
||||
matched = true
|
||||
}
|
||||
// Comment contains query
|
||||
else if (!matched && comment.includes(queryLower)) {
|
||||
score = 400
|
||||
score = 3000
|
||||
matched = true
|
||||
}
|
||||
// Fuzzy match on name only (not on all fields)
|
||||
else {
|
||||
else if (!matched) {
|
||||
const nameFinder = new Fzf.Finder([app], {
|
||||
"selector": a => a.name || "",
|
||||
"casing": "case-insensitive",
|
||||
@@ -86,7 +86,7 @@ Singleton {
|
||||
})
|
||||
const fuzzyResults = nameFinder.find(query)
|
||||
if (fuzzyResults.length > 0 && fuzzyResults[0].score > 0) {
|
||||
score = fuzzyResults[0].score
|
||||
score = Math.min(fuzzyResults[0].score, 2000)
|
||||
matched = true
|
||||
}
|
||||
}
|
||||
@@ -96,10 +96,7 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by score descending
|
||||
scoredApps.sort((a, b) => b.score - a.score)
|
||||
|
||||
// Return top results
|
||||
return scoredApps.slice(0, 50).map(item => item.app)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
pragma Singleton
|
||||
|
||||
pragma ComponentBehavior
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
@@ -6,9 +6,11 @@ Item {
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
property bool isColorWallpaper: SessionData.wallpaperPath && SessionData.wallpaperPath.startsWith("#")
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Theme.background
|
||||
color: isColorWallpaper ? SessionData.wallpaperPath : Theme.background
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -18,6 +20,7 @@ Item {
|
||||
height: parent.height * 1.5
|
||||
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.15)
|
||||
rotation: 35
|
||||
visible: !isColorWallpaper
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -27,6 +30,7 @@ Item {
|
||||
height: parent.height * 1.2
|
||||
color: Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.12)
|
||||
rotation: 35
|
||||
visible: !isColorWallpaper
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -35,16 +39,18 @@ Item {
|
||||
anchors.leftMargin: Theme.spacingXL * 2
|
||||
anchors.bottomMargin: Theme.spacingXL * 2
|
||||
opacity: 0.25
|
||||
visible: !isColorWallpaper
|
||||
|
||||
StyledText {
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
// ! TODO qmlfmt will brick this
|
||||
text: `██████╗ █████╗ ███╗ ██╗██╗ ██╗
|
||||
██╔══██╗██╔══██╗████╗ ██║██║ ██╔╝
|
||||
██║ ██║███████║██╔██╗ ██║█████╔╝
|
||||
██║ ██║██╔══██║██║╚██╗██║██╔═██╗
|
||||
██████╔╝██║ ██║██║ ╚████║██║ ██╗
|
||||
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝`
|
||||
██╔══██╗██╔══██╗████╗ ██║██║ ██╔╝
|
||||
██║ ██║███████║██╔██╗ ██║█████╔╝
|
||||
██║ ██║██╔══██║██║╚██╗██║██╔═██╗
|
||||
██████╔╝██║ ██║██║ ╚████║██║ ██╗
|
||||
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═╝`
|
||||
isMonospace: true
|
||||
font.pixelSize: Theme.fontSizeLarge * 1.2
|
||||
color: Theme.primary
|
||||
|
||||
117
Widgets/DankColorPicker.qml
Normal file
117
Widgets/DankColorPicker.qml
Normal file
@@ -0,0 +1,117 @@
|
||||
import QtQuick
|
||||
import qs.Common
|
||||
import qs.Widgets
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property string pickerTitle: "Choose Color"
|
||||
property color selectedColor: Theme.primary
|
||||
property bool isOpen: false
|
||||
|
||||
signal colorSelected(color selectedColor)
|
||||
|
||||
function open() {
|
||||
customColorField.text = ""
|
||||
isOpen = true
|
||||
Qt.callLater(() => root.forceActiveFocus())
|
||||
}
|
||||
|
||||
function close() {
|
||||
isOpen = false
|
||||
}
|
||||
|
||||
anchors.centerIn: parent
|
||||
width: 320
|
||||
height: 340
|
||||
radius: Theme.cornerRadius
|
||||
color: Theme.surfaceContainer
|
||||
border.color: Theme.outlineMedium
|
||||
border.width: 1
|
||||
z: 1000
|
||||
visible: isOpen
|
||||
focus: isOpen
|
||||
|
||||
Keys.onPressed: function (event) {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
close()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
|
||||
DankActionButton {
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Theme.spacingS
|
||||
buttonSize: 28
|
||||
iconName: "close"
|
||||
iconSize: 16
|
||||
iconColor: Theme.surfaceText
|
||||
onClicked: root.close()
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Theme.spacingL
|
||||
spacing: Theme.spacingM
|
||||
|
||||
StyledText {
|
||||
text: pickerTitle
|
||||
font.pixelSize: Theme.fontSizeLarge
|
||||
font.weight: Font.Medium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
Grid {
|
||||
columns: 8
|
||||
spacing: 4
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
property var colors: ["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#795548", "#9e9e9e", "#607d8b", "#000000", "#ffffff", "#ff1744", "#f50057", "#d500f9", "#651fff", "#3d5afe", "#2979ff", "#00b0ff", "#00e5ff", "#1de9b6", "#00e676", "#76ff03", "#c6ff00", "#ffff00", "#ffc400", "#ff9100", "#ff3d00", "#bf360c", "#424242", "#37474f"]
|
||||
|
||||
Repeater {
|
||||
model: parent.colors
|
||||
Rectangle {
|
||||
width: 24
|
||||
height: 24
|
||||
color: modelData
|
||||
radius: 4
|
||||
border.color: Theme.outline
|
||||
border.width: root.selectedColor == modelData ? 2 : 1
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
root.selectedColor = modelData
|
||||
root.colorSelected(modelData)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "Custom Color:"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
}
|
||||
|
||||
DankTextField {
|
||||
id: customColorField
|
||||
width: parent.width
|
||||
height: 40
|
||||
placeholderText: "#ff0000"
|
||||
text: ""
|
||||
onAccepted: {
|
||||
var hexColor = text.startsWith("#") ? text : "#" + text
|
||||
if (/^#[0-9A-Fa-f]{6}$/.test(hexColor)) {
|
||||
root.selectedColor = hexColor
|
||||
root.colorSelected(hexColor)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user