mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 21:48:20 -06:00
#670: each pane of a 2- or 4-view layout chooses its own view
Problem: the extra panes of View > Switch View Layout were fixed to Top, Front and Right, and the 3D View menu only changed the main view.
Fix: every extra pane has a view selector (Active Camera, Default, Front, Left, Top, Back, Right, Bottom, Custom View 1-3). The choice is kept per comp in Views3D::panes (serde default, so older editor states load with Top/Front/Right) and set by the new command view.setPaneView {pane 0-3, view}. The Active Camera pane renders through the comp camera.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
f19f3a8a39
commit
fa7ffb6d09
@@ -320,6 +320,21 @@ fn set_3d_view(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
Ok(switch_view(s, cid, v))
|
||||
}
|
||||
|
||||
/// The view of one pane of the View Layout: pane 0 is the main view (the same as Switch 3D View),
|
||||
/// panes 1 to 3 are the extra views of a 2- or 4-view layout. UI state, not part of the project.
|
||||
fn set_pane_view(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let cid = comp_id(s, p)?;
|
||||
let v = view_p(p, "view.setPaneView")?;
|
||||
let pane = p.get("pane").and_then(Value::as_u64).filter(|n| *n <= 3).ok_or_else(|| bad("view.setPaneView", "pane: 0 (main view) to 3"))? as usize;
|
||||
if pane == 0 {
|
||||
switch_view(s, cid, v);
|
||||
} else {
|
||||
views(s, cid).set_pane(pane - 1, v);
|
||||
}
|
||||
let vs = views(s, cid);
|
||||
Ok(json!({"pane": pane, "view": v.id(), "views": [vs.current.id(), vs.pane(0).id(), vs.pane(1).id(), vs.pane(2).id()]}))
|
||||
}
|
||||
|
||||
macro_rules! view_cmd {
|
||||
($f:ident, $v:expr) => {
|
||||
fn $f(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
@@ -706,6 +721,15 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
has_comp,
|
||||
set_3d_view
|
||||
),
|
||||
cmd!(
|
||||
"view.setPaneView",
|
||||
"Set View of Pane",
|
||||
[],
|
||||
None,
|
||||
"{pane: 0 (main) | 1 | 2 | 3, view: activeCamera|default|front|left|top|back|right|bottom|custom1|custom2|custom3, comp?}",
|
||||
has_comp,
|
||||
set_pane_view
|
||||
),
|
||||
cmd!("view.3d.activeCamera", "Active Camera", ["View", "Switch 3D View"], Some("F12"), "{comp?}", has_comp, view_active),
|
||||
cmd!("view.3d.default", "Default", ["View", "Switch 3D View"], None, "{comp?}", has_comp, view_default),
|
||||
cmd!("view.3d.front", "Front", ["View", "Switch 3D View"], Some("F10"), "{comp?}", has_comp, view_front),
|
||||
|
||||
@@ -243,3 +243,25 @@ fn demo_has_3d_showcase() {
|
||||
let lit = img.data.iter().filter(|p| p[3] > 0.99 && p[0] + p[1] + p[2] > 0.3).count();
|
||||
assert!(lit > 2_000, "{lit}");
|
||||
}
|
||||
|
||||
/// #670: the views of the panes of a multi-view layout are chosen per pane, kept per comp, and
|
||||
/// editor states saved before panes existed load with the default Top / Front / Right.
|
||||
#[test]
|
||||
fn layout_panes_choose_their_view() {
|
||||
use effectcraft_render::three_d::{View3D, Views3D};
|
||||
let mut s = Session::default();
|
||||
s.execute("comp.new", json!({"name": "C", "width": 640, "height": 360, "duration": 2})).unwrap();
|
||||
let cid = s.active_comp_id().unwrap();
|
||||
assert_eq!(s.state.views3d.get(&cid).cloned().unwrap_or_default().pane(0), View3D::Top);
|
||||
let r = s.execute("view.setPaneView", json!({"pane": 2, "view": "bottom"})).unwrap();
|
||||
assert_eq!(r["views"], json!(["activeCamera", "top", "bottom", "right"]));
|
||||
assert_eq!(s.state.views3d[&cid].current, View3D::ActiveCamera, "the main view is untouched");
|
||||
s.execute("view.setPaneView", json!({"pane": 0, "view": "custom1"})).unwrap();
|
||||
assert_eq!(s.state.views3d[&cid].current, View3D::Custom1);
|
||||
assert!(s.execute("view.setPaneView", json!({"pane": 4, "view": "top"})).is_err());
|
||||
assert!(s.execute("view.setPaneView", json!({"pane": 1, "view": "nope"})).is_err());
|
||||
let back: crate::EditorState = serde_json::from_value(serde_json::to_value(&s.state).unwrap()).unwrap();
|
||||
assert_eq!(back.views3d[&cid].pane(1), View3D::Bottom);
|
||||
let old: Views3D = serde_json::from_value(json!({"current": "Front"})).unwrap();
|
||||
assert_eq!((old.current, old.pane(0), old.pane(1), old.pane(2)), (View3D::Front, View3D::Top, View3D::Front, View3D::Right));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user