using Aisu.SIM1.Face.Core; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Aisu.SIM1.Face.UI.Common { /// /// Demo 场景运行时构建器。 /// public sealed class FaceModuleDemoBootstrap : MonoBehaviour { #region Unity API /// /// 执行 Awake 方法。 /// private void Awake() { Build(); } #endregion /// /// 构建完整 UGUI 页面。 /// public void Build() { if (FindObjectOfType() == null) { var eventSystem = new GameObject("EventSystem"); eventSystem.AddComponent(); eventSystem.AddComponent(); } var font = Resources.GetBuiltinResource("Arial.ttf"); var builder = new FaceModuleUiBuilder(font); var manager = FindObjectOfType() ?? new GameObject("FaceModuleManager").AddComponent(); var canvasGo = FaceModuleUiBuilder.Create("Canvas", transform); var canvas = canvasGo.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvasGo.AddComponent(); var scaler = canvasGo.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1920, 1080); var safe = FaceModuleUiBuilder.Create("SafeArea", canvasGo.transform); FaceModuleUiBuilder.Stretch(safe.GetComponent()); var safeLayout = safe.AddComponent(); safeLayout.padding = new RectOffset(16, 16, 16, 16); safeLayout.spacing = 12; safeLayout.childControlWidth = true; safeLayout.childForceExpandWidth = true; var top = FaceModuleUiBuilder.Create("TopStatusBar", safe.transform); top.AddComponent().color = new Color(0.9f, 0.94f, 0.97f); var topLayoutElement = top.AddComponent(); topLayoutElement.preferredHeight = 54; var topLayout = top.AddComponent(); topLayout.padding = new RectOffset(12, 12, 8, 8); topLayout.spacing = 20; var statusBar = top.AddComponent(); statusBar.Bind( builder.Text(top.transform, "未连接", 20), builder.Text(top.transform, "未 READY", 20), builder.Text(top.transform, "状态: Invalid", 20), builder.Text(top.transform, "命令:", 20), builder.Text(top.transform, "错误:", 20)); var body = FaceModuleUiBuilder.Create("Body", safe.transform); var bodyLayoutElement = body.AddComponent(); bodyLayoutElement.flexibleHeight = 1; var bodyLayout = body.AddComponent(); bodyLayout.spacing = 12; bodyLayout.childControlHeight = true; bodyLayout.childForceExpandHeight = true; var navigation = FaceModuleUiBuilder.Create("NavigationPanel", body.transform).AddComponent(); navigation.gameObject.AddComponent().color = new Color(0.86f, 0.9f, 0.94f); var navLayoutElement = navigation.gameObject.AddComponent(); navLayoutElement.preferredWidth = 240; var navLayout = navigation.gameObject.AddComponent(); navLayout.padding = new RectOffset(10, 10, 10, 10); navLayout.spacing = 8; var pageContainer = FaceModuleUiBuilder.Create("PageContainer", body.transform); pageContainer.AddComponent().color = new Color(0.98f, 0.99f, 1f); pageContainer.AddComponent().flexibleWidth = 1; var bottom = FaceModuleUiBuilder.Create("BottomLogPanel", safe.transform); bottom.AddComponent().color = new Color(0.08f, 0.09f, 0.1f); bottom.AddComponent().preferredHeight = 220; var bottomLayout = bottom.AddComponent(); bottomLayout.padding = new RectOffset(8, 8, 8, 8); bottomLayout.spacing = 6; var logPanel = bottom.AddComponent(); var autoScroll = builder.Toggle(bottom.transform, "自动滚动", true); var scroll = builder.ScrollView(bottom.transform, out var logText); logText.color = Color.white; logPanel.Bind(logText, scroll, autoScroll); var logButtons = builder.Row(bottom.transform); builder.Button(logButtons.transform, "清空日志", logPanel.Clear); builder.Button(logButtons.transform, "保存日志", logPanel.Save); var loadingGo = FaceModuleUiBuilder.Create("LoadingView", canvasGo.transform); loadingGo.AddComponent().color = new Color(0, 0, 0, 0.25f); FaceModuleUiBuilder.Stretch(loadingGo.GetComponent()); var loadingLayout = loadingGo.AddComponent(); loadingLayout.childAlignment = TextAnchor.MiddleCenter; var loading = loadingGo.AddComponent(); loading.Bind(builder.Text(loadingGo.transform, "处理中...", 28, TextAnchor.MiddleCenter), builder.Slider(loadingGo.transform)); var dialogGo = FaceModuleUiBuilder.Create("ConfirmDialog", canvasGo.transform); dialogGo.AddComponent().color = new Color(0, 0, 0, 0.35f); FaceModuleUiBuilder.Stretch(dialogGo.GetComponent()); var dialogLayout = dialogGo.AddComponent(); dialogLayout.childAlignment = TextAnchor.MiddleCenter; dialogLayout.spacing = 12; var dialog = dialogGo.AddComponent(); var dialogText = builder.Text(dialogGo.transform, "确认操作?", 26, TextAnchor.MiddleCenter); var dialogButtons = builder.Row(dialogGo.transform); var confirmButton = builder.Button(dialogButtons.transform, "确认", () => { }); var cancelButton = builder.Button(dialogButtons.transform, "取消", () => { }); dialog.Bind(dialogText, confirmButton, cancelButton); var mainPanel = canvasGo.AddComponent(); mainPanel.Bind(statusBar, navigation, logPanel, loading); BuildPages(pageContainer.transform, builder, mainPanel); mainPanel.Init(manager); mainPanel.ShowPage("Connect"); } /// /// 构建 Demo 功能页面。 /// private void BuildPages(Transform pageContainer, FaceModuleUiBuilder builder, FaceModuleMainPanel mainPanel) { AddPage(pageContainer, builder, mainPanel, "Connect", "连接"); AddPage(pageContainer, builder, mainPanel, "ProtocolDebug", "协议调试"); AddPage(pageContainer, builder, mainPanel, "Verify", "人脸验证"); AddPage(pageContainer, builder, mainPanel, "Enroll", "人脸录入"); AddPage(pageContainer, builder, mainPanel, "UserManage", "用户管理"); AddPage(pageContainer, builder, mainPanel, "QrCode", "二维码"); AddPage(pageContainer, builder, mainPanel, "Image", "图片抓拍"); AddPage(pageContainer, builder, mainPanel, "PhotoEnroll", "照片注册"); AddPage(pageContainer, builder, mainPanel, "Feature", "特征管理"); AddPage(pageContainer, builder, mainPanel, "Uvc", "UVC 设置"); AddPage(pageContainer, builder, mainPanel, "Advanced", "高级设置"); AddPage(pageContainer, builder, mainPanel, "Encryption", "加密"); AddPage(pageContainer, builder, mainPanel, "Firmware", "固件升级"); } /// /// 添加 Demo 功能页面。 /// private void AddPage(Transform parent, FaceModuleUiBuilder builder, FaceModuleMainPanel mainPanel, string pageName, string label) where T : FaceModulePageBase { var pageGo = FaceModuleUiBuilder.Create(pageName + "Page", parent); FaceModuleUiBuilder.Stretch(pageGo.GetComponent()); var layout = pageGo.AddComponent(); layout.padding = new RectOffset(16, 16, 16, 16); layout.spacing = 10; layout.childControlWidth = true; layout.childForceExpandWidth = true; var page = pageGo.AddComponent(); page.Build(builder); mainPanel.RegisterPage(pageName, label, page, builder); } } }