Application prototype #14

Merged
glen merged 101 commits from app-proto into main 2024-10-21 23:38:28 +00:00
2 changed files with 123 additions and 97 deletions
Showing only changes of commit 7709c61f71 - Show all commits

View File

@ -1,6 +1,5 @@
body { body {
margin-left: 20px; margin: 0px;
margin-top: 20px;
color: #fcfcfc; color: #fcfcfc;
background-color: #222; background-color: #222;
} }
@ -10,76 +9,72 @@ body {
#outline { #outline {
float: left; float: left;
width: 450px; width: 450px;
height: 750px; height: 100vh;
margin: 0px; margin: 0px;
padding: 8px; padding: 0px;
border: 1px solid #555; border-width: 0px 1px 0px 0px;
border-radius: 16px; border-style: solid;
box-sizing: border-box; border-color: #555;
overflow-y: scroll;
} }
li { summary {
list-style-type: none;
}
li:not(:last-child) {
margin-bottom: 8px;
}
.elt {
display: flex; display: flex;
padding: 3px; user-select: none;
background-color: #444;
border-radius: 8px;
} }
.elt.selected { summary.selected {
color: #fff; color: #fff;
background-color: #666; background-color: #444;
} }
.elt > .elt-label { summary > div, .cst {
padding-top: 4px;
padding-bottom: 4px;
}
.elt, .cst {
display: flex;
flex-grow: 1; flex-grow: 1;
padding: 2px 0px 2px 4px; padding-left: 8px;
padding-right: 8px;
} }
.elt > .elt-rep { .elt-switch {
width: 18px;
padding-left: 2px;
text-align: center;
}
details:has(li) .elt-switch::after {
content: '▸';
}
details[open]:has(li) .elt-switch::after {
content: '▾';
}
.elt-label {
flex-grow: 1;
}
.elt-rep {
display: flex; display: flex;
} }
.elt > .elt-rep > div { .elt-rep > div {
padding: 2px; padding: 2px 0px 0px 0px;
margin-left: 3px; font-size: 10pt;
text-align: center; text-align: center;
width: 60px; width: 56px;
background-color: #333;
}
.elt.selected > .elt-rep > div {
background-color: #555;
}
.elt-rep > div:first-child {
border-radius: 6px 0px 0px 6px;
}
.elt-rep > div:last-child {
border-radius: 0px 6px 6px 0px;
}
.constraints > li {
margin-top: 4px;
margin-bottom: 4px;
padding: 5px;
background-color: #444;
border-radius: 8px;
} }
/* display */ /* display */
canvas { canvas {
float: left; float: left;
margin-left: 16px; margin-left: 20px;
margin-top: 20px;
background-color: #020202; background-color: #020202;
border: 1px solid #555; border: 1px solid #555;
border-radius: 16px; border-radius: 16px;

View File

@ -1,6 +1,6 @@
use itertools::Itertools; use itertools::Itertools;
use sycamore::{prelude::*, web::tags::div}; use sycamore::{prelude::*, web::tags::div};
use web_sys::{KeyboardEvent, MouseEvent}; use web_sys::{Element, KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
use crate::AppState; use crate::AppState;
@ -31,9 +31,9 @@ pub fn Outline() -> View {
let class = create_memo({ let class = create_memo({
move || { move || {
if state.selection.with(|sel| sel.contains(&key)) { if state.selection.with(|sel| sel.contains(&key)) {
"elt selected" "selected"
} else { } else {
"elt" ""
} }
} }
}); });
@ -42,59 +42,90 @@ pub fn Outline() -> View {
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 details_node = create_node_ref();
view! { view! {
/* [TO DO] switch to integer-valued parameters whenever /* [TO DO] switch to integer-valued parameters whenever
that becomes possible again */ that becomes possible again */
li { li {
div( details(ref=details_node) {
class=class.get(), summary(
tabindex="0", class=class.get(),
on:click={ on:keydown={
move |event: MouseEvent| { move |event: KeyboardEvent| {
if event.shift_key() { match event.key().as_str() {
state.selection.update(|sel| { "Enter" => {
if !sel.remove(&key) { if event.shift_key() {
sel.insert(key); state.selection.update(|sel| {
} if !sel.remove(&key) {
}); sel.insert(key);
} else { }
state.selection.update(|sel| { });
sel.clear(); } else {
sel.insert(key); state.selection.update(|sel| {
}); sel.clear();
} sel.insert(key);
event.stop_propagation(); });
}
},
on:keydown={
move |event: KeyboardEvent| {
if event.key() == "Enter" {
if event.shift_key() {
state.selection.update(|sel| {
if !sel.remove(&key) {
sel.insert(key);
} }
}); event.prevent_default();
} else { },
state.selection.update(|sel| { "ArrowRight" if constrained => {
sel.clear(); let _ = details_node
sel.insert(key); .get()
}); .unchecked_into::<Element>()
.set_attribute("open", "");
},
"ArrowLeft" => {
let _ = details_node
.get()
.unchecked_into::<Element>()
.remove_attribute("open");
},
_ => ()
} }
event.prevent_default();
} }
} }
) {
div(
class="elt-switch",
on:click=|event: MouseEvent| event.stop_propagation()
)
div(
class="elt",
on:click={
move |event: MouseEvent| {
if event.shift_key() {
state.selection.update(|sel| {
if !sel.remove(&key) {
sel.insert(key);
}
});
} else {
state.selection.update(|sel| {
sel.clear();
sel.insert(key);
});
}
event.stop_propagation();
event.prevent_default();
}
}
) {
div(class="elt-label") { (label) }
div(class="elt-rep") { (rep_components) }
}
}
ul(class="constraints") {
Keyed(
list=elt.constraints.into_iter().collect::<Vec<_>>(),
view=|c_key: usize| view! {
li(class="cst") {
(c_key.to_string())
}
},
key=|c_key| c_key.clone()
)
} }
) {
div(class="elt-label") { (label) }
div(class="elt-rep") { (rep_components) }
}
ul(class="constraints") {
Keyed(
list=elt.constraints.into_iter().collect::<Vec<_>>(),
view=|c_key: usize| view! { li { (c_key.to_string()) } },
key=|c_key| c_key.clone()
)
} }
} }
} }