Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit 6e8ed9a

Browse files
Adding generalized FileHistoryWindow and HistoryBase
1 parent 5f566c4 commit 6e8ed9a

File tree

4 files changed

+323
-299
lines changed

4 files changed

+323
-299
lines changed

src/UnityExtension/Assets/Editor/GitHub.Unity/Misc/Styles.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,14 +472,14 @@ public static GUIStyle ToolbarButtonStyle
472472
}
473473
}
474474

475-
public static GUIStyle HistoryLockStyle
475+
public static GUIStyle LockButtonStyle
476476
{
477477
get
478478
{
479479
if (historyLockStyle == null)
480480
{
481481
historyLockStyle = new GUIStyle(GUI.skin.FindStyle("IN LockButton"));
482-
historyLockStyle.name = "HistoryLockStyle";
482+
historyLockStyle.name = "LockStyle";
483483
}
484484
historyLockStyle.margin = new RectOffset(3, 3, 2, 2);
485485
return historyLockStyle;

src/UnityExtension/Assets/Editor/GitHub.Unity/UI/ContextMenu.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ private static void GitFileHistory()
1717
foreach(var guid in Selection.assetGUIDs)
1818
{
1919
var assetPath = AssetDatabase.GUIDToAssetPath(guid);
20-
FileHistoryWindow.OpenWindow(assetPath);
20+
FileHistoryWindow.OpenWindow(EntryPoint.ApplicationManager, assetPath);
2121
windowsOpened++;
2222
if (windowsOpened >= maxWindowsToOpen)
2323
{
Lines changed: 93 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,244 +1,149 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
3-
using System;
4-
using UnityEngine;
1+
using System;
52
using UnityEditor;
3+
using UnityEngine;
64

75
namespace GitHub.Unity
86
{
97
public class FileHistoryWindow : BaseWindow
108
{
9+
private const string Title = "File History";
10+
11+
[NonSerialized] private bool firstOnGUI = true;
12+
13+
[SerializeField] private bool locked;
1114
[SerializeField] private string assetPath;
12-
[SerializeField] private List<GitLogEntry> history;
13-
[SerializeField] private Vector2 scroll;
14-
[SerializeField] private Vector2 detailsScroll;
15-
[NonSerialized] private bool busy;
16-
[SerializeField] private HistoryControl historyControl;
17-
[SerializeField] private GitLogEntry selectedEntry = GitLogEntry.Default;
18-
[SerializeField] private ChangesTree treeChanges = new ChangesTree { IsSelectable = false, DisplayRootNode = false };
15+
[SerializeField] private FileHistoryView fileHistoryView = new FileHistoryView();
1916

20-
public static FileHistoryWindow OpenWindow(string assetPath)
17+
public static FileHistoryWindow OpenWindow(IApplicationManager applicationManager, string assetPath)
2118
{
22-
var popupWindow = CreateInstance<FileHistoryWindow>();
19+
var fileHistoryWindow = CreateInstance<FileHistoryWindow>();
20+
fileHistoryWindow.InitializeWindow(applicationManager);
2321

24-
popupWindow.titleContent = new GUIContent(assetPath + " History");
25-
popupWindow.Open(assetPath);
22+
fileHistoryWindow.Open(assetPath);
23+
fileHistoryWindow.Show();
2624

27-
popupWindow.Show();
25+
return fileHistoryWindow;
26+
}
2827

29-
return popupWindow;
28+
public void Open(string path)
29+
{
30+
assetPath = path;
31+
fileHistoryView.SetPath(path);
3032
}
3133

32-
public override bool IsBusy { get { return this.busy; } }
34+
public override void Initialize(IApplicationManager applicationManager)
35+
{
36+
base.Initialize(applicationManager);
3337

34-
public void Open(string assetPath)
38+
fileHistoryView.InitializeView(this);
39+
}
40+
41+
public override bool IsBusy
3542
{
36-
this.assetPath = assetPath;
43+
get { return false; }
44+
}
3745

38-
this.RefreshLog();
46+
public override void OnEnable()
47+
{
48+
base.OnEnable();
49+
50+
if (fileHistoryView != null)
51+
fileHistoryView.OnEnable();
3952
}
4053

41-
public void RefreshLog()
54+
public override void OnDisable()
4255
{
43-
var path = Application.dataPath.ToNPath().Parent.Combine(assetPath.ToNPath());
44-
this.busy = true;
45-
this.GitClient.LogFile(path).ThenInUI((success, logEntries) => {
46-
this.history = logEntries;
47-
this.BuildHistoryControl();
48-
this.Repaint();
49-
this.busy = false;
50-
}).Start();
56+
base.OnDisable();
57+
if (fileHistoryView != null)
58+
fileHistoryView.OnDisable();
5159
}
5260

53-
private void CheckoutVersion(string commitID)
61+
public override void OnDataUpdate()
5462
{
55-
this.busy = true;
56-
this.GitClient.CheckoutVersion(commitID, new string[]{assetPath}).ThenInUI((success, result) => {
57-
AssetDatabase.Refresh();
58-
this.busy = false;
59-
}).Start();
63+
base.OnDataUpdate();
64+
MaybeUpdateData();
65+
66+
if (fileHistoryView != null)
67+
fileHistoryView.OnDataUpdate();
6068
}
6169

62-
private void Checkout()
70+
public override void OnFocusChanged()
6371
{
64-
// TODO: This is a destructive, irreversible operation; we should prompt user if
65-
// there are any changes to the file
66-
this.CheckoutVersion(this.selectedEntry.CommitID);
72+
if (fileHistoryView != null)
73+
fileHistoryView.OnFocusChanged();
6774
}
6875

69-
public override void OnUI()
76+
public override void OnRepositoryChanged(IRepository oldRepository)
7077
{
71-
// TODO:
72-
// - should handle case where the file is outside of the repository (handle exceptional cases)
73-
// - should display a spinner while history is still loading...
74-
base.OnUI();
75-
GUILayout.BeginHorizontal(Styles.HeaderStyle);
78+
base.OnRepositoryChanged(oldRepository);
79+
80+
DetachHandlers(oldRepository);
81+
AttachHandlers(Repository);
82+
83+
if (HasRepository)
7684
{
77-
GUILayout.Label("GIT File History for: ", Styles.BoldLabel);
78-
if (HyperlinkLabel(this.assetPath))
79-
{
80-
var asset = AssetDatabase.LoadMainAssetAtPath(this.assetPath);
81-
Selection.activeObject = asset;
82-
EditorGUIUtility.PingObject(asset);
83-
}
84-
GUILayout.FlexibleSpace();
85+
8586
}
86-
GUILayout.EndHorizontal();
87-
88-
if (historyControl != null)
87+
else
8988
{
90-
var rect = GUILayoutUtility.GetLastRect();
91-
var historyControlRect = new Rect(0f, 0f, Position.width, Position.height - rect.height);
92-
93-
var requiresRepaint = historyControl.Render(historyControlRect,
94-
entry => {
95-
selectedEntry = entry;
96-
BuildTree();
97-
},
98-
entry => { }, entry => {
99-
GenericMenu menu = new GenericMenu();
100-
menu.AddItem(new GUIContent("Checkout version " + entry.ShortID), false, Checkout);
101-
menu.ShowAsContext();
102-
});
103-
104-
if (requiresRepaint)
105-
Redraw();
89+
10690
}
91+
}
10792

108-
// DrawDetails is maybe irrelevant? Would be a nice place to put the short id perhaps?
109-
DrawDetails();
93+
public override void OnSelectionChange()
94+
{
95+
base.OnSelectionChange();
96+
if (fileHistoryView != null)
97+
fileHistoryView.OnSelectionChange();
11098
}
11199

112-
private bool HyperlinkLabel(string label)
100+
public override void Refresh()
113101
{
114-
bool returnValue = false;
115-
if (GUILayout.Button(label, HyperlinkStyle))
116-
{
117-
returnValue = true;
118-
}
119-
var rect = GUILayoutUtility.GetLastRect();
120-
var size = HyperlinkStyle.CalcSize(new GUIContent(label));
121-
rect.width = size.x;
122-
EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link);
123-
return returnValue;
102+
base.Refresh();
103+
if (fileHistoryView != null)
104+
fileHistoryView.Refresh();
105+
Refresh(CacheType.GitLocks);
106+
Redraw();
124107
}
125108

126-
private void BuildHistoryControl()
109+
public override void OnUI()
127110
{
128-
if (historyControl == null)
129-
{
130-
historyControl = new HistoryControl();
131-
}
111+
base.OnUI();
132112

133-
historyControl.Load(0, this.history);
113+
fileHistoryView.OnGUI();
134114
}
135115

136-
private const string CommitDetailsTitle = "Commit details";
137-
private const string ClearSelectionButton = "×";
138-
139-
private void DrawDetails()
116+
private void MaybeUpdateData()
140117
{
141-
if (!selectedEntry.Equals(GitLogEntry.Default))
118+
if (firstOnGUI)
142119
{
143-
// Top bar for scrolling to selection or clearing it
144-
GUILayout.BeginHorizontal(EditorStyles.toolbar);
145-
{
146-
if (GUILayout.Button(CommitDetailsTitle, Styles.ToolbarButtonStyle))
147-
{
148-
historyControl.ScrollTo(historyControl.SelectedIndex);
149-
}
150-
if (GUILayout.Button(ClearSelectionButton, Styles.ToolbarButtonStyle, GUILayout.ExpandWidth(false)))
151-
{
152-
selectedEntry = GitLogEntry.Default;
153-
historyControl.SelectedIndex = -1;
154-
}
155-
}
156-
GUILayout.EndHorizontal();
157-
158-
// Log entry details - including changeset tree (if any changes are found)
159-
detailsScroll = GUILayout.BeginScrollView(detailsScroll, GUILayout.Height(250));
160-
{
161-
HistoryDetailsEntry(selectedEntry);
162-
163-
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
164-
GUILayout.Label("Files changed", EditorStyles.boldLabel);
165-
GUILayout.Space(-5);
166-
167-
var rect = GUILayoutUtility.GetLastRect();
168-
GUILayout.BeginHorizontal(Styles.HistoryFileTreeBoxStyle);
169-
GUILayout.BeginVertical();
170-
{
171-
var borderLeft = Styles.Label.margin.left;
172-
var treeControlRect = new Rect(rect.x + borderLeft, rect.y, Position.width - borderLeft * 2, Position.height - rect.height + Styles.CommitAreaPadding);
173-
var treeRect = new Rect(0f, 0f, 0f, 0f);
174-
if (treeChanges != null)
175-
{
176-
treeChanges.FolderStyle = Styles.Foldout;
177-
treeChanges.TreeNodeStyle = Styles.TreeNode;
178-
treeChanges.ActiveTreeNodeStyle = Styles.ActiveTreeNode;
179-
treeChanges.FocusedTreeNodeStyle = Styles.FocusedTreeNode;
180-
treeChanges.FocusedActiveTreeNodeStyle = Styles.FocusedActiveTreeNode;
181-
182-
treeRect = treeChanges.Render(treeControlRect, detailsScroll,
183-
node => {
184-
},
185-
node => {
186-
},
187-
node => {
188-
});
189-
190-
if (treeChanges.RequiresRepaint)
191-
Redraw();
192-
}
193-
194-
GUILayout.Space(treeRect.y - treeControlRect.y);
195-
}
196-
GUILayout.EndVertical();
197-
GUILayout.EndHorizontal();
198-
199-
GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
200-
}
201-
GUILayout.EndScrollView();
120+
titleContent = new GUIContent(Title, Styles.SmallLogo);
202121
}
122+
firstOnGUI = false;
203123
}
204124

205-
private void HistoryDetailsEntry(GitLogEntry entry)
125+
private void AttachHandlers(IRepository repository)
206126
{
207-
GUILayout.BeginVertical(Styles.HeaderBoxStyle);
208-
GUILayout.Label(entry.Summary, Styles.HistoryDetailsTitleStyle);
209-
210-
GUILayout.Space(-5);
211-
212-
GUILayout.BeginHorizontal();
213-
GUILayout.Label(entry.PrettyTimeString, Styles.HistoryDetailsMetaInfoStyle);
214-
GUILayout.Label(entry.AuthorName, Styles.HistoryDetailsMetaInfoStyle);
215-
GUILayout.FlexibleSpace();
216-
GUILayout.EndHorizontal();
217-
218-
GUILayout.Space(3);
219-
GUILayout.EndVertical();
127+
if (repository == null)
128+
return;
220129
}
221130

222-
private void BuildTree()
131+
private void DetachHandlers(IRepository repository)
223132
{
224-
treeChanges.PathSeparator = Environment.FileSystem.DirectorySeparatorChar.ToString();
225-
treeChanges.Load(selectedEntry.changes.Select(entry => new GitStatusEntryTreeData(entry)));
226-
Redraw();
133+
if (repository == null)
134+
return;
227135
}
228136

229-
protected static GUIStyle hyperlinkStyle = null;
230-
231-
public static GUIStyle HyperlinkStyle
137+
private void ShowButton(Rect rect)
232138
{
233-
get
234-
{
235-
if (hyperlinkStyle == null)
236-
{
237-
hyperlinkStyle = new GUIStyle(EditorStyles.wordWrappedLabel);
238-
hyperlinkStyle.normal.textColor = new Color(95.0f/255.0f, 170.0f/255.0f, 247.0f/255.0f);
239-
}
240-
return hyperlinkStyle;
241-
}
242-
}
139+
EditorGUI.BeginChangeCheck();
140+
141+
locked = GUI.Toggle(rect, locked, GUIContent.none, Styles.LockButtonStyle);
142+
143+
if (!EditorGUI.EndChangeCheck())
144+
return;
145+
146+
this.OnSelectionChange();
147+
}
243148
}
244-
}
149+
}

0 commit comments

Comments
 (0)