123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- // 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.GUI
- {
- public class DiffWindow : EditorWindow
- {
- private string _filePath;
- private string _diffContent;
- private Action<bool> _onCloseCallback;
- private Vector2 _scrollPosition;
- private bool _callbackInvoked;
- private GUIStyle _diffStyle;
- /// <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)
- {
- var 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 OnEnable()
- {
- // Initialize the style here to avoid doing it every OnGUI call.
- _diffStyle = new GUIStyle(EditorStyles.label)
- {
- richText = true,
- wordWrap = false,
- alignment = TextAnchor.UpperLeft
- };
- }
- private void OnGUI()
- {
- EditorGUILayout.LabelField(_filePath, EditorStyles.boldLabel);
- _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, EditorStyles.helpBox);
-
- var coloredText = GetColoredDiff(_diffContent);
- var content = new GUIContent(coloredText);
-
- // Calculate the required height based on the window's width, accounting for scrollbar and padding.
- var viewWidth = EditorGUIUtility.currentViewWidth - 30; // Approximate width inside scroll view
- var requiredHeight = _diffStyle.CalcHeight(content, viewWidth);
-
- // Use GUILayout.Label with an explicit height to ensure the ScrollView's content area is sized correctly.
- EditorGUILayout.SelectableLabel(coloredText, _diffStyle, GUILayout.MinHeight(requiredHeight));
- 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)))
- {
- 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 + "\n";
- }
- 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);
- }
- }
- }
- }
|