Files
nix/hosts/common/configs/user/gui/theme/options.nix
Nikolaos Karaolidis b631d466ff Add asusctl settings
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2025-05-25 21:18:28 +01:00

507 lines
14 KiB
Nix

{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
lib,
pkgs,
...
}:
let
cfg = config.theme;
init = pkgs.writeShellApplication {
name = "theme-init";
runtimeInputs = with pkgs; [
matugen
imagemagick
];
text = ''
mkdir -p "${cfg.configDir}"
[[ ! -f "${cfg.configDir}"/wallpaper ]] && magick -size 1x1 xc:"#000000" png:"${cfg.configDir}"/wallpaper
[[ ! -f "${cfg.configDir}"/mode ]] && echo "dark" > "${cfg.configDir}"/mode
[[ ! -f "${cfg.configDir}"/flavor ]] && echo "tonal-spot" > "${cfg.configDir}"/flavor
[[ ! -f "${cfg.configDir}"/contrast ]] && echo "0" > "${cfg.configDir}"/contrast
matugen image "${cfg.configDir}"/wallpaper \
--mode "$(<"${cfg.configDir}/mode")" \
--type "scheme-$(<"${cfg.configDir}/flavor")" \
--contrast "$(<"${cfg.configDir}/contrast")"
${cfg.initExtraConfig}
wait
'';
};
reload = pkgs.writeShellApplication {
name = "theme-reload";
text = ''
${cfg.reloadExtraConfig}
wait
'';
};
theme = pkgs.writeShellApplication {
name = "theme";
runtimeInputs = with pkgs; [
coreutils
imagemagick
];
runtimeEnv = {
CONFIG = cfg.configDir;
INIT = lib.meta.getExe init;
RELOAD = lib.meta.getExe reload;
};
text = builtins.readFile ./theme.sh;
};
in
{
# https://github.com/Theaninova/TheaninovOS/blob/master/modules/home-manager/theme/md3-evo.nix
options.theme =
with lib;
with types;
{
enable = mkEnableOption "theme";
configDir = mkOption {
type = str;
default = "${config.xdg.configHome}/theme";
description = "The path to the theme config directory.";
};
pkg = mkOption {
type = package;
default = theme;
readOnly = true;
description = "The package containing the `theme` script";
};
initExtraConfig = mkOption {
type = lines;
default = "";
description = "Extra configuration lines to add to the theme initialization script.";
};
reloadExtraConfig = mkOption {
type = lines;
default = "";
description = "Extra configuration lines to add to the theme reload script.";
};
template = mkOption {
type = attrsOf (
submodule (
{ name, config, ... }:
{
options = {
source = mkOption {
type = path;
description = "Path of the source file or directory.";
default = null;
};
target = mkOption {
type = str;
defaultText = literalExpression "name";
description = "Path to target relative to the user's {env}`HOME`.";
};
};
config.target = mkDefault name;
}
)
);
default = { };
description = "Templates to fill with theme colors.";
};
opacity = mkOption {
type = numbers.between 0 1;
default = 1;
description = "The opacity of apps.";
};
radius = mkOption {
type = ints.unsigned;
default = 0;
description = "The radius of corners.";
};
padding = mkOption {
type = ints.unsigned;
default = 0;
description = "The padding of windows.";
};
blur = mkOption {
type = ints.unsigned;
default = 0;
description = "The blur amount of windows.";
};
color = {
semantic = {
blend = mkOption {
type = bool;
default = true;
description = "Blend the colors.";
};
danger = mkOption {
type = str;
default = "#ff0000";
description = "The color of danger.";
};
warning = mkOption {
type = str;
default = "#ffff00";
description = "The color of warning.";
};
success = mkOption {
type = str;
default = "#00ff00";
description = "The color of success.";
};
info = mkOption {
type = str;
default = "#0000ff";
description = "The color of info.";
};
};
syntax = {
blend = mkOption {
type = bool;
default = true;
description = "Blend the colors.";
};
keywords = mkOption {
type = str;
default = "#ff8000";
description = "The color of keywords.";
};
functions = mkOption {
type = str;
default = "#0000ff";
description = "The color of functions.";
};
properties = mkOption {
type = str;
default = "#ff00ff";
description = "The color of properties.";
};
constants = mkOption {
type = str;
default = "#ff00ff";
description = "The color of constants.";
};
strings = mkOption {
type = str;
default = "#00ff00";
description = "The color of variables.";
};
numbers = mkOption {
type = str;
default = "#00ffff";
description = "The color of numbers.";
};
structures = mkOption {
type = str;
default = "#ffff00";
description = "The color of structures.";
};
types = mkOption {
type = str;
default = "#00ffff";
description = "The color of types.";
};
};
basic = {
blend = mkOption {
type = bool;
default = true;
description = "Blend the colors.";
};
red = mkOption {
type = str;
default = "#ff0000";
description = "The color of red.";
};
orange = mkOption {
type = str;
default = "#ff8000";
description = "The color of orange.";
};
yellow = mkOption {
type = str;
default = "#ffff00";
description = "The color of yellow.";
};
green = mkOption {
type = str;
default = "#00ff00";
description = "The color of green.";
};
cyan = mkOption {
type = str;
default = "#00ffff";
description = "The color of cyan.";
};
blue = mkOption {
type = str;
default = "#0000ff";
description = "The color of blue.";
};
magenta = mkOption {
type = str;
default = "#ff00ff";
description = "The color of magenta.";
};
pink = mkOption {
type = str;
default = "#ffc0cb";
description = "The color of pink.";
};
};
};
font = {
sansSerif = {
names = mkOption {
type = listOf str;
default = [ "Roboto" ];
description = "The sans serif font families.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [ roboto ];
description = "The sans serif font packages.";
};
};
serif = {
names = mkOption {
type = listOf str;
default = [ "Roboto Serif" ];
description = "The serif font families.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [ roboto-serif ];
description = "The serif font packages.";
};
};
monospace = {
names = mkOption {
type = listOf str;
default = [ "JetBrainsMono Nerd Font" ];
description = "The monospace font families.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [ nerd-fonts.jetbrains-mono ];
description = "The monospace font packages.";
};
};
emoji = {
names = mkOption {
type = listOf str;
default = [
"Noto Emoji"
"Font Awesome"
];
description = "The emoji font families.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [
noto-fonts-color-emoji
font-awesome
];
description = "The emoji font packages.";
};
};
size = mkOption {
type = ints.positive;
default = 12;
description = "The font size.";
};
};
icon = {
names = mkOption {
type = listOf str;
default = [ "Adwaita" ];
description = "The icon theme names.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [
adwaita-icon-theme
nixos-icons
];
description = "The icon theme packages.";
};
};
cursor = {
names = mkOption {
type = listOf str;
default = [ "Adwaita" ];
description = "The cursor names.";
};
packages = mkOption {
type = listOf package;
default = with pkgs; [ adwaita-icon-theme ];
description = "The cursor theme packages.";
};
size = mkOption {
type = ints.positive;
default = 24;
description = "The cursor size.";
};
};
};
config = lib.mkIf cfg.enable {
home = {
activation.themeInit = inputs.home-manager.lib.hm.dag.entryAfter [
"writeBoundary"
"dconfSettings"
] "run ${lib.meta.getExe init}";
packages =
with pkgs;
[
matugen
theme
]
++ cfg.font.sansSerif.packages
++ cfg.font.serif.packages
++ cfg.font.monospace.packages
++ cfg.font.emoji.packages
++ cfg.icon.packages
++ cfg.cursor.packages;
pointerCursor = {
name = builtins.head cfg.cursor.names;
package = builtins.head cfg.cursor.packages;
inherit (cfg.cursor) size;
};
};
fonts.fontconfig = {
enable = true;
defaultFonts = {
sansSerif = cfg.font.sansSerif.names;
serif = cfg.font.serif.names;
monospace = cfg.font.monospace.names;
emoji = cfg.font.emoji.names;
};
};
xdg.configFile."matugen/config.toml".source = (
(pkgs.formats.toml { }).generate "config.toml" {
config = {
custom_colors =
let
mkColor = category: color: {
color = cfg.color.${category}.${color};
blend = cfg.color.${category}.blend;
};
in
{
danger = mkColor "semantic" "danger";
warning = mkColor "semantic" "warning";
success = mkColor "semantic" "success";
info = mkColor "semantic" "info";
red = mkColor "basic" "red";
orange = mkColor "basic" "orange";
yellow = mkColor "basic" "yellow";
green = mkColor "basic" "green";
cyan = mkColor "basic" "cyan";
blue = mkColor "basic" "blue";
magenta = mkColor "basic" "magenta";
pink = mkColor "basic" "pink";
keywords = mkColor "syntax" "keywords";
functions = mkColor "syntax" "functions";
properties = mkColor "syntax" "properties";
constants = mkColor "syntax" "constants";
strings = mkColor "syntax" "strings";
numbers = mkColor "syntax" "numbers";
structures = mkColor "syntax" "structures";
types = mkColor "syntax" "types";
};
custom_keywords =
let
zeroPad = hex: if builtins.stringLength hex == 1 then "0${hex}" else hex;
percentageToHex = percentage: zeroPad (lib.trivial.toHexString (builtins.floor (percentage * 255)));
in
{
radius = builtins.toString cfg.radius;
padding = builtins.toString cfg.padding;
padding_double = builtins.toString (cfg.padding * 2);
blur = builtins.toString cfg.blur;
opacity = builtins.toString cfg.opacity;
opacity_hex = builtins.toString (percentageToHex cfg.opacity);
opacity_shadow = builtins.toString (cfg.opacity * 0.75);
opacity_shadow_hex = builtins.toString (percentageToHex (cfg.opacity * 0.75));
font_size = builtins.toString cfg.font.size;
font_sans_serif = builtins.head cfg.font.sansSerif.names;
font_sans_serif_all = builtins.concatStringsSep ", " cfg.font.sansSerif.names;
font_serif = builtins.head cfg.font.serif.names;
font_serif_all = builtins.concatStringsSep ", " cfg.font.serif.names;
font_monospace = builtins.head cfg.font.monospace.names;
font_monospace_all = builtins.concatStringsSep ", " cfg.font.monospace.names;
font_emoji = builtins.head cfg.font.emoji.names;
font_emoji_all = builtins.concatStringsSep ", " cfg.font.emoji.names;
};
};
templates = builtins.mapAttrs (name: template: {
input_path = template.source;
output_path = "${home}/${template.target}";
}) cfg.template;
}
);
programs.zsh.initContent = builtins.readFile ./theme.completion.zsh;
};
}