Refactor ControlReference to use FlaxObjectRefPickerControl as a base class
#3123
This commit is contained in:
@@ -2,15 +2,9 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using FlaxEditor.CustomEditors.Elements;
|
using FlaxEditor.CustomEditors.Elements;
|
||||||
using FlaxEditor.GUI;
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEditor.GUI.Drag;
|
|
||||||
using FlaxEditor.SceneGraph;
|
|
||||||
using FlaxEditor.SceneGraph.GUI;
|
|
||||||
using FlaxEditor.Windows;
|
|
||||||
using FlaxEditor.Windows.Assets;
|
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
using FlaxEngine.Utilities;
|
|
||||||
using Object = FlaxEngine.Object;
|
using Object = FlaxEngine.Object;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Editors;
|
namespace FlaxEditor.CustomEditors.Editors;
|
||||||
@@ -18,433 +12,17 @@ namespace FlaxEditor.CustomEditors.Editors;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The reference picker control used for UIControls using ControlReference.
|
/// The reference picker control used for UIControls using ControlReference.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UIControlRefPickerControl : Control
|
internal class UIControlRefPickerControl : FlaxObjectRefPickerControl
|
||||||
{
|
{
|
||||||
private Type _controlType;
|
|
||||||
private UIControl _value;
|
|
||||||
private ActorTreeNode _linkedTreeNode;
|
|
||||||
private string _valueName;
|
|
||||||
private bool _supportsPickDropDown;
|
|
||||||
|
|
||||||
private bool _isMouseDown;
|
|
||||||
private Float2 _mouseDownPos;
|
|
||||||
private Float2 _mousePos;
|
|
||||||
|
|
||||||
private bool _hasValidDragOver;
|
|
||||||
private DragActors _dragActors;
|
|
||||||
private DragHandlers _dragHandlers;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The presenter using this control.
|
/// Type of the control to pick.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPresenterOwner PresenterContext;
|
public Type ControlType;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Occurs when value gets changed.
|
|
||||||
/// </summary>
|
|
||||||
public event Action ValueChanged;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type of the Control
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException">Throws exception if value is not a subclass of control.</exception>
|
|
||||||
public Type ControlType
|
|
||||||
{
|
|
||||||
get => _controlType;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_controlType == value)
|
|
||||||
return;
|
|
||||||
if (!value.IsSubclassOf(typeof(Control)))
|
|
||||||
throw new ArgumentException(string.Format("Invalid type for UIControlObjectRefPicker. Input type: {0}", value));
|
|
||||||
_controlType = value;
|
|
||||||
_supportsPickDropDown = typeof(Control).IsAssignableFrom(value);
|
|
||||||
|
|
||||||
// Deselect value if it's not valid now
|
|
||||||
if (!IsValid(_value))
|
|
||||||
Value = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The UIControl value.
|
|
||||||
/// </summary>
|
|
||||||
public UIControl Value
|
|
||||||
{
|
|
||||||
get => _value;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (_value == value)
|
|
||||||
return;
|
|
||||||
if (!IsValid(value))
|
|
||||||
value = null;
|
|
||||||
|
|
||||||
// Special case for missing objects (eg. referenced actor in script that is deleted in editor)
|
|
||||||
if (value != null && (Object.GetUnmanagedPtr(value) == IntPtr.Zero || value.ID == Guid.Empty))
|
|
||||||
value = null;
|
|
||||||
|
|
||||||
_value = value;
|
|
||||||
|
|
||||||
// Get name to display
|
|
||||||
if (_value != null)
|
|
||||||
_valueName = _value.Name;
|
|
||||||
else
|
|
||||||
_valueName = string.Empty;
|
|
||||||
|
|
||||||
// Update tooltip
|
|
||||||
if (_value is SceneObject sceneObject)
|
|
||||||
TooltipText = Utilities.Utils.GetTooltip(sceneObject);
|
|
||||||
else
|
|
||||||
TooltipText = string.Empty;
|
|
||||||
|
|
||||||
OnValueChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the selected object value by identifier.
|
|
||||||
/// </summary>
|
|
||||||
public Guid ValueID
|
|
||||||
{
|
|
||||||
get => _value ? _value.ID : Guid.Empty;
|
|
||||||
set => Value = Object.Find<UIControl>(ref value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="UIControlRefPickerControl"/> class.
|
|
||||||
/// </summary>
|
|
||||||
public UIControlRefPickerControl()
|
|
||||||
: base(0, 0, 50, 16)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnValueChanged()
|
|
||||||
{
|
|
||||||
ValueChanged?.Invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShowDropDownMenu()
|
|
||||||
{
|
|
||||||
Focus();
|
|
||||||
if (typeof(Control).IsAssignableFrom(_controlType))
|
|
||||||
{
|
|
||||||
ActorSearchPopup.Show(this, new Float2(0, Height), IsValid, actor =>
|
|
||||||
{
|
|
||||||
Value = actor as UIControl;
|
|
||||||
RootWindow.Focus();
|
|
||||||
Focus();
|
|
||||||
}, PresenterContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsValid(Actor actor)
|
|
||||||
{
|
|
||||||
return actor == null || actor is UIControl a && a.Control.GetType() == _controlType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ValidateDragActor(ActorNode a)
|
|
||||||
{
|
|
||||||
if (!IsValid(a.Actor))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (PresenterContext is PrefabWindow prefabWindow)
|
|
||||||
{
|
|
||||||
if (prefabWindow.Tree == a.TreeNode.ParentTree)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (PresenterContext is PropertiesWindow || PresenterContext == null)
|
|
||||||
{
|
|
||||||
if (a.ParentScene != null)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Draw()
|
protected override bool IsValid(Object obj)
|
||||||
{
|
{
|
||||||
base.Draw();
|
return obj == null || (obj is UIControl control && control.Control.GetType() == ControlType);
|
||||||
|
|
||||||
// Cache data
|
|
||||||
var style = Style.Current;
|
|
||||||
bool isSelected = _value != null;
|
|
||||||
bool isEnabled = EnabledInHierarchy;
|
|
||||||
var frameRect = new Rectangle(0, 0, Width, 16);
|
|
||||||
if (isSelected)
|
|
||||||
frameRect.Width -= 16;
|
|
||||||
if (_supportsPickDropDown)
|
|
||||||
frameRect.Width -= 16;
|
|
||||||
var nameRect = new Rectangle(2, 1, frameRect.Width - 4, 14);
|
|
||||||
var button1Rect = new Rectangle(nameRect.Right + 2, 1, 14, 14);
|
|
||||||
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
|
||||||
|
|
||||||
// Draw frame
|
|
||||||
Render2D.DrawRectangle(frameRect, isEnabled && (IsMouseOver || IsNavFocused) ? style.BorderHighlighted : style.BorderNormal);
|
|
||||||
|
|
||||||
// Check if has item selected
|
|
||||||
if (isSelected)
|
|
||||||
{
|
|
||||||
// Draw name
|
|
||||||
Render2D.PushClip(nameRect);
|
|
||||||
Render2D.DrawText(style.FontMedium, $"{_valueName} ({Utilities.Utils.GetPropertyNameUI(ControlType.GetTypeDisplayName())})", nameRect, isEnabled ? style.Foreground : style.ForegroundDisabled, TextAlignment.Near, TextAlignment.Center);
|
|
||||||
Render2D.PopClip();
|
|
||||||
|
|
||||||
// Draw deselect button
|
|
||||||
Render2D.DrawSprite(style.Cross, button1Rect, isEnabled && button1Rect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Draw info
|
|
||||||
Render2D.PushClip(nameRect);
|
|
||||||
Render2D.DrawText(style.FontMedium, ControlType != null ? $"None ({Utilities.Utils.GetPropertyNameUI(ControlType.GetTypeDisplayName())})" : "-", nameRect, isEnabled ? style.ForegroundGrey : style.ForegroundGrey.AlphaMultiplied(0.75f), TextAlignment.Near, TextAlignment.Center);
|
|
||||||
Render2D.PopClip();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw picker button
|
|
||||||
if (_supportsPickDropDown)
|
|
||||||
{
|
|
||||||
var pickerRect = isSelected ? button2Rect : button1Rect;
|
|
||||||
Render2D.DrawSprite(style.ArrowDown, pickerRect, isEnabled && pickerRect.Contains(_mousePos) ? style.Foreground : style.ForegroundGrey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if drag is over
|
|
||||||
if (IsDragOver && _hasValidDragOver)
|
|
||||||
{
|
|
||||||
var bounds = new Rectangle(Float2.Zero, Size);
|
|
||||||
Render2D.FillRectangle(bounds, style.Selection);
|
|
||||||
Render2D.DrawRectangle(bounds, style.SelectionBorder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnMouseEnter(Float2 location)
|
|
||||||
{
|
|
||||||
_mousePos = location;
|
|
||||||
_mouseDownPos = Float2.Minimum;
|
|
||||||
|
|
||||||
base.OnMouseEnter(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnMouseLeave()
|
|
||||||
{
|
|
||||||
_mousePos = Float2.Minimum;
|
|
||||||
|
|
||||||
// Check if start drag drop
|
|
||||||
if (_isMouseDown)
|
|
||||||
{
|
|
||||||
// Do the drag
|
|
||||||
DoDrag();
|
|
||||||
|
|
||||||
// Clear flag
|
|
||||||
_isMouseDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnMouseLeave();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnMouseMove(Float2 location)
|
|
||||||
{
|
|
||||||
_mousePos = location;
|
|
||||||
|
|
||||||
// Check if start drag drop
|
|
||||||
if (_isMouseDown && Float2.Distance(location, _mouseDownPos) > 10.0f)
|
|
||||||
{
|
|
||||||
// Do the drag
|
|
||||||
DoDrag();
|
|
||||||
|
|
||||||
// Clear flag
|
|
||||||
_isMouseDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnMouseMove(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool OnMouseUp(Float2 location, MouseButton button)
|
|
||||||
{
|
|
||||||
if (button == MouseButton.Left)
|
|
||||||
{
|
|
||||||
// Clear flag
|
|
||||||
_isMouseDown = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache data
|
|
||||||
bool isSelected = _value != null;
|
|
||||||
var frameRect = new Rectangle(0, 0, Width, 16);
|
|
||||||
if (isSelected)
|
|
||||||
frameRect.Width -= 16;
|
|
||||||
if (_supportsPickDropDown)
|
|
||||||
frameRect.Width -= 16;
|
|
||||||
var nameRect = new Rectangle(2, 1, frameRect.Width - 4, 14);
|
|
||||||
var button1Rect = new Rectangle(nameRect.Right + 2, 1, 14, 14);
|
|
||||||
var button2Rect = new Rectangle(button1Rect.Right + 2, 1, 14, 14);
|
|
||||||
|
|
||||||
// Deselect
|
|
||||||
if (_value != null && button1Rect.Contains(ref location))
|
|
||||||
Value = null;
|
|
||||||
|
|
||||||
// Picker dropdown menu
|
|
||||||
if (_supportsPickDropDown && (isSelected ? button2Rect : button1Rect).Contains(ref location))
|
|
||||||
{
|
|
||||||
ShowDropDownMenu();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button == MouseButton.Left)
|
|
||||||
{
|
|
||||||
_isMouseDown = false;
|
|
||||||
|
|
||||||
// Highlight actor or script reference
|
|
||||||
if (!_hasValidDragOver && !IsDragOver && nameRect.Contains(location))
|
|
||||||
{
|
|
||||||
Actor actor = _value;
|
|
||||||
if (actor != null)
|
|
||||||
{
|
|
||||||
if (_linkedTreeNode != null && _linkedTreeNode.Actor == actor)
|
|
||||||
{
|
|
||||||
_linkedTreeNode.ExpandAllParents();
|
|
||||||
_linkedTreeNode.StartHighlight();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_linkedTreeNode = Editor.Instance.Scene.GetActorNode(actor).TreeNode;
|
|
||||||
_linkedTreeNode.ExpandAllParents();
|
|
||||||
Editor.Instance.Windows.SceneWin.SceneTreePanel.ScrollViewTo(_linkedTreeNode, true);
|
|
||||||
_linkedTreeNode.StartHighlight();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset valid drag over if still true at this point
|
|
||||||
if (_hasValidDragOver)
|
|
||||||
_hasValidDragOver = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnMouseUp(location, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool OnMouseDown(Float2 location, MouseButton button)
|
|
||||||
{
|
|
||||||
if (button == MouseButton.Left)
|
|
||||||
{
|
|
||||||
// Set flag
|
|
||||||
_isMouseDown = true;
|
|
||||||
_mouseDownPos = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnMouseDown(location, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override bool OnMouseDoubleClick(Float2 location, MouseButton button)
|
|
||||||
{
|
|
||||||
Focus();
|
|
||||||
|
|
||||||
// Check if has object selected
|
|
||||||
if (_value != null)
|
|
||||||
{
|
|
||||||
if (_linkedTreeNode != null)
|
|
||||||
{
|
|
||||||
_linkedTreeNode.StopHighlight();
|
|
||||||
_linkedTreeNode = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select object
|
|
||||||
if (_value is Actor actor)
|
|
||||||
Editor.Instance.SceneEditing.Select(actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return base.OnMouseDoubleClick(location, button);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnSubmit()
|
|
||||||
{
|
|
||||||
base.OnSubmit();
|
|
||||||
|
|
||||||
// Picker dropdown menu
|
|
||||||
if (_supportsPickDropDown)
|
|
||||||
ShowDropDownMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DoDrag()
|
|
||||||
{
|
|
||||||
// Do the drag drop operation if has selected element
|
|
||||||
if (_value != null)
|
|
||||||
{
|
|
||||||
if (_value is Actor actor)
|
|
||||||
DoDragDrop(DragActors.GetDragData(actor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DragDropEffect DragEffect => _hasValidDragOver ? DragDropEffect.Move : DragDropEffect.None;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override DragDropEffect OnDragEnter(ref Float2 location, DragData data)
|
|
||||||
{
|
|
||||||
base.OnDragEnter(ref location, data);
|
|
||||||
|
|
||||||
// Ensure to have valid drag helpers (uses lazy init)
|
|
||||||
if (_dragActors == null)
|
|
||||||
_dragActors = new DragActors(ValidateDragActor);
|
|
||||||
if (_dragHandlers == null)
|
|
||||||
{
|
|
||||||
_dragHandlers = new DragHandlers
|
|
||||||
{
|
|
||||||
_dragActors,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_hasValidDragOver = _dragHandlers.OnDragEnter(data) != DragDropEffect.None;
|
|
||||||
|
|
||||||
return DragEffect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override DragDropEffect OnDragMove(ref Float2 location, DragData data)
|
|
||||||
{
|
|
||||||
base.OnDragMove(ref location, data);
|
|
||||||
|
|
||||||
return DragEffect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnDragLeave()
|
|
||||||
{
|
|
||||||
_hasValidDragOver = false;
|
|
||||||
_dragHandlers.OnDragLeave();
|
|
||||||
|
|
||||||
base.OnDragLeave();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override DragDropEffect OnDragDrop(ref Float2 location, DragData data)
|
|
||||||
{
|
|
||||||
var result = DragEffect;
|
|
||||||
|
|
||||||
base.OnDragDrop(ref location, data);
|
|
||||||
|
|
||||||
if (_dragActors.HasValidDrag)
|
|
||||||
{
|
|
||||||
Value = _dragActors.Objects[0].Actor as UIControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override void OnDestroy()
|
|
||||||
{
|
|
||||||
_value = null;
|
|
||||||
_controlType = null;
|
|
||||||
_valueName = null;
|
|
||||||
_linkedTreeNode = null;
|
|
||||||
|
|
||||||
base.OnDestroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +30,7 @@ public class UIControlRefPickerControl : Control
|
|||||||
/// ControlReferenceEditor class.
|
/// ControlReferenceEditor class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CustomEditor(typeof(ControlReference<>)), DefaultEditor]
|
[CustomEditor(typeof(ControlReference<>)), DefaultEditor]
|
||||||
public class ControlReferenceEditor : CustomEditor
|
internal class ControlReferenceEditor : CustomEditor
|
||||||
{
|
{
|
||||||
private CustomElement<UIControlRefPickerControl> _element;
|
private CustomElement<UIControlRefPickerControl> _element;
|
||||||
|
|
||||||
@@ -475,6 +53,7 @@ public class ControlReferenceEditor : CustomEditor
|
|||||||
{
|
{
|
||||||
_element.CustomControl.PresenterContext = Presenter.Owner;
|
_element.CustomControl.PresenterContext = Presenter.Owner;
|
||||||
_element.CustomControl.ControlType = genType;
|
_element.CustomControl.ControlType = genType;
|
||||||
|
_element.CustomControl.Type = new ScriptType(typeof(UIControl));
|
||||||
}
|
}
|
||||||
_element.CustomControl.ValueChanged += () =>
|
_element.CustomControl.ValueChanged += () =>
|
||||||
{
|
{
|
||||||
@@ -484,7 +63,7 @@ public class ControlReferenceEditor : CustomEditor
|
|||||||
Type t = typeof(ControlReference<>);
|
Type t = typeof(ControlReference<>);
|
||||||
Type tw = t.MakeGenericType(new Type[] { genericType });
|
Type tw = t.MakeGenericType(new Type[] { genericType });
|
||||||
var instance = Activator.CreateInstance(tw);
|
var instance = Activator.CreateInstance(tw);
|
||||||
((IControlReference)instance).UIControl = _element.CustomControl.Value;
|
((IControlReference)instance).UIControl = (UIControl)_element.CustomControl.Value;
|
||||||
SetValue(instance);
|
SetValue(instance);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
public IPresenterOwner PresenterContext;
|
public IPresenterOwner PresenterContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the allowed objects type (given type and all sub classes). Must be <see cref="Object"/> type of any subclass.
|
/// Gets or sets the allowed objects type (given type and all subclasses). Must be <see cref="Object"/> type of any subclass.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ScriptType Type
|
public ScriptType Type
|
||||||
{
|
{
|
||||||
@@ -61,7 +61,8 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
throw new ArgumentException(string.Format("Invalid type for FlaxObjectRefEditor. Input type: {0}", value != ScriptType.Null ? value.TypeName : "null"));
|
throw new ArgumentException(string.Format("Invalid type for FlaxObjectRefEditor. Input type: {0}", value != ScriptType.Null ? value.TypeName : "null"));
|
||||||
|
|
||||||
_type = value;
|
_type = value;
|
||||||
_supportsPickDropDown = new ScriptType(typeof(Actor)).IsAssignableFrom(value) || new ScriptType(typeof(Script)).IsAssignableFrom(value);
|
_supportsPickDropDown = new ScriptType(typeof(Actor)).IsAssignableFrom(value) ||
|
||||||
|
new ScriptType(typeof(Script)).IsAssignableFrom(value);
|
||||||
|
|
||||||
// Deselect value if it's not valid now
|
// Deselect value if it's not valid now
|
||||||
if (!IsValid(_value))
|
if (!IsValid(_value))
|
||||||
@@ -80,7 +81,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
if (_value == value)
|
if (_value == value)
|
||||||
return;
|
return;
|
||||||
if (!IsValid(value))
|
if (!IsValid(value))
|
||||||
throw new ArgumentException("Invalid object type.");
|
value = null;
|
||||||
|
|
||||||
// Special case for missing objects (eg. referenced actor in script that is deleted in editor)
|
// Special case for missing objects (eg. referenced actor in script that is deleted in editor)
|
||||||
if (value != null && (Object.GetUnmanagedPtr(value) == IntPtr.Zero || value.ID == Guid.Empty))
|
if (value != null && (Object.GetUnmanagedPtr(value) == IntPtr.Zero || value.ID == Guid.Empty))
|
||||||
@@ -91,27 +92,17 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
|
|
||||||
// Get name to display
|
// Get name to display
|
||||||
if (_value is Script script)
|
if (_value is Script script)
|
||||||
{
|
|
||||||
_valueName = script.Actor ? $"{type.Name} ({script.Actor.Name})" : type.Name;
|
_valueName = script.Actor ? $"{type.Name} ({script.Actor.Name})" : type.Name;
|
||||||
}
|
|
||||||
else if (_value != null)
|
else if (_value != null)
|
||||||
{
|
|
||||||
_valueName = _value.ToString();
|
_valueName = _value.ToString();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
_valueName = string.Empty;
|
_valueName = string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
// Update tooltip
|
// Update tooltip
|
||||||
if (_value is SceneObject sceneObject)
|
if (_value is SceneObject sceneObject)
|
||||||
{
|
|
||||||
TooltipText = Utilities.Utils.GetTooltip(sceneObject);
|
TooltipText = Utilities.Utils.GetTooltip(sceneObject);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
TooltipText = string.Empty;
|
TooltipText = string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
OnValueChanged();
|
OnValueChanged();
|
||||||
}
|
}
|
||||||
@@ -150,7 +141,12 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
_type = ScriptType.Object;
|
_type = ScriptType.Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsValid(Object obj)
|
/// <summary>
|
||||||
|
/// Object validation check routine.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Input object to check.</param>
|
||||||
|
/// <returns>True if it can be assigned, otherwise false.</returns>
|
||||||
|
protected virtual bool IsValid(Object obj)
|
||||||
{
|
{
|
||||||
var type = TypeUtils.GetObjectType(obj);
|
var type = TypeUtils.GetObjectType(obj);
|
||||||
return obj == null || _type.IsAssignableFrom(type) && (CheckValid == null || CheckValid(obj, type));
|
return obj == null || _type.IsAssignableFrom(type) && (CheckValid == null || CheckValid(obj, type));
|
||||||
@@ -168,6 +164,15 @@ namespace FlaxEditor.CustomEditors.Editors
|
|||||||
Focus();
|
Focus();
|
||||||
}, PresenterContext);
|
}, PresenterContext);
|
||||||
}
|
}
|
||||||
|
else if (new ScriptType(typeof(Control)).IsAssignableFrom(_type))
|
||||||
|
{
|
||||||
|
ActorSearchPopup.Show(this, new Float2(0, Height), IsValid, actor =>
|
||||||
|
{
|
||||||
|
Value = actor as UIControl;
|
||||||
|
RootWindow.Focus();
|
||||||
|
Focus();
|
||||||
|
}, PresenterContext);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScriptSearchPopup.Show(this, new Float2(0, Height), IsValid, script =>
|
ScriptSearchPopup.Show(this, new Float2(0, Height), IsValid, script =>
|
||||||
|
|||||||
Reference in New Issue
Block a user