Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions Assets/Editor/E07_Data.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Experimental.UIElements;
using UnityEditor.SceneManagement;
using UnityEditor.Experimental.UIElements;
using System.Collections.Generic;
using System.Linq;

namespace UIElementsExamples
{
public class E07_Data : EditorWindow
{
[MenuItem("UIElementsExamples/07_Data")]
public static void ShowExample()
{
E07_Data window = GetWindow<E07_Data>();
window.minSize = new Vector2(450, 200);
window.titleContent = new GUIContent("Example 7");
}

static VisualTreeAsset s_Asset;
static VisualTreeAsset asset
{
get
{
if (s_Asset == null)
{
s_Asset = Resources.Load<VisualTreeAsset>("TreeView");
Debug.Assert(s_Asset != null);
}
return s_Asset;
}
}

List<int> m_ExpandedGOs;

public void OnEnable()
{
if (m_ExpandedGOs == null)
m_ExpandedGOs = new List<int>();

Scene scene = SceneManager.GetSceneAt(0);

var scrollView = new ScrollView();
scrollView.StretchToParentSize();

if (scene.IsValid())
{
GameObject[] gameObjects = scene.GetRootGameObjects();
RecursiveSetUp(gameObjects, scrollView.contentView);
}

this.GetRootVisualContainer().AddChild(scrollView);
this.GetRootVisualContainer().AddStyleSheetPath("TreeView");
}

static void UpdateName(VisualElement treeViewItem, Object data)
{
if (data == null)
return;

Copy link

Choose a reason for hiding this comment

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

could be multiple labels if we change the template.

treeViewItem.Q<Label>().text = data.name;
}

public void UpdateChildren(VisualElement treeViewItem, Object data)
{
Transform transform = data as Transform;

// Might be deleted
if (transform == null)
return;

List<GameObject> gos = new List<GameObject>();
for (int i = 0; i < transform.childCount; i++)
{
gos.Add(transform.GetChild(i).gameObject);
}
Toggle toggle = treeViewItem.Q<Toggle>();
toggle.enabled = gos.Count > 0;
toggle.on = toggle.enabled && m_ExpandedGOs.Contains(transform.gameObject.GetInstanceID());
Copy link

Choose a reason for hiding this comment

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

toggle state known duplicate code


if (m_ExpandedGOs.Contains(transform.gameObject.GetInstanceID()))
{
RecursiveSetUp(gos, treeViewItem.Q<VisualContainer>("ChildrenContainer"));
}
}

public void RecursiveSetUp(IEnumerable<GameObject> gameObjects, VisualContainer container)
{
var currentGOs = new List<GameObject>();
container.ToList().ForEach((e) => {
GameObject go = e.data as GameObject;

// remove gone objects
if (go == null || !gameObjects.Contains(go))
{
container.RemoveChild(e);
}
// or-remember those that already have an item
else
{
currentGOs.Add(go);
}
});


foreach(GameObject go in gameObjects.Except(currentGOs))
{
VisualContainer added = asset.CloneTree();
added.data = go;

UpdateName(added, go);
added.RegisterWatch(go, UpdateName);
UpdateChildren(added, go.transform);
added.RegisterWatch(go.transform, UpdateChildren);

Copy link

Choose a reason for hiding this comment

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

As discussed, we need a lambda here because the delegate does not send the VE with it.
We should change all VisualElement delegates to send the 'this' as context.

added.Q<Toggle>().OnToggle(() =>
{
OnToggle(added);
});

container.AddChild(added);
}

container.Sort((a, b) => {
Transform aTrans = (a.data as GameObject).transform;
Transform bTrans = (b.data as GameObject).transform;
Debug.Assert(aTrans.parent == bTrans.parent);
int order = aTrans.GetSiblingIndex() - bTrans.GetSiblingIndex();
return order;
});
}

void OnToggle(VisualContainer treeViewItem)
{
GameObject go = treeViewItem.data as GameObject;
Debug.Assert(go != null, "No GO attached to item!");
Copy link

Choose a reason for hiding this comment

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

Let's see how in the next PR we can have a ViewData service to store and retrieve that.

// Off the cuff?
var v = ViewDataStore.GetOrCreateDefault(key);
var v = ViewDataStore.Store(key, 5);

if (!m_ExpandedGOs.Contains(go.GetInstanceID()))
{
m_ExpandedGOs.Add(go.GetInstanceID());
UpdateChildren(treeViewItem, go.transform);
}
else
{
treeViewItem.Q<VisualContainer>("ChildrenContainer").ClearChildren();
m_ExpandedGOs.Remove(go.GetInstanceID());
}
}
}
}
12 changes: 12 additions & 0 deletions Assets/Editor/E07_Data.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions Assets/Editor/Resources/TreeView.uss
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#TitleContainer {
flex-direction: row;
}

#ChildrenContainer {
padding-left: 20px;
}

#TitleContainer > Toggle {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout.png");
}

#TitleContainer > Toggle:focus, #TitleContainer Toggle:focus:active {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout focus.png");
}

#TitleContainer > Toggle:active {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout act.png");
}

#TitleContainer > Toggle:checked {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout on.png");
}

#TitleContainer > Toggle:checked:focus {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout focus on.png");
}

#TitleContainer > Toggle:checked:active:focus, #TitleContainer > Toggle:checked:active {
background-image: resource("Builtin Skins/DarkSkin/Images/IN foldout act on.png");
}

9 changes: 9 additions & 0 deletions Assets/Editor/Resources/TreeView.uss.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions Assets/Editor/Resources/TreeView.uxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Template id="TreeView" xmlns="UnityEngine.Experimental.UIElements">
<VisualContainer class="TreeView">
<VisualContainer name="TitleContainer">
<Toggle />
<Label text="Hello" />
</VisualContainer>
<VisualContainer name="ChildrenContainer" />
</VisualContainer>
</Template>
9 changes: 9 additions & 0 deletions Assets/Editor/Resources/TreeView.uxml.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions Assets/Editor/Resources/uielementssettings.asset
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 1
m_Script: {fileID: 11995, guid: 0000000000000000e000000000000000, type: 0}
m_Name: uielementssettings
m_EditorClassIdentifier:
viewTable:
- id: TreeView
viewNamespace:
template: {fileID: 11400000, guid: f05a1e0d273c94b1db91b227901e714f, type: 3}
9 changes: 9 additions & 0 deletions Assets/Editor/Resources/uielementssettings.asset.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Assets/test.unity.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ProjectSettings/ProjectVersion.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
m_EditorVersion: 2017.2.0a1
m_EditorVersion: 2017.2.0a4