using System; using UnityEngine; using UnityEngine.UIElements; using UnityEditor; namespace io.github.hatayama.uLoopMCP { /// /// View layer for McpEditorWindow in MVP architecture. /// Owns UI sections and forwards user interactions to presenter via events. /// Related: McpEditorWindow (presenter), McpEditorModel (model) /// public class McpEditorWindowUI : IDisposable { private const string UXML_RELATIVE_PATH = "Editor/UI/UIToolkit/McpEditorWindow.uxml"; private const string USS_RELATIVE_PATH = "Editor/UI/UIToolkit/McpEditorWindow.uss"; private const string GITHUB_ICON_RELATIVE_PATH = "Editor/UI/Setup/GitHub_Invertocat_White.png"; private readonly VisualElement _root; private ConnectionModeSection _connectionModeSection; private CliSetupSection _cliSetupSection; private ConnectedToolsSection _connectedToolsSection; private EditorConfigSection _editorConfigSection; private ToolSettingsSection _toolSettingsSection; private VisualElement _cliContent; private VisualElement _mcpContent; private ScrollView _mainScrollView; private VisualElement _githubLinkRow; private Label _githubLinkLabel; private Image _githubLinkIcon; public event Action OnConnectionModeChanged; public event Action OnRefreshCliVersion; public event Action OnInstallCli; public event Action OnInstallSkills; public event Action OnRefreshSkillsState; public event Action OnSkillsTargetChanged; public event Action OnGroupSkillsChanged; public event Action OnUseProjectCliVersionChanged; public event Action OnConfigurationFoldoutChanged; public event Action OnConnectedToolsFoldoutChanged; public event Action OnEditorTypeChanged; public event Action OnRepositoryRootChanged; public event Action OnConfigureClicked; public event Action OnDeleteConfigClicked; public event Action OnOpenSettingsClicked; public event Action OnToolSettingsFoldoutChanged; public event Action OnToolToggled; public event Action OnAllowThirdPartyChanged; public event Action OnSecurityLevelChanged; public McpEditorWindowUI(VisualElement root) { _root = root; LoadLayout(); ApplyDebugStyle(); InitializeSections(); } private void ApplyDebugStyle() { #if ULOOPMCP_DEBUG VisualElement mainContainer = _root.Q("main-scroll-view"); mainContainer?.AddToClassList("mcp-main-container--debug"); #endif } private void LoadLayout() { string uxmlPath = $"{McpConstants.PackageAssetPath}/{UXML_RELATIVE_PATH}"; string ussPath = $"{McpConstants.PackageAssetPath}/{USS_RELATIVE_PATH}"; VisualTreeAsset visualTree = AssetDatabase.LoadAssetAtPath(uxmlPath); if (visualTree == null) { Debug.LogError($"Failed to load UXML from: {uxmlPath}"); return; } visualTree.CloneTree(_root); StyleSheet styleSheet = AssetDatabase.LoadAssetAtPath(ussPath); if (styleSheet == null) { Debug.LogError($"Failed to load USS from: {ussPath}"); return; } _root.styleSheets.Add(styleSheet); } private void InitializeSections() { _connectionModeSection = new ConnectionModeSection(_root); _connectionModeSection.OnModeChanged += mode => OnConnectionModeChanged?.Invoke(mode); _connectionModeSection.OnFoldoutChanged += value => OnConfigurationFoldoutChanged?.Invoke(value); _cliSetupSection = new CliSetupSection(_root); _cliSetupSection.SetupBindings(); _cliSetupSection.OnRefreshCliVersion += () => OnRefreshCliVersion?.Invoke(); _cliSetupSection.OnInstallCli += () => OnInstallCli?.Invoke(); _cliSetupSection.OnInstallSkills += () => OnInstallSkills?.Invoke(); _cliSetupSection.OnRefreshSkillsState += () => OnRefreshSkillsState?.Invoke(); _cliSetupSection.OnSkillsTargetChanged += value => OnSkillsTargetChanged?.Invoke(value); _cliSetupSection.OnGroupSkillsChanged += value => OnGroupSkillsChanged?.Invoke(value); _cliSetupSection.OnUseProjectCliVersionChanged += value => OnUseProjectCliVersionChanged?.Invoke(value); _mainScrollView = _root.Q("main-scroll-view"); ConfigureScrollView(); _cliContent = _root.Q("cli-content"); _mcpContent = _root.Q("mcp-content"); _connectedToolsSection = new ConnectedToolsSection(_root); _connectedToolsSection.OnFoldoutChanged += value => OnConnectedToolsFoldoutChanged?.Invoke(value); _editorConfigSection = new EditorConfigSection(_root); _editorConfigSection.OnEditorTypeChanged += value => OnEditorTypeChanged?.Invoke(value); _editorConfigSection.OnRepositoryRootChanged += value => OnRepositoryRootChanged?.Invoke(value); _editorConfigSection.OnConfigureClicked += () => OnConfigureClicked?.Invoke(); _editorConfigSection.OnDeleteConfigClicked += () => OnDeleteConfigClicked?.Invoke(); _editorConfigSection.OnOpenSettingsClicked += () => OnOpenSettingsClicked?.Invoke(); _toolSettingsSection = new ToolSettingsSection(_root); _toolSettingsSection.OnFoldoutChanged += value => OnToolSettingsFoldoutChanged?.Invoke(value); _toolSettingsSection.OnToolToggled += (toolName, enabled) => OnToolToggled?.Invoke(toolName, enabled); _toolSettingsSection.OnAllowThirdPartyChanged += value => OnAllowThirdPartyChanged?.Invoke(value); _toolSettingsSection.OnSecurityLevelChanged += value => OnSecurityLevelChanged?.Invoke(value); _githubLinkRow = _root.Q("github-link-row"); _githubLinkLabel = _root.Q