Skip to main content

max / makenotwork

4.1 KB · 111 lines History Blame Raw
1 # theme-common
2
3 Shared theme loading logic for TOML-based theme files. Parses theme metadata and color values from `.toml` files on disk.
4
5 Used by GoingsOn and Balanced Breakfast (Tauri apps that load themes at runtime). audiofiles uses a different compile-time embedding approach and does not use this crate.
6
7 ## Usage
8
9 ```rust
10 use theme_common::{load_theme, list_themes_from_dirs, dev_themes_dir};
11 use std::path::PathBuf;
12
13 // Set up theme directories (later entries override earlier ones)
14 let bundled = PathBuf::from("/path/to/MNW/shared/themes");
15 let custom = PathBuf::from("/path/to/user/custom-themes");
16 let dirs = vec![(bundled, false), (custom, true)];
17
18 // List available themes (sorted by name)
19 let themes = list_themes_from_dirs(&dirs);
20 for t in &themes {
21 println!("{} ({}, {})", t.name, t.id, t.variant);
22 }
23
24 // Load a specific theme by ID
25 let theme = load_theme(&dirs, "catppuccin-mocha").unwrap();
26 println!("Name: {}", theme.meta.name); // "Catppuccin Mocha"
27 println!("Variant: {}", theme.meta.variant); // "dark"
28 println!("BG: {}", theme.colors["background.primary"]); // "#181825"
29
30 // Dev helper: find MNW/shared/themes/ relative to CARGO_MANIFEST_DIR
31 if let Some(dev_dir) = dev_themes_dir(Path::new(env!("CARGO_MANIFEST_DIR")), 3) {
32 // dev_dir = .../Code/MNW/shared/themes
33 }
34 ```
35
36 ## Theme File Format
37
38 Theme files are TOML with four color sections. See `../themes/` for the 16 bundled themes.
39
40 ```toml
41 # Attribution comment (optional, for credit)
42 # Based on Catppuccin by Catppuccin Org -- MIT License
43
44 [meta]
45 name = "Theme Name" # Display name (required)
46 variant = "dark" # "dark", "light", or "high-contrast" (default: "dark")
47
48 [background]
49 primary = "#181825" # Main background
50 secondary = "#11111b" # Sidebar / panel background (optional)
51 tertiary = "#313244" # Hover / selection background (optional)
52 surface = "#1e1e2e" # Card / elevated surface (optional)
53
54 [foreground]
55 primary = "#cdd6f4" # Main text
56 secondary = "#bac2de" # Secondary text (optional)
57 muted = "#9399b2" # Placeholder / disabled text (optional)
58
59 [accent]
60 red = "#f38ba8" # Error, destructive actions
61 green = "#a6e3a1" # Success, positive actions
62 blue = "#89b4fa" # Links, primary accent
63 yellow = "#f9e2af" # Warnings
64 purple = "#cba6f7" # Tags, special elements
65 cyan = "#89dceb" # Info, secondary accent
66
67 [border]
68 default = "#45475a" # Default border color
69 ```
70
71 ### Color Key Flattening
72
73 Colors are loaded into a flat `HashMap<String, String>` with dotted keys:
74
75 ```
76 "background.primary" -> "#181825"
77 "foreground.muted" -> "#9399b2"
78 "accent.blue" -> "#89b4fa"
79 "border.default" -> "#45475a"
80 ```
81
82 Apps map these keys to CSS variables or egui color values.
83
84 ### Theme ID
85
86 The theme ID is the filename without `.toml` (e.g., `catppuccin-mocha.toml` has ID `catppuccin-mocha`). IDs must contain only alphanumeric characters, hyphens, and underscores. Path traversal characters are rejected.
87
88 ## API
89
90 | Function | Description |
91 |----------|-------------|
92 | `list_themes_from_dirs(dirs)` | Scan directories for `.toml` files, return sorted `Vec<ThemeMeta>` |
93 | `load_theme(dirs, id)` | Load a theme by ID, returning `ThemeColors` (metadata + color map) |
94 | `find_theme_path(dirs, id)` | Find the file path for a theme ID (highest-priority directory wins) |
95 | `parse_meta(id, table, is_custom)` | Parse `[meta]` from a TOML table into `ThemeMeta` |
96 | `extract_colors(table)` | Flatten color sections into a `HashMap<String, String>` |
97 | `validate_theme_id(id)` | Check that an ID contains only safe characters |
98 | `dev_themes_dir(manifest_dir, levels)` | Walk up parent directories to find `MNW/shared/themes/` (dev convenience) |
99
100 ## Directory Priority
101
102 `list_themes_from_dirs` and `load_theme` accept a list of `(PathBuf, bool)` pairs. Later directories override earlier ones by theme ID. The `bool` marks whether the directory contains user-custom themes (`is_custom` on `ThemeMeta`).
103
104 Typical setup for a Tauri app:
105 1. Bundled themes from `MNW/shared/themes/` (is_custom = false)
106 2. User themes from an app data directory (is_custom = true)
107
108 ## License
109
110 PolyForm Noncommercial 1.0.0
111