// -----------------------------------------------------------------------
//
// Copyright 2015 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
namespace Perspex
{
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
///
/// Determines how the current binding is selected for a .
///
internal enum LevelPrecedenceMode
{
///
/// The latest fired binding is used as the current value.
///
Latest,
///
/// The latest added binding is used as the current value.
///
Newest,
}
///
/// Stores bindings for a priority level in a .
///
///
///
/// Each priority level in a has a current ,
/// a list of and a . When there are no
/// bindings present, or all bindings return then
/// Value will equal DirectValue.
///
///
/// When there are bindings present, then the latest added binding that doesn't return
/// UnsetValue will take precedence. The active binding is returned by the
/// property (which refers to the active binding's
/// property rather than the index in
/// Bindings).
///
///
/// If DirectValue is set while a binding is active, then it will replace the
/// current value until the active binding fires again/
///
///
internal class PriorityLevel
{
///
/// Method called when current value changes.
///
private Action changed;
///
/// The current direct value.
///
private object directValue;
///
/// The index of the next .
///
private int nextIndex;
private LevelPrecedenceMode mode;
///
/// Initializes a new instance of the class.
///
/// The priority.
/// A method to be called when the current value changes.
public PriorityLevel(
int priority,
LevelPrecedenceMode mode,
Action changed)
{
Contract.Requires(changed != null);
this.mode = mode;
this.changed = changed;
this.Priority = priority;
this.Value = this.directValue = PerspexProperty.UnsetValue;
this.ActiveBindingIndex = -1;
this.Bindings = new LinkedList();
}
///
/// Gets the priority of this level.
///
public int Priority { get; }
///
/// Gets or sets the direct value for this priority level.
///
public object DirectValue
{
get
{
return this.directValue;
}
set
{
this.Value = this.directValue = value;
this.changed(this);
}
}
///
/// Gets the current binding for the priority level.
///
public object Value { get; private set; }
///
/// Gets the value of the active binding, or -1
/// if no binding is active.
///
public int ActiveBindingIndex { get; private set; }
///
/// Gets the bindings for the priority level.
///
public LinkedList Bindings { get; }
///
/// Adds a binding.
///
/// The binding to add.
/// A disposable used to remove the binding.
public IDisposable Add(IObservable