diff --git a/app-proto/Cargo.toml b/app-proto/Cargo.toml index 04ea271..e5bc05e 100644 --- a/app-proto/Cargo.toml +++ b/app-proto/Cargo.toml @@ -26,6 +26,7 @@ console_error_panic_hook = { version = "0.1.7", optional = true } version = "0.3.69" features = [ 'HtmlCanvasElement', + 'HtmlInputElement', 'Performance', 'WebGl2RenderingContext', 'WebGlBuffer', diff --git a/app-proto/main.css b/app-proto/main.css index bdbacfb..44dc7a1 100644 --- a/app-proto/main.css +++ b/app-proto/main.css @@ -93,7 +93,7 @@ details[open]:has(li) .elt-switch::after { display: flex; } -.elt-rep > div, .cst-rep { +.elt-rep > div { padding: 2px 0px 0px 0px; font-size: 10pt; text-align: center; @@ -104,10 +104,17 @@ details[open]:has(li) .elt-switch::after { font-style: italic; } -.cst > input { +.cst > input[type=checkbox] { margin: 0px 8px 0px 0px; } +.cst > input[type=number] { + color: #fcfcfc; + background-color: inherit; + border: 1px solid #555; + border-radius: 2px; +} + /* display */ canvas { diff --git a/app-proto/src/add_remove.rs b/app-proto/src/add_remove.rs index 00b63f8..5435418 100644 --- a/app-proto/src/add_remove.rs +++ b/app-proto/src/add_remove.rs @@ -214,11 +214,14 @@ pub fn AddRemove() -> View { (arg_vec[0].clone(), arg_vec[1].clone()) } ); + let rep = create_signal(0.0); let active = create_signal(true); state.assembly.insert_constraint(Constraint { args: args, - rep: 0.0, - active: active + rep: rep, + rep_text: create_signal(String::new()), + rep_valid: create_signal(false), + active: active, }); state.assembly.realize(); state.selection.update(|sel| sel.clear()); @@ -233,13 +236,19 @@ pub fn AddRemove() -> View { &JsValue::from(cst.args.0), &JsValue::from(cst.args.1), &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 || { + rep.track(); + console::log_2( + &JsValue::from("Constraint rep updated to"), + &JsValue::from(rep.get_untracked()) + ); if active.get() { state.assembly.realize(); } diff --git a/app-proto/src/assembly.rs b/app-proto/src/assembly.rs index 648d0ef..62f5405 100644 --- a/app-proto/src/assembly.rs +++ b/app-proto/src/assembly.rs @@ -22,7 +22,9 @@ pub struct Element { #[derive(Clone)] pub struct Constraint { pub args: (usize, usize), - pub rep: f64, + pub rep: Signal, + pub rep_text: Signal, + pub rep_valid: Signal, pub active: Signal } @@ -116,11 +118,11 @@ impl Assembly { let mut gram_to_be = PartialMatrix::new(); self.constraints.with_untracked(|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 row = elts[args.0].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()); } } }); diff --git a/app-proto/src/outline.rs b/app-proto/src/outline.rs index 4e4de9c..d6b0390 100644 --- a/app-proto/src/outline.rs +++ b/app-proto/src/outline.rs @@ -1,6 +1,7 @@ use itertools::Itertools; 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; @@ -51,8 +52,6 @@ pub fn Outline() -> View { 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 { details(ref=details_node) { summary( @@ -138,7 +137,25 @@ pub fn Outline() -> View { li(class="cst") { input(r#type="checkbox", bind:checked=cst.active) 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()); + } + }); + } + ) } } },