123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // Copyright (c) 2025 TerraByte Inc.
- //
- // A modal editor window for displaying text differences (diffs) and
- // confirming an action with the user.
- using System;
- using System.IO;
- using UnityEditor;
- using UnityEngine;
- namespace Terra.Arbitrator
- {
- public class DiffWindow : EditorWindow
- {
- private string _filePath;
- private string _diffContent;
- private Action<bool> _onCloseCallback;
- private Vector2 _scrollPosition;
- private bool _callbackInvoked = false;
- /// <summary>
- /// Shows a modal window to display the diff and get user confirmation.
- /// </summary>
- /// <param name="filePath">The path of the file being diffed.</param>
- /// <param name="diffContent">The diff text to display.</param>
- /// <param name="onCloseCallback">A callback that returns true if the user confirmed, otherwise false.</param>
- public static void ShowWindow(string filePath, string diffContent, Action<bool> onCloseCallback)
- {
- DiffWindow window = GetWindow<DiffWindow>(true, "Diff Viewer", true);
- window.titleContent = new GUIContent($"Diff: {Path.GetFileName(filePath)}");
- window.minSize = new Vector2(700, 500);
- window._filePath = filePath;
- window._diffContent = diffContent;
- window._onCloseCallback = onCloseCallback;
- window._callbackInvoked = false;
- window.ShowModalUtility(); // Show as a blocking modal window
- }
- private void OnGUI()
- {
- EditorGUILayout.LabelField(_filePath, EditorStyles.boldLabel);
- // Create a custom style for the diff text for better readability
- var diffStyle = new GUIStyle(EditorStyles.textArea)
- {
- richText = true,
- wordWrap = false
- };
-
- _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox, GUILayout.ExpandHeight(true));
- EditorGUILayout.SelectableLabel(GetColoredDiff(_diffContent), diffStyle, GUILayout.ExpandHeight(true));
- EditorGUILayout.EndScrollView();
- EditorGUILayout.Space();
- EditorGUILayout.HelpBox("Review the changes above. Green lines are additions, red lines are deletions. Reverting will permanently discard these changes.", MessageType.Warning);
- EditorGUILayout.BeginHorizontal();
- GUILayout.FlexibleSpace();
- if (GUILayout.Button("Revert Changes", GUILayout.Height(30), GUILayout.Width(150)))
- {
- _callbackInvoked = true;
- _onCloseCallback?.Invoke(true);
- Close();
- }
- if (GUILayout.Button("Cancel", GUILayout.Height(30), GUILayout.Width(120)))
- {
- // Let OnDestroy handle the callback
- Close();
- }
- EditorGUILayout.EndHorizontal();
- }
- private static string GetColoredDiff(string rawDiff)
- {
- var coloredDiff = "";
- var lines = rawDiff.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
- foreach (var line in lines)
- {
- if (line.StartsWith("+"))
- {
- coloredDiff += $"<color=green>{line}</color>\n";
- }
- else if (line.StartsWith("-"))
- {
- coloredDiff += $"<color=red>{line}</color>\n";
- }
- else if (line.StartsWith("@@"))
- {
- coloredDiff += $"<color=cyan>{line}</color>\n";
- }
- else
- {
- coloredDiff += $"{line}\n";
- }
- }
- return coloredDiff;
- }
- private void OnDestroy()
- {
- // This is called when the window is closed by any means.
- // If the callback hasn't been invoked yet (i.e., user clicked 'X' or 'Cancel'),
- // we invoke it with 'false' to signify cancellation.
- if (!_callbackInvoked)
- {
- _onCloseCallback?.Invoke(false);
- }
- }
- }
- }
|