Application prototype #14
@ -1,6 +1,5 @@
|
||||
body {
|
||||
margin-left: 20px;
|
||||
margin-top: 20px;
|
||||
margin: 0px;
|
||||
color: #fcfcfc;
|
||||
background-color: #222;
|
||||
}
|
||||
@ -10,76 +9,72 @@ body {
|
||||
#outline {
|
||||
float: left;
|
||||
width: 450px;
|
||||
height: 750px;
|
||||
height: 100vh;
|
||||
margin: 0px;
|
||||
padding: 8px;
|
||||
border: 1px solid #555;
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
padding: 0px;
|
||||
border-width: 0px 1px 0px 0px;
|
||||
border-style: solid;
|
||||
border-color: #555;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li:not(:last-child) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.elt {
|
||||
summary {
|
||||
display: flex;
|
||||
padding: 3px;
|
||||
background-color: #444;
|
||||
border-radius: 8px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.elt.selected {
|
||||
summary.selected {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
.elt > .elt-rep > div {
|
||||
padding: 2px;
|
||||
margin-left: 3px;
|
||||
.elt-rep > div {
|
||||
padding: 2px 0px 0px 0px;
|
||||
font-size: 10pt;
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
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;
|
||||
width: 56px;
|
||||
}
|
||||
|
||||
/* display */
|
||||
|
||||
canvas {
|
||||
float: left;
|
||||
margin-left: 16px;
|
||||
margin-left: 20px;
|
||||
margin-top: 20px;
|
||||
background-color: #020202;
|
||||
border: 1px solid #555;
|
||||
border-radius: 16px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use itertools::Itertools;
|
||||
use sycamore::{prelude::*, web::tags::div};
|
||||
use web_sys::{KeyboardEvent, MouseEvent};
|
||||
use web_sys::{Element, KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
@ -31,9 +31,9 @@ pub fn Outline() -> View {
|
||||
let class = create_memo({
|
||||
move || {
|
||||
if state.selection.with(|sel| sel.contains(&key)) {
|
||||
"elt selected"
|
||||
"selected"
|
||||
} else {
|
||||
"elt"
|
||||
""
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -42,13 +42,56 @@ pub fn Outline() -> View {
|
||||
let u_coord = u.to_string().replace("-", "\u{2212}");
|
||||
View::from(div().children(u_coord))
|
||||
}).collect::<Vec<_>>();
|
||||
let constrained = elt.constraints.len() > 0;
|
||||
let details_node = create_node_ref();
|
||||
view! {
|
||||
/* [TO DO] switch to integer-valued parameters whenever
|
||||
that becomes possible again */
|
||||
li {
|
||||
div(
|
||||
details(ref=details_node) {
|
||||
summary(
|
||||
class=class.get(),
|
||||
tabindex="0",
|
||||
on:keydown={
|
||||
move |event: KeyboardEvent| {
|
||||
match event.key().as_str() {
|
||||
"Enter" => {
|
||||
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.prevent_default();
|
||||
},
|
||||
"ArrowRight" if constrained => {
|
||||
let _ = details_node
|
||||
.get()
|
||||
.unchecked_into::<Element>()
|
||||
.set_attribute("open", "");
|
||||
},
|
||||
"ArrowLeft" => {
|
||||
let _ = details_node
|
||||
.get()
|
||||
.unchecked_into::<Element>()
|
||||
.remove_attribute("open");
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
div(
|
||||
class="elt-switch",
|
||||
on:click=|event: MouseEvent| event.stop_propagation()
|
||||
)
|
||||
div(
|
||||
class="elt",
|
||||
on:click={
|
||||
move |event: MouseEvent| {
|
||||
if event.shift_key() {
|
||||
@ -64,40 +107,28 @@ pub fn Outline() -> View {
|
||||
});
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
state.selection.update(|sel| {
|
||||
sel.clear();
|
||||
sel.insert(key);
|
||||
});
|
||||
}
|
||||
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 { (c_key.to_string()) } },
|
||||
view=|c_key: usize| view! {
|
||||
li(class="cst") {
|
||||
(c_key.to_string())
|
||||
}
|
||||
},
|
||||
key=|c_key| c_key.clone()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
key=|(key, _)| key.clone()
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user