343 lines
15 KiB
C#
343 lines
15 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using DG.Tweening;
|
|
using Ichni.RhythmGame;
|
|
using Lean.Pool;
|
|
using Sirenix.OdinInspector;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Ichni.Editor
|
|
{
|
|
public partial class ToolBar : StaticWindow
|
|
{
|
|
[Title("Buttons")] public Button escapeButton;
|
|
public Button reloadButton;
|
|
public Button projectInfoButton;
|
|
public Button songInfoButton;
|
|
public Button saveButton;
|
|
public Button exportButton;
|
|
public Button mergeButton;
|
|
public Button clipSaveButton;
|
|
public Button clipLoadButton;
|
|
public Button beatmapToolsButton;
|
|
|
|
[Title("Search")]
|
|
public TMP_InputField searchInput;
|
|
public RectTransform searchResultsRoot;
|
|
public GameObject searchResultItemPrefab;
|
|
|
|
[Title("Windows")]
|
|
public GeneralSecondaryWindow clipManagementWindow;
|
|
|
|
private readonly List<GameObject> searchResultItems = new List<GameObject>();
|
|
|
|
protected override void Start()
|
|
{
|
|
base.Start();
|
|
escapeButton.onClick.AddListener(GenerateEscapeConfirmWindow);
|
|
reloadButton.onClick.AddListener(GenerateReloadConfirmWindow);
|
|
saveButton.onClick.AddListener(EditorManager.instance.projectManager.saveManager.Save);
|
|
exportButton.onClick.AddListener(EditorManager.instance.projectManager.exportManager.Export);
|
|
mergeButton.onClick.AddListener(GenerateMergeWindow);
|
|
clipSaveButton.onClick.AddListener(GenerateSaveClipWindow);
|
|
clipLoadButton.onClick.AddListener(GenerateLoadClipWindow);
|
|
beatmapToolsButton.onClick.AddListener(GenerateBeatmapToolsWindow);
|
|
//songInfoButton.onClick.AddListener(已经在songinfo好了);
|
|
//projectInfoButton.onClick.AddListener(已经在projectinfo好了);
|
|
|
|
SetupSearch();
|
|
}
|
|
|
|
private void SetupSearch()
|
|
{
|
|
searchInput.onValueChanged.AddListener(OnSearchValueChanged);
|
|
searchInput.onSelect.AddListener(_ =>
|
|
{
|
|
searchResultsRoot.transform.DOScaleX(1, 0.25f);
|
|
searchResultsRoot.gameObject.SetActive(true);
|
|
});
|
|
// searchInput.onDeselect.AddListener(_ =>
|
|
// {
|
|
// // 延迟隐藏,避免点击结果项时面板先消失了
|
|
//
|
|
// });
|
|
searchResultsRoot.gameObject.SetActive(false);
|
|
}
|
|
|
|
|
|
|
|
private void OnSearchValueChanged(string query)
|
|
{
|
|
ClearSearchResults();
|
|
|
|
if (string.IsNullOrWhiteSpace(query)) return;
|
|
|
|
string lowerQuery = query.ToLower();
|
|
|
|
var matches = EditorManager.instance.beatmapContainer.gameElementList
|
|
.Where(e => e != null && e.elementName.ToLower().Contains(lowerQuery))
|
|
.Take(20)
|
|
.ToList();
|
|
|
|
if (matches.Count == 0) return;
|
|
|
|
searchResultsRoot.gameObject.SetActive(true);
|
|
|
|
foreach (var element in matches)
|
|
{
|
|
var item = LeanPool.Spawn(searchResultItemPrefab, searchResultsRoot);
|
|
var itemText = item.GetComponentInChildren<TMP_Text>();
|
|
if (itemText != null)
|
|
itemText.text = element.elementName + " | " + element.GetType().ToString();
|
|
|
|
var button = item.GetComponentInChildren<Button>();
|
|
if (button != null)
|
|
{
|
|
GameElement captured = element;
|
|
button.onClick.RemoveAllListeners();
|
|
button.onClick.AddListener(() =>
|
|
{
|
|
EditorManager.instance.uiManager.hierarchy.FindTab(captured);
|
|
|
|
searchResultsRoot.transform.DOScaleX(0, 0.25f).OnComplete(() =>
|
|
{
|
|
searchInput.text = string.Empty;
|
|
ClearSearchResults();
|
|
searchResultsRoot.gameObject.SetActive(false);
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
|
|
searchResultItems.Add(item);
|
|
}
|
|
}
|
|
|
|
private void ClearSearchResults()
|
|
{
|
|
foreach (var item in searchResultItems)
|
|
{
|
|
if (item != null)
|
|
LeanPool.Despawn(item);
|
|
}
|
|
searchResultItems.Clear();
|
|
}
|
|
}
|
|
|
|
public partial class ToolBar
|
|
{
|
|
private void GenerateEscapeConfirmWindow()
|
|
{
|
|
GeneralSecondaryWindow escapeConfirmWindow =
|
|
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
|
|
escapeConfirmWindow.Initialize("Confirm Escape (without saving)");
|
|
|
|
var container = escapeConfirmWindow.GenerateContainer();
|
|
var clipSettings = container.GenerateSubcontainer(3);
|
|
var applyClipButton = escapeConfirmWindow.GenerateButton(clipSettings, "Yes", () =>
|
|
{
|
|
SceneManager.LoadScene("StartMenu");
|
|
});
|
|
var cancelButton = escapeConfirmWindow.GenerateButton(clipSettings, "No", () =>
|
|
{
|
|
escapeConfirmWindow.closeButton.onClick.Invoke();
|
|
});
|
|
}
|
|
|
|
private void GenerateReloadConfirmWindow()
|
|
{
|
|
GeneralSecondaryWindow escapeConfirmWindow =
|
|
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
|
|
escapeConfirmWindow.Initialize("Confirm Reload");
|
|
|
|
var container = escapeConfirmWindow.GenerateContainer();
|
|
var clipSettings = container.GenerateSubcontainer(3);
|
|
var applyClipButton = escapeConfirmWindow.GenerateButton(clipSettings, "Yes", () =>
|
|
{
|
|
InformationTransistor.instance.isLoadedProject = true;
|
|
InformationTransistor.instance.loadedProjectName = EditorManager.instance.projectInformation.projectName;
|
|
SceneManager.LoadScene("EditorScene");
|
|
});
|
|
var cancelButton = escapeConfirmWindow.GenerateButton(clipSettings, "No", () =>
|
|
{
|
|
escapeConfirmWindow.closeButton.onClick.Invoke();
|
|
});
|
|
}
|
|
|
|
private void GenerateSaveClipWindow()
|
|
{
|
|
GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
|
|
|
if (currentElement == null)
|
|
{
|
|
LogWindow.Log("No Game Element selected.", Color.red);
|
|
return;
|
|
}
|
|
|
|
if (clipManagementWindow != null)
|
|
{
|
|
LogWindow.Log("Clip Management Window already exists.", Color.red);
|
|
return;
|
|
}
|
|
|
|
GeneralSecondaryWindow saveClipWindow =
|
|
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
clipManagementWindow = saveClipWindow;
|
|
saveClipWindow.Initialize("Save Clip: " + currentElement.elementName, () => clipManagementWindow = null);
|
|
|
|
var container = saveClipWindow.GenerateContainer();
|
|
var clipSettings = container.GenerateSubcontainer(3);
|
|
var clipNameInputField = saveClipWindow.GenerateInputField(clipSettings, "Clip Name", currentElement.elementName);
|
|
var applyClipButton = saveClipWindow.GenerateButton(clipSettings, "Apply", () =>
|
|
{
|
|
EditorManager.instance.projectManager.beatmapClipManager.SaveClip(clipNameInputField.GetValue<string>());
|
|
clipManagementWindow.closeButton.onClick.Invoke();
|
|
});
|
|
}
|
|
|
|
private void GenerateLoadClipWindow()
|
|
{
|
|
GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
|
|
|
if (currentElement == null)
|
|
{
|
|
LogWindow.Log("No Game Element selected.", Color.red);
|
|
return;
|
|
}
|
|
|
|
GameElement loadTarget = currentElement == EditorManager.instance ? null : currentElement.parentElement;
|
|
|
|
if (clipManagementWindow != null)
|
|
{
|
|
LogWindow.Log("Clip Management Window already exists.", Color.red);
|
|
return;
|
|
}
|
|
|
|
GeneralSecondaryWindow loadClipWindow =
|
|
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
clipManagementWindow = loadClipWindow;
|
|
loadClipWindow.Initialize("Load Clip", () => clipManagementWindow = null);
|
|
|
|
var container = loadClipWindow.GenerateContainer();
|
|
var clipSettings = container.GenerateSubcontainer(3);
|
|
var clipNameInputField = loadClipWindow.GenerateInputField(clipSettings, "Clip Name");
|
|
var applyClipButton = loadClipWindow.GenerateButton(clipSettings, "Apply", () =>
|
|
{
|
|
EditorManager.instance.projectManager.beatmapClipManager.LoadClip(clipNameInputField.GetValue<string>());
|
|
clipManagementWindow.closeButton.onClick.Invoke();
|
|
});
|
|
}
|
|
|
|
private void GenerateMergeWindow()
|
|
{
|
|
GeneralSecondaryWindow mergeWindow = Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
|
|
mergeWindow.Initialize("Merge Beatmap");
|
|
|
|
var container = mergeWindow.GenerateContainer();
|
|
var clipSettings = container.GenerateSubcontainer(3);
|
|
var clipNameInputField = mergeWindow.GenerateInputField(clipSettings, "Beatmap Name");
|
|
var applyClipButton = mergeWindow.GenerateButton(clipSettings, "Apply", () =>
|
|
{
|
|
EditorManager.instance.projectManager.beatmapMergeManager.MergeBeatmap(clipNameInputField.GetValue<string>());
|
|
});
|
|
}
|
|
}
|
|
|
|
public partial class ToolBar
|
|
{
|
|
private void GenerateBeatmapToolsWindow()
|
|
{
|
|
GeneralSecondaryWindow beatmapToolsWindow =
|
|
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
|
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
|
|
|
beatmapToolsWindow.Initialize("Beatmap Tools", () => clipManagementWindow = null);
|
|
|
|
var container = beatmapToolsWindow.GenerateContainer("Note Tools");
|
|
var beatmapToolsSettings = container.GenerateSubcontainer(3);
|
|
var applyTimeOnNameButton = beatmapToolsWindow.GenerateButton(beatmapToolsSettings, "Apply Time On Note Name", () =>
|
|
{
|
|
List<NoteBase> allNotes = EditorManager.instance.beatmapContainer.gameElementList.FindAll(x => x is NoteBase).ConvertAll(x => x as NoteBase);
|
|
List<Tap> allTaps = allNotes.FindAll(x => x is Tap).ConvertAll(x => x as Tap);
|
|
List<Stay> allStays = allNotes.FindAll(x => x is Stay).ConvertAll(x => x as Stay);
|
|
List<Hold> allHolds = allNotes.FindAll(x => x is Hold).ConvertAll(x => x as Hold);
|
|
List<Flick> allFlicks = allNotes.FindAll(x => x is Flick).ConvertAll(x => x as Flick);
|
|
|
|
foreach (var tap in allTaps.Where(tap => tap.elementName == "New Tap" || Regex.IsMatch(tap.elementName, @"Tap \(\d+\)")))
|
|
{
|
|
tap.elementName = "Tap (" + tap.exactJudgeTime + ")";
|
|
tap.Refresh();
|
|
}
|
|
|
|
foreach (var stay in allStays.Where(stay => stay.elementName == "New Stay" || Regex.IsMatch(stay.elementName, @"Stay \(\d+\)")))
|
|
{
|
|
stay.elementName = "Stay (" + stay.exactJudgeTime + ")";
|
|
stay.Refresh();
|
|
}
|
|
|
|
foreach (var hold in allHolds.Where(hold => hold.elementName == "New Hold" || Regex.IsMatch(hold.elementName, @"Hold \(\d+-\d+\)")))
|
|
{
|
|
hold.elementName = "Hold (" + hold.exactJudgeTime + "-" + hold.holdEndTime + ")";
|
|
hold.Refresh();
|
|
}
|
|
|
|
foreach (var flick in allFlicks.Where(flick => flick.elementName == "New Flick" || Regex.IsMatch(flick.elementName, @"Flick \(\d+\)")))
|
|
{
|
|
flick.elementName = "Flick (" + flick.exactJudgeTime + ")";
|
|
flick.Refresh();
|
|
}
|
|
});
|
|
|
|
var ResetNoteAudioButton = beatmapToolsWindow.GenerateButton(beatmapToolsSettings, "Reset Note Audio", () =>
|
|
{
|
|
List<NoteBase> allNotes = EditorManager.instance.beatmapContainer.gameElementList.FindAll(x => x is NoteBase).ConvertAll(x => x as NoteBase);
|
|
List<Hold> allHolds = allNotes.FindAll(x => x is Hold).ConvertAll(x => x as Hold);
|
|
List<Flick> allFlicks = allNotes.FindAll(x => x is Flick).ConvertAll(x => x as Flick);
|
|
|
|
foreach (Hold hold in allHolds)
|
|
{
|
|
if (hold.noteAudioSubmodule.generalJudgeAudioList.Contains("DefaultTap"))
|
|
{
|
|
hold.submoduleList.Remove(hold.noteAudioSubmodule);
|
|
hold.noteAudioSubmodule = null;
|
|
hold.noteAudioSubmodule = new NoteAudioSubmodule(hold,
|
|
new List<string>() { "DefaultEndHold" },
|
|
new List<string>(), new List<string>(),
|
|
new List<string>(), new List<string>(),
|
|
new List<string>() { "DefaultStartHold" });
|
|
}
|
|
}
|
|
|
|
foreach (Flick flick in allFlicks)
|
|
{
|
|
if (flick.noteAudioSubmodule.generalJudgeAudioList.Contains("DefaultStay"))
|
|
{
|
|
flick.submoduleList.Remove(flick.noteAudioSubmodule);
|
|
flick.noteAudioSubmodule = null;
|
|
flick.noteAudioSubmodule = new NoteAudioSubmodule(flick,
|
|
new List<string>() { "DefaultFlick" },
|
|
new List<string>(), new List<string>(),
|
|
new List<string>(), new List<string>(),
|
|
new List<string>());
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
}
|
|
} |