Skip to content

Commit

Permalink
Merge pull request #1 from alconley/tiles_dev
Browse files Browse the repository at this point in the history
Tiles dev
  • Loading branch information
alconley committed Jun 6, 2024
2 parents 0cfd8b0 + 817a1fb commit 28381fd
Show file tree
Hide file tree
Showing 27 changed files with 2,782 additions and 1,694 deletions.
38 changes: 31 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 10 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ authors = ["Alex Conley <[email protected]>"]
edition = "2021"
rust-version = "1.72"

[package.metadata.docs.rs]
all-features = true
targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"]

[dependencies]
egui = "0.27.0"
eframe = { version = "0.27.0", default-features = false, features = [
egui = "0.27.2"
eframe = { version = "0.27.2", default-features = false, features = [
"default_fonts", # Embed the default egui fonts.
"glow", # Use the glow rendering backend. Alternative: "wgpu".
"persistence", # Enable restoring app state when restarting the app.
Expand All @@ -18,11 +21,14 @@ log = "0.4"
# You only need serde if you want app persistence:
serde = { version = "1", features = ["derive"] }

egui_plot = {version = "0.27.2", features = ["serde"] }
egui_tiles = "0.8.0"
epaint = "0.27.2"

# native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
env_logger = "0.10"

egui_plot = {version = "0.27.2", features = ["serde"] }
polars = { version = "0.36", features = ["lazy", "parquet", "ndarray"] }
rfd = "0.13"
serde = { version = "1.0", features = ["derive"] }
Expand All @@ -46,12 +52,4 @@ opt-level = 2 # fast and small wasm
opt-level = 2


[patch.crates-io]

# If you want to use the bleeding edge version of egui and eframe:
# egui = { git = "https://github.com/emilk/egui", branch = "master" }
# eframe = { git = "https://github.com/emilk/egui", branch = "master" }

# If you fork https://github.com/emilk/egui you can test with:
# egui = { path = "../egui/crates/egui" }
# eframe = { path = "../egui/crates/eframe" }
[patch.crates-io]
222 changes: 171 additions & 51 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,81 +1,201 @@
use eframe::egui::{self};
use eframe::App;
use super::pane::Pane;
use super::tree::TreeBehavior;

use super::processer::Processer;
use super::workspacer::Workspacer;

#[derive(Default, serde::Deserialize, serde::Serialize)]
pub struct MUCApp {
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)] // if we add new fields, give them default values when deserializing old state
pub struct NATApp {
tree: egui_tiles::Tree<Pane>,

workspacer: Workspacer,
processer: Processer,
window: bool,

#[serde(skip)] // This how you opt-out of serialization of a field
behavior: TreeBehavior,

side_panel_open: bool,
}

impl MUCApp {
pub fn new(_cc: &eframe::CreationContext<'_>, window: bool) -> Self {
impl Default for NATApp {
fn default() -> Self {
let mut tiles = egui_tiles::Tiles::default();

let workspacer = Workspacer::new();
let processer = Processer::new();

let mut tabs = vec![];

Check failure on line 28 in src/app.rs

View workflow job for this annotation

GitHub Actions / Clippy

calls to `push` immediately after creation
tabs.push(tiles.insert_pane(Pane::Workspace(workspacer.clone())));

let root = tiles.insert_tab_tile(tabs);

let tree = egui_tiles::Tree::new("my_tree", root, tiles);

Self {
workspacer: Workspacer::new(),
processer: Processer::new(),
window,
tree,
workspacer,
processer,
behavior: Default::default(),
side_panel_open: false,
}
}
}

fn ui(&mut self, ui: &mut egui::Ui) {
egui::TopBottomPanel::top("plotter_top_panel").show_inside(ui, |ui| {
egui::menu::bar(ui, |ui| {
ui.menu_button("Workspace", |ui| {
self.workspacer.workspace_ui(ui);
});
impl NATApp {
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
// Load previous app state (if any).
// Note that you must enable the `persistence` feature for this to work.
if let Some(storage) = cc.storage {
return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
}

if !self.workspacer.selected_files.is_empty() {
self.processer.files = self.workspacer.selected_files.clone();
self.processer.calculation_ui(ui);
// ui.separator();
Default::default()
}

pub fn ui(&mut self, ui: &mut egui::Ui) {
self.tree.ui(&mut self.behavior, ui);
}

pub fn add_histograms_to_tree(&mut self) {
// let mut panes = self.processer.histogrammer.get_histogram1d_panes();

// panes.push(Pane::Workspace(self.workspacer.clone()));

// let tree = egui_tiles::Tree::new_grid("histograms", panes);

// if ui.button("Calculate histograms").clicked() {
// // add selected files to processer
// self.processer.files = self.workspacer.selected_files.clone();
// info!("Calculating histograms");
// self.tree = tree;

// self.processer.calculate_histograms();
// info!("Finished caluclating histograms");
// }
self.tree = self.processer.histogrammer.histogrammer_tree();

// let tabs: Vec<TileId> = vec![tiles.insert_pane(Pane { }), tiles.insert_pane(Pane { })];

// self.tree.tiles.insert_container(container);
}
}

impl eframe::App for NATApp {
/// Called by the frame work to save state before shutdown.
fn save(&mut self, storage: &mut dyn eframe::Storage) {
eframe::set_value(storage, eframe::APP_KEY, self);
}

// ui.separator();
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::TopBottomPanel::top("muc_top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| {
ui.checkbox(&mut self.side_panel_open, "Side Panel");

ui.separator();

if !self.workspacer.selected_files.borrow().is_empty() {
// Properly clone the shared state for processing
self.processer.files = self.workspacer.selected_files.borrow().clone();

Check failure on line 92 in src/app.rs

View workflow job for this annotation

GitHub Actions / Clippy

assigning the result of `Clone::clone()` may be inefficient
// self.processer.calculation_ui(ui);

if ui.button("Calculate Histograms").clicked() {
self.processer.calculate_histograms();
self.add_histograms_to_tree();
}
}
});
});

egui::SidePanel::right("plotter_right_panel").show_inside(ui, |ui| {
self.processer.select_histograms_ui(ui);
});
egui::SidePanel::left("tree")
.max_width(300.0)
.show_animated(ctx, self.side_panel_open, |ui| {
egui::global_dark_light_mode_buttons(ui);

ui.separator();

if self.workspacer.file_selecton {
egui::SidePanel::left("plotter_left_panel").show_inside(ui, |ui| {
self.workspacer.file_selection_ui_side_panel(ui);
if ui.button("Reset").clicked() {
*self = Default::default();
}
self.behavior.ui(ui);

ui.separator();

// ui.collapsing("Tree", |ui| {
// ui.style_mut().wrap = Some(false);
// let tree_debug = format!("{:#?}", self.tree);
// ui.monospace(&tree_debug);
// });

ui.separator();

ui.collapsing("Active tiles", |ui| {
let active = self.tree.active_tiles();
for tile_id in active {
use egui_tiles::Behavior as _;
let name = self.behavior.tab_title_for_tile(&self.tree.tiles, tile_id);
ui.label(format!("{} - {tile_id:?}", name.text()));
}
});

ui.separator();

if let Some(root) = self.tree.root() {
tree_ui(ui, &mut self.behavior, &mut self.tree.tiles, root);
}
});
}

egui::CentralPanel::default().show_inside(ui, |ui| {
self.processer.render_histos(ui);
egui::CentralPanel::default().show(ctx, |ui| {
self.tree.ui(&mut self.behavior, ui);
});
}
}

impl App for MUCApp {
fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
if self.window {
let mut size = ctx.screen_rect().size();
size.x -= 50.0; // Subtract 50 from the width
size.y -= 100.0; // Subtract 50 from the height
fn tree_ui(
ui: &mut egui::Ui,
behavior: &mut dyn egui_tiles::Behavior<Pane>,
tiles: &mut egui_tiles::Tiles<Pane>,
tile_id: egui_tiles::TileId,
) {
// Get the name BEFORE we remove the tile below!
let text = format!(
"{} - {tile_id:?}",
behavior.tab_title_for_tile(tiles, tile_id).text()
);

egui::Window::new("Plotter").max_size(size).show(ctx, |ui| {
self.ui(ui);
});
} else {
egui::CentralPanel::default().show(ctx, |ui| {
self.ui(ui);
});
// Temporarily remove the tile to circumvent the borrowchecker
let Some(mut tile) = tiles.remove(tile_id) else {
log::debug!("Missing tile {tile_id:?}");
return;
};

let default_open = false;
egui::collapsing_header::CollapsingState::load_with_default_open(
ui.ctx(),
egui::Id::new((tile_id, "tree")),
default_open,
)
.show_header(ui, |ui| {
ui.label(text);
let mut visible = tiles.is_visible(tile_id);
ui.checkbox(&mut visible, "Visible");
tiles.set_visible(tile_id, visible);
})
.body(|ui| match &mut tile {
egui_tiles::Tile::Pane(_) => {}
egui_tiles::Tile::Container(container) => {
let mut kind = container.kind();
egui::ComboBox::from_label("Kind")
.selected_text(format!("{kind:?}"))
.show_ui(ui, |ui| {
for typ in egui_tiles::ContainerKind::ALL {
ui.selectable_value(&mut kind, typ, format!("{typ:?}"))
.clicked();
}
});
if kind != container.kind() {
container.set_kind(kind);
}

for &child in container.children() {
tree_ui(ui, behavior, tiles, child);
}
}
}
});

// Put the tile back
tiles.insert(tile_id, tile);
}
Loading

0 comments on commit 28381fd

Please sign in to comment.