public static BindableElement CreateField <T>(string _label, Type _valueType, T _value, Action <object> _onValueChanged) { Type realValueType = _valueType; // 对字段类型进行修饰,UnityObject的子类型修饰为UnityObject // 枚举类型修饰为Enum if (!fieldDrawerCreatorMap.ContainsKey(_valueType)) { if (typeof(UnityObject).IsAssignableFrom(_valueType)) { _valueType = typeof(UnityObject); } else if (typeof(Enum).IsAssignableFrom(_valueType) && !fieldDrawerCreatorMap.ContainsKey(_valueType)) { _valueType = typeof(Enum); } } // LayerMask需单独创建 if (_value is LayerMask layerMask) { var layerField = new LayerMaskField(_label, layerMask.value); layerField.RegisterValueChangedCallback(e => { _onValueChanged(new LayerMask { value = e.newValue }); }); return(layerField); } if (_value is IList list) { Type elementType = null; if (_valueType.IsArray) { elementType = _valueType.GetElementType(); } else { Type type2 = _valueType; while (!type2.IsGenericType) { type2 = type2.BaseType; } elementType = type2.GetGenericArguments()[0]; } BindableElement bind = Activator.CreateInstance(typeof(ListField <,>).MakeGenericType(_valueType, elementType), _label, _value) as BindableElement; return(bind); } BindableElement fieldDrawer = null; var createFieldSpecificMethod = CreateFieldMethod.MakeGenericMethod(_valueType); fieldDrawer = createFieldSpecificMethod.Invoke(null, new object[] { _label, _value, realValueType, _onValueChanged }) as BindableElement; return(fieldDrawer); }
public static VisualElement GetElementOfLayerMaskField(LayerMask startValue, string fieldName, Action <object> setValue, Action <object> getValue) { LayerMaskField field = new LayerMaskField(fieldName, startValue); field.RegisterValueChangedCallback(s => setValue.Invoke(new LayerMask() { value = s.newValue })); return(field); }
void draw_grid_gui() { EditorGUI.indentLevel = 0; show_grid_config = EditorGUILayout.Foldout(show_grid_config, "Pathfinding Grid"); if (show_grid_config) { EditorGUI.indentLevel = 2; Ferr_EditorTools.Box(4, () => { //debug display config.grid_debug_display = EditorGUILayout.Toggle(new GUIContent("Debug display", "Displays and updates waypoint grid every frame and shows all terrain collider size offsets"), config.grid_debug_display); if (Application.isPlaying) { if (config.grid_last_debug_display != config.grid_debug_display && config.grid_debug_display) { Map.grid.recreate_grid(); } else { Map.grid.recalc_waypoint_nodes(); } } config.grid_last_debug_display = config.grid_debug_display; //point seperation config.grid_point_sep = EditorGUILayout.FloatField(new GUIContent("Point seperation", "Determines how far apart each point is from each other on the grid " + "(in world space units). The smaller the value, the more nodes there are on the pathfinding grid"), config.grid_point_sep); config.grid_point_sep = Mathf.Clamp(config.grid_point_sep, .25f, 5.0f); if (Application.isPlaying) { if (config.grid_last_point_sep != config.grid_point_sep) { Map.grid.recreate_grid(); } } config.grid_last_point_sep = config.grid_point_sep; //size offset config.grid_terrain_offset = EditorGUILayout.FloatField(new GUIContent("Size offset", "When checking whether an object is collidable or not on the grid, this value determines how much " + "larger the area around the terrain is (in world space units)"), config.grid_terrain_offset); //collidable layers config.grid_collidable_layers = LayerMaskField.draw("Collidable layers", config.grid_collidable_layers); }); } }
/// <summary> /// 绘制一个字段元素 /// </summary> /// <param name="label">字段名</param> /// <param name="valueType">类型</param> /// <param name="value">值</param> /// <param name="onValueChanged">字段改变回调</param> /// <returns></returns> public static VisualElement DrawField(string label, Type fieldType, object value, Action <object> onValueChanged) { //枚举单独处理(熟悉的操作) if (typeof(Enum).IsAssignableFrom(fieldType)) { fieldType = typeof(Enum); } VisualElement field = null; //这边处理特殊的字段 if (fieldType == typeof(LayerMask)) { var layerField = new LayerMaskField(label, ((LayerMask)value).value); layerField.RegisterValueChangedCallback(e => { onValueChanged(new LayerMask { value = e.newValue }); }); field = layerField; } else { try { var createFieldSpecificMethod = createFieldMethod.MakeGenericMethod(fieldType); try { field = createFieldSpecificMethod.Invoke(null, new object[] { value, onValueChanged, label }) as VisualElement; } catch { } // handle the Object field case if (field == null && (value == null || value is UnityEngine.Object)) { createFieldSpecificMethod = createFieldMethod.MakeGenericMethod(typeof(UnityEngine.Object)); field = createFieldSpecificMethod.Invoke(null, new object[] { value, onValueChanged, label }) as VisualElement; if (field is ObjectField objField) { objField.objectType = fieldType; objField.value = value as UnityEngine.Object; } } } catch (Exception e) { Debug.LogError(e); } } return(field); }
public static VisualElement CreateField(Type fieldType, object value, Action <object> onValueChanged, string label) { if (typeof(Enum).IsAssignableFrom(fieldType)) { fieldType = typeof(Enum); } VisualElement field = null; // Handle special cases here if (fieldType == typeof(LayerMask)) { // LayerMasks inherit from INotifyValueChanged<int> instead of INotifyValueChanged<LayerMask> // so we can't register it inside our factory system :( var layerField = new LayerMaskField(label, ((LayerMask)value).value); layerField.RegisterValueChangedCallback(e => { onValueChanged(new LayerMask { value = e.newValue }); }); field = layerField; } else { try { var createFieldSpecificMethod = createFieldMethod.MakeGenericMethod(fieldType); try { field = createFieldSpecificMethod.Invoke(null, new object[] { value, onValueChanged, label }) as VisualElement; } catch {} // handle the Object field case if (field == null && (value == null || value is UnityEngine.Object)) { createFieldSpecificMethod = createFieldMethod.MakeGenericMethod(typeof(UnityEngine.Object)); field = createFieldSpecificMethod.Invoke(null, new object[] { value, onValueChanged, label }) as VisualElement; if (field is ObjectField objField) { objField.objectType = fieldType; objField.value = value as UnityEngine.Object; } } } catch (Exception e) { Debug.LogError(e); } } return(field); }
void Init() { LayerMaskField field = new LayerMaskField() { value = config.value is LayerMask ? (LayerMask)config.value : default(LayerMask), }; field.EnableInClassList("compositeField", false); field.RegisterValueChangedCallback((e) => { config.OnValueChanged((LayerMask)e.newValue); MarkDirtyRepaint(); }); Add(field); }
internal override void Apply(VisualElement container) { /// <sample> // Get a reference to the field from UXML and assign it its value. var uxmlField = container.Q <LayerMaskField>("the-uxml-field"); uxmlField.value = 0; // Create a new field, disable it, and give it a style class. var csharpField = new LayerMaskField("C# Field"); csharpField.SetEnabled(false); csharpField.AddToClassList("some-styled-field"); csharpField.value = uxmlField.value; container.Add(csharpField); // Mirror value of uxml field into the C# field. uxmlField.RegisterCallback <ChangeEvent <int> >((evt) => { csharpField.value = evt.newValue; }); /// </sample> }
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); }
void CreateUIElements() { var titleRow = new VisualElement() { style = { flexDirection = FlexDirection.Row, flexShrink = 0f, justifyContent = Justify.SpaceBetween } }; m_VisualElementContainer.Add(new Label("VisualElements Container")); var curveX = AnimationCurve.Linear(0, 0, 1, 0); var popupFieldValues = new List <SomeClass> { new SomeClass("First Class Value"), new SomeClass("Second Value"), new SomeClass("Another Value"), new SomeClass("Another Value with a very lonnnnnnnnnnnnnnnnnnnnnnnnng text to make sure this is really overflowing the popup field.") }; var maskFieldOptions = new List <string>(m_MaskFieldOptions); m_VisualElementContainer.Add(m_IntegerField = new IntegerField()); m_VisualElementContainer.Add(m_LongField = new LongField()); m_VisualElementContainer.Add(m_FloatField = new FloatField()); m_VisualElementContainer.Add(m_DoubleField = new DoubleField()); m_VisualElementContainer.Add(m_EnumField = new EnumField(EnumValues.Two)); m_VisualElementContainer.Add(m_TextField = new TextField()); m_VisualElementContainer.Add(m_PasswordField = new TextField() { isPasswordField = true, maskChar = '*' }); m_VisualElementContainer.Add(m_Vector3Field = new Vector3Field()); m_VisualElementContainer.Add(m_Vector3IntField = new Vector3IntField()); m_VisualElementContainer.Add(m_Vector2Field = new Vector2Field()); m_VisualElementContainer.Add(m_ColorField = new ColorField()); m_VisualElementContainer.Add(m_ObjectFieldCamera = new ObjectField() { objectType = typeof(Camera) }); m_VisualElementContainer.Add(m_ObjectFieldGameObject = new ObjectField() { objectType = typeof(GameObject) }); m_VisualElementContainer.Add(m_CurveField = new CurveField() { value = curveX }); m_VisualElementContainer.Add(m_CurveFieldMesh = new CurveField() { value = curveX, renderMode = CurveField.RenderMode.Mesh }); m_VisualElementContainer.Add(m_PopupField = new PopupField <SomeClass>(popupFieldValues, popupFieldValues[1])); m_VisualElementContainer.Add(m_RectField = new RectField()); m_VisualElementContainer.Add(m_BoundsField = new BoundsField()); m_VisualElementContainer.Add(m_ToggleField = new Toggle()); m_VisualElementContainer.Add(m_MaskField = new MaskField(maskFieldOptions, 6)); m_VisualElementContainer.Add(m_LayerField = new LayerField()); m_VisualElementContainer.Add(m_TagField = new TagField()); m_VisualElementContainer.Add(m_MinMaxSliderField = new MinMaxSlider(5, 10, 0, 125)); m_VisualElementContainer.Add(m_Slider = new Slider(2, 8)); m_VisualElementContainer.Add(m_SliderInt = new SliderInt(11, 23)); var buttonRow = new VisualElement() { style = { flexDirection = FlexDirection.Row, flexShrink = 0f, } }; buttonRow.Add(new Button() { text = k_ButtonLeftTitle, style = { flexGrow = 1 } }); buttonRow.Add(new Button() { text = k_ButtonRightTitle, style = { flexGrow = 1 } }); m_VisualElementContainer.Add(buttonRow); m_VisualElementContainer.Add(new Button() { text = k_ButtonTopTitle }); m_VisualElementContainer.Add(new Button() { text = k_ButtonBottomTitle }); m_VisualElementContainer.Add(m_ColorField1 = new ColorField()); m_VisualElementContainer.Add(m_LayerMaskField = new LayerMaskField(0)); m_VisualElementContainer.Add(m_MultiLineTextField = new TextField() { multiline = true }); m_VisualElementContainer.Add(m_SliderProgressBar = new SliderInt()); m_VisualElementContainer.Add(m_ProgressBar = new ProgressBar()); m_ProgressBar.title = nameof(ProgressBar); m_SliderProgressBar.lowValue = 0; m_SliderProgressBar.highValue = 100; m_SliderProgressBar.bindingPath = nameof(SliderProgressTestObject.exampleValue); m_ProgressBar.bindingPath = nameof(SliderProgressTestObject.exampleValue); m_SliderProgressBar.Bind(SliderProgressTestSO); m_ProgressBar.Bind(SliderProgressTestSO); // The progress bar by itself does not contain any margin in IMGUI... // In this example, we are artifically adding the textfield margin to it. (see below, in the IMGUI section, ProgressBar()) m_ProgressBar.style.marginBottom = 2f; m_VisualElementContainer.Add(m_GradientField = new GradientField()); RefreshUIElements(); }
public static VisualElement CreateControl(FieldInfo fieldInfo, NodeView view, string label = null) { // This mess is similar to what Unity is doing for ShaderGraph. It's not great. // But the automatic alternatives depend on SerializableObject which is a performance bottleneck. // Ref: https://github.com/Unity-Technologies/ScriptableRenderPipeline/blob/master/com.unity.shadergraph/Editor/Drawing/Controls/DefaultControl.cs Type type = fieldInfo.FieldType; // Builtin unity type editors if (type == typeof(bool)) { return(BuildVal <Toggle, bool>(view, fieldInfo, label)); } if (type == typeof(int)) { return(BuildVal <IntegerField, int>(view, fieldInfo, label)); } if (type == typeof(float)) { return(BuildVal <FloatField, float>(view, fieldInfo, label)); } if (type == typeof(string)) { return(BuildVal <TextField, string>(view, fieldInfo, label)); } if (type == typeof(Rect)) { return(BuildVal <RectField, Rect>(view, fieldInfo, label)); } if (type == typeof(Color)) { return(BuildVal <ColorField, Color>(view, fieldInfo, label)); } if (type == typeof(Vector2)) { return(BuildVal <Vector2Field, Vector2>(view, fieldInfo, label)); } if (type == typeof(Vector3)) { return(BuildVal <Vector3Field, Vector3>(view, fieldInfo, label)); } if (type == typeof(Vector4)) { return(BuildVal <Vector4Field, Vector4>(view, fieldInfo, label)); } if (type == typeof(Gradient)) { return(BuildVal <GradientField, Gradient>(view, fieldInfo, label)); } if (type == typeof(AnimationCurve)) { return(BuildVal <CurveField, AnimationCurve>(view, fieldInfo, label)); } if (type == typeof(LayerMask)) { var value = ((LayerMask)fieldInfo.GetValue(view.Target)).value; var field = new LayerMaskField(label, value); field.RegisterValueChangedCallback((change) => { fieldInfo.SetValue(view.Target, (LayerMask)change.newValue); view.Target.Validate(); view.OnPropertyChange(); }); return(field); } // Implementation (rather than just using EnumField) comes from: // https://github.com/Unity-Technologies/UnityCsReference/blob/1e8347ec4cbda9e8a4929e42a20f39df9bbab9d9/Editor/Mono/UIElements/Controls/PropertyField.cs#L306-L323 if (typeof(Enum).IsAssignableFrom(type)) { var choices = new List <string>(type.GetEnumNames()); var defaultIndex = (int)fieldInfo.GetValue(view.Target); if (type.IsDefined(typeof(FlagsAttribute), false)) { var field = new EnumFlagsField(label, (Enum)fieldInfo.GetValue(view.Target)); field.RegisterValueChangedCallback((change) => { fieldInfo.SetValue(view.Target, change.newValue); view.OnPropertyChange(); }); return(field); } else { var field = new PopupField <string>(label, choices, defaultIndex); field.RegisterValueChangedCallback((change) => { fieldInfo.SetValue(view.Target, field.index); view.OnPropertyChange(); }); return(field); } } // Specialized construct so I can set .objectType on the ObjectField if (typeof(UnityEngine.Object).IsAssignableFrom(type)) { var field = BuildRef <ObjectField, UnityEngine.Object>(view, fieldInfo, label) as ObjectField; if (field != null) { field.objectType = type; } return(field); } // TODO: EnumFlags/Masks (we have MaskField - how do we detect mask types?) // TODO: Specialized common types. Transform, Rotation, Texture2D, etc. // TODO: Custom plugin types return(null); }
private void CreateUI() { _ChangeCheck = new ChangeCheck(); _ChangeCheck.ColumnDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _ChangeCheck.ColumnDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _ChangeCheck.RowDefinitions.Add(24, Skill.Framework.UI.GridUnitType.Pixel); // _BtnAdd , _BtnRemove _ChangeCheck.RowDefinitions.Add(164, Skill.Framework.UI.GridUnitType.Pixel); // _PointsScrollView _ChangeCheck.RowDefinitions.Add(86, Skill.Framework.UI.GridUnitType.Pixel); // _PnlPoperties _ChangeCheck.RowDefinitions.Add(130, Skill.Framework.UI.GridUnitType.Pixel); //_PnlTools _BtnAdd = new Button() { Row = 0, Column = 0 }; _BtnAdd.Content.text = "Add"; _BtnAdd.Content.tooltip = "Add new point the end of the path."; _BtnAdd.Content.image = Resources.UITextures.Plus; _BtnRemove = new Button() { Row = 0, Column = 1 }; _BtnRemove.Content.text = "Remove"; _BtnRemove.Content.tooltip = "Remove selected point."; _BtnRemove.Content.image = Resources.UITextures.Minus; _PointsScrollView = new Skill.Framework.UI.ScrollView() { Row = 1, Column = 0, ColumnSpan = 2, AlwayShowVertical = true, Padding = new Skill.Framework.UI.Thickness(0, 2) }; _GridPoints = new Skill.Framework.UI.SelectionGrid() { XCount = 5 }; _PointsScrollView.Controls.Add(_GridPoints); _PointsScrollView.RenderAreaChanged += _PointsScrollView_RenderAreaChanged; _SelectedPointPropertiesBackground = new Skill.Framework.UI.Box() { Row = 2, Column = 0, ColumnSpan = 2 }; _PnlPoperties = new Skill.Framework.UI.StackPanel() { Row = 2, Column = 0, ColumnSpan = 2, Orientation = Skill.Framework.UI.Orientation.Vertical, Padding = new Skill.Framework.UI.Thickness(2) }; _FFTime = new FloatField() { Height = 16, Margin = new Skill.Framework.UI.Thickness(0, 2, 0, 4) }; _FFTime.Label.text = "Time"; _VFValue = new Vector3Field() { Height = 20 }; _VFValue.Label.text = "Position"; _VFInTangent = new Vector3Field() { Height = 20 }; _VFInTangent.Label.text = "InTangent"; _VFOutTangent = new Vector3Field() { Height = 20 }; _VFOutTangent.Label.text = "OutTangent"; _PnlPoperties.Controls.Add(_FFTime); _PnlPoperties.Controls.Add(_VFValue); _PnlPoperties.Controls.Add(_VFInTangent); _PnlPoperties.Controls.Add(_VFOutTangent); _PnlTools = new Skill.Framework.UI.Grid() { Row = 5, Column = 0, ColumnSpan = 2, Padding = new Skill.Framework.UI.Thickness(2) }; _PnlTools.ColumnDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _PnlTools.ColumnDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _PnlTools.ColumnDefinitions.Add(2, Skill.Framework.UI.GridUnitType.Star); _PnlTools.RowDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); // _LmGroundLayer _PnlTools.RowDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); // _BtnGroundAll , _BtnGroundSelected _PnlTools.RowDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); // _LblFLinearTime _PnlTools.RowDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _PnlTools.RowDefinitions.Add(1, Skill.Framework.UI.GridUnitType.Star); _LmGroundLayer = new LayerMaskField() { Row = 0, Column = 0, ColumnSpan = 3, Layers = _Path.GroundLayer, Margin = new Framework.UI.Thickness(2) }; _LmGroundLayer.Label.text = "Ground Layer"; _BtnGroundSelected = new Button() { Row = 1, Column = 0, ColumnSpan = 2, Margin = new Skill.Framework.UI.Thickness(2, 2) }; _BtnGroundSelected.Content.text = "Ground Selected"; _BtnGroundSelected.Content.tooltip = "put selected on ground"; _BtnGroundAll = new Button() { Row = 1, Column = 2, Margin = new Skill.Framework.UI.Thickness(2, 2) }; _BtnGroundAll.Content.text = "Ground All"; _BtnGroundAll.Content.tooltip = "put all points on ground"; _LblFLinearTime = new LabelField() { Row = 2, Column = 0, Margin = new Skill.Framework.UI.Thickness(0, 2) }; _LblFLinearTime.Label.text = "Time"; _FFLinearTime = new FloatField() { Row = 2, Column = 1, Margin = new Skill.Framework.UI.Thickness(0, 2), Value = _Path.PathTime }; _BtnSetLinearTime = new Button() { Row = 2, Column = 2, Margin = new Skill.Framework.UI.Thickness(2, 2) }; _BtnSetLinearTime.Content.text = "Set Time by Distance"; _BtnSetLinearTime.Content.tooltip = "Set time of nodes by relative distance"; _SliSmoothValue = new Skill.Editor.UI.Slider() { Row = 3, Column = 0, ColumnSpan = 3, MinValue = 0.0f, MaxValue = 1.0f, Value = _Path.SmoothValue }; _SliSmoothValue.Label.text = "Smooth Value"; _BtnSmoothCurve = new Button() { Row = 4, Column = 0, ColumnSpan = 2, Margin = new Skill.Framework.UI.Thickness(2, 2) }; _BtnSmoothCurve.Content.text = "Smooth Curve"; _BtnSmoothCurve.Content.tooltip = "Smooth the in and out tangents of the keys."; _BtnSmoothPoint = new Button() { Row = 4, Column = 2, Margin = new Skill.Framework.UI.Thickness(2, 2) }; _BtnSmoothPoint.Content.text = "Smooth Point"; _BtnSmoothPoint.Content.tooltip = "Smooth the in and out tangents of the selected key."; _PnlTools.Controls.Add(_LmGroundLayer); _PnlTools.Controls.Add(_BtnGroundSelected); _PnlTools.Controls.Add(_BtnGroundAll); _PnlTools.Controls.Add(_LblFLinearTime); _PnlTools.Controls.Add(_FFLinearTime); _PnlTools.Controls.Add(_BtnSetLinearTime); _PnlTools.Controls.Add(_SliSmoothValue); _PnlTools.Controls.Add(_BtnSmoothPoint); _PnlTools.Controls.Add(_BtnSmoothCurve); _ChangeCheck.Controls.Add(_BtnAdd); _ChangeCheck.Controls.Add(_BtnRemove); _ChangeCheck.Controls.Add(_PointsScrollView); _ChangeCheck.Controls.Add(_SelectedPointPropertiesBackground); _ChangeCheck.Controls.Add(_PnlPoperties); _ChangeCheck.Controls.Add(_PnlTools); _Frame = new Skill.Framework.UI.Frame("EditorFrame"); _Frame.Grid.Controls.Add(_ChangeCheck); _BtnAdd.Click += _BtnAdd_Click; _BtnRemove.Click += _BtnRemove_Click; _ChangeCheck.Changed += _ChangeCheck_Changed; _GridPoints.SelectedChanged += _GridPoints_SelectedChanged; _FFTime.ValueChanged += SelectedPoint_ValueChanged; _VFValue.ValueChanged += SelectedPoint_ValueChanged; _VFInTangent.ValueChanged += SelectedPoint_ValueChanged; _VFOutTangent.ValueChanged += SelectedPoint_ValueChanged; _FFLinearTime.ValueChanged += _FFLinearTime_ValueChanged; _BtnSmoothPoint.Click += _BtnSmoothPoint_Click; _BtnSmoothCurve.Click += _BtnSmoothCurve_Click; _BtnSetLinearTime.Click += _BtnSetLinearTime_Click; _SliSmoothValue.ValueChanged += _SliSmoothValue_ValueChanged; _LmGroundLayer.LayersChanged += _LmGroundLayer_LayersChanged; _BtnGroundSelected.Click += _BtnGroundSelected_Click; _BtnGroundAll.Click += _BtnGroundAll_Click; }
private void RefreshUI() { rootVisualElement.Clear(); VisualElement topRowElement = new VisualElement(); topRowElement.AddToClassList("svbm-row"); rootVisualElement.Add(topRowElement); Button refreshButton = new Button(RefreshUI) { name = "Refresh", text = "Refresh" }; refreshButton.AddToClassList("svbm-cell"); topRowElement.Add(refreshButton); Button saveButton = new Button(() => Bookmarks.Instance?.SaveToJson(Bookmarks.path)) { name = "Save", text = "Save" }; saveButton.AddToClassList("svbm-cell"); topRowElement.Add(saveButton); IMGUIContainer header = new IMGUIContainer(OnCustomGUI); header.AddToClassList("sceneLightingButton"); rootVisualElement.Add(header); if (Bookmarks.Count == 0) { return; } for (int i = 0; i < Bookmarks.Count; i++) { var index = i; VisualElement bookmarkElement = new VisualElement(); bookmarkElement.AddToClassList("svbm-row"); Button loadButton = new Button(() => Bookmarks.Instance[index].Load(SceneView.lastActiveSceneView)) { name = "LOAD", text = "LOAD" }; loadButton.AddToClassList("svbm-cell-button"); bookmarkElement.Add(loadButton); Button updateButton = new Button(() => Bookmarks.Instance[index].Save(SceneView.lastActiveSceneView)) { name = "UPDATE", text = "UPDATE" }; updateButton.AddToClassList("svbm-cell-button"); bookmarkElement.Add(updateButton); Button deleteButton = new Button(() => { Bookmarks.Instance.viewpoints.RemoveAt(index); RefreshUI(); }) { name = "DELETE", text = "DELETE" }; deleteButton.AddToClassList("svbm-cell-button"); bookmarkElement.Add(deleteButton); TextField nameField = new TextField("") { tooltip = "Set this bookmark's menu path / name.\nUse '/' to create a submenu." }; nameField.value = Bookmarks.Instance[index].name; nameField.AddToClassList("svbm-cell-text"); nameField.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].name = x.newValue); bookmarkElement.Add(nameField); MaskField overridesMask = new MaskField(Enum.GetNames(typeof(Viewpoint.Overrides)).ToList(), (int)Bookmarks.Instance[index].overrides) { tooltip = "Set this bookmark's Overrides." }; overridesMask.AddToClassList("svbm-cell-mask"); overridesMask.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].overrides = (Viewpoint.Overrides)x.newValue); bookmarkElement.Add(overridesMask); Toggle orthoToggle = new Toggle("") { tooltip = "Enable to set this bookmark's SceneView to Orthographic." }; orthoToggle.value = Bookmarks.Instance[index].settings.ortho; orthoToggle.AddToClassList("svbm-cell-checkbox"); orthoToggle.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.ortho = x.newValue); bookmarkElement.Add(orthoToggle); Toggle is2dToggle = new Toggle("") { tooltip = "Enable to set this bookmark's SceneView to 2D Mode." }; is2dToggle.value = Bookmarks.Instance[index].settings.is2D; is2dToggle.AddToClassList("svbm-cell-checkbox"); is2dToggle.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.is2D = x.newValue); bookmarkElement.Add(is2dToggle); FloatField fovField = new FloatField() { tooltip = "Set this bookmark's Camera Field of View." }; fovField.value = Bookmarks.Instance[index].settings.fov; fovField.AddToClassList("svbm-cell-float"); fovField.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.fov = Mathf.Clamp(x.newValue, 4, 120)); bookmarkElement.Add(fovField); EnumField cameraModeMask = new EnumField("", Bookmarks.Instance[index].settings.mode.drawMode) { tooltip = "Set this bookmark's Camera Shading Mode." }; cameraModeMask.AddToClassList("svbm-cell-mask"); // Catching cases where SceneView.GetBuiltinCameraMode() will fail on some DrawCameraMode such as Normal and User Defined cameraModeMask.RegisterValueChangedCallback((x) => { try { Bookmarks.Instance[index].settings.mode = SceneView.GetBuiltinCameraMode((DrawCameraMode)x.newValue); } catch { cameraModeMask.SetValueWithoutNotify(x.previousValue); } }); bookmarkElement.Add(cameraModeMask); Toggle lightingToggle = new Toggle("") { tooltip = "Enable this bookmark's SceneView Lighting." }; lightingToggle.value = Bookmarks.Instance[index].settings.sceneLighting; lightingToggle.AddToClassList("svbm-cell-checkbox"); lightingToggle.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.sceneLighting = x.newValue); bookmarkElement.Add(lightingToggle); MaskField viewStatesMask = new MaskField(SceneViewStatesLabels, (int)Bookmarks.Instance[index].settings.sceneViewState.GetFlags()) { tooltip = "Set this bookmark's SceneView States." }; viewStatesMask.AddToClassList("svbm-cell-mask"); viewStatesMask.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.sceneViewState.SetFlags((SceneViewExtensions.SceneViewStateFlags)x.newValue)); bookmarkElement.Add(viewStatesMask); Toggle gridToggle = new Toggle("") { tooltip = "Enable this bookmark's SceneView Grid." }; gridToggle.value = Bookmarks.Instance[index].settings.showGrid; gridToggle.AddToClassList("svbm-cell-checkbox"); gridToggle.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.showGrid = x.newValue); bookmarkElement.Add(gridToggle); Toggle gizmosToggle = new Toggle("") { tooltip = "Enable this bookmark's SceneView Gizmos." }; gizmosToggle.value = Bookmarks.Instance[index].settings.drawGizmos; gizmosToggle.AddToClassList("svbm-cell-checkbox"); gizmosToggle.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].settings.drawGizmos = x.newValue); bookmarkElement.Add(gizmosToggle); LayerMaskField visibleLayerMask = new LayerMaskField("", Bookmarks.Instance[index].visibleLayers) { tooltip = "Set this bookmark's Visible Layers." }; visibleLayerMask.AddToClassList("svbm-cell-mask"); visibleLayerMask.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].visibleLayers = x.newValue); bookmarkElement.Add(visibleLayerMask); LayerMaskField lockedLayerMask = new LayerMaskField("", Bookmarks.Instance[index].lockedLayers) { tooltip = "Set this bookmark's Locked Layers." }; lockedLayerMask.AddToClassList("svbm-cell-mask"); lockedLayerMask.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].lockedLayers = x.newValue); bookmarkElement.Add(lockedLayerMask); EnumField shortcutMask = new EnumField("", Bookmarks.Instance[index].shortcut) { tooltip = "Set this bookmark's shortcut\nBeware this will override any other function the shortcut is associated with." }; shortcutMask.AddToClassList("svbm-cell-mask"); shortcutMask.RegisterValueChangedCallback((x) => Bookmarks.Instance[index].shortcut = (KeyCode)x.newValue); bookmarkElement.Add(shortcutMask); Button moveUpButton = new Button(() => { if (index <= 0) { return; } var item = Bookmarks.Instance.viewpoints[index]; Bookmarks.Instance.viewpoints.RemoveAt(index); Bookmarks.Instance.viewpoints.Insert(index - 1, item); RefreshUI(); }) { name = "Up", text = "Up" }; moveUpButton.AddToClassList("svbm-cell-button"); bookmarkElement.Add(moveUpButton); Button moveDownButton = new Button(() => { if (index >= Bookmarks.Instance.viewpoints.Count - 1) { return; } var item = Bookmarks.Instance.viewpoints[index]; Bookmarks.Instance.viewpoints.RemoveAt(index); Bookmarks.Instance.viewpoints.Insert(index + 1, item); RefreshUI(); }) { name = "Down", text = "Dn" }; moveDownButton.AddToClassList("svbm-cell-button"); bookmarkElement.Add(moveDownButton); rootVisualElement.Add(bookmarkElement); } }