variables: highlighted row owns Delete, Options and Select Bound Object

Select Bound Object ran variable.unbind on the selection, so choosing it silently
removed the bindings; Delete Variable and Delete Data Set deleted every row. Now
the panel keeps a highlighted variable row (a click highlights and selects what
it drives, as the reference panel does): Select Bound Object selects what the
highlighted variable drives via select.set, Delete Variable deletes only it, and
Delete Data Set deletes only the current set. Variable Options and Rename Data
Set open their dialogs preselected with the highlighted variable / active set
(the double-click used to invoke variable.rename with a bare name, which only
errored). Unbind enables only over a bound selection; Make Text Dynamic only for
exactly one type object.

The highlight is per-document session state with its own command
(variable.highlight, no undo step, like layer.highlight): rename carries it,
delete clears it when stale. New engine tests (18) and panel tests cover the
reviewer's regression case, verified to fail on the old wiring.
This commit is contained in:
Fahri Meral
2026-10-10 23:34:21 +07:00
committed by bflatastic
parent 06dbe5b1e8
commit f2252b0d9c
14 changed files with 262 additions and 38 deletions
+42
View File
@@ -104,6 +104,12 @@ fn rename(s: &mut Session, p: &Value) -> Result<Value> {
}
Ok(())
})?;
// The highlight names a variable, so it follows the rename rather than going stale.
let st = s.doc_mut()?;
if st.variables_highlight.as_deref() == Some(from.as_str()) {
st.variables_highlight = Some(to.clone());
}
st.revision += 1;
Ok(json!({"from": from, "name": to}))
}
@@ -149,6 +155,12 @@ fn make_dynamic(s: &mut Session, kind: VariableKind, stem: &str) -> Result<Value
fn delete(s: &mut Session, p: &Value) -> Result<Value> {
let names = names_param(p, "variable.delete")?;
let n = s.edit("Delete Variables", |d, _| Ok(d.variables.prune(&names)))?;
// A highlight of a variable that is gone highlights nothing.
let st = s.doc_mut()?;
if st.variables_highlight.as_ref().is_some_and(|h| st.doc.variables.variable(h).is_none()) {
st.variables_highlight = None;
}
st.revision += 1;
Ok(json!({"deleted": n}))
}
@@ -227,6 +239,27 @@ fn unbind(s: &mut Session, p: &Value) -> Result<Value> {
Ok(json!({"unbound": n}))
}
/// Highlight one Variables panel row: what the panel's Delete, Options… and Select Bound
/// Object act on. Panel state, not art selection: not saved, not an undo step (an empty
/// or missing `variable` clears it), like `layer.highlight`.
fn highlight(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "variable.highlight";
let name = match str_param(p, "variable").filter(|v| !v.is_empty()) {
Some(v) => {
let v = v.to_string();
if s.doc()?.doc.variables.variable(&v).is_none() {
return Err(bad(C, format!("no variable named `{v}`")));
}
Some(v)
}
None => None,
};
let st = s.doc_mut()?;
st.variables_highlight = name.clone();
st.revision += 1;
Ok(json!({"variable": name}))
}
fn dataset_new(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "dataset.new";
let name = var_name(p, C)?;
@@ -480,6 +513,15 @@ pub fn specs() -> Vec<CommandSpec> {
has_doc,
unbind
),
cmd!(
"variable.highlight",
"Highlight Variable",
[],
None,
"{variable?} highlight one Variables panel row (a click); what the panel's Delete, Options… and Select Bound Object act on. An empty or missing `variable` clears it. Not an undo step → {variable}",
has_doc,
highlight
),
cmd!("dataset.new", "New Data Set…", ["Window", "Variables"], None, "{name, values?: {variable: value}} add a dataset", has_doc, dataset_new),
cmd!(
"dataset.set",