123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // Copyright (c) 2025 TerraByte Inc.
- //
- // A modal editor window that displays pull conflicts and allows the user
- // to select files to reset before proceeding.
- using System;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using Terra.Arbitrator.Services;
- using System.Collections.Generic;
- namespace Terra.Arbitrator.GUI
- {
- public class ConflictResolutionWindow : EditorWindow
- {
- private List<string> _conflictingFiles;
- private List<bool> _filesToReset;
- private Vector2 _scrollPosition;
- private Action<List<string>> _onCloseCallback;
- private bool _callbackInvoked;
- /// <summary>
- /// Shows a modal window to display pull conflicts and get user action.
- /// </summary>
- /// <param name="conflictingFiles">The list of files that have conflicts.</param>
- /// <param name="onCloseCallback">A callback that provides the list of files the user selected to reset. If the user cancels, the list will be null.</param>
- public static void ShowWindow(List<string> conflictingFiles, Action<List<string>> onCloseCallback)
- {
- var window = GetWindow<ConflictResolutionWindow>(true, "Pull Conflicts Detected", true);
- window.minSize = new Vector2(600, 400);
- window._conflictingFiles = conflictingFiles;
- window._filesToReset = new List<bool>(new bool[conflictingFiles.Count]); // Initialize all to false
- window._onCloseCallback = onCloseCallback;
- window._callbackInvoked = false;
- window.ShowModalUtility();
- }
- private void OnGUI()
- {
- EditorGUILayout.HelpBox("A pull would result in conflicts with your local changes. To proceed with a clean pull, you must reset your local changes for the conflicting files listed below.", MessageType.Warning);
-
- EditorGUILayout.LabelField("Conflicting Files:", EditorStyles.boldLabel);
- _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox);
- for (var i = 0; i < _conflictingFiles.Count; i++)
- {
- EditorGUILayout.BeginHorizontal();
- _filesToReset[i] = EditorGUILayout.Toggle(_filesToReset[i], GUILayout.Width(20));
- EditorGUILayout.LabelField(_conflictingFiles[i]);
- if (GUILayout.Button("Local Diff", GUILayout.Width(100)))
- {
- // Find the GitChange object to pass to the diff service.
- var change = GitService.GetChangeForFile(_conflictingFiles[i]);
- if (change != null)
- {
- GitService.LaunchExternalDiff(change);
- }
- else
- {
- Debug.LogWarning($"Could not get status for {_conflictingFiles[i]} to launch diff.");
- }
- }
- EditorGUILayout.EndHorizontal();
- }
- EditorGUILayout.EndScrollView();
- EditorGUILayout.Space();
- // --- Action Buttons ---
- DrawActionButtons();
- }
- private void DrawActionButtons()
- {
- var selectedCount = _filesToReset.Count(selected => selected);
- var canReset = selectedCount > 0;
- EditorGUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
- // Reset Button
- EditorGUI.BeginDisabledGroup(!canReset);
- if (GUILayout.Button($"Reset {selectedCount} Selected File(s)", GUILayout.Height(30), GUILayout.Width(200)))
- {
- var filesToResetPaths = new List<string>();
- for (var i = 0; i < _conflictingFiles.Count; i++)
- {
- if (_filesToReset[i])
- {
- filesToResetPaths.Add(_conflictingFiles[i]);
- }
- }
- _callbackInvoked = true;
- _onCloseCallback?.Invoke(filesToResetPaths);
- Close();
- }
- EditorGUI.EndDisabledGroup();
- if (GUILayout.Button(new GUIContent("Pull Anyway", "This will perform the pull, leaving merge conflicts in your local files for you to resolve."), GUILayout.Height(30)))
- {
- // Signal "Pull Anyway" by invoking the callback with an empty, non-null list.
- _callbackInvoked = true;
- _onCloseCallback?.Invoke(new List<string>());
- Close();
- }
-
- // Cancel Button
- if (GUILayout.Button("Cancel", GUILayout.Height(30)))
- {
- Close();
- }
- EditorGUILayout.EndHorizontal();
- }
- private void OnDestroy()
- {
- if (!_callbackInvoked)
- {
- _onCloseCallback?.Invoke(null);
- }
- }
- }
- }
|