ConflictResolutionWindow.cs 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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 System.IO;
  6. using UnityEditor;
  7. using UnityEngine;
  8. using System.Linq;
  9. using UnityEngine.Scripting;
  10. using Terra.Arbitrator.Services;
  11. using System.Collections.Generic;
  12. namespace Terra.Arbitrator.GUI
  13. {
  14. [Preserve]
  15. public class ConflictResolutionWindow : EditorWindow
  16. {
  17. private List<GitChange> _conflictingFiles;
  18. private Vector2 _scrollPosition;
  19. private ArbitratorController _controller;
  20. private GUIStyle _wordWrapStyle;
  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. public static void ShowWindow(ArbitratorController controller, IReadOnlyList<GitChange> conflictingFiles)
  27. {
  28. var window = GetWindow<ConflictResolutionWindow>(true, "Pull Conflicts Detected", true);
  29. window.minSize = new Vector2(600, 400);
  30. window._controller = controller;
  31. window._conflictingFiles = new List<GitChange>(conflictingFiles);
  32. window.ShowModalUtility();
  33. }
  34. private void OnGUI()
  35. {
  36. _wordWrapStyle ??= new GUIStyle(EditorStyles.label) { wordWrap = true };
  37. 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);
  38. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
  39. GUILayout.Label("Filename");
  40. GUILayout.FlexibleSpace();
  41. GUILayout.Label(""); //Spacer
  42. GUILayout.FlexibleSpace();
  43. GUILayout.Label("Choice", GUILayout.Width(70));
  44. EditorGUILayout.EndHorizontal();
  45. _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox);
  46. if (_conflictingFiles != null)
  47. {
  48. foreach (var change in _conflictingFiles)
  49. {
  50. DrawFileRow(change);
  51. }
  52. }
  53. EditorGUILayout.EndScrollView();
  54. EditorGUILayout.Space();
  55. DrawActionButtons();
  56. }
  57. private void DrawFileRow(GitChange change)
  58. {
  59. EditorGUILayout.BeginHorizontal(EditorStyles.helpBox);
  60. EditorGUILayout.LabelField(new GUIContent(change.FilePath, change.FilePath), _wordWrapStyle, GUILayout.ExpandWidth(true));
  61. change.Resolution = (GitChange.ConflictResolution)EditorGUILayout.EnumPopup(change.Resolution, GUILayout.Width(70));
  62. EditorGUILayout.EndHorizontal();
  63. }
  64. private void DrawActionButtons()
  65. {
  66. EditorGUILayout.BeginHorizontal();
  67. GUILayout.FlexibleSpace();
  68. var allResolved = _conflictingFiles != null && _conflictingFiles.All(c => c.Resolution != GitChange.ConflictResolution.None);
  69. var pullButtonText = allResolved ? "Pull Safely" : "Pull Anyways (Risky)";
  70. if (GUILayout.Button(pullButtonText, GUILayout.Height(30), GUILayout.Width(180)))
  71. {
  72. _controller?.ResolveConflictsAndPull(_conflictingFiles);
  73. Close();
  74. }
  75. if (GUILayout.Button("Cancel", GUILayout.Height(30)))
  76. {
  77. Close();
  78. }
  79. EditorGUILayout.EndHorizontal();
  80. }
  81. }
  82. }