192 lines
5.0 KiB
C#
192 lines
5.0 KiB
C#
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<IResourceMeta> _manager;
|
|
IResourceAction _importAction;
|
|
readonly IResourceAction[] _importActionArray = new IResourceAction[1];
|
|
|
|
readonly HashSet<int> _selectedItems = new();
|
|
readonly Dictionary<int, BrowserItem> _items = new();
|
|
|
|
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() {
|
|
_manager?.Activate();
|
|
}
|
|
void OnDisable() {
|
|
_manager?.Deactivate();
|
|
}
|
|
|
|
public void Init(IPathedResourceManager<IResourceMeta> 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<BrowserItem>();
|
|
_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<string>());
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|