Pull down IPathedResourceManager. Reconstruct resource browser.

This commit is contained in:
2023-11-10 14:57:52 +08:00
parent bd834cff4a
commit ddf738ee27
11 changed files with 147 additions and 111 deletions

View File

@@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
namespace Cryville.Crtr.Browsing {
public interface IResourceManager<T> {
string[] CurrentDirectory { get; }
int ChangeDirectory(string[] dir);
int OpenDirectory(int id);
int ReturnToDirectory(int id);
int ItemCount { get; }
ResourceItemMeta GetItemMeta(int id);
T GetItemDetail(int id);
string GetItemPath(int id);
@@ -13,5 +12,13 @@ namespace Cryville.Crtr.Browsing {
bool ImportItemFrom(string path);
string[] GetSupportedFormats();
IReadOnlyDictionary<string, string> GetPresetPaths();
event Action ItemChanged;
}
public interface IPathedResourceManager<T> : IResourceManager<T> {
string[] CurrentDirectory { get; }
void ChangeDirectory(string[] dir);
void OpenDirectory(int id);
void ReturnToDirectory(int id);
}
}

View File

@@ -13,14 +13,17 @@ using UnityEngine;
using Logger = Cryville.Common.Logging.Logger;
namespace Cryville.Crtr.Browsing {
internal class LegacyResourceManager : IResourceManager<ChartDetail> {
internal class LegacyResourceManager : IPathedResourceManager<ChartDetail> {
private readonly string _rootPath;
private DirectoryInfo cd;
private DirectoryInfo[] items = new DirectoryInfo[0];
public string[] CurrentDirectory { get; private set; }
public int ItemCount { get { return items.Length; } }
static bool _init;
public event Action ItemChanged;
public LegacyResourceManager(string rootPath) {
_rootPath = rootPath;
if (!_init) {
@@ -29,24 +32,24 @@ namespace Cryville.Crtr.Browsing {
}
}
public int ChangeDirectory(string[] dir) {
public void ChangeDirectory(string[] dir) {
CurrentDirectory = dir;
cd = new DirectoryInfo(_rootPath + "/charts/" + string.Join("/", dir));
items = cd.GetDirectories();
return items.Length;
ItemChanged?.Invoke();
}
public int OpenDirectory(int id) {
public void OpenDirectory(int id) {
string[] nd = new string[CurrentDirectory.Length + 1];
Array.Copy(CurrentDirectory, nd, CurrentDirectory.Length);
nd[CurrentDirectory.Length] = items[id].Name;
return ChangeDirectory(nd);
ChangeDirectory(nd);
}
public int ReturnToDirectory(int id) {
public void ReturnToDirectory(int id) {
string[] nd = new string[id + 1];
Array.Copy(CurrentDirectory, nd, id + 1);
return ChangeDirectory(nd);
ChangeDirectory(nd);
}
public ResourceItemMeta GetItemMeta(int id) {

View File

@@ -4,9 +4,15 @@ namespace Cryville.Crtr.Browsing.UI {
internal abstract class BrowserItem : MonoBehaviour {
public int? Id { get; private set; }
protected ResourceItemMeta meta;
internal virtual void Load(int id, ResourceItemMeta item) {
internal void Load(int id, ResourceItemMeta item, bool selected) {
OnReset();
Id = id;
meta = item;
OnLoad(selected);
}
protected abstract void OnReset();
protected abstract void OnLoad(bool selected);
internal virtual void OnSelect() { }
internal virtual void OnDeselect() { }
}
}

View File

@@ -1,3 +1,4 @@
using Cryville.Common.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
@@ -17,26 +18,31 @@ namespace Cryville.Crtr.Browsing.UI {
[SerializeField]
TMP_Text m_desc;
#pragma warning disable IDE0051
StateTweener _tweener;
void Awake() {
_tweener = GetComponent<StateTweener>();
}
void OnDestroy() {
OnReset();
}
protected override void OnReset() {
if (meta.Icon != null) meta.Icon.Cancel();
if (m_icon.sprite != null && m_icon.sprite != m_iconPlaceholder) {
Destroy(m_icon.sprite.texture);
Destroy(m_icon.sprite);
}
_tweener.ClearState();
}
#pragma warning restore IDE0051
internal override void Load(int id, ResourceItemMeta item) {
OnDestroy();
base.Load(id, item);
protected override void OnLoad(bool selected) {
_dir = meta.IsDirectory;
m_icon.sprite = m_iconPlaceholder;
if (meta.Icon != null) meta.Icon.Destination = DisplayCover;
m_title.text = meta.Name;
m_desc.text = string.Format("{0}\n{1}", meta.DescriptionMain, meta.DescriptionSub);
if (selected) _tweener.EnterState("Selected");
}
private void DisplayCover(bool succeeded, Texture2D tex) {
if (succeeded) {
@@ -45,9 +51,17 @@ namespace Cryville.Crtr.Browsing.UI {
}
public void OnClick() {
if (Id == null) return;
var resourceBrowser = GetComponentInParent<ResourceBrowser>();
var resourceBrowser = GetComponentInParent<PathedResourceBrowser>();
if (_dir) resourceBrowser.OnDirectoryItemClicked(Id.Value);
else resourceBrowser.OnObjectItemClicked(Id.Value);
}
internal override void OnSelect() {
base.OnSelect();
_tweener.EnterState("Selected", 0.1f);
}
internal override void OnDeselect() {
base.OnDeselect();
_tweener.ExitState("Selected", 0.1f);
}
}
}

View File

@@ -5,7 +5,7 @@ using UnityEngine;
using UnityEngine.UI;
namespace Cryville.Crtr.Browsing.UI {
public class DetailPanel : ResourceBrowserUnit {
public class DetailPanel : MonoBehaviour {
[SerializeField]
Sprite m_coverPlaceholder;
[SerializeField]
@@ -19,10 +19,13 @@ namespace Cryville.Crtr.Browsing.UI {
[SerializeField]
TMP_Text m_desc;
ResourceBrowserMaster _master;
int _id;
ChartDetail _data;
protected override void Awake() {
void Awake() {
_master = GetComponentInParent<ResourceBrowserMaster>();
}
void OnDestroy() {
if (_data.Cover != null) _data.Cover.Cancel();
@@ -53,10 +56,10 @@ namespace Cryville.Crtr.Browsing.UI {
}
}
public void OnPlay() {
Master.Open(_id, _data);
_master.Open(_id, _data);
}
public void OnConfig() {
Master.OpenConfig(_id, _data);
_master.OpenConfig(_id, _data);
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Cryville.Crtr.Browsing.UI {
else return exp;
}
public void OnClick() {
GetComponentInParent<ResourceBrowser>().OnPathClicked(_id);
GetComponentInParent<PathedResourceBrowser>().OnPathClicked(_id);
}
}
}

View File

@@ -0,0 +1,83 @@
using Cryville.Common.Unity;
using Cryville.Common.Unity.UI;
using Cryville.Crtr.UI;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Cryville.Crtr.Browsing.UI {
public class PathedResourceBrowser : ResourceBrowser {
public IPathedResourceManager<ChartDetail> ResourceManager;
public ScrollableItemGrid ItemContainer;
readonly HashSet<int> _selectedItems = new HashSet<int>();
readonly Dictionary<int, BrowserItem> _items = new Dictionary<int, BrowserItem>();
FileDialog _dialog;
protected virtual void Start() {
ItemContainer.LoadItem = LoadItem;
ResourceManager.ItemChanged += OnItemChanged;
ResourceManager.ChangeDirectory(new string[] { "" });
InitDialog();
}
protected void InitDialog() {
_dialog = Instantiate(Resources.Load<GameObject>("Common/FileDialog")).GetComponent<FileDialog>();
_dialog.gameObject.SetActive(false);
_dialog.Filter = ResourceManager.GetSupportedFormats();
_dialog.PresetPaths = ResourceManager.GetPresetPaths();
_dialog.OnClose += OnAddDialogClosed;
}
void OnItemChanged() {
ItemContainer.ItemCount = ResourceManager.ItemCount;
_selectedItems.Clear();
_items.Clear();
}
private bool LoadItem(int id, GameObject obj) {
var bi = obj.GetComponent<BrowserItem>();
_items[id] = bi;
try {
var item = ResourceManager.GetItemMeta(id);
bi.Load(id, item, _selectedItems.Contains(id));
}
catch (Exception) {
bi.Load(id, new ResourceItemMeta { Name = "<color=#ff0000>Invalid resource</color>" }, _selectedItems.Contains(id));
}
return true;
}
public virtual void OnDirectoryItemClicked(int id) {
ResourceManager.OpenDirectory(id);
}
public void OnObjectItemClicked(int id) {
foreach (var item in _selectedItems) _items[item].OnDeselect();
_selectedItems.Clear();
_items[id].OnSelect();
_selectedItems.Add(id);
Master.ShowDetail(id, ResourceManager.GetItemDetail(id));
}
public void OnPathClicked(int id) {
ResourceManager.ReturnToDirectory(id);
}
public void OnAddButtonClicked() {
_dialog.Show();
}
private void OnAddDialogClosed() {
if (_dialog.FileName == null) return;
if (ResourceManager.ImportItemFrom(_dialog.FileName)) {
Popup.Create("Import succeeded");
OnPathClicked(ResourceManager.CurrentDirectory.Length - 1);
}
else {
Popup.Create("Import failed");
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e8d98fa73d49ab94cb1a16c5ef09db6c
guid: f3c17bb298cf2294dad4b675c7290b2a
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,78 +1,10 @@
using Cryville.Common.Unity;
using Cryville.Common.Unity.UI;
using Cryville.Crtr.UI;
using System;
using UnityEngine;
using UnityEngine.UI;
namespace Cryville.Crtr.Browsing.UI {
public class ResourceBrowser : ResourceBrowserUnit {
public IResourceManager<ChartDetail> ResourceManager;
public ScrollableItemGrid PathContainer;
public ScrollableItemGrid ItemContainer;
FileDialog _dialog;
protected void Start() {
PathContainer.LoadItem = LoadPathPart;
ItemContainer.LoadItem = LoadItem;
ItemContainer.ItemCount = ResourceManager.ChangeDirectory(new string[] { "" });
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
_dialog = GameObject.Instantiate(Resources.Load<GameObject>("Common/FileDialog")).GetComponent<FileDialog>();
_dialog.gameObject.SetActive(false);
_dialog.Filter = ResourceManager.GetSupportedFormats();
_dialog.PresetPaths = ResourceManager.GetPresetPaths();
_dialog.OnClose += OnAddDialogClosed;
}
private bool LoadPathPart(int id, GameObject obj) {
var item = ResourceManager.CurrentDirectory[id];
obj.GetComponent<PathPart>().Load(id, item);
return true;
}
private bool LoadItem(int id, GameObject obj) {
var bi = obj.GetComponent<BrowserItem>();
try {
var item = ResourceManager.GetItemMeta(id);
bi.Load(id, item);
}
catch (Exception) {
bi.Load(id, new ResourceItemMeta { Name = "<color=#ff0000>Invalid resource</color>" });
}
return true;
}
public void OnDirectoryItemClicked(int id) {
ItemContainer.ItemCount = ResourceManager.OpenDirectory(id);
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
if (PathContainer.ItemCount >= PathContainer.VisibleLines - 1)
PathContainer.GetComponentInParent<ScrollRect>().velocity = new Vector2(-Screen.width, 0);
}
public void OnObjectItemClicked(int id) {
Master.ShowDetail(id, ResourceManager.GetItemDetail(id));
}
public void OnPathClicked(int id) {
ItemContainer.ItemCount = ResourceManager.ReturnToDirectory(id);
PathContainer.ItemCount = ResourceManager.CurrentDirectory.Length;
}
public void OnAddButtonClicked() {
_dialog.Show();
}
private void OnAddDialogClosed() {
if (_dialog.FileName == null) return;
if (ResourceManager.ImportItemFrom(_dialog.FileName)) {
Popup.Create("Import succeeded");
OnPathClicked(ResourceManager.CurrentDirectory.Length - 1);
}
else {
Popup.Create("Import failed");
}
public abstract class ResourceBrowser : MonoBehaviour {
protected ResourceBrowserMaster Master { get; private set; }
protected virtual void Awake() {
Master = GetComponentInParent<ResourceBrowserMaster>();
}
}
}

View File

@@ -18,12 +18,12 @@ namespace Cryville.Crtr.Browsing.UI {
[SerializeField]
private DetailPanel m_detailPanel;
readonly List<ResourceBrowserUnit> _units = new List<ResourceBrowserUnit>();
readonly List<ResourceBrowser> _units = new List<ResourceBrowser>();
void Awake() {
m_mainBrowser.ResourceManager = new LegacyResourceManager(Settings.Default.GameDataPath);
_units.Add(MainBrowser);
_units.Add(_detailPanel);
_units.Add(m_mainBrowser);
// _units.Add(m_detailPanel);
}
public void ShowDetail(int id, ChartDetail detail) {

View File

@@ -1,12 +0,0 @@
using UnityEngine;
namespace Cryville.Crtr.Browsing.UI {
public abstract class ResourceBrowserUnit : MonoBehaviour {
protected ResourceBrowserMaster Master { get; private set; }
protected virtual void Awake() {
Master = GetComponentInParent<ResourceBrowserMaster>();
}
public virtual void SlideToLeft() { }
public virtual void SlideToRight() { }
}
}