diff options
author | metamuffin <yvchraiqi@protonmail.com> | 2022-08-16 16:11:57 +0200 |
---|---|---|
committer | metamuffin <yvchraiqi@protonmail.com> | 2022-08-16 16:11:57 +0200 |
commit | ea35ce0e6848c1224fa4c1cff424480a2996b49a (patch) | |
tree | e98781327e7f1dc0ae0eb6397b5aeb51e9bfa52e /karlgui/src/main.rs | |
parent | 0c12d22f53865fadf7f6eb17b44396663ddbf0e0 (diff) | |
download | karlender-ea35ce0e6848c1224fa4c1cff424480a2996b49a.tar karlender-ea35ce0e6848c1224fa4c1cff424480a2996b49a.tar.bz2 karlender-ea35ce0e6848c1224fa4c1cff424480a2996b49a.tar.zst |
lets make a gui anyway
Diffstat (limited to 'karlgui/src/main.rs')
-rw-r--r-- | karlgui/src/main.rs | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/karlgui/src/main.rs b/karlgui/src/main.rs new file mode 100644 index 0000000..f4f9696 --- /dev/null +++ b/karlgui/src/main.rs @@ -0,0 +1,169 @@ +pub mod client; + +use crate::client::Client; +use eframe::CreationContext; +use egui::{text::LayoutJob, CentralPanel, Color32, Response, TextFormat, Ui, Widget}; +use karlcommon::{socket_path, ClientboundPacket, Condition, Schedule, ServerboundPacket, Task}; +use log::{error, info}; +use std::{ + ops::{Deref, DerefMut, Range}, + os::unix::net::UnixStream, + process::exit, +}; + +fn main() { + env_logger::init(); + eframe::run_native( + "karlender", + eframe::NativeOptions::default(), + Box::new(move |cc| Box::new(App::new(cc))), + ) +} + +struct App { + client: Client, + tasks: Vec<ShowOrEdit<Task>>, +} + +impl App { + pub fn new(cc: &CreationContext) -> Self { + cc.egui_ctx.set_visuals(egui::Visuals::dark()); + + let socket = match UnixStream::connect(socket_path()) { + Ok(s) => s, + Err(e) => { + error!("failed to connect to socket: {}", e); + exit(1) + } + }; + + let mut client = Client::new(socket); + info!("connected"); + + client.send(ServerboundPacket::ListTasks); + App { + client, + tasks: vec![], + } + } + + pub fn update_network(&mut self) { + for p in self.client.receiver.try_iter() { + match p { + ClientboundPacket::TaskList(t) => { + self.tasks = t.into_iter().map(|t| ShowOrEdit::new(t, false)).collect() + } + _ => {} + } + } + } +} + +impl eframe::App for App { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + self.update_network(); + CentralPanel::default().show(ctx, |ui| { + for t in &mut self.tasks { + t.ui(ui); + ui.separator(); + } + }); + } +} + +struct ShowOrEdit<T> { + pub inner: T, + pub edit: bool, +} + +impl<T: EditableWidget> ShowOrEdit<T> { + pub fn new(inner: T, edit: bool) -> ShowOrEdit<T> { + Self { inner, edit } + } + pub fn ui(&mut self, ui: &mut Ui) { + match self.edit { + true => { + if ui.button("💾 Save").clicked() { + self.edit = false; + } + } + false => { + if ui.button("✏ Edit").clicked() { + self.edit = true; + } + } + } + self.inner.ui(ui, self.edit); + } +} + +trait EditableWidget { + fn ui(&mut self, ui: &mut Ui, edit: bool); +} + +impl EditableWidget for Task { + fn ui(&mut self, ui: &mut Ui, edit: bool) { + ui.heading(&self.name); + ui.indent((), |ui| { + if let Some(d) = &self.description { + ui.label(d); + } + ui.horizontal(|ui| { + ui.label("Tags:"); + for t in &self.tags { + ui.colored_label(Color32::LIGHT_GREEN, t); + } + }); + self.schedule.ui(ui, edit); + }); + } +} + +impl EditableWidget for Schedule { + fn ui(&mut self, ui: &mut Ui, edit: bool) { + match self { + Schedule::Never => { + let mut j = LayoutJob::default(); + j.append( + "No schedule", + 0.0, + TextFormat { + italics: true, + ..Default::default() + }, + ); + ui.label(j); + } + Schedule::Dynamic { + priority, + scheduled, + duration, + condition, + } => { + let mut j = LayoutJob::default(); + let f = TextFormat { + italics: true, + ..Default::default() + }; + j.append("Dynamic with priority", 0.0, f.clone()); + j.append(&format!(" {} ", priority), 0.0, f.clone()); + + ui.label(j); + } + Schedule::Condition(c) => c.ui(ui, edit), + Schedule::Static(t) => t.ui(ui, edit), + } + } +} + +impl EditableWidget for Condition { + fn ui(&mut self, ui: &mut Ui, edit: bool) { + ui.label("todo"); + } +} + +impl EditableWidget for Range<i64> { + fn ui(&mut self, ui: &mut Ui, edit: bool) { + ui.label("todo"); + } +} |