using UnityEngine; using UnityEngine.UI; using System.Collections; using TMPro; public class Dashboard : MonoBehaviour { [Header("Pages")] [SerializeField] private GameObject startPage; [SerializeField] private GameObject page1; [SerializeField] private GameObject page2; [Header("Client")] [SerializeField] private GameObject clientMenu; [SerializeField] private TMP_InputField clientNameInput; [SerializeField] private TMP_InputField clientEmailInput; [Header("Page 1")] [SerializeField] private ToggleGroup page1ToggleGroup; [SerializeField] private Section[] page1Sections; [SerializeField] private GameObject selectionShapeContainer; [Tooltip("Le ShapeRecipe du panneau Shapes : c'est lui qui pilote son bouton Next.")] [SerializeField] private ShapeRecipe shapeRecipe; [SerializeField, Range(0f, 1f)] private float lockedAlpha = 0.5f; [Header("Calcul avant Page 2")] [SerializeField] private GameObject calculatingOverlay; [SerializeField] private Image calculatingBar; [SerializeField] private TMP_Text calculatingPercent; [SerializeField] private float calculatingDuration = 5f; [System.Serializable] private class Section { public Toggle toggle; public GameObject panel; [System.NonSerialized] public CanvasGroup canvasGroup; } private int _page1Progress; private Coroutine _calculating; void Start() { foreach (Section section in page1Sections) { if (section.toggle == null) continue; section.canvasGroup = section.toggle.GetComponent(); section.toggle.onValueChanged.AddListener(_ => RefreshPage1Panels()); } RefreshPage1Panels(); ResetPage1(); ShowStartPage(); } void Update() { // Le container de formes n'apparaît qu'une fois au moins une forme choisie. bool hasShapes = _G.SHAPE_SELECTIONS.Count > 0; if (selectionShapeContainer != null && selectionShapeContainer.activeSelf != hasShapes) selectionShapeContainer.SetActive(hasShapes); // Le bouton Next du panneau Shapes est piloté par ShapeRecipe, au moment // où une forme est posée. Rien ici, sinon les deux se contrediraient. } // À brancher sur le OnClick de ButtonStartNew public void OpenClientMenu() { if (clientNameInput != null) clientNameInput.text = ""; if (clientEmailInput != null) clientEmailInput.text = ""; if (clientMenu != null) clientMenu.SetActive(true); } public void CloseClientMenu() { if (clientMenu != null) clientMenu.SetActive(false); } // À brancher sur le bouton de validation du menu client public void StartNewProject() { _G.CLIENT_NAME = clientNameInput != null ? clientNameInput.text.Trim() : ""; _G.CLIENT_EMAIL = clientEmailInput != null ? clientEmailInput.text.Trim() : ""; CloseClientMenu(); ClearPage1Selection(); ResetPage1(); ShowPage(page1); } public void ShowStartPage() { CloseClientMenu(); ShowPage(startPage); } // À brancher sur le bouton de Page 1 qui mène à la facture public void OpenPage2() { if (_calculating != null) return; _calculating = StartCoroutine(CalculateThenShowPage2()); } private IEnumerator CalculateThenShowPage2() { if (calculatingOverlay != null) calculatingOverlay.SetActive(true); float elapsed = 0f; while (elapsed < calculatingDuration) { elapsed += Time.deltaTime; float progress = Mathf.Clamp01(elapsed / calculatingDuration); if (calculatingBar != null) calculatingBar.fillAmount = progress; if (calculatingPercent != null) calculatingPercent.text = Mathf.RoundToInt(progress * 100f) + " %"; yield return null; } if (calculatingOverlay != null) calculatingOverlay.SetActive(false); _calculating = null; ShowPage(page2); } // À brancher sur le OnClick du Background de Page 1 public void ClearPage1Selection() { ToggleGroup group = page1ToggleGroup; if (group == null && page1 != null) group = page1.GetComponentInChildren(true); if (group != null) group.SetAllTogglesOff(); if (page1 == null) { Debug.LogWarning("Dashboard : le champ Page 1 n'est pas assigné.", this); return; } // Filet de sécurité pour les toggles qui ne sont rattachés à aucun groupe. Toggle[] toggles = page1.GetComponentsInChildren(true); foreach (Toggle toggle in toggles) { if (toggle.group == null) toggle.isOn = false; } if (group == null && toggles.Length == 0) Debug.LogWarning("Dashboard : aucun Toggle trouvé sous Page 1.", this); RefreshPage1Panels(); } // État de départ de Page 1 : aucune forme choisie, ouverte sur le premier panneau. private void ResetPage1() { // ShapeRecipe désactive les formes du container, vide les sélections et // rebloque son Next. Sans lui, on ne vide au moins que la liste. if (shapeRecipe != null) shapeRecipe.ClearSelection(); else _G.SHAPE_SELECTIONS.Clear(); if (selectionShapeContainer != null) selectionShapeContainer.SetActive(false); _page1Progress = 0; RefreshPage1Lock(); if (page1Sections.Length > 0 && page1Sections[0].toggle != null) page1Sections[0].toggle.isOn = true; RefreshPage1Panels(); } // À brancher sur le bouton Next de chaque panneau public void NextPanel() { int current = CurrentSectionIndex(); if (current < 0) return; // On ne quitte le panneau Shapes qu'une fois une forme choisie. if (current == 0 && _G.SHAPE_SELECTIONS.Count == 0) return; GoToSection(current + 1); } public void GoToSection(int index) { if (index < 0 || index >= page1Sections.Length) return; if (index > _page1Progress) { _page1Progress = index; RefreshPage1Lock(); } Toggle toggle = page1Sections[index].toggle; if (toggle != null) toggle.isOn = true; } private int CurrentSectionIndex() { for (int i = 0; i < page1Sections.Length; i++) { Toggle toggle = page1Sections[i].toggle; if (toggle != null && toggle.isOn) return i; } return -1; } // Seules les sections déjà atteintes sont utilisables. private void RefreshPage1Lock() { for (int i = 0; i < page1Sections.Length; i++) SetSectionInteractable(page1Sections[i], i <= _page1Progress); } private void SetSectionInteractable(Section section, bool interactable) { if (section.canvasGroup != null) { section.canvasGroup.interactable = interactable; section.canvasGroup.alpha = interactable ? 1f : lockedAlpha; } else if (section.toggle != null) section.toggle.interactable = interactable; } // Chaque panneau suit l'état de son toggle : Shapes coché => Panel Shape visible. private void RefreshPage1Panels() { foreach (Section section in page1Sections) { if (section.panel == null) continue; section.panel.SetActive(section.toggle != null && section.toggle.isOn); } } private void ShowPage(GameObject page) { if (startPage != null) startPage.SetActive(page == startPage); if (page1 != null) page1.SetActive(page == page1); if (page2 != null) page2.SetActive(page == page2); } }