Make constraints editable

This commit is contained in:
Aaron Fenyes 2024-10-29 22:32:00 -07:00
parent e5f4d523f9
commit e0880d2ad2
5 changed files with 49 additions and 13 deletions

View File

@ -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',

View File

@ -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 {

View File

@ -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();
} }

View File

@ -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());
} }
} }
}); });

View File

@ -1,6 +1,7 @@
use itertools::Itertools; use itertools::Itertools;
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());
}
});
}
)
} }
} }
}, },