forked from 1b-agent/fieldcraft-upstream
ui: File › New starts an empty model (file.new, #144); an unknown sample name opens the samples (#200)
file.new replaces the session with an empty one: no design, mesh, definitions, results or journal, nothing to save, the undo history empty. The File menu and Cmd/Ctrl+N run it, asking first over unsaved changes. A sample name the app does not know (a typo, an old ?sample= link) opens the samples to choose from, and the status names it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
92b6225a72
commit
0625125ed7
7 files changed
+81
-5
No files matched your search
@@ -585,7 +585,8 @@ pub static CATALOGUE: &[Capability] = &[
|
||||
// ---- Tools ----
|
||||
// Renaming starts from a definition's item menu (Rename…); the search finds it here too.
|
||||
ready_more("model.info", "Model Info", Tools, "Model", "Node and element counts and the model summary", &["model.rename"]),
|
||||
ready("file.open", "Open Model", Tools, "File", "Open a .fieldcraft model"),
|
||||
// New starts from the File menu; the search finds it here too.
|
||||
ready_more("file.open", "Open Model", Tools, "File", "Open a .fieldcraft model", &["file.new"]),
|
||||
ready("file.sample", "Samples", Tools, "File", "Open a sample model, ready to solve"),
|
||||
ready("file.save", "Save", Tools, "File", "Save the model to its .fieldcraft file"),
|
||||
ready("file.save_as", "Save As", Tools, "File", "Save the model to a new .fieldcraft file"),
|
||||
|
||||
@@ -19,6 +19,16 @@ use fieldcraft_io::roots::{Access, Roots};
|
||||
use super::{file_param, req};
|
||||
use crate::{CommandKind, CommandSpec, EngineError, Result, Session, next_revision};
|
||||
|
||||
pub const NEW: CommandSpec = CommandSpec {
|
||||
id: "file.new",
|
||||
label: "New Model",
|
||||
params: r#"{} — starts an empty model in place of the current one: no design, mesh, definitions, results or journal; unsaved changes are discarded (the window asks first) and the undo history starts empty"#,
|
||||
form: Some(&[]),
|
||||
kind: CommandKind::Session,
|
||||
requires: &[],
|
||||
run: new_model,
|
||||
};
|
||||
|
||||
pub const OPEN: CommandSpec = CommandSpec {
|
||||
id: "file.open",
|
||||
label: "Open Model",
|
||||
@@ -89,6 +99,15 @@ pub const SAMPLE: CommandSpec = CommandSpec {
|
||||
run: open_sample,
|
||||
};
|
||||
|
||||
fn new_model(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
let mut empty = Session::default();
|
||||
// Nothing to save until a command changes it.
|
||||
empty.saved_revision = Some(empty.revision);
|
||||
empty.saved_view = empty.view.clone();
|
||||
s.replace_with(empty);
|
||||
Ok(summary(s, &[]))
|
||||
}
|
||||
|
||||
fn open_sample(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let name: &str = req(p, "name")?;
|
||||
let names = || crate::sample::SAMPLES.iter().map(|x| x.name).collect::<Vec<_>>().join(", ");
|
||||
@@ -375,6 +394,19 @@ mod tests {
|
||||
s.execute("model.material.create", &json!({"name": "Steel", "elastic": {"type": "isotropic", "young": 210000.0, "poisson": 0.3}})).unwrap();
|
||||
}
|
||||
|
||||
/// `file.new` empties the model, its journal and its undo history, and has nothing to save.
|
||||
#[test]
|
||||
fn new_starts_an_empty_model() {
|
||||
let mut s = Session::default();
|
||||
s.execute("file.sample", &json!({"name": "cantilever"})).unwrap();
|
||||
s.execute("mesh.node.add", &json!({"label": 10_000, "xyz": [0, 0, 0]})).unwrap();
|
||||
let r = s.execute("file.new", &json!({})).unwrap();
|
||||
assert_eq!((r["nodes"].as_u64(), r["elements"].as_u64(), r["journal"].as_u64()), (Some(0), Some(0), Some(0)), "{r}");
|
||||
assert!(s.model.materials().is_empty() && s.model.steps().is_empty() && s.design.is_none() && s.sample.is_none());
|
||||
assert!(!s.is_dirty(), "an empty model has nothing to save");
|
||||
assert!(s.execute("edit.undo", &json!({})).is_err(), "the undo history starts empty");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_and_open_keep_the_model_journal_and_design() {
|
||||
let d = dir("roundtrip");
|
||||
|
||||
@@ -135,6 +135,7 @@ pub static ALL: &[CommandSpec] = &[
|
||||
define::STEP_ACTIVATE,
|
||||
define::RENAME,
|
||||
define::ACTIVITY,
|
||||
file::NEW,
|
||||
file::OPEN,
|
||||
file::SAVE,
|
||||
file::SAVE_AS,
|
||||
|
||||
Reference in new issue
Block a user