Application prototype #14
@ -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;
|
||||||
|
@ -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()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user