Integrate engine into application prototype #15
@ -26,6 +26,7 @@ console_error_panic_hook = { version = "0.1.7", optional = true }
|
|||||||
version = "0.3.69"
|
version = "0.3.69"
|
||||||
features = [
|
features = [
|
||||||
'HtmlCanvasElement',
|
'HtmlCanvasElement',
|
||||||
|
'HtmlInputElement',
|
||||||
'Performance',
|
'Performance',
|
||||||
'WebGl2RenderingContext',
|
'WebGl2RenderingContext',
|
||||||
'WebGlBuffer',
|
'WebGlBuffer',
|
||||||
|
@ -93,7 +93,7 @@ details[open]:has(li) .elt-switch::after {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.elt-rep > div, .cst-rep {
|
.elt-rep > div {
|
||||||
padding: 2px 0px 0px 0px;
|
padding: 2px 0px 0px 0px;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -104,10 +104,17 @@ details[open]:has(li) .elt-switch::after {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cst > input {
|
.cst > input[type=checkbox] {
|
||||||
margin: 0px 8px 0px 0px;
|
margin: 0px 8px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cst > input[type=number] {
|
||||||
|
color: #fcfcfc;
|
||||||
|
background-color: inherit;
|
||||||
|
border: 1px solid #555;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
/* display */
|
/* display */
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
|
@ -214,11 +214,14 @@ pub fn AddRemove() -> View {
|
|||||||
(arg_vec[0].clone(), arg_vec[1].clone())
|
(arg_vec[0].clone(), arg_vec[1].clone())
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
let rep = create_signal(0.0);
|
||||||
let active = create_signal(true);
|
let active = create_signal(true);
|
||||||
state.assembly.insert_constraint(Constraint {
|
state.assembly.insert_constraint(Constraint {
|
||||||
args: args,
|
args: args,
|
||||||
rep: 0.0,
|
rep: rep,
|
||||||
active: active
|
rep_text: create_signal(String::new()),
|
||||||
|
rep_valid: create_signal(false),
|
||||||
|
active: active,
|
||||||
});
|
});
|
||||||
state.assembly.realize();
|
state.assembly.realize();
|
||||||
state.selection.update(|sel| sel.clear());
|
state.selection.update(|sel| sel.clear());
|
||||||
@ -233,13 +236,19 @@ pub fn AddRemove() -> View {
|
|||||||
&JsValue::from(cst.args.0),
|
&JsValue::from(cst.args.0),
|
||||||
&JsValue::from(cst.args.1),
|
&JsValue::from(cst.args.1),
|
||||||
&JsValue::from(":"),
|
&JsValue::from(":"),
|
||||||
&JsValue::from(cst.rep)
|
&JsValue::from(cst.rep.get_untracked())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// make constraint activation trigger a realization update
|
// update the realization when the constraint activated, or
|
||||||
|
// edited while active
|
||||||
create_effect(move || {
|
create_effect(move || {
|
||||||
|
rep.track();
|
||||||
|
console::log_2(
|
||||||
|
&JsValue::from("Constraint rep updated to"),
|
||||||
|
&JsValue::from(rep.get_untracked())
|
||||||
|
);
|
||||||
if active.get() {
|
if active.get() {
|
||||||
state.assembly.realize();
|
state.assembly.realize();
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@ pub struct Element {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Constraint {
|
pub struct Constraint {
|
||||||
pub args: (usize, usize),
|
pub args: (usize, usize),
|
||||||
pub rep: f64,
|
pub rep: Signal<f64>,
|
||||||
|
pub rep_text: Signal<String>,
|
||||||
|
pub rep_valid: Signal<bool>,
|
||||||
pub active: Signal<bool>
|
pub active: Signal<bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +118,11 @@ impl Assembly {
|
|||||||
let mut gram_to_be = PartialMatrix::new();
|
let mut gram_to_be = PartialMatrix::new();
|
||||||
self.constraints.with_untracked(|csts| {
|
self.constraints.with_untracked(|csts| {
|
||||||
for (_, cst) in csts {
|
for (_, cst) in csts {
|
||||||
if cst.active.get_untracked() {
|
if cst.active.get_untracked() && cst.rep_valid.get_untracked() {
|
||||||
let args = cst.args;
|
let args = cst.args;
|
||||||
let row = elts[args.0].index;
|
let row = elts[args.0].index;
|
||||||
let col = elts[args.1].index;
|
let col = elts[args.1].index;
|
||||||
gram_to_be.push_sym(row, col, cst.rep);
|
gram_to_be.push_sym(row, col, cst.rep.get_untracked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
glen marked this conversation as resolved
|
|||||||
use sycamore::{prelude::*, web::tags::div};
|
use sycamore::{prelude::*, web::tags::div};
|
||||||
use web_sys::{Element, KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
|
use web_sys::{Element, Event, HtmlInputElement, KeyboardEvent, MouseEvent, wasm_bindgen::JsCast};
|
||||||
|
use web_sys::{console, wasm_bindgen::JsValue}; /* DEBUG */
|
||||||
|
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
|
|
||||||
@ -51,8 +52,6 @@ pub fn Outline() -> View {
|
|||||||
let constrained = elt.constraints.len() > 0;
|
let constrained = elt.constraints.len() > 0;
|
||||||
let details_node = create_node_ref();
|
let details_node = create_node_ref();
|
||||||
view! {
|
view! {
|
||||||
/* [TO DO] switch to integer-valued parameters whenever
|
|
||||||
that becomes possible again */
|
|
||||||
li {
|
li {
|
||||||
details(ref=details_node) {
|
details(ref=details_node) {
|
||||||
summary(
|
summary(
|
||||||
@ -138,7 +137,25 @@ pub fn Outline() -> View {
|
|||||||
li(class="cst") {
|
li(class="cst") {
|
||||||
input(r#type="checkbox", bind:checked=cst.active)
|
input(r#type="checkbox", bind:checked=cst.active)
|
||||||
div(class="cst-label") { (other_arg_label) }
|
div(class="cst-label") { (other_arg_label) }
|
||||||
div(class="cst-rep") { (cst.rep) }
|
input(
|
||||||
|
r#type="number",
|
||||||
|
step="0.01",
|
||||||
|
bind:value=cst.rep_text,
|
||||||
|
on:change=move |event: Event| {
|
||||||
|
let target: HtmlInputElement = event.target().unwrap().unchecked_into();
|
||||||
|
let rep_valid = target.check_validity() && !target.value().is_empty();
|
||||||
|
batch(|| {
|
||||||
|
cst.rep_valid.set(rep_valid);
|
||||||
|
if rep_valid {
|
||||||
|
console::log_2(
|
||||||
|
&JsValue::from("Constraint rep parsed to"),
|
||||||
|
&JsValue::from(target.value_as_number())
|
||||||
|
);
|
||||||
|
cst.rep.set(target.value_as_number());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user
Definitely at some point we are going to need to separate the src directory into parts for the Assembly/Engine and for each of the views, but fine if you don't think that's warranted yet. On the other hand, if you just want to set up a reasonable hierarchy now and see how it works, that's fine too.
Yeah, I think we'll probably want separate modules for "front of house" and "back of house" code at some point. Right now it does seem like the
engine
andassembly
modules should go together in the "back of house" module, but I could imagine that changing, since the assembly structure is pretty tailored to the needs of the user interface.Note that the
Display
andOutline
views each have their own module already: that's why the expressionsmod display;
andmod outline;
appear at the top ofmain.rs
.I was commenting on the fact that outline is in the same directory as assembly and engine. I guess the module structure may not be immediately clear to the untrained eye; but directory structure is.
Also be cautious about the notion that "assembly is tailored to needs of UI". The driver for what goes in Assembly is the facts of the platonic universe we are observing. So color and label are OK because the sphere labeled George is red in the platonic universe. But unless "hidden" means that an entity must be hidden in all possible views -- and I doubt it should -- that should not be part of Assembly. (That's just an example, I know there is not a "hidden" property yet.)