From 4d0cbe0185bdc4fc65eb63503a7c5cb578539669 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 15 Jul 2026 09:39:11 +0100 Subject: [PATCH] Lower provider-authored cockpit overlays --- .../README.md | 7 ++++ .../Runtime/EveUiToolkitSurfaceLowerer.cs | 38 +++++++++++++++++-- .../Editor/EveUiToolkitSurfaceLowererTests.cs | 30 +++++++++++++++ .../package.json | 2 +- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/packages/org.gamecult.eve.unity-uitoolkit/README.md b/packages/org.gamecult.eve.unity-uitoolkit/README.md index a0b325c..cf788bd 100644 --- a/packages/org.gamecult.eve.unity-uitoolkit/README.md +++ b/packages/org.gamecult.eve.unity-uitoolkit/README.md @@ -27,6 +27,13 @@ Nested CultUI regions use component `EmbeddedDocuments`. Pass an mounts the resolved child surface under the slot while preserving the child document's command surface id. +`progress` components lower to native UI Toolkit `ProgressBar` elements. The +provider supplies a normalized `ratio` (falling back to `value`), label, and +layout; Unity clamps the native visual to `[0,1]` without becoming the value +authority. Generated layout supports relative or absolute positioning plus +`inset`, `top`, `right`, `bottom`, and `left`, so provider-authored overlays +can compose over scene lowerers without consumer-specific HUD code. + Discovery and test coverage for this feature live in the shared Eve parity matrix: `../../tools/parity/parity-manifest.json` names `embeddedDocuments` and `../../web/fixtures/cultui-embedded-surface.json` is the canonical fixture. diff --git a/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs index f989ccf..6586d67 100644 --- a/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs +++ b/packages/org.gamecult.eve.unity-uitoolkit/Runtime/EveUiToolkitSurfaceLowerer.cs @@ -129,11 +129,14 @@ namespace GameCult.Eve.UnityUIToolkit } case "progress": { - var progress = new VisualElement(); + var progress = new ProgressBar + { + title = component.GetProp("label"), + lowValue = 0f, + highValue = 1f, + value = ParseRatio(component.GetProp("ratio", component.GetProp("value"))) + }; progress.AddToClassList("eve-progress"); - progress.style.flexDirection = FlexDirection.Column; - progress.Add(MutedLabel(component.GetProp("label"))); - progress.Add(ValueLabel(component.GetProp("value"))); return progress; } case "options": @@ -313,6 +316,26 @@ namespace GameCult.Eve.UnityUIToolkit element.style.display = string.Equals(display, "none", StringComparison.OrdinalIgnoreCase) ? DisplayStyle.None : DisplayStyle.Flex; + if (TryGet(layout, "position", out var position)) + element.style.position = string.Equals(position, "absolute", StringComparison.OrdinalIgnoreCase) + ? Position.Absolute + : Position.Relative; + if (TryGet(layout, "inset", out var inset)) + { + var value = ParseLength(inset); + element.style.top = value; + element.style.right = value; + element.style.bottom = value; + element.style.left = value; + } + if (TryGet(layout, "top", out var top)) + element.style.top = ParseLength(top); + if (TryGet(layout, "right", out var right)) + element.style.right = ParseLength(right); + if (TryGet(layout, "bottom", out var bottom)) + element.style.bottom = ParseLength(bottom); + if (TryGet(layout, "left", out var left)) + element.style.left = ParseLength(left); if (TryGet(layout, "direction", out var direction)) { if (string.Equals(direction, "horizontal", StringComparison.OrdinalIgnoreCase) || @@ -430,6 +453,13 @@ namespace GameCult.Eve.UnityUIToolkit : StyleKeyword.Null; } + private static float ParseRatio(string value) + { + return float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var ratio) + ? Mathf.Clamp01(ratio) + : 0f; + } + private static void ApplyBoxLength(string value, Action apply) { apply(ParseLength(value)); diff --git a/packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs b/packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs index a9d88fb..0b9dc54 100644 --- a/packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs +++ b/packages/org.gamecult.eve.unity-uitoolkit/Tests/Editor/EveUiToolkitSurfaceLowererTests.cs @@ -112,6 +112,36 @@ namespace GameCult.Eve.UnityUIToolkit.Tests Assert.That(embedded.ClassListContains("eve-embedded-kind-inline"), Is.True); } + [Test] + public void ProgressAndAbsoluteLayoutLowerToNativeUiToolkitPrimitives() + { + var progress = new EveSurfaceComponent( + "hull", + "progress", + new Dictionary + { + ["label"] = "Hull", + ["ratio"] = "0.625" + }, + Array.Empty(), + Array.Empty(), + Array.Empty(), + new Dictionary + { + ["position"] = "absolute", + ["right"] = "24", + ["bottom"] = "32" + }); + + var root = new EveUiToolkitSurfaceLowerer().Lower(Document(progress)); + + Assert.That(root, Is.TypeOf()); + Assert.That(((ProgressBar)root).value, Is.EqualTo(0.625f)); + Assert.That(root.style.position.value, Is.EqualTo(Position.Absolute)); + Assert.That(root.style.right.value.value, Is.EqualTo(24f)); + Assert.That(root.style.bottom.value.value, Is.EqualTo(32f)); + } + private static EveSurfaceDocument Document(EveSurfaceComponent root, string surfaceId = "test-surface") { return new EveSurfaceDocument( diff --git a/packages/org.gamecult.eve.unity-uitoolkit/package.json b/packages/org.gamecult.eve.unity-uitoolkit/package.json index cf91087..ee02cd0 100644 --- a/packages/org.gamecult.eve.unity-uitoolkit/package.json +++ b/packages/org.gamecult.eve.unity-uitoolkit/package.json @@ -1,7 +1,7 @@ { "name": "org.gamecult.eve.unity-uitoolkit", "displayName": "Eve UI Toolkit Lowering", - "version": "0.1.0", + "version": "0.1.1", "unity": "2021.3", "description": "Unity UI Toolkit lowering for gamecult.eve.surface.v1 documents.", "dependencies": {