Pseudo pseudorandom color picker
This commit is contained in:
parent
8df3893baa
commit
218ee49a8b
7 changed files with 75 additions and 15 deletions
|
@ -15,4 +15,4 @@ toml = "0.9.5"
|
|||
slint-build = "1.12.1"
|
||||
|
||||
[profile.release]
|
||||
opt-level = "s"
|
||||
opt-level = 3
|
||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -1,5 +1,5 @@
|
|||
use config::Config;
|
||||
use std::path::PathBuf;
|
||||
use std::{hash::{DefaultHasher, Hash, Hasher}, path::PathBuf};
|
||||
|
||||
pub mod config;
|
||||
pub mod log;
|
||||
|
@ -13,3 +13,11 @@ 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.count_ones() / 4) as i32
|
||||
}
|
||||
|
|
17
src/main.rs
17
src/main.rs
|
@ -3,7 +3,7 @@
|
|||
|
||||
use std::{error::Error, rc::Rc, sync::{Arc, Mutex}};
|
||||
|
||||
use aliveline::{config::Config, load_config, log::{Event, Log}};
|
||||
use aliveline::{color_id_from_name, config::Config, load_config, log::{Event, Log}};
|
||||
use chrono::{Datelike, Timelike};
|
||||
use slint::{Model, ModelRc, SharedString, ToSharedString, VecModel, Weak};
|
||||
use toml::value::{Date as TomlDate, Time};
|
||||
|
@ -22,7 +22,8 @@ impl From<Event> for TimelineEvent {
|
|||
start,
|
||||
duration: end - start,
|
||||
label: event.name.to_shared_string(),
|
||||
finished: event.finished
|
||||
finished: event.finished,
|
||||
color_id: color_id_from_name(event.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,8 +144,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let event = TimelineEvent {
|
||||
duration: 0,
|
||||
finished: false,
|
||||
label: event_name,
|
||||
start: offset
|
||||
label: event_name.clone(),
|
||||
start: offset,
|
||||
color_id: color_id_from_name(event_name.to_string())
|
||||
};
|
||||
|
||||
{
|
||||
|
@ -177,8 +179,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
let new_event = TimelineEvent {
|
||||
duration: offset - event.start,
|
||||
finished: true,
|
||||
label: event.label,
|
||||
start: event.start
|
||||
label: event.label.clone(),
|
||||
start: event.start,
|
||||
color_id: color_id_from_name(event.label.to_string())
|
||||
};
|
||||
|
||||
{
|
||||
|
@ -215,7 +218,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||
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
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ export component AppWindow inherits Window {
|
|||
property<[string]> combo-spans: ["1 Hour", "4 Hours", "8 Hours", "24 Hours"];
|
||||
|
||||
title: "Aliveline";
|
||||
|
||||
TabWidget {
|
||||
Tab {
|
||||
title: "Record";
|
||||
|
|
|
@ -16,7 +16,6 @@ export component RecordWidget inherits VerticalBox {
|
|||
property<string> event-name: "";
|
||||
property<bool> minimized: false;
|
||||
property<int> combo-index: 0;
|
||||
|
||||
tl := Timeline {
|
||||
preferred-height: 100%;
|
||||
updating: true;
|
||||
|
|
43
ui/theme.slint
Normal file
43
ui/theme.slint
Normal file
|
@ -0,0 +1,43 @@
|
|||
export global Palette {
|
||||
in-out property<color> background: gray;
|
||||
in-out property<color> timeline: darkgray;
|
||||
in-out property<color> 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
|
||||
];
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
import { Palette } from "theme.slint";
|
||||
|
||||
export struct TimelineEvent {
|
||||
start: int,
|
||||
duration: int,
|
||||
finished: bool,
|
||||
label: string
|
||||
label: string,
|
||||
color-id: int
|
||||
}
|
||||
|
||||
global TimeString {
|
||||
|
@ -26,6 +29,7 @@ global TimeString {
|
|||
export component Timeline inherits Rectangle {
|
||||
callback new-day-started;
|
||||
callback clicked <=> ta.clicked;
|
||||
background: Palette.background;
|
||||
|
||||
in-out property<bool> updating: true;
|
||||
in-out property<[TimelineEvent]> events: [];
|
||||
|
@ -52,7 +56,6 @@ export component Timeline inherits Rectangle {
|
|||
preferred-height: 100%;
|
||||
}
|
||||
|
||||
background: gray;
|
||||
border-width: 1px;
|
||||
border-color: black;
|
||||
Rectangle {
|
||||
|
@ -63,19 +66,21 @@ export component Timeline inherits Rectangle {
|
|||
height: parent.height / 2;
|
||||
border-color: black;
|
||||
border-width: 1px;
|
||||
background: purple;
|
||||
background: Palette.timeline;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -91,13 +96,14 @@ export component Timeline inherits Rectangle {
|
|||
visible: self.width > 0 && self.real-x < parent.width;
|
||||
border-color: black;
|
||||
border-width: 1px;
|
||||
background: red;
|
||||
background: Palette.event-colors[event.color-id];
|
||||
|
||||
Text {
|
||||
x: 0;
|
||||
y: -self.height;
|
||||
text: event.label;
|
||||
visible: timeline-event.visible;
|
||||
color: Palette.background-text;
|
||||
}
|
||||
start-txt := Text {
|
||||
x: 0;
|
||||
|
@ -108,6 +114,7 @@ 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;
|
||||
|
@ -116,6 +123,7 @@ 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue