From 32bfbe158ab695c9258c13e6f32a619b780d8930 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 16 Aug 2022 18:06:43 +0200 Subject: stuff --- karlgui/src/edit.rs | 233 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 karlgui/src/edit.rs (limited to 'karlgui/src/edit.rs') diff --git a/karlgui/src/edit.rs b/karlgui/src/edit.rs new file mode 100644 index 0000000..d2f7150 --- /dev/null +++ b/karlgui/src/edit.rs @@ -0,0 +1,233 @@ +use std::ops::Range; + +use egui::{Color32, DragValue, RichText, Ui}; +use karlcommon::{Condition, Property, Schedule, Task}; + +pub struct ShowOrEdit { + pub inner: T, + pub edit: bool, +} + +impl ShowOrEdit { + pub fn new(inner: T, edit: bool) -> ShowOrEdit { + Self { inner, edit } + } + pub fn changed(&mut self, ui: &mut Ui) -> bool { + let changed = match self.edit { + true => { + if ui.button("💾 Save").clicked() { + self.edit = false; + true + } else { + false + } + } + false => { + if ui.button("✏ Edit").clicked() { + self.edit = true; + } + false + } + }; + self.inner.ui(ui, self.edit); + changed + } +} + +pub 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) = &mut self.description { + if edit { + ui.text_edit_singleline(d); + } else { + 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 => { + ui.label("No schedule"); + } + Schedule::Dynamic { + priority, + scheduled, + duration, + condition, + } => { + ui.horizontal(|ui| { + ui.label("Dynamic with priority"); + ui.label(&format!(" {} ", priority)); + }); + } + 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.group(|ui| match self { + Condition::Never => { + ui.label("never"); + } + Condition::From(c) => { + ui.horizontal(|ui| { + ui.label("Starting from"); + c.ui(ui, edit); + if edit { + ui.menu_button("✏ Change type", |ui| { + add_condition(ui, |d| *c = Box::new(d)) + }); + } + }); + } + Condition::Invert(c) => { + ui.horizontal(|ui| { + ui.label("not when"); + c.ui(ui, edit); + if edit { + ui.menu_button("✏ Change type", |ui| { + add_condition(ui, |d| *c = Box::new(d)) + }); + } + }); + } + Condition::Or(cs) => combine_condition(ui, edit, "or", cs), + Condition::And(cs) => combine_condition(ui, edit, "and", cs), + Condition::Equal { + prop, + value, + modulus: _, + } => { + ui.horizontal(|ui| { + ui.label("when"); + if edit { + egui::ComboBox::from_id_source(ui.id()) + .selected_text(prop.to_str()) + .show_ui(ui, |ui| { + for v in Property::VALUES { + ui.selectable_value(prop, *v, v.to_str()); + } + }); + } else { + ui.label(prop.to_str()); + } + ui.label("="); + if edit { + ui.add(DragValue::new(value)); + } else { + ui.label(&format!("{}", value)); + } + }); + } + Condition::Range { + prop, + min, + max, + modulus: _, + } => { + ui.horizontal(|ui| { + ui.label("when "); + ui.label(&format!("{}", min)); + ui.label("≤"); + ui.label(&format!("{:?}", prop)); + ui.label("<"); + ui.label(&format!("{}", max)) + }); + } + }); + } +} + +impl EditableWidget for Range { + fn ui(&mut self, ui: &mut Ui, edit: bool) { + ui.label("todo"); + } +} + +fn combine_condition(ui: &mut Ui, edit: bool, combinator: &str, cs: &mut Vec) { + ui.vertical(|ui| { + let mut remove = None; + for (i, c) in cs.iter_mut().enumerate() { + ui.push_id(i, |ui| { + ui.horizontal(|ui| { + ui.label(if i != 0 { combinator } else { "" }); + c.ui(ui, edit); + if edit { + if ui.button(RichText::from("🗑").color(Color32::RED)).clicked() { + remove = Some(i); + } + } + }); + }); + } + if edit { + ui.menu_button("➕ Add condition", |ui| { + add_condition(ui, |e| { + cs.push(e); + }) + }); + } + if let Some(remove) = remove { + cs.remove(remove); + } + }); +} + +fn add_condition(ui: &mut Ui, mut add: impl FnMut(Condition) -> ()) { + ui.menu_button("Combinators", |ui| { + if ui.button("And").clicked() { + add(Condition::And(vec![])) + } + if ui.button("Or").clicked() { + add(Condition::Or(vec![])) + } + }); + ui.menu_button("Constraints", |ui| { + if ui.button("Equal").clicked() { + add(Condition::Equal { + modulus: None, + prop: Property::Unix, + value: 0, + }) + } + if ui.button("Range").clicked() { + add(Condition::Range { + prop: Property::Unix, + min: 0, + max: 10, + modulus: None, + }) + } + if ui.button("Never").clicked() { + add(Condition::Never) + } + }); + ui.menu_button("Modifier", |ui| { + if ui.button("Invert").clicked() { + add(Condition::Invert(Box::new(Condition::Never))) + } + if ui.button("Starting from").clicked() { + add(Condition::From(Box::new(Condition::Never))) + } + }); +} -- cgit v1.2.3-70-g09d2