WIP: Clean up the outline view #16

Closed
Vectornaut wants to merge 29 commits from outline-cleanup into main
Showing only changes of commit df6db983ba - Show all commits

View File

@ -1,7 +1,6 @@
use itertools::Itertools; use itertools::Itertools;
use sycamore::{prelude::*, web::tags::div}; use sycamore::{prelude::*, web::tags::div};
use web_sys::{ use web_sys::{
Element,
Event, Event,
HtmlInputElement, HtmlInputElement,
KeyboardEvent, KeyboardEvent,
@ -9,7 +8,7 @@ use web_sys::{
wasm_bindgen::JsCast wasm_bindgen::JsCast
}; };
use crate::{AppState, assembly::Constraint}; use crate::{AppState, assembly, assembly::Constraint};
// an editable view of the Lorentz product representing a constraint // an editable view of the Lorentz product representing a constraint
#[component(inline_props)] #[component(inline_props)]
@ -53,35 +52,9 @@ fn ConstraintOutlineItem(constraint_key: usize, element_key: usize) -> View {
} }
} }
// a component that lists the elements of the current assembly, showing the // a list item that shows an element in an outline view of an assembly
// constraints on each element as a collapsible sub-list. its implementation #[component(inline_props)]
// is based on Kate Morley's HTML + CSS tree views: fn ElementOutlineItem(key: usize, element: assembly::Element) -> View {
//
// https://iamkate.com/code/tree-views/
//
#[component]
pub fn Outline() -> View {
// sort the elements alphabetically by ID
let elements_sorted = create_memo(|| {
let state = use_context::<AppState>();
state.assembly.elements
.get_clone()
.into_iter()
.sorted_by_key(|(_, elt)| elt.id.clone())
.collect()
});
view! {
ul(
id="outline",
on:click={
let state = use_context::<AppState>();
move |_| state.selection.update(|sel| sel.clear())
}
) {
Keyed(
list=elements_sorted,
view=|(key, elt)| {
let state = use_context::<AppState>(); let state = use_context::<AppState>();
let class = create_memo({ let class = create_memo({
move || { move || {
@ -92,12 +65,12 @@ pub fn Outline() -> View {
} }
} }
}); });
let label = elt.label.clone(); let label = element.label.clone();
let rep_components = elt.rep.iter().map(|u| { let rep_components = element.rep.iter().map(|u| {
let u_coord = u.to_string().replace("-", "\u{2212}"); let u_coord = u.to_string().replace("-", "\u{2212}");
View::from(div().children(u_coord)) View::from(div().children(u_coord))
}).collect::<Vec<_>>(); }).collect::<Vec<_>>();
let constrained = elt.constraints.len() > 0; let constrained = element.constraints.len() > 0;
let details_node = create_node_ref(); let details_node = create_node_ref();
view! { view! {
li { li {
@ -125,13 +98,13 @@ pub fn Outline() -> View {
"ArrowRight" if constrained => { "ArrowRight" if constrained => {
let _ = details_node let _ = details_node
.get() .get()
.unchecked_into::<Element>() .unchecked_into::<web_sys::Element>()
.set_attribute("open", ""); .set_attribute("open", "");
}, },
"ArrowLeft" => { "ArrowLeft" => {
let _ = details_node let _ = details_node
.get() .get()
.unchecked_into::<Element>() .unchecked_into::<web_sys::Element>()
.remove_attribute("open"); .remove_attribute("open");
}, },
_ => () _ => ()
@ -170,7 +143,7 @@ pub fn Outline() -> View {
} }
ul(class="constraints") { ul(class="constraints") {
Keyed( Keyed(
list=elt.constraints.into_iter().collect::<Vec<_>>(), list=element.constraints.into_iter().collect::<Vec<_>>(),
view=move |cst_key| view! { view=move |cst_key| view! {
ConstraintOutlineItem( ConstraintOutlineItem(
constraint_key=cst_key, constraint_key=cst_key,
@ -183,6 +156,38 @@ pub fn Outline() -> View {
} }
} }
} }
}
// a component that lists the elements of the current assembly, showing the
// constraints on each element as a collapsible sub-list. its implementation
// is based on Kate Morley's HTML + CSS tree views:
//
// https://iamkate.com/code/tree-views/
//
#[component]
pub fn Outline() -> View {
// sort the elements alphabetically by ID
let elements_sorted = create_memo(|| {
let state = use_context::<AppState>();
state.assembly.elements
.get_clone()
.into_iter()
.sorted_by_key(|(_, elt)| elt.id.clone())
.collect()
});
view! {
ul(
id="outline",
on:click={
let state = use_context::<AppState>();
move |_| state.selection.update(|sel| sel.clear())
}
) {
Keyed(
list=elements_sorted,
view=|(key, elt)| view! {
ElementOutlineItem(key=key, element=elt)
}, },
key=|(key, elt)| ( key=|(key, elt)| (
key.clone(), key.clone(),