diff --git a/src/app.rs b/src/app.rs index 91d1a87..0e80d7a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -34,6 +34,7 @@ mod key_bind; pub mod localize; pub mod markdown; pub mod menu; +pub mod settings; pub struct App { core: Core, @@ -41,7 +42,7 @@ pub struct App { content: Content, details: Details, config_handler: Option, - config: config::Config, + config: config::CosmicTasksConfig, app_themes: Vec, context_page: ContextPage, key_binds: HashMap, @@ -109,7 +110,7 @@ pub enum DialogPage { #[derive(Clone, Debug)] pub struct Flags { pub config_handler: Option, - pub config: config::Config, + pub config: config::CosmicTasksConfig, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -222,7 +223,8 @@ impl App { .insert() .text(format!( "{} {}", - list.icon.clone() + list.icon + .clone() .unwrap_or(emojis::get_by_shortcode("pencil").unwrap().to_string()), list.name.clone() )) @@ -351,12 +353,10 @@ impl Application for App { .width(spacing.space_l) .height(spacing.space_l) .align_y(Vertical::Center) - .align_x(Horizontal::Center) + .align_x(Horizontal::Center), ) - .on_press(Message::DialogUpdate(DialogPage::Icon( - emoji.to_string(), - ))) - .into() + .on_press(Message::DialogUpdate(DialogPage::Icon(emoji.to_string()))) + .into() }) .collect(); let mut dialog = widget::dialog(fl!("icon-select")) @@ -371,13 +371,15 @@ impl Application for App { .control( widget::container(scrollable(widget::row::with_children(vec![ widget::flex_row(icon_buttons).into(), - horizontal_space(Length::Fixed(spacing.space_s as f32)).into() + horizontal_space(Length::Fixed(spacing.space_s as f32)).into(), ]))) - .height(Length::Fixed(300.0)), + .height(Length::Fixed(300.0)), ); if !icon.is_empty() { - dialog = dialog.icon(widget::container(widget::text(icon.as_str()).size(spacing.space_l))); + dialog = dialog.icon(widget::container( + widget::text(icon.as_str()).size(spacing.space_l), + )); } dialog @@ -826,10 +828,7 @@ impl Application for App { if let Some(list) = self.nav_model.active_data::() { let entity = self.nav_model.active(); let title = format!("{} {}", icon.clone(), list.name.clone()); - self.nav_model.text_set( - entity, - title, - ); + self.nav_model.text_set(entity, title); } if let Some(list) = self.nav_model.active_data_mut::() { list.icon = Some(icon); diff --git a/src/app/config.rs b/src/app/config.rs index 06f552d..4f9a7fe 100644 --- a/src/app/config.rs +++ b/src/app/config.rs @@ -1,24 +1,38 @@ -use crate::app; -use crate::app::icon_cache::{IconCache, ICON_CACHE}; -use crate::app::{App, Flags}; -use cosmic::app::Settings; -use cosmic::iced::{Limits, Size}; -use cosmic::widget::icon; +use crate::app::App; use cosmic::{ - cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, CosmicConfigEntry}, + cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Config, CosmicConfigEntry}, theme, Application, }; -use done_core::service::Services; use serde::{Deserialize, Serialize}; -use std::sync::Mutex; pub const CONFIG_VERSION: u64 = 1; #[derive(Clone, Default, Debug, Eq, PartialEq, Deserialize, Serialize, CosmicConfigEntry)] -pub struct Config { +pub struct CosmicTasksConfig { pub app_theme: AppTheme, } +impl CosmicTasksConfig { + pub fn config_handler() -> Option { + Config::new(App::APP_ID, CONFIG_VERSION).ok() + } + + pub fn config() -> CosmicTasksConfig { + match Self::config_handler() { + Some(config_handler) => { + let config = CosmicTasksConfig::get_entry(&config_handler).unwrap_or_else( + |(errs, config)| { + log::info!("errors loading config: {:?}", errs); + config + }, + ); + config + } + None => CosmicTasksConfig::default(), + } + } +} + #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] pub enum AppTheme { Dark, @@ -36,68 +50,3 @@ impl AppTheme { } } } - -pub fn get_icon(name: &'static str, size: u16) -> icon::Icon { - let mut icon_cache = ICON_CACHE.get().unwrap().lock().unwrap(); - icon_cache.get(name, size) -} - -pub fn config() -> (Settings, Flags) { - logger(); - app::localize::localize(); - icons(); - services(); - let settings = settings(); - let flags = flags(); - (settings, flags) -} - -pub fn flags() -> Flags { - let (config_handler, config) = get_config(); - - let flags = Flags { - config_handler, - config, - }; - flags -} - -pub fn settings() -> Settings { - let (_, config) = get_config(); - - let mut settings = Settings::default(); - settings = settings.theme(config.app_theme.theme()); - settings = settings.size_limits(Limits::NONE.min_width(400.0).min_height(180.0)); - settings = settings.size(Size::new(800.0, 800.0)); - settings = settings.debug(false); - settings -} - -pub fn get_config() -> (Option, Config) { - let (config_handler, config) = match cosmic_config::Config::new(App::APP_ID, CONFIG_VERSION) { - Ok(config_handler) => { - let config = Config::get_entry(&config_handler).unwrap_or_else(|(errs, config)| { - log::info!("errors loading config: {:?}", errs); - config - }); - (Some(config_handler), config) - } - Err(err) => { - log::error!("failed to create config handler: {}", err); - (None, Config::default()) - } - }; - (config_handler, config) -} - -pub fn logger() { - env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); -} - -pub fn icons() { - ICON_CACHE.get_or_init(|| Mutex::new(IconCache::new())); -} - -pub fn services() { - Services::init(App::APP_ID); -} diff --git a/src/app/icon_cache.rs b/src/app/icon_cache.rs index b325c98..7a927f6 100644 --- a/src/app/icon_cache.rs +++ b/src/app/icon_cache.rs @@ -60,7 +60,7 @@ impl IconCache { Self { cache } } - pub fn get(&mut self, name: &'static str, size: u16) -> icon::Icon { + fn get_icon(&mut self, name: &'static str, size: u16) -> icon::Icon { let handle = self .cache .entry(IconCacheKey { name, size }) @@ -68,4 +68,9 @@ impl IconCache { .clone(); icon::icon(handle).size(size) } + + pub fn get(name: &'static str, size: u16) -> icon::Icon { + let mut icon_cache = ICON_CACHE.get().unwrap().lock().unwrap(); + icon_cache.get_icon(name, size) + } } diff --git a/src/app/localize.rs b/src/app/localize.rs index 1bad586..7a53da6 100644 --- a/src/app/localize.rs +++ b/src/app/localize.rs @@ -37,7 +37,7 @@ pub fn localizer() -> Box { Box::from(DefaultLocalizer::new(&*LANGUAGE_LOADER, &Localizations)) } -pub fn localize() { +pub fn set_localization() { let localizer = localizer(); let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages(); diff --git a/src/app/settings.rs b/src/app/settings.rs new file mode 100644 index 0000000..6c4f7ec --- /dev/null +++ b/src/app/settings.rs @@ -0,0 +1,56 @@ +use crate::app::icon_cache::{IconCache, ICON_CACHE}; +use crate::app::{App, Flags}; +use cosmic::app::Settings; +use cosmic::iced::{Limits, Size}; +use cosmic::Application; +use done_core::service::Services; +use std::sync::Mutex; + +use super::config::CosmicTasksConfig; +use super::localize::set_localization; + +pub fn init() -> (Settings, Flags) { + set_localization(); + set_icon_cache(); + set_logger(); + start_services(); + let settings = get_app_settings(); + let flags = get_flags(); + (settings, flags) +} + +pub fn get_app_settings() -> Settings { + let config = CosmicTasksConfig::config(); + + let mut settings = Settings::default(); + settings = settings.theme(config.app_theme.theme()); + settings = settings.size_limits(Limits::NONE.min_width(400.0).min_height(180.0)); + settings = settings.size(Size::new(800.0, 800.0)); + settings = settings.debug(false); + settings +} + +pub fn set_logger() { + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); +} + +pub fn set_icon_cache() { + ICON_CACHE.get_or_init(|| Mutex::new(IconCache::new())); +} + +pub fn start_services() { + Services::init(App::APP_ID); +} + +pub fn get_flags() -> Flags { + let (config_handler, config) = ( + CosmicTasksConfig::config_handler(), + CosmicTasksConfig::config(), + ); + + let flags = Flags { + config_handler, + config, + }; + flags +} diff --git a/src/content.rs b/src/content.rs index 1e04e72..0b00717 100644 --- a/src/content.rs +++ b/src/content.rs @@ -1,4 +1,4 @@ -use crate::app::config; +use crate::app::icon_cache::IconCache; use cosmic::iced::alignment::{Horizontal, Vertical}; use cosmic::iced::{Alignment, Length, Subscription}; use cosmic::iced_widget::row; @@ -59,7 +59,7 @@ impl Content { fn list_header<'a>(&'a self, list: &'a List) -> Element<'a, Message> { let spacing = theme::active().cosmic().spacing; - let export_button = widget::button(config::get_icon("share-symbolic", 18)) + let export_button = widget::button(IconCache::get("share-symbolic", 18)) .style(theme::Button::Suggested) .padding(spacing.space_xxs) .on_press(Message::Export(self.tasks.values().cloned().collect())); @@ -99,12 +99,12 @@ impl Content { Message::Complete(id, value) }); - let delete_button = widget::button(config::get_icon("user-trash-full-symbolic", 18)) + let delete_button = widget::button(IconCache::get("user-trash-full-symbolic", 18)) .padding(space_xxs) .style(theme::Button::Destructive) .on_press(Message::Delete(id)); - let details_button = widget::button(config::get_icon("info-outline-symbolic", 18)) + let details_button = widget::button(IconCache::get("info-outline-symbolic", 18)) .padding(space_xxs) .style(theme::Button::Standard) .on_press(Message::Select(item.clone())); @@ -155,7 +155,7 @@ impl Content { let container = widget::container( widget::column::with_children(vec![ - config::get_icon("task-past-due-symbolic", 56).into(), + IconCache::get("task-past-due-symbolic", 56).into(), widget::text::title1(fl!("no-tasks")).into(), widget::text(fl!("no-tasks-suggestion")).into(), ]) @@ -183,7 +183,7 @@ impl Content { .on_submit(Message::AddTask) .width(Length::Fill) .into(), - widget::button(config::get_icon("mail-send-symbolic", 18)) + widget::button(IconCache::get("mail-send-symbolic", 18)) .padding(space_xxs) .style(theme::Button::Suggested) .on_press(Message::AddTask) @@ -283,7 +283,7 @@ impl Content { let Some(ref list) = self.list else { return widget::container( widget::column::with_children(vec![ - config::get_icon("applications-office-symbolic", 56).into(), + IconCache::get("applications-office-symbolic", 56).into(), widget::text::title1(fl!("no-list-selected")).into(), widget::text(fl!("no-list-suggestion")).into(), ]) diff --git a/src/details.rs b/src/details.rs index 189cd45..346e62b 100644 --- a/src/details.rs +++ b/src/details.rs @@ -1,4 +1,4 @@ -use crate::app::config; +use crate::app::icon_cache::IconCache; use chrono::{NaiveDate, TimeZone, Utc}; use cosmic::iced::{Alignment, Length}; use cosmic::iced_widget::row; @@ -51,17 +51,17 @@ impl Details { let priority_model = segmented_button::ModelBuilder::default() .insert(|entity| { entity - .icon(config::get_icon("flag-outline-thin-symbolic", 16)) + .icon(IconCache::get("flag-outline-thin-symbolic", 16)) .data(Priority::Low) }) .insert(|entity| { entity - .icon(config::get_icon("flag-outline-thick-symbolic", 16)) + .icon(IconCache::get("flag-outline-thick-symbolic", 16)) .data(Priority::Normal) }) .insert(|entity| { entity - .icon(config::get_icon("flag-filled-symbolic", 16)) + .icon(IconCache::get("flag-filled-symbolic", 16)) .data(Priority::High) }) .build(); @@ -200,11 +200,10 @@ impl Details { .on_input(move |title| Message::SetSubTaskTitle(id, title)) .on_submit(Message::SubTaskEditDone); - let delete_button = - widget::button(config::get_icon("user-trash-full-symbolic", 18)) - .padding(space_xxs) - .style(widget::button::Style::Destructive) - .on_press(Message::DeleteSubTask(id)); + let delete_button = widget::button(IconCache::get("user-trash-full-symbolic", 18)) + .padding(space_xxs) + .style(widget::button::Style::Destructive) + .on_press(Message::DeleteSubTask(id)); let row = widget::row::with_capacity(3) .align_items(Alignment::Center) @@ -300,7 +299,7 @@ impl Details { .on_submit(Message::AddTask) .width(Length::Fill) .into(), - widget::button(config::get_icon("mail-send-symbolic", 18)) + widget::button(IconCache::get("mail-send-symbolic", 18)) .padding(space_xxs) .on_press(Message::AddTask) .into(), diff --git a/src/main.rs b/src/main.rs index b112540..3e27070 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,7 @@ mod todo; #[rustfmt::skip] pub fn main() -> Result<(), Box> { - let (settings, flags) = app::config::config(); + let (settings, flags) = app::settings::init(); cosmic::app::run::(settings, flags)?; Ok(()) }