diff --git a/rust/cli/src/lib.rs b/rust/cli/src/lib.rs index 0ef72b3..56e5a85 100644 --- a/rust/cli/src/lib.rs +++ b/rust/cli/src/lib.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Context}; use clap::Parser; -use client::open_window; +use client::{generate_color_theme_sample, generate_theme_sample, open_window}; use management_client::start_management_client; use server::start; @@ -18,6 +18,8 @@ struct Cli { enum Commands { Open, Settings, + GenerateSampleTheme, + GenerateSampleColorTheme, } pub fn init() { @@ -46,6 +48,8 @@ pub fn init() { match command { Commands::Open => open_window(), Commands::Settings => start_management_client(), + Commands::GenerateSampleTheme => generate_theme_sample().expect("Unable to generate sample theme"), + Commands::GenerateSampleColorTheme => generate_color_theme_sample().expect("Unable to generate sample color theme") }; } } diff --git a/rust/client/src/lib.rs b/rust/client/src/lib.rs index d457514..7a11339 100644 --- a/rust/client/src/lib.rs +++ b/rust/client/src/lib.rs @@ -1,6 +1,8 @@ +use common::dirs::Dirs; use common::model::{BackendRequestData, BackendResponseData, UiRequestData, UiResponseData}; use common::rpc::backend_api::BackendApi; use utils::channel::{RequestReceiver, RequestSender}; +use crate::ui::GauntletTheme; pub(in crate) mod ui; pub(in crate) mod model; @@ -33,3 +35,39 @@ pub fn open_window() { } }) } + +pub fn generate_theme_sample() -> anyhow::Result<()> { + let dirs = Dirs::new(); + + let sample_theme_file = dirs.sample_theme_file(); + let theme_file = dirs.theme_file(); + + let theme = GauntletTheme::default_theme(GauntletTheme::default_color_theme()); + + let string = serde_json::to_string_pretty(&theme)?; + + std::fs::write(&sample_theme_file, string)?; + + println!("Created sample using default theme at {:?}", sample_theme_file); + println!("Make changes and rename file to {:?}", theme_file.file_name().unwrap()); + + Ok(()) +} + +pub fn generate_color_theme_sample() -> anyhow::Result<()> { + let dirs = Dirs::new(); + + let sample_theme_color_file = dirs.sample_theme_color_file(); + let theme_color_file = dirs.theme_color_file(); + + let theme = GauntletTheme::default_color_theme(); + + let string = serde_json::to_string_pretty(&theme)?; + + std::fs::write(&sample_theme_color_file, string)?; + + println!("Created sample using default color theme at {:?}", sample_theme_color_file); + println!("Make changes and rename file to {:?}", theme_color_file.file_name().unwrap()); + + Ok(()) +} \ No newline at end of file diff --git a/rust/client/src/ui/mod.rs b/rust/client/src/ui/mod.rs index 2e197b2..f6efd37 100644 --- a/rust/client/src/ui/mod.rs +++ b/rust/client/src/ui/mod.rs @@ -33,7 +33,7 @@ use utils::channel::{channel, RequestReceiver, RequestSender}; use crate::model::UiViewEvent; use crate::ui::inline_view_container::inline_view_container; use crate::ui::search_list::search_list; -use crate::ui::theme::{Element, GauntletTheme, ThemableWidget}; +use crate::ui::theme::{Element, ThemableWidget}; use crate::ui::theme::container::ContainerStyle; use crate::ui::theme::text_input::TextInputStyle; use crate::ui::view_container::view_container; @@ -47,6 +47,8 @@ mod client_context; mod widget_container; mod inline_view_container; +pub use theme::GauntletTheme; + pub struct AppModel { // logic backend_api: BackendForFrontendApi, diff --git a/rust/client/src/ui/theme/mod.rs b/rust/client/src/ui/theme/mod.rs index b8b6fdf..640387f 100644 --- a/rust/client/src/ui/theme/mod.rs +++ b/rust/client/src/ui/theme/mod.rs @@ -2,7 +2,7 @@ use std::io::ErrorKind; use std::path::PathBuf; use iced::{application, Color, Padding}; use serde::de::DeserializeOwned; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use serde_json::Error; use common::dirs::Dirs; @@ -26,7 +26,7 @@ pub type Element<'a, Message> = iced::Element<'a, Message, GauntletTheme>; const CURRENT_COLOR_THEME_VERSION: u64 = 1; const CURRENT_THEME_VERSION: u64 = 1; -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct GauntletColorTheme { version: u64, background_color: ThemeColor, @@ -42,7 +42,7 @@ pub struct GauntletColorTheme { date_picker_text_darker: ThemeColor } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct GauntletTheme { version: u64, text: ThemeColor, @@ -138,7 +138,7 @@ impl GauntletTheme { theme } - fn parse_file(theme_file: PathBuf, theme_name: &str) -> Option { + fn parse_file(theme_file: PathBuf, theme_name: &str) -> Option { match std::fs::read_to_string(theme_file) { Ok(value) => { let result = serde_json::from_str::(&value); @@ -194,7 +194,7 @@ impl GauntletTheme { } } - fn default_color_theme() -> GauntletColorTheme { + pub fn default_color_theme() -> GauntletColorTheme { GauntletColorTheme { version: CURRENT_COLOR_THEME_VERSION, background_color: BACKGROUND, @@ -211,7 +211,7 @@ impl GauntletTheme { } } - fn default_theme(color_theme: GauntletColorTheme) -> GauntletTheme { + pub fn default_theme(color_theme: GauntletColorTheme) -> GauntletTheme { let GauntletColorTheme { version: _, background_color, @@ -600,7 +600,7 @@ const fn padding_axis(vertical: f32, horizontal: f32) -> ThemePadding { } } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeButton { padding: ThemePadding, background_color: ThemeColor, @@ -612,7 +612,7 @@ pub struct ThemeButton { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeCheckbox { background_color_checked: ThemeColor, background_color_unchecked: ThemeColor, @@ -627,7 +627,7 @@ pub struct ThemeCheckbox { icon_color: ThemeColor } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeSelect { background_color: ThemeColor, background_color_hovered: ThemeColor, @@ -640,7 +640,7 @@ pub struct ThemeSelect { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeSelectMenu { background_color: ThemeColor, background_color_selected: ThemeColor, @@ -653,7 +653,7 @@ pub struct ThemeSelectMenu { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeTextField { background_color: ThemeColor, background_color_hovered: ThemeColor, @@ -669,12 +669,12 @@ pub struct ThemeTextField { border_color_hovered: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeSeparator { color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeScrollbar { color: ThemeColor, border_radius: f32, @@ -682,7 +682,7 @@ pub struct ThemeScrollbar { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeRoot { background_color: ThemeColor, border_radius: f32, @@ -690,7 +690,7 @@ pub struct ThemeRoot { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeActionShortcutModifier { padding: ThemePadding, spacing: f32, @@ -700,13 +700,13 @@ pub struct ThemeActionShortcutModifier { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeLink { text_color: ThemeColor, text_color_hovered: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeCode { padding: ThemePadding, background_color: ThemeColor, @@ -715,7 +715,7 @@ pub struct ThemeCode { border_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeDatePicker { background_color: ThemeColor, @@ -734,67 +734,68 @@ pub struct ThemeDatePicker { day_background_color_hovered: ThemeColor } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemePaddingTextColor { padding: ThemePadding, text_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemePaddingTextColorSize { padding: ThemePadding, text_color: ThemeColor, text_size: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemePaddingBackgroundColor { padding: ThemePadding, background_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeTooltip { padding: f32, // TODO for some reason padding on tooltip is a single number in iced-rs background_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemePaddingOnly { padding: ThemePadding, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeImage { padding: ThemePadding, border_radius: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemeTextColor { text_color: ThemeColor, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ThemePaddingSize { padding: ThemePadding, size: ExternalThemeSize, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExternalThemeGrid { padding: ThemePadding, spacing: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExternalThemeSize { width: f32, height: f32, } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] pub enum ThemePadding { Each { top: f32, @@ -843,7 +844,7 @@ impl ThemePadding { } -#[derive(Clone, Debug, Copy, Deserialize)] +#[derive(Clone, Debug, Copy, Serialize, Deserialize)] pub struct ThemeColor { r: u8, g: u8, diff --git a/rust/common/src/dirs.rs b/rust/common/src/dirs.rs index 8065771..96f3485 100644 --- a/rust/common/src/dirs.rs +++ b/rust/common/src/dirs.rs @@ -1,4 +1,3 @@ -use std::fs::File; use std::path::{Path, PathBuf}; use anyhow::Context; @@ -9,10 +8,6 @@ pub struct Dirs { inner: ProjectDirs } -impl Dirs { - -} - impl Dirs { pub fn new() -> Self { Self { @@ -58,6 +53,14 @@ impl Dirs { self.config_dir().join("color_theme.json") } + pub fn sample_theme_file(&self) -> PathBuf { + self.config_dir().join("theme.sample.json") + } + + pub fn sample_theme_color_file(&self) -> PathBuf { + self.config_dir().join("color_theme.sample.json") + } + pub fn config_dir(&self) -> PathBuf { let config_dir = if cfg!(feature = "release") || cfg!(feature = "scenario_runner") { self.inner.config_dir().to_path_buf()