using System; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; using UnityEngine.UIElements; using Button = UnityEngine.UI.Button; using Image = UnityEngine.UI.Image; namespace ADOFAIRenderer.UI; internal class DialogButton { // ReSharper disable FieldCanBeMadeReadOnly.Global public string Text; public Action OnClick; public Color? BackgroundColor; // ReSharper restore FieldCanBeMadeReadOnly.Global public DialogButton(string text, Action onClick, Color? backgroundColor = null) { Text = text; OnClick = onClick; BackgroundColor = backgroundColor; } } internal class CommonWarningDialogUI : MonoBehaviour { public static CommonWarningDialogUI? Instance { get; private set; } private readonly List _disabledElements = new(); private void Awake() { Instance = this; } private void OnDestroy() { foreach (var elem in _disabledElements) { if (elem != null) { elem.SetEnabled(true); } } _disabledElements.Clear(); if (Instance == this) { Instance = null; } } public static void ShowDialog(string title, string description, params DialogButton[] buttons) { if (buttons.Length == 0) return; var obj = new GameObject("CommonWarningDialogUI"); DontDestroyOnLoad(obj); var dialog = obj.AddComponent(); dialog.Initialize(title, description, buttons); } private void Initialize(string title, string description, DialogButton[] buttons) { if (!UnityEngine.EventSystems.EventSystem.current) { var eventSystemObj = new GameObject("EventSystem"); eventSystemObj.transform.SetParent(transform); eventSystemObj.AddComponent(); eventSystemObj.AddComponent(); } foreach (var doc in FindObjectsByType(FindObjectsSortMode.None)) { if (doc && doc.rootVisualElement is { enabledSelf: true }) { doc.rootVisualElement.SetEnabled(false); _disabledElements.Add(doc.rootVisualElement); } } // Set UI layer (5) gameObject.layer = 5; // Canvas setup var canvas = gameObject.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.sortingOrder = 32766; // Just below FFmpegDownloadUI (32767) // Responsive Canvas Scaler setup var scaler = gameObject.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1920, 1080); scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight; scaler.matchWidthOrHeight = 0.5f; gameObject.AddComponent(); // 1. Create full screen overlay background var bgPanelObj = new GameObject("BackgroundPanel"); bgPanelObj.transform.SetParent(transform, false); bgPanelObj.layer = 5; var bgImage = bgPanelObj.AddComponent(); bgImage.color = new Color(0f, 0f, 0f, 0.65f); // Dark transparent overlay bgImage.raycastTarget = true; var bgRect = bgPanelObj.GetComponent(); bgRect.anchorMin = Vector2.zero; bgRect.anchorMax = Vector2.one; bgRect.offsetMin = Vector2.zero; bgRect.offsetMax = Vector2.zero; var font = ModAssets.NanumSquareNeoNormal; // 2. Create modal container var modalContainerObj = new GameObject("ModalContainer"); modalContainerObj.transform.SetParent(bgPanelObj.transform, false); modalContainerObj.layer = 5; var modalImage = modalContainerObj.AddComponent(); modalImage.color = new Color(0.08f, 0.08f, 0.1f, 0.88f); // Matching background tone of existing UI var modalOutline = modalContainerObj.AddComponent(); modalOutline.effectColor = Color.white; modalOutline.effectDistance = new Vector2(3.0f, -3.0f); // Consistent with existing UI outline style var modalRect = modalContainerObj.GetComponent(); modalRect.anchorMin = new Vector2(0.5f, 0.5f); modalRect.anchorMax = new Vector2(0.5f, 0.5f); modalRect.pivot = new Vector2(0.5f, 0.5f); modalRect.sizeDelta = new Vector2(650, 360); // 3. Create title text var titleObj = new GameObject("TitleText"); titleObj.transform.SetParent(modalContainerObj.transform, false); titleObj.layer = 5; var titleText = titleObj.AddComponent(); titleText.text = title; titleText.fontSize = 24; titleText.font = font; titleText.color = new Color(1.0f, 0.8f, 0.2f, 1.0f); // Orange/yellow tone matching warning theme titleText.alignment = TextAlignmentOptions.Center; var titleRect = titleObj.GetComponent(); titleRect.anchorMin = new Vector2(0, 1); titleRect.anchorMax = new Vector2(1, 1); titleRect.pivot = new Vector2(0.5f, 1); titleRect.anchoredPosition = new Vector2(0, -35); titleRect.sizeDelta = new Vector2(0, 40); // 4. Create description text var descObj = new GameObject("DescriptionText"); descObj.transform.SetParent(modalContainerObj.transform, false); descObj.layer = 5; var descText = descObj.AddComponent(); descText.text = description; descText.fontSize = 20; descText.font = font; descText.color = new Color(0.85f, 0.85f, 0.85f, 1f); descText.alignment = TextAlignmentOptions.Center; descText.lineSpacing = 8; var descRect = descObj.GetComponent(); descRect.anchorMin = new Vector2(0, 0.5f); descRect.anchorMax = new Vector2(1, 1); descRect.pivot = new Vector2(0.5f, 0.5f); descRect.anchoredPosition = new Vector2(0, -65); descRect.sizeDelta = new Vector2(-40, 120); // 5. Create button container var buttonContainerObj = new GameObject("ButtonContainer", typeof(RectTransform)); buttonContainerObj.transform.SetParent(modalContainerObj.transform, false); buttonContainerObj.layer = 5; var btnContainerRect = buttonContainerObj.GetComponent(); btnContainerRect.anchorMin = new Vector2(0, 0); btnContainerRect.anchorMax = new Vector2(1, 0); btnContainerRect.pivot = new Vector2(0.5f, 0); btnContainerRect.anchoredPosition = new Vector2(0, 35); btnContainerRect.sizeDelta = new Vector2(0, 50); // 6. Dynamic button layout and styling float totalWidth = 560f; float spacing = 15f; float buttonHeight = 45f; int numButtons = buttons.Length; float buttonWidth = numButtons == 1 ? 200f : (totalWidth - (spacing * (numButtons - 1))) / numButtons; float startX = numButtons == 1 ? 0 : (-totalWidth / 2f) + (buttonWidth / 2f); for (int i = 0; i < numButtons; i++) { var btnData = buttons[i]; var btnObj = new GameObject($"Button_{i}"); btnObj.transform.SetParent(buttonContainerObj.transform, false); btnObj.layer = 5; // Define default colors Color baseColor = btnData.BackgroundColor ?? new Color(0.2f, 0.2f, 0.23f, 1f); // Custom color or gray default Color hoverColor = ApplyColorBrightness(baseColor, 1.2f); Color pressedColor = ApplyColorBrightness(baseColor, 0.8f); var btnImage = btnObj.AddComponent(); btnImage.color = baseColor; btnImage.raycastTarget = true; var btn = btnObj.AddComponent