Skip to content

Commit 60fc584

Browse files
Merge pull request 54248 from feature/149609-figmaRefactoring into master
1 parent 394aaca commit 60fc584

File tree

11 files changed

+331
-1
lines changed

11 files changed

+331
-1
lines changed

Runtime/Extensions/NodeExtensions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ record Metadata(UIDocument document, UxmlAttribute uxml, string path);
2626
static Dictionary<VisualElement, Metadata> rootMetadata = new();
2727
static List<VisualElement> search = new(256);
2828
static Dictionary<VisualElement, string> cloneMap = new(256);
29+
static List<VisualElement> hide = new();
2930
#endregion
3031

3132
#region Properties
@@ -84,7 +85,9 @@ public static void Rebuild(VisualElement target)
8485
if (target is ISubElement targetSubElement) targetSubElement.OnRebuild();
8586
foreach (VisualElement child in target.Children()) Rebuild(child);
8687

87-
OnRebuildElement(target);
88+
OnRebuildElement?.Invoke(target);
89+
90+
if (hide.Contains(target)) target.Hide();
8891
}
8992

9093
public static IEnumerable<T> Search<T>(this VisualElement value, string path, string className = default) where T : VisualElement
@@ -763,6 +766,8 @@ VisualElement FindIn(VisualElement root)
763766
Initialize(subElement, field.FieldType, element, throwException, silent);
764767
subElement.OnInitialize();
765768
}
769+
770+
if (query.Hide) hide.Add(element);
766771
}
767772
}
768773
#endregion
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using Trackman;
5+
using UnityEngine.UIElements;
6+
7+
namespace Figma
8+
{
9+
public static class VisualElementExtensions
10+
{
11+
#region Fields
12+
static Dictionary<(VisualElement prefab, VisualElement parent), IList> cloneDictionary = new();
13+
#endregion
14+
15+
#region Methods
16+
public static bool HasVisibility(this VisualElement element) => element.style.visibility == Visibility.Visible;
17+
public static void MakeVisible(this VisualElement element) => element.style.visibility = Visibility.Visible;
18+
public static void MakeInvisible(this VisualElement element) => element.style.visibility = Visibility.Hidden;
19+
public static void SetVisibility(this VisualElement element, bool visible)
20+
{
21+
if (visible) element.MakeVisible();
22+
else element.MakeInvisible();
23+
}
24+
public static bool IsShowing(this VisualElement element) => element.resolvedStyle.display == DisplayStyle.Flex;
25+
public static void Show(this VisualElement element)
26+
{
27+
element.style.display = DisplayStyle.Flex;
28+
element.MarginMe();
29+
}
30+
public static void Hide(this VisualElement element) => element.style.display = DisplayStyle.None;
31+
public static void SetDisplay(this VisualElement element, bool visible)
32+
{
33+
if (visible) Show(element);
34+
else Hide(element);
35+
}
36+
public static void Disable(this VisualElement element) => element.pickingMode = PickingMode.Ignore;
37+
public static void Enable(this VisualElement element) => element.pickingMode = PickingMode.Position;
38+
39+
public static IList EnsureList<TVisualElement>(TVisualElement prefab, VisualElement parent) where TVisualElement : VisualElement
40+
{
41+
(TVisualElement prefab, VisualElement parent) identifier = (prefab, parent);
42+
43+
if (!cloneDictionary.TryGetValue(identifier, out IList elements))
44+
cloneDictionary.Add(identifier, elements = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(prefab.GetType())));
45+
46+
return elements;
47+
}
48+
public static TVisualElement GetElement<TVisualElement>(this TVisualElement prefab, int index) where TVisualElement : VisualElement => GetElements(prefab, prefab.parent)[index];
49+
public static List<TVisualElement> GetElements<TVisualElement>(this TVisualElement prefab) where TVisualElement : VisualElement => GetElements(prefab, prefab.parent);
50+
public static List<TVisualElement> GetElements<TVisualElement>(this TVisualElement prefab, VisualElement parent) where TVisualElement : VisualElement
51+
{
52+
if (EnsureList(prefab, parent) is List<TVisualElement> list) return list;
53+
throw new ArgumentException($"Casting from {typeof(List<TVisualElement>)} to {cloneDictionary[(prefab, parent)]}");
54+
}
55+
public static List<VisualElement> GetElements(this VisualElement prefab) => GetElements<VisualElement>(prefab);
56+
public static List<VisualElement> GetElements(this VisualElement prefab, VisualElement parent) => GetElements<VisualElement>(prefab, parent);
57+
public static void Sync<TVisualElement, TData>(this TVisualElement prefab, VisualElement parent, IEnumerable<TData> data, Action<TVisualElement> onCreateElement = default) where TVisualElement : VisualElement, ISyncElement<TData>
58+
{
59+
IList elements = EnsureList(prefab, parent);
60+
61+
int i = 0;
62+
foreach (TData value in data)
63+
{
64+
TVisualElement element;
65+
if (i >= elements.Count)
66+
{
67+
element = prefab.Clone(parent, i);
68+
element.Initialize(i);
69+
onCreateElement?.Invoke(element);
70+
elements.Add(element);
71+
}
72+
else
73+
{
74+
element = (TVisualElement)elements[i];
75+
}
76+
77+
if (element.IsVisible(i, value)) element.Show();
78+
else element.Hide();
79+
80+
++i;
81+
}
82+
83+
for (int j = i; j < elements.Count; ++j) elements[j].As<TVisualElement>().Hide();
84+
}
85+
public static void Sync<TVisualElement, TCreationData, TData>(this TVisualElement prefab, VisualElement parent, TCreationData creationData, IEnumerable<TData> data, Action<TVisualElement> onCreateElement = default) where TVisualElement : VisualElement, ISyncElement<TCreationData, TData>
86+
{
87+
IList elements = EnsureList(prefab, parent);
88+
89+
int i = 0;
90+
foreach (TData value in data)
91+
{
92+
TVisualElement element;
93+
if (i >= elements.Count)
94+
{
95+
element = prefab.Clone(parent, i);
96+
element.Initialize(i, creationData);
97+
onCreateElement?.Invoke(element);
98+
elements.Add(element);
99+
}
100+
else
101+
{
102+
element = (TVisualElement)elements[i];
103+
}
104+
105+
if (element.IsVisible(i, value)) element.Show();
106+
else element.Hide();
107+
108+
++i;
109+
}
110+
111+
for (int j = i; j < elements.Count; ++j) elements[j].As<TVisualElement>().Hide();
112+
}
113+
#endregion
114+
}
115+
}

Runtime/Extensions/VisualElementExtensions.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Interface/Attributes.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public class QueryAttribute : Attribute
5151
public bool StartRoot { get; set; }
5252
public bool EndRoot { get; set; }
5353
public bool Nullable { get; set; }
54+
public bool Hide { get; set; }
55+
public bool Localize { get; set; } = true;
5456
public string Clicked { get; set; }
5557
public string Template { get; set; }
5658
public TrickleDown UseTrickleDown { get; set; }

Runtime/Interface/Core.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using UnityEngine.UIElements;
2+
3+
namespace Figma
4+
{
5+
public abstract class SubVisualElement : VisualElement, ISubElement
6+
{
7+
#region Methods
8+
protected virtual void OnInitialize() { }
9+
protected virtual void OnRebuild() { }
10+
11+
void ISubElement.OnInitialize() => OnInitialize();
12+
void ISubElement.OnRebuild() => OnRebuild();
13+
#endregion
14+
}
15+
16+
public abstract class SubButton : Button, ISubElement
17+
{
18+
#region Methods
19+
protected virtual void OnInitialize() { }
20+
protected virtual void OnRebuild() { }
21+
22+
void ISubElement.OnInitialize() => OnInitialize();
23+
void ISubElement.OnRebuild() => OnRebuild();
24+
#endregion
25+
}
26+
27+
public abstract class SubLabel : Label, ISubElement
28+
{
29+
#region Methods
30+
protected virtual void OnInitialize() { }
31+
protected virtual void OnRebuild() { }
32+
33+
void ISubElement.OnInitialize() => OnInitialize();
34+
void ISubElement.OnRebuild() => OnRebuild();
35+
#endregion
36+
}
37+
38+
public abstract class SubScrollView : ScrollView, ISubElement
39+
{
40+
#region Methods
41+
protected virtual void OnInitialize() { }
42+
protected virtual void OnRebuild() { }
43+
44+
void ISubElement.OnInitialize() => OnInitialize();
45+
void ISubElement.OnRebuild() => OnRebuild();
46+
#endregion
47+
}
48+
}

Runtime/Interface/Core/SubElement.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using UnityEngine.UIElements;
4+
5+
namespace Figma
6+
{
7+
public abstract class SyncVisualElement<T> : SubVisualElement, ISyncElement<T>
8+
{
9+
#region Methods
10+
public void Sync(VisualElement parent, IEnumerable<T> data) => VisualElementExtensions.Sync(this, parent, data);
11+
public abstract bool IsVisible(int index, T data);
12+
#endregion
13+
}
14+
15+
public abstract class SyncVisualElement<TCreationData, TData> : SubVisualElement, ISyncElement<TCreationData, TData>
16+
{
17+
#region Methods
18+
public void Sync(VisualElement parent, TCreationData creationData, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, creationData, data);
19+
public abstract void Initialize(int index, TCreationData creationData);
20+
public abstract bool IsVisible(int index, TData data);
21+
#endregion
22+
}
23+
24+
public abstract class SyncButton<TData> : SubButton, ISyncElement<TData>
25+
{
26+
#region Methods
27+
public void Sync(VisualElement parent, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, data);
28+
public abstract bool IsVisible(int index, TData data);
29+
#endregion
30+
}
31+
32+
public abstract class SyncButton<TCreationData, TData> : SubButton, ISyncElement<TCreationData, TData>
33+
{
34+
#region Methods
35+
public void Sync(VisualElement parent, TCreationData creationData, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, creationData, data);
36+
public abstract void Initialize(int index, TCreationData creationData);
37+
public abstract bool IsVisible(int index, TData data);
38+
#endregion
39+
}
40+
41+
public abstract class SyncButtonSimple<TData> : SubButton, ISyncElement<Action<int>, TData>
42+
{
43+
#region Methods
44+
public void Sync(VisualElement parent, Action<int> creationData, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, creationData, data);
45+
public void Initialize(int index, Action<int> creationData) => clicked += () => creationData(index);
46+
public abstract bool IsVisible(int index, TData data);
47+
#endregion
48+
}
49+
50+
public abstract class SyncLabel<TData> : SubLabel, ISyncElement<TData>
51+
{
52+
#region Methods
53+
public void Sync(VisualElement parent, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, data);
54+
public abstract bool IsVisible(int index, TData data);
55+
#endregion
56+
}
57+
58+
public abstract class SyncLabel<TCreationData, TData> : SubLabel, ISyncElement<TCreationData, TData>
59+
{
60+
#region Methods
61+
public void Sync(VisualElement parent, TCreationData creationData, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, creationData, data);
62+
public abstract void Initialize(int index, TCreationData creationData);
63+
public abstract bool IsVisible(int index, TData data);
64+
#endregion
65+
}
66+
67+
public abstract class SyncScrollView<TData> : SubScrollView, ISyncElement<TData>
68+
{
69+
#region Methods
70+
public void Sync(VisualElement parent, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, data);
71+
public abstract bool IsVisible(int index, TData data);
72+
#endregion
73+
}
74+
75+
public abstract class SyncScrollView<TCreationData, TData> : SubScrollView, ISyncElement<TCreationData, TData>
76+
{
77+
#region Methods
78+
public void Sync(VisualElement parent, TCreationData creationData, IEnumerable<TData> data) => VisualElementExtensions.Sync(this, parent, creationData, data);
79+
public abstract void Initialize(int index, TCreationData creationData);
80+
public abstract bool IsVisible(int index, TData data);
81+
#endregion
82+
}
83+
}

Runtime/Interface/Core/SyncElement.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Collections.Generic;
2+
using UnityEngine.UIElements;
3+
4+
#pragma warning disable S1186 // Functions and closures should not be empty
5+
6+
namespace Figma
7+
{
8+
public interface ISyncElement<TData>
9+
{
10+
#region Methods
11+
void Sync(VisualElement parent, IEnumerable<TData> data);
12+
void Initialize(int index) { }
13+
bool IsVisible(int index, TData data);
14+
#endregion
15+
}
16+
17+
public interface ISyncElement<TCreationData, TData>
18+
{
19+
#region Methods
20+
void Sync(VisualElement parent, TCreationData creationData, IEnumerable<TData> data);
21+
void Initialize(int index, TCreationData creationData);
22+
bool IsVisible(int index, TData data);
23+
#endregion
24+
}
25+
}

0 commit comments

Comments
 (0)