// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Styling { using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Reactive; using System.Reactive.Subjects; public class Classes : ICollection, INotifyCollectionChanged { private List inner; private Subject beforeChanged = new Subject(); private Subject changed = new Subject(); private Subject afterChanged = new Subject(); public Classes() { this.inner = new List(); } public Classes(params string[] classes) { this.inner = new List(classes); } public Classes(IEnumerable classes) { this.inner = new List(classes); } public event NotifyCollectionChangedEventHandler CollectionChanged; public int Count { get { return this.inner.Count; } } public bool IsReadOnly { get { return false; } } public IObservable BeforeChanged { get { return this.beforeChanged; } } public IObservable Changed { get { return this.changed; } } public IObservable AfterChanged { get { return this.afterChanged; } } public void Add(string item) { this.Add(Enumerable.Repeat(item, 1)); } public void Add(params string[] items) { this.Add((IEnumerable)items); } public void Add(IEnumerable items) { items = items.Except(this.inner); NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Add, items); this.beforeChanged.OnNext(e); this.inner.AddRange(items); this.RaiseChanged(e); } public void Clear() { NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset); this.beforeChanged.OnNext(e); this.inner.Clear(); this.RaiseChanged(e); } public bool Contains(string item) { return this.inner.Contains(item); } public void CopyTo(string[] array, int arrayIndex) { this.inner.CopyTo(array, arrayIndex); } public IEnumerator GetEnumerator() { return this.inner.GetEnumerator(); } public override string ToString() { return string.Join(" ", this); } IEnumerator IEnumerable.GetEnumerator() { return this.inner.GetEnumerator(); } public bool Remove(string item) { return this.Remove(Enumerable.Repeat(item, 1)); } public bool Remove(params string[] items) { return this.Remove((IEnumerable)items); } public bool Remove(IEnumerable items) { items = items.Intersect(this.inner); if (items.Any()) { NotifyCollectionChangedEventArgs e = new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Remove, items); this.beforeChanged.OnNext(e); foreach (string item in items) { this.inner.Remove(item); } this.RaiseChanged(e); return true; } else { return false; } } private void RaiseChanged(NotifyCollectionChangedEventArgs e) { if (this.CollectionChanged != null) { this.CollectionChanged(this, e); } this.changed.OnNext(e); this.afterChanged.OnNext(e); } } }