diff --git a/app-proto/sketch-outline/main.css b/app-proto/sketch-outline/main.css index 9e8cdb4..cd7bc44 100644 --- a/app-proto/sketch-outline/main.css +++ b/app-proto/sketch-outline/main.css @@ -26,7 +26,7 @@ li { border-radius: 8px; } -li:focus { +li.selected { color: #fff; background-color: #666; } @@ -52,7 +52,7 @@ li > .elt-rep > div { background-color: #333; } -li:focus > .elt-rep > div { +li.selected > .elt-rep > div { background-color: #555; } diff --git a/app-proto/sketch-outline/src/assembly.rs b/app-proto/sketch-outline/src/assembly.rs index b53e38d..dded2a1 100644 --- a/app-proto/sketch-outline/src/assembly.rs +++ b/app-proto/sketch-outline/src/assembly.rs @@ -7,6 +7,10 @@ pub struct Element { pub label: String, pub color: [f32; 3], pub rep: DVector, + + /* TO DO */ + // does this belong in the element data? + pub selected: Signal } // a complete, view-independent description of an assembly diff --git a/app-proto/sketch-outline/src/display.rs b/app-proto/sketch-outline/src/display.rs index f3804f6..70beacf 100644 --- a/app-proto/sketch-outline/src/display.rs +++ b/app-proto/sketch-outline/src/display.rs @@ -101,6 +101,11 @@ pub fn Display() -> View { // change listener let scene_changed = create_signal(true); + create_effect(move || { + let elements = state.assembly.elements.get_clone(); + for elt in elements { elt.selected.track(); } + scene_changed.set(true); + }); /* INSTRUMENTS */ const SAMPLE_PERIOD: i32 = 60; @@ -284,7 +289,13 @@ pub fn Display() -> View { let elements = state.assembly.elements.get_clone(); let element_iter = (&elements).into_iter(); let reps_world: Vec<_> = element_iter.clone().map(|elt| &assembly_to_world * &elt.rep).collect(); - let colors: Vec<_> = element_iter.map(|elt| elt.color).collect(); + let colors: Vec<_> = element_iter.map(|elt| + if elt.selected.get() { + elt.color.map(|ch| 0.5 + 0.5*ch) + } else { + elt.color + } + ).collect(); // set the resolution let width = canvas.width() as f32; diff --git a/app-proto/sketch-outline/src/main.rs b/app-proto/sketch-outline/src/main.rs index ee7682a..06cc43d 100644 --- a/app-proto/sketch-outline/src/main.rs +++ b/app-proto/sketch-outline/src/main.rs @@ -24,19 +24,22 @@ fn main() { id: String::from("wing_a"), label: String::from("Wing A"), color: [1.00_f32, 0.25_f32, 0.00_f32], - rep: DVector::::from_column_slice(&[0.5, 0.5, 0.0, 0.5, -0.25]) + rep: DVector::::from_column_slice(&[0.5, 0.5, 0.0, 0.5, -0.25]), + selected: create_signal(false) }, Element { id: String::from("wing_b"), label: String::from("Wing B"), color: [0.00_f32, 0.25_f32, 1.00_f32], - rep: DVector::::from_column_slice(&[-0.5, -0.5, 0.0, 0.5, -0.25]) + rep: DVector::::from_column_slice(&[-0.5, -0.5, 0.0, 0.5, -0.25]), + selected: create_signal(false) }, Element { id: String::from("central"), label: String::from("Central"), color: [0.75_f32, 0.75_f32, 0.75_f32], - rep: DVector::::from_column_slice(&[0.0, 0.0, 0.0, 0.4, -0.625]) + rep: DVector::::from_column_slice(&[0.0, 0.0, 0.0, 0.4, -0.625]), + selected: create_signal(false) } ]) } diff --git a/app-proto/sketch-outline/src/outline.rs b/app-proto/sketch-outline/src/outline.rs index 546b272..5d650b3 100644 --- a/app-proto/sketch-outline/src/outline.rs +++ b/app-proto/sketch-outline/src/outline.rs @@ -1,5 +1,6 @@ use itertools::Itertools; use sycamore::{prelude::*, web::tags::div}; +use web_sys::KeyboardEvent; use crate::AppState; @@ -21,6 +22,9 @@ pub fn Outline() -> View { Keyed( list=elements_sorted, view=|elt| { + let class = create_memo(move || + if elt.selected.get() { "selected" } else { "" } + ); let label = elt.label.clone(); let rep_components = elt.rep.iter().map(|u| { let u_coord = u.to_string().replace("-", "\u{2212}"); @@ -29,7 +33,19 @@ pub fn Outline() -> View { view! { /* [TO DO] switch to integer-valued parameters whenever that becomes possible again */ - li(tabindex="0") { + li( + class=class.get(), + tabindex="0", + on:click=move |_| { + elt.selected.set_fn(|sel| !sel); + }, + on:keydown=move |event: KeyboardEvent| { + if event.key() == "Enter" { + elt.selected.set_fn(|sel| !sel); + event.prevent_default(); + } + } + ) { div(class="elt-label") { (label) } div(class="elt-rep") { (rep_components) } }