void RefreshClassListContainer() { ClearAddStyleValidationWarning(); m_ClassListContainer.Clear(); if (BuilderSharedStyles.IsSelectorElement(currentVisualElement)) { return; } var builderWindow = m_PaneWindow as Builder; if (builderWindow == null) { return; } var documentRootElement = builderWindow.documentRootElement; foreach (var className in currentVisualElement.GetClasses()) { m_ClassPillTemplate.CloneTree(m_ClassListContainer.contentContainer); var pill = m_ClassListContainer.contentContainer.ElementAt(m_ClassListContainer.childCount - 1); var pillLabel = pill.Q <Label>("class-name-label"); var pillDeleteButton = pill.Q <Button>("delete-class-button"); // Add ellipsis if the class name is too long. var classNameShortened = BuilderNameUtilities.CapStringLengthAndAddEllipsis(className, BuilderConstants.ClassNameInPillMaxLength); pillLabel.text = "." + classNameShortened; pillDeleteButton.userData = className; pillDeleteButton.clickable.clickedWithEventInfo += OnStyleClassDelete; // See if the class is in document as its own selector. var selector = BuilderSharedStyles.FindSelectorElement(documentRootElement, "." + className); pill.SetProperty(BuilderConstants.InspectorClassPillLinkedSelectorElementVEPropertyName, selector); var clickable = CreateClassPillClickableManipulator(); pill.AddManipulator(clickable); if (selector == null) { pill.AddToClassList(BuilderConstants.InspectorClassPillNotInDocumentClassName); pill.tooltip = BuilderConstants.InspectorClassPillDoubleClickToCreate; } else { pill.tooltip = BuilderConstants.InspectorClassPillDoubleClickToSelect; } } }
string GetRemapAttributeNameToCSProperty(string attributeName) { if (currentVisualElement is ObjectField && attributeName == "type") { return("objectType"); } else if (attributeName == "readonly") { return("isReadOnly"); } var camel = BuilderNameUtilities.ConvertDashToCamel(attributeName); return(camel); }
void OnBackgroundImageScaleModeChange(ChangeEvent <string> evt) { var newValue = BuilderNameUtilities.ConvertDashToHungarian(evt.newValue); var enumValue = (ScaleMode)Enum.Parse(typeof(ScaleMode), newValue); settings.CanvasBackgroundImageScaleMode = enumValue; PostSettingsChange(); if (settings.CanvasBackgroundMode != BuilderCanvasBackgroundMode.Image) { return; } customBackgroundElement.style.unityBackgroundScaleMode = enumValue; }
public static Dictionary <string, string> GetOverriddenAttributes(this VisualElement ve) { var attributeList = ve.GetAttributeDescriptions(); var overriddenAttributes = new Dictionary <string, string>(); foreach (var attribute in attributeList) { if (attribute == null || attribute.name == null) { continue; } var veType = ve.GetType(); var camel = BuilderNameUtilities.ConvertDashToCamel(attribute.name); var fieldInfo = veType.GetProperty(camel); if (fieldInfo != null) { var veValueAbstract = fieldInfo.GetValue(ve, null); if (veValueAbstract == null) { continue; } var veValueStr = veValueAbstract.ToString(); if (veValueStr == "False") { veValueStr = "false"; } else if (veValueStr == "True") { veValueStr = "true"; } var attributeValueStr = attribute.defaultValueAsString; if (veValueStr == attributeValueStr) { continue; } overriddenAttributes.Add(attribute.name, veValueStr); } } return(overriddenAttributes); }
BuilderStyleRow CreateAttributeRow(UxmlAttributeDescription attribute) { var attributeType = attribute.GetType(); // Generate field label. var fieldLabel = BuilderNameUtilities.ConvertDashToHuman(attribute.name); BindableElement fieldElement; if (attribute is UxmlStringAttributeDescription) { // Hard-coded if (attribute.name.Equals("value") && currentVisualElement is EnumField enumField) { var uiField = new EnumField("Value"); if (null != enumField.value) { uiField.Init(enumField.value, enumField.includeObsoleteValues); } else { uiField.SetValueWithoutNotify(null); } uiField.RegisterValueChangedCallback(evt => PostAttributeValueChange(uiField, uiField.value.ToString())); fieldElement = uiField; } else if (attribute.name.Equals("value") && currentVisualElement is TagField tagField) { var uiField = new TagField("Value"); uiField.RegisterValueChangedCallback(evt => PostAttributeValueChange(uiField, uiField.value.ToString())); fieldElement = uiField; } else { var uiField = new TextField(fieldLabel); if (attribute.name.Equals("name") || attribute.name.Equals("view-data-key")) { uiField.RegisterValueChangedCallback(e => { OnValidatedAttributeValueChange(e, BuilderNameUtilities.attributeRegex, BuilderConstants.AttributeValidationSpacialCharacters); }); } else if (attribute.name.Equals("binding-path")) { uiField.RegisterValueChangedCallback(e => { OnValidatedAttributeValueChange(e, BuilderNameUtilities.bindingPathAttributeRegex, BuilderConstants.BindingPathAttributeValidationSpacialCharacters); }); } else { uiField.RegisterValueChangedCallback(OnAttributeValueChange); } if (attribute.name.Equals("text") || attribute.name.Equals("label")) { uiField.multiline = true; uiField.AddToClassList(BuilderConstants.InspectorMultiLineTextFieldClassName); } fieldElement = uiField; } } else if (attribute is UxmlFloatAttributeDescription) { var uiField = new FloatField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlDoubleAttributeDescription) { var uiField = new DoubleField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlIntAttributeDescription) { if (attribute.name.Equals("value") && currentVisualElement is LayerField) { var uiField = new LayerField("Value"); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute.name.Equals("value") && currentVisualElement is LayerMaskField) { var uiField = new LayerMaskField("Value"); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else { var uiField = new IntegerField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } } else if (attribute is UxmlLongAttributeDescription) { var uiField = new LongField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlBoolAttributeDescription) { var uiField = new Toggle(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlColorAttributeDescription) { var uiField = new ColorField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attributeType.IsGenericType && !attributeType.GetGenericArguments()[0].IsEnum && attributeType.GetGenericArguments()[0] is Type) { var desiredType = attributeType.GetGenericArguments()[0]; var uiField = new TextField(fieldLabel) { isDelayed = true }; var completer = new FieldSearchCompleter <TypeInfo>(uiField); uiField.RegisterCallback <AttachToPanelEvent, FieldSearchCompleter <TypeInfo> >((evt, c) => { // When possible, the popup should have the same width as the input field, so that the auto-complete // characters will try to match said input field. c.popup.anchoredControl = ((VisualElement)evt.target).Q(className: "unity-text-field__input"); }, completer); completer.matcherCallback += (str, info) => info.value.IndexOf(str, StringComparison.OrdinalIgnoreCase) >= 0; completer.itemHeight = 36; completer.dataSourceCallback += () => { return(TypeCache.GetTypesDerivedFrom(desiredType) .Where(t => !t.IsGenericType) // Remove UIBuilder types from the list .Where(t => t.Assembly != GetType().Assembly) .Select(GetTypeInfo)); }; completer.getTextFromDataCallback += info => info.value; completer.makeItem = () => s_TypeNameItemPool.Get(); completer.destroyItem = e => { if (e is BuilderAttributeTypeName typeItem) { s_TypeNameItemPool.Release(typeItem); } }; completer.bindItem = (v, i) => { if (v is BuilderAttributeTypeName l) { l.SetType(completer.results[i].type, completer.textField.text); } }; uiField.RegisterValueChangedCallback(e => OnValidatedTypeAttributeChange(e, desiredType)); fieldElement = uiField; uiField.RegisterCallback <DetachFromPanelEvent, FieldSearchCompleter <TypeInfo> >((evt, c) => { c.popup.RemoveFromHierarchy(); }, completer); uiField.userData = completer; } else if (attributeType.IsGenericType && attributeType.GetGenericArguments()[0].IsEnum) { var propInfo = attributeType.GetProperty("defaultValue"); var defaultEnumValue = propInfo.GetValue(attribute, null) as Enum; if (defaultEnumValue.GetType().GetCustomAttribute <FlagsAttribute>() == null) { // Create and initialize the EnumField. var uiField = new EnumField(fieldLabel); uiField.Init(defaultEnumValue); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else { // Create and initialize the EnumField. var uiField = new EnumFlagsField(fieldLabel); uiField.Init(defaultEnumValue); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } } else { var uiField = new TextField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } // Create row. var styleRow = new BuilderStyleRow(); styleRow.Add(fieldElement); // Link the field. fieldElement.SetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName, styleRow); fieldElement.SetProperty(BuilderConstants.InspectorLinkedAttributeDescriptionVEPropertyName, attribute); // Set initial value. RefreshAttributeField(fieldElement); // Setup field binding path. fieldElement.bindingPath = attribute.name; fieldElement.tooltip = attribute.name; // Context menu. fieldElement.AddManipulator(new ContextualMenuManipulator(BuildAttributeFieldContextualMenu)); return(styleRow); }
public BuilderInspectorCanvas(BuilderInspector inspector) { m_Inspector = inspector; m_Document = inspector.document; m_CanvasInspector = m_Inspector.Q(ContainerName); var builderWindow = inspector.paneWindow as Builder; if (builderWindow == null) { return; } m_Canvas = builderWindow.canvas; m_CameraModeEnabled = false; // Size Fields m_CanvasWidth = root.Q <IntegerField>("canvas-width"); m_CanvasWidth.RegisterValueChangedCallback(OnWidthChange); m_CanvasHeight = root.Q <IntegerField>("canvas-height"); m_CanvasHeight.RegisterValueChangedCallback(OnHeightChange); m_Canvas.RegisterCallback <GeometryChangedEvent>(OnCanvasSizeChange); // This allows user to temporarily type values below the minimum canvas size SetDelayOnSizeFieldsEnabled(true); // To update the canvas size as user mouse drags the width or height labels DisableDelayOnActiveLabelMouseDraggers(); m_MatchGameViewToggle = root.Q <Toggle>("match-game-view"); m_MatchGameViewToggle.RegisterValueChangedCallback(OnMatchGameViewModeChanged); m_MatchGameViewHelpBox = root.Q <HelpBox>("match-game-view-hint"); // Background Opacity m_ColorOpacityField = root.Q <PercentSlider>("background-color-opacity-field"); m_ColorOpacityField.RegisterValueChangedCallback(e => { settings.ColorModeBackgroundOpacity = e.newValue; OnBackgroundOpacityChange(e.newValue); }); m_ImageOpacityField = root.Q <PercentSlider>("background-image-opacity-field"); m_ImageOpacityField.RegisterValueChangedCallback(e => { settings.ImageModeCanvasBackgroundOpacity = e.newValue; OnBackgroundOpacityChange(e.newValue); }); m_CameraOpacityField = root.Q <PercentSlider>("background-camera-opacity-field"); m_CameraOpacityField.RegisterValueChangedCallback(e => { settings.CameraModeCanvasBackgroundOpacity = e.newValue; OnBackgroundOpacityChange(e.newValue); }); // Setup Background State m_BackgroundOptionsFoldout = root.Q <FoldoutWithCheckbox>("canvas-background-foldout"); m_BackgroundOptionsFoldout.RegisterCheckboxValueChangedCallback(e => { settings.EnableCanvasBackground = e.newValue; PostSettingsChange(); ApplyBackgroundOptions(); }); // Setup Background Mode var backgroundModeType = typeof(BuilderCanvasBackgroundMode); var backgroundModeValues = Enum.GetValues(backgroundModeType) .OfType <BuilderCanvasBackgroundMode>().Select((v) => v.ToString()).ToList(); m_BackgroundMode = root.Q <ToggleButtonStrip>("background-mode-field"); m_BackgroundMode.enumType = backgroundModeType; m_BackgroundMode.choices = backgroundModeValues; m_BackgroundMode.RegisterValueChangedCallback(OnBackgroundModeChange); // Color field. m_ColorField = root.Q <ColorField>("background-color-field"); m_ColorField.RegisterValueChangedCallback(OnBackgroundColorChange); // Set Image field. m_ImageField = root.Q <ObjectField>("background-image-field"); m_ImageField.objectType = typeof(Texture2D); m_ImageField.RegisterValueChangedCallback(OnBackgroundImageChange); m_ImageScaleModeField = root.Q <ToggleButtonStrip>("background-image-scale-mode-field"); m_ImageScaleModeField.enumType = typeof(ScaleMode); var backgroundScaleModeValues = Enum.GetValues(typeof(ScaleMode)) .OfType <ScaleMode>().Select((v) => BuilderNameUtilities.ConvertCamelToDash(v.ToString())).ToList(); m_ImageScaleModeField.choices = backgroundScaleModeValues; m_ImageScaleModeField.RegisterValueChangedCallback(OnBackgroundImageScaleModeChange); m_FitCanvasToImageButton = root.Q <Button>("background-image-fit-canvas-button"); m_FitCanvasToImageButton.clickable.clicked += FitCanvasToImage; // Set Camera field. m_CameraField = root.Q <ObjectField>("background-camera-field"); m_CameraField.objectType = typeof(Camera); m_CameraField.RegisterValueChangedCallback(OnBackgroundCameraChange); #if !UNITY_2019_4 SetupEditorExtensionsModeToggle(); #else RemoveDocumentSettings(); #endif // Control Containers m_BackgroundColorModeControls = root.Q("canvas-background-color-mode-controls"); m_BackgroundImageModeControls = root.Q("canvas-background-image-mode-controls"); m_BackgroundCameraModeControls = root.Q("canvas-background-camera-mode-controls"); EditorApplication.playModeStateChanged += PlayModeStateChange; }
void FillItem(VisualElement element, ITreeViewItem item) { var explorerItem = element as BuilderExplorerItem; explorerItem.Clear(); // Pre-emptive cleanup. var row = explorerItem.parent.parent; row.RemoveFromClassList(BuilderConstants.ExplorerHeaderRowClassName); row.RemoveFromClassList(BuilderConstants.ExplorerItemHiddenClassName); // Get target element (in the document). var documentElement = (item as TreeViewItem <VisualElement>).data; documentElement.SetProperty(BuilderConstants.ElementLinkedExplorerItemVEPropertyName, explorerItem); explorerItem.SetProperty(BuilderConstants.ElementLinkedDocumentVisualElementVEPropertyName, documentElement); row.userData = documentElement; // If we have a FillItem callback (override), we call it and stop creating the rest of the item. var fillItemCallback = documentElement.GetProperty(BuilderConstants.ExplorerItemFillItemCallbackVEPropertyName) as Action <VisualElement, ITreeViewItem, BuilderSelection>; if (fillItemCallback != null) { fillItemCallback(explorerItem, item, m_Selection); return; } // Create main label container. var labelCont = new VisualElement(); labelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(labelCont); if (BuilderSharedStyles.IsSelectorsContainerElement(documentElement)) { var styleSheetAsset = documentElement.GetStyleSheet(); var styleSheetFileName = AssetDatabase.GetAssetPath(styleSheetAsset); var styleSheetAssetName = BuilderAssetUtilities.GetStyleSheetAssetName(styleSheetAsset); var ssLabel = new Label(styleSheetAssetName); ssLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); ssLabel.AddToClassList("unity-debugger-tree-item-type"); row.AddToClassList(BuilderConstants.ExplorerHeaderRowClassName); labelCont.Add(ssLabel); return; } else if (BuilderSharedStyles.IsSelectorElement(documentElement)) { var selectorParts = BuilderSharedStyles.GetSelectorParts(documentElement); foreach (var partStr in selectorParts) { if (partStr.StartsWith(BuilderConstants.UssSelectorClassNameSymbol)) { m_ClassPillTemplate.CloneTree(labelCont); var pill = labelCont.contentContainer.ElementAt(labelCont.childCount - 1); var pillLabel = pill.Q <Label>("class-name-label"); pill.AddToClassList("unity-debugger-tree-item-pill"); pill.SetProperty(BuilderConstants.ExplorerStyleClassPillClassNameVEPropertyName, partStr); pill.userData = documentElement; // Add ellipsis if the class name is too long. var partStrShortened = BuilderNameUtilities.CapStringLengthAndAddEllipsis(partStr, BuilderConstants.ClassNameInPillMaxLength); pillLabel.text = partStrShortened; m_ClassDragger.RegisterCallbacksOnTarget(pill); } else if (partStr.StartsWith(BuilderConstants.UssSelectorNameSymbol)) { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementNameClassName); labelCont.Add(selectorPartLabel); } else if (partStr.StartsWith(BuilderConstants.UssSelectorPseudoStateSymbol)) { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementPseudoStateClassName); labelCont.Add(selectorPartLabel); } else if (partStr == BuilderConstants.SingleSpace) { var selectorPartLabel = new Label(BuilderConstants.TripleSpace); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(selectorPartLabel); } else { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(selectorPartLabel); } } // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); return; } if (BuilderSharedStyles.IsDocumentElement(documentElement)) { var uxmlAsset = documentElement.GetVisualTreeAsset(); var ssLabel = new Label(BuilderAssetUtilities.GetVisualTreeAssetAssetName(uxmlAsset)); ssLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); ssLabel.AddToClassList("unity-debugger-tree-item-type"); row.AddToClassList(BuilderConstants.ExplorerHeaderRowClassName); labelCont.Add(ssLabel); return; } // Check if element is inside current document. if (!documentElement.IsPartOfCurrentDocument()) { row.AddToClassList(BuilderConstants.ExplorerItemHiddenClassName); } // Register drag-and-drop events for reparenting. m_HierarchyDragger.RegisterCallbacksOnTarget(explorerItem); // Allow reparenting. explorerItem.SetProperty(BuilderConstants.ExplorerItemElementLinkVEPropertyName, documentElement); // Element type label. if (string.IsNullOrEmpty(documentElement.name) || elementInfoVisibilityState.HasFlag(BuilderExplorer.BuilderElementInfoVisibilityState.TypeName)) { var typeLabel = new Label(documentElement.typeName); typeLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); typeLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(typeLabel); } // Element name label. var nameLabel = new Label(); nameLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); nameLabel.AddToClassList("unity-debugger-tree-item-name-label"); nameLabel.AddToClassList(BuilderConstants.ExplorerItemNameLabelClassName); nameLabel.AddToClassList(BuilderConstants.ElementNameClassName); if (!string.IsNullOrEmpty(documentElement.name)) { nameLabel.text = "#" + documentElement.name; } labelCont.Add(nameLabel); // Textfield to rename element in hierarchy. var renameTextfield = explorerItem.CreateRenamingTextField(documentElement, nameLabel, m_Selection); labelCont.Add(renameTextfield); // Add class list. if (documentElement.classList.Count > 0 && elementInfoVisibilityState.HasFlag(BuilderExplorer.BuilderElementInfoVisibilityState.ClassList)) { foreach (var ussClass in documentElement.GetClasses()) { var classLabelCont = new VisualElement(); classLabelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(classLabelCont); var classLabel = new Label("." + ussClass); classLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); classLabel.AddToClassList(BuilderConstants.ElementClassNameClassName); classLabel.AddToClassList("unity-debugger-tree-item-classlist-label"); classLabelCont.Add(classLabel); } } // Show name of uxml file if this element is a TemplateContainer. var path = documentElement.GetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName) as string; if (documentElement is TemplateContainer && !string.IsNullOrEmpty(path)) { var pathStr = Path.GetFileName(path); var label = new Label(pathStr); label.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); label.AddToClassList(BuilderConstants.ElementTypeClassName); label.AddToClassList("unity-builder-explorer-tree-item-template-path"); // Just make it look a bit shaded. labelCont.Add(label); } // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); }
BuilderStyleRow CreateAttributeRow(UxmlAttributeDescription attribute) { var attributeType = attribute.GetType(); // Generate field label. var fieldLabel = BuilderNameUtilities.ConvertDashToHuman(attribute.name); BindableElement fieldElement; if (attribute is UxmlStringAttributeDescription) { var uiField = new TextField(fieldLabel); if (attribute.name.Equals("name") || attribute.name.Equals("view-data-key")) { uiField.RegisterValueChangedCallback(e => { OnValidatedAttributeValueChange(e, BuilderNameUtilities.AttributeRegex, BuilderConstants.AttributeValidationSpacialCharacters); }); } else if (attribute.name.Equals("binding-path")) { uiField.RegisterValueChangedCallback(e => { OnValidatedAttributeValueChange(e, BuilderNameUtilities.BindingPathAttributeRegex, BuilderConstants.BindingPathAttributeValidationSpacialCharacters); }); } else { uiField.RegisterValueChangedCallback(OnAttributeValueChange); } if (attribute.name.Equals("text")) { uiField.multiline = true; uiField.AddToClassList(BuilderConstants.InspectorMultiLineTextFieldClassName); } fieldElement = uiField; } else if (attribute is UxmlFloatAttributeDescription) { var uiField = new FloatField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlDoubleAttributeDescription) { var uiField = new DoubleField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlIntAttributeDescription) { var uiField = new IntegerField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlLongAttributeDescription) { var uiField = new LongField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlBoolAttributeDescription) { var uiField = new Toggle(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlColorAttributeDescription) { var uiField = new ColorField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attributeType.IsGenericType && !attributeType.GetGenericArguments()[0].IsEnum && attributeType.GetGenericArguments()[0] is Type) { var uiField = new TextField(fieldLabel); uiField.isDelayed = true; uiField.RegisterValueChangedCallback(e => { OnValidatedTypeAttributeChange(e, attributeType.GetGenericArguments()[0]); }); fieldElement = uiField; } else if (attributeType.IsGenericType && attributeType.GetGenericArguments()[0].IsEnum) { var propInfo = attributeType.GetProperty("defaultValue"); var enumValue = propInfo.GetValue(attribute, null) as Enum; // Create and initialize the EnumField. var uiField = new EnumField(fieldLabel); uiField.Init(enumValue); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else { var uiField = new TextField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } // Create row. var styleRow = new BuilderStyleRow(); styleRow.Add(fieldElement); // Link the field. fieldElement.SetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName, styleRow); fieldElement.SetProperty(BuilderConstants.InspectorLinkedAttributeDescriptionVEPropertyName, attribute); // Set initial value. RefreshAttributeField(fieldElement); // Setup field binding path. fieldElement.bindingPath = attribute.name; // Tooltip. var label = fieldElement.Q <Label>(); if (label != null) { label.tooltip = attribute.name; } else { fieldElement.tooltip = attribute.name; } // Context menu. fieldElement.AddManipulator(new ContextualMenuManipulator(BuildAttributeFieldContextualMenu)); return(styleRow); }
public void BindStyleField(BuilderStyleRow styleRow, string styleName, VisualElement fieldElement) { // Link the row. fieldElement.SetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName, styleRow); var field = FindStylePropertyInfo(styleName); if (field == null) { return; } // We don't care which element we get the value for here as we're only interested // in the type of Enum it might be (and for validation), but not it's actual value. var val = field.GetValue(fieldElement.computedStyle, null); var valType = val.GetType(); if (val is StyleFloat && fieldElement is FloatField) { var uiField = fieldElement as FloatField; uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (val is StyleFloat && fieldElement is IntegerField) { var uiField = fieldElement as IntegerField; #if UNITY_2019_3_OR_NEWER if (BuilderConstants.SpecialSnowflakeLengthSytles.Contains(styleName)) { uiField.RegisterValueChangedCallback(e => OnFieldDimensionChange(e, styleName)); } else #endif uiField.RegisterValueChangedCallback(e => OnFieldValueChangeIntToFloat(e, styleName)); } else if (val is StyleFloat && fieldElement is PercentSlider) { var uiField = fieldElement as PercentSlider; uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (val is StyleInt && fieldElement is IntegerField) { var uiField = fieldElement as IntegerField; uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (val is StyleLength && fieldElement is IntegerField) { var uiField = fieldElement as IntegerField; #if UNITY_2019_3_OR_NEWER uiField.RegisterValueChangedCallback(e => OnFieldDimensionChange(e, styleName)); #else uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); #endif } else if (val is StyleColor && fieldElement is ColorField) { var uiField = fieldElement as ColorField; uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (val is StyleFont && fieldElement is ObjectField) { var uiField = fieldElement as ObjectField; uiField.objectType = typeof(Font); uiField.RegisterValueChangedCallback(e => OnFieldValueChangeFont(e, styleName)); } else if (val is StyleBackground && fieldElement is ObjectField) { var uiField = fieldElement as ObjectField; uiField.objectType = typeof(Texture2D); uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (val is StyleCursor && fieldElement is ObjectField) { var uiField = fieldElement as ObjectField; uiField.objectType = typeof(Texture2D); uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (valType.IsGenericType && valType.GetGenericArguments()[0].IsEnum) { var propInfo = valType.GetProperty("value"); var enumValue = propInfo.GetValue(val, null) as Enum; if (fieldElement is EnumField) { var uiField = fieldElement as EnumField; uiField.Init(enumValue); uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else if (fieldElement is IToggleButtonStrip) { var uiField = fieldElement as IToggleButtonStrip; var choices = new List <string>(); var labels = new List <string>(); var enumType = enumValue.GetType(); foreach (Enum item in Enum.GetValues(enumType)) { var typeName = item.ToString(); var label = string.Empty; if (typeName == "Auto") { label = "AUTO"; } var choice = BuilderNameUtilities.ConvertCamelToDash(typeName); choices.Add(choice); labels.Add(label); } uiField.enumType = enumType; uiField.choices = choices; uiField.labels = labels; uiField.RegisterValueChangedCallback(e => OnFieldValueChange(e, styleName)); } else { // Unsupported style value type. return; } } else { // Unsupported style value type. return; } fieldElement.SetProperty(BuilderConstants.InspectorStylePropertyNameVEPropertyName, styleName); fieldElement.SetProperty(BuilderConstants.InspectorComputedStylePropertyInfoVEPropertyName, field); fieldElement.AddManipulator(new ContextualMenuManipulator(BuildStyleFieldContextualMenu)); // Add to styleName to field map. if (!m_StyleFields.ContainsKey(styleName)) { var newList = new List <VisualElement>(); newList.Add(fieldElement); m_StyleFields.Add(styleName, newList); } else { m_StyleFields[styleName].Add(fieldElement); } }
BuilderStyleRow CreateAttributeRow(UxmlAttributeDescription attribute) { var attributeType = attribute.GetType(); var vea = currentVisualElement.GetVisualElementAsset(); // Generate field label. var fieldLabel = BuilderNameUtilities.ConvertDashToHuman(attribute.name); BindableElement fieldElement = null; if (attribute is UxmlStringAttributeDescription) { var uiField = new TextField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlFloatAttributeDescription) { var uiField = new FloatField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlDoubleAttributeDescription) { var uiField = new DoubleField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlIntAttributeDescription) { var uiField = new IntegerField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlLongAttributeDescription) { var uiField = new LongField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlBoolAttributeDescription) { var uiField = new Toggle(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attribute is UxmlColorAttributeDescription) { var uiField = new ColorField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else if (attributeType.IsGenericType && attributeType.GetGenericArguments()[0].IsEnum) { var propInfo = attributeType.GetProperty("defaultValue"); var enumValue = propInfo.GetValue(attribute, null) as Enum; // Create and initialize the EnumField. var uiField = new EnumField(fieldLabel); uiField.Init(enumValue); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } else { var uiField = new TextField(fieldLabel); uiField.RegisterValueChangedCallback(OnAttributeValueChange); fieldElement = uiField; } // Create row. var styleRow = new BuilderStyleRow(); styleRow.Add(fieldElement); // Link the field. fieldElement.SetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName, styleRow); fieldElement.SetProperty(BuilderConstants.InspectorLinkedAttributeDescriptionVEPropertyName, attribute); // Set initial value. RefreshAttributeField(fieldElement); // Setup field binding path. fieldElement.bindingPath = attribute.name; // Tooltip. var label = fieldElement.Q <Label>(); if (label != null) { label.tooltip = attribute.name; } else { fieldElement.tooltip = attribute.name; } // Context menu. fieldElement.AddManipulator(new ContextualMenuManipulator(BuildAttributeFieldContextualMenu)); return(styleRow); }
void FillItem(VisualElement element, ITreeViewItem item) { var explorerItem = element as BuilderExplorerItem; explorerItem.Clear(); // Pre-emptive cleanup. var row = explorerItem.parent.parent; row.RemoveFromClassList(BuilderConstants.ExplorerHeaderRowClassName); row.RemoveFromClassList(BuilderConstants.ExplorerItemHiddenClassName); row.RemoveFromClassList(BuilderConstants.ExplorerActiveStyleSheetClassName); // Get target element (in the document). var documentElement = (item as TreeViewItem <VisualElement>).data; documentElement.SetProperty(BuilderConstants.ElementLinkedExplorerItemVEPropertyName, explorerItem); explorerItem.SetProperty(BuilderConstants.ElementLinkedDocumentVisualElementVEPropertyName, documentElement); row.userData = documentElement; // If we have a FillItem callback (override), we call it and stop creating the rest of the item. var fillItemCallback = documentElement.GetProperty(BuilderConstants.ExplorerItemFillItemCallbackVEPropertyName) as Action <VisualElement, ITreeViewItem, BuilderSelection>; if (fillItemCallback != null) { fillItemCallback(explorerItem, item, m_Selection); return; } // Create main label container. var labelCont = new VisualElement(); labelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(labelCont); if (BuilderSharedStyles.IsStyleSheetElement(documentElement)) { var owningUxmlPath = documentElement.GetProperty(BuilderConstants.ExplorerItemLinkedUXMLFileName) as string; var isPartOfParentDocument = !string.IsNullOrEmpty(owningUxmlPath); var styleSheetAsset = documentElement.GetStyleSheet(); var styleSheetFileName = AssetDatabase.GetAssetPath(styleSheetAsset); var styleSheetAssetName = BuilderAssetUtilities.GetStyleSheetAssetName(styleSheetAsset, hasUnsavedChanges && !isPartOfParentDocument); var ssLabel = new Label(styleSheetAssetName); ssLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); ssLabel.AddToClassList("unity-debugger-tree-item-type"); row.AddToClassList(BuilderConstants.ExplorerHeaderRowClassName); labelCont.Add(ssLabel); // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); // Register drag-and-drop events for reparenting. m_ExplorerDragger.RegisterCallbacksOnTarget(explorerItem); // Allow reparenting. explorerItem.SetProperty(BuilderConstants.ExplorerItemElementLinkVEPropertyName, documentElement); var assetIsActiveStyleSheet = styleSheetAsset == m_PaneWindow.document.activeStyleSheet; if (assetIsActiveStyleSheet) { row.AddToClassList(BuilderConstants.ExplorerActiveStyleSheetClassName); } if (isPartOfParentDocument) { row.AddToClassList(BuilderConstants.ExplorerItemHiddenClassName); } // Show name of UXML file that USS file 'belongs' to. if (!string.IsNullOrEmpty(owningUxmlPath)) { var pathStr = Path.GetFileName(owningUxmlPath); var label = new Label(BuilderConstants.TripleSpace + pathStr); label.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); label.AddToClassList(BuilderConstants.ElementTypeClassName); label.AddToClassList("unity-builder-explorer-tree-item-template-path"); // Just make it look a bit shaded. labelCont.Add(label); } return; } else if (BuilderSharedStyles.IsSelectorElement(documentElement)) { var selectorParts = BuilderSharedStyles.GetSelectorParts(documentElement); // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); // Register drag-and-drop events for reparenting. m_ExplorerDragger.RegisterCallbacksOnTarget(explorerItem); foreach (var partStr in selectorParts) { if (partStr.StartsWith(BuilderConstants.UssSelectorClassNameSymbol)) { m_ClassPillTemplate.CloneTree(labelCont); var pill = labelCont.contentContainer.ElementAt(labelCont.childCount - 1); var pillLabel = pill.Q <Label>("class-name-label"); pill.name = "unity-builder-tree-class-pill"; pill.AddToClassList("unity-debugger-tree-item-pill"); pill.SetProperty(BuilderConstants.ExplorerStyleClassPillClassNameVEPropertyName, partStr); pill.userData = documentElement; // Add ellipsis if the class name is too long. var partStrShortened = BuilderNameUtilities.CapStringLengthAndAddEllipsis(partStr, BuilderConstants.ClassNameInPillMaxLength); pillLabel.text = partStrShortened; m_ClassDragger.RegisterCallbacksOnTarget(pill); } else if (partStr.StartsWith(BuilderConstants.UssSelectorNameSymbol)) { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementNameClassName); labelCont.Add(selectorPartLabel); } else if (partStr.StartsWith(BuilderConstants.UssSelectorPseudoStateSymbol)) { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementPseudoStateClassName); labelCont.Add(selectorPartLabel); } else if (partStr == BuilderConstants.SingleSpace) { var selectorPartLabel = new Label(BuilderConstants.TripleSpace); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(selectorPartLabel); } else { var selectorPartLabel = new Label(partStr); selectorPartLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); selectorPartLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(selectorPartLabel); } } // Allow reparenting. explorerItem.SetProperty(BuilderConstants.ExplorerItemElementLinkVEPropertyName, documentElement); // Check if selector element is inside current open StyleSheets if (documentElement.IsParentSelector()) { row.AddToClassList(BuilderConstants.ExplorerItemHiddenClassName); } return; } if (BuilderSharedStyles.IsDocumentElement(documentElement)) { var uxmlAsset = documentElement.GetVisualTreeAsset(); var ssLabel = new Label(BuilderAssetUtilities.GetVisualTreeAssetAssetName(uxmlAsset, hasUnsavedChanges)); ssLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); ssLabel.AddToClassList("unity-debugger-tree-item-type"); row.AddToClassList(BuilderConstants.ExplorerHeaderRowClassName); labelCont.Add(ssLabel); // Allow reparenting. explorerItem.SetProperty(BuilderConstants.ExplorerItemElementLinkVEPropertyName, documentElement); // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); return; } // Check if element is inside current document. if (!documentElement.IsPartOfActiveVisualTreeAsset(m_PaneWindow.document)) { row.AddToClassList(BuilderConstants.ExplorerItemHiddenClassName); } // Register drag-and-drop events for reparenting. m_ExplorerDragger.RegisterCallbacksOnTarget(explorerItem); // Allow reparenting. explorerItem.SetProperty(BuilderConstants.ExplorerItemElementLinkVEPropertyName, documentElement); // Element type label. if (string.IsNullOrEmpty(documentElement.name) || elementInfoVisibilityState.HasFlag(BuilderExplorer.BuilderElementInfoVisibilityState.TypeName)) { var typeLabel = new Label(documentElement.typeName); typeLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); typeLabel.AddToClassList(BuilderConstants.ElementTypeClassName); labelCont.Add(typeLabel); } // Element name label. var nameLabel = new Label(); nameLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); nameLabel.AddToClassList("unity-debugger-tree-item-name-label"); nameLabel.AddToClassList(BuilderConstants.ExplorerItemNameLabelClassName); nameLabel.AddToClassList(BuilderConstants.ElementNameClassName); if (!string.IsNullOrEmpty(documentElement.name)) { nameLabel.text = BuilderConstants.UssSelectorNameSymbol + documentElement.name; } labelCont.Add(nameLabel); // Textfield to rename element in hierarchy. var renameTextfield = explorerItem.CreateRenamingTextField(documentElement, nameLabel, m_Selection); labelCont.Add(renameTextfield); // Add class list. if (documentElement.classList.Count > 0 && elementInfoVisibilityState.HasFlag(BuilderExplorer.BuilderElementInfoVisibilityState.ClassList)) { foreach (var ussClass in documentElement.GetClasses()) { var classLabelCont = new VisualElement(); classLabelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(classLabelCont); var classLabel = new Label(BuilderConstants.UssSelectorClassNameSymbol + ussClass); classLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); classLabel.AddToClassList(BuilderConstants.ElementClassNameClassName); classLabel.AddToClassList("unity-debugger-tree-item-classlist-label"); classLabelCont.Add(classLabel); } } // Add stylesheets. if (elementInfoVisibilityState.HasFlag(BuilderExplorer.BuilderElementInfoVisibilityState.StyleSheets)) { var vea = documentElement.GetVisualElementAsset(); if (vea != null) { foreach (var ussPath in vea.GetStyleSheetPaths()) { if (string.IsNullOrEmpty(ussPath)) { continue; } var classLabelCont = new VisualElement(); classLabelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(classLabelCont); var classLabel = new Label(Path.GetFileName(ussPath)); classLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); classLabel.AddToClassList(BuilderConstants.ElementAttachedStyleSheetClassName); classLabel.AddToClassList("unity-debugger-tree-item-classlist-label"); classLabelCont.Add(classLabel); } } else { for (int i = 0; i < documentElement.styleSheets.count; ++i) { var attachedStyleSheet = documentElement.styleSheets[i]; if (attachedStyleSheet == null) { continue; } var classLabelCont = new VisualElement(); classLabelCont.AddToClassList(BuilderConstants.ExplorerItemLabelContClassName); explorerItem.Add(classLabelCont); var classLabel = new Label(attachedStyleSheet.name + BuilderConstants.UssExtension); classLabel.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); classLabel.AddToClassList(BuilderConstants.ElementAttachedStyleSheetClassName); classLabel.AddToClassList("unity-debugger-tree-item-classlist-label"); classLabelCont.Add(classLabel); } } } // Show name of uxml file if this element is a TemplateContainer. var path = documentElement.GetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName) as string; Texture2D itemIcon; if (documentElement is TemplateContainer && !string.IsNullOrEmpty(path)) { var pathStr = Path.GetFileName(path); var label = new Label(pathStr); label.AddToClassList(BuilderConstants.ExplorerItemLabelClassName); label.AddToClassList(BuilderConstants.ElementTypeClassName); label.AddToClassList("unity-builder-explorer-tree-item-template-path"); // Just make it look a bit shaded. labelCont.Add(label); itemIcon = BuilderLibraryContent.GetUXMLAssetIcon(path); } else { itemIcon = BuilderLibraryContent.GetTypeLibraryIcon(documentElement.GetType()); } // Element icon. var icon = new VisualElement(); icon.AddToClassList(BuilderConstants.ExplorerItemIconClassName); var styleBackgroundImage = icon.style.backgroundImage; styleBackgroundImage.value = new Background { texture = itemIcon }; icon.style.backgroundImage = styleBackgroundImage; labelCont.Insert(0, icon); // Register right-click events for context menu actions. m_ContextMenuManipulator.RegisterCallbacksOnTarget(explorerItem); }
public BuilderInspectorCanvas(BuilderInspector inspector) { m_Inspector = inspector; m_Document = inspector.document; m_CanvasInspector = m_Inspector.Q("canvas-inspector"); var builderWindow = inspector.paneWindow as Builder; if (builderWindow == null) { return; } m_Canvas = builderWindow.canvas; m_CameraModeEnabled = false; // Size Fields m_CanvasWidth = root.Q <IntegerField>("canvas-width"); m_CanvasWidth.isDelayed = true; m_CanvasWidth.RegisterValueChangedCallback(OnWidthChange); m_CanvasHeight = root.Q <IntegerField>("canvas-height"); m_CanvasHeight.isDelayed = true; m_CanvasHeight.RegisterValueChangedCallback(OnHeightChange); m_Canvas.RegisterCallback <GeometryChangedEvent>(OnCanvasSizeChange); // Background Opacity m_OpacityField = root.Q <PercentSlider>("background-opacity-field"); m_OpacityField.RegisterValueChangedCallback(OnBackgroundOpacityChange); // Setup Background Mode var backgroundModeType = typeof(BuilderCanvasBackgroundMode); var backgroundModeValues = Enum.GetValues(backgroundModeType) .OfType <BuilderCanvasBackgroundMode>().Select((v) => v.ToString()).ToList(); var backgroundModeNames = Enum.GetNames(backgroundModeType); m_BackgroundMode = root.Q <ToggleButtonStrip>("background-mode-field"); m_BackgroundMode.enumType = backgroundModeType; m_BackgroundMode.labels = backgroundModeNames; m_BackgroundMode.choices = backgroundModeValues; m_BackgroundMode.RegisterValueChangedCallback(OnBackgroundModeChange); // Color field. m_ColorField = root.Q <ColorField>("background-color-field"); m_ColorField.RegisterValueChangedCallback(OnBackgroundColorChange); // Set Image field. m_ImageField = root.Q <ObjectField>("background-image-field"); m_ImageField.objectType = typeof(Texture2D); m_ImageField.RegisterValueChangedCallback(OnBackgroundImageChange); m_ImageScaleModeField = root.Q <ToggleButtonStrip>("background-image-scale-mode-field"); m_ImageScaleModeField.enumType = typeof(ScaleMode); var backgroundScaleModeValues = Enum.GetValues(typeof(ScaleMode)) .OfType <ScaleMode>().Select((v) => BuilderNameUtilities.ConvertCamelToDash(v.ToString())).ToList(); m_ImageScaleModeField.choices = backgroundScaleModeValues; m_ImageScaleModeField.RegisterValueChangedCallback(OnBackgroundImageScaleModeChange); m_FitCanvasToImageButton = root.Q <Button>("background-image-fit-canvas-button"); m_FitCanvasToImageButton.clickable.clicked += FitCanvasToImage; // Set Camera field. m_CameraField = root.Q <ObjectField>("background-camera-field"); m_CameraField.objectType = typeof(Camera); m_CameraField.RegisterValueChangedCallback(OnBackgroundCameraChange); // Control Containers m_BackgroundColorModeControls = root.Q("canvas-background-color-mode-controls"); m_BackgroundImageModeControls = root.Q("canvas-background-image-mode-controls"); m_BackgroundCameraModeControls = root.Q("canvas-background-camera-mode-controls"); EditorApplication.playModeStateChanged += PlayModeStateChange; }
void RefreshAttributeField(BindableElement fieldElement) { var styleRow = fieldElement.GetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName) as VisualElement; var attribute = fieldElement.GetProperty(BuilderConstants.InspectorLinkedAttributeDescriptionVEPropertyName) as UxmlAttributeDescription; var veType = currentVisualElement.GetType(); var camel = BuilderNameUtilities.ConvertDashToCamel(attribute.name); var fieldInfo = veType.GetProperty(camel, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase); object veValueAbstract = null; if (fieldInfo == null) { veValueAbstract = GetCustomValueAbstract(attribute.name); } else { veValueAbstract = fieldInfo.GetValue(currentVisualElement); } if (veValueAbstract == null) { return; } var attributeType = attribute.GetType(); var vea = currentVisualElement.GetVisualElementAsset(); if (attribute is UxmlStringAttributeDescription && fieldElement is TextField) { string value; if (veValueAbstract is Enum) { value = (veValueAbstract as Enum).ToString(); } else { value = (string)veValueAbstract; } (fieldElement as TextField).SetValueWithoutNotify(value); } else if (attribute is UxmlFloatAttributeDescription && fieldElement is FloatField) { (fieldElement as FloatField).SetValueWithoutNotify((float)veValueAbstract); } else if (attribute is UxmlDoubleAttributeDescription && fieldElement is DoubleField) { (fieldElement as DoubleField).SetValueWithoutNotify((double)veValueAbstract); } else if (attribute is UxmlIntAttributeDescription && fieldElement is IntegerField) { if (veValueAbstract is int) { (fieldElement as IntegerField).SetValueWithoutNotify((int)veValueAbstract); } else if (veValueAbstract is float) { (fieldElement as IntegerField).SetValueWithoutNotify(Convert.ToInt32(veValueAbstract)); } } else if (attribute is UxmlLongAttributeDescription && fieldElement is LongField) { (fieldElement as LongField).SetValueWithoutNotify((long)veValueAbstract); } else if (attribute is UxmlBoolAttributeDescription && fieldElement is Toggle) { (fieldElement as Toggle).SetValueWithoutNotify((bool)veValueAbstract); } else if (attribute is UxmlColorAttributeDescription && fieldElement is ColorField) { (fieldElement as ColorField).SetValueWithoutNotify((Color)veValueAbstract); } else if (attributeType.IsGenericType && !attributeType.GetGenericArguments()[0].IsEnum && attributeType.GetGenericArguments()[0] is Type && fieldElement is TextField textField && veValueAbstract is Type veTypeValue) { var fullTypeName = veTypeValue.AssemblyQualifiedName; var fullTypeNameSplit = fullTypeName.Split(','); textField.SetValueWithoutNotify($"{fullTypeNameSplit[0]},{fullTypeNameSplit[1]}"); }
/// <summary> /// This will iterate over the current UI Builder hierarchy and extract the supported animatable properties. /// This will allow to display the options to users in the same order that they are in the builder. /// </summary> void GenerateTransitionPropertiesContent() { var content = new CategoryDropdownContent(); content.AppendValue(new CategoryDropdownContent.ValueItem { value = "all", displayName = "all" }); foreach (var kvp in m_StyleCategories) { var groupName = kvp.Key.text; if (string.IsNullOrWhiteSpace(groupName) || groupName == "Transition Animations") { continue; } content.AppendCategory(new CategoryDropdownContent.Category { name = groupName }); foreach (var element in kvp.Value) { var styleName = element.GetProperty(BuilderConstants.InspectorStylePropertyNameVEPropertyName) as string; if (!string.IsNullOrWhiteSpace(styleName)) { var styleId = StyleDebug.GetStylePropertyIdFromName(styleName); if (!StylePropertyUtil.IsAnimatable(styleId)) { continue; } if (!string.IsNullOrWhiteSpace(styleId.ToString())) { content.AppendValue( new CategoryDropdownContent.ValueItem { categoryName = groupName, value = styleName, displayName = ObjectNames.NicifyVariableName(styleId.ToString()) }); } } if (!(element is FoldoutField foldoutField)) { continue; } var hashSet = HashSetPool <StylePropertyId> .Get(); try { foreach (var bindingPath in foldoutField.bindingPathArray) { var shortHandId = StyleDebug.GetStylePropertyIdFromName(bindingPath).GetShorthandProperty(); if (shortHandId == StylePropertyId.Unknown || !hashSet.Add(shortHandId)) { continue; } if (!StylePropertyUtil.IsAnimatable(shortHandId)) { continue; } if (!string.IsNullOrWhiteSpace(shortHandId.ToString())) { content.AppendValue( new CategoryDropdownContent.ValueItem { categoryName = groupName, value = BuilderNameUtilities.ConvertStyleCSharpNameToUssName( shortHandId.ToString()), displayName = ObjectNames.NicifyVariableName(shortHandId.ToString()) }); } } } finally { HashSetPool <StylePropertyId> .Release(hashSet); } } } content.AppendSeparator(); content.AppendValue(new CategoryDropdownContent.ValueItem { value = "none", displayName = "none" }); content.AppendValue(new CategoryDropdownContent.ValueItem { value = "initial", displayName = "initial" }); content.AppendValue(new CategoryDropdownContent.ValueItem { value = "ignored", displayName = "ignored" }); TransitionPropertyDropdownContent.Content = content; }
public static Dictionary <string, string> GetOverriddenAttributes(this VisualElement ve) { var attributeList = ve.GetAttributeDescriptions(); var overriddenAttributes = new Dictionary <string, string>(); foreach (var attribute in attributeList) { if (attribute?.name == null) { continue; } var veType = ve.GetType(); var camel = BuilderNameUtilities.ConvertDashToCamel(attribute.name); var fieldInfo = veType.GetProperty(camel); if (fieldInfo != null) { var veValueAbstract = fieldInfo.GetValue(ve, null); if (veValueAbstract == null) { continue; } var veValueStr = veValueAbstract.ToString(); if (veValueStr == "False") { veValueStr = "false"; } else if (veValueStr == "True") { veValueStr = "true"; } // The result of Type.ToString is not enough for us to find the correct Type. if (veValueAbstract is Type type) { veValueStr = $"{type.FullName}, {type.Assembly.GetName().Name}"; } var attributeValueStr = attribute.defaultValueAsString; if (veValueStr == attributeValueStr) { continue; } overriddenAttributes.Add(attribute.name, veValueStr); } // This is a special patch that allows to search for built-in elements' attribute specifically // without needing to add to the public API. // Allowing to search for internal/private properties in all cases could lead to unforeseen issues. else if (ve is EnumField && camel == "type") { fieldInfo = veType.GetProperty(camel, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var veValueAbstract = fieldInfo.GetValue(ve, null); if (!(veValueAbstract is Type type)) { continue; } var veValueStr = $"{type.FullName}, {type.Assembly.GetName().Name}"; var attributeValueStr = attribute.defaultValueAsString; if (veValueStr == attributeValueStr) { continue; } overriddenAttributes.Add(attribute.name, veValueStr); } } return(overriddenAttributes); }
public void RefreshStyleField(string styleName, VisualElement fieldElement) { var field = FindStylePropertyInfo(styleName); if (field == null) { return; } var val = field.GetValue(currentVisualElement.computedStyle, null); var valType = val.GetType(); var cSharpStyleName = ConvertUssStyleNameToCSharpStyleName(styleName); var styleProperty = GetStyleProperty(currentRule, cSharpStyleName); if (val is StyleFloat && fieldElement is FloatField) { var style = (StyleFloat)val; var uiField = fieldElement as FloatField; var value = style.value; if (styleProperty != null) { value = styleSheet.GetFloat(styleProperty.values[0]); } uiField.SetValueWithoutNotify(value); } else if (val is StyleFloat && fieldElement is IntegerField) { var style = (StyleFloat)val; var uiField = fieldElement as IntegerField; var value = (int)style.value; if (styleProperty != null) { value = (int)styleSheet.GetFloat(styleProperty.values[0]); } uiField.SetValueWithoutNotify(value); } else if (val is StyleFloat && fieldElement is PercentSlider) { var style = (StyleFloat)val; var uiField = fieldElement as PercentSlider; var value = style.value; if (styleProperty != null) { value = styleSheet.GetFloat(styleProperty.values[0]); } uiField.SetValueWithoutNotify(value); } else if (val is StyleInt && fieldElement is IntegerField) { var style = (StyleInt)val; var uiField = fieldElement as IntegerField; var value = style.value; if (styleProperty != null) { value = styleSheet.GetInt(styleProperty.values[0]); } uiField.SetValueWithoutNotify(value); } else if (val is StyleLength && fieldElement is IntegerField) { var style = (StyleLength)val; var uiField = fieldElement as IntegerField; var value = (int)style.value.value; if (styleProperty != null) #if UNITY_2019_3_OR_NEWER { value = (int)styleSheet.GetDimension(styleProperty.values[0]).value; } #else { value = styleSheet.GetInt(styleProperty.values[0]); } #endif uiField.SetValueWithoutNotify(value); } else if (val is StyleColor && fieldElement is ColorField) { var style = (StyleColor)val; var uiField = fieldElement as ColorField; var value = style.value; if (styleProperty != null) { value = styleSheet.GetColor(styleProperty.values[0]); } // We keep falling into the alpha==0 trap. This patches the issue a little. if (value.a < 0.1f) { value.a = 255.0f; } uiField.SetValueWithoutNotify(value); } else if (val is StyleFont && fieldElement is ObjectField) { var style = (StyleFont)val; var uiField = fieldElement as ObjectField; var value = style.value; if (styleProperty != null) { value = styleSheet.GetAsset(styleProperty.values[0]) as Font; } uiField.SetValueWithoutNotify(value); } else if (val is StyleBackground && fieldElement is ObjectField) { var style = (StyleBackground)val; var uiField = fieldElement as ObjectField; var value = style.value; if (styleProperty != null) { value.texture = styleSheet.GetAsset(styleProperty.values[0]) as Texture2D; } uiField.SetValueWithoutNotify(value.texture); } else if (val is StyleCursor && fieldElement is ObjectField) { var style = (StyleCursor)val; var uiField = fieldElement as ObjectField; var value = style.value; if (styleProperty != null) { value.texture = styleSheet.GetAsset(styleProperty.values[0]) as Texture2D; } uiField.SetValueWithoutNotify(value.texture); } else if (valType.IsGenericType && valType.GetGenericArguments()[0].IsEnum) { var propInfo = valType.GetProperty("value"); var enumValue = propInfo.GetValue(val, null) as Enum; if (styleProperty != null) { var enumStr = styleSheet.GetEnum(styleProperty.values[0]); var enumStrHungarian = BuilderNameUtilities.ConvertDashToHungarian(enumStr); var enumObj = Enum.Parse(enumValue.GetType(), enumStrHungarian); enumValue = enumObj as Enum; } // The state of Flex Direction can affect many other Flex-related fields. if (styleName == "flex-direction") { updateFlexColumnGlobalState?.Invoke(enumValue); } if (fieldElement is EnumField) { var uiField = fieldElement as EnumField; uiField.SetValueWithoutNotify(enumValue); } else if (fieldElement is IToggleButtonStrip) { var enumStr = BuilderNameUtilities.ConvertCamelToDash(enumValue.ToString()); var uiField = fieldElement as IToggleButtonStrip; uiField.SetValueWithoutNotify(enumStr); } else { // Unsupported style value type. return; } } else { // Unsupported style value type. return; } // Add override style to field if it is overwritten. var styleRow = fieldElement.GetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName) as BuilderStyleRow; Assert.IsNotNull(styleRow); if (styleRow == null) { return; } var styleFields = styleRow.Query <BindableElement>().ToList(); bool isRowOverride = false; foreach (var styleField in styleFields) { var cShartStyleName = ConvertUssStyleNameToCSharpStyleName(styleField.bindingPath); if (GetStyleProperty(currentRule, cShartStyleName) != null) { isRowOverride = true; styleField.RemoveFromClassList(BuilderConstants.InspectorLocalStyleResetClassName); styleField.AddToClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); } else if (!string.IsNullOrEmpty(styleField.bindingPath)) { styleField.AddToClassList(BuilderConstants.InspectorLocalStyleResetClassName); } } if (styleProperty != null || isRowOverride) { styleRow.AddToClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); } else { styleRow.RemoveFromClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); foreach (var styleField in styleFields) { styleField.RemoveFromClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); styleField.RemoveFromClassList(BuilderConstants.InspectorLocalStyleResetClassName); } } }
void RefreshAttributeField(BindableElement fieldElement) { var styleRow = fieldElement.GetProperty(BuilderConstants.InspectorLinkedStyleRowVEPropertyName) as VisualElement; var attribute = fieldElement.GetProperty(BuilderConstants.InspectorLinkedAttributeDescriptionVEPropertyName) as UxmlAttributeDescription; var veType = currentVisualElement.GetType(); var camel = BuilderNameUtilities.ConvertDashToCamel(attribute.name); var fieldInfo = veType.GetProperty(camel, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase); object veValueAbstract = null; if (fieldInfo == null) { veValueAbstract = GetCustomValueAbstract(attribute.name); } else { veValueAbstract = fieldInfo.GetValue(currentVisualElement); } if (veValueAbstract == null) { return; } var attributeType = attribute.GetType(); var vea = currentVisualElement.GetVisualElementAsset(); if (attribute is UxmlStringAttributeDescription && fieldElement is TextField) { string value; if (veValueAbstract is Enum) { value = (veValueAbstract as Enum).ToString(); } else { value = (string)veValueAbstract; } (fieldElement as TextField).SetValueWithoutNotify(value); } else if (attribute is UxmlFloatAttributeDescription && fieldElement is FloatField) { (fieldElement as FloatField).SetValueWithoutNotify((float)veValueAbstract); } else if (attribute is UxmlDoubleAttributeDescription && fieldElement is DoubleField) { (fieldElement as DoubleField).SetValueWithoutNotify((double)veValueAbstract); } else if (attribute is UxmlIntAttributeDescription && fieldElement is IntegerField) { (fieldElement as IntegerField).SetValueWithoutNotify((int)veValueAbstract); } else if (attribute is UxmlLongAttributeDescription && fieldElement is LongField) { (fieldElement as LongField).SetValueWithoutNotify((long)veValueAbstract); } else if (attribute is UxmlBoolAttributeDescription && fieldElement is Toggle) { (fieldElement as Toggle).SetValueWithoutNotify((bool)veValueAbstract); } else if (attribute is UxmlColorAttributeDescription && fieldElement is ColorField) { (fieldElement as ColorField).SetValueWithoutNotify((Color)veValueAbstract); } else if (attributeType.IsGenericType && attributeType.GetGenericArguments()[0].IsEnum && fieldElement is EnumField) { var propInfo = attributeType.GetProperty("defaultValue"); var enumValue = propInfo.GetValue(attribute, null) as Enum; // Create and initialize the EnumField. var uiField = fieldElement as EnumField; // Set the value from the UXML attribute. var enumAttributeValueStr = vea?.GetAttributeValue(attribute.name); if (!string.IsNullOrEmpty(enumAttributeValueStr)) { var parsedValue = Enum.Parse(enumValue.GetType(), enumAttributeValueStr, true) as Enum; uiField.SetValueWithoutNotify(parsedValue); } } else if (fieldElement is TextField) { (fieldElement as TextField).SetValueWithoutNotify(veValueAbstract.ToString()); } // Determine if overridden. styleRow.RemoveFromClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); if (vea != null && attribute.name == "picking-mode") { var veaAttributeValue = vea.GetAttributeValue(attribute.name); if (veaAttributeValue != null && veaAttributeValue.ToLower() != attribute.defaultValueAsString.ToLower()) { styleRow.AddToClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); } } else if (attribute.name == "name") { if (!string.IsNullOrEmpty(currentVisualElement.name)) { styleRow.AddToClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); } } else if (vea != null && vea.HasAttribute(attribute.name)) { styleRow.AddToClassList(BuilderConstants.InspectorLocalStyleOverrideClassName); } }