2026-04-17 14:21:41 +08:00
|
|
|
using System;
|
2025-02-20 10:48:57 +08:00
|
|
|
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";
|
2026-04-17 14:21:41 +08:00
|
|
|
|
2025-02-20 11:44:00 +08:00
|
|
|
public static FrameworkPackageManagerWindow Instance;
|
2025-02-20 10:48:57 +08:00
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
public List<RepositoryPackageData> RepositoryPackageDatas { get; private set; } = new List<RepositoryPackageData>();
|
|
|
|
|
|
|
|
|
|
private PackageListView packageListView;
|
|
|
|
|
private PackageInfoView packageInfoView;
|
|
|
|
|
private PackageBottomStateBar bottomStateBar;
|
|
|
|
|
private bool isRefreshing;
|
|
|
|
|
|
2025-02-20 11:44:00 +08:00
|
|
|
public FrameworkPackageManagerWindow()
|
|
|
|
|
{
|
|
|
|
|
Instance = this;
|
|
|
|
|
}
|
2025-02-20 10:48:57 +08:00
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
[MenuItem("AlicizaX/PackageManager")]
|
|
|
|
|
internal static void Open()
|
2025-02-20 13:15:18 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
GetWindow<FrameworkPackageManagerWindow>().Show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Refresh()
|
|
|
|
|
{
|
|
|
|
|
if (isRefreshing)
|
2025-02-20 13:15:18 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
return;
|
2025-02-20 13:15:18 +08:00
|
|
|
}
|
2026-04-17 14:21:41 +08:00
|
|
|
|
|
|
|
|
isRefreshing = true;
|
|
|
|
|
SetRefreshState("Refreshing packages...");
|
|
|
|
|
|
|
|
|
|
RepositoryDataFetcher.FetchRepositoryData(datas =>
|
|
|
|
|
{
|
|
|
|
|
RepositoryPackageDatas = datas ?? new List<RepositoryPackageData>();
|
|
|
|
|
PackageManagerCheckTool.RefreshInstalledPackages(_ =>
|
|
|
|
|
{
|
|
|
|
|
PackageManagerCheckTool.ValidatePackageStates(RepositoryPackageDatas);
|
|
|
|
|
RebuildList();
|
|
|
|
|
isRefreshing = false;
|
|
|
|
|
SetRefreshState($"Last refresh: {RepositoryDataFetcher.GetLastRefreshTime()}");
|
|
|
|
|
});
|
|
|
|
|
});
|
2025-02-20 13:15:18 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
public void RefreshPackage(string packageName)
|
2025-02-20 10:48:57 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
if (string.IsNullOrEmpty(packageName))
|
2025-02-20 10:48:57 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var package = RepositoryPackageDatas.FirstOrDefault(t => string.Equals(t.name, packageName, StringComparison.OrdinalIgnoreCase));
|
|
|
|
|
if (package == null)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PackageManagerCheckTool.ValidatePackageStates(new List<RepositoryPackageData> { package });
|
|
|
|
|
|
|
|
|
|
RebuildList();
|
|
|
|
|
if (packageListView.selectedItem == package)
|
|
|
|
|
{
|
|
|
|
|
packageInfoView.RefreshView(package);
|
|
|
|
|
}
|
2025-02-20 10:48:57 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
public bool IsBusy()
|
2025-02-20 10:48:57 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
return isRefreshing || PackageOperationRunner.IsBusy;
|
2025-02-20 10:48:57 +08:00
|
|
|
}
|
|
|
|
|
|
2025-11-17 20:28:48 +08:00
|
|
|
private void OnDestroy()
|
|
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
if (Instance == this)
|
|
|
|
|
{
|
|
|
|
|
Instance = null;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-17 20:28:48 +08:00
|
|
|
PackageManagerCoroutines.DestroyCoroutines();
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-20 10:48:57 +08:00
|
|
|
private void CreateGUI()
|
|
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(VisualAssetPath);
|
|
|
|
|
visualTree?.CloneTree(rootVisualElement);
|
|
|
|
|
CreateLayout();
|
|
|
|
|
Refresh();
|
2025-02-20 10:48:57 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
private void CreateLayout()
|
2025-02-20 10:48:57 +08:00
|
|
|
{
|
|
|
|
|
var leftContainer = rootVisualElement.Q<VisualElement>("LeftContainer");
|
|
|
|
|
leftContainer.style.backgroundColor = new Color(0.1686275f, 0.1606275f, 0.1686275f);
|
|
|
|
|
|
|
|
|
|
packageListView = new PackageListView();
|
2026-04-17 14:21:41 +08:00
|
|
|
packageListView.OnSelectionChangedEvent += OnPackageSelectionChanged;
|
2025-02-20 10:48:57 +08:00
|
|
|
leftContainer.Add(packageListView);
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
bottomStateBar = new PackageBottomStateBar(this);
|
|
|
|
|
leftContainer.Add(bottomStateBar);
|
2025-02-20 10:48:57 +08:00
|
|
|
|
|
|
|
|
var rightContainer = rootVisualElement.Q<VisualElement>("RightContainer");
|
2026-04-17 14:21:41 +08:00
|
|
|
packageInfoView = new PackageInfoView(this);
|
2025-02-20 10:48:57 +08:00
|
|
|
rightContainer.Add(packageInfoView);
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
packageListView.itemsSource = RepositoryPackageDatas;
|
|
|
|
|
}
|
2025-02-20 10:48:57 +08:00
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
private void RebuildList()
|
|
|
|
|
{
|
2025-02-20 10:48:57 +08:00
|
|
|
packageListView.itemsSource = RepositoryPackageDatas;
|
2026-04-17 14:21:41 +08:00
|
|
|
packageListView.Rebuild();
|
2025-02-20 11:44:00 +08:00
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
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<RepositoryPackageData> selectedItems)
|
|
|
|
|
{
|
|
|
|
|
packageInfoView.RefreshView(selectedItems.FirstOrDefault());
|
2025-02-20 10:48:57 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-17 14:21:41 +08:00
|
|
|
private void SetRefreshState(string text)
|
2025-02-20 10:48:57 +08:00
|
|
|
{
|
2026-04-17 14:21:41 +08:00
|
|
|
bottomStateBar?.SetStateText(text);
|
2025-02-20 10:48:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|