Multi-select, select joined walls and fences, pond with swimming fish
Deploy web Studio / deploy (push) Successful in 1m27s
Deploy web Studio / deploy (push) Successful in 1m27s
Selection: S.sel stays the object picked last; S.selIds holds everything selected. - In the object list, Ctrl+click adds or removes an object and Shift+click selects a range. - On the map, Ctrl/Shift+click toggles an object and Shift+drag draws a box that selects what lies wholly inside it (locked and hidden objects are left out). - Ctrl+A selects everything that is not locked; Esc selects nothing. - Clicking a wall or fence a second time selects every piece of the same type joined to it; another click goes back to that one piece. - Dragging one selected object moves them all, together with the windows and doors on them, as one undo step. Arrow keys, R (turns the group about its middle), Ctrl+D, Delete, Lock and Hide all work on the whole selection. - When all selected objects share a type, the property form edits them all; fields where they differ show "mixed". - The agent's system prompt lists the selected objects. The viewer outlines several objects with selectObj([ids]) and passes the click event to onPick. A batch op now answers `ids`, one per operation, so the copies from a group duplicate get selected. Pond (Nature): natural, round or square, with a stone or grass edge, fish, lily pads, spreading ripples and reed clumps. The fish come from a new Swim primitive (script: s.swim). One matrix maps the object's frame to the screen. Each fish turns round its ellipse with a CSS rotation, so off-screen pausing and reduced motion apply as for the other animations. The house demo gets a koi pond in the back garden. Tests: ponds in every shape and rotation have the right number of fish, no NaN and no depth-sort cycles, and stay inside their rectangle. check_studio covers list and map multi-select, a group drag undone in one step, joined-fence selection, a mixed-value form applied to all, box select, delete and undo, Ctrl+A, Esc, and a new pond's fish.
This commit is contained in:
1 parent
e4017ce2a8
commit
19f4c83ae8
21 files changed
+759
-59
No files matched your search
@@ -23,7 +23,8 @@ pub fn meta<S: Store>(ws: &Workspace<S>) -> Value {
|
||||
}
|
||||
|
||||
/// One operation, or `{ "ops": [...] }` as one undo step. Answers the new
|
||||
/// state with `ok` and the id of the object made or changed, or `error`.
|
||||
/// state with `ok`, the id of the object made or changed (the last one) and
|
||||
/// `ids` (one per operation that made or changed an object), or `error`.
|
||||
pub fn op<S: Store>(ws: &mut Workspace<S>, body: &Value) -> Value {
|
||||
let r = if let Some(list) = body.get("ops").and_then(|v| v.as_array()) {
|
||||
let ops: Result<Vec<Op>, String> = list
|
||||
@@ -31,18 +32,19 @@ pub fn op<S: Store>(ws: &mut Workspace<S>, body: &Value) -> Value {
|
||||
.map(|v| serde_json::from_value::<Op>(v.clone()).map_err(|e| e.to_string()))
|
||||
.collect();
|
||||
ops.and_then(|l| ws.apply_all(l))
|
||||
.map(|o| o.last().and_then(|x| x.id.clone()))
|
||||
.map(|o| o.into_iter().filter_map(|x| x.id).collect::<Vec<_>>())
|
||||
} else {
|
||||
serde_json::from_value::<Op>(body.clone())
|
||||
.map_err(|e| format!("bad operation: {e}"))
|
||||
.and_then(|op| ws.apply(op))
|
||||
.map(|o| o.id)
|
||||
.map(|o| o.id.into_iter().collect())
|
||||
};
|
||||
match r {
|
||||
Ok(id) => {
|
||||
Ok(ids) => {
|
||||
let mut s = state(ws);
|
||||
s["ok"] = json!(true);
|
||||
s["id"] = json!(id);
|
||||
s["id"] = json!(ids.last());
|
||||
s["ids"] = json!(ids);
|
||||
s
|
||||
}
|
||||
Err(e) => json!({ "error": e }),
|
||||
|
||||
Reference in new issue
Block a user