forked from glen/dyna3
Require regulators to have valid specifications
When an invalid specification is entered into a regulator input, keep it confined to that input. Reset a regulator input by pressing *escape*.
This commit is contained in:
parent
fef4127f69
commit
302d93638d
3 changed files with 49 additions and 26 deletions
|
@ -133,28 +133,25 @@ details[open]:has(li) .element-switch::after {
|
|||
font-size: 10pt;
|
||||
}
|
||||
|
||||
.regulator.invalid-constraint {
|
||||
color: var(--text-invalid);
|
||||
}
|
||||
|
||||
.regulator > input {
|
||||
.regulator-input {
|
||||
color: inherit;
|
||||
background-color: inherit;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.regulator > input::placeholder {
|
||||
.regulator-input::placeholder {
|
||||
color: inherit;
|
||||
opacity: 54%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.regulator.valid-constraint > input {
|
||||
.regulator-input.constraint {
|
||||
background-color: var(--display-background);
|
||||
}
|
||||
|
||||
.regulator.invalid-constraint > input {
|
||||
.regulator-input.invalid {
|
||||
color: var(--text-invalid);
|
||||
border-color: var(--border-invalid);
|
||||
}
|
||||
|
||||
|
@ -166,7 +163,7 @@ details[open]:has(li) .element-switch::after {
|
|||
font-style: normal;
|
||||
}
|
||||
|
||||
.invalid-constraint > .status::after, details:has(.invalid-constraint):not([open]) .status::after {
|
||||
.regulator:has(.invalid) > .status::after, details:has(.invalid):not([open]) .status::after {
|
||||
content: '⚠';
|
||||
color: var(--text-invalid);
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ impl Element {
|
|||
}
|
||||
}
|
||||
|
||||
// `set_point_spec` must always be a valid specification of `set_point`
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Regulator {
|
||||
pub subjects: (ElementKey, ElementKey),
|
||||
|
@ -119,12 +120,6 @@ pub struct Regulator {
|
|||
pub set_point_spec: Signal<String>
|
||||
}
|
||||
|
||||
impl Regulator {
|
||||
pub fn has_no_set_point_spec(&self) -> bool {
|
||||
self.set_point_spec.with(|spec| spec.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
// the velocity is expressed in uniform coordinates
|
||||
pub struct ElementMotion<'a> {
|
||||
pub key: ElementKey,
|
||||
|
|
|
@ -19,17 +19,55 @@ use crate::{
|
|||
// an editable view of a regulator
|
||||
#[component(inline_props)]
|
||||
fn RegulatorInput(regulator: Regulator) -> View {
|
||||
let valid = create_signal(true);
|
||||
let value = create_signal(regulator.set_point_spec.get_clone_untracked());
|
||||
create_effect(move || value.set(regulator.set_point_spec.get_clone()));
|
||||
|
||||
// this closure resets the input value to the regulator's set point
|
||||
// specification, which is always a valid specification
|
||||
let reset_value = move || {
|
||||
batch(|| {
|
||||
valid.set(true);
|
||||
value.set(regulator.set_point_spec.get_clone());
|
||||
})
|
||||
};
|
||||
|
||||
// reset the input value whenever the regulator's set point specification
|
||||
// is updated
|
||||
create_effect(reset_value);
|
||||
|
||||
view! {
|
||||
input(
|
||||
r#type="text",
|
||||
class=move || {
|
||||
if valid.get() {
|
||||
match regulator.set_point.get() {
|
||||
Some(_) => "regulator-input constraint",
|
||||
None => "regulator-input"
|
||||
}
|
||||
} else {
|
||||
"regulator-input invalid"
|
||||
}
|
||||
},
|
||||
placeholder=regulator.measurement.with(|result| result.to_string()),
|
||||
bind:value=value,
|
||||
on:change=move |_| {
|
||||
let value_val = value.get_clone_untracked();
|
||||
regulator.set_point.set(value_val.parse::<f64>().ok());
|
||||
regulator.set_point_spec.set(value_val);
|
||||
match value_val.parse::<f64>() {
|
||||
Err(_) if !value_val.is_empty() => valid.set(false),
|
||||
set_pt => batch(|| {
|
||||
regulator.set_point.set(set_pt.ok());
|
||||
regulator.set_point_spec.set(value_val);
|
||||
valid.set(true);
|
||||
})
|
||||
};
|
||||
},
|
||||
on:keydown={
|
||||
move |event: KeyboardEvent| {
|
||||
match event.key().as_str() {
|
||||
"Escape" => reset_value(),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -47,15 +85,8 @@ fn RegulatorOutlineItem(regulator_key: RegulatorKey, element_key: ElementKey) ->
|
|||
regulator.subjects.0
|
||||
};
|
||||
let other_subject_label = assembly.elements.with(|elts| elts[other_subject].label.clone());
|
||||
let class = create_memo(move || {
|
||||
match regulator.set_point.get() {
|
||||
None if regulator.has_no_set_point_spec() => "regulator",
|
||||
None => "regulator invalid-constraint",
|
||||
Some(_) => "regulator valid-constraint"
|
||||
}
|
||||
});
|
||||
view! {
|
||||
li(class=class.get()) {
|
||||
li(class="regulator") {
|
||||
div(class="regulator-label") { (other_subject_label) }
|
||||
div(class="regulator-type") { "Inversive distance" }
|
||||
RegulatorInput(regulator=regulator)
|
||||
|
|
Loading…
Add table
Reference in a new issue