Open Parameters directly and prepare SolidCraft 0.3.0

This commit is contained in:
bherbruck committed 2026-10-11 17:49:47 -04:00
1 parent 4af2d06007
commit d8beaedfa4
7 files changed
+72 -16

No files matched your search

Generated
+13 -13
View File
@@ -3269,7 +3269,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft" name = "solvecraft"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"eframe", "eframe",
"egui", "egui",
@@ -3284,7 +3284,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-cli" name = "solvecraft-cli"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"serde_json", "serde_json",
"solvecraft-engine", "solvecraft-engine",
@@ -3293,7 +3293,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-doc" name = "solvecraft-doc"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"log", "log",
"serde", "serde",
@@ -3308,7 +3308,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-engine" name = "solvecraft-engine"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"log", "log",
"serde", "serde",
@@ -3324,7 +3324,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-geom" name = "solvecraft-geom"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
@@ -3332,7 +3332,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-io" name = "solvecraft-io"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"quick-xml 0.38.4", "quick-xml 0.38.4",
"solvecraft-doc", "solvecraft-doc",
@@ -3344,7 +3344,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-kernel" name = "solvecraft-kernel"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"log", "log",
"serde", "serde",
@@ -3359,7 +3359,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-mcp" name = "solvecraft-mcp"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"serde_json", "serde_json",
"solvecraft-engine", "solvecraft-engine",
@@ -3367,7 +3367,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-render" name = "solvecraft-render"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"image", "image",
"serde", "serde",
@@ -3377,7 +3377,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-sketch" name = "solvecraft-sketch"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
@@ -3388,7 +3388,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-ui-egui" name = "solvecraft-ui-egui"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"egui", "egui",
"egui-wgpu", "egui-wgpu",
@@ -3403,7 +3403,7 @@ dependencies = [
[[package]] [[package]]
name = "solvecraft-web" name = "solvecraft-web"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"eframe", "eframe",
"egui", "egui",
@@ -4775,7 +4775,7 @@ checksum = "e450f9b2ed1dff33c94c12589a87338689467b9c4f5d8a5710bd09a847d2c8a7"
[[package]] [[package]]
name = "xtask" name = "xtask"
version = "0.2.1" version = "0.3.0"
dependencies = [ dependencies = [
"serde_json", "serde_json",
] ]
+1 -1
View File
@@ -5,7 +5,7 @@ members = ["crates/*", "apps/*", "xtask"]
exclude = ["vendor"] exclude = ["vendor"]
[workspace.package] [workspace.package]
version = "0.2.1" version = "0.3.0"
edition = "2024" edition = "2024"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
rust-version = "1.95" rust-version = "1.95"
+3
View File
@@ -250,6 +250,9 @@ headline counts in-scope tabs only and lists the deferred ones separately.
record their coordinate frame; legacy wires migrate from known provenance without changing record their coordinate frame; legacy wires migrate from known provenance without changing
coordinates. Broken legacy links with missing provenance can require explicit refresh or relink. coordinates. Broken legacy links with missing provenance can require explicit refresh or relink.
See [occurrence workflows](docs/occurrence-workflows.md). See [occurrence workflows](docs/occurrence-workflows.md).
- Parameters and Configurations have distinct actions in the SOLID toolbar's CONFIGURE panel.
Parameters opens the user/model variable editor; Configurations opens the configuration table.
Configure remains available in the panel dropdown.
- Configuration rules: ordered typed conditions can drive parameters and suppressions or - Configuration rules: ordered typed conditions can drive parameters and suppressions or
restrict values. Preview explains effective values without modifying the document; applying restrict values. Preview explains effective values without modifying the document; applying
rules validates rows atomically. Length expressions retain their authoring units across rules validates rows atomically. Length expressions retain their authoring units across
+6
View File
@@ -240,6 +240,12 @@ pub fn paint(p: &Painter, r: Rect, name: &str, ink: Color32, fill: Color32, acce
pen.arrow((12.0, 12.0), (12.0 + 9.0 * dx, 12.0 + 9.0 * dy), a); pen.arrow((12.0, 12.0), (12.0 + 9.0 * dx, 12.0 + 9.0 * dy), a);
} }
} }
"configuration_table" => {
pen.poly(&[(3.0, 4.0), (21.0, 4.0), (21.0, 20.0), (3.0, 20.0)], pen.fill, ink);
pen.line(&[(3.0, 9.0), (21.0, 9.0)], a);
pen.line(&[(3.0, 14.0), (21.0, 14.0)], ink);
pen.line(&[(9.0, 4.0), (9.0, 20.0)], ink);
}
"params" => { "params" => {
pen.line(&[(8.0, 20.0), (9.0, 8.0), (10.0, 5.0), (13.0, 4.0)], ink); pen.line(&[(8.0, 20.0), (9.0, 8.0), (10.0, 5.0), (13.0, 4.0)], ink);
pen.line(&[(6.0, 11.0), (12.0, 11.0)], ink); pen.line(&[(6.0, 11.0), (12.0, 11.0)], ink);
+12 -2
View File
@@ -481,9 +481,19 @@ pub fn toolbar(app: &mut SolveApp, ui: &mut egui::Ui) {
} else { } else {
(t.border, t.panel_header, t.border) (t.border, t.panel_header, t.border)
}; };
let icon = if c.id == "sketch.finish" { "finish" } else { c.icon }; let icon = match c.id {
"sketch.finish" => "finish",
"config.table" => "configuration_table",
_ => c.icon,
};
icons::paint(&painter, br.shrink(6.0), icon, ink, fill, acc); icons::paint(&painter, br.shrink(6.0), icon, ink, fill, acc);
let tr_label = app.tr_label(c.label); let label = match c.id {
"parameters.change" if *panel == "CONFIGURE" => "Parameters",
"config.table" if *panel == "CONFIGURE" => "Configurations",
_ => c.label,
};
let tr_label = app.tr_label(label);
resp.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled() && info.enabled, tr_label));
let tip = match &info.disabled_reason { let tip = match &info.disabled_reason {
Some(why) => format!("{}\n{why}", tr_label), Some(why) => format!("{}\n{why}", tr_label),
None => format!("{}{}", tr_label, c.shortcut.map(|k| format!(" ({k})")).unwrap_or_default()), None => format!("{}{}", tr_label, c.shortcut.map(|k| format!(" ({k})")).unwrap_or_default()),
+33
View File
@@ -100,6 +100,7 @@ pub fn panels(tab: &str) -> Option<&'static [&'static str]> {
/// to the registry. /// to the registry.
pub fn layout<'a>(tab: &str, panel: &str, specs: &[&'a CommandSpec]) -> Option<(Vec<&'a CommandSpec>, usize)> { pub fn layout<'a>(tab: &str, panel: &str, specs: &[&'a CommandSpec]) -> Option<(Vec<&'a CommandSpec>, usize)> {
let (ids, promoted, own_tab): (&[&str], usize, &str) = match (tab, panel) { let (ids, promoted, own_tab): (&[&str], usize, &str) = match (tab, panel) {
("SOLID", "CONFIGURE") => (&["parameters.change", "config.table"], 2, tab),
("SOLID" | "SHEET METAL" | "PLASTIC", "ASSEMBLE") => (ASSEMBLE, 3, tab), ("SOLID" | "SHEET METAL" | "PLASTIC", "ASSEMBLE") => (ASSEMBLE, 3, tab),
("SHEET METAL", "CREATE") => (SHEET_CREATE, 3, tab), ("SHEET METAL", "CREATE") => (SHEET_CREATE, 3, tab),
("SHEET METAL", "MODIFY") => (SHEET_MODIFY, 2, tab), ("SHEET METAL", "MODIFY") => (SHEET_MODIFY, 2, tab),
@@ -146,6 +147,38 @@ mod tests {
layout(tab, panel, &specs).map(|(v, _)| v.iter().map(|c| c.id).collect()).unwrap_or_default() layout(tab, panel, &specs).map(|(v, _)| v.iter().map(|c| c.id).collect()).unwrap_or_default()
} }
#[test]
fn configure_header_clicks_open_parameters_and_configurations_separately() {
use serde_json::json;
let mut h = crate::scenario::Harness::new();
let commands = ids("SOLID", "CONFIGURE");
assert_eq!(&commands[..2], &["parameters.change", "config.table"]);
assert!(commands.contains(&"config.configure"), "Configure remains available in the dropdown");
h.step(&json!({"widget":"Parameters"})).unwrap();
assert!(h.app.params.is_some(), "the ordinary Parameters button opens the editor");
assert!(h.app.dialog.is_none());
assert!(h.widget("User Parameters").is_some());
assert!(h.widget("Model Parameters").is_some());
// Exercise the editor's Add button, not a script-only parameter command.
let parameters = h.app.params.as_mut().unwrap();
parameters.new_name = "width".into();
parameters.new_expr = "25 mm".into();
h.frames(3);
h.step(&json!({"widget":"Add"})).unwrap();
let values = h.app.session.execute("parameters.list", &json!({})).unwrap();
assert!(values["parameters"].as_array().unwrap().iter().any(|p| p["name"] == "width" && p["value"] == 25.0));
h.step(&json!({"click":{"handle":"params:close"}})).unwrap();
assert!(h.app.params.is_none());
h.step(&json!({"widget":"Configurations"})).unwrap();
assert!(h.app.params.is_none());
assert!(matches!(
h.app.dialog.as_ref().map(|d| &d.kind),
Some(crate::dialogs::Kind::Motion(crate::dialogs_motion::Mo::Configurations { .. }))
));
assert!(h.widget("Add Column").is_some());
assert!(h.widget("Add Row").is_some());
}
/// Fusion's layout: joints on every tab's ASSEMBLE panel, sheet metal and plastic tabs /// Fusion's layout: joints on every tab's ASSEMBLE panel, sheet metal and plastic tabs
/// reach the shared solid commands, the plastic rules sit on SETUP. /// reach the shared solid commands, the plastic rules sit on SETUP.
#[test] #[test]
+4
View File
@@ -5,6 +5,10 @@ are ones you add yourself, with a unit, an expression and an optional comment. C
**Change Parameters** (`parameters.change`). The timeline rebuilds from the first feature that **Change Parameters** (`parameters.change`). The timeline rebuilds from the first feature that
uses them. uses them.
In the SOLID toolbar's CONFIGURE panel, click **Parameters** to open the user and model
parameter editor. The separate **Configurations** button opens the configuration table;
**Configure** remains in the dropdown for configuring columns.
Expressions are unit-aware: `2 * width + 5 mm`, `angle / 2`, `sqrt(area)`, `1 in + 3 mm`, using Expressions are unit-aware: `2 * width + 5 mm`, `angle / 2`, `sqrt(area)`, `1 in + 3 mm`, using
`+ - * / ^`, parentheses, `sin cos tan asin acos atan atan2 sqrt abs min max floor ceil round mod `+ - * / ^`, parentheses, `sin cos tan asin acos atan atan2 sqrt abs min max floor ceil round mod
trunc` and unit conversion. A length where an angle is expected (or the other way round) is an trunc` and unit conversion. A length where an angle is expected (or the other way round) is an