using System.Collections.Generic; using Uigenx.Bridge; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace Uigenx.Editor { /// /// Project Settings page for UI Creator. Shows whether a daemon token was found but never the /// token itself, and writes only , which is safe to commit. /// public static class UgxSettingsProvider { public const string Path = "Project/UI Creator"; [SettingsProvider] public static SettingsProvider Create() { return new SettingsProvider(Path, SettingsScope.Project) { label = "UI Creator", keywords = new HashSet { "uigenx", "ui creator", "uxml", "uss", "bridge", "daemon", "studio", }, activateHandler = (searchContext, root) => Build(root), }; } static void Build(VisualElement root) { var settings = UgxProjectSettings.Load(); root.style.paddingLeft = 10f; root.style.paddingRight = 10f; root.style.paddingTop = 8f; var title = new Label("UI Creator") { style = { unityFontStyleAndWeight = FontStyle.Bold } }; title.style.marginBottom = 8f; root.Add(title); var projectField = new TextField("UI Creator project") { value = settings.UgxProject, tooltip = "Path to the UI Creator project folder, relative to this Unity project.", // Delayed so the file is written when the field is committed, not per keystroke. isDelayed = true, }; root.Add(projectField); var status = new Label(); status.style.marginBottom = 8f; root.Add(status); var uiFolderField = new TextField("UI folder") { value = settings.UiFolder, tooltip = "Folder under Assets/ that exports are written to.", isDelayed = true, }; root.Add(uiFolderField); var bridgeToggle = new Toggle("Bridge enabled") { value = settings.BridgeEnabled }; root.Add(bridgeToggle); var hzField = new FloatField("Data stream Hz") { value = settings.StreamHz, isDelayed = true }; root.Add(hzField); var tokenStatus = new Label(); tokenStatus.style.marginTop = 8f; root.Add(tokenStatus); var bridgeStatus = new Label(); root.Add(bridgeStatus); void Refresh() { var resolved = settings.ResolveUicProjectPath(); status.text = resolved == null ? "No folder at that path." : "Found: " + resolved; var daemon = resolved == null ? null : UgxDaemonInfo.Load(resolved); tokenStatus.text = daemon == null ? "Daemon: not running (no .uigenx/daemon.json)." : "Daemon: " + daemon.ResolveUrl() + ", token " + (string.IsNullOrEmpty(daemon.Token) ? "missing" : "found"); bridgeStatus.text = "Bridge: " + UgxEditorBridge.State; } void Save() { settings.UgxProject = projectField.value; settings.UiFolder = uiFolderField.value; settings.BridgeEnabled = bridgeToggle.value; settings.StreamHz = Mathf.Clamp(hzField.value, 1f, 240f); hzField.SetValueWithoutNotify(settings.StreamHz); settings.Save(); Refresh(); } projectField.RegisterValueChangedCallback(_ => Save()); uiFolderField.RegisterValueChangedCallback(_ => Save()); bridgeToggle.RegisterValueChangedCallback(_ => Save()); hzField.RegisterValueChangedCallback(_ => Save()); var buttons = new VisualElement { style = { flexDirection = FlexDirection.Row, marginTop = 10f } }; buttons.Add(new Button(() => { UgxEditorBridge.Connect(); Refresh(); }) { text = "Connect" }); buttons.Add(new Button(() => { UgxEditorBridge.Stop(); Refresh(); }) { text = "Disconnect" }); buttons.Add(new Button(Refresh) { text = "Refresh" }); root.Add(buttons); Refresh(); } } }