// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using FlaxEditor.Viewport.Modes;
using FlaxEngine;
namespace FlaxEditor.Gizmo
{
///
/// Represents collection of gizmo tools where one is active and in use.
///
///
[HideInEditor]
public class GizmosCollection : List
{
private IGizmoOwner _owner;
private GizmoBase _active;
private EditorGizmoMode _activeMode;
private readonly List _modes = new List();
///
/// Occurs when active gizmo tool gets changed.
///
public event Action ActiveChanged;
///
/// Gets or sets the active gizmo.
///
public GizmoBase Active
{
get => _active;
set
{
if (_active == value)
return;
if (value != null && !Contains(value))
throw new ArgumentException("Not added.");
_active?.OnDeactivated();
_active = value;
_active?.OnActivated();
ActiveChanged?.Invoke();
}
}
///
/// Gets the active gizmo mode.
///
public EditorGizmoMode ActiveMode
{
get => _activeMode;
set
{
if (_activeMode == value)
return;
if (value != null)
{
if (!_modes.Contains(value))
throw new ArgumentException("Not added.");
if (value.Owner != _owner)
throw new InvalidOperationException();
}
_activeMode?.OnDeactivated();
Active = null;
_activeMode = value;
_activeMode?.OnActivated();
ActiveModeChanged?.Invoke(value);
}
}
///
/// Occurs when active mode gets changed.
///
public event Action ActiveModeChanged;
///
/// Init.
///
/// The gizmos owner interface.
public GizmosCollection(IGizmoOwner owner)
{
_owner = owner;
}
///
/// Removes the specified item.
///
/// The item.
public new void Remove(GizmoBase item)
{
if (item == _active)
Active = null;
base.Remove(item);
}
///
/// Clears the collection.
///
public new void Clear()
{
Active = null;
ActiveMode = null;
foreach (var mode in _modes)
mode.Dispose();
_modes.Clear();
base.Clear();
}
///
/// Adds the mode to the viewport.
///
/// The mode.
public void AddMode(EditorGizmoMode mode)
{
if (mode == null)
throw new ArgumentNullException(nameof(mode));
if (_modes.Contains(mode))
throw new ArgumentException("Already added.");
if (mode.Owner != null)
throw new ArgumentException("Already added to other viewport.");
_modes.Add(mode);
mode.Init(_owner);
}
///
/// Removes the mode from the viewport.
///
/// The mode.
public void RemoveMode(EditorGizmoMode mode)
{
if (mode == null)
throw new ArgumentNullException(nameof(mode));
if (!_modes.Contains(mode))
throw new ArgumentException("Not added.");
if (mode.Owner != _owner)
throw new ArgumentException("Not added to this viewport.");
if (_activeMode == mode)
ActiveMode = null;
_modes.Remove(mode);
}
///
/// Sets the active mode.
///
/// The mode type.
/// The activated mode.
public T SetActiveMode() where T : EditorGizmoMode
{
for (int i = 0; i < _modes.Count; i++)
{
if (_modes[i] is T mode)
{
ActiveMode = mode;
return mode;
}
}
throw new ArgumentException("Not added mode to activate.");
}
}
}