/* ┌──────────────────────────────────────────────────────────────────┐ │ Author: Ivan Murzak (https://github.com/IvanMurzak) │ │ Repository: GitHub (https://github.com/IvanMurzak/Unity-MCP) │ │ Copyright (c) 2025 Ivan Murzak │ │ Licensed under the Apache License, Version 2.0. │ │ See the LICENSE file in the project root for more information. │ └──────────────────────────────────────────────────────────────────┘ */ #nullable enable using System; using System.Collections.Generic; using System.Linq; using com.IvanMurzak.McpPlugin; using com.IvanMurzak.Unity.MCP.Editor.Utils; using Extensions.Unity.PlayerPrefsEx; using Microsoft.Extensions.Logging; using R3; using UnityEngine.UIElements; namespace com.IvanMurzak.Unity.MCP.Editor.UI { public class McpResourcesWindow : McpListWindowBase { private static readonly string[] _windowUxmlPaths = EditorAssetLoader.GetEditorAssetPaths("Editor/UI/uxml/McpResourcesWindow.uxml"); private static readonly string[] _itemUxmlPaths = EditorAssetLoader.GetEditorAssetPaths("Editor/UI/uxml/ResourceItem.uxml"); private static readonly string[] _windowUssPaths = EditorAssetLoader.GetEditorAssetPaths("Editor/UI/uss/McpResourcesWindow.uss"); protected override string[] WindowUxmlPaths => _windowUxmlPaths; protected override string[] ItemUxmlPaths => _itemUxmlPaths; protected override string[] WindowUssPaths => _windowUssPaths; protected override string WindowTitle => "MCP Resources"; protected override string MissingTemplateMessage => "ResourceItem template is missing. Please ensure ResourceItem.uxml exists in the package or the Packages/com.ivanmurzak.unity.mcp folder."; public static McpResourcesWindow ShowWindow() { var window = GetWindow("MCP Resources"); window.SetupWindowWithIcon(); window.Show(); window.Focus(); return window; } protected override Observable? GetOnUpdatedObservable(IMcpPlugin plugin) => plugin.McpManager.ResourceManager?.OnResourcesUpdated; protected override void RefreshItems() { var resourceManager = UnityMcpPluginEditor.Instance.Resources; var refreshed = new List(); if (resourceManager != null) { foreach (var resource in resourceManager.GetAllResources().Where(resource => resource != null)) { refreshed.Add(new ResourceViewModel(resourceManager, resource)); } } allItems = refreshed; } protected override void OnItemToggleChanged(ResourceViewModel viewModel, bool isEnabled) { var resourceManager = UnityMcpPluginEditor.Instance.Resources; if (resourceManager == null) { Logger.LogError("{method} ResourceManager is not available.", nameof(OnItemToggleChanged)); return; } viewModel.IsEnabled = isEnabled; if (!string.IsNullOrWhiteSpace(viewModel.Name)) { Logger.LogTrace("{method} Setting resource '{name}' enabled state to {enabled}.", nameof(OnItemToggleChanged), viewModel.Name, isEnabled); resourceManager.SetResourceEnabled(viewModel.Name, isEnabled); UnityMcpPluginEditor.Instance.Save(); } } protected override void OnFoldoutChanged(ResourceViewModel viewModel, string foldoutName, bool isExpanded) { if (foldoutName == "description-foldout") { viewModel.descriptionExpanded.Value = isExpanded; } } protected override void BindItem(VisualElement element, ResourceViewModel viewModel) { BindCommonItemFields(element, viewModel); BindDescriptionFoldout(element, viewModel, viewModel.descriptionExpanded.Value); var uriLabel = element.Q