Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Some extensions to Unity's VisualElement class.
/* Original code[1] Copyright (c) 2021 Shane Celis[2]
Licensed under the MIT License[3]
This comment generated by code-cite[4].
[1]: https://gist.github.com/shanecelis/343e3159b6dab44b18b53f47a05fd7c7/edit
[2]: https://twitter.com/shanecelis
[3]: https://opensource.org/licenses/MIT
[4]: https://github.com/shanecelis/code-cite
*/
using UnityEngine;
using UnityEngine.UIElements;
/** Some extensions to Unity's VisualElement class. */
public static class VisualElementExtensions {
/** Add a ChangeEvent<Visibility> that sends an event when visibility changes.
This is based off whether the rect of the element becomes zero.
```
element.AddChangeEventVisibility();
element.RegisterCallback<ChangeEvent<Visibility>>(evt => {
if (evt.newValue)
Debug.Log($"{evt.target} is visible");
else
Debug.Log($"{evt.target} is not visible");
});
```
*/
public static void AddChangeEventVisibility(this VisualElement element) {
element.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged);
}
private static void OnGeometryChanged(GeometryChangedEvent evt) {
// Thanks to Midiphony-panda for his comments.
// https://forum.unity.com/threads/visualelement-lacking-equivalent-to-monobehaviour-messages.1082570/
if (evt.newRect == Rect.zero) {
// "Likely", DisplayStyle was set to None
using var rectZero = ChangeEvent<Visibility>.GetPooled(evt.oldRect != Rect.zero, false);
rectZero.target = evt.target;
evt.target.SendEvent(rectZero);
} else if(evt.oldRect == Rect.zero) {
// "Likely", DisplayStyle was set to None and is back to Flex
using var rectZero = ChangeEvent<Visibility>.GetPooled(false, true);
rectZero.target = evt.target;
evt.target.SendEvent(rectZero);
}
}
/** Query up the list of parents. */
public static VisualElement QUp(this VisualElement element,
string name = null,
string className = null) {
while (element != null
&& (name == null || (name != null && element.name != name))
&& (className == null || (className != null && ! element.ClassListContains(className))))
element = element.parent;
return element;
}
}
public class Visibility : IChangeEvent {
public bool isVisible;
// XXX: I don't normally care for implicits but this class is just a 1bit wrapper.
public static implicit operator Visibility(bool b) => new Visibility { isVisible = b };
public static implicit operator bool(Visibility rz) => rz.isVisible;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment