using System; using System.Collections.Generic; using System.Reflection; using Artemis.Storage.Entities.Profile; namespace Artemis.Core { /// /// For internal use only, to implement your own layer property type, extend instead. /// public abstract class BaseLayerProperty { protected readonly List _dataBindings = new List(); private bool _isHidden; private bool _keyframesEnabled; internal BaseLayerProperty() { } /// /// Gets the profile element (such as layer or folder) this effect is applied to /// public RenderProfileElement ProfileElement { get; internal set; } /// /// The parent group of this layer property, set after construction /// public LayerPropertyGroup Parent { get; internal set; } /// /// Gets whether keyframes are supported on this type of property /// public bool KeyframesSupported { get; protected internal set; } = true; /// /// Gets whether data bindings are supported on this type of property /// public bool DataBindingsSupported { get; protected internal set; } = true; /// /// Gets a read-only collection of the currently applied data bindings /// public IReadOnlyCollection DataBindings => _dataBindings.AsReadOnly(); /// /// Gets or sets whether keyframes are enabled on this property, has no effect if is /// False /// public bool KeyframesEnabled { get => _keyframesEnabled; set { if (_keyframesEnabled == value) return; _keyframesEnabled = value; OnKeyframesToggled(); } } /// /// Gets or sets whether the property is hidden in the UI /// public bool IsHidden { get => _isHidden; set { _isHidden = value; OnVisibilityChanged(); } } /// /// Indicates whether the BaseValue was loaded from storage, useful to check whether a default value must be applied /// public bool IsLoadedFromStorage { get; internal set; } /// /// Used to declare that this property doesn't belong to a plugin and should use the core plugin GUID /// public bool IsCoreProperty { get; internal set; } /// /// Gets the description attribute applied to this property /// public PropertyDescriptionAttribute PropertyDescription { get; internal set; } /// /// Gets a list of all the keyframes in their non-generic base form, without their values being available /// public abstract IReadOnlyList BaseKeyframes { get; } internal PropertyEntity PropertyEntity { get; set; } internal LayerPropertyGroup LayerPropertyGroup { get; set; } /// /// Overrides the property value with the default value /// public abstract void ApplyDefaultValue(); /// /// Returns the type of the property /// public abstract Type GetPropertyType(); /// /// Returns a list of properties to which data bindings can be applied /// /// public abstract List GetDataBindingProperties(); /// /// Called when the provided data binding must be applied to a property /// /// protected abstract void ApplyDataBinding(DataBinding dataBinding); /// /// Applies the provided property entity to the layer property by deserializing the JSON base value and keyframe values /// /// /// /// internal abstract void ApplyToLayerProperty(PropertyEntity entity, LayerPropertyGroup layerPropertyGroup, bool fromStorage); /// /// Saves the property to the underlying property entity that was configured when calling /// /// internal abstract void ApplyToEntity(); #region Data bindings /// /// Applies the current to the layer property /// public void ApplyDataBindings() { foreach (var dataBinding in DataBindings) ApplyDataBinding(dataBinding); } /// /// Adds a new data binding targeting the given property to the collection /// /// The property the new data binding should target /// The newly created data binding public DataBinding AddDataBinding(PropertyInfo targetProperty) { var dataBinding = new DataBinding(this, targetProperty); _dataBindings.Add(dataBinding); return dataBinding; } /// /// Removes the provided data binding from the collection /// /// The data binding to remove public void RemoveDataBinding(DataBinding dataBinding) { _dataBindings.Remove(dataBinding); } #endregion #region Events /// /// Occurs once every frame when the layer property is updated /// public event EventHandler Updated; /// /// Occurs when the base value of the layer property was updated /// public event EventHandler BaseValueChanged; /// /// Occurs when the value of the layer property was updated /// public event EventHandler VisibilityChanged; /// /// Occurs when keyframes are enabled/disabled /// public event EventHandler KeyframesToggled; /// /// Occurs when a new keyframe was added to the layer property /// public event EventHandler KeyframeAdded; /// /// Occurs when a keyframe was removed from the layer property /// public event EventHandler KeyframeRemoved; protected virtual void OnUpdated() { Updated?.Invoke(this, new LayerPropertyEventArgs(this)); } protected virtual void OnBaseValueChanged() { BaseValueChanged?.Invoke(this, new LayerPropertyEventArgs(this)); } protected virtual void OnVisibilityChanged() { VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs(this)); } protected virtual void OnKeyframesToggled() { KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs(this)); } protected virtual void OnKeyframeAdded() { KeyframeAdded?.Invoke(this, new LayerPropertyEventArgs(this)); } protected virtual void OnKeyframeRemoved() { KeyframeRemoved?.Invoke(this, new LayerPropertyEventArgs(this)); } #endregion } }