using Cryville.Common.Unity.UI; using Cryville.Crtr.Browsing.Actions; using Cryville.Crtr.UI; using System; using System.Collections.Generic; using System.IO; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; namespace Cryville.Crtr.Browsing.UI { internal class PathedResourceBrowser : ResourceBrowser { [SerializeField] Button[] m_writeTools; [SerializeField] TextMeshProUGUI m_pathText; [SerializeField] ScrollableItemGrid m_itemContainer; [SerializeField] DetailPanel m_detailPanel; [SerializeField] ActionBar m_actionBar; [SerializeField] Sprite m_readonlyIcon; public override Sprite Icon { get { return _manager.IsReadOnly ? m_readonlyIcon : base.Icon; } } IPathedResourceManager _manager; IResourceAction _importAction; readonly IResourceAction[] _importActionArray = new IResourceAction[1]; readonly HashSet _selectedItems = new HashSet(); readonly Dictionary _items = new Dictionary(); bool _destroyed; protected virtual void Start() { m_itemContainer.LoadItem = LoadItem; } void OnDestroy() { _destroyed = true; UnregisterManager(); } void UnregisterManager() { if (_importAction != null) Master.Actions.Unregister(_importAction); _manager.ItemChanged -= OnItemChanged; _manager.DirectoryChanged -= OnDirectoryChanged; } void OnEnable() { if (_manager != null) _manager.Activate(); } void OnDisable() { if (_manager != null) _manager.Deactivate(); } public void Init(IPathedResourceManager manager) { if (_manager != null) { OnDisable(); UnregisterManager(); } _manager = manager; _manager.ItemChanged += OnItemChanged; _manager.DirectoryChanged += OnDirectoryChanged; if (!_manager.IsReadOnly) { Master.Actions.Register(_importAction = _manager.GetImportAction()); _importActionArray[0] = _importAction; } foreach (var tool in m_writeTools) tool.interactable = !_manager.IsReadOnly; OnEnable(); OnItemChanged(); OnDirectoryChanged(); } bool _itemChanged; void OnItemChanged() { _itemChanged = true; } void OnDirectoryChanged() { if (_manager.CurrentDirectory.Count == 0) m_pathText.text = "(Home)"; else m_pathText.text = string.Join(Path.DirectorySeparatorChar, _manager.CurrentDirectory); } void Update() { if (_itemChanged) { _itemChanged = false; _selectedItems.Clear(); _items.Clear(); m_itemContainer.ItemCount = _manager.Count; m_detailPanel.Clear(); m_actionBar.Clear(); } } private bool LoadItem(int id, GameObject obj) { var bi = obj.GetComponent(); _items[id] = bi; try { var item = _manager[id]; bi.Load(this, id, _manager.IsDirectory(id), item, _selectedItems.Contains(id)); } catch (Exception) { bi.Load(this, id, _manager.IsDirectory(id), null, _selectedItems.Contains(id)); } return true; } public override void OnItemClicked(int id) { if (_manager.IsDirectory(id)) { _manager.OpenDirectory(id); } else { foreach (var item in _selectedItems) _items[item].OnDeselect(); _selectedItems.Clear(); _items[id].OnSelect(); _selectedItems.Add(id); try { var res = _manager[id]; m_detailPanel.Load(res); if (_selectedItems.Count == 1) { LoadActions(_manager.GetItemUri(id), res); } } catch (Exception ex) { Popup.CreateException(ex); } } } internal override void OnActionsChanged() { if (_destroyed) return; if (_selectedItems.Count == 1) { int id = _selectedItems.Single(); LoadActions(_manager.GetItemUri(id), _manager[id]); } } void LoadActions(Uri uri, IResourceMeta res) { m_actionBar.Load(this, Master.Actions.GetActions(uri, res).Except(_importActionArray)); } public void OnPathClicked(int index) { _manager.ReturnToDirectory(index); } public void OnHomeClicked() { _manager.ChangeDirectory(Enumerable.Empty()); } public void OnParentClicked() { var depth = _manager.CurrentDirectory.Count; if (depth <= 0) return; _manager.ReturnToDirectory(_manager.CurrentDirectory.Count - 2); } public void OnSearch(string value) { _manager.ApplyFilter(value); } public void OnDeleteClicked() { if (_selectedItems.Count == 0) { Popup.Create("No item is selected."); return; } Dialog.Show(DeleteSelectedItems, "Are you sure to delete the selected item(s)?", "Yes", "No"); } void DeleteSelectedItems(int result) { if (result != 0) return; foreach (var item in _selectedItems.OrderByDescending(i => i)) _manager.RemoveAt(item); } public override void InvokeAction(IResourceAction action) { if (_selectedItems.Count == 0) { Popup.Create("No item is selected."); return; } if (_selectedItems.Count > 1) { Popup.Create("Cannot run this action with multiple items."); return; } foreach (var i in _selectedItems) { try { action.Invoke(_manager.GetItemUri(i), _manager[i]); } catch (Exception ex) { Dialog.Show(null, ex.Message); Game.MainLogger.Log(4, "Config", "An error occurred while running the action: {0}", ex); } } } } }