mirror of
https://git.alemi.dev/dashboard.git
synced 2024-11-22 15:34:54 +01:00
feat: made side panel resizable
also renamed some stuff and moved some settings around
This commit is contained in:
parent
8df10ec5ed
commit
66253fe900
3 changed files with 75 additions and 58 deletions
|
@ -1,8 +1,8 @@
|
||||||
use chrono::{Local, Utc};
|
use chrono::{Local, Utc};
|
||||||
use eframe::egui::{
|
use eframe::{egui::{
|
||||||
plot::{Corner, GridMark, Legend, Line, Plot},
|
plot::{Corner, GridMark, Legend, Line, Plot},
|
||||||
DragValue, Layout, Slider, Ui,
|
DragValue, Layout, Ui, Slider, TextEdit,
|
||||||
};
|
}, emath::Vec2};
|
||||||
|
|
||||||
use crate::app::{
|
use crate::app::{
|
||||||
data::source::{Panel, Source},
|
data::source::{Panel, Source},
|
||||||
|
@ -10,13 +10,13 @@ use crate::app::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn panel_edit_inline_ui(ui: &mut Ui, panel: &mut Panel) {
|
pub fn panel_edit_inline_ui(ui: &mut Ui, panel: &mut Panel) {
|
||||||
eframe::egui::TextEdit::singleline(&mut panel.name)
|
TextEdit::singleline(&mut panel.name)
|
||||||
.hint_text("name")
|
.hint_text("name")
|
||||||
.desired_width(50.0)
|
.desired_width(50.0)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panel_title_ui(ui: &mut Ui, panel: &mut Panel) {
|
pub fn panel_title_ui(ui: &mut Ui, panel: &mut Panel, extra: bool) {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.heading(panel.name.as_str());
|
ui.heading(panel.name.as_str());
|
||||||
ui.with_layout(Layout::right_to_left(), |ui| {
|
ui.with_layout(Layout::right_to_left(), |ui| {
|
||||||
|
@ -30,11 +30,12 @@ pub fn panel_title_ui(ui: &mut Ui, panel: &mut Panel) {
|
||||||
.clamp_range(0..=2147483647i32),
|
.clamp_range(0..=2147483647i32),
|
||||||
);
|
);
|
||||||
ui.checkbox(&mut panel.limit, "limit");
|
ui.checkbox(&mut panel.limit, "limit");
|
||||||
|
if extra {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.checkbox(&mut panel.timeserie, "timeserie");
|
ui.checkbox(&mut panel.timeserie, "timeserie");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.add(Slider::new(&mut panel.height, 0..=500).text("height"));
|
ui.add(Slider::new(&mut panel.height, 0..=500).text("height"));
|
||||||
ui.separator();
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -50,7 +51,7 @@ pub fn panel_body_ui(ui: &mut Ui, panel: &mut Panel, sources: &Vec<Source>) {
|
||||||
p = p.include_x(Utc::now().timestamp() as f64);
|
p = p.include_x(Utc::now().timestamp() as f64);
|
||||||
if panel.limit {
|
if panel.limit {
|
||||||
p = p
|
p = p
|
||||||
.set_margin_fraction(eframe::emath::Vec2 { x: 0.0, y: 0.1 })
|
.set_margin_fraction(Vec2 { x: 0.0, y: 0.1 })
|
||||||
.include_x((Utc::now().timestamp() + (panel.view_size as i64 * 3)) as f64);
|
.include_x((Utc::now().timestamp() + (panel.view_size as i64 * 3)) as f64);
|
||||||
}
|
}
|
||||||
if panel.limit {
|
if panel.limit {
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
use eframe::egui;
|
use eframe::egui::{Ui, TextEdit, ComboBox, Slider, DragValue};
|
||||||
use eframe::egui::Ui;
|
|
||||||
|
|
||||||
use crate::app::data::source::{Panel, Source};
|
use crate::app::data::source::{Panel, Source};
|
||||||
|
|
||||||
pub fn source_edit_inline_ui(ui: &mut Ui, source: &mut Source, panels: &Vec<Panel>) {
|
pub fn source_edit_inline_ui(ui: &mut Ui, source: &mut Source, panels: &Vec<Panel>) {
|
||||||
eframe::egui::TextEdit::singleline(&mut source.name)
|
TextEdit::singleline(&mut source.name)
|
||||||
.hint_text("name")
|
.hint_text("name")
|
||||||
.desired_width(50.0)
|
.desired_width(50.0)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
eframe::egui::TextEdit::singleline(&mut source.url)
|
TextEdit::singleline(&mut source.url)
|
||||||
.hint_text("url")
|
.hint_text("url")
|
||||||
.desired_width(160.0)
|
.desired_width(160.0)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
eframe::egui::TextEdit::singleline(&mut source.query_x)
|
TextEdit::singleline(&mut source.query_x)
|
||||||
.hint_text("x")
|
.hint_text("x")
|
||||||
.desired_width(30.0)
|
.desired_width(30.0)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
eframe::egui::TextEdit::singleline(&mut source.query_y)
|
TextEdit::singleline(&mut source.query_y)
|
||||||
.hint_text("y")
|
.hint_text("y")
|
||||||
.desired_width(30.0)
|
.desired_width(30.0)
|
||||||
.show(ui);
|
.show(ui);
|
||||||
egui::ComboBox::from_id_source("panel")
|
ComboBox::from_id_source("panel")
|
||||||
.selected_text(format!("panel [{}]", source.panel_id))
|
.selected_text(format!("panel [{}]", source.panel_id))
|
||||||
.width(70.0)
|
.width(70.0)
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
|
@ -29,36 +28,44 @@ pub fn source_edit_inline_ui(ui: &mut Ui, source: &mut Source, panels: &Vec<Pane
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ui.checkbox(&mut source.visible, "visible");
|
ui.checkbox(&mut source.visible, "visible");
|
||||||
ui.add(egui::Slider::new(&mut source.interval, 1..=60));
|
ui.add(Slider::new(&mut source.interval, 1..=60));
|
||||||
ui.color_edit_button_srgba(&mut source.color);
|
ui.color_edit_button_srgba(&mut source.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_ui(ui: &mut Ui, source: &mut Source, panels: &Vec<Panel>) {
|
pub fn source_edit_ui(ui: &mut Ui, source: &mut Source, panels: &Vec<Panel>, width: f32) {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
let text_width = width - 25.0;
|
||||||
ui.checkbox(&mut source.visible, "");
|
ui.checkbox(&mut source.visible, "");
|
||||||
eframe::egui::TextEdit::singleline(&mut source.name)
|
TextEdit::singleline(&mut source.name)
|
||||||
|
.desired_width(text_width / 4.0)
|
||||||
.hint_text("name")
|
.hint_text("name")
|
||||||
.desired_width(80.0)
|
|
||||||
.show(ui);
|
.show(ui);
|
||||||
eframe::egui::TextEdit::singleline(&mut source.url)
|
TextEdit::singleline(&mut source.url)
|
||||||
|
.desired_width(text_width * 3.0 / 4.0)
|
||||||
.hint_text("url")
|
.hint_text("url")
|
||||||
.desired_width(300.0)
|
|
||||||
.show(ui);
|
.show(ui);
|
||||||
});
|
});
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.add(egui::Slider::new(&mut source.interval, 1..=60));
|
let text_width : f32 ;
|
||||||
eframe::egui::TextEdit::singleline(&mut source.query_x)
|
if width > 400.0 {
|
||||||
|
ui.add(Slider::new(&mut source.interval, 1..=60));
|
||||||
|
text_width = width - 330.0
|
||||||
|
} else {
|
||||||
|
ui.add(DragValue::new(&mut source.interval).clamp_range(1..=60));
|
||||||
|
text_width = width - 220.0
|
||||||
|
}
|
||||||
|
TextEdit::singleline(&mut source.query_x)
|
||||||
|
.desired_width(text_width / 2.0)
|
||||||
.hint_text("x")
|
.hint_text("x")
|
||||||
.desired_width(50.0)
|
|
||||||
.show(ui);
|
.show(ui);
|
||||||
eframe::egui::TextEdit::singleline(&mut source.query_y)
|
TextEdit::singleline(&mut source.query_y)
|
||||||
|
.desired_width(text_width / 2.0)
|
||||||
.hint_text("y")
|
.hint_text("y")
|
||||||
.desired_width(50.0)
|
|
||||||
.show(ui);
|
.show(ui);
|
||||||
egui::ComboBox::from_id_source(format!("panel-{}", source.id))
|
ComboBox::from_id_source(format!("panel-{}", source.id))
|
||||||
|
.width(60.0)
|
||||||
.selected_text(format!("panel [{}]", source.panel_id))
|
.selected_text(format!("panel [{}]", source.panel_id))
|
||||||
.width(70.0)
|
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
for p in panels {
|
for p in panels {
|
||||||
ui.selectable_value(&mut source.panel_id, p.id, p.name.as_str());
|
ui.selectable_value(&mut source.panel_id, p.id, p.name.as_str());
|
||||||
|
|
|
@ -3,14 +3,18 @@ pub mod gui;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod worker;
|
pub mod worker;
|
||||||
|
|
||||||
use eframe::egui;
|
use eframe::egui::{
|
||||||
|
global_dark_light_mode_switch, CentralPanel, Context, Layout, ScrollArea, SidePanel,
|
||||||
|
TopBottomPanel, collapsing_header::CollapsingState,
|
||||||
|
};
|
||||||
|
use eframe::emath::Align;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use self::data::source::{Panel, Source};
|
use self::data::source::{Panel, Source};
|
||||||
use self::data::ApplicationState;
|
use self::data::ApplicationState;
|
||||||
use self::gui::panel::{panel_body_ui, panel_edit_inline_ui, panel_title_ui};
|
use self::gui::panel::{panel_body_ui, panel_edit_inline_ui, panel_title_ui};
|
||||||
use self::gui::source::{source_edit_inline_ui, source_ui};
|
use self::gui::source::{source_edit_inline_ui, source_edit_ui};
|
||||||
use self::util::human_size;
|
use self::util::human_size;
|
||||||
use self::worker::native_save;
|
use self::worker::native_save;
|
||||||
|
|
||||||
|
@ -33,10 +37,10 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &Context, frame: &mut eframe::Frame) {
|
||||||
egui::TopBottomPanel::top("heading").show(ctx, |ui| {
|
TopBottomPanel::top("heading").show(ctx, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
egui::widgets::global_dark_light_mode_switch(ui);
|
global_dark_light_mode_switch(ui);
|
||||||
ui.heading("dashboard");
|
ui.heading("dashboard");
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.checkbox(&mut self.edit, "edit");
|
ui.checkbox(&mut self.edit, "edit");
|
||||||
|
@ -67,7 +71,7 @@ impl eframe::App for App {
|
||||||
}
|
}
|
||||||
ui.separator();
|
ui.separator();
|
||||||
}
|
}
|
||||||
ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
|
ui.with_layout(Layout::top_down(Align::RIGHT), |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
if ui.small_button("×").clicked() {
|
if ui.small_button("×").clicked() {
|
||||||
frame.quit();
|
frame.quit();
|
||||||
|
@ -76,8 +80,8 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
egui::TopBottomPanel::bottom("footer").show(ctx, |ui| {
|
TopBottomPanel::bottom("footer").show(ctx, |ui| {
|
||||||
egui::collapsing_header::CollapsingState::load_with_default_open(
|
CollapsingState::load_with_default_open(
|
||||||
ctx,
|
ctx,
|
||||||
ui.make_persistent_id("footer-logs"),
|
ui.make_persistent_id("footer-logs"),
|
||||||
false,
|
false,
|
||||||
|
@ -93,7 +97,7 @@ impl eframe::App for App {
|
||||||
.read()
|
.read()
|
||||||
.expect("Filesize RwLock poisoned"),
|
.expect("Filesize RwLock poisoned"),
|
||||||
));
|
));
|
||||||
ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
|
ui.with_layout(Layout::top_down(Align::RIGHT), |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label(format!(
|
ui.label(format!(
|
||||||
"v{}-{}",
|
"v{}-{}",
|
||||||
|
@ -109,7 +113,7 @@ impl eframe::App for App {
|
||||||
})
|
})
|
||||||
.body(|ui| {
|
.body(|ui| {
|
||||||
ui.set_height(200.0);
|
ui.set_height(200.0);
|
||||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
ScrollArea::vertical().show(ui, |ui| {
|
||||||
let msgs = self
|
let msgs = self
|
||||||
.data
|
.data
|
||||||
.diagnostics
|
.diagnostics
|
||||||
|
@ -122,12 +126,16 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if self.edit {
|
if self.edit {
|
||||||
egui::SidePanel::left("sources-bar").show(ctx, |ui| {
|
SidePanel::left("sources-bar")
|
||||||
|
.width_range(240.0..=800.0)
|
||||||
|
.default_width(500.0)
|
||||||
|
.show(ctx, |ui| {
|
||||||
let mut sources = self.data.sources.write().expect("Sources RwLock poisoned");
|
let mut sources = self.data.sources.write().expect("Sources RwLock poisoned");
|
||||||
let panels = self.data.panels.read().expect("Panels RwLock poisoned");
|
let panels = self.data.panels.read().expect("Panels RwLock poisoned");
|
||||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
ScrollArea::vertical().show(ui, |ui| {
|
||||||
|
let width = ui.available_width();
|
||||||
for source in &mut *sources {
|
for source in &mut *sources {
|
||||||
source_ui(ui, source, &panels);
|
source_edit_ui(ui, source, &panels, width);
|
||||||
}
|
}
|
||||||
// TODO make this not necessary
|
// TODO make this not necessary
|
||||||
ui.collapsing("extra space", |ui| {
|
ui.collapsing("extra space", |ui| {
|
||||||
|
@ -138,8 +146,8 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let mut to_swap: Vec<usize> = Vec::new();
|
let mut to_swap: Vec<usize> = Vec::new();
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
CentralPanel::default().show(ctx, |ui| {
|
||||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
ScrollArea::vertical().show(ui, |ui| {
|
||||||
let mut panels = self.data.panels.write().expect("Panels RwLock poisoned"); // TODO only lock as write when editing
|
let mut panels = self.data.panels.write().expect("Panels RwLock poisoned"); // TODO only lock as write when editing
|
||||||
let panels_count = panels.len();
|
let panels_count = panels.len();
|
||||||
let sources = self.data.sources.read().expect("Sources RwLock poisoned"); // TODO only lock as write when editing
|
let sources = self.data.sources.read().expect("Sources RwLock poisoned"); // TODO only lock as write when editing
|
||||||
|
@ -147,7 +155,7 @@ impl eframe::App for App {
|
||||||
if index > 0 {
|
if index > 0 {
|
||||||
ui.separator();
|
ui.separator();
|
||||||
}
|
}
|
||||||
egui::collapsing_header::CollapsingState::load_with_default_open(
|
CollapsingState::load_with_default_open(
|
||||||
ctx,
|
ctx,
|
||||||
ui.make_persistent_id(format!("panel-{}-compressable", panel.id)),
|
ui.make_persistent_id(format!("panel-{}-compressable", panel.id)),
|
||||||
true,
|
true,
|
||||||
|
@ -164,8 +172,9 @@ impl eframe::App for App {
|
||||||
to_swap.push(index + 1); // TODO kinda jank but is there a better way?
|
to_swap.push(index + 1); // TODO kinda jank but is there a better way?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui.separator();
|
||||||
}
|
}
|
||||||
panel_title_ui(ui, panel);
|
panel_title_ui(ui, panel, self.edit);
|
||||||
})
|
})
|
||||||
.body(|ui| panel_body_ui(ui, panel, &sources));
|
.body(|ui| panel_body_ui(ui, panel, &sources));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue