using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEditor.SceneManagement; namespace GitMerge { /// /// The window that lets you perform merges on scenes and prefabs. /// public class GitMergeWindow : EditorWindow { private VCS vcs = new VCSGit (); //EditorPrefs keys for settings private const string epAutomerge = "GitMerge_automerge"; private const string epAutofocus = "GitMerge_autofocus"; //Settings public static bool automerge { private set; get; } public static bool autofocus { private set; get; } //The MergeManager that has the actual merging logic private MergeManager manager; public bool mergeInProgress { get { return manager != null; } } private Vector2 scrollPosition = Vector2.zero; private int tab = 0; [MenuItem ("Window/GitMerge")] static void OpenEditor () { var window = EditorWindow.GetWindow (typeof (GitMergeWindow), false, "GitMerge"); //In case we're merging and the scene becomes edited, //the shown SerializedProperties should be repainted window.autoRepaintOnSceneChange = true; window.minSize = new Vector2 (500, 100); } void OnEnable () { LoadSettings (); } private static void LoadSettings () { if (EditorPrefs.HasKey (epAutomerge)) { automerge = EditorPrefs.GetBool (epAutomerge); } else { automerge = true; } if (EditorPrefs.HasKey (epAutofocus)) { autofocus = EditorPrefs.GetBool (epAutofocus); } else { autofocus = true; } } void OnHierarchyChange () { //Repaint if we changed the scene this.Repaint (); } //Always check for editor state changes, and abort the active merge process if needed void Update () { if (MergeAction.inMergePhase && (EditorApplication.isCompiling || EditorApplication.isPlayingOrWillChangePlaymode)) { ShowNotification (new GUIContent ("Aborting merge due to editor state change.")); AbortMerge (); } } private void AbortMerge () { manager.AbortMerge (); manager = null; } void OnGUI () { Resources.DrawLogo (); DrawTabButtons (); switch (tab) { case 0: OnGUISceneTab (); break; case 1: OnGUIPrefabTab (); break; default: OnGUISettingsTab (); break; } } /// /// Tab that offers scene merging. /// private void OnGUISceneTab () { GUILayout.Label ("Open Scene: " + EditorSceneManager.GetActiveScene().ToString()); if (EditorSceneManager.GetActiveScene().ToString() != "" && !mergeInProgress && GUILayout.Button ("Start merging this scene", GUILayout.Height (80))) { var mm = new MergeManagerScene (this, vcs); if (mm.InitializeMerge ()) { manager = mm; } } DisplayMergeProcess (); } /// /// Tab that offers prefab merging. /// private void OnGUIPrefabTab () { GameObject prefab; if (!mergeInProgress) { GUILayout.Label ("Drag your prefab here to start merging:"); if (prefab = EditorGUILayout.ObjectField (null, typeof (GameObject), false, GUILayout.Height (60)) as GameObject) { var mm = new MergeManagerPrefab (this, vcs); if (mm.InitializeMerge (prefab)) { manager = mm; } } } DisplayMergeProcess (); } /// /// Tab that offers various settings for the tool. /// private void OnGUISettingsTab () { var vcsPath = vcs.exe (); var vcsPathNew = EditorGUILayout.TextField ("Path to git.exe", vcsPath); if (vcsPath != vcsPathNew) { vcs.SetPath (vcsPathNew); } var amNew = EditorGUILayout.Toggle ("Automerge", automerge); if (automerge != amNew) { automerge = amNew; EditorPrefs.SetBool (epAutomerge, automerge); } GUILayout.Label ("(Automerge new/deleted GameObjects/Components upon merge start)"); var afNew = EditorGUILayout.Toggle ("Auto Highlight", autofocus); if (autofocus != afNew) { autofocus = afNew; EditorPrefs.SetBool (epAutofocus, autofocus); } GUILayout.Label ("(Highlight GameObjects when applying a MergeAction to it)"); } /// /// If no merge is in progress, draws the buttons to switch between tabs. /// Otherwise, draws the "abort merge" button. /// private void DrawTabButtons () { if (!mergeInProgress) { string[] tabs = { "Merge Scene", "Merge Prefab", "Settings" }; tab = GUI.SelectionGrid (new Rect (72, 36, 300, 22), tab, tabs, 3); } else { GUI.backgroundColor = new Color (1, 0.4f, 0.4f, 1); if (GUI.Button (new Rect (72, 36, 300, 22), "Abort merge")) { manager.AbortMerge (); manager = null; } GUI.backgroundColor = Color.white; } } /// /// Displays all MergeActions and the "apply merge" button if a merge is in progress. /// private void DisplayMergeProcess () { if (mergeInProgress) { var done = DisplayMergeActions (); GUILayout.BeginHorizontal (); if (done && GUILayout.Button ("Apply merge")) { manager.CompleteMerge (); manager = null; } GUILayout.EndHorizontal (); } } /// /// Displays all GameObjectMergeActions. /// /// True, if all MergeActions are flagged as "merged". private bool DisplayMergeActions () { scrollPosition = GUILayout.BeginScrollView (scrollPosition, false, true); GUILayout.BeginVertical (GUILayout.MinWidth (480)); var textColor = GUI.skin.label.normal.textColor; GUI.skin.label.normal.textColor = Color.black; var done = true; foreach (var actions in manager.allMergeActions) { actions.OnGUI (); done = done && actions.merged; } GUI.skin.label.normal.textColor = textColor; GUILayout.EndVertical (); GUILayout.EndScrollView (); return done; } } }