using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; using System.ComponentModel; using Eina; #if EFL_BETA namespace Efl { /// /// Generic helper class to ease manual implementation of C# models. /// /// It provides an expanded API like async helpers to get children. /// /// For MVVM-based models, provides a simpler API. /// /// The type of the child model. It is the type used when adding/removing/getting items to this /// model. public class GenericModel : Efl.Object, Efl.IModel { private Efl.IModel model; /// Creates a new model wrapping model. /// The model to be wrapped. /// The parent of the model. public GenericModel (Efl.IModel model, Efl.Object parent = null) : base(parent) { this.model = model; } /// The list of properties available in the wrapped model. public IEnumerable Properties { get { return GetProperties(); } } /// The number of children in the wrapped model. public uint ChildrenCount { get { return GetChildrenCount(); } } /// The list of properties available in the wrapped model. /// The list of properties in the model. public IEnumerable GetProperties() { return model.GetProperties(); } /// Gets the value of the given property in the wrapped model. /// The property of the model. /// The value of the property. public Eina.Value GetProperty(System.String property) { return model.GetProperty(property); } /// Sets the value of the given property in the given model. /// The property of the model. /// The value of the property. /// An that resolves when the property has /// been set or reports an error if it could not be set. public Eina.Future SetProperty(System.String property, Eina.Value value) { return model.SetProperty(property, value); } /// Returns the number of children in the wrapped model. /// The number of children. public uint GetChildrenCount() { return model.GetChildrenCount(); } /// Returns an that will resolve when the property is ready to be read. /// The property of the model. /// An that resolves when the property is ready. public Eina.Future GetPropertyReady(System.String property) { return model.GetPropertyReady(property); } /// Gets a number of children from the wrapped model. /// The start of the range. /// The size of the range. /// An that resolves to an /// of children models. public Eina.Future GetChildrenSlice(uint start, uint count) { return model.GetChildrenSlice(start, count); } /// Adds a new object to the wrapper model. /// The object to get the properties from. public void Add(T o) { Efl.IModel child = (Efl.IModel)this.AddChild(); ModelHelper.SetProperties(o, child); } /// Adds a new child to the model and returns it. /// The object to be wrapped. public Efl.Object AddChild() { return model.AddChild(); } /// Deletes the given child from the wrapped model. /// The child to be deleted. public void DelChild( Efl.Object child) { model.DelChild(child); } /// Gets the element at the specified index. /// The position of the element. /// Token to notify the async operation of external request to cancel. async public System.Threading.Tasks.Task GetAtAsync(uint index) { using (Eina.Value v = await GetChildrenSliceAsync(index, 1).ConfigureAwait(false)) { if (v.GetValueType().IsContainer()) { var child = (Efl.IModel)v[0]; T obj = (T)Activator.CreateInstance(typeof(T), Array.Empty()); ModelHelper.GetProperties(obj, child); return obj; } else { throw new System.InvalidOperationException("GetChildrenSlice must have returned a container"); } } } /// Async wrapper around . /// The property to be added. /// The value of the property. /// The token for the task's cancellation. /// Task that resolves when the property has been set or could not /// be set. public System.Threading.Tasks.Task SetPropertyAsync(System.String property, Eina.Value value, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) { return model.SetPropertyAsync(property, value, token); } /// Async wrapper around . /// The property of the model. /// The token for the task's cancellation. /// Task that resolves when the given property is ready to be /// read. public System.Threading.Tasks.Task GetPropertyReadyAsync(System.String property, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) { return model.GetPropertyReadyAsync(property, token); } /// Async wrapper around . /// The start of the range. /// The size of the range. /// Token to notify the async operation of external request to cancel. /// Task that resolves when the desired of /// children models is ready. public System.Threading.Tasks.Task GetChildrenSliceAsync(uint start, uint count, System.Threading.CancellationToken token=default(System.Threading.CancellationToken)) { return model.GetChildrenSliceAsync(start, count, token); } /// Event triggered when properties on the wrapped model changes. public event EventHandler PropertiesChangedEvent { add { model.PropertiesChangedEvent += value; } remove { model.PropertiesChangedEvent -= value; } } /// Event triggered when a child is added from the wrapped model. public event EventHandler ChildAddedEvent { add { model.ChildAddedEvent += value; } remove { model.ChildAddedEvent -= value; } } /// Event triggered when a child is removed from the wrapped model. public event EventHandler ChildRemovedEvent { add { model.ChildRemovedEvent += value; } remove { model.ChildRemovedEvent -= value; } } /// Event triggered when the number of children changes. public event EventHandler ChildrenCountChangedEvent { add { model.ChildrenCountChangedEvent += value; } remove { model.ChildrenCountChangedEvent -= value; } } } } #endif