From c59c4b0009eb0732e0376407e37bc9d2d1253039 Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 5 Nov 2022 03:28:51 +0100 Subject: [PATCH] feat: improved top panel, allow to reconnect during session --- src/gui/mod.rs | 29 +++++++++----- src/gui/panel.rs | 96 ++++++++++++++++++++++++++++++--------------- src/gui/scaffold.rs | 38 +++++++++--------- src/gui/source.rs | 39 ++++++------------ 4 files changed, 113 insertions(+), 89 deletions(-) diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 34d1c72..b5699e1 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -6,7 +6,7 @@ mod scaffold; use chrono::Utc; use eframe::egui::{CentralPanel, Context, SidePanel, TopBottomPanel, Window}; -use tokio::sync::watch; +use tokio::sync::{watch, mpsc}; use tracing::error; use crate::{data::entities, worker::{visualizer::AppStateView, BackgroundAction}}; @@ -21,7 +21,8 @@ use self::scaffold::{footer, EditingModel, popup_edit_ui}; pub struct App { view: AppStateView, - db_path: String, + db_uri: String, + db_uri_tx: mpsc::Sender, interval: i64, last_redraw: i64, @@ -31,19 +32,19 @@ pub struct App { // buffer_panel: entities::panels::Model, buffer_source: entities::sources::Model, - // buffer_metric: entities::metrics::Model, + buffer_metric: entities::metrics::Model, edit: bool, editing: Vec, sidebar: bool, - padding: bool, + _padding: bool, // windows: Vec>, } impl App { pub fn new( _cc: &eframe::CreationContext, - db_path: String, + db_uri_tx: mpsc::Sender, interval: i64, view: AppStateView, width_tx: watch::Sender, @@ -51,13 +52,15 @@ impl App { ) -> Self { let panels = view.panels.borrow().clone(); Self { - db_path, interval, panels, width_tx, view, logger_view, + db_uri_tx, interval, panels, width_tx, view, logger_view, + db_uri: "".into(), buffer_source: entities::sources::Model::default(), + buffer_metric: entities::metrics::Model::default(), last_redraw: 0, edit: false, editing: vec![], sidebar: true, - padding: false, + _padding: false, // windows: vec![], } } @@ -90,7 +93,7 @@ impl eframe::App for App { }); TopBottomPanel::bottom("footer").show(ctx, |ui| { - footer(ctx, ui, self.logger_view.clone(), self.db_path.clone(), self.view.points.borrow().len()); + footer(ctx, ui, self.logger_view.clone(), self.db_uri.clone(), self.view.points.borrow().len()); }); for m in self.editing.iter_mut() { @@ -101,7 +104,7 @@ impl eframe::App for App { if self.sidebar { SidePanel::left("sources-bar") - .width_range(if self.edit { 400.0..=1000.0 } else { 280.0..=680.0 }) + .width_range(280.0..=800.0) .default_width(if self.edit { 450.0 } else { 330.0 }) .show(ctx, |ui| source_panel(self, ui)); } @@ -110,7 +113,13 @@ impl eframe::App for App { main_content(self, ctx, ui); }); - if let Some(viewsize) = self.panels.iter().map(|p| p.view_size + p.view_offset).max() { + if let Some(viewsize) = + self.panels + .iter() + .chain(self.view.panels.borrow().iter()) + .map(|p| p.view_size + p.view_offset) + .max() + { if let Err(e) = self.width_tx.send(viewsize as i64) { error!(target: "app", "Could not update fetch size : {:?}", e); } diff --git a/src/gui/panel.rs b/src/gui/panel.rs index 36c08ea..c3b54dd 100644 --- a/src/gui/panel.rs +++ b/src/gui/panel.rs @@ -11,39 +11,33 @@ use crate::data::entities; use super::scaffold::EditingModel; pub fn main_content(app: &mut App, ctx: &Context, ui: &mut Ui) { - let mut _to_swap: Option = None; - let mut _to_delete: Option = None; + let metrics = app.view.metrics.borrow(); ScrollArea::vertical().show(ui, |ui| { - let panels = &mut app.panels; - let _panels_count = panels.len(); - let metrics = app.view.metrics.borrow(); - for (index, panel) in panels.iter_mut().enumerate() { - if index > 0 { - ui.separator(); // only show this if there is at least one panel + ui.separator(); + if app.edit { + for mut panel in app.panels.iter_mut() { + CollapsingState::load_with_default_open( + ctx, + ui.make_persistent_id(format!("panel-{}-compressable", panel.id)), + true, + ) + .show_header(ui, |ui| { + panel_title_ui_edit(ui, &mut panel, &mut app.editing, &app.view.metrics.borrow(), &app.view.panel_metric.borrow()); + }) + .body(|ui| panel_body_ui(ui, panel, &metrics, &app.view.points.borrow(), &app.view.panel_metric.borrow())); + } + } else { + for panel in app.view.panels.borrow().iter() { + CollapsingState::load_with_default_open( + ctx, + ui.make_persistent_id(format!("panel-{}-compressable", panel.id)), + true, + ) + .show_header(ui, |ui| { + panel_title_ui(ui, &panel); + }) + .body(|ui| panel_body_ui(ui, panel, &metrics, &app.view.points.borrow(), &app.view.panel_metric.borrow())); } - CollapsingState::load_with_default_open( - ctx, - ui.make_persistent_id(format!("panel-{}-compressable", panel.id)), - true, - ) - .show_header(ui, |ui| { - // if ui.small_button(" + ").clicked() { - // if index > 0 { - // to_swap = Some(index); // TODO kinda jank but is there a better way? - // } - // } - // if ui.small_button(" − ").clicked() { - // if index < panels_count - 1 { - // to_swap = Some(index + 1); // TODO kinda jank but is there a better way? - // } - // } - // if ui.small_button(" × ").clicked() { - // to_delete = Some(index); // TODO kinda jank but is there a better way? - // } - // ui.separator(); - panel_title_ui(ui, panel, &mut app.editing, &app.view.metrics.borrow(), &app.view.panel_metric.borrow()); - }) - .body(|ui| panel_body_ui(ui, panel, &metrics, &app.view.points.borrow(), &app.view.panel_metric.borrow())); } }); } @@ -56,6 +50,46 @@ pub fn _panel_edit_inline_ui(_ui: &mut Ui, _panel: &entities::panels::Model) { } pub fn panel_title_ui( + ui: &mut Ui, + panel: &entities::panels::Model, +) { // TODO make edit UI in separate func + ui.horizontal(|ui| { + ui.heading(panel.name.as_str()); + ui.with_layout(Layout::right_to_left(eframe::emath::Align::Min), |ui| { + ui.horizontal(|_ui| { + // TODO just show these, with no editing + // ui.toggle_value(&mut panel.view_scroll, "🔒"); + // ui.separator(); + // ui.add( + // DragValue::new(&mut panel.view_size) + // .speed(10) + // .suffix(" min") + // .clamp_range(0..=2147483647i32), + // ); + // ui.separator(); + // ui.add( + // DragValue::new(&mut panel.view_offset) + // .speed(10) + // .suffix(" min") + // .clamp_range(0..=2147483647i32), + // ); + // ui.separator(); + // if panel.reduce_view { + // ui.add( + // DragValue::new(&mut panel.view_chunks) + // .speed(1) + // .prefix("x") + // .clamp_range(1..=1000), // TODO allow to average larger spans maybe? + // ); + // ui.toggle_value(&mut panel.average_view, "avg"); + // } + // ui.toggle_value(&mut panel.reduce_view, "reduce"); + }); + }); + }); +} + +pub fn panel_title_ui_edit( ui: &mut Ui, panel: &mut entities::panels::Model, editing: &mut Vec, diff --git a/src/gui/scaffold.rs b/src/gui/scaffold.rs index c8f13f7..ff2e4a8 100644 --- a/src/gui/scaffold.rs +++ b/src/gui/scaffold.rs @@ -72,7 +72,7 @@ impl EditingModel { EditingModelType::EditingSource { source: _ } => "source", EditingModelType::EditingMetric { metric: _ } => "metric", }; - format!("edit_{}_{}", prefix, self.id) + format!("edit {} #{}", prefix, self.id) } pub fn should_fetch(&self) -> bool { @@ -200,7 +200,6 @@ pub fn popup_edit_ui( ) { match &mut model.m { EditingModelType::EditingPanel { panel, opts } => { - ui.heading(format!("Edit panel #{}", panel.id)); TextEdit::singleline(&mut panel.name) .hint_text("name") .show(ui); @@ -216,7 +215,6 @@ pub fn popup_edit_ui( } }, EditingModelType::EditingSource { source } => { - ui.heading(format!("Edit source #{}", source.id)); ui.horizontal(|ui| { ui.add(Checkbox::new(&mut source.enabled, "")); TextEdit::singleline(&mut source.name) @@ -233,7 +231,6 @@ pub fn popup_edit_ui( ui.add(Slider::new(&mut source.interval, 1..=3600).text("interval")); }, EditingModelType::EditingMetric { metric } => { - ui.heading(format!("Edit metric #{}", metric.id)); ui.horizontal(|ui| { let mut color_buf = unpack_color(metric.color); ui.color_edit_button_srgba(&mut color_buf); @@ -284,29 +281,30 @@ pub fn header(app: &mut App, ui: &mut Ui, frame: &mut Frame) { ui.separator(); ui.checkbox(&mut app.sidebar, "sources"); ui.separator(); - if ui.button("reset").clicked() { - app.panels = app.view.panels.borrow().clone(); - } - ui.separator(); - if ui.button("save").clicked() { - app.save_all_panels(); - } - ui.separator(); if ui.button("refresh").clicked() { app.refresh_data(); } - ui.separator(); - if ui.button("new panel").clicked() { - app.editing.push(entities::panels::Model::default().into()); + TextEdit::singleline(&mut app.db_uri) + .hint_text("db uri") + .show(ui); + if ui.button("connect").clicked() { + app.db_uri_tx.blocking_send(app.db_uri.clone()).unwrap(); // TODO!!! + app.refresh_data(); } ui.separator(); - if ui.button("new source").clicked() { - app.editing.push(entities::sources::Model::default().into()); + ui.checkbox(&mut app.edit, "edit"); + if app.edit { + if ui.button("reset").clicked() { + app.panels = app.view.panels.borrow().clone(); + } + if ui.button("save").clicked() { + app.save_all_panels(); + } + if ui.button("+").clicked() { + app.editing.push(entities::panels::Model::default().into()); + } } ui.separator(); - if ui.button("new metric").clicked() { - app.editing.push(entities::metrics::Model::default().into()); - } // ui.separator(); // ui.checkbox(&mut app.edit, "edit"); // if app.edit { diff --git a/src/gui/source.rs b/src/gui/source.rs index d5b539e..f380558 100644 --- a/src/gui/source.rs +++ b/src/gui/source.rs @@ -1,7 +1,4 @@ -use eframe::{ - egui::{Layout, ScrollArea, Ui, DragValue, TextEdit, Checkbox, Button}, - emath::Align, -}; +use eframe::egui::{ScrollArea, Ui, DragValue, TextEdit, Checkbox}; use crate::gui::App; use crate::data::entities; @@ -77,7 +74,9 @@ pub fn source_panel(app: &mut App, ui: &mut Ui) { ui.horizontal(|ui| { // 1 more for uncategorized sources ui.vertical(|ui| { ui.add_space(8.0); - ui.add_enabled(false, Button::new("#").small()); + if ui.small_button("+").clicked() { + app.editing.push(entities::sources::Model::default().into()); + } }); ui.vertical(|ui| { // actual sources list container ui.group(|ui| { @@ -110,33 +109,17 @@ pub fn source_panel(app: &mut App, ui: &mut Ui) { } }); } + // Add an empty metric to insert new ones + ui.horizontal(|ui| { + metric_edit_ui(ui, &mut app.buffer_metric); + if ui.small_button("+").clicked() { + app.editing.push(entities::metrics::Model::default().into()); + } + }); }); }); }); } - if app.edit { - ui.separator(); - ui.horizontal(|ui| { - ui.heading("new source"); - ui.with_layout(Layout::top_down(Align::RIGHT), |ui| { - ui.horizontal(|ui| { - if ui.button("add").clicked() { - // if let Err(e) = app.data.add_source(&app.input_source) { - // error!(target: "ui", "Error adding source : {:?}", e); - // } else { - // app.input_source.id += 1; - // } - } - ui.toggle_value(&mut app.padding, "#"); - }); - }); - }); - source_edit_ui(ui, &mut app.buffer_source); - ui.add_space(5.0); - if app.padding { - ui.add_space(300.0); - } - } }); //if let Some(i) = to_delete { // // TODO can this be done in background? idk