diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIDialog.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIDialog.cs index e1a564978d..2490475da9 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIDialog.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/AUIDialog.cs @@ -355,5 +355,10 @@ namespace BrewMonster.UI { m_bUpdateRenderTarget = false; } + + public virtual void CloseDialogue() + { + CECUIManager.Instance.HideCurrentUIInStack(); + } } } diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgInstall.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgInstall.cs index 7d3f70bb4e..c5169a8b3e 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgInstall.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgInstall.cs @@ -589,7 +589,7 @@ namespace BrewMonster var host = GetHostPlayer(); host?.EndNPCService(); host?.GetPack(InventoryConst.IVTRTYPE_PACK).UnfreezeAllItems(); - gameObject.SetActive(false); + CloseDialogue(); } @@ -654,5 +654,10 @@ namespace BrewMonster } } } + + public void ShowTest(bool isStack) + { + CECUIManager.Instance.ShowUI("Win_Disenchase",isStack); + } } } \ No newline at end of file diff --git a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs index 2c791c6861..0ca4a7456b 100644 --- a/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs +++ b/Assets/PerfectWorld/Scripts/UI/Dialogs/DlgNPC.cs @@ -3411,8 +3411,9 @@ namespace BrewMonster.UI { uint npcID = pCurNPCEssence.Value.id; - var dlgInstall =GetGameUIMan().GetDialog("Win_Enchase"); - dlgInstall.Show(true); + // var dlgInstall =GetGameUIMan().GetDialog("Win_Enchase"); + // dlgInstall.Show(true); + CECUIManager.Instance.ShowUI("Win_Enchase",true); } //pShow1 = m_pAUIManager.GetDialog("Win_Enchase"); //pShow2 = m_pAUIManager.GetDialog("Win_Inventory"); diff --git a/Assets/Scripts/CECUIManager.cs b/Assets/Scripts/CECUIManager.cs index 04de9b1ca7..6ce2c282b8 100644 --- a/Assets/Scripts/CECUIManager.cs +++ b/Assets/Scripts/CECUIManager.cs @@ -12,7 +12,10 @@ public class CECUIManager : MonoSingleton [SerializeField] private TMP_Text _fpsText; [SerializeField] private List uiPrefabs; // drag các prefab UI vào đây - private readonly Dictionary _spawnedUIs = new(); + private readonly Dictionary _spawnedUIs = new(); + + /// Stack of dialog names (front = index 0 = top / currently on top). + private readonly List _uiStack = new(); [SerializeField] private HUDNPC npsUI; @@ -135,19 +138,138 @@ public class CECUIManager : MonoSingleton } /// - /// Show UI by name of component ("DlgTask", "EC_InventoryUI") + /// Show UI by name of component ("DlgTask", "EC_InventoryUI"). When isStack is true, pushes the dialog onto the UI stack (brings to front and tracks for Pop). /// - /// name of component ("DlgTask", "EC_InventoryUI") - public void ShowUI(string componentName) + /// Name of component ("DlgTask", "EC_InventoryUI") + /// If true, push onto stack (show + SetAsLastSibling + track); if false, just show. + /// just hide current ui- not pop + public void ShowUI(string componentName, bool isStack = true, bool hideCurrentUI = true) { if (string.IsNullOrEmpty(componentName) || canvasDlg == null) { if (canvasDlg == null) Debug.LogError("canvasDlg chưa được gán"); return; } + if (hideCurrentUI) + { + var currentDialogue = GetCurrentDialog(); + if(currentDialogue !=null) + { + currentDialogue.Show(false); + } + } - GetInGameUIMan().GetDialog(componentName).Show(true); + if (isStack) + { + Push(componentName); + return; + } + + var dialogue = GetInGameUIMan().GetDialog(componentName); + dialogue.Show(true); + dialogue.transform.SetAsLastSibling(); } + public void HideCurrentUIInStack() + { + var currentDialogue = GetCurrentDialog(); + Debug.Log(_uiStack.Count); + Pop(); + Debug.Log(_uiStack.Count); + //show next one + currentDialogue = GetCurrentDialog(); + if(currentDialogue !=null) + { + currentDialogue.Show(true); + } + } + + /// + /// Push a dialog onto the UI stack: show it, add to front of stack, and SetAsLastSibling so it draws on top. If already in stack, moves it to front. + /// + private void Push(string componentName) + { + if (string.IsNullOrEmpty(componentName) || canvasDlg == null) return; + + _uiStack.Remove(componentName); + + var dlg = GetInGameUIMan().GetDialog(componentName); + if (dlg == null) return; + + dlg.Show(true); + _uiStack.Insert(0, componentName); + dlg.transform.SetAsLastSibling(); + } + + /// + /// Pop the top dialog off the stack: hide it and bring the new top (if any) to front. Returns true if something was popped. + /// + private bool Pop() + { + if (_uiStack.Count == 0) return false; + + string top = _uiStack[0]; + _uiStack.RemoveAt(0); + + var dlg = GetInGameUIMan().GetDialog(top); + if (dlg != null) + dlg.Show(false); + + if (_uiStack.Count > 0) + { + var newTop = GetInGameUIMan().GetDialog(_uiStack[0]); + if (newTop != null) + newTop.transform.SetAsLastSibling(); + } + + return true; + } + + /// Returns the name of the dialog currently on top of the stack, or null if stack is empty. + public string GetCurrentUI() + { + if (_uiStack.Count == 0) return null; + return _uiStack[0]; + } + + /// Returns the dialog instance currently on top of the stack, or null if stack is empty. + public AUIDialog GetCurrentDialog() + { + var name = GetCurrentUI(); + if (name == null) return null; + return GetInGameUIMan().GetDialog(name); + } + + /// Returns the number of dialogs in the stack (0 when empty). + public int GetStackCount() => _uiStack.Count; + + /// Returns true if the given dialog name is in the stack. + public bool IsInStack(string componentName) + { + return !string.IsNullOrEmpty(componentName) && _uiStack.Contains(componentName); + } + + /// Returns the dialog name at the given index (0 = top) without removing. Returns null if index is out of range. + public string PeekStack(int index = 0) + { + if (index < 0 || index >= _uiStack.Count) return null; + return _uiStack[index]; + } + + /// Clears the entire stack. If hideAll is true, hides every dialog in the stack before clearing. + public void ClearStack(bool hideAll = true) + { + if (hideAll) + { + var gui = GetInGameUIMan(); + foreach (string name in _uiStack) + { + var dlg = gui?.GetDialog(name); + if (dlg != null) dlg.Show(false); + } + } + _uiStack.Clear(); + } + public CDlgMessageBox ShowMessageBox(MessageBoxData messageBoxData) { var msgBox = GetInGameUIMan().GetDialog("DlgMessageBox") as CDlgMessageBox;