ConflictResolutionWindow.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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 UnityEngine.Scripting;
  8. using System.Collections.Generic;
  9. namespace Terra.Arbitrator.GUI
  10. {
  11. [Preserve]
  12. public class ConflictResolutionWindow : EditorWindow
  13. {
  14. private List<string> _conflictingFiles;
  15. private string _fileBeingReset;
  16. private Vector2 _scrollPosition;
  17. private ArbitratorController _controller;
  18. /// <summary>
  19. /// Shows a modal window to display pull conflicts and get user action.
  20. /// </summary>
  21. /// <param name="controller">Reference to the arbitrator controller</param>
  22. /// <param name="conflictingFiles">The list of files that have conflicts.</param>
  23. public static void ShowWindow(ArbitratorController controller, List<string> conflictingFiles)
  24. {
  25. var window = GetWindow<ConflictResolutionWindow>(true, "Pull Conflicts Detected", true);
  26. window.minSize = new Vector2(600, 400);
  27. window._controller = controller;
  28. window._conflictingFiles = new List<string>(conflictingFiles);
  29. window.ShowModalUtility();
  30. }
  31. private void OnGUI()
  32. {
  33. 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);
  34. EditorGUILayout.LabelField("Conflicting Files:", EditorStyles.boldLabel);
  35. _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox);
  36. foreach (var file in new List<string>(_conflictingFiles))
  37. {
  38. DrawFileRow(file);
  39. }
  40. EditorGUILayout.EndScrollView();
  41. EditorGUILayout.Space();
  42. DrawActionButtons();
  43. }
  44. private void DrawFileRow(string filePath)
  45. {
  46. EditorGUILayout.BeginHorizontal();
  47. EditorGUILayout.LabelField(new GUIContent(filePath, filePath));
  48. var isThisFileLoading = _fileBeingReset == filePath;
  49. EditorGUI.BeginDisabledGroup(isThisFileLoading || !string.IsNullOrEmpty(_fileBeingReset));
  50. if (GUILayout.Button(isThisFileLoading ? "Resetting..." : "Reset", GUILayout.Width(100)))
  51. {
  52. HandleResetFile(filePath);
  53. }
  54. EditorGUI.EndDisabledGroup();
  55. EditorGUILayout.EndHorizontal();
  56. }
  57. private void HandleResetFile(string filePath)
  58. {
  59. _fileBeingReset = filePath;
  60. Repaint();
  61. _controller.ResetSingleConflictingFile(filePath, () =>
  62. {
  63. _conflictingFiles.Remove(filePath);
  64. _fileBeingReset = null;
  65. Repaint();
  66. });
  67. }
  68. private void DrawActionButtons()
  69. {
  70. EditorGUILayout.BeginHorizontal();
  71. GUILayout.FlexibleSpace();
  72. if (GUILayout.Button("Proceed with Pull (Risky)", GUILayout.Height(30), GUILayout.Width(180)))
  73. {
  74. _controller.ForcePull();
  75. Close();
  76. }
  77. if (GUILayout.Button("Cancel", GUILayout.Height(30)))
  78. {
  79. Close();
  80. }
  81. EditorGUILayout.EndHorizontal();
  82. }
  83. }
  84. }