use std::rc::Rc; use sycamore::prelude::*; use super::test_assembly_chooser::TestAssemblyChooser; use crate::{ AppState, assembly::{InversiveDistanceRegulator, Point, Sphere}, }; #[component] pub fn AddRemove() -> View { view! { div(id="add-remove") { button( on:click=|_| { let state = use_context::(); batch(|| { // this call is batched to avoid redundant realizations. // it updates the element list and the regulator list, // which are both tracked by the realization effect /* TO DO */ // it would make more to do the batching inside // `insert_element_default`, but that will have to wait // until Sycamore handles nested batches correctly. // // https://github.com/sycamore-rs/sycamore/issues/802 // // the nested batch issue is relevant here because the // assembly loaders in the test assembly chooser use // `insert_element_default` within larger batches state.assembly.insert_element_default::(); }); } ) { "Add sphere" } button( on:click=|_| { let state = use_context::(); state.assembly.insert_element_default::(); } ) { "Add point" } button( class="emoji", /* KLUDGE */ // for convenience, we're using an emoji as a temporary icon for this button disabled={ let state = use_context::(); state.selection.with(|sel| sel.len() != 2) }, on:click=|_| { let state = use_context::(); let subjects: [_; 2] = state.selection.with( // the button is only enabled when two elements are // selected, so we know the cast to a two-element array // will succeed |sel| sel .clone() .into_iter() .collect::>() .try_into() .unwrap() ); state.assembly.insert_regulator( Rc::new(InversiveDistanceRegulator::new(subjects)) ); state.selection.update(|sel| sel.clear()); } ) { "🔗" } TestAssemblyChooser {} } } }