using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using UnityEngine.UIElements; namespace AlicizaX.PackageManager.Editor { [EditorWindowTitle(title = "Package Manager", icon = "Package Manager")] internal class FrameworkPackageManagerWindow : EditorWindow { private const string VisualAssetPath = "Packages/com.alicizax.unity.packagemanager/Editor/PackageManager/Res/AlicizaXPackageManagerWindow.uxml"; public static FrameworkPackageManagerWindow Instance; public List RepositoryPackageDatas { get; private set; } = new List(); private PackageListView packageListView; private PackageInfoView packageInfoView; private PackageBottomStateBar bottomStateBar; private bool isRefreshing; public FrameworkPackageManagerWindow() { Instance = this; } [MenuItem("AlicizaX/PackageManager")] internal static void Open() { GetWindow().Show(); } public void Refresh() { if (isRefreshing) { return; } isRefreshing = true; SetRefreshState("Refreshing packages..."); RepositoryDataFetcher.FetchRepositoryData(datas => { RepositoryPackageDatas = datas ?? new List(); PackageManagerCheckTool.RefreshInstalledPackages(_ => { PackageManagerCheckTool.ValidatePackageStates(RepositoryPackageDatas); RebuildList(); isRefreshing = false; SetRefreshState($"Last refresh: {RepositoryDataFetcher.GetLastRefreshTime()}"); }); }); } public void RefreshPackage(string packageName) { if (string.IsNullOrEmpty(packageName)) { return; } var package = RepositoryPackageDatas.FirstOrDefault(t => string.Equals(t.name, packageName, StringComparison.OrdinalIgnoreCase)); if (package == null) { return; } PackageManagerCheckTool.ValidatePackageStates(new List { package }); RebuildList(); if (packageListView.selectedItem == package) { packageInfoView.RefreshView(package); } } public bool IsBusy() { return isRefreshing || PackageOperationRunner.IsBusy; } private void OnDestroy() { if (Instance == this) { Instance = null; } PackageManagerCoroutines.DestroyCoroutines(); } private void CreateGUI() { var visualTree = AssetDatabase.LoadAssetAtPath(VisualAssetPath); visualTree?.CloneTree(rootVisualElement); CreateLayout(); Refresh(); } private void CreateLayout() { var leftContainer = rootVisualElement.Q("LeftContainer"); leftContainer.style.backgroundColor = new Color(0.1686275f, 0.1606275f, 0.1686275f); packageListView = new PackageListView(); packageListView.OnSelectionChangedEvent += OnPackageSelectionChanged; leftContainer.Add(packageListView); bottomStateBar = new PackageBottomStateBar(this); leftContainer.Add(bottomStateBar); var rightContainer = rootVisualElement.Q("RightContainer"); packageInfoView = new PackageInfoView(this); rightContainer.Add(packageInfoView); packageListView.itemsSource = RepositoryPackageDatas; } private void RebuildList() { packageListView.itemsSource = RepositoryPackageDatas; packageListView.Rebuild(); if (RepositoryPackageDatas.Count > 0 && packageListView.selectedIndex < 0) { packageListView.SetSelection(0); packageInfoView.RefreshView(RepositoryPackageDatas[0]); } else if (packageListView.selectedItem is RepositoryPackageData selected) { packageInfoView.RefreshView(selected); } else { packageInfoView.RefreshView(null); } } private void OnPackageSelectionChanged(IEnumerable selectedItems) { packageInfoView.RefreshView(selectedItems.FirstOrDefault()); } private void SetRefreshState(string text) { bottomStateBar?.SetStateText(text); } } }