public static VisualElement CreateVisualElement(XmlNode node) { if (node == null) { throw new Exception("Node is null"); } // Debug.Log($"Looking for type: {node.Name.Replace("ui:", "")}"); Type elementType = Array.Find(typeof(VisualElement).Assembly.GetTypes(), x => x.Name.Equals(node.Name.Replace("ui:", ""))); if (elementType == null) { if (!node.Name.Replace("ui:", "").Equals("Style")) { Debug.Log($"Couldn't find type \"{node.Name.Replace("ui:", "")}\"\nSkipping..."); } return(null); } VisualElement element = (VisualElement)typeof(VisualElement).GetMethod("CreateUnityType") ?.MakeGenericMethod(elementType) .Invoke(null, new object[] { new object[] { } }); // Debug.Log("Creating element.."); if (node.Attributes != null) { foreach (XmlAttribute attr in node.Attributes) { // Debug.Log("Parsing Attribute"); var property = elementType.GetProperty(MapCssName(attr.Name)); if (attr.Name.Equals("class")) { //Debug.Log("Class found with value: " + attr.Value); element?.AddToClassList(attr.Value); } if (property == null) { if (!attr.Name.Equals("class")) { Debug.Log($"Skipping attribute \"{attr.Name}\""); } // throw new Exception($"No property found with name \"{attr.Name}\""); continue; } if (property.PropertyType.IsEnum) { property.SetValue(element, Enum.Parse(property.PropertyType, attr.Value)); continue; } switch (property.PropertyType.Name) { case "Boolean": // Debug.Log($"Parsing Boolean: {attr.Value}"); property.SetValue(element, bool.Parse(attr.Value)); break; case "String": // Debug.Log($"Parsing String: {attr.Value}"); property.SetValue(element, attr.Value); break; case "IStyle": // Debug.Log("Parsing IStyle"); element = ParseStyle(attr.Value, element); break; default: throw new Exception($"Found no matching type to {property.PropertyType.FullName}"); } } } VisualElement resultElement = element; foreach (XmlNode child in node.ChildNodes) { var parsedChild = CreateVisualElement(child); } return(resultElement); }
public RecycledItem(VisualElement element) { this.element = element; index = id = -1; element.AddToClassList(itemUssClassName); }
public static void BuildInspectorPropertiesElement(string elementPath, IEditorContainer editor, System.Collections.Generic.HashSet <System.Type> usedComponents, SerializedProperty obj, UnityEngine.UIElements.VisualElement container, bool noFields, System.Action <int, PropertyField> onBuild = null) { obj = obj.Copy(); container.Clear(); var source = obj.Copy(); SerializedProperty iterator = obj; if (iterator.NextVisible(true) == false) { return; } if (iterator.NextVisible(true) == false) { return; } var depth = iterator.depth; var i = 0; var iteratorNext = iterator.Copy(); do { if (string.IsNullOrEmpty(elementPath) == false) { iterator = iteratorNext.FindPropertyRelative(elementPath); } else { iterator = iteratorNext; } if (iterator.propertyType != SerializedPropertyType.ManagedReference) { continue; } var element = new VisualElement(); element.AddToClassList("element"); var itCopy = iterator.Copy(); GetTypeFromManagedReferenceFullTypeName(iterator.managedReferenceFullTypename, out var type); element.AddToClassList(i % 2 == 0 ? "even" : "odd"); element.RegisterCallback <UnityEngine.UIElements.ContextClickEvent, int>((evt, idx) => { var menu = new GenericMenu(); if (usedComponents != null) { menu.AddItem(new GUIContent("Delete"), false, () => { RemoveComponent((DataConfigEditor)editor, usedComponents, source, type, noFields); editor.Save(); BuildInspectorProperties(editor, usedComponents, source, container, noFields); }); menu.AddItem(new GUIContent("Copy JSON"), false, () => { var instance = itCopy.GetValue(); var json = JsonUtility.ToJson(instance, true); EditorGUIUtility.systemCopyBuffer = json; }); } editor.OnComponentMenu(menu, idx); menu.ShowAsContext(); }, i); if (type != null && usedComponents?.Contains(type) == false) { usedComponents?.Add(type); } if (type == null) { var label = new UnityEngine.UIElements.Label("MISSING: " + iterator.managedReferenceFullTypename); element.name = "missing"; label.AddToClassList("inner-element"); label.AddToClassList("missing-label"); element.Add(label); } else if (iterator.hasVisibleChildren == false || noFields == true) { var horizontal = new UnityEngine.UIElements.VisualElement(); horizontal.AddToClassList("inner-element"); horizontal.AddToClassList("no-fields-container"); element.name = type.Name; var toggle = new UnityEngine.UIElements.Toggle(); toggle.AddToClassList("no-fields-toggle"); toggle.SetEnabled(false); toggle.SetValueWithoutNotify(true); horizontal.Add(toggle); var label = new UnityEngine.UIElements.Label(GUILayoutExt.GetStringCamelCaseSpace(type.Name)); label.AddToClassList("no-fields-label"); horizontal.Add(label); element.Add(horizontal); } else { var label = GUILayoutExt.GetStringCamelCaseSpace(type.Name); if (iterator.hasVisibleChildren == true) { var childs = iterator.Copy(); //var height = EditorUtilities.GetPropertyHeight(childs, true, new GUIContent(label)); var cnt = EditorUtilities.GetPropertyChildCount(childs); if (cnt == 1 /*&& height <= 22f*/) { iterator.NextVisible(true); } } var propertyField = new PropertyField(iterator.Copy(), label); propertyField.BindProperty(iterator); onBuild?.Invoke(i, propertyField); propertyField.AddToClassList("property-field"); propertyField.AddToClassList("inner-element"); element.name = type.Name; element.Add(propertyField); } if (type != null) { var helps = type.GetCustomAttributes(typeof(ComponentHelpAttribute), false); if (helps.Length > 0) { var label = new UnityEngine.UIElements.Label(((ComponentHelpAttribute)helps[0]).comment); label.AddToClassList("comment"); element.Add(label); } if (typeof(IComponentStatic).IsAssignableFrom(type) == true) { var label = new UnityEngine.UIElements.Label("Static"); label.AddToClassList("static-component"); element.AddToClassList("has-static-component"); element.Add(label); } if (typeof(IComponentShared).IsAssignableFrom(type) == true) { var label = new UnityEngine.UIElements.Label("Shared"); label.AddToClassList("shared-component"); element.AddToClassList("has-shared-component"); element.Add(label); } } container.Add(element); ++i; } while (iteratorNext.NextVisible(false) == true && depth <= iteratorNext.depth); }
/// <summary> /// Constructor. /// </summary> /// <param name="minValue">The minimum value in the range to be represented.</param> /// <param name="maxValue">The maximum value in the range to be represented.</param> /// <param name="minLimit">The minimum value of the slider limit.</param> /// <param name="maxLimit">The maximum value of the slider limit.</param> public MinMaxSlider(string label, float minValue = 0, float maxValue = kDefaultHighValue, float minLimit = float.MinValue, float maxLimit = float.MaxValue) : base(label, null) { m_MinLimit = float.MinValue; m_MaxLimit = float.MaxValue; lowLimit = minLimit; highLimit = maxLimit; // Can't set to value here, because it could be overriden in a derived type. var clampedValue = ClampValues(new Vector2(minValue, maxValue)); this.minValue = clampedValue.x; this.maxValue = clampedValue.y; AddToClassList(ussClassName); labelElement.AddToClassList(labelUssClassName); visualInput.AddToClassList(inputUssClassName); pickingMode = PickingMode.Ignore; m_DragState = DragState.NoThumb; visualInput.pickingMode = PickingMode.Position; var trackElement = new VisualElement() { name = "unity-tracker" }; trackElement.AddToClassList(trackerUssClassName); visualInput.Add(trackElement); dragElement = new VisualElement() { name = "unity-dragger" }; dragElement.AddToClassList(draggerUssClassName); dragElement.RegisterCallback <GeometryChangedEvent>(UpdateDragElementPosition); visualInput.Add(dragElement); // For a better handling of the cursor style, children elements are created so that the style is automatic with the uss. dragMinThumb = new VisualElement() { name = "unity-thumb-min" }; dragMaxThumb = new VisualElement() { name = "unity-thumb-max" }; dragMinThumb.AddToClassList(minThumbUssClassName); dragMaxThumb.AddToClassList(maxThumbUssClassName); dragElement.Add(dragMinThumb); dragElement.Add(dragMaxThumb); clampedDragger = new ClampedDragger <float>(null, SetSliderValueFromClick, SetSliderValueFromDrag); visualInput.AddManipulator(clampedDragger); m_MinLimit = minLimit; m_MaxLimit = maxLimit; rawValue = ClampValues(new Vector2(minValue, maxValue)); UpdateDragElementPosition(); }
internal static VisualElement Create(VisualElementAsset asset, CreationContext ctx) { List <IUxmlFactory> factoryList; if (!VisualElementFactoryRegistry.TryGetValue(asset.fullTypeName, out factoryList)) { if (asset.fullTypeName.StartsWith("UnityEngine.Experimental.UIElements.") || asset.fullTypeName.StartsWith("UnityEditor.Experimental.UIElements.")) { string experimentalTypeName = asset.fullTypeName.Replace(".Experimental.UIElements", ".UIElements"); if (!VisualElementFactoryRegistry.TryGetValue(experimentalTypeName, out factoryList)) { Debug.LogErrorFormat("Element '{0}' has no registered factory method.", asset.fullTypeName); return(new Label(string.Format("Unknown type: '{0}'", asset.fullTypeName))); } } else { Debug.LogErrorFormat("Element '{0}' has no registered factory method.", asset.fullTypeName); return(new Label(string.Format("Unknown type: '{0}'", asset.fullTypeName))); } } IUxmlFactory factory = null; foreach (IUxmlFactory f in factoryList) { if (f.AcceptsAttributeBag(asset, ctx)) { factory = f; break; } } if (factory == null) { Debug.LogErrorFormat("Element '{0}' has a no factory that accept the set of XML attributes specified.", asset.fullTypeName); return(new Label(string.Format("Type with no factory: '{0}'", asset.fullTypeName))); } if (factory is UxmlRootElementFactory) { return(null); } VisualElement res = factory.Create(asset, ctx); if (res == null) { Debug.LogErrorFormat("The factory of Visual Element Type '{0}' has returned a null object", asset.fullTypeName); return(new Label(string.Format("The factory of Visual Element Type '{0}' has returned a null object", asset.fullTypeName))); } if (asset.classes != null) { for (int i = 0; i < asset.classes.Length; i++) { res.AddToClassList(asset.classes[i]); } } if (asset.stylesheetPaths != null) { for (int i = 0; i < asset.stylesheetPaths.Count; i++) { res.AddStyleSheetPath(asset.stylesheetPaths[i]); } } if (asset.stylesheets != null) { for (int i = 0; i < asset.stylesheets.Count; ++i) { res.styleSheets.Add(asset.stylesheets[i]); } } return(res); }
private VisualElement CloneSetupRecursively(VisualElementAsset root, Dictionary <int, List <VisualElementAsset> > idToChildren, CreationContext context) { VisualElement ve = Create(root, context); // context.target is the created templateContainer if (root.id == context.visualTreeAsset.contentContainerId) { if (context.target is TemplateContainer) { ((TemplateContainer)context.target).SetContentContainer(ve); } else { Debug.LogError( "Trying to clone a VisualTreeAsset with a custom content container into a element which is not a template container"); } } // if the current element had a slot-name attribute, put it in the resulting slot mapping string slotName; if (context.slotInsertionPoints != null && TryGetSlotInsertionPoint(root.id, out slotName)) { context.slotInsertionPoints.Add(slotName, ve); } if (root.classes != null) { for (int i = 0; i < root.classes.Length; i++) { ve.AddToClassList(root.classes[i]); } } if (root.ruleIndex != -1) { if (inlineSheet == null) { Debug.LogWarning("VisualElementAsset has a RuleIndex but no inlineStyleSheet"); } else { StyleRule r = inlineSheet.rules[root.ruleIndex]; var stylesData = new VisualElementStylesData(false); ve.SetInlineStyles(stylesData); s_StylePropertyReader.SetInlineContext(inlineSheet, r, root.ruleIndex); stylesData.ApplyProperties(s_StylePropertyReader, null); } } var templateAsset = root as TemplateAsset; List <VisualElementAsset> children; if (idToChildren.TryGetValue(root.id, out children)) { children.Sort(CompareForOrder); foreach (VisualElementAsset childVea in children) { // this will fill the slotInsertionPoints mapping VisualElement childVe = CloneSetupRecursively(childVea, idToChildren, context); if (childVe == null) { continue; } // if the parent is not a template asset, just add the child to whatever hierarchy we currently have // if ve is a scrollView (with contentViewport as contentContainer), this will go to the right place if (templateAsset == null) { ve.Add(childVe); continue; } int index = templateAsset.slotUsages == null ? -1 : templateAsset.slotUsages.FindIndex(u => u.assetId == childVea.id); if (index != -1) { VisualElement parentSlot; string key = templateAsset.slotUsages[index].slotName; Assert.IsFalse(String.IsNullOrEmpty(key), "a lost name should not be null or empty, this probably points to an importer or serialization bug"); if (context.slotInsertionPoints == null || !context.slotInsertionPoints.TryGetValue(key, out parentSlot)) { Debug.LogErrorFormat("Slot '{0}' was not found. Existing slots: {1}", key, context.slotInsertionPoints == null ? String.Empty : String.Join(", ", System.Linq.Enumerable.ToArray(context.slotInsertionPoints.Keys))); ve.Add(childVe); } else { parentSlot.Add(childVe); } } else { ve.Add(childVe); } } } if (templateAsset != null && context.slotInsertionPoints != null) { context.slotInsertionPoints.Clear(); } return(ve); }