diff --git a/Cargo.toml b/Cargo.toml index 7675ffc..49e34c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,4 @@ toml = "0.9.5" slint-build = "1.12.1" [profile.release] -opt-level = 3 +opt-level = "s" diff --git a/src/config.rs b/src/config.rs index e1afe8d..68afdf0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,138 +2,23 @@ use std::path::PathBuf; use serde::Deserialize; #[derive(Deserialize)] -struct RawColors { - pub background: Option, - pub timeline: Option, - pub background_text: Option -} - -#[derive(Clone)] -pub struct Colors { - pub background: u32, - pub timeline: u32, - pub background_text: u32 -} - -impl Default for Colors { - fn default() -> Self { - Colors { - background: 0xff_808080, - timeline: 0xff_a9a9a9, - background_text: 0xff_000000 - } - } -} - -impl From for Colors { - fn from(value: RawColors) -> Self { - let default_colors: Colors = Default::default(); - Colors { - background: value.background.unwrap_or(default_colors.background), - timeline: value.timeline.unwrap_or(default_colors.timeline), - background_text: value.background_text.unwrap_or(default_colors.background_text), - } - } -} - -#[derive(Deserialize)] -struct RawConfig { - pub log_path: Option, - pub colors: Option, - pub event_colors: Option>, - pub text_colors: Option> -} - pub struct Config { /// directory, where config is located + #[serde(skip)] pub conf_path: PathBuf, - pub log_path: PathBuf, - pub colors: Colors, - pub event_colors: Vec, - pub text_colors: Vec -} - -impl Default for Config { - fn default() -> Self { - let conf_path = PathBuf::new(); - let colors: Colors = Default::default(); - let event_colors: Vec = vec![ - 0xff_97f9f9, - 0xff_a4def9, - 0xff_c1e0f7, - 0xff_cfbae1, - 0xff_c59fc9, - 0xff_4e3d42, - 0xff_c9d5b5, - 0xff_2d82b7, - 0xff_556f44, - 0xff_772e25, - 0xff_c44536, - 0xff_7c6a0a, - 0xff_babd8d, - 0xff_ffdac6, - 0xff_fa9500, - 0xff_eb6424 - ]; - let text_colors: Vec = vec![ - 0xff000000, - 0xff000000, - 0xff000000, - 0xff000000, - 0xff000000, - 0xffffffff, - 0xff000000, - 0xff000000, - 0xff000000, - 0xffffffff, - 0xff000000, - 0xff000000, - 0xff000000, - 0xff000000, - 0xff000000, - 0xff000000 - ]; - Config { - conf_path, - log_path: PathBuf::from("./logs"), - colors, - event_colors, - text_colors - } - } -} - -impl From for Config { - fn from(value: RawConfig) -> Self { - let default_config: Config = Default::default(); - let colors: Colors = match value.colors { - Some(raw_colors) => raw_colors.into(), - None => default_config.colors.clone() - }; - Config { - conf_path: default_config.conf_path, - log_path: value.log_path.unwrap_or(default_config.log_path), - colors, - event_colors: value.event_colors.unwrap_or(default_config.event_colors.clone()), - text_colors: value.text_colors.unwrap_or(default_config.text_colors.clone()) - } - } + pub log_path: PathBuf } impl Config { pub fn new(conf_path: PathBuf) -> Self { let conf_dir: PathBuf = conf_path.parent().unwrap().into(); - Config { - conf_path: conf_dir, - ..Default::default() - } + Config { conf_path: conf_dir, log_path: PathBuf::from("./logs") } } pub fn load(path: PathBuf) -> Self { if let Ok(toml_string) = std::fs::read_to_string(path.clone()) { - let conf = toml::from_str::(&toml_string); - if let Ok(raw_conf) = conf { - let mut conf: Config = raw_conf.into(); + let conf = toml::from_str::(&toml_string); + if let Ok(mut conf) = conf { conf.conf_path = path.parent().unwrap().into(); return conf; } diff --git a/src/lib.rs b/src/lib.rs index 7eb4df8..bdf3eb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ use config::Config; -use std::{hash::{DefaultHasher, Hash, Hasher}, path::PathBuf}; +use std::path::PathBuf; pub mod config; pub mod log; @@ -13,10 +13,3 @@ pub fn load_config() -> Config { } Config::new(PathBuf::from("./config.toml")) } - -/// Get random-like color id in range 0..16 by computing string hash -pub fn color_id_from_name(name: String) -> i32 { - let mut s = DefaultHasher::new(); - name.hash(&mut s); - let hash = s.finish(); - (hash % 16) as i32 } diff --git a/src/main.rs b/src/main.rs index 9b1c5a0..3285d0f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,9 +3,9 @@ use std::{error::Error, rc::Rc, sync::{Arc, Mutex}}; -use aliveline::{color_id_from_name, config::Config, load_config, log::{Event, Log}}; +use aliveline::{config::Config, load_config, log::{Event, Log}}; use chrono::{Datelike, Timelike}; -use slint::{Color, Model, ModelRc, SharedString, ToSharedString, VecModel, Weak}; +use slint::{Model, ModelRc, SharedString, ToSharedString, VecModel, Weak}; use toml::value::{Date as TomlDate, Time}; slint::include_modules!(); @@ -22,8 +22,7 @@ impl From for TimelineEvent { start, duration: end - start, label: event.name.to_shared_string(), - finished: event.finished, - color_id: color_id_from_name(event.name) + finished: event.finished } } } @@ -61,26 +60,6 @@ fn load_log(ui_weak: Weak, log: Arc>) { ui.set_in_progress(in_progress); } -fn load_colors(ui_weak: Weak, config: Arc) { - let ui = ui_weak.unwrap(); - let pal = ui.global::(); - pal.set_background(Color::from_argb_encoded(config.colors.background)); - pal.set_timeline(Color::from_argb_encoded(config.colors.timeline)); - pal.set_background_text(Color::from_argb_encoded(config.colors.background_text)); - - // This looks like war crime - let event_colors_rc: ModelRc = Rc::new(VecModel::from( - config.event_colors.iter() - .map(|value| Color::from_argb_encoded(*value)).collect::>() - )).into(); - pal.set_event_colors(event_colors_rc); - let event_text_rc: ModelRc = Rc::new(VecModel::from( - config.text_colors.iter() - .map(|value| Color::from_argb_encoded(*value)).collect::>() - )).into(); - pal.set_event_text(event_text_rc); -} - fn main() -> Result<(), Box> { let ui = AppWindow::new()?; @@ -100,10 +79,6 @@ fn main() -> Result<(), Box> { let log = writing_log.clone(); load_log(ui_weak, log); - let ui_weak = ui.as_weak(); - let config_arc = config.clone(); - load_colors(ui_weak, config_arc); - ui.invoke_update_record_offset(offset as i32); ui.on_fetch_log({ @@ -168,9 +143,8 @@ fn main() -> Result<(), Box> { let event = TimelineEvent { duration: 0, finished: false, - label: event_name.clone(), - start: offset, - color_id: color_id_from_name(event_name.to_string()) + label: event_name, + start: offset }; { @@ -203,9 +177,8 @@ fn main() -> Result<(), Box> { let new_event = TimelineEvent { duration: offset - event.start, finished: true, - label: event.label.clone(), - start: event.start, - color_id: color_id_from_name(event.label.to_string()) + label: event.label, + start: event.start }; { @@ -242,7 +215,7 @@ fn main() -> Result<(), Box> { let maybe_unfinished_event = log_guard.events.iter().find(|event| !event.finished); match maybe_unfinished_event { Some(unfinished_event) => Some(Event::new(unfinished_event.name.clone(), 0, 0, false)), - _ => None + None => None } }; diff --git a/ui/app-window.slint b/ui/app-window.slint index 7535149..373e060 100644 --- a/ui/app-window.slint +++ b/ui/app-window.slint @@ -2,7 +2,6 @@ import { TabWidget } from "std-widgets.slint"; import { RecordWidget } from "record.slint"; import { ReviewWidget } from "review.slint"; import { TimelineEvent } from "timeline.slint"; -export { Palette } from "theme.slint"; export component AppWindow inherits Window { callback start-new-event <=> record.start-new-event; @@ -32,6 +31,7 @@ export component AppWindow inherits Window { property<[string]> combo-spans: ["1 Hour", "4 Hours", "8 Hours", "24 Hours"]; title: "Aliveline"; + TabWidget { Tab { title: "Record"; diff --git a/ui/record.slint b/ui/record.slint index 4d7090c..1dff7b4 100644 --- a/ui/record.slint +++ b/ui/record.slint @@ -16,6 +16,7 @@ export component RecordWidget inherits VerticalBox { property event-name: ""; property minimized: false; property combo-index: 0; + tl := Timeline { preferred-height: 100%; updating: true; diff --git a/ui/theme.slint b/ui/theme.slint deleted file mode 100644 index 30b211a..0000000 --- a/ui/theme.slint +++ /dev/null @@ -1,43 +0,0 @@ -export global Palette { - in-out property background: gray; - in-out property timeline: darkgray; - in-out property background-text: black; - // Note: these colors were almost randomly picked - in-out property<[color]> event-colors: [ - #97f9f9, - #a4def9, - #c1e0f7, - #cfbae1, - #c59fc9, - #4e3d42, - #c9d5b5, - #2d82b7, - #556f44, - #772e25, - #c44536, - #7c6a0a, - #babd8d, - #ffdac6, - #fa9500, - #eb6424 - ]; - - in-out property <[color]> event-text: [ - #000000, - #000000, - #000000, - #000000, - #000000, - #ffffff, - #000000, - #000000, - #000000, - #ffffff, - #000000, - #000000, - #000000, - #000000, - #000000, - #000000 - ]; -} diff --git a/ui/timeline.slint b/ui/timeline.slint index 2e9db7f..c9fef81 100644 --- a/ui/timeline.slint +++ b/ui/timeline.slint @@ -1,11 +1,8 @@ -import { Palette } from "theme.slint"; - export struct TimelineEvent { start: int, duration: int, finished: bool, - label: string, - color-id: int + label: string } global TimeString { @@ -29,7 +26,6 @@ global TimeString { export component Timeline inherits Rectangle { callback new-day-started; callback clicked <=> ta.clicked; - background: Palette.background; in-out property updating: true; in-out property<[TimelineEvent]> events: []; @@ -56,6 +52,7 @@ export component Timeline inherits Rectangle { preferred-height: 100%; } + background: gray; border-width: 1px; border-color: black; Rectangle { @@ -66,21 +63,19 @@ export component Timeline inherits Rectangle { height: parent.height / 2; border-color: black; border-width: 1px; - background: Palette.timeline; + background: purple; } Text { x: 0; y: parent.height - self.height; text: TimeString.from(visible-offset - visible-time); - color: Palette.background-text; } Text { x: parent.width - self.width; y: parent.height - self.height; text: TimeString.from(visible-offset); - color: Palette.background-text; } for event in events: timeline-event := Rectangle { @@ -96,14 +91,13 @@ export component Timeline inherits Rectangle { visible: self.width > 0 && self.real-x < parent.width; border-color: black; border-width: 1px; - background: Palette.event-colors[event.color-id]; + background: red; Text { x: 0; y: -self.height; text: event.label; visible: timeline-event.visible; - color: Palette.background-text; } start-txt := Text { x: 0; @@ -114,7 +108,6 @@ export component Timeline inherits Rectangle { visible: timeline-event.visible && (self.width * 2 < timeline-event.width || (!end-txt.visible && self.width < timeline-event.width)); - color: Palette.event-text[event.color-id]; } end-txt := Text { x: timeline-event.width - self.width; @@ -123,7 +116,6 @@ export component Timeline inherits Rectangle { TimeString.from(event.start + event.duration) : TimeString.from(visible-offset); visible: timeline-event.visible && timeline-event.width - self.width * 2 > 0; - color: Palette.event-text[event.color-id]; } } @children