Example #1
0
        private void RenderEntry(Rect entryRect, GitLogEntry entry, int index)
        {
            var isLocalCommit = index < statusAhead;
            var isSelected    = index == SelectedIndex;
            var summaryRect   = new Rect(entryRect.x, entryRect.y + Styles.BaseSpacing / 2, entryRect.width, Styles.HistorySummaryHeight + Styles.BaseSpacing);
            var timestampRect = new Rect(entryRect.x, entryRect.yMax - Styles.HistoryDetailsHeight - Styles.BaseSpacing / 2, entryRect.width, Styles.HistoryDetailsHeight);

            var hasKeyboardFocus = GUIUtility.keyboardControl == controlId;

            Styles.Label.Draw(entryRect, GUIContent.none, false, false, isSelected, hasKeyboardFocus);
            Styles.HistoryEntrySummaryStyle.Draw(summaryRect, entry.Summary, false, false, isSelected, hasKeyboardFocus);

            var historyEntryDetail = string.Format(HistoryEntryDetailFormat, entry.PrettyTimeString, entry.AuthorName);

            Styles.HistoryEntryDetailsStyle.Draw(timestampRect, historyEntryDetail, false, false, isSelected, hasKeyboardFocus);

            if (!string.IsNullOrEmpty(entry.MergeA))
            {
                const float MergeIndicatorWidth  = 10.28f;
                const float MergeIndicatorHeight = 12f;
                var         mergeIndicatorRect   = new Rect(entryRect.x + 7, summaryRect.y, MergeIndicatorWidth, MergeIndicatorHeight);

                GUI.DrawTexture(mergeIndicatorRect, Styles.MergeIcon);

                DrawTimelineRectAroundIconRect(entryRect, mergeIndicatorRect);

                summaryRect.Set(mergeIndicatorRect.xMax, summaryRect.y, summaryRect.width - MergeIndicatorWidth,
                                summaryRect.height);
            }
            else
            {
                if (isLocalCommit)
                {
                    const float LocalIndicatorSize = 6f;
                    var         localIndicatorRect = new Rect(entryRect.x + (Styles.BaseSpacing - 2), summaryRect.y + 5, LocalIndicatorSize,
                                                              LocalIndicatorSize);

                    DrawTimelineRectAroundIconRect(entryRect, localIndicatorRect);

                    GUI.DrawTexture(localIndicatorRect, Styles.LocalCommitIcon);

                    summaryRect.Set(localIndicatorRect.xMax, summaryRect.y, summaryRect.width - LocalIndicatorSize,
                                    summaryRect.height);
                }
                else
                {
                    const float NormalIndicatorWidth  = 6f;
                    const float NormalIndicatorHeight = 6f;

                    var normalIndicatorRect = new Rect(entryRect.x + (Styles.BaseSpacing - 2), summaryRect.y + 5,
                                                       NormalIndicatorWidth, NormalIndicatorHeight);

                    DrawTimelineRectAroundIconRect(entryRect, normalIndicatorRect);

                    GUI.DrawTexture(normalIndicatorRect, Styles.DotIcon);
                }
            }
        }
Example #2
0
        private bool HandleInput(Rect rect, GitLogEntry entry, int index, Action <GitLogEntry> singleClick = null,
                                 Action <GitLogEntry> doubleClick = null, Action <GitLogEntry> rightClick = null)
        {
            var requiresRepaint = false;
            var clickRect       = new Rect(0f, rect.y, rect.width, rect.height);

            if (Event.current.type == EventType.MouseDown && clickRect.Contains(Event.current.mousePosition))
            {
                Event.current.Use();
                GUIUtility.keyboardControl = controlId;

                SelectedIndex   = index;
                requiresRepaint = true;
                var clickCount  = Event.current.clickCount;
                var mouseButton = Event.current.button;

                if (mouseButton == 0 && clickCount == 1 && singleClick != null)
                {
                    singleClick(entry);
                }
                if (mouseButton == 0 && clickCount > 1 && doubleClick != null)
                {
                    doubleClick(entry);
                }
                if (mouseButton == 1 && clickCount == 1 && rightClick != null)
                {
                    rightClickNextRender      = rightClick;
                    rightClickNextRenderEntry = entry;
                }
            }

            // Keyboard navigation if this child is the current selection
            if (GUIUtility.keyboardControl == controlId && index == SelectedIndex && Event.current.type == EventType.KeyDown)
            {
                var directionY = Event.current.keyCode == KeyCode.UpArrow ? -1 : Event.current.keyCode == KeyCode.DownArrow ? 1 : 0;
                if (directionY != 0)
                {
                    Event.current.Use();

                    if (directionY > 0)
                    {
                        requiresRepaint = SelectNext(index) != index;
                    }
                    else
                    {
                        requiresRepaint = SelectPrevious(index) != index;
                    }
                }
            }

            return(requiresRepaint);
        }
Example #3
0
        private void BuildHistoryControl()
        {
            if (historyControl == null)
            {
                historyControl = new HistoryControl();
            }

            historyControl.Load(statusAhead, logEntries);
            if (!selectedEntry.Equals(GitLogEntry.Default) &&
                selectedEntry.CommitID != historyControl.SelectedGitLogEntry.CommitID)
            {
                selectedEntry = GitLogEntry.Default;
            }
        }
Example #4
0
        public bool Render(Rect containingRect, Action <GitLogEntry> singleClick = null,
                           Action <GitLogEntry> doubleClick = null, Action <GitLogEntry> rightClick = null)
        {
            var requiresRepaint = false;

            scroll = GUILayout.BeginScrollView(scroll);
            {
                controlId = GUIUtility.GetControlID(FocusType.Keyboard);

                if (Event.current.type != EventType.Repaint)
                {
                    if (rightClickNextRender != null)
                    {
                        rightClickNextRender.Invoke(rightClickNextRenderEntry);
                        rightClickNextRender      = null;
                        rightClickNextRenderEntry = GitLogEntry.Default;
                    }
                }

                var startDisplay = scroll.y;
                var endDisplay   = scroll.y + containingRect.height;

                var rect = new Rect(containingRect.x, containingRect.y, containingRect.width, 0);

                for (var index = 0; index < entries.Count; index++)
                {
                    var entry = entries[index];

                    var entryRect = new Rect(rect.x, rect.y, rect.width, Styles.HistoryEntryHeight);

                    var shouldRenderEntry = !(entryRect.y > endDisplay || entryRect.yMax < startDisplay);
                    if (shouldRenderEntry && Event.current.type == EventType.Repaint)
                    {
                        RenderEntry(entryRect, entry, index);
                    }

                    var entryRequiresRepaint =
                        HandleInput(entryRect, entry, index, singleClick, doubleClick, rightClick);
                    requiresRepaint = requiresRepaint || entryRequiresRepaint;

                    rect.y += Styles.HistoryEntryHeight;
                }

                GUILayout.Space(rect.y - containingRect.y);
            }
            GUILayout.EndScrollView();

            return(requiresRepaint);
        }
Example #5
0
        private void HistoryDetailsEntry(GitLogEntry entry)
        {
            GUILayout.BeginVertical(Styles.HeaderBoxStyle);
            GUILayout.Label(entry.Summary, Styles.HistoryDetailsTitleStyle);

            GUILayout.Space(-5);

            GUILayout.BeginHorizontal();
            GUILayout.Label(entry.PrettyTimeString, Styles.HistoryDetailsMetaInfoStyle);
            GUILayout.Label(entry.AuthorName, Styles.HistoryDetailsMetaInfoStyle);
            GUILayout.FlexibleSpace();
            GUILayout.EndHorizontal();

            GUILayout.Space(3);
            GUILayout.EndVertical();
        }
Example #6
0
 public bool Equals(GitLogEntry other)
 {
     return
         (String.Equals(commitID, other.commitID) &&
          String.Equals(mergeA, other.mergeA) &&
          String.Equals(mergeB, other.mergeB) &&
          String.Equals(authorName, other.authorName) &&
          String.Equals(authorEmail, other.authorEmail) &&
          String.Equals(commitEmail, other.commitEmail) &&
          String.Equals(commitName, other.commitName) &&
          String.Equals(summary, other.summary) &&
          String.Equals(description, other.description) &&
          String.Equals(timeString, other.timeString) &&
          String.Equals(commitTimeString, other.commitTimeString) &&
          object.Equals(changes, other.changes)
         );
 }
Example #7
0
        public override void OnGUI()
        {
            // History toolbar
            GUILayout.BeginHorizontal(EditorStyles.toolbar);
            {
                GUILayout.FlexibleSpace();

                if (hasRemote)
                {
                    EditorGUI.BeginDisabledGroup(currentRemoteName == null);
                    {
                        // Fetch button
                        var fetchClicked = GUILayout.Button(FetchButtonText, Styles.HistoryToolbarButtonStyle);
                        if (fetchClicked)
                        {
                            Fetch();
                        }

                        // Pull button
                        var pullButtonText = statusBehind > 0 ? String.Format(PullButtonCount, statusBehind) : PullButton;
                        var pullClicked    = GUILayout.Button(pullButtonText, Styles.HistoryToolbarButtonStyle);

                        if (pullClicked &&
                            EditorUtility.DisplayDialog(PullConfirmTitle,
                                                        String.Format(PullConfirmDescription, currentRemoteName),
                                                        PullConfirmYes,
                                                        PullConfirmCancel)
                            )
                        {
                            Pull();
                        }
                    }
                    EditorGUI.EndDisabledGroup();

                    // Push button
                    EditorGUI.BeginDisabledGroup(currentRemoteName == null || statusBehind != 0);
                    {
                        var pushButtonText = statusAhead > 0 ? String.Format(PushButtonCount, statusAhead) : PushButton;
                        var pushClicked    = GUILayout.Button(pushButtonText, Styles.HistoryToolbarButtonStyle);

                        if (pushClicked &&
                            EditorUtility.DisplayDialog(PushConfirmTitle,
                                                        String.Format(PushConfirmDescription, currentRemoteName),
                                                        PushConfirmYes,
                                                        PushConfirmCancel)
                            )
                        {
                            Push();
                        }
                    }
                    EditorGUI.EndDisabledGroup();
                }
                else
                {
                    // Publishing a repo
                    var publishedClicked = GUILayout.Button(PublishButton, Styles.HistoryToolbarButtonStyle);
                    if (publishedClicked)
                    {
                        PopupWindow.OpenWindow(PopupWindow.PopupViewType.PublishView);
                    }
                }
            }
            GUILayout.EndHorizontal();

            var rect = GUILayoutUtility.GetLastRect();

            if (historyControl != null)
            {
                var historyControlRect = new Rect(0f, 0f, Position.width, Position.height - rect.height);

                var requiresRepaint = historyControl.Render(historyControlRect,
                                                            entry => {
                    selectedEntry = entry;
                    BuildTree();
                },
                                                            entry => { },
                                                            entry => { });

                if (requiresRepaint)
                {
                    Redraw();
                }
            }

            if (!selectedEntry.Equals(GitLogEntry.Default))
            {
                // Top bar for scrolling to selection or clearing it
                GUILayout.BeginHorizontal(EditorStyles.toolbar);
                {
                    if (GUILayout.Button(CommitDetailsTitle, Styles.HistoryToolbarButtonStyle))
                    {
                        historyControl.ScrollTo(historyControl.SelectedIndex);
                    }
                    if (GUILayout.Button(ClearSelectionButton, Styles.HistoryToolbarButtonStyle, GUILayout.ExpandWidth(false)))
                    {
                        selectedEntry = GitLogEntry.Default;
                        historyControl.SelectedIndex = -1;
                    }
                }
                GUILayout.EndHorizontal();

                // Log entry details - including changeset tree (if any changes are found)
                detailsScroll = GUILayout.BeginScrollView(detailsScroll, GUILayout.Height(250));
                {
                    HistoryDetailsEntry(selectedEntry);

                    GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
                    GUILayout.Label("Files changed", EditorStyles.boldLabel);
                    GUILayout.Space(-5);

                    rect = GUILayoutUtility.GetLastRect();
                    GUILayout.BeginHorizontal(Styles.HistoryFileTreeBoxStyle);
                    GUILayout.BeginVertical();
                    {
                        var borderLeft      = Styles.Label.margin.left;
                        var treeControlRect = new Rect(rect.x + borderLeft, rect.y, Position.width - borderLeft * 2, Position.height - rect.height + Styles.CommitAreaPadding);
                        var treeRect        = Rect.zero;
                        if (treeChanges != null)
                        {
                            treeChanges.FolderStyle                = Styles.Foldout;
                            treeChanges.TreeNodeStyle              = Styles.TreeNode;
                            treeChanges.ActiveTreeNodeStyle        = Styles.ActiveTreeNode;
                            treeChanges.FocusedTreeNodeStyle       = Styles.FocusedTreeNode;
                            treeChanges.FocusedActiveTreeNodeStyle = Styles.FocusedActiveTreeNode;

                            treeRect = treeChanges.Render(treeControlRect, detailsScroll,
                                                          node => { },
                                                          node => {
                            },
                                                          node => {
                            });

                            if (treeChanges.RequiresRepaint)
                            {
                                Redraw();
                            }
                        }

                        GUILayout.Space(treeRect.y - treeControlRect.y);
                    }
                    GUILayout.EndVertical();
                    GUILayout.EndHorizontal();

                    GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
                }
                GUILayout.EndScrollView();
            }
        }
Example #8
0
        private bool HistoryEntry(GitLogEntry entry, LogEntryState state, bool selected)
        {
            var entryRect       = GUILayoutUtility.GetRect(Styles.HistoryEntryHeight, Styles.HistoryEntryHeight);
            var timelineBarRect = new Rect(entryRect.x + Styles.BaseSpacing, 0, 2, Styles.HistoryDetailsHeight);

            if (Event.current.type == EventType.Repaint)
            {
                var keyboardFocus = GUIUtility.keyboardControl == listID;

                var summaryRect   = new Rect(entryRect.x, entryRect.y + (Styles.BaseSpacing / 2), entryRect.width, Styles.HistorySummaryHeight + Styles.BaseSpacing);
                var timestampRect = new Rect(entryRect.x, entryRect.yMax - Styles.HistoryDetailsHeight - (Styles.BaseSpacing / 2), entryRect.width, Styles.HistoryDetailsHeight);
                var authorRect    = new Rect(timestampRect.xMax, timestampRect.y, timestampRect.width, timestampRect.height);

                var contentOffset = new Vector2(Styles.BaseSpacing * 2, 0);

                Styles.Label.Draw(entryRect, "", false, false, selected, keyboardFocus);

                Styles.Label.contentOffset = contentOffset;
                Styles.HistoryEntryDetailsStyle.contentOffset = contentOffset;

                Styles.Label.Draw(summaryRect, entry.Summary, false, false, selected, keyboardFocus);
                Styles.HistoryEntryDetailsStyle.Draw(timestampRect, entry.PrettyTimeString + "     " + entry.AuthorName, false, false, selected, keyboardFocus);

                if (!string.IsNullOrEmpty(entry.MergeA))
                {
                    const float MergeIndicatorWidth  = 10.28f;
                    const float MergeIndicatorHeight = 12f;
                    var         mergeIndicatorRect   = new Rect(entryRect.x + 7, summaryRect.y, MergeIndicatorWidth, MergeIndicatorHeight);

                    GUI.DrawTexture(mergeIndicatorRect, Styles.MergeIcon);

                    drawTimelineRectAroundIconRect(entryRect, mergeIndicatorRect);

                    summaryRect.Set(mergeIndicatorRect.xMax, summaryRect.y, summaryRect.width - MergeIndicatorWidth, summaryRect.height);
                }

                if (state == LogEntryState.Local && string.IsNullOrEmpty(entry.MergeA))
                {
                    const float LocalIndicatorSize = 6f;
                    var         localIndicatorRect = new Rect(entryRect.x + (Styles.BaseSpacing - 2), summaryRect.y + 5, LocalIndicatorSize, LocalIndicatorSize);

                    drawTimelineRectAroundIconRect(entryRect, localIndicatorRect);

                    GUI.DrawTexture(localIndicatorRect, Styles.LocalCommitIcon);

                    summaryRect.Set(localIndicatorRect.xMax, summaryRect.y, summaryRect.width - LocalIndicatorSize, summaryRect.height);
                }

                if (state == LogEntryState.Normal && string.IsNullOrEmpty(entry.MergeA))
                {
                    const float NormalIndicatorWidth  = 6f;
                    const float NormalIndicatorHeight = 6f;

                    Rect normalIndicatorRect = new Rect(entryRect.x + (Styles.BaseSpacing - 2),
                                                        summaryRect.y + 5,
                                                        NormalIndicatorWidth,
                                                        NormalIndicatorHeight);

                    drawTimelineRectAroundIconRect(entryRect, normalIndicatorRect);

                    GUI.DrawTexture(normalIndicatorRect, Styles.DotIcon);
                }
            }
            else if (Event.current.type == EventType.ContextClick && entryRect.Contains(Event.current.mousePosition))
            {
                GenericMenu menu = new GenericMenu();
                menu.AddItem(new GUIContent("Revert"), false, RevertCommit);
                menu.ShowAsContext();

                Event.current.Use();
            }
            else if (Event.current.type == EventType.MouseDown && entryRect.Contains(Event.current.mousePosition))
            {
                Event.current.Use();
                return(true);
            }

            return(false);
        }
Example #9
0
        public override void OnGUI()
        {
            var rect = GUILayoutUtility.GetLastRect();

            if (historyControl != null)
            {
                var historyControlRect = new Rect(0f, 0f, Position.width, Position.height - rect.height);

                var requiresRepaint = historyControl.Render(historyControlRect,
                                                            entry => {
                    selectedEntry = entry;
                    BuildTree();
                },
                                                            entry => { }, entry => {
                    GenericMenu menu = new GenericMenu();
                    menu.AddItem(new GUIContent("Revert"), false, RevertCommit);
                    menu.ShowAsContext();
                });

                if (requiresRepaint)
                {
                    Redraw();
                }
            }

            DoProgressGUI();

            if (!selectedEntry.Equals(GitLogEntry.Default))
            {
                // Top bar for scrolling to selection or clearing it
                GUILayout.BeginHorizontal(EditorStyles.toolbar);
                {
                    if (GUILayout.Button(CommitDetailsTitle, Styles.ToolbarButtonStyle))
                    {
                        historyControl.ScrollTo(historyControl.SelectedIndex);
                    }
                    if (GUILayout.Button(ClearSelectionButton, Styles.ToolbarButtonStyle, GUILayout.ExpandWidth(false)))
                    {
                        selectedEntry = GitLogEntry.Default;
                        historyControl.SelectedIndex = -1;
                    }
                }
                GUILayout.EndHorizontal();

                // Log entry details - including changeset tree (if any changes are found)
                detailsScroll = GUILayout.BeginScrollView(detailsScroll, GUILayout.Height(250));
                {
                    HistoryDetailsEntry(selectedEntry);

                    GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
                    GUILayout.Label("Files changed", EditorStyles.boldLabel);
                    GUILayout.Space(-5);

                    rect = GUILayoutUtility.GetLastRect();
                    GUILayout.BeginHorizontal(Styles.HistoryFileTreeBoxStyle);
                    GUILayout.BeginVertical();
                    {
                        var borderLeft      = Styles.Label.margin.left;
                        var treeControlRect = new Rect(rect.x + borderLeft, rect.y, Position.width - borderLeft * 2, Position.height - rect.height + Styles.CommitAreaPadding);
                        var treeRect        = new Rect(0f, 0f, 0f, 0f);
                        if (treeChanges != null)
                        {
                            treeChanges.FolderStyle                = Styles.Foldout;
                            treeChanges.TreeNodeStyle              = Styles.TreeNode;
                            treeChanges.ActiveTreeNodeStyle        = Styles.ActiveTreeNode;
                            treeChanges.FocusedTreeNodeStyle       = Styles.FocusedTreeNode;
                            treeChanges.FocusedActiveTreeNodeStyle = Styles.FocusedActiveTreeNode;

                            treeRect = treeChanges.Render(treeControlRect, detailsScroll,
                                                          node => { },
                                                          node => {
                            },
                                                          node => {
                            });

                            if (treeChanges.RequiresRepaint)
                            {
                                Redraw();
                            }
                        }

                        GUILayout.Space(treeRect.y - treeControlRect.y);
                    }
                    GUILayout.EndVertical();
                    GUILayout.EndHorizontal();

                    GUILayout.Space(EditorGUIUtility.standardVerticalSpacing);
                }
                GUILayout.EndScrollView();
            }
        }