// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using FlaxEditor.CustomEditors.Editors;
using FlaxEditor.GUI;
using FlaxEditor.GUI.Input;
using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.Surface.Elements
{
///
/// The handler for the input box default value editing. Used to display the default to the UI.
///
[HideInEditor]
public interface IDefaultValueEditor
{
///
/// Checks if the handles supports the given type.
///
/// The input box that uses this editor.
/// The type to check.
/// True if can create UI for this type editing, otherwise false.
bool CanUse(InputBox box, ref ScriptType type);
///
/// Creates the UI for the value editing.
///
/// The input box that uses this editor.
/// The control bounds (control can be smaller but cannot be bigger).
/// The root control of the created UI
Control Create(InputBox box, ref Rectangle bounds);
///
/// Returns true if given control is valid root editor for the value.
///
/// The input box that uses this editor.
/// The root control of the editor UI.
/// true if the specified control is valid; otherwise, false.
bool IsValid(InputBox box, Control control);
///
/// Updates the default value editor UI value.
///
/// The input box that uses this editor.
/// The root control of the editor UI.
void UpdateDefaultValue(InputBox box, Control control);
///
/// Updates the UI after box attributes change.
///
/// The input box that uses this editor.
/// The custom attributes collection.
/// The root control of the editor UI.
void UpdateAttributes(InputBox box, object[] attributes, Control control);
}
class BooleanDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(bool);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = BoolValue.Get(box.ParentNode, box.Archetype);
var control = new CheckBox(bounds.X, bounds.Y, value, bounds.Height)
{
Parent = box.Parent,
Tag = box,
};
control.StateChanged += OnCheckboxStateChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is CheckBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is CheckBox checkBox)
{
checkBox.Checked = BoolValue.Get(box.ParentNode, box.Archetype);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private void OnCheckboxStateChanged(CheckBox control)
{
var box = (InputBox)control.Tag;
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.Checked);
}
}
class IntegerDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(int);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = IntegerValue.Get(box.ParentNode, box.Archetype);
var control = new IntValueBox(value, bounds.X, bounds.Y, 40, int.MinValue, int.MaxValue, 0.01f)
{
Height = bounds.Height,
Parent = box.Parent,
Tag = box,
};
control.BoxValueChanged += OnIntValueBoxChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is IntValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is IntValueBox intValue)
{
intValue.Value = IntegerValue.Get(box.ParentNode, box.Archetype);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private void OnIntValueBoxChanged(ValueBox control)
{
var box = (InputBox)control.Tag;
IntegerValue.Set(box.ParentNode, box.Archetype, control.Value);
}
}
class UnsignedIntegerDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(uint);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = UnsignedIntegerValue.Get(box.ParentNode, box.Archetype);
var control = new UIntValueBox(value, bounds.X, bounds.Y, 40, uint.MinValue, uint.MaxValue, 0.01f)
{
Height = bounds.Height,
Parent = box.Parent,
Tag = box,
};
control.BoxValueChanged += OnValueBoxChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is UIntValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is UIntValueBox intValue)
{
intValue.Value = UnsignedIntegerValue.Get(box.ParentNode, box.Archetype);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private void OnValueBoxChanged(ValueBox control)
{
var box = (InputBox)control.Tag;
UnsignedIntegerValue.Set(box.ParentNode, box.Archetype, control.Value);
}
}
class FloatingDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(float) || type.Type == typeof(double);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = FloatValue.Get(box.ParentNode, box.Archetype);
var control = new FloatValueBox(value, bounds.X, bounds.Y, 40, float.MinValue, float.MaxValue, 0.01f)
{
Height = bounds.Height,
Parent = box.Parent,
Tag = box,
};
control.BoxValueChanged += OnFloatValueBoxChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is FloatValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is FloatValueBox floatValue)
{
floatValue.Value = FloatValue.Get(box.ParentNode, box.Archetype);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private void OnFloatValueBoxChanged(ValueBox control)
{
var box = (InputBox)control.Tag;
FloatValue.Set(box.ParentNode, box.Archetype, control.Value);
}
}
class StringDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(string) && (box.Attributes == null || box.Attributes.All(x => x.GetType() != typeof(TypeReferenceAttribute)));
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = box.ParentNode.Values[box.Archetype.ValueIndex] as string;
var control = new TextBox(false, bounds.X, bounds.Y, 40)
{
Text = value,
Height = bounds.Height,
Parent = box.Parent,
Tag = box,
};
control.TextBoxEditEnd += OnTextBoxTextChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is TextBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is TextBox textBox)
{
textBox.Text = box.ParentNode.Values[box.Archetype.ValueIndex] as string;
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private void OnTextBoxTextChanged(TextBoxBase control)
{
var box = (InputBox)control.Tag;
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.Text);
}
}
class Vector2DefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(Vector2);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new ContainerControl(bounds.X, bounds.Y, 22 * 2 - 2, bounds.Height)
{
ClipChildren = false,
AutoFocus = false,
Parent = box.Parent,
Tag = box,
};
var floatX = new FloatValueBox(value.X, 0, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatX.BoxValueChanged += OnVector2ValueChanged;
var floatY = new FloatValueBox(value.Y, 22, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatY.BoxValueChanged += OnVector2ValueChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is ContainerControl vec2
&& vec2.ChildrenCount == 2
&& vec2.Children[0] is FloatValueBox
&& vec2.Children[1] is FloatValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is ContainerControl vec2
&& vec2.Tag as Type == typeof(Vector2)
&& vec2.ChildrenCount == 2
&& vec2.Children[0] is FloatValueBox x
&& vec2.Children[1] is FloatValueBox y)
{
var value = GetValue(box);
x.Value = value.X;
y.Value = value.Y;
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private Vector2 GetValue(InputBox box)
{
var value = Vector2.Zero;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Vector2 vec2)
value = vec2;
else if (v is Vector3 vec3)
value = new Vector2(vec3);
else if (v is Vector4 vec4)
value = new Vector2(vec4);
else if (v is Color col)
value = new Vector2(col.R, col.G);
else if (v is float f)
value = new Vector2(f);
else if (v is int i)
value = new Vector2(i);
return value;
}
private void OnVector2ValueChanged(ValueBox valueBox)
{
var control = valueBox.Parent;
var box = (InputBox)control.Tag;
var x = ((FloatValueBox)control.Children[0]).Value;
var y = ((FloatValueBox)control.Children[1]).Value;
box.ParentNode.SetValue(box.Archetype.ValueIndex, new Vector2(x, y));
}
}
class Vector3DefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(Vector3);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new ContainerControl(bounds.X, bounds.Y, 22 * 3 - 2, bounds.Height)
{
ClipChildren = false,
AutoFocus = false,
Parent = box.Parent,
Tag = box,
};
var floatX = new FloatValueBox(value.X, 0, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatX.BoxValueChanged += OnVector3ValueChanged;
var floatY = new FloatValueBox(value.Y, 22, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatY.BoxValueChanged += OnVector3ValueChanged;
var floatZ = new FloatValueBox(value.Z, 44, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatZ.BoxValueChanged += OnVector3ValueChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is ContainerControl vec3
&& vec3.ChildrenCount == 3
&& vec3.Children[0] is FloatValueBox
&& vec3.Children[1] is FloatValueBox
&& vec3.Children[2] is FloatValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is ContainerControl vec3
&& vec3.ChildrenCount == 3
&& vec3.Children[0] is FloatValueBox x
&& vec3.Children[1] is FloatValueBox y
&& vec3.Children[2] is FloatValueBox z)
{
var value = GetValue(box);
x.Value = value.X;
y.Value = value.Y;
z.Value = value.Z;
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private Vector3 GetValue(InputBox box)
{
var value = Vector3.Zero;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Vector2 vec2)
value = new Vector3(vec2, 0.0f);
else if (v is Vector3 vec3)
value = vec3;
else if (v is Vector4 vec4)
value = new Vector3(vec4);
else if (v is Color col)
value = col;
else if (v is float f)
value = new Vector3(f);
else if (v is int i)
value = new Vector3(i);
return value;
}
private void OnVector3ValueChanged(ValueBox valueBox)
{
var control = valueBox.Parent;
var box = (InputBox)control.Tag;
var x = ((FloatValueBox)control.Children[0]).Value;
var y = ((FloatValueBox)control.Children[1]).Value;
var z = ((FloatValueBox)control.Children[2]).Value;
box.ParentNode.SetValue(box.Archetype.ValueIndex, new Vector3(x, y, z));
}
}
class Vector4DefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(Vector4);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new ContainerControl(bounds.X, bounds.Y, 22 * 4 - 2, bounds.Height)
{
ClipChildren = false,
AutoFocus = false,
Parent = box.Parent,
Tag = box,
};
var floatX = new FloatValueBox(value.X, 0, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatX.BoxValueChanged += OnVector4ValueChanged;
var floatY = new FloatValueBox(value.Y, 22, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatY.BoxValueChanged += OnVector4ValueChanged;
var floatZ = new FloatValueBox(value.Z, 44, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatZ.BoxValueChanged += OnVector4ValueChanged;
var floatW = new FloatValueBox(value.W, 66, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatW.BoxValueChanged += OnVector4ValueChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is ContainerControl vec4
&& vec4.ChildrenCount == 4
&& vec4.Children[0] is FloatValueBox
&& vec4.Children[1] is FloatValueBox
&& vec4.Children[2] is FloatValueBox
&& vec4.Children[3] is FloatValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is ContainerControl vec4
&& vec4.ChildrenCount == 4
&& vec4.Children[0] is FloatValueBox x
&& vec4.Children[1] is FloatValueBox y
&& vec4.Children[2] is FloatValueBox z
&& vec4.Children[3] is FloatValueBox w)
{
var value = GetValue(box);
x.Value = value.X;
y.Value = value.Y;
z.Value = value.Z;
w.Value = value.W;
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private Vector4 GetValue(InputBox box)
{
var value = Vector4.Zero;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Vector2 vec2)
value = new Vector4(vec2, 0.0f, 0.0f);
else if (v is Vector3 vec3)
value = new Vector4(vec3, 0.0f);
else if (v is Vector4 vec4)
value = vec4;
else if (v is Color col)
value = col;
else if (v is float f)
value = new Vector4(f);
else if (v is int i)
value = new Vector4(i);
return value;
}
private void OnVector4ValueChanged(ValueBox valueBox)
{
var control = valueBox.Parent;
var box = (InputBox)control.Tag;
var x = ((FloatValueBox)control.Children[0]).Value;
var y = ((FloatValueBox)control.Children[1]).Value;
var z = ((FloatValueBox)control.Children[2]).Value;
var w = ((FloatValueBox)control.Children[3]).Value;
box.ParentNode.SetValue(box.Archetype.ValueIndex, new Vector4(x, y, z, w));
}
}
class QuaternionDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(Quaternion);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box).EulerAngles;
var control = new ContainerControl(bounds.X, bounds.Y, 22 * 3 - 2, bounds.Height)
{
ClipChildren = false,
AutoFocus = false,
Parent = box.Parent,
Tag = box,
};
var floatX = new FloatValueBox(value.X, 0, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatX.BoxValueChanged += OnQuaternionValueChanged;
var floatY = new FloatValueBox(value.Y, 22, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatY.BoxValueChanged += OnQuaternionValueChanged;
var floatZ = new FloatValueBox(value.Z, 44, 0, 20, float.MinValue, float.MaxValue, 0.0f)
{
Height = bounds.Height,
Parent = control,
};
floatZ.BoxValueChanged += OnQuaternionValueChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is ContainerControl vec3
&& vec3.ChildrenCount == 3
&& vec3.Children[0] is FloatValueBox
&& vec3.Children[1] is FloatValueBox
&& vec3.Children[2] is FloatValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is ContainerControl quat
&& quat.ChildrenCount == 3
&& quat.Children[0] is FloatValueBox x
&& quat.Children[1] is FloatValueBox y
&& quat.Children[2] is FloatValueBox z)
{
var value = GetValue(box).EulerAngles;
x.Value = value.X;
y.Value = value.Y;
z.Value = value.Z;
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private Quaternion GetValue(InputBox box)
{
var value = Quaternion.Identity;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Quaternion quat)
value = quat;
else if (v is Transform transform)
value = transform.Orientation;
return value;
}
private void OnQuaternionValueChanged(ValueBox valueBox)
{
var control = valueBox.Parent;
var box = (InputBox)control.Tag;
var x = ((FloatValueBox)control.Children[0]).Value;
var y = ((FloatValueBox)control.Children[1]).Value;
var z = ((FloatValueBox)control.Children[2]).Value;
box.ParentNode.SetValue(box.Archetype.ValueIndex, Quaternion.Euler(x, y, z));
}
}
class ColorDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.Type == typeof(Color);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new ColorValueBox(value, bounds.X, bounds.Y)
{
Height = bounds.Height,
Parent = box.Parent,
Tag = box,
};
control.ColorValueChanged += OnColorValueChanged;
return control;
}
public bool IsValid(InputBox box, Control control)
{
return control is ColorValueBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is ColorValueBox colorValueBox)
{
colorValueBox.Value = GetValue(box);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private Vector4 GetValue(InputBox box)
{
var value = Color.Black;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Vector2 vec2)
value = new Color(vec2.X, vec2.Y, 0.0f, 1.0f);
else if (v is Vector3 vec3)
value = new Color(vec3.X, vec3.Y, vec3.Z, 1.0f);
else if (v is Vector4 vec4)
value = new Color(vec4.X, vec4.Y, vec4.Z, vec4.W);
else if (v is Color col)
value = col;
else if (v is float f)
value = new Color(f);
else if (v is int i)
value = new Color(i);
return value;
}
private void OnColorValueChanged(ColorValueBox control)
{
var box = (InputBox)control.Tag;
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.Value);
}
}
class EnumDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
return type.IsEnum;
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new EnumComboBox(box.CurrentType.Type)
{
Location = new Vector2(bounds.X, bounds.Y),
Size = new Vector2(60.0f, bounds.Height),
EnumTypeValue = value ?? box.CurrentType.CreateInstance(),
Parent = box.Parent,
Tag = box,
};
control.EnumValueChanged += OnEnumValueChanged;
return control;
}
private void OnEnumValueChanged(EnumComboBox control)
{
var box = (InputBox)control.Tag;
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.EnumTypeValue);
}
public bool IsValid(InputBox box, Control control)
{
return control is EnumComboBox;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is EnumComboBox enumComboBox)
{
enumComboBox.EnumTypeValue = GetValue(box);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
}
private object GetValue(InputBox box)
{
var value = box.CurrentType.CreateInstance();
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v != null && v.GetType().IsEnum)
value = v;
return value;
}
}
class TypeDefaultValueEditor : IDefaultValueEditor
{
public bool CanUse(InputBox box, ref ScriptType type)
{
if (type.Type == typeof(string) && box.Attributes != null && box.Attributes.Any(x => x.GetType() == typeof(TypeReferenceAttribute)))
return true;
return type.Type == typeof(Type) || type.Type == typeof(ScriptType);
}
public Control Create(InputBox box, ref Rectangle bounds)
{
var value = GetValue(box);
var control = new TypePickerControl
{
Location = new Vector2(bounds.X, bounds.Y),
Size = new Vector2(60.0f, bounds.Height),
ValueTypeName = value,
Parent = box.Parent,
Tag = box,
};
if (box.CurrentType.Type == typeof(Type))
control.CheckValid = type => type.Type != null;
control.TypePickerValueChanged += OnTypeValueChanged;
return control;
}
private void OnTypeValueChanged(TypePickerControl control)
{
var box = (InputBox)control.Tag;
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is string)
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.ValueTypeName);
else if (v is Type)
box.ParentNode.SetValue(box.Archetype.ValueIndex, TypeUtils.GetType(control.Value));
else
box.ParentNode.SetValue(box.Archetype.ValueIndex, control.Value);
}
public bool IsValid(InputBox box, Control control)
{
return control is TypePickerControl;
}
public void UpdateDefaultValue(InputBox box, Control control)
{
if (control is TypePickerControl typePickerControl)
{
typePickerControl.ValueTypeName = GetValue(box);
}
}
public void UpdateAttributes(InputBox box, object[] attributes, Control control)
{
var typeReference = (TypeReferenceAttribute)attributes.FirstOrDefault(x => x.GetType() == typeof(TypeReferenceAttribute));
var type = typeReference != null ? TypeUtils.GetType(typeReference.TypeName) : ScriptType.Null;
((TypePickerControl)control).Type = type ? type : new ScriptType(typeof(object));
}
private string GetValue(InputBox box)
{
var v = box.ParentNode.Values[box.Archetype.ValueIndex];
if (v is Type asType)
return asType.FullName;
if (v is ScriptType asScriptType)
return asScriptType.TypeName;
if (v is string asString)
return asString;
return string.Empty;
}
}
///
/// Visject Surface input box element.
///
///
[HideInEditor]
public class InputBox : Box
{
private Control _defaultValueEditor;
private IDefaultValueEditor _editor;
///
/// The handlers for the input box default value editing. Used to display the default to the UI.
///
public static readonly List DefaultValueEditors = new List()
{
new BooleanDefaultValueEditor(),
new IntegerDefaultValueEditor(),
new UnsignedIntegerDefaultValueEditor(),
new FloatingDefaultValueEditor(),
new StringDefaultValueEditor(),
new Vector2DefaultValueEditor(),
new Vector3DefaultValueEditor(),
new Vector4DefaultValueEditor(),
new QuaternionDefaultValueEditor(),
new ColorDefaultValueEditor(),
new EnumDefaultValueEditor(),
new TypeDefaultValueEditor(),
};
///
/// Gets the control that is used to edit default value (optional).
///
public Control DefaultValueEditor => _defaultValueEditor;
///
public InputBox(SurfaceNode parentNode, NodeElementArchetype archetype)
: base(parentNode, archetype, archetype.Position)
{
// Check if use inlined default value editor
if (Archetype.ValueIndex != -1)
{
ParentNode.ValuesChanged += UpdateDefaultValue;
}
}
///
/// Updates the default value editor UI value.
///
public void UpdateDefaultValue()
{
var currentType = CurrentType.Type;
if (_defaultValueEditor != null && currentType != null)
{
_editor.UpdateDefaultValue(this, _defaultValueEditor);
}
}
///
public override bool IsOutput => false;
///
protected override void OnLocationChanged()
{
base.OnLocationChanged();
if (_defaultValueEditor != null)
{
_defaultValueEditor.Location = new Vector2(X + Width + 8 + Style.Current.FontSmall.MeasureText(Text).X, Y);
}
}
///
public override void Draw()
{
base.Draw();
// Box
DrawBox();
// Draw text
var style = Style.Current;
var rect = new Rectangle(Width + 4, 0, 1410, Height);
Render2D.DrawText(style.FontSmall, Text, rect, Enabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
}
///
protected override void OnCurrentTypeChanged()
{
base.OnCurrentTypeChanged();
if (_defaultValueEditor != null && !_editor.IsValid(this, _defaultValueEditor))
{
_defaultValueEditor.Dispose();
_defaultValueEditor = null;
_editor = null;
}
if (Connections.Count == 0)
{
CreateDefaultEditor();
}
}
///
public override void OnConnectionsChanged()
{
bool showEditor = Connections.Count == 0 && Archetype.ValueIndex != -1;
if (showEditor)
{
CreateDefaultEditor();
}
if (_defaultValueEditor != null)
{
_defaultValueEditor.Enabled = showEditor;
_defaultValueEditor.Visible = showEditor;
}
}
///
protected override void OnAttributesChanged()
{
OnCurrentTypeChanged();
_editor?.UpdateAttributes(this, _attributes ?? Utils.GetEmptyArray