From b9034566b0607c5bb8c04134d17139f99989e1d0 Mon Sep 17 00:00:00 2001 From: ymote <151983+ymote@users.noreply.github.com> Date: Sat, 26 Sep 2026 10:02:37 -0700 Subject: [PATCH] Support stateful native mini-app inputs and multilingual font fallback --- Cargo.toml | 4 ++-- crates/octoscript-makepad/src/design.rs | 11 +++++++++++ crates/octoscript-makepad/src/l0.rs | 7 ++++++- crates/octoscript-makepad/src/lib.rs | 17 ++++++++++------- runtime.json | 2 +- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3d55d78..60e2fc9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,8 +17,8 @@ members = [ # runtime.json is the source contract shared by every OctoSense application. [workspace.dependencies] -makepad-widgets = { git = "https://github.com/OctoSense-org/makepad.git", rev = "1d3d383e84a66dbb18a4a860f505430c9d5b20f4" } -makepad-script = { git = "https://github.com/OctoSense-org/makepad.git", rev = "1d3d383e84a66dbb18a4a860f505430c9d5b20f4" } +makepad-widgets = { git = "https://github.com/OctoSense-org/makepad.git", rev = "3fda5b6f9b48f390bd5396938a95d30ad035cd6d" } +makepad-script = { git = "https://github.com/OctoSense-org/makepad.git", rev = "3fda5b6f9b48f390bd5396938a95d30ad035cd6d" } # The VM-independent Octoscript node model, from the Octoscript repo itself. octoscript-ui-l0 = { git = "https://github.com/OctoSense-org/Octoscript.git", rev = "68f6a9df55692b5d8ef8873a12721e279a3f40d6" } diff --git a/crates/octoscript-makepad/src/design.rs b/crates/octoscript-makepad/src/design.rs index 685dcd7..25402a2 100644 --- a/crates/octoscript-makepad/src/design.rs +++ b/crates/octoscript-makepad/src/design.rs @@ -170,6 +170,17 @@ pub fn to_makepad_ui(tree: &UiNode) -> Result { write!(out, "{id} := ").unwrap(); } writeln!(out, "{widget} {{").unwrap(); + if n.kind == NodeKind::Input { + for (property, route) in [("on_change", &a.changeto), ("on_return", &a.tapto)] { + if let Some(target) = route.as_ref().filter(|t| !t.is_empty()) { + writeln!(out, "{property}: fn(text) {{ NAV(t: {target:?}, v: text) }}").unwrap(); + } + } + } else if n.kind == NodeKind::Button { + if let Some(target) = a.tapto.as_ref().filter(|t| !t.is_empty()) { + writeln!(out, "on_click: || {{ NAV(t: {target:?}) }}").unwrap(); + } + } if let Some(config)=&contract { writeln!(out,"contract: {:?} glass: {}",config.to_string(),a.variant.as_deref()==Some("glass_group")).unwrap(); } diff --git a/crates/octoscript-makepad/src/l0.rs b/crates/octoscript-makepad/src/l0.rs index 43e6032..63e1871 100644 --- a/crates/octoscript-makepad/src/l0.rs +++ b/crates/octoscript-makepad/src/l0.rs @@ -40,7 +40,12 @@ pub fn inspectable(tree: &mut octoscript_render::UiNode) -> Vec Result { - let report = octoscript_ui_l0::realize(card, data, Default::default()); + prepare_with_state(card, data, &Default::default(), dir) +} + +/// Stateful hosts use the same kit pipeline as static previews. +pub fn prepare_with_state(card: &str, data: &serde_json::Value, state: &octoscript_ui_l0::InstanceStore, dir: &Path) -> Result { + let report = octoscript_ui_l0::realize_with_state(card, data, state, Default::default()); let root = report.complete_root()?; let mood = octoscript_ui_l0::card_theme(card).unwrap_or_else(|| "dark".into()); if octoscript_ui_l0::kit_pack::contains(root) { diff --git a/crates/octoscript-makepad/src/lib.rs b/crates/octoscript-makepad/src/lib.rs index d15f634..e83b543 100644 --- a/crates/octoscript-makepad/src/lib.rs +++ b/crates/octoscript-makepad/src/lib.rs @@ -780,11 +780,14 @@ fn emit_attrs(node: &UiNode, out: &mut String, depth: usize, resolved: bool) { } // `tapto` wires an on_click that writes the route into the `nav_signal` // widget; the host app reads that text and re-mounts the target screen. - if let Some(target) = a.tapto.as_ref().filter(|t| !t.is_empty()) { - let _ = writeln!( - out, - "{ind}on_click: || {{ NAV(t: {target:?}) }}" - ); + if matches!(node.kind, NodeKind::Input | NodeKind::Textarea) { + for (property, route) in [("on_change", &a.changeto), ("on_return", &a.tapto)] { + if let Some(target) = route.as_ref().filter(|t| !t.is_empty()) { + let _ = writeln!(out, "{ind}{property}: fn(text) {{ NAV(t: {target:?}, v: text) }}"); + } + } + } else if let Some(target) = a.tapto.as_ref().filter(|t| !t.is_empty()) { + let _ = writeln!(out, "{ind}on_click: || {{ NAV(t: {target:?}) }}"); } if let Some(s) = a.size { // The DSL states type sizes in sp, as Material does; makepad's font_size @@ -820,10 +823,10 @@ fn emit_attrs(node: &UiNode, out: &mut String, depth: usize, resolved: bool) { // also tried and is marginally worse without moving `adaptive`. let w = a.weight.unwrap_or(400).max(1) as f32; let font = a.font_src.as_deref().filter(|s|!s.is_empty()) - .unwrap_or("self:resources/Roboto-Regular.ttf"); + .unwrap_or("makepad_widgets:resources/Roboto-Regular.ttf"); let _ = writeln!( out, - "{ind}draw_text.text_style: TextStyle{{ font_family: FontFamily{{ latin := FontMember{{res: crate_resource({font:?}) asc: -0.1 desc: 0.0 weight: {w}}} }} line_spacing: 1.45 font_size: {s} }}" + "{ind}draw_text.text_style: TextStyle{{ font_family: FontFamily{{ latin := FontMember{{res: crate_resource({font:?}) asc: -0.1 desc: 0.0 weight: {w}}} cjk := FontMember{{res: crate_resource(\"makepad_widgets:resources/LXGWWenKaiRegular.ttf\") asc: 0.0 desc: 0.0}} emoji := FontMember{{res: crate_resource(\"makepad_widgets:resources/NotoColorEmoji.ttf\") asc: 0.0 desc: 0.0}} }} line_spacing: 1.45 font_size: {s} }}" ); } else if a.icon == Some(1) { let _ = writeln!( diff --git a/runtime.json b/runtime.json index e19e0e1..bf3539d 100644 --- a/runtime.json +++ b/runtime.json @@ -3,7 +3,7 @@ "repositories": { "makepad": { "url": "https://github.com/OctoSense-org/makepad.git", - "revision": "1d3d383e84a66dbb18a4a860f505430c9d5b20f4" + "revision": "3fda5b6f9b48f390bd5396938a95d30ad035cd6d" }, "octoscript": { "url": "https://github.com/OctoSense-org/Octoscript.git",