// 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.IO; using UnityEditor; using UnityEngine; using System.Linq; using UnityEngine.Scripting; using Terra.Arbitrator.Services; using System.Collections.Generic; namespace Terra.Arbitrator.GUI { [Preserve] public class ConflictResolutionWindow : EditorWindow { private List _conflictingFiles; private Vector2 _scrollPosition; private ArbitratorController _controller; private GUIStyle _wordWrapStyle; /// /// Shows a modal window to display pull conflicts and get user action. /// /// Reference to the arbitrator controller /// The list of files that have conflicts. public static void ShowWindow(ArbitratorController controller, IReadOnlyList conflictingFiles) { var window = GetWindow(true, "Pull Conflicts Detected", true); window.minSize = new Vector2(600, 400); window._controller = controller; window._conflictingFiles = new List(conflictingFiles); window.ShowModalUtility(); } private void OnGUI() { _wordWrapStyle ??= new GUIStyle(EditorStyles.label) { wordWrap = true }; EditorGUILayout.HelpBox("A pull would result in conflicts with your local changes. To proceed with a clean pull, you must choose a resolution for the conflicting files listed below.", MessageType.Warning); EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); GUILayout.Label("Filename"); GUILayout.FlexibleSpace(); GUILayout.Label(""); //Spacer GUILayout.FlexibleSpace(); GUILayout.Label("Choice", GUILayout.Width(70)); EditorGUILayout.EndHorizontal(); _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox); if (_conflictingFiles != null) { foreach (var change in _conflictingFiles) { DrawFileRow(change); } } EditorGUILayout.EndScrollView(); EditorGUILayout.Space(); DrawActionButtons(); } private void DrawFileRow(GitChange change) { EditorGUILayout.BeginHorizontal(EditorStyles.helpBox); EditorGUILayout.LabelField(new GUIContent(change.FilePath, change.FilePath), _wordWrapStyle, GUILayout.ExpandWidth(true)); change.Resolution = (GitChange.ConflictResolution)EditorGUILayout.EnumPopup(change.Resolution, GUILayout.Width(70)); EditorGUILayout.EndHorizontal(); } private void DrawActionButtons() { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); var allResolved = _conflictingFiles != null && _conflictingFiles.All(c => c.Resolution != GitChange.ConflictResolution.None); var pullButtonText = allResolved ? "Pull Safely" : "Pull Anyways (Risky)"; if (GUILayout.Button(pullButtonText, GUILayout.Height(30), GUILayout.Width(180))) { _controller?.ResolveConflictsAndPull(_conflictingFiles); Close(); } if (GUILayout.Button("Cancel", GUILayout.Height(30))) { Close(); } EditorGUILayout.EndHorizontal(); } } }