// Copyright (c) Wojciech Figat. All rights reserved. #if USE_LARGE_WORLDS using RealValueBox = FlaxEditor.GUI.Input.DoubleValueBox; #else using RealValueBox = FlaxEditor.GUI.Input.FloatValueBox; #endif using FlaxEngine; using FlaxEngine.GUI; namespace FlaxEditor.Surface.Elements { /// /// Bounding Box value editing element. /// /// /// [HideInEditor] public sealed class BoxValue : ContainerControl, ISurfaceNodeElement { private RealValueBox _minX, _minY, _minZ, _maxX, _maxY, _maxZ; private const float BoxWidth = 50; private const float LabelWidth = 26; private const float MarginX = 2; private const float MarginY = 2; private const float SlideSpeed = 0.1f; /// public SurfaceNode ParentNode { get; } /// public NodeElementArchetype Archetype { get; } /// /// Gets the surface. /// public VisjectSurface Surface => ParentNode.Surface; /// /// Gets the value. /// public BoundingBox Value { get => new BoundingBox(new Vector3(_minX.Value, _minY.Value, _minZ.Value), new Vector3(_maxX.Value, _maxY.Value, _maxZ.Value)); set { _minX.Value = value.Minimum.X; _minY.Value = value.Minimum.Y; _minZ.Value = value.Minimum.Z; _maxX.Value = value.Maximum.X; _maxY.Value = value.Maximum.Y; _maxZ.Value = value.Maximum.Z; } } /// /// Initializes a new instance of the class. /// /// The parent node. /// The node element archetype. public BoxValue(SurfaceNode parentNode, NodeElementArchetype archetype) : base(archetype.Position.X, archetype.Position.Y, LabelWidth + (BoxWidth + MarginX) * 3, TextBox.DefaultHeight * 2 + MarginY) { ParentNode = parentNode; Archetype = archetype; AutoFocus = true; var back = Style.Current.TextBoxBackground; var grayOutFactor = 0.6f; var axisColorX = CustomEditors.Editors.ActorTransformEditor.AxisColorX; var axisColorY = CustomEditors.Editors.ActorTransformEditor.AxisColorY; var axisColorZ = CustomEditors.Editors.ActorTransformEditor.AxisColorZ; var value = Get(parentNode, archetype); float minX = 0; float minY = 0; var labelMin = new Label(minX, minY, LabelWidth, TextBox.DefaultHeight) { Text = "Min", HorizontalAlignment = TextAlignment.Near, Parent = this }; _minX = new RealValueBox(value.Minimum.X, LabelWidth, minY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorX, back, grayOutFactor), BorderSelectedColor = axisColorX, Parent = this }; _minX.ValueChanged += OnValueChanged; _minY = new RealValueBox(value.Minimum.Y, _minX.Right + MarginX, minY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorY, back, grayOutFactor), BorderSelectedColor = axisColorY, Parent = this }; _minY.ValueChanged += OnValueChanged; _minZ = new RealValueBox(value.Minimum.Z, _minY.Right + MarginX, minY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorZ, back, grayOutFactor), BorderSelectedColor = axisColorZ, Parent = this }; _minZ.ValueChanged += OnValueChanged; float maxX = 0; float maxY = labelMin.Bottom + MarginY; var labelMax = new Label(maxX, maxY, LabelWidth, TextBox.DefaultHeight) { Text = "Max", HorizontalAlignment = TextAlignment.Near, Parent = this }; _maxX = new RealValueBox(value.Maximum.X, LabelWidth, maxY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorX, back, grayOutFactor), BorderSelectedColor = axisColorX, Parent = this }; _maxX.ValueChanged += OnValueChanged; _maxY = new RealValueBox(value.Maximum.Y, _maxX.Right + MarginX, maxY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorY, back, grayOutFactor), BorderSelectedColor = axisColorY, Parent = this }; _maxY.ValueChanged += OnValueChanged; _maxZ = new RealValueBox(value.Maximum.Z, _maxY.Right + MarginX, maxY, BoxWidth, float.MinValue, float.MaxValue, SlideSpeed) { BorderColor = Color.Lerp(axisColorZ, back, grayOutFactor), BorderSelectedColor = axisColorZ, Parent = this }; _maxZ.ValueChanged += OnValueChanged; ParentNode.ValuesChanged += OnNodeValuesChanged; } private void OnNodeValuesChanged() { Value = Get(ParentNode, Archetype); } private void OnValueChanged() { var value = Value; Set(ParentNode, Archetype, ref 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 result value. public static BoundingBox Get(SurfaceNode parentNode, NodeElementArchetype arch) { if (arch.ValueIndex < 0) return BoundingBox.Empty; return (BoundingBox)parentNode.Values[arch.ValueIndex]; } /// /// 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, ref BoundingBox toSet) { if (arch.ValueIndex < 0) return; parentNode.SetValue(arch.ValueIndex, toSet); } } }