using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Xamarin.PropertyEditing
{
public class EditorPropertyChangedEventArgs
: EventArgs
{
/// The property that was updated, or null if a full refresh is required.
public EditorPropertyChangedEventArgs (IPropertyInfo property)
{
Property = property;
}
///
/// Gets the property that was changed, or null for a full refresh.
///
public IPropertyInfo Property
{
get;
}
}
public interface IObjectEditor
{
///
/// Gets the target object being edited.
///
object Target { get; }
///
/// Gets the real type name for the object.
///
/// Also used for iconography.
string TypeName { get; }
///
/// These properties should be minimally equatable to the same property for another object of the same type. This includes
/// for base class properties for two different derived types.
///
IReadOnlyCollection Properties { get; }
///
/// Gets the parent object editor for the object this editor represents or null if none.
///
IObjectEditor Parent { get; }
///
/// These are children that do not participate in the standard element hierarchy, such as segments in a segmented control.
/// Note that objects defined by editors do not need to match real objects in the real hierarchy, they can be faked. An existing
/// iOS property chooser itself can be maped to having an object editor for its actual object.
///
IReadOnlyList DirectChildren { get; }
///
/// Raised when a property's value changes. can be null for a full refresh.
///
event EventHandler PropertyChanged;
/// The property to get retrieve assignable types for.
/// Whether or not to return assignable types for a property's children rather than the property itself.
/// An instance containing the assignable types. No assignable types should use an empty array and not return null.
Task GetAssignableTypesAsync (IPropertyInfo property, bool childTypes);
/*
* Dealing with async values in the context of what's possible across all target platforms is a bit complex.
* While implicit safety may be able to be ensured, it would be exhaustive to reason it out and could change
* at any moment, so we need an explicit safety strategy. As we make value gets and sets async, we open ourselves
* to race conditions even on just the UI thread. Value changes can come from the user, or from the object editor
* at any point. So, we break these changes into two categories: Blocking UI & Waiting Values.
*
* Anything that needs to deal with the current state of the values will Wait asynchronously on prior changes to
* finish. These largely involve value changes from the object editor, which just acts as a INPC and does not
* contain the value itself, so it will be safe and the latest value when queried upon reaching active state in
* the wait queue (see AsyncWorkQueue). Selected objects (when >1) need to wait on values as they need to be
* able to calculate the intersection values.
*
* Anything that needs to deal with user input will need to block its UI. We simply can't reason about the user
* changing values while waiting for previous changes, because they value they're changing may change underneath
* them or become invalid as a result of a prior pending change.
*/
///
/// For the or sources, implementers should
/// ignore 's property and unset the value completely.
/// For XML based backings this usually means removing the attribute altogether. Implementers should not simply set
/// the value to its default value as this would still be a local value and override inheritance, styles, etc.
/// When 's is ,
/// the will be set to a instance. Implementers
/// need not see whether the resource contains a value itself.
/// When the is and
/// is the same as the default value, implementers should consider unsetting the value such that the subsequent
/// would return
/// for . This allows users to clear the value for a property and have it remove
/// the attribute for XML backed platforms without having to issue an .
/// Before the returned task completes, in order:
/// 1. must be able to retrieve the new value.
/// 2. should fire with the appropriate property.
/// For defensive purposes, consumers will not assume the they pass in will be the same
/// as the new value and as a result will re-query the value upon the assumed firing.
/// There should not be a case where is not fired when SetValueAsync is called, consumers
/// will do basic verification before calling. Even changes with the value staying the
/// same is a change in the property.
///
///
Task SetValueAsync (IPropertyInfo property, ValueInfo value, PropertyVariation variation = null);
///
/// Implementers should strive to include the actual value of resources or bindings for
/// whereever possible.
/// If the platform can know the value of a property when unset, it should return that value and the
/// source. If the platform only knows that the value is unset, use instead.
///
/// is null.
Task> GetValueAsync (IPropertyInfo property, PropertyVariation variation = null);
}
}