diff --git a/src/aesthetics.rs b/src/aesthetics.rs index 0c6c627..d85a207 100644 --- a/src/aesthetics.rs +++ b/src/aesthetics.rs @@ -7,7 +7,7 @@ use crate::geom::{ AesFilter, AnyTag, Drag, GeomArrow, GeomHist, GeomMetabolite, HistPlot, HistTag, PopUp, Side, VisCondition, Xaxis, }; -use crate::gui::{or_color, UiState}; +use crate::gui::{or_color, ActiveData, UiState}; use itertools::Itertools; use std::collections::HashMap; @@ -31,6 +31,7 @@ impl Plugin for AesPlugin { .add_systems(Update, unscale_histogram_children) .add_systems(Update, fill_conditions) .add_systems(Update, filter_histograms) + .add_systems(Update, activate_settings) .add_systems(Update, follow_the_axes) // TODO: check since these were before load_map .add_systems(PostUpdate, (build_axes, build_hover_axes, build_point_axes)) @@ -854,3 +855,48 @@ fn follow_the_axes( } } } + +/// Set which data is actively plotted in the screen to show its corresponding +/// settings. +fn activate_settings( + ui_state: ResMut, + mut active_data: ResMut, + arrows: Query<(&Aesthetics, &Point), With>, + circles: Query<(&Aesthetics, &Point), With>, + hists: Query<(&Aesthetics, &GeomHist), With>>, +) { + active_data.arrow = arrows + .iter() + // this works because data without a condition should always be shown + .any(|(aes, _)| { + aes.condition + .as_ref() + .map(|c| c == &ui_state.condition) + .unwrap_or(true) + }); + active_data.circle = circles.iter().any(|(aes, _)| { + aes.condition + .as_ref() + .map(|c| c == &ui_state.condition) + .unwrap_or(true) + }); + ( + active_data.histogram.left, + active_data.histogram.right, + active_data.histogram.top, + ) = hists + .iter() + .filter(|(aes, _)| { + aes.condition + .as_ref() + .map(|c| c == &ui_state.condition) + .unwrap_or(true) + }) + .fold((false, false, false), |(left, right, top), (_, geom)| { + ( + left | (geom.side == Side::Left), + right | (geom.side == Side::Right), + top | (geom.side == Side::Up), + ) + }); +} diff --git a/src/gui.rs b/src/gui.rs index 7d950b4..79f5886 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -23,6 +23,7 @@ impl Plugin for GuiPlugin { .add_plugins(EguiPlugin) .insert_resource(UiState::default()) .insert_resource(AxisMode::Hide) + .insert_resource(ActiveData::default()) .add_event::() .add_systems(Update, ui_settings) .add_systems(Update, show_hover) @@ -180,6 +181,35 @@ impl UiState { } } +#[derive(Default)] +pub struct ActiveHists { + pub left: bool, + pub right: bool, + pub top: bool, +} + +#[derive(Default, Resource)] +/// Holds state about what data is being plotted, to then only show relevant +/// options in the Settings at [`ui_settings`]. +pub struct ActiveData { + pub arrow: bool, + pub circle: bool, + pub histogram: ActiveHists, +} + +impl ActiveData { + fn get(&self, key: &str) -> bool { + match key { + "Reaction" => self.arrow, + "Metabolite" => self.circle, + "left" => self.histogram.left, + "right" => self.histogram.right, + "top" => self.histogram.top, + _ => panic!("{key} should never be an ActiveData key!"), + } + } +} + #[derive(Event)] pub struct SaveEvent(String); @@ -188,6 +218,7 @@ pub struct SaveEvent(String); pub fn ui_settings( mut egui_context: EguiContexts, mut state: ResMut, + active_set: Res, mut save_events: EventWriter, mut load_events: EventWriter, mut screen_events: EventWriter, @@ -201,6 +232,9 @@ pub fn ui_settings( .into_iter() .cartesian_product(["min", "max"]) { + if !active_set.get(geom) { + continue; + } if "min" == ext { ui.label(format!("{geom} scale")); } @@ -215,6 +249,9 @@ pub fn ui_settings( if condition != "ALL" { ui.label("Histogram scale"); for side in ["left", "right", "top"] { + if !active_set.get(side) { + continue; + } ui.horizontal(|ui| { let (color, value) = state.get_geom_params_mut(side, &condition); color_edit_button_rgba(ui, color, Alpha::BlendOrAdditive); diff --git a/src/tests.rs b/src/tests.rs index b24a6cb..650bae8 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,6 +1,6 @@ use crate::aesthetics::{AesPlugin, Aesthetics, Distribution, Gy, Point, RestoreEvent, Unscale}; use crate::geom::{AesFilter, GeomHist, HistTag, Xaxis}; -use crate::gui::{file_drop, UiState}; +use crate::gui::{file_drop, ActiveData, UiState}; use crate::{data, escher, geom, info}; use bevy::prelude::*; use bevy_prototype_lyon::prelude::{GeometryBuilder, Path, PathBuilder, ShapeBundle, Stroke}; @@ -61,6 +61,7 @@ fn gy_dist_aes_spaws_xaxis_spawns_hist() { let asset_server = setup("assets"); app.insert_resource(asset_server); + app.insert_resource(ActiveData::default()); app.insert_resource(UiState::default()); app.add_plugins(AesPlugin); app.update(); @@ -123,6 +124,7 @@ fn point_dist_aes_spaws_box_axis_spawns_box() { )); app.insert_resource(UiState::default()); + app.insert_resource(ActiveData::default()); app.insert_resource(AssetServer::new(FileAssetIo::new("asset1", &None))); app.add_plugins(AesPlugin); app.update();