feat(ui): Catppuccin Latte, Frappé, Macchiato and Mocha themes

Four new themes on the Studio layout (Window > Theme, Preferences, ui.set),
wired through the engine's Theme/DarkTheme/LightTheme preferences. Palette
is the MIT-licensed Catppuccin one (LICENSE-catppuccin.txt, ATTRIBUTION.md).
Menu and preference labels translated for every complete-menu language.
.debrand now exempts itself from its own check.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Marcos Paulo
2026-10-11 19:59:03 -03:00
parent eb7321b0e4
commit ac9e15a079
26 changed files with 385 additions and 10 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
# Strip upstream (ArtCraft / Discord) branding. Run: ~/.agents/skills/debrand/debrand.pl (--check in CI)
delete docs/brand
# MIT/Apache texts stay verbatim. The copyright holder line stays everywhere (legal requirement).
keep ^LICENSE-(MIT|APACHE)$
keep ^(LICENSE-(MIT|APACHE)|\.debrand)$
dropline ^crates/ui-egui/src/i18n/.*\.tsv$ :: \t.*(?:ArtCraft|Discord)
dropline ^ATTRIBUTION\.md$ :: \|\s*`docs/brand/
sub (?s)\nThe ArtCraft name, wordmark and logos in docs/brand/.*?LICENSE-brand\.txt\.\n =>
+1
View File
@@ -50,6 +50,7 @@ next to them.
| `assets/app-icon/` (all files) | PhotoCraft app icon (nine-tailed kitsune) | The project owner (drawn by hand, vectorised) | Original work, see [`assets/app-icon/README.md`](assets/app-icon/README.md) | MIT OR Apache-2.0, [`assets/app-icon/LICENSE.txt`](assets/app-icon/LICENSE.txt) |
| `packaging/macos/dmg/` (all files) | PhotoCraft DMG window background and layout | @XusBadia, from the PhotoCraft app icon | Original work, see [`packaging/macos/dmg/README.md`](packaging/macos/dmg/README.md) | MIT OR Apache-2.0, like the code |
| `crates/ui-egui/src/theme.rs` (Solarized Dark palette) | Solarized colour scheme used by the Solarized Dark theme | Ethan Schoonover | <https://ethanschoonover.com/solarized/> | MIT, [`LICENSE-solarized.txt`](crates/ui-egui/src/LICENSE-solarized.txt) |
| `crates/ui-egui/src/theme_catppuccin.rs` (Catppuccin palettes) | Catppuccin Latte, Frappé, Macchiato and Mocha colours used by the Catppuccin themes | Catppuccin | <https://catppuccin.com/palette> | MIT, [`LICENSE-catppuccin.txt`](crates/ui-egui/src/LICENSE-catppuccin.txt) |
| `crates/ui-egui/src/theme.rs` (Breeze Light and Breeze Dark themes) | The Breeze Light and Breeze Dark themes are original colour values on PhotoCraft's Studio layout, chosen to look close to KDE Plasma's Breeze (cool blue-greys, blue accent, 5 px frame radius) so the app blends into a Plasma desktop. None of Breeze's colour values, files or code are copied; the values are a few levels away from its schemes and tuned for text contrast | PhotoCraft contributors | Inspired by the look of KDE Breeze, <https://invent.kde.org/plasma/breeze> (its colour schemes are LGPL-2.0-or-later) | Original work |
### Optional build input: craft-fonts (not files in this repo)
+1 -1
View File
@@ -309,7 +309,7 @@ pub struct UiSetParams {
/// Fields for the control method `ui.set`: tool, panels, dock, dockTabs, dockWidth, colorPanel
/// ({background: bool} picks which swatch the Color panel edits), maskTarget,
/// vectorMaskTarget, selectionMode, zoom, center, rotation (view angle in degrees), fit, theme (pro, proMedium, studio,
/// studioLight, classic, solarizedDark, adwaita, adwaitaDark, breezeLight, breezeDark), brushSection, brushTab,
/// studioLight, classic, solarizedDark, adwaita, adwaitaDark, breezeLight, breezeDark, catppuccinLatte, catppuccinFrappe, catppuccinMacchiato, catppuccinMocha), brushSection, brushTab,
/// brushesView, brushPicker ([x, y] opens the Brush Preset picker there, null closes it),
/// brushPickerName, brushPickerStroke, brushPickerTip (the picker card's parts, at least one
/// on), brushPickerScale (the picker footer's card-scale slider, 0.15 to 2, 1 the standard),
+31 -5
View File
@@ -55,10 +55,10 @@ choice!(TypeUnit { Points = "points", Pixels = "pixels", Millimeters = "mm" } de
choice!(PointSize { PostScript = "postScript", Traditional = "traditional" } default PostScript);
choice!(Interpolation { BicubicAutomatic = "bicubicAutomatic", Nearest = "nearestNeighbor", Bilinear = "bilinear", Bicubic = "bicubic", BicubicSmoother = "bicubicSmoother", BicubicSharper = "bicubicSharper", PreserveDetails = "preserveDetails" } default BicubicAutomatic);
choice!(ColorPicker { Adobe = "adobe", System = "system" } default Adobe);
choice!(Theme { Pro = "pro", ProMedium = "proMedium", ProLightGray = "proLightGray", ProLight = "proLight", Studio = "studio", StudioLight = "studioLight", Classic = "classic", SolarizedDark = "solarizedDark", Adwaita = "adwaita", AdwaitaDark = "adwaitaDark", BreezeLight = "breezeLight", BreezeDark = "breezeDark" } default ProMedium);
choice!(Theme { Pro = "pro", ProMedium = "proMedium", ProLightGray = "proLightGray", ProLight = "proLight", Studio = "studio", StudioLight = "studioLight", Classic = "classic", SolarizedDark = "solarizedDark", Adwaita = "adwaita", AdwaitaDark = "adwaitaDark", BreezeLight = "breezeLight", BreezeDark = "breezeDark", CatppuccinLatte = "catppuccinLatte", CatppuccinFrappe = "catppuccinFrappe", CatppuccinMacchiato = "catppuccinMacchiato", CatppuccinMocha = "catppuccinMocha" } default ProMedium);
choice!(AppearanceMode { Auto = "auto", Dark = "dark", Light = "light" } default Dark);
choice!(DarkTheme { Pro = "pro", ProMedium = "proMedium", Studio = "studio", SolarizedDark = "solarizedDark", AdwaitaDark = "adwaitaDark", BreezeDark = "breezeDark" } default ProMedium);
choice!(LightTheme { StudioLight = "studioLight", ProLightGray = "proLightGray", ProLight = "proLight", Classic = "classic", Adwaita = "adwaita", BreezeLight = "breezeLight" } default StudioLight);
choice!(DarkTheme { Pro = "pro", ProMedium = "proMedium", Studio = "studio", SolarizedDark = "solarizedDark", AdwaitaDark = "adwaitaDark", BreezeDark = "breezeDark", CatppuccinFrappe = "catppuccinFrappe", CatppuccinMacchiato = "catppuccinMacchiato", CatppuccinMocha = "catppuccinMocha" } default ProMedium);
choice!(LightTheme { StudioLight = "studioLight", ProLightGray = "proLightGray", ProLight = "proLight", Classic = "classic", Adwaita = "adwaita", BreezeLight = "breezeLight", CatppuccinLatte = "catppuccinLatte" } default StudioLight);
choice!(CanvasColor { Default = "default", Black = "black", DarkGray = "darkGray", MediumGray = "mediumGray", LightGray = "lightGray", Custom = "custom" } default Default);
choice!(CanvasBorder { DropShadow = "dropShadow", Line = "line", None = "none" } default DropShadow);
choice!(UiScale { Auto = "auto", P75 = "75", P80 = "80", P85 = "85", P90 = "90", P95 = "95", P100 = "100", P125 = "125", P150 = "150", P175 = "175", P200 = "200", P250 = "250", P300 = "300" } default Auto);
@@ -1542,8 +1542,18 @@ impl Session {
&& let Some(theme) = interface.get("theme").and_then(Value::as_str).and_then(Theme::parse)
{
let (mode, slot) = match theme {
Theme::Pro | Theme::ProMedium | Theme::Studio | Theme::SolarizedDark | Theme::AdwaitaDark | Theme::BreezeDark => ("dark", "darkTheme"),
Theme::StudioLight | Theme::ProLightGray | Theme::ProLight | Theme::Classic | Theme::Adwaita | Theme::BreezeLight => ("light", "lightTheme"),
Theme::Pro
| Theme::ProMedium
| Theme::Studio
| Theme::SolarizedDark
| Theme::AdwaitaDark
| Theme::BreezeDark
| Theme::CatppuccinFrappe
| Theme::CatppuccinMacchiato
| Theme::CatppuccinMocha => ("dark", "darkTheme"),
Theme::StudioLight | Theme::ProLightGray | Theme::ProLight | Theme::Classic | Theme::Adwaita | Theme::BreezeLight | Theme::CatppuccinLatte => {
("light", "lightTheme")
}
};
interface.insert("appearanceMode".into(), json!(mode));
interface.insert(slot.into(), json!(theme.name()));
@@ -1666,6 +1676,22 @@ impl Session {
next.interface.light_theme = LightTheme::BreezeLight;
next.interface.appearance_mode = AppearanceMode::Light;
}
Theme::CatppuccinLatte => {
next.interface.light_theme = LightTheme::CatppuccinLatte;
next.interface.appearance_mode = AppearanceMode::Light;
}
Theme::CatppuccinFrappe => {
next.interface.dark_theme = DarkTheme::CatppuccinFrappe;
next.interface.appearance_mode = AppearanceMode::Dark;
}
Theme::CatppuccinMacchiato => {
next.interface.dark_theme = DarkTheme::CatppuccinMacchiato;
next.interface.appearance_mode = AppearanceMode::Dark;
}
Theme::CatppuccinMocha => {
next.interface.dark_theme = DarkTheme::CatppuccinMocha;
next.interface.appearance_mode = AppearanceMode::Dark;
}
}
}
self.prefs.edit(|p| *p = next);
+28
View File
@@ -0,0 +1,28 @@
Catppuccin
https://catppuccin.com/palette
https://github.com/catppuccin/catppuccin
The Catppuccin Latte, Frappé, Macchiato and Mocha themes' colour palettes in `theme_catppuccin.rs`
are the Catppuccin project's palettes, used under the MIT License below.
MIT License
Copyright (c) 2021 Catppuccin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+8
View File
@@ -729,6 +729,14 @@
Classic Theme Klasický motiv
Solarized dark Solarized tmavý
Solarized Dark Theme Tmavý motiv Solarized
Catppuccin Latte Theme Motiv Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Motiv Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Motiv Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Motiv Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze tmavý
Breeze Dark Theme Tmavý motiv Breeze
Breeze light Breeze světlý
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -715,6 +715,14 @@
Classic Theme Klassisches Design
Solarized dark Solarized dunkel
Solarized Dark Theme Solarized-Design (Dunkel)
Catppuccin Latte Theme Catppuccin-Design Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin-Design Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin-Design Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin-Design Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze dunkel
Breeze Dark Theme Breeze-Design (Dunkel)
Breeze light Breeze hell
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -2115,6 +2115,14 @@
Classic Theme Κλασικό θέμα
Solarized dark Solarized σκούρο
Solarized Dark Theme Σκούρο θέμα Solarized
Catppuccin Latte Theme Θέμα Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Θέμα Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Θέμα Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Θέμα Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze σκούρο
Breeze Dark Theme Σκούρο θέμα Breeze
Breeze light Breeze φωτεινό
Can't render this file because it contains an unexpected character in line 1000 and column 18.
+8
View File
@@ -722,6 +722,14 @@
Classic Theme Tema Clásico
Solarized dark Solarized oscuro
Solarized Dark Theme Tema Solarized oscuro
Catppuccin Latte Theme Tema Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Tema Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Tema Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Tema Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze oscuro
Breeze Dark Theme Tema Breeze oscuro
Breeze light Breeze claro
Can't render this file because it contains an unexpected character in line 4 and column 47.
+8
View File
@@ -712,6 +712,14 @@
Classic Theme Thème Classique
Solarized dark Solarized sombre
Solarized Dark Theme Thème Solarized sombre
Catppuccin Latte Theme Thème Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Thème Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Thème Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Thème Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze sombre
Breeze Dark Theme Thème Breeze sombre
Breeze light Breeze clair
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -705,6 +705,14 @@
Classic Theme Tema Klasik
Solarized dark Solarized gelap
Solarized Dark Theme Tema Solarized Gelap
Catppuccin Latte Theme Tema Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Tema Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Tema Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Tema Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze gelap
Breeze Dark Theme Tema Breeze Gelap
Breeze light Breeze terang
Can't render this file because it contains an unexpected character in line 4 and column 47.
+8
View File
@@ -720,6 +720,14 @@
Classic Theme Tema classico
Solarized dark Solarized scuro
Solarized Dark Theme Tema Solarized scuro
Catppuccin Latte Theme Tema Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Tema Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Tema Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Tema Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze scuro
Breeze Dark Theme Tema Breeze scuro
Breeze light Breeze chiaro
1 # Italian (it) catalog. Columns, separated by a TAB: context <TAB> source <TAB> translation
720
721
722
723
724
725
726
727
728
729
730
731
732
733
+8
View File
@@ -722,6 +722,14 @@
Classic Theme クラシックテーマ
Solarized dark Solarized ダーク
Solarized Dark Theme Solarized ダークテーマ
Catppuccin Latte Theme Catppuccin Latte テーマ
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin Frappé テーマ
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin Macchiato テーマ
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin Mocha テーマ
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze ダーク
Breeze Dark Theme Breeze ダークテーマ
Breeze light Breeze ライト
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -696,6 +696,14 @@
Classic Theme 클래식 테마
Solarized dark Solarized 어두움
Solarized Dark Theme Solarized 어두운 테마
Catppuccin Latte Theme Catppuccin Latte 테마
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin Frappé 테마
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin Macchiato 테마
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin Mocha 테마
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze 어두움
Breeze Dark Theme Breeze 어두운 테마
Breeze light Breeze 밝게
1 # Korean (ko) catalog. UTF-8: context<TAB>English source<TAB>translation.
696
697
698
699
700
701
702
703
704
705
706
707
708
709
+8
View File
@@ -701,6 +701,14 @@
Classic Theme Klassiek thema
Solarized dark Solarized donker
Solarized Dark Theme Solarized-thema donker
Catppuccin Latte Theme Catppuccin-thema Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin-thema Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin-thema Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin-thema Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze donker
Breeze Dark Theme Breeze-thema donker
Breeze light Breeze licht
Can't render this file because it contains an unexpected character in line 8 and column 34.
+8
View File
@@ -721,6 +721,14 @@
Classic Theme Motyw klasyczny
Solarized dark Solarized ciemny
Solarized Dark Theme Ciemny motyw Solarized
Catppuccin Latte Theme Motyw Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Motyw Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Motyw Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Motyw Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze ciemny
Breeze Dark Theme Ciemny motyw Breeze
Breeze light Breeze jasny
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -707,6 +707,14 @@
Classic Theme Tema clássico
Solarized dark Solarized escuro
Solarized Dark Theme Tema Solarized Escuro
Catppuccin Latte Theme Tema Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Tema Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Tema Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Tema Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze escuro
Breeze Dark Theme Tema Breeze Escuro
Breeze light Breeze claro
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -1422,6 +1422,14 @@
Classic Theme Классическая тема
Solarized dark Solarized тёмная
Solarized Dark Theme Тёмная тема Solarized
Catppuccin Latte Theme Тема Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Тема Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Тема Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Тема Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze тёмная
Breeze Dark Theme Тёмная тема Breeze
Breeze light Breeze светлая
Can't render this file because it contains an unexpected character in line 6 and column 47.
+8
View File
@@ -1401,6 +1401,14 @@
Classic Theme Класична тема
Solarized dark Solarized темна
Solarized Dark Theme Темна тема Solarized
Catppuccin Latte Theme Тема Catppuccin Latte
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Тема Catppuccin Frappé
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Тема Catppuccin Macchiato
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Тема Catppuccin Mocha
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze темна
Breeze Dark Theme Темна тема Breeze
Breeze light Breeze світла
Can't render this file because it contains an unexpected character in line 1355 and column 18.
+8
View File
@@ -724,6 +724,14 @@
Classic Theme 经典主题
Solarized dark Solarized 深色
Solarized Dark Theme Solarized 深色主题
Catppuccin Latte Theme Catppuccin Latte 主题
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin Frappé 主题
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin Macchiato 主题
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin Mocha 主题
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze 深色
Breeze Dark Theme Breeze 深色主题
Breeze light Breeze 浅色
1 # Simplified Chinese (zh-hans) catalog. UTF-8, TAB-separated columns:
724
725
726
727
728
729
730
731
732
733
734
735
736
737
+8
View File
@@ -729,6 +729,14 @@
Classic Theme 經典主題
Solarized dark Solarized 深色
Solarized Dark Theme Solarized 深色主題
Catppuccin Latte Theme Catppuccin Latte 主題
Catppuccin latte Catppuccin Latte
Catppuccin Frappé Theme Catppuccin Frappé 主題
Catppuccin frappe Catppuccin Frappé
Catppuccin Macchiato Theme Catppuccin Macchiato 主題
Catppuccin macchiato Catppuccin Macchiato
Catppuccin Mocha Theme Catppuccin Mocha 主題
Catppuccin mocha Catppuccin Mocha
Breeze dark Breeze 深色
Breeze Dark Theme Breeze 深色主題
Breeze light Breeze 淺色
Can't render this file because it contains an unexpected character in line 6 and column 47.
+1
View File
@@ -187,6 +187,7 @@ mod tab_strip;
pub mod targa_options_ui;
pub mod text_field_menu;
pub mod theme;
mod theme_catppuccin;
pub mod tiff_options_ui;
mod timeline_ui;
mod titlebar;
+9 -1
View File
@@ -89,6 +89,10 @@ pub const UI_COMMANDS: &[(&str, &str, &[&str], Option<&str>)] = &[
("window.theme.adwaitaDark", "Adwaita Dark Theme", &["Window", "Theme"], None),
("window.theme.breezeLight", "Breeze Light Theme", &["Window", "Theme"], None),
("window.theme.breezeDark", "Breeze Dark Theme", &["Window", "Theme"], None),
("window.theme.catppuccinLatte", "Catppuccin Latte Theme", &["Window", "Theme"], None),
("window.theme.catppuccinFrappe", "Catppuccin Frappé Theme", &["Window", "Theme"], None),
("window.theme.catppuccinMacchiato", "Catppuccin Macchiato Theme", &["Window", "Theme"], None),
("window.theme.catppuccinMocha", "Catppuccin Mocha Theme", &["Window", "Theme"], None),
("window.theme.system", "Sync with system", &["Window", "Theme"], None),
("edit.search", "Search…", &["Edit"], Some("Cmd+F")),
("help.github", "PhotoCraft on GitHub", &["Help"], None),
@@ -367,7 +371,11 @@ pub(crate) fn invoke_unguarded(app: &mut PhotocraftApp, ctx: &egui::Context, id:
| "window.theme.adwaita"
| "window.theme.adwaitaDark"
| "window.theme.breezeLight"
| "window.theme.breezeDark" => {
| "window.theme.breezeDark"
| "window.theme.catppuccinLatte"
| "window.theme.catppuccinFrappe"
| "window.theme.catppuccinMacchiato"
| "window.theme.catppuccinMocha" => {
let k = crate::theme::ThemeKind::from_name(&id["window.theme.".len()..]).unwrap_or_default();
app.set_theme(ctx, k);
Ok(Value::Null)
+8
View File
@@ -97,6 +97,7 @@ fn selected_theme(interface: &prefs::Interface, system: Option<egui::Theme>) ->
LightTheme::Classic => ThemeKind::Classic,
LightTheme::Adwaita => ThemeKind::Adwaita,
LightTheme::BreezeLight => ThemeKind::BreezeLight,
LightTheme::CatppuccinLatte => ThemeKind::CatppuccinLatte,
}
} else {
match interface.dark_theme {
@@ -106,6 +107,9 @@ fn selected_theme(interface: &prefs::Interface, system: Option<egui::Theme>) ->
DarkTheme::SolarizedDark => ThemeKind::SolarizedDark,
DarkTheme::AdwaitaDark => ThemeKind::AdwaitaDark,
DarkTheme::BreezeDark => ThemeKind::BreezeDark,
DarkTheme::CatppuccinFrappe => ThemeKind::CatppuccinFrappe,
DarkTheme::CatppuccinMacchiato => ThemeKind::CatppuccinMacchiato,
DarkTheme::CatppuccinMocha => ThemeKind::CatppuccinMocha,
}
}
}
@@ -133,6 +137,7 @@ const LIGHT_THEME_OPTIONS: &[(&str, ThemeKind)] = &[
("classic", ThemeKind::Classic),
("adwaita", ThemeKind::Adwaita),
("breezeLight", ThemeKind::BreezeLight),
("catppuccinLatte", ThemeKind::CatppuccinLatte),
];
const DARK_THEME_OPTIONS: &[(&str, ThemeKind)] = &[
("proMedium", ThemeKind::ProMedium),
@@ -141,6 +146,9 @@ const DARK_THEME_OPTIONS: &[(&str, ThemeKind)] = &[
("solarizedDark", ThemeKind::SolarizedDark),
("adwaitaDark", ThemeKind::AdwaitaDark),
("breezeDark", ThemeKind::BreezeDark),
("catppuccinFrappe", ThemeKind::CatppuccinFrappe),
("catppuccinMacchiato", ThemeKind::CatppuccinMacchiato),
("catppuccinMocha", ThemeKind::CatppuccinMocha),
];
fn favorite_theme_groups(favorites: &[SavedTheme]) -> (Vec<ThemeKind>, Vec<ThemeKind>) {
+37 -2
View File
@@ -48,10 +48,18 @@ pub enum ThemeKind {
BreezeLight,
/// An adaptation of KDE Plasma's Breeze Dark look.
BreezeDark,
/// Catppuccin Latte (light).
CatppuccinLatte,
/// Catppuccin Frappé (dark).
CatppuccinFrappe,
/// Catppuccin Macchiato (dark).
CatppuccinMacchiato,
/// Catppuccin Mocha (dark).
CatppuccinMocha,
}
impl ThemeKind {
pub const ALL: [ThemeKind; 12] = [
pub const ALL: [ThemeKind; 16] = [
ThemeKind::Pro,
ThemeKind::ProMedium,
ThemeKind::ProLightGray,
@@ -64,6 +72,10 @@ impl ThemeKind {
ThemeKind::AdwaitaDark,
ThemeKind::BreezeLight,
ThemeKind::BreezeDark,
ThemeKind::CatppuccinLatte,
ThemeKind::CatppuccinFrappe,
ThemeKind::CatppuccinMacchiato,
ThemeKind::CatppuccinMocha,
];
pub fn label(self) -> &'static str {
match self {
@@ -79,6 +91,10 @@ impl ThemeKind {
ThemeKind::SolarizedDark => "Solarized Dark",
ThemeKind::BreezeLight => "Breeze Light",
ThemeKind::BreezeDark => "Breeze Dark",
ThemeKind::CatppuccinLatte => "Catppuccin Latte",
ThemeKind::CatppuccinFrappe => "Catppuccin Frappé",
ThemeKind::CatppuccinMacchiato => "Catppuccin Macchiato",
ThemeKind::CatppuccinMocha => "Catppuccin Mocha",
}
}
/// The canonical name: `ui.set {theme}` accepts it and the Window › Theme commands are
@@ -97,6 +113,10 @@ impl ThemeKind {
ThemeKind::SolarizedDark => "solarizedDark",
ThemeKind::BreezeLight => "breezeLight",
ThemeKind::BreezeDark => "breezeDark",
ThemeKind::CatppuccinLatte => "catppuccinLatte",
ThemeKind::CatppuccinFrappe => "catppuccinFrappe",
ThemeKind::CatppuccinMacchiato => "catppuccinMacchiato",
ThemeKind::CatppuccinMocha => "catppuccinMocha",
}
}
/// Photoshop-grammar layout (tab strips, flat panels): the four Pro brightness levels.
@@ -121,6 +141,10 @@ impl ThemeKind {
"solarizeddark" | "solarized" => Some(ThemeKind::SolarizedDark),
"breezelight" | "breeze" | "kde" | "kdelight" | "plasma" | "plasmalight" => Some(ThemeKind::BreezeLight),
"breezedark" | "kdedark" | "plasmadark" => Some(ThemeKind::BreezeDark),
"catppuccinlatte" | "latte" => Some(ThemeKind::CatppuccinLatte),
"catppuccinfrappe" | "catppuccinfrappé" | "frappe" | "frappé" => Some(ThemeKind::CatppuccinFrappe),
"catppuccinmacchiato" | "macchiato" => Some(ThemeKind::CatppuccinMacchiato),
"catppuccinmocha" | "catppuccin" | "mocha" => Some(ThemeKind::CatppuccinMocha),
_ => None,
}
}
@@ -645,6 +669,9 @@ impl Tokens {
caption_close_text: Color32::from_rgb(253, 246, 227),
scrim: Color32::from_black_alpha(110),
},
ThemeKind::CatppuccinLatte | ThemeKind::CatppuccinFrappe | ThemeKind::CatppuccinMacchiato | ThemeKind::CatppuccinMocha => {
crate::theme_catppuccin::tokens(kind)
}
}
}
@@ -714,7 +741,15 @@ impl Tokens {
pub fn dark(&self) -> bool {
matches!(
self.kind,
ThemeKind::Studio | ThemeKind::Pro | ThemeKind::ProMedium | ThemeKind::SolarizedDark | ThemeKind::AdwaitaDark | ThemeKind::BreezeDark
ThemeKind::Studio
| ThemeKind::Pro
| ThemeKind::ProMedium
| ThemeKind::SolarizedDark
| ThemeKind::AdwaitaDark
| ThemeKind::BreezeDark
| ThemeKind::CatppuccinFrappe
| ThemeKind::CatppuccinMacchiato
| ThemeKind::CatppuccinMocha
)
}
}
+140
View File
@@ -0,0 +1,140 @@
//! Catppuccin Latte, Frappé, Macchiato and Mocha on the Studio layout. Palette: the Catppuccin
//! project's colours (https://catppuccin.com/palette, MIT; see LICENSE-catppuccin.txt), accent Mauve.
use egui::Color32;
use crate::theme::{ThemeKind, Tokens};
/// The Catppuccin colours these themes use, as 0xRRGGBB.
struct Palette {
text: u32,
subtext1: u32,
subtext0: u32,
overlay1: u32,
surface1: u32,
surface0: u32,
base: u32,
mantle: u32,
crust: u32,
mauve: u32,
red: u32,
yellow: u32,
}
const LATTE: Palette = Palette {
text: 0x4c4f69,
subtext1: 0x5c5f77,
subtext0: 0x6c6f85,
overlay1: 0x8c8fa1,
surface1: 0xbcc0cc,
surface0: 0xccd0da,
base: 0xeff1f5,
mantle: 0xe6e9ef,
crust: 0xdce0e8,
mauve: 0x8839ef,
red: 0xd20f39,
yellow: 0xdf8e1d,
};
const FRAPPE: Palette = Palette {
text: 0xc6d0f5,
subtext1: 0xb5bfe2,
subtext0: 0xa5adce,
overlay1: 0x838ba7,
surface1: 0x51576d,
surface0: 0x414559,
base: 0x303446,
mantle: 0x292c3c,
crust: 0x232634,
mauve: 0xca9ee6,
red: 0xe78284,
yellow: 0xe5c890,
};
const MACCHIATO: Palette = Palette {
text: 0xcad3f5,
subtext1: 0xb8c0e0,
subtext0: 0xa5adcb,
overlay1: 0x8087a2,
surface1: 0x494d64,
surface0: 0x363a4f,
base: 0x24273a,
mantle: 0x1e2030,
crust: 0x181926,
mauve: 0xc6a0f6,
red: 0xed8796,
yellow: 0xeed49f,
};
const MOCHA: Palette = Palette {
text: 0xcdd6f4,
subtext1: 0xbac2de,
subtext0: 0xa6adc8,
overlay1: 0x7f849c,
surface1: 0x45475a,
surface0: 0x313244,
base: 0x1e1e2e,
mantle: 0x181825,
crust: 0x11111b,
mauve: 0xcba6f7,
red: 0xf38ba8,
yellow: 0xf9e2af,
};
fn c(rgb: u32) -> Color32 {
Color32::from_rgb((rgb >> 16) as u8, (rgb >> 8) as u8, rgb as u8)
}
fn soft(rgb: u32, alpha: u8) -> Color32 {
Color32::from_rgba_unmultiplied((rgb >> 16) as u8, (rgb >> 8) as u8, rgb as u8, alpha)
}
/// Tokens for a Catppuccin kind. Any other kind falls back to Mocha (never reached: `for_kind` only routes these four here).
pub(crate) fn tokens(kind: ThemeKind) -> Tokens {
let (p, light) = match kind {
ThemeKind::CatppuccinLatte => (&LATTE, true),
ThemeKind::CatppuccinFrappe => (&FRAPPE, false),
ThemeKind::CatppuccinMacchiato => (&MACCHIATO, false),
_ => (&MOCHA, false),
};
// Dark flavours step up from the darkest surface; Latte steps down from the lightest.
let (canvas, chrome, dock, hover, pressed) =
if light { (p.crust, p.base, p.mantle, p.crust, p.surface0) } else { (p.base, p.mantle, p.crust, p.surface0, p.surface1) };
Tokens {
kind,
chrome: c(chrome),
canvas: c(canvas),
canvas_dot: c(p.surface0),
dock: c(dock),
card: c(chrome),
card_border: c(if light { p.surface0 } else { p.crust }),
field: c(dock),
field_border: c(p.surface1),
hover: c(hover),
pressed: c(pressed),
text: c(p.text),
text_dim: c(p.subtext0),
text_faint: c(p.overlay1),
icon: c(p.subtext1),
accent: c(p.mauve),
accent_soft: soft(p.mauve, if light { 40 } else { 46 }),
accent_border: soft(p.mauve, if light { 130 } else { 120 }),
accent_text: c(if light { p.mauve } else { p.text }),
separator: c(if light { p.surface0 } else { p.crust }),
shadow: Color32::from_black_alpha(if light { 45 } else { 150 }),
primary_bg: c(p.mauve),
primary_text: c(if light { p.base } else { p.crust }),
danger: c(p.red),
warning: c(p.yellow),
radius_sm: 6.0,
radius: 8.0,
radius_lg: 12.0,
bevel: false,
pro: false,
round_chips: true,
tab_strip: Color32::TRANSPARENT,
row_selected: Color32::TRANSPARENT,
histogram_bg: if light { Color32::from_gray(40) } else { c(p.base) },
histogram_level: if light { 240 } else { 225 },
caption_close: c(p.red),
caption_close_text: c(if light { p.base } else { p.crust }),
scrim: Color32::from_black_alpha(110),
}
}