// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. using FlaxEditor.GUI.Input; using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.Surface.Elements { /// /// Floating point value editing element. /// /// /// [HideInEditor] public sealed class FloatValue : FloatValueBox, ISurfaceNodeElement { /// public SurfaceNode ParentNode { get; } /// public NodeElementArchetype Archetype { get; } /// /// Gets the surface. /// public VisjectSurface Surface => ParentNode.Surface; /// public FloatValue(SurfaceNode parentNode, NodeElementArchetype archetype) : base(Get(parentNode, archetype), archetype.Position.X, archetype.Position.Y, 50, archetype.ValueMin, archetype.ValueMax, 0.01f) { ParentNode = parentNode; Archetype = archetype; ParentNode.ValuesChanged += OnNodeValuesChanged; // Disable slider if surface doesn't allow it if (ParentNode.Surface != null && !ParentNode.Surface.CanLivePreviewValueChanges) _slideSpeed = 0.0f; } private void OnNodeValuesChanged() { Value = Get(ParentNode, Archetype); } /// public override void Draw() { base.Draw(); // Draw border if (!IsFocused) Render2D.DrawRectangle(new Rectangle(Float2.Zero, Size), Style.Current.BorderNormal); } /// protected override void OnValueChanged() { base.OnValueChanged(); Set(ParentNode, Archetype, Value); } /// /// Gets the floating point value from the specified parent node. Handles type casting and components gather. /// /// The parent node. /// The node element archetype. /// The custom value override (optional). /// The result value. public static float Get(SurfaceNode parentNode, NodeElementArchetype arch, object customValue = null) { if (arch.ValueIndex < 0 && customValue == null) return 0; float result; var value = customValue ?? parentNode.Values[arch.ValueIndex]; // Note: this value box may edit on component of the vector like Vector3.Y, BoxID from Archetype tells which component pick if (value is int asInt) { result = (float)asInt; } else if (value is float asFloat) { result = asFloat; } else if (value is double asDouble) { result = (float)asDouble; } else if (value is Vector2 asVector2) { result = (float)(arch.BoxID == 0 ? asVector2.X : asVector2.Y); } else if (value is Vector3 asVector3) { result = (float)(arch.BoxID == 0 ? asVector3.X : arch.BoxID == 1 ? asVector3.Y : asVector3.Z); } else if (value is Vector4 asVector4) { result = (float)(arch.BoxID == 0 ? asVector4.X : arch.BoxID == 1 ? asVector4.Y : arch.BoxID == 2 ? asVector4.Z : asVector4.W); } else if (value is Float2 asFloat2) { result = (arch.BoxID == 0 ? asFloat2.X : asFloat2.Y); } else if (value is Float3 asFloat3) { result = (arch.BoxID == 0 ? asFloat3.X : arch.BoxID == 1 ? asFloat3.Y : asFloat3.Z); } else if (value is Float4 asFloat4) { result = (arch.BoxID == 0 ? asFloat4.X : arch.BoxID == 1 ? asFloat4.Y : arch.BoxID == 2 ? asFloat4.Z : asFloat4.W); } else if (value is Double2 asDouble2) { result = (float)(arch.BoxID == 0 ? asDouble2.X : asDouble2.Y); } else if (value is Double3 asDouble3) { result = (float)(arch.BoxID == 0 ? asDouble3.X : arch.BoxID == 1 ? asDouble3.Y : asDouble3.Z); } else if (value is Double4 asDouble4) { result = (float)(arch.BoxID == 0 ? asDouble4.X : arch.BoxID == 1 ? asDouble4.Y : arch.BoxID == 2 ? asDouble4.Z : asDouble4.W); } else { result = 0; } return result; } /// /// Sets the floating point value of the specified parent node. Handles type casting and components assignment. /// /// The parent node. /// The node element archetype. /// The value to set. public static void Set(SurfaceNode parentNode, NodeElementArchetype arch, float toSet) { if (arch.ValueIndex < 0) return; var value = parentNode.Values[arch.ValueIndex]; if (value is int) { value = (int)toSet; } else if (value is float) { value = toSet; } else if (value is double) { value = (double)toSet; } else if (parentNode.GroupArchetype.GroupID != 2) { // Per-component editing is used only by nodes from Constant group, otherwise use float value = toSet; } else if (value is Vector2 asVector2) { if (arch.BoxID == 0) asVector2.X = toSet; else asVector2.Y = toSet; value = asVector2; } else if (value is Vector3 asVector3) { if (arch.BoxID == 0) asVector3.X = toSet; else if (arch.BoxID == 1) asVector3.Y = toSet; else asVector3.Z = toSet; value = asVector3; } else if (value is Vector4 asVector4) { if (arch.BoxID == 0) asVector4.X = toSet; else if (arch.BoxID == 1) asVector4.Y = toSet; else if (arch.BoxID == 2) asVector4.Z = toSet; else asVector4.W = toSet; value = asVector4; } else if (value is Float2 asFloat2) { if (arch.BoxID == 0) asFloat2.X = toSet; else asFloat2.Y = toSet; value = asFloat2; } else if (value is Float3 asFloat3) { if (arch.BoxID == 0) asFloat3.X = toSet; else if (arch.BoxID == 1) asFloat3.Y = toSet; else asFloat3.Z = toSet; value = asFloat3; } else if (value is Float4 asFloat4) { if (arch.BoxID == 0) asFloat4.X = toSet; else if (arch.BoxID == 1) asFloat4.Y = toSet; else if (arch.BoxID == 2) asFloat4.Z = toSet; else asFloat4.W = toSet; value = asFloat4; } else if (value is Double2 asDouble2) { if (arch.BoxID == 0) asDouble2.X = toSet; else asDouble2.Y = toSet; value = asDouble2; } else if (value is Double3 asDouble3) { if (arch.BoxID == 0) asDouble3.X = toSet; else if (arch.BoxID == 1) asDouble3.Y = toSet; else asDouble3.Z = toSet; value = asDouble3; } else if (value is Double4 asDouble4) { if (arch.BoxID == 0) asDouble4.X = toSet; else if (arch.BoxID == 1) asDouble4.Y = toSet; else if (arch.BoxID == 2) asDouble4.Z = toSet; else asDouble4.W = toSet; value = asDouble4; } else { value = 0; } parentNode.SetValue(arch.ValueIndex, value); } /// /// Sets all the values to the given value (eg. all components of the vector). /// /// The parent node. /// The node element archetype. /// The value to assign. public static void SetAllValues(SurfaceNode parentNode, NodeElementArchetype arch, float toSet) { if (arch.ValueIndex < 0) return; var value = parentNode.Values[arch.ValueIndex]; if (value is int) { value = (int)toSet; } else if (value is float) { value = toSet; } else if (value is double) { value = (double)toSet; } else if (value is Vector2) { value = new Vector2(toSet); } else if (value is Vector3) { value = new Vector3(toSet); } else if (value is Vector4) { value = new Vector4(toSet); } else if (value is Float2) { value = new Float2(toSet); } else if (value is Float3) { value = new Float3(toSet); } else if (value is Float4) { value = new Float4(toSet); } else if (value is Double2) { value = new Double2(toSet); } else if (value is Double3) { value = new Double3(toSet); } else if (value is Double4) { value = new Double4(toSet); } else { value = 0; } parentNode.SetValue(arch.ValueIndex, value); } } }