6
6
7
7
namespace GitHub . Unity
8
8
{
9
- struct HistoryControlRenderResult
10
- {
11
- public Rect Rect ;
12
- public bool RequiresRepaint ;
13
- }
14
-
15
9
[ Serializable ]
16
10
class HistoryControl
17
11
{
18
12
private const string HistoryEntryDetailFormat = "{0} {1}" ;
19
13
14
+ [ SerializeField ] private Vector2 scroll ;
20
15
[ SerializeField ] private List < GitLogEntry > entries = new List < GitLogEntry > ( ) ;
21
16
[ SerializeField ] private int statusAhead ;
22
- [ SerializeField ] private int selectedIndex ;
17
+ [ SerializeField ] private int selectedIndex = - 1 ;
23
18
24
19
[ NonSerialized ] private Action < GitLogEntry > rightClickNextRender ;
25
20
[ NonSerialized ] private GitLogEntry rightClickNextRenderEntry ;
26
21
[ NonSerialized ] private int controlId ;
27
22
28
- public HistoryControlRenderResult Render ( Rect containingRect , Rect rect , Vector2 scroll , Action < GitLogEntry > singleClick = null ,
23
+ public int SelectedIndex
24
+ {
25
+ get { return selectedIndex ; }
26
+ set { selectedIndex = value ; }
27
+ }
28
+
29
+ public GitLogEntry SelectedGitLogEntry
30
+ {
31
+ get { return SelectedIndex < 0 ? GitLogEntry . Default : entries [ SelectedIndex ] ; }
32
+ }
33
+
34
+ public bool Render ( Rect containingRect , Action < GitLogEntry > singleClick = null ,
29
35
Action < GitLogEntry > doubleClick = null , Action < GitLogEntry > rightClick = null )
30
36
{
31
37
var requiresRepaint = false ;
38
+ var rect = Rect . zero ;
32
39
33
- controlId = GUIUtility . GetControlID ( FocusType . Keyboard ) ;
34
-
35
- if ( Event . current . type != EventType . Repaint )
40
+ scroll = GUILayout . BeginScrollView ( scroll ) ;
36
41
{
37
- if ( rightClickNextRender != null )
42
+ controlId = GUIUtility . GetControlID ( FocusType . Keyboard ) ;
43
+
44
+ if ( Event . current . type != EventType . Repaint )
38
45
{
39
- rightClickNextRender . Invoke ( rightClickNextRenderEntry ) ;
40
- rightClickNextRender = null ;
41
- rightClickNextRenderEntry = GitLogEntry . Default ;
46
+ if ( rightClickNextRender != null )
47
+ {
48
+ rightClickNextRender . Invoke ( rightClickNextRenderEntry ) ;
49
+ rightClickNextRender = null ;
50
+ rightClickNextRenderEntry = GitLogEntry . Default ;
51
+ }
42
52
}
43
- }
44
53
45
- var startDisplay = scroll . y ;
46
- var endDisplay = scroll . y + containingRect . height ;
54
+ var startDisplay = scroll . y ;
55
+ var endDisplay = scroll . y + containingRect . height ;
47
56
48
- rect = new Rect ( rect . x , rect . y , rect . width , 0 ) ;
57
+ rect = new Rect ( containingRect . x , containingRect . y , containingRect . width , 0 ) ;
49
58
50
- for ( var index = 0 ; index < entries . Count ; index ++ )
51
- {
52
- var entry = entries [ index ] ;
59
+ for ( var index = 0 ; index < entries . Count ; index ++ )
60
+ {
61
+ var entry = entries [ index ] ;
53
62
54
- var entryRect = new Rect ( rect . x , rect . y , rect . width , Styles . HistoryEntryHeight ) ;
63
+ var entryRect = new Rect ( rect . x , rect . y , rect . width , Styles . HistoryEntryHeight ) ;
55
64
56
- var shouldRenderEntry = ! ( entryRect . y > endDisplay || entryRect . yMax < startDisplay ) ;
57
- if ( shouldRenderEntry && Event . current . type == EventType . Repaint )
58
- {
59
- RenderEntry ( entryRect , entry , index ) ;
60
- }
65
+ var shouldRenderEntry = ! ( entryRect . y > endDisplay || entryRect . yMax < startDisplay ) ;
66
+ if ( shouldRenderEntry && Event . current . type == EventType . Repaint )
67
+ {
68
+ RenderEntry ( entryRect , entry , index ) ;
69
+ }
61
70
62
- var entryRequiresRepaint = HandleInput ( entryRect , entry , index , singleClick , doubleClick , rightClick ) ;
63
- requiresRepaint = requiresRepaint || entryRequiresRepaint ;
71
+ var entryRequiresRepaint = HandleInput ( entryRect , entry , index , singleClick , doubleClick , rightClick ) ;
72
+ requiresRepaint = requiresRepaint || entryRequiresRepaint ;
64
73
65
- rect . y += Styles . HistoryEntryHeight ;
74
+ rect . y += Styles . HistoryEntryHeight ;
75
+ }
66
76
}
67
77
68
- return new HistoryControlRenderResult {
69
- Rect = rect ,
70
- RequiresRepaint = requiresRepaint
71
- } ;
78
+ GUILayout . Space ( rect . y - containingRect . y ) ;
79
+
80
+ GUILayout . EndScrollView ( ) ;
81
+
82
+ return requiresRepaint ;
72
83
}
73
84
74
85
private void RenderEntry ( Rect entryRect , GitLogEntry entry , int index )
75
86
{
76
87
var isLocalCommit = index < statusAhead ;
77
- var isSelected = index == selectedIndex ;
88
+ var isSelected = index == SelectedIndex ;
78
89
var summaryRect = new Rect ( entryRect . x , entryRect . y + Styles . BaseSpacing / 2 , entryRect . width , Styles . HistorySummaryHeight + Styles . BaseSpacing ) ;
79
90
var timestampRect = new Rect ( entryRect . x , entryRect . yMax - Styles . HistoryDetailsHeight - Styles . BaseSpacing / 2 , entryRect . width , Styles . HistoryDetailsHeight ) ;
80
91
@@ -139,7 +150,7 @@ private bool HandleInput(Rect rect, GitLogEntry entry, int index, Action<GitLogE
139
150
Event . current . Use ( ) ;
140
151
GUIUtility . keyboardControl = controlId ;
141
152
142
- selectedIndex = index ;
153
+ SelectedIndex = index ;
143
154
requiresRepaint = true ;
144
155
var clickCount = Event . current . clickCount ;
145
156
var mouseButton = Event . current . button ;
@@ -160,7 +171,7 @@ private bool HandleInput(Rect rect, GitLogEntry entry, int index, Action<GitLogE
160
171
}
161
172
162
173
// Keyboard navigation if this child is the current selection
163
- if ( GUIUtility . keyboardControl == controlId && index == selectedIndex && Event . current . type == EventType . KeyDown )
174
+ if ( GUIUtility . keyboardControl == controlId && index == SelectedIndex && Event . current . type == EventType . KeyDown )
164
175
{
165
176
var directionY = Event . current . keyCode == KeyCode . UpArrow ? - 1 : Event . current . keyCode == KeyCode . DownArrow ? 1 : 0 ;
166
177
if ( directionY != 0 )
@@ -213,8 +224,27 @@ private void DrawTimelineRectAroundIconRect(Rect parentRect, Rect iconRect)
213
224
214
225
public void Load ( int loadAhead , List < GitLogEntry > loadEntries )
215
226
{
227
+ var selectedCommitId = SelectedGitLogEntry . CommitID ;
228
+
216
229
statusAhead = loadAhead ;
217
230
entries = loadEntries ;
231
+
232
+ var changed = false ;
233
+ for ( var index = 0 ; index < entries . Count ; index ++ )
234
+ {
235
+ var gitLogEntry = entries [ index ] ;
236
+ if ( gitLogEntry . CommitID . Equals ( selectedCommitId ) )
237
+ {
238
+ selectedIndex = index ;
239
+ changed = true ;
240
+ break ;
241
+ }
242
+ }
243
+
244
+ if ( ! changed )
245
+ {
246
+ selectedIndex = - 1 ;
247
+ }
218
248
}
219
249
220
250
private int SelectNext ( int index )
@@ -223,7 +253,7 @@ private int SelectNext(int index)
223
253
224
254
if ( index < entries . Count )
225
255
{
226
- selectedIndex = index ;
256
+ SelectedIndex = index ;
227
257
}
228
258
else
229
259
{
@@ -239,15 +269,20 @@ private int SelectPrevious(int index)
239
269
240
270
if ( index >= 0 )
241
271
{
242
- selectedIndex = index ;
272
+ SelectedIndex = index ;
243
273
}
244
274
else
245
275
{
246
- selectedIndex = - 1 ;
276
+ SelectedIndex = - 1 ;
247
277
}
248
278
249
279
return index ;
250
280
}
281
+
282
+ public void ScrollTo ( int index )
283
+ {
284
+ scroll . Set ( scroll . x , Styles . HistoryEntryHeight * index ) ;
285
+ }
251
286
}
252
287
253
288
enum LogEntryState
@@ -286,8 +321,10 @@ class HistoryView : Subview
286
321
[ SerializeField ] private bool hasRemote ;
287
322
[ SerializeField ] private string currentRemoteName ;
288
323
289
- [ SerializeField ] private Vector2 historyScroll ;
290
324
[ SerializeField ] private HistoryControl historyControl ;
325
+ [ SerializeField ] private GitLogEntry selectedEntry = GitLogEntry . Default ;
326
+
327
+ [ SerializeField ] private Vector2 detailsScroll ;
291
328
292
329
[ SerializeField ] private List < GitLogEntry > logEntries = new List < GitLogEntry > ( ) ;
293
330
@@ -393,30 +430,74 @@ public void OnEmbeddedGUI()
393
430
GUILayout . EndHorizontal ( ) ;
394
431
395
432
var rect = GUILayoutUtility . GetLastRect ( ) ;
396
- historyScroll = GUILayout . BeginScrollView ( historyScroll ) ;
397
- {
398
- OnHistoryGUI ( new Rect ( 0f , 0f , Position . width , Position . height - rect . height ) ) ;
399
- }
400
- GUILayout . EndScrollView ( ) ;
401
- }
402
-
403
- private void OnHistoryGUI ( Rect rect )
404
- {
405
- var initialRect = rect ;
406
433
if ( historyControl != null )
407
434
{
408
- var renderResult = historyControl . Render ( initialRect , rect , historyScroll ,
409
- entry => { } ,
435
+ var historyControlRect = new Rect ( 0f , 0f , Position . width , Position . height - rect . height ) ;
436
+
437
+ var requiresRepaint = historyControl . Render ( historyControlRect ,
438
+ entry => {
439
+ selectedEntry = entry ;
440
+ } ,
410
441
entry => { } ,
411
442
entry => { } ) ;
412
443
413
- rect = renderResult . Rect ;
414
-
415
- if ( renderResult . RequiresRepaint )
444
+ if ( requiresRepaint )
416
445
Redraw ( ) ;
417
446
}
418
447
419
- GUILayout . Space ( rect . y - initialRect . y ) ;
448
+ if ( ! selectedEntry . Equals ( GitLogEntry . Default ) )
449
+ {
450
+ // Top bar for scrolling to selection or clearing it
451
+ GUILayout . BeginHorizontal ( EditorStyles . toolbar ) ;
452
+ {
453
+ if ( GUILayout . Button ( CommitDetailsTitle , Styles . HistoryToolbarButtonStyle ) )
454
+ {
455
+ historyControl . ScrollTo ( historyControl . SelectedIndex ) ;
456
+ }
457
+ if ( GUILayout . Button ( ClearSelectionButton , Styles . HistoryToolbarButtonStyle , GUILayout . ExpandWidth ( false ) ) )
458
+ {
459
+ selectedEntry = GitLogEntry . Default ;
460
+ historyControl . SelectedIndex = - 1 ;
461
+ }
462
+ }
463
+ GUILayout . EndHorizontal ( ) ;
464
+
465
+ // Log entry details - including changeset tree (if any changes are found)
466
+ detailsScroll = GUILayout . BeginScrollView ( detailsScroll , GUILayout . Height ( 250 ) ) ;
467
+ {
468
+ HistoryDetailsEntry ( selectedEntry ) ;
469
+
470
+ GUILayout . Space ( EditorGUIUtility . standardVerticalSpacing ) ;
471
+ GUILayout . Label ( "Files changed" , EditorStyles . boldLabel ) ;
472
+ GUILayout . Space ( - 5 ) ;
473
+
474
+ GUILayout . BeginHorizontal ( Styles . HistoryFileTreeBoxStyle ) ;
475
+ {
476
+ //changesetTree.OnGUI();
477
+ }
478
+ GUILayout . EndHorizontal ( ) ;
479
+
480
+ GUILayout . Space ( EditorGUIUtility . standardVerticalSpacing ) ;
481
+ }
482
+ GUILayout . EndScrollView ( ) ;
483
+ }
484
+ }
485
+
486
+ private void HistoryDetailsEntry ( GitLogEntry entry )
487
+ {
488
+ GUILayout . BeginVertical ( Styles . HeaderBoxStyle ) ;
489
+ GUILayout . Label ( entry . Summary , Styles . HistoryDetailsTitleStyle , GUILayout . Width ( Position . width ) ) ;
490
+
491
+ GUILayout . Space ( - 5 ) ;
492
+
493
+ GUILayout . BeginHorizontal ( ) ;
494
+ GUILayout . Label ( entry . PrettyTimeString , Styles . HistoryDetailsMetaInfoStyle ) ;
495
+ GUILayout . Label ( entry . AuthorName , Styles . HistoryDetailsMetaInfoStyle ) ;
496
+ GUILayout . FlexibleSpace ( ) ;
497
+ GUILayout . EndHorizontal ( ) ;
498
+
499
+ GUILayout . Space ( 3 ) ;
500
+ GUILayout . EndVertical ( ) ;
420
501
}
421
502
422
503
private void RepositoryTrackingOnStatusChanged ( CacheUpdateEvent cacheUpdateEvent )
@@ -519,6 +600,11 @@ private void BuildHistoryControl()
519
600
}
520
601
521
602
historyControl . Load ( statusAhead , logEntries ) ;
603
+ if ( ! selectedEntry . Equals ( GitLogEntry . Default )
604
+ && selectedEntry . CommitID != historyControl . SelectedGitLogEntry . CommitID )
605
+ {
606
+ selectedEntry = GitLogEntry . Default ;
607
+ }
522
608
}
523
609
524
610
private void Pull ( )
0 commit comments