mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
support for custom themes
This commit is contained in:
@@ -12,6 +12,7 @@ Singleton {
|
|||||||
|
|
||||||
// Theme settings
|
// Theme settings
|
||||||
property string currentThemeName: "blue"
|
property string currentThemeName: "blue"
|
||||||
|
property string customThemeFile: ""
|
||||||
property real topBarTransparency: 0.75
|
property real topBarTransparency: 0.75
|
||||||
property real topBarWidgetTransparency: 0.85
|
property real topBarWidgetTransparency: 0.85
|
||||||
property real popupTransparency: 0.92
|
property real popupTransparency: 0.92
|
||||||
@@ -65,6 +66,7 @@ Singleton {
|
|||||||
property string systemDefaultIconTheme: ""
|
property string systemDefaultIconTheme: ""
|
||||||
property bool qt5ctAvailable: false
|
property bool qt5ctAvailable: false
|
||||||
property bool qt6ctAvailable: false
|
property bool qt6ctAvailable: false
|
||||||
|
property bool gtkAvailable: false
|
||||||
property bool useOSLogo: false
|
property bool useOSLogo: false
|
||||||
property string osLogoColorOverride: ""
|
property string osLogoColorOverride: ""
|
||||||
property real osLogoBrightness: 0.5
|
property real osLogoBrightness: 0.5
|
||||||
@@ -126,6 +128,7 @@ Singleton {
|
|||||||
} else {
|
} else {
|
||||||
currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "blue"
|
currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "blue"
|
||||||
}
|
}
|
||||||
|
customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : ""
|
||||||
topBarTransparency = settings.topBarTransparency
|
topBarTransparency = settings.topBarTransparency
|
||||||
!== undefined ? (settings.topBarTransparency
|
!== undefined ? (settings.topBarTransparency
|
||||||
> 1 ? settings.topBarTransparency
|
> 1 ? settings.topBarTransparency
|
||||||
@@ -288,6 +291,7 @@ Singleton {
|
|||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
settingsFile.setText(JSON.stringify({
|
settingsFile.setText(JSON.stringify({
|
||||||
"currentThemeName": currentThemeName,
|
"currentThemeName": currentThemeName,
|
||||||
|
"customThemeFile": customThemeFile,
|
||||||
"topBarTransparency": topBarTransparency,
|
"topBarTransparency": topBarTransparency,
|
||||||
"topBarWidgetTransparency": topBarWidgetTransparency,
|
"topBarWidgetTransparency": topBarWidgetTransparency,
|
||||||
"popupTransparency": popupTransparency,
|
"popupTransparency": popupTransparency,
|
||||||
@@ -459,6 +463,11 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setCustomThemeFile(filePath) {
|
||||||
|
customThemeFile = filePath
|
||||||
|
saveSettings()
|
||||||
|
}
|
||||||
|
|
||||||
function setTopBarTransparency(transparency) {
|
function setTopBarTransparency(transparency) {
|
||||||
topBarTransparency = transparency
|
topBarTransparency = transparency
|
||||||
saveSettings()
|
saveSettings()
|
||||||
@@ -808,11 +817,17 @@ Singleton {
|
|||||||
function setGtkThemingEnabled(enabled) {
|
function setGtkThemingEnabled(enabled) {
|
||||||
gtkThemingEnabled = enabled
|
gtkThemingEnabled = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
if (enabled && typeof Theme !== "undefined") {
|
||||||
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setQtThemingEnabled(enabled) {
|
function setQtThemingEnabled(enabled) {
|
||||||
qtThemingEnabled = enabled
|
qtThemingEnabled = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
if (enabled && typeof Theme !== "undefined") {
|
||||||
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setShowDock(enabled) {
|
function setShowDock(enabled) {
|
||||||
@@ -967,7 +982,7 @@ Singleton {
|
|||||||
Process {
|
Process {
|
||||||
id: qtToolsDetectionProcess
|
id: qtToolsDetectionProcess
|
||||||
|
|
||||||
command: ["sh", "-c", "echo -n 'qt5ct:'; command -v qt5ct >/dev/null && echo 'true' || echo 'false'; echo -n 'qt6ct:'; command -v qt6ct >/dev/null && echo 'true' || echo 'false'"]
|
command: ["sh", "-c", "echo -n 'qt5ct:'; command -v qt5ct >/dev/null && echo 'true' || echo 'false'; echo -n 'qt6ct:'; command -v qt6ct >/dev/null && echo 'true' || echo 'false'; echo -n 'gtk:'; (command -v gsettings >/dev/null || command -v dconf >/dev/null) && echo 'true' || echo 'false'"]
|
||||||
running: false
|
running: false
|
||||||
|
|
||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
@@ -980,6 +995,8 @@ Singleton {
|
|||||||
qt5ctAvailable = line.split(':')[1] === 'true'
|
qt5ctAvailable = line.split(':')[1] === 'true'
|
||||||
else if (line.startsWith('qt6ct:'))
|
else if (line.startsWith('qt6ct:'))
|
||||||
qt6ctAvailable = line.split(':')[1] === 'true'
|
qt6ctAvailable = line.split(':')[1] === 'true'
|
||||||
|
else if (line.startsWith('gtk:'))
|
||||||
|
gtkAvailable = line.split(':')[1] === 'true'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
148
Common/Theme.qml
148
Common/Theme.qml
@@ -1,24 +1,23 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtCore
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Io
|
import Quickshell.Io
|
||||||
import Quickshell.Services.UPower
|
import Quickshell.Services.UPower
|
||||||
import Qt.labs.platform
|
import qs.Services
|
||||||
import "StockThemes.js" as StockThemes
|
import "StockThemes.js" as StockThemes
|
||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
// Theme selection
|
|
||||||
property string currentTheme: "blue"
|
property string currentTheme: "blue"
|
||||||
property bool isLightMode: false
|
property bool isLightMode: false
|
||||||
|
|
||||||
readonly property string dynamic: "dynamic"
|
readonly property string dynamic: "dynamic"
|
||||||
readonly property bool isDynamicTheme: !StockThemes.isStockTheme(currentTheme)
|
readonly property bool isDynamicTheme: !StockThemes.isStockTheme(currentTheme)
|
||||||
|
|
||||||
// Dynamic color extraction properties
|
|
||||||
readonly property string homeDir: {
|
readonly property string homeDir: {
|
||||||
const url = StandardPaths.writableLocation(StandardPaths.HomeLocation).toString()
|
const url = StandardPaths.writableLocation(StandardPaths.HomeLocation).toString()
|
||||||
return url.startsWith("file://") ? url.substring(7) : url
|
return url.startsWith("file://") ? url.substring(7) : url
|
||||||
@@ -31,14 +30,14 @@ Singleton {
|
|||||||
readonly property string wallpaperPath: typeof SessionData !== "undefined" ? SessionData.wallpaperPath : ""
|
readonly property string wallpaperPath: typeof SessionData !== "undefined" ? SessionData.wallpaperPath : ""
|
||||||
|
|
||||||
property bool matugenAvailable: false
|
property bool matugenAvailable: false
|
||||||
property bool gtkThemingEnabled: false
|
property bool gtkThemingEnabled: typeof SettingsData !== "undefined" ? SettingsData.gtkAvailable : false
|
||||||
property bool qtThemingEnabled: false
|
property bool qtThemingEnabled: typeof SettingsData !== "undefined" ? (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) : false
|
||||||
property bool systemThemeGenerationInProgress: false
|
property bool systemThemeGenerationInProgress: false
|
||||||
property var matugenColors: ({})
|
property var matugenColors: ({})
|
||||||
property bool extractionRequested: false
|
property bool extractionRequested: false
|
||||||
property int colorUpdateTrigger: 0
|
property int colorUpdateTrigger: 0
|
||||||
|
property var customThemeData: null
|
||||||
|
|
||||||
// Helper function to get matugen colors (unified from Colors.qml)
|
|
||||||
function getMatugenColor(path, fallback) {
|
function getMatugenColor(path, fallback) {
|
||||||
colorUpdateTrigger
|
colorUpdateTrigger
|
||||||
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
|
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
|
||||||
@@ -51,9 +50,10 @@ Singleton {
|
|||||||
return cur || fallback
|
return cur || fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current theme data
|
|
||||||
readonly property var currentThemeData: {
|
readonly property var currentThemeData: {
|
||||||
if (isDynamicTheme) {
|
if (currentTheme === "custom") {
|
||||||
|
return customThemeData || StockThemes.getThemeByName("blue", isLightMode)
|
||||||
|
} else if (currentTheme === dynamic) {
|
||||||
return {
|
return {
|
||||||
primary: getMatugenColor("primary", "#42a5f5"),
|
primary: getMatugenColor("primary", "#42a5f5"),
|
||||||
primaryText: getMatugenColor("on_primary", "#ffffff"),
|
primaryText: getMatugenColor("on_primary", "#ffffff"),
|
||||||
@@ -68,14 +68,16 @@ Singleton {
|
|||||||
backgroundText: getMatugenColor("on_background", "#e3e8ef"),
|
backgroundText: getMatugenColor("on_background", "#e3e8ef"),
|
||||||
outline: getMatugenColor("outline", "#8e918f"),
|
outline: getMatugenColor("outline", "#8e918f"),
|
||||||
surfaceContainer: getMatugenColor("surface_container", "#1e2023"),
|
surfaceContainer: getMatugenColor("surface_container", "#1e2023"),
|
||||||
surfaceContainerHigh: getMatugenColor("surface_container_high", "#292b2f")
|
surfaceContainerHigh: getMatugenColor("surface_container_high", "#292b2f"),
|
||||||
|
error: "#F2B8B5",
|
||||||
|
warning: "#FF9800",
|
||||||
|
info: "#2196F3"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return StockThemes.getThemeByName(currentTheme, isLightMode)
|
return StockThemes.getThemeByName(currentTheme, isLightMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Core color properties (unified from both Theme.qml and Colors.qml)
|
|
||||||
property color primary: currentThemeData.primary
|
property color primary: currentThemeData.primary
|
||||||
property color primaryText: currentThemeData.primaryText
|
property color primaryText: currentThemeData.primaryText
|
||||||
property color primaryContainer: currentThemeData.primaryContainer
|
property color primaryContainer: currentThemeData.primaryContainer
|
||||||
@@ -91,12 +93,10 @@ Singleton {
|
|||||||
property color surfaceContainer: currentThemeData.surfaceContainer
|
property color surfaceContainer: currentThemeData.surfaceContainer
|
||||||
property color surfaceContainerHigh: currentThemeData.surfaceContainerHigh
|
property color surfaceContainerHigh: currentThemeData.surfaceContainerHigh
|
||||||
|
|
||||||
// Additional semantic colors
|
property color error: currentThemeData.error || "#F2B8B5"
|
||||||
property color error: "#F2B8B5"
|
property color warning: currentThemeData.warning || "#FF9800"
|
||||||
property color warning: "#FF9800"
|
property color info: currentThemeData.info || "#2196F3"
|
||||||
property color info: "#2196F3"
|
|
||||||
|
|
||||||
// Interaction states
|
|
||||||
property color primaryHover: Qt.rgba(primary.r, primary.g, primary.b, 0.12)
|
property color primaryHover: Qt.rgba(primary.r, primary.g, primary.b, 0.12)
|
||||||
property color primaryHoverLight: Qt.rgba(primary.r, primary.g, primary.b, 0.08)
|
property color primaryHoverLight: Qt.rgba(primary.r, primary.g, primary.b, 0.08)
|
||||||
property color primaryPressed: Qt.rgba(primary.r, primary.g, primary.b, 0.16)
|
property color primaryPressed: Qt.rgba(primary.r, primary.g, primary.b, 0.16)
|
||||||
@@ -125,7 +125,6 @@ Singleton {
|
|||||||
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
||||||
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
// Animation and timing
|
|
||||||
property int shortDuration: 150
|
property int shortDuration: 150
|
||||||
property int mediumDuration: 300
|
property int mediumDuration: 300
|
||||||
property int longDuration: 500
|
property int longDuration: 500
|
||||||
@@ -133,7 +132,6 @@ Singleton {
|
|||||||
property int standardEasing: Easing.OutCubic
|
property int standardEasing: Easing.OutCubic
|
||||||
property int emphasizedEasing: Easing.OutQuart
|
property int emphasizedEasing: Easing.OutQuart
|
||||||
|
|
||||||
// Layout and sizing
|
|
||||||
property real cornerRadius: typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12
|
property real cornerRadius: typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12
|
||||||
property real spacingXS: 4
|
property real spacingXS: 4
|
||||||
property real spacingS: 8
|
property real spacingS: 8
|
||||||
@@ -149,29 +147,26 @@ Singleton {
|
|||||||
property real iconSizeSmall: 16
|
property real iconSizeSmall: 16
|
||||||
property real iconSizeLarge: 32
|
property real iconSizeLarge: 32
|
||||||
|
|
||||||
// Transparency settings
|
|
||||||
property real panelTransparency: 0.85
|
property real panelTransparency: 0.85
|
||||||
property real widgetTransparency: typeof SettingsData !== "undefined" && SettingsData.topBarWidgetTransparency !== undefined ? SettingsData.topBarWidgetTransparency : 0.85
|
property real widgetTransparency: typeof SettingsData !== "undefined" && SettingsData.topBarWidgetTransparency !== undefined ? SettingsData.topBarWidgetTransparency : 0.85
|
||||||
property real popupTransparency: typeof SettingsData !== "undefined" && SettingsData.popupTransparency !== undefined ? SettingsData.popupTransparency : 0.92
|
property real popupTransparency: typeof SettingsData !== "undefined" && SettingsData.popupTransparency !== undefined ? SettingsData.popupTransparency : 0.92
|
||||||
|
|
||||||
// Theme switching API
|
|
||||||
function switchTheme(themeName, savePrefs = true) {
|
function switchTheme(themeName, savePrefs = true) {
|
||||||
if (themeName === dynamic) {
|
if (themeName === dynamic) {
|
||||||
if (StockThemes.isStockTheme(currentTheme)) {
|
|
||||||
// Switching from stock to dynamic, restore old theme
|
|
||||||
restoreSystemThemes()
|
|
||||||
}
|
|
||||||
currentTheme = dynamic
|
currentTheme = dynamic
|
||||||
extractColors()
|
extractColors()
|
||||||
} else {
|
} else if (themeName === "custom") {
|
||||||
if (!StockThemes.isStockTheme(currentTheme)) {
|
currentTheme = "custom"
|
||||||
// Switching from dynamic to stock
|
if (typeof SettingsData !== "undefined" && SettingsData.customThemeFile) {
|
||||||
restoreSystemThemes()
|
loadCustomThemeFromFile(SettingsData.customThemeFile)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
currentTheme = themeName
|
currentTheme = themeName
|
||||||
}
|
}
|
||||||
if (savePrefs && typeof SettingsData !== "undefined")
|
if (savePrefs && typeof SettingsData !== "undefined")
|
||||||
SettingsData.setTheme(currentTheme)
|
SettingsData.setTheme(currentTheme)
|
||||||
|
|
||||||
|
generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLightMode(savePrefs = true) {
|
function toggleLightMode(savePrefs = true) {
|
||||||
@@ -190,15 +185,33 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getThemeColors(themeName) {
|
function getThemeColors(themeName) {
|
||||||
|
if (themeName === "custom" && customThemeData) {
|
||||||
|
return customThemeData
|
||||||
|
}
|
||||||
return StockThemes.getThemeByName(themeName, isLightMode)
|
return StockThemes.getThemeByName(themeName, isLightMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadCustomTheme(themeData) {
|
||||||
|
if (themeData.dark || themeData.light) {
|
||||||
|
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
|
||||||
|
const selectedTheme = themeData[colorMode] || themeData.dark || themeData.light
|
||||||
|
customThemeData = selectedTheme
|
||||||
|
} else {
|
||||||
|
customThemeData = themeData
|
||||||
|
}
|
||||||
|
|
||||||
|
generateSystemThemesFromCurrentTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCustomThemeFromFile(filePath) {
|
||||||
|
customThemeFileView.path = filePath
|
||||||
|
}
|
||||||
|
|
||||||
property alias availableThemeNames: root._availableThemeNames
|
property alias availableThemeNames: root._availableThemeNames
|
||||||
readonly property var _availableThemeNames: StockThemes.getAllThemeNames()
|
readonly property var _availableThemeNames: StockThemes.getAllThemeNames()
|
||||||
property string currentThemeName: currentTheme
|
property string currentThemeName: currentTheme
|
||||||
|
|
||||||
|
|
||||||
// Background helper functions
|
|
||||||
function popupBackground() {
|
function popupBackground() {
|
||||||
return Qt.rgba(surfaceContainer.r, surfaceContainer.g, surfaceContainer.b, popupTransparency)
|
return Qt.rgba(surfaceContainer.r, surfaceContainer.g, surfaceContainer.b, popupTransparency)
|
||||||
}
|
}
|
||||||
@@ -223,7 +236,6 @@ Singleton {
|
|||||||
return popupTransparency
|
return popupTransparency
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility functions
|
|
||||||
function isColorDark(c) {
|
function isColorDark(c) {
|
||||||
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) < 0.5
|
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) < 0.5
|
||||||
}
|
}
|
||||||
@@ -305,7 +317,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic color extraction (merged from Colors.qml)
|
|
||||||
function extractColors() {
|
function extractColors() {
|
||||||
extractionRequested = true
|
extractionRequested = true
|
||||||
if (matugenAvailable)
|
if (matugenAvailable)
|
||||||
@@ -321,6 +332,10 @@ Singleton {
|
|||||||
generateSystemThemes()
|
generateSystemThemes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentTheme === "custom" && customThemeFileView.path) {
|
||||||
|
customThemeFileView.reload()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateSystemThemes() {
|
function generateSystemThemes() {
|
||||||
@@ -337,19 +352,30 @@ Singleton {
|
|||||||
systemThemeGenerator.running = true
|
systemThemeGenerator.running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreSystemThemes() {
|
function generateSystemThemesFromCurrentTheme() {
|
||||||
if (!shellDir) return
|
if (!isDynamicTheme)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (systemThemeGenerationInProgress)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (!matugenAvailable || !wallpaperPath)
|
||||||
|
return
|
||||||
|
|
||||||
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "true" : "false"
|
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "true" : "false"
|
||||||
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
||||||
const gtkTheming = (typeof SettingsData !== "undefined" && SettingsData.gtkThemingEnabled) ? "true" : "false"
|
const gtkTheming = (typeof SettingsData !== "undefined" && SettingsData.gtkThemingEnabled) ? "true" : "false"
|
||||||
const qtTheming = (typeof SettingsData !== "undefined" && SettingsData.qtThemingEnabled) ? "true" : "false"
|
const qtTheming = (typeof SettingsData !== "undefined" && SettingsData.qtThemingEnabled) ? "true" : "false"
|
||||||
|
|
||||||
systemThemeRestoreProcess.command = [shellDir + "/generate-themes.sh", "", shellDir, configDir, "restore", isLight, iconTheme, gtkTheming, qtTheming]
|
if (gtkTheming === "false" && qtTheming === "false")
|
||||||
systemThemeRestoreProcess.running = true
|
return
|
||||||
|
|
||||||
|
systemThemeGenerationInProgress = true
|
||||||
|
systemThemeGenerator.command = [shellDir + "/generate-themes.sh", wallpaperPath, shellDir, configDir, "generate", isLight, iconTheme, gtkTheming, qtTheming]
|
||||||
|
systemThemeGenerator.running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON extraction helper
|
|
||||||
function extractJsonFromText(text) {
|
function extractJsonFromText(text) {
|
||||||
if (!text) return null
|
if (!text) return null
|
||||||
|
|
||||||
@@ -400,7 +426,6 @@ Singleton {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process definitions for dynamic theming
|
|
||||||
Process {
|
Process {
|
||||||
id: matugenCheck
|
id: matugenCheck
|
||||||
command: ["which", "matugen"]
|
command: ["which", "matugen"]
|
||||||
@@ -505,30 +530,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
|
||||||
id: systemThemeRestoreProcess
|
|
||||||
running: false
|
|
||||||
|
|
||||||
stdout: StdioCollector {
|
|
||||||
id: restoreThemeStdout
|
|
||||||
}
|
|
||||||
|
|
||||||
stderr: StdioCollector {
|
|
||||||
id: restoreThemeStderr
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: exitCode => {
|
|
||||||
if (typeof ToastService !== "undefined") {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
ToastService.showInfo("System themes restored to default")
|
|
||||||
} else {
|
|
||||||
ToastService.showWarning("Failed to restore system themes: " + restoreThemeStderr.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate app configs
|
|
||||||
function generateAppConfigs() {
|
function generateAppConfigs() {
|
||||||
if (!matugenColors || !matugenColors.colors) {
|
if (!matugenColors || !matugenColors.colors) {
|
||||||
return
|
return
|
||||||
@@ -623,4 +625,32 @@ Singleton {
|
|||||||
if (typeof SessionData !== "undefined")
|
if (typeof SessionData !== "undefined")
|
||||||
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileView {
|
||||||
|
id: customThemeFileView
|
||||||
|
watchChanges: true
|
||||||
|
|
||||||
|
function parseAndLoadTheme() {
|
||||||
|
try {
|
||||||
|
var themeData = JSON.parse(customThemeFileView.text())
|
||||||
|
loadCustomTheme(themeData)
|
||||||
|
} catch (e) {
|
||||||
|
ToastService.showError("Invalid JSON format: " + e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
parseAndLoadTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChanged: {
|
||||||
|
customThemeFileView.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoadFailed: function(error) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.showError("Failed to read theme file: " + error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,15 +19,17 @@ DankModal {
|
|||||||
StandardPaths.HomeLocation)
|
StandardPaths.HomeLocation)
|
||||||
property string currentPath: ""
|
property string currentPath: ""
|
||||||
property var fileExtensions: ["*.*"]
|
property var fileExtensions: ["*.*"]
|
||||||
|
property alias filterExtensions: fileBrowserModal.fileExtensions
|
||||||
property string browserTitle: "Select File"
|
property string browserTitle: "Select File"
|
||||||
property string browserIcon: "folder_open"
|
property string browserIcon: "folder_open"
|
||||||
property string browserType: "generic" // "wallpaper" or "profile" for last path memory
|
property string browserType: "generic" // "wallpaper" or "profile" for last path memory
|
||||||
|
property bool showHiddenFiles: false
|
||||||
|
|
||||||
FolderListModel {
|
FolderListModel {
|
||||||
id: folderModel
|
id: folderModel
|
||||||
showDirsFirst: true
|
showDirsFirst: true
|
||||||
showDotAndDotDot: false
|
showDotAndDotDot: false
|
||||||
showHidden: false
|
showHidden: fileBrowserModal.showHiddenFiles
|
||||||
nameFilters: fileExtensions
|
nameFilters: fileExtensions
|
||||||
showFiles: true
|
showFiles: true
|
||||||
showDirs: true
|
showDirs: true
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
|
import Quickshell.Io
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Modals
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
@@ -179,7 +181,6 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Theme.availableThemeNames.slice(0, 5)
|
model: Theme.availableThemeNames.slice(0, 5)
|
||||||
@@ -248,7 +249,6 @@ Item {
|
|||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: Theme.availableThemeNames.slice(5, 10)
|
model: Theme.availableThemeNames.slice(5, 10)
|
||||||
@@ -320,11 +320,14 @@ Item {
|
|||||||
height: Theme.spacingM
|
height: Theme.spacingM
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 120
|
width: 120
|
||||||
height: 40
|
height: 40
|
||||||
radius: 20
|
radius: 20
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
color: {
|
color: {
|
||||||
if (ToastService.wallpaperErrorStatus === "error"
|
if (ToastService.wallpaperErrorStatus === "error"
|
||||||
|| ToastService.wallpaperErrorStatus === "matugen_missing")
|
|| ToastService.wallpaperErrorStatus === "matugen_missing")
|
||||||
@@ -342,13 +345,13 @@ Item {
|
|||||||
return Qt.rgba(Theme.error.r,
|
return Qt.rgba(Theme.error.r,
|
||||||
Theme.error.g,
|
Theme.error.g,
|
||||||
Theme.error.b, 0.5)
|
Theme.error.b, 0.5)
|
||||||
else if (Theme.isDynamicTheme)
|
else if (Theme.currentThemeName === "dynamic")
|
||||||
return Theme.primary
|
return Theme.primary
|
||||||
else
|
else
|
||||||
return Theme.outline
|
return Theme.outline
|
||||||
}
|
}
|
||||||
border.width: Theme.isDynamicTheme ? 2 : 1
|
border.width: (Theme.currentThemeName === "dynamic") ? 2 : 1
|
||||||
scale: Theme.isDynamicTheme ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
|
scale: (Theme.currentThemeName === "dynamic") ? 1.1 : (autoMouseArea.containsMouse ? 1.02 : 1)
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -474,6 +477,86 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 120
|
||||||
|
height: 40
|
||||||
|
radius: 20
|
||||||
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: (Theme.currentThemeName === "custom") ? Theme.primary : Theme.outline
|
||||||
|
border.width: (Theme.currentThemeName === "custom") ? 2 : 1
|
||||||
|
scale: (Theme.currentThemeName === "custom") ? 1.1 : (customMouseArea.containsMouse ? 1.02 : 1)
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
name: "folder_open"
|
||||||
|
size: 16
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
text: "Custom"
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: customMouseArea
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
fileBrowserModal.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: customTooltipText.contentWidth + Theme.spacingM * 2
|
||||||
|
height: customTooltipText.contentHeight + Theme.spacingS * 2
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
border.color: Theme.outline
|
||||||
|
border.width: 1
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
anchors.bottom: parent.top
|
||||||
|
anchors.bottomMargin: Theme.spacingS
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
visible: customMouseArea.containsMouse && (Theme.currentThemeName !== "custom")
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: customTooltipText
|
||||||
|
text: "Load custom theme from JSON file"
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
width: Math.min(implicitWidth, 250)
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.emphasizedEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Close Row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -625,7 +708,7 @@ Item {
|
|||||||
StyledText {
|
StyledText {
|
||||||
id: warningText
|
id: warningText
|
||||||
|
|
||||||
text: "Changing these settings will manipulate GTK and Qt configurations on the system"
|
text: "Changing these settings will manipulate GTK and Qt configurations on the system, requires \"Auto\" theme"
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: Theme.warning
|
color: Theme.warning
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
@@ -732,9 +815,9 @@ Item {
|
|||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Theme GTK Applications"
|
text: "Theme GTK Applications"
|
||||||
description: Theme.gtkThemingEnabled ? "File managers, text editors, and system dialogs will match your theme" : "GTK theming not available (install gsettings)"
|
description: SettingsData.gtkAvailable ? "File managers, text editors, and system dialogs will match your theme" : "GTK theming not available (install gsettings)"
|
||||||
enabled: Theme.gtkThemingEnabled
|
enabled: SettingsData.gtkAvailable
|
||||||
checked: Theme.gtkThemingEnabled
|
checked: SettingsData.gtkAvailable
|
||||||
&& SettingsData.gtkThemingEnabled
|
&& SettingsData.gtkThemingEnabled
|
||||||
onToggled: function (checked) {
|
onToggled: function (checked) {
|
||||||
SettingsData.setGtkThemingEnabled(checked)
|
SettingsData.setGtkThemingEnabled(checked)
|
||||||
@@ -744,9 +827,9 @@ Item {
|
|||||||
DankToggle {
|
DankToggle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: "Theme Qt Applications"
|
text: "Theme Qt Applications"
|
||||||
description: Theme.qtThemingEnabled ? "Qt applications will match your theme colors" : "Qt theming not available (install qt5ct or qt6ct)"
|
description: (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) ? "Qt applications will match your theme colors" : "Qt theming not available (install qt5ct or qt6ct)"
|
||||||
enabled: Theme.qtThemingEnabled
|
enabled: (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable)
|
||||||
checked: Theme.qtThemingEnabled
|
checked: (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable)
|
||||||
&& SettingsData.qtThemingEnabled
|
&& SettingsData.qtThemingEnabled
|
||||||
onToggled: function (checked) {
|
onToggled: function (checked) {
|
||||||
SettingsData.setQtThemingEnabled(checked)
|
SettingsData.setQtThemingEnabled(checked)
|
||||||
@@ -756,4 +839,24 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileBrowserModal {
|
||||||
|
id: fileBrowserModal
|
||||||
|
browserTitle: "Select Custom Theme"
|
||||||
|
filterExtensions: ["*.json"]
|
||||||
|
showHiddenFiles: true
|
||||||
|
|
||||||
|
function selectCustomTheme() {
|
||||||
|
shouldBeVisible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileSelected: function(filePath) {
|
||||||
|
// Save the custom theme file path and switch to custom theme
|
||||||
|
if (filePath.endsWith(".json")) {
|
||||||
|
SettingsData.setCustomThemeFile(filePath)
|
||||||
|
Theme.switchTheme("custom")
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
width: shouldBeVisible ?
|
width: shouldBeVisible ? (ToastService.hasDetails ? 380 : 350) : frozenWidth
|
||||||
(ToastService.hasDetails ? 380 : messageText.implicitWidth + Theme.iconSize + Theme.spacingM * 3 + Theme.spacingL * 2) :
|
|
||||||
frozenWidth
|
|
||||||
height: toastContent.height + Theme.spacingL * 2
|
height: toastContent.height + Theme.spacingL * 2
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
y: Theme.barHeight - 4 + SettingsData.topBarSpacing + 2
|
y: Theme.barHeight - 4 + SettingsData.topBarSpacing + 2
|
||||||
@@ -132,10 +130,14 @@ PanelWindow {
|
|||||||
anchors.left: statusIcon.right
|
anchors.left: statusIcon.right
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: ToastService.hasDetails ? expandButton.left : closeButton.left
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
||||||
DankActionButton {
|
DankActionButton {
|
||||||
|
id: expandButton
|
||||||
iconName: toast.expanded ? "expand_less" : "expand_more"
|
iconName: toast.expanded ? "expand_less" : "expand_more"
|
||||||
iconSize: Theme.iconSize
|
iconSize: Theme.iconSize
|
||||||
iconColor: Theme.background
|
iconColor: Theme.background
|
||||||
|
|||||||
127
docs/CUSTOM_THEMES.md
Normal file
127
docs/CUSTOM_THEMES.md
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
# Custom Themes
|
||||||
|
|
||||||
|
This guide covers creating custom themes for DankMaterialShell. You can define your own color schemes by creating theme files that the shell can load.
|
||||||
|
|
||||||
|
## Theme Structure
|
||||||
|
|
||||||
|
Themes are defined using the same structure as the built-in themes. Each theme must specify a complete set of Material Design 3 colors that work together harmoniously.
|
||||||
|
|
||||||
|
### Required Core Colors
|
||||||
|
|
||||||
|
These are the essential colors that define your theme's appearance:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"dark": {
|
||||||
|
"name": "Cyberpunk Electric Dark",
|
||||||
|
"primary": "#00FFCC",
|
||||||
|
"primaryText": "#000000",
|
||||||
|
"primaryContainer": "#00CC99",
|
||||||
|
"secondary": "#FF4DFF",
|
||||||
|
"surface": "#0F0F0F",
|
||||||
|
"surfaceText": "#E0FFE0",
|
||||||
|
"surfaceVariant": "#1F2F1F",
|
||||||
|
"surfaceVariantText": "#CCFFCC",
|
||||||
|
"surfaceTint": "#00FFCC",
|
||||||
|
"background": "#000000",
|
||||||
|
"backgroundText": "#F0FFF0",
|
||||||
|
"outline": "#80FF80",
|
||||||
|
"surfaceContainer": "#1A2B1A",
|
||||||
|
"surfaceContainerHigh": "#264026",
|
||||||
|
"error": "#FF0066",
|
||||||
|
"warning": "#CCFF00",
|
||||||
|
"info": "#00FFCC"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Cyberpunk Electric Light",
|
||||||
|
"primary": "#00B899",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#66FFDD",
|
||||||
|
"secondary": "#CC00CC",
|
||||||
|
"surface": "#F0FFF0",
|
||||||
|
"surfaceText": "#1F2F1F",
|
||||||
|
"surfaceVariant": "#E6FFE6",
|
||||||
|
"surfaceVariantText": "#2D4D2D",
|
||||||
|
"surfaceTint": "#00B899",
|
||||||
|
"background": "#FFFFFF",
|
||||||
|
"backgroundText": "#000000",
|
||||||
|
"outline": "#4DCC4D",
|
||||||
|
"surfaceContainer": "#F5FFF5",
|
||||||
|
"surfaceContainerHigh": "#EBFFEB",
|
||||||
|
"error": "#B3004D",
|
||||||
|
"warning": "#99CC00",
|
||||||
|
"info": "#00B899"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can the colors at the top level if you do not want "dark" and "light" variants.
|
||||||
|
|
||||||
|
## Example Themes
|
||||||
|
|
||||||
|
There are example themes you can start from:
|
||||||
|
|
||||||
|
- [Cyberpunk Electric](theme_cyberpunk_electric.json) - Neon green and magenta cyberpunk aesthetic
|
||||||
|
- [Hotline Miami](theme_hotline_miami.json) - Retro 80s inspired hot pink and blue
|
||||||
|
- [Miami Vice](theme_miami_vice.json) - Classic teal and pink vice aesthetic
|
||||||
|
- [Synthwave Electric](theme_synthwave_electric.json) - Electric purple and cyan synthwave vibes
|
||||||
|
|
||||||
|
### Color Definitions
|
||||||
|
|
||||||
|
**Primary Colors**
|
||||||
|
- `primary` - Main accent color used for buttons, highlights, and active states
|
||||||
|
- `primaryText` - Text color that contrasts well with primary background
|
||||||
|
- `primaryContainer` - Darker/lighter variant of primary for containers
|
||||||
|
|
||||||
|
**Secondary Colors**
|
||||||
|
- `secondary` - Supporting accent color for variety and hierarchy
|
||||||
|
- `surfaceTint` - Tint color applied to surfaces, usually derived from primary
|
||||||
|
|
||||||
|
**Surface Colors**
|
||||||
|
- `surface` - Default surface color for cards, panels, etc.
|
||||||
|
- `surfaceText` - Primary text color on surface backgrounds
|
||||||
|
- `surfaceVariant` - Alternate surface color for subtle differentiation
|
||||||
|
- `surfaceVariantText` - Text color for surfaceVariant backgrounds
|
||||||
|
- `surfaceContainer` - Container surface color, slightly different from surface
|
||||||
|
- `surfaceContainerHigh` - Elevated container color for layered interfaces
|
||||||
|
|
||||||
|
**Background Colors**
|
||||||
|
- `background` - Main background color for the entire interface
|
||||||
|
- `backgroundText` - Text color for background areas
|
||||||
|
|
||||||
|
**Outline Colors**
|
||||||
|
- `outline` - Border and divider color for subtle boundaries
|
||||||
|
|
||||||
|
## Optional Properties
|
||||||
|
|
||||||
|
While the core colors above are required, you can also customize these optional properties:
|
||||||
|
|
||||||
|
### Semantic Colors
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "#f44336",
|
||||||
|
"warning": "#ff9800",
|
||||||
|
"info": "#2196f3"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `error` - Used for error states, delete buttons, and critical warnings
|
||||||
|
- `warning` - Used for warning states and caution indicators
|
||||||
|
- `info` - Used for informational states and neutral indicators
|
||||||
|
|
||||||
|
## Setting Custom Theme
|
||||||
|
|
||||||
|
In settings -> Theme & Colors you can choose "Custom" to choose a path to your theme.
|
||||||
|
|
||||||
|
You can also edit `~/.config/DankMaterialShell/settings.json` manually
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"currentThemeName": "custom",
|
||||||
|
"customThemeFile": "/path/to/mytheme.json"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reactivity
|
||||||
|
|
||||||
|
Editing the custom theme file will auto-update the shell if it's the current theme.
|
||||||
42
docs/theme_cyberpunk_electric.json
Normal file
42
docs/theme_cyberpunk_electric.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"dark": {
|
||||||
|
"name": "Cyberpunk Electric Dark",
|
||||||
|
"primary": "#00FFCC",
|
||||||
|
"primaryText": "#000000",
|
||||||
|
"primaryContainer": "#00CC99",
|
||||||
|
"secondary": "#FF4DFF",
|
||||||
|
"surface": "#0F0F0F",
|
||||||
|
"surfaceText": "#E0FFE0",
|
||||||
|
"surfaceVariant": "#1F2F1F",
|
||||||
|
"surfaceVariantText": "#CCFFCC",
|
||||||
|
"surfaceTint": "#00FFCC",
|
||||||
|
"background": "#000000",
|
||||||
|
"backgroundText": "#F0FFF0",
|
||||||
|
"outline": "#80FF80",
|
||||||
|
"surfaceContainer": "#1A2B1A",
|
||||||
|
"surfaceContainerHigh": "#264026",
|
||||||
|
"error": "#FF0066",
|
||||||
|
"warning": "#CCFF00",
|
||||||
|
"info": "#00FFCC"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Cyberpunk Electric Light",
|
||||||
|
"primary": "#00B899",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#66FFDD",
|
||||||
|
"secondary": "#CC00CC",
|
||||||
|
"surface": "#F0FFF0",
|
||||||
|
"surfaceText": "#1F2F1F",
|
||||||
|
"surfaceVariant": "#E6FFE6",
|
||||||
|
"surfaceVariantText": "#2D4D2D",
|
||||||
|
"surfaceTint": "#00B899",
|
||||||
|
"background": "#FFFFFF",
|
||||||
|
"backgroundText": "#000000",
|
||||||
|
"outline": "#4DCC4D",
|
||||||
|
"surfaceContainer": "#F5FFF5",
|
||||||
|
"surfaceContainerHigh": "#EBFFEB",
|
||||||
|
"error": "#B3004D",
|
||||||
|
"warning": "#99CC00",
|
||||||
|
"info": "#00B899"
|
||||||
|
}
|
||||||
|
}
|
||||||
42
docs/theme_hotline_miami.json
Normal file
42
docs/theme_hotline_miami.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"dark": {
|
||||||
|
"name": "Hotline Miami Dark",
|
||||||
|
"primary": "#FF0080",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#CC0066",
|
||||||
|
"secondary": "#00FF80",
|
||||||
|
"surface": "#0D0D0D",
|
||||||
|
"surfaceText": "#F0F0F0",
|
||||||
|
"surfaceVariant": "#1A0F1A",
|
||||||
|
"surfaceVariantText": "#E0E0E0",
|
||||||
|
"surfaceTint": "#FF0080",
|
||||||
|
"background": "#000000",
|
||||||
|
"backgroundText": "#FFFFFF",
|
||||||
|
"outline": "#8000FF",
|
||||||
|
"surfaceContainer": "#1A0D1A",
|
||||||
|
"surfaceContainerHigh": "#260F26",
|
||||||
|
"error": "#FF4080",
|
||||||
|
"warning": "#FFFF00",
|
||||||
|
"info": "#00FF80"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Hotline Miami Light",
|
||||||
|
"primary": "#CC0066",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#FF80B3",
|
||||||
|
"secondary": "#00CC66",
|
||||||
|
"surface": "#FFF0FF",
|
||||||
|
"surfaceText": "#1A0F1A",
|
||||||
|
"surfaceVariant": "#F0E6F0",
|
||||||
|
"surfaceVariantText": "#2D1A2D",
|
||||||
|
"surfaceTint": "#CC0066",
|
||||||
|
"background": "#FFFFFF",
|
||||||
|
"backgroundText": "#0D0D0D",
|
||||||
|
"outline": "#6600CC",
|
||||||
|
"surfaceContainer": "#F5F0F5",
|
||||||
|
"surfaceContainerHigh": "#EBE0EB",
|
||||||
|
"error": "#B30040",
|
||||||
|
"warning": "#B3B300",
|
||||||
|
"info": "#00B359"
|
||||||
|
}
|
||||||
|
}
|
||||||
42
docs/theme_miami_vice.json
Normal file
42
docs/theme_miami_vice.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"dark": {
|
||||||
|
"name": "Miami Vice Dark",
|
||||||
|
"primary": "#00FFFF",
|
||||||
|
"primaryText": "#000000",
|
||||||
|
"primaryContainer": "#00CCCC",
|
||||||
|
"secondary": "#FF1493",
|
||||||
|
"surface": "#0A0A0F",
|
||||||
|
"surfaceText": "#E0E0FF",
|
||||||
|
"surfaceVariant": "#1A1A2E",
|
||||||
|
"surfaceVariantText": "#C0C0FF",
|
||||||
|
"surfaceTint": "#00FFFF",
|
||||||
|
"background": "#000008",
|
||||||
|
"backgroundText": "#F0F0FF",
|
||||||
|
"outline": "#4040FF",
|
||||||
|
"surfaceContainer": "#131325",
|
||||||
|
"surfaceContainerHigh": "#1F1F40",
|
||||||
|
"error": "#FF0080",
|
||||||
|
"warning": "#FFFF00",
|
||||||
|
"info": "#00FFFF"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Miami Vice Light",
|
||||||
|
"primary": "#0099CC",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#00CCFF",
|
||||||
|
"secondary": "#CC0066",
|
||||||
|
"surface": "#F8F8FF",
|
||||||
|
"surfaceText": "#1A1A2E",
|
||||||
|
"surfaceVariant": "#E8E8FF",
|
||||||
|
"surfaceVariantText": "#2A2A4E",
|
||||||
|
"surfaceTint": "#0099CC",
|
||||||
|
"background": "#FFFFFF",
|
||||||
|
"backgroundText": "#0A0A2E",
|
||||||
|
"outline": "#6666CC",
|
||||||
|
"surfaceContainer": "#F0F0FF",
|
||||||
|
"surfaceContainerHigh": "#E0E0FF",
|
||||||
|
"error": "#CC0055",
|
||||||
|
"warning": "#CC9900",
|
||||||
|
"info": "#0099CC"
|
||||||
|
}
|
||||||
|
}
|
||||||
42
docs/theme_synthwave_electric.json
Normal file
42
docs/theme_synthwave_electric.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"dark": {
|
||||||
|
"name": "Synthwave Electric Dark",
|
||||||
|
"primary": "#FF6600",
|
||||||
|
"primaryText": "#000000",
|
||||||
|
"primaryContainer": "#CC5200",
|
||||||
|
"secondary": "#0080FF",
|
||||||
|
"surface": "#0A0A15",
|
||||||
|
"surfaceText": "#E6F0FF",
|
||||||
|
"surfaceVariant": "#1A1A33",
|
||||||
|
"surfaceVariantText": "#CCE0FF",
|
||||||
|
"surfaceTint": "#FF6600",
|
||||||
|
"background": "#000008",
|
||||||
|
"backgroundText": "#F0F8FF",
|
||||||
|
"outline": "#4D80FF",
|
||||||
|
"surfaceContainer": "#151529",
|
||||||
|
"surfaceContainerHigh": "#212147",
|
||||||
|
"error": "#FF3366",
|
||||||
|
"warning": "#FFCC00",
|
||||||
|
"info": "#0080FF"
|
||||||
|
},
|
||||||
|
"light": {
|
||||||
|
"name": "Synthwave Electric Light",
|
||||||
|
"primary": "#CC5200",
|
||||||
|
"primaryText": "#FFFFFF",
|
||||||
|
"primaryContainer": "#FF9966",
|
||||||
|
"secondary": "#0066CC",
|
||||||
|
"surface": "#FFF8F0",
|
||||||
|
"surfaceText": "#1A1A33",
|
||||||
|
"surfaceVariant": "#F0F0FF",
|
||||||
|
"surfaceVariantText": "#333366",
|
||||||
|
"surfaceTint": "#CC5200",
|
||||||
|
"background": "#FFFFFF",
|
||||||
|
"backgroundText": "#000008",
|
||||||
|
"outline": "#3366CC",
|
||||||
|
"surfaceContainer": "#F5F5FF",
|
||||||
|
"surfaceContainerHigh": "#EBEBFF",
|
||||||
|
"error": "#CC1A40",
|
||||||
|
"warning": "#CC9900",
|
||||||
|
"info": "#0066CC"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user