
This introduces a dependency on the Charming crate, which we use to plot the loss history, and the ECharts JavaScript library, which Charming depends on. Now that there's more than one canvas on the page, we have to pick out the display by ID rather than by element type in our style sheet.
70 lines
No EOL
1.6 KiB
Rust
70 lines
No EOL
1.6 KiB
Rust
mod add_remove;
|
|
mod assembly;
|
|
mod diagnostics;
|
|
mod display;
|
|
mod engine;
|
|
mod outline;
|
|
mod specified;
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
use std::{collections::BTreeSet, rc::Rc};
|
|
use sycamore::prelude::*;
|
|
|
|
use add_remove::AddRemove;
|
|
use assembly::{Assembly, Element};
|
|
use diagnostics::Diagnostics;
|
|
use display::Display;
|
|
use outline::Outline;
|
|
|
|
#[derive(Clone)]
|
|
struct AppState {
|
|
assembly: Assembly,
|
|
selection: Signal<BTreeSet<Rc<dyn Element>>>
|
|
}
|
|
|
|
impl AppState {
|
|
fn new() -> AppState {
|
|
AppState {
|
|
assembly: Assembly::new(),
|
|
selection: create_signal(BTreeSet::default())
|
|
}
|
|
}
|
|
|
|
// in single-selection mode, select the given element. in multiple-selection
|
|
// mode, toggle whether the given element is selected
|
|
fn select(&self, element: &Rc<dyn Element>, multi: bool) {
|
|
if multi {
|
|
self.selection.update(|sel| {
|
|
if !sel.remove(element) {
|
|
sel.insert(element.clone());
|
|
}
|
|
});
|
|
} else {
|
|
self.selection.update(|sel| {
|
|
sel.clear();
|
|
sel.insert(element.clone());
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// set the console error panic hook
|
|
#[cfg(feature = "console_error_panic_hook")]
|
|
console_error_panic_hook::set_once();
|
|
|
|
sycamore::render(|| {
|
|
provide_context(AppState::new());
|
|
|
|
view! {
|
|
div(id="sidebar") {
|
|
AddRemove {}
|
|
Outline {}
|
|
Diagnostics {}
|
|
}
|
|
Display {}
|
|
}
|
|
});
|
|
} |