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

Conversation

shana
Copy link
Member

@shana shana commented Jul 31, 2017

Note: This branch targets enhancements/branches-view-rollup #464

This PR introduces a tree view control to display data in a tree view in a performant way, since the layouting system can't really handle a lot of the data we throw into it.

The approach here is to separate the data from the UI - the data gets put into a data structure (with whatever necessary processing), and then passed into the UI structure that will render it. Both can be cached separately and independently.

This tries to solve a number of problems:

  • Unity can't serialize data recursively (like a tree of nodes that have child nodes), so the data that is fed to the UI must be serialized in a flat structure
  • The layout system has problems when nodes are collapsed, changing the padding and spacing of items
  • We need to cache the UI so that it doesn't disappear when Unity reloads the domain. We also need to cache the data that feeds the UI so we can show existing data while we're refreshing it.

Missing in this PR

  • Scrolling support, rendering only the area that needs to be displayed, so that we don't try to render a 1000 objects

This is currently applied to the branches view but the Treeview control should be generic enough to be applied to the changes view as well, hopefully fixing the performance problems there.

@StanleyGoldman
Copy link
Contributor

Testing the latest, it is looking good. Noticed this display issue with remotes and multiple remotes at that.

img

@StanleyGoldman
Copy link
Contributor

I sent this PR a PR.. #372

@StanleyGoldman
Copy link
Contributor

Sending you a pull request in #378

@StanleyGoldman
Copy link
Contributor

Making an edit to say this depends on #384

@StanleyGoldman StanleyGoldman changed the base branch from master to features/cache-manager October 20, 2017 19:33
@StanleyGoldman StanleyGoldman changed the base branch from features/cache-manager to master October 20, 2017 19:34
@StanleyGoldman StanleyGoldman self-requested a review November 27, 2017 13:20
@StanleyGoldman StanleyGoldman changed the base branch from master to enhancements/branches-view-rollup November 27, 2017 13:20
# Conflicts:
#	src/UnityExtension/Assets/Editor/GitHub.Unity/UI/BranchesView.cs

[SerializeField] public GUIStyle FolderStyle;
[SerializeField] public GUIStyle TreeNodeStyle;
[SerializeField] public GUIStyle ActiveTreeNodeStyle;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally I wouldn't serialize GUIStyles/Textures, instead I load them on demand (typically in OnEnable). This makes it more difficult to iterate on the source styles/textures without recreating the serialized object completely. Nothing particularly wrong with this approach though.

Copy link
Collaborator

@CapnRat CapnRat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things to clean up, but overall looks good.

{
[SerializeField] public float ItemHeight = EditorGUIUtility.singleLineHeight;
[SerializeField] public float ItemSpacing = EditorGUIUtility.standardVerticalSpacing;
[SerializeField] public float Indentation = 12f;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't look like these three fields ever change? Why serialize them, rather than just making them const values?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

for (int i = 0; i < parts.Length; i++)
{
var label = parts[i];
var name = String.Join("/", parts, 0, i + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GC probably hates you for all of these joins/splits. You may want to take a look at how much garbage memory you're creating for this operation. And how much time is taking to clean it up.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm about to add functionality to the TreeControl to display a different type of tree. So these lines of codes are going to be a stomping ground for a little bit. I'm going to log an issue under tech-debt for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
bool selectionChanged = false;
var clickRect = new Rect(0f, rect.y, rect.width, rect.height);
if (Event.current.type == EventType.MouseDown && clickRect.Contains(Event.current.mousePosition))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this would also intercept right click or middle click. Is that desirable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct. The fix to this is coming in another pull request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


if (Event.current.type == EventType.repaint)
{
nodeStyle.Draw(fillRect, "", false, false, false, isSelected);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GUIContent.none rather than empty string.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Using the Styles.TreeIndentation constant
The value never changes so no need to make it serializable
Copy link
Collaborator

@CapnRat CapnRat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Copy link

@drguthals drguthals left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo on line 215 of TreeControl.cs

{
Repository.CheckLocalAndRemoteBranchListChangedEvent(lastLocalAndRemoteBranchListChangedEvent);
}
Repository.CheckLocalAndRemoteBranchListChangedEvent(lastLocalAndRemoteBranchListChangedEvent);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repository is not longer possibly null then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the time the BranchesView is displayed we always have a Repository

{
if (node == null || node.Children == null)
//if (IsFavorite(a.Name))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

meant to be commented out? Should it just be removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is getting cleaned up in #468

}

//private bool IsFavorite(string branchName)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commented or deleted?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is getting cleaned up in #468

int directionX = Event.current.keyCode == KeyCode.LeftArrow ? -1 : Event.current.keyCode == KeyCode.RightArrow ? 1 : 0;
if (directionY != 0 || directionX != 0)
{
if (directionY < 0 || directionY < 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be directionX on the second condition

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

{
int directionY = Event.current.keyCode == KeyCode.UpArrow ? -1 : Event.current.keyCode == KeyCode.DownArrow ? 1 : 0;
int directionX = Event.current.keyCode == KeyCode.LeftArrow ? -1 : Event.current.keyCode == KeyCode.RightArrow ? 1 : 0;
if (directionY != 0 || directionX != 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by this set of if statements. I don't fully understand the functionality here, so that just might be my confusion, but it seems like a set of nested ifs with two different variables shouldn't just be an or?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, the wrapping if statement is redundant.

The local and remote trees are two separate tree controls.
This code lets you travel from one tree control to the other via keystroke if the scenario is correct.

return idx;
}

private bool HandleInput(Rect rect, TreeNode currentNode, int index, Action<TreeNode> singleClick = null, Action<TreeNode> doubleClick = null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So are singleClick and doubleClick what gets displayed if a node gets single or double clicked?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost... they are the function delegates that get called when a node gets single or double clicked

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks!

@StanleyGoldman StanleyGoldman merged commit 8198c74 into enhancements/branches-view-rollup Nov 29, 2017
@StanleyGoldman StanleyGoldman deleted the branches-view branch November 29, 2017 15:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants