ConflictResolutionWindow.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (c) 2025 TerraByte Inc.
  2. //
  3. // A modal editor window that displays pull conflicts and allows the user
  4. // to select files to reset before proceeding.
  5. using UnityEditor;
  6. using UnityEngine;
  7. using System.Linq;
  8. using UnityEngine.Scripting;
  9. using Terra.Arbitrator.Services;
  10. using System.Collections.Generic;
  11. namespace Terra.Arbitrator.GUI
  12. {
  13. [Preserve]
  14. public class ConflictResolutionWindow : EditorWindow
  15. {
  16. private Vector2 _scrollPosition;
  17. private GUIStyle _wordWrapStyle;
  18. private IConflictSource _conflictSource;
  19. private ArbitratorController _controller;
  20. private List<GitChange> _conflictingFiles;
  21. /// <summary>
  22. /// Shows a modal window to display pull conflicts and get user action.
  23. /// </summary>
  24. /// <param name="controller">Reference to the arbitrator controller</param>
  25. /// <param name="conflictingFiles">The list of files that have conflicts.</param>
  26. /// <param name="source">The source of the conflict (e.g., pull, stash).</param>
  27. public static void ShowWindow(ArbitratorController controller, IReadOnlyList<GitChange> conflictingFiles, IConflictSource source)
  28. {
  29. var window = GetWindow<ConflictResolutionWindow>(true, "Pull Conflicts Detected", true);
  30. window.minSize = new Vector2(600, 400);
  31. window._controller = controller;
  32. window._conflictingFiles = new List<GitChange>(conflictingFiles);
  33. window._conflictSource = source;
  34. window.ShowModalUtility();
  35. }
  36. private void OnGUI()
  37. {
  38. _wordWrapStyle ??= new GUIStyle(EditorStyles.label) { wordWrap = true };
  39. 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);
  40. EditorGUILayout.LabelField($"Mine: {_conflictSource?.MineLabel ?? "Your Changes"}", EditorStyles.boldLabel);
  41. EditorGUILayout.LabelField($"Theirs: {_conflictSource?.TheirsLabel ?? "Incoming Changes"}", EditorStyles.boldLabel);
  42. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
  43. GUILayout.Label("Filename");
  44. GUILayout.FlexibleSpace();
  45. GUILayout.Label(""); //Spacer
  46. GUILayout.FlexibleSpace();
  47. GUILayout.Label("Choice", GUILayout.Width(70));
  48. EditorGUILayout.EndHorizontal();
  49. _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox);
  50. if (_conflictingFiles != null)
  51. {
  52. foreach (var change in _conflictingFiles)
  53. {
  54. DrawFileRow(change);
  55. }
  56. }
  57. EditorGUILayout.EndScrollView();
  58. EditorGUILayout.Space();
  59. DrawActionButtons();
  60. }
  61. private void DrawFileRow(GitChange change)
  62. {
  63. EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
  64. EditorGUILayout.LabelField(new GUIContent(change.FilePath, change.FilePath), _wordWrapStyle, GUILayout.ExpandWidth(true));
  65. change.Resolution = (GitChange.ConflictResolution)EditorGUILayout.EnumPopup(change.Resolution, GUILayout.Width(70));
  66. EditorGUILayout.EndHorizontal();
  67. }
  68. private void DrawActionButtons()
  69. {
  70. EditorGUILayout.BeginHorizontal();
  71. GUILayout.FlexibleSpace();
  72. var allResolved = _conflictingFiles != null && _conflictingFiles.All(c => c.Resolution != GitChange.ConflictResolution.None);
  73. var pullButtonText = allResolved ? "Resolve Safely" : "Resolve with Unchosen (Risky)";
  74. if (GUILayout.Button(pullButtonText, GUILayout.Height(30), GUILayout.Width(180)))
  75. {
  76. if (_controller != null && _conflictSource != null)
  77. {
  78. _controller.ResolveConflicts(_conflictingFiles, _conflictSource);
  79. }
  80. Close();
  81. }
  82. if (GUILayout.Button("Cancel", GUILayout.Height(30)))
  83. {
  84. Close();
  85. }
  86. EditorGUILayout.EndHorizontal();
  87. }
  88. }
  89. }