1 | // <developer>kevin@kevlindev.com</developer>
|
---|
2 | // <completed>100</completed>
using System;
using System.Collections;
|
---|
3 | using System.Collections.Generic;
|
---|
4 | namespace SharpVectors.Dom.Svg
{
/// <summary>
/// Base class for all SVG*List-derived classes.
|
---|
5 | /// Note we're using <see cref="List{T}"/> (as opposed to deriving from) to hide unneeded <see cref="List{T}"/> methods
/// Note that a CLR uint is equivalent to an IDL ulong, so uint is used for all index values
/// </summary>
|
---|
6 | public abstract class SvgList<T> : IEnumerable<T>
{
#region Private Fields
|
---|
7 |
|
---|
8 | private static Hashtable itemOwnerMap;
protected List<T> items;
#endregion
|
---|
9 | #region Constructor
/// <summary>
/// SvgList constructor
/// </summary>
protected SvgList()
{
itemOwnerMap = new Hashtable();
items = new List<T>();
}
#endregion
#region ISvgList Interface
/// <summary>
/// NumberOfItems
/// </summary>
public uint NumberOfItems
{
|
---|
10 | get { return (uint) items.Count; }
|
---|
11 | }
|
---|
12 |
|
---|
13 | /// <summary>
/// Clear
/// </summary>
|
---|
14 | public void Clear()
|
---|
15 | {
|
---|
16 | // Note that we cannot use List<T>'s Clear method since we need to
|
---|
17 | // remove all items from the itemOwnerMap
|
---|
18 | while ( items.Count > 0 )
|
---|
19 | RemoveItem(0);
|
---|
20 | }
|
---|
21 |
|
---|
22 | /// <summary>
/// Initialize
/// </summary>
/// <param name="newItem"></param>
/// <returns></returns>
|
---|
23 | public T Initialize(T newItem)
|
---|
24 | {
|
---|
25 | Clear();
|
---|
26 | return AppendItem(newItem);
|
---|
27 | }
|
---|
28 |
|
---|
29 | /// <summary>
/// GetItem
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
|
---|
30 | public T GetItem(uint index)
|
---|
31 | {
|
---|
32 | if ( index < 0 || items.Count <= index )
|
---|
33 | throw new DomException(DomExceptionType.IndexSizeErr);
|
---|
34 |
|
---|
35 | return items[(int) index];
|
---|
36 | }
|
---|
37 |
|
---|
38 | /// <summary>
/// InsertItemBefore
/// </summary>
/// <param name="newItem"></param>
/// <param name="index"></param>
/// <returns></returns>
|
---|
39 | public T InsertItemBefore(T newItem, uint index)
|
---|
40 | {
|
---|
41 | if ( index < 0 || items.Count <= index )
|
---|
42 | throw new DomException(DomExceptionType.IndexSizeErr);
|
---|
43 |
|
---|
44 | // cache cast
|
---|
45 | int i = (int) index;
|
---|
46 |
|
---|
47 | // if newItem exists in a list, remove it from that list
|
---|
48 | if ( SvgList<T>.itemOwnerMap.ContainsKey(newItem) )
|
---|
49 | ((SvgList<T>)SvgList<T>.itemOwnerMap[newItem]).RemoveItem(newItem);
|
---|
50 |
|
---|
51 | // insert item into this list
|
---|
52 | items.Insert(i, newItem);
|
---|
53 |
|
---|
54 | // update the itemOwnerMap to associate newItem with this list
|
---|
55 | SvgList<T>.itemOwnerMap[newItem] = this;
|
---|
56 |
|
---|
57 | return items[i];
|
---|
58 | }
|
---|
59 |
|
---|
60 | /// <summary>
/// ReplaceItem
/// </summary>
/// <param name="newItem"></param>
/// <param name="index"></param>
/// <returns></returns>
|
---|
61 | public T ReplaceItem(T newItem, uint index)
|
---|
62 | {
|
---|
63 | if ( index < 0 || items.Count <= index )
|
---|
64 | throw new DomException(DomExceptionType.IndexSizeErr);
|
---|
65 |
|
---|
66 | // cache cast
|
---|
67 | int i = (int) index;
|
---|
68 |
|
---|
69 | // if newItem exists in a list, remove it from that list
|
---|
70 | if (SvgList<T>.itemOwnerMap.ContainsKey(newItem))
|
---|
71 | ((SvgList<T>)SvgList<T>.itemOwnerMap[newItem]).RemoveItem(newItem);
|
---|
72 |
|
---|
73 | // remove oldItem from itemOwnerMap
|
---|
74 | SvgList<T>.itemOwnerMap.Remove(items[i]);
|
---|
75 |
|
---|
76 | // update the itemOwnerMap to associate newItem with this list
|
---|
77 | SvgList<T>.itemOwnerMap[newItem] = this;
|
---|
78 |
|
---|
79 | // store newItem and return
|
---|
80 | return items[i] = newItem;
|
---|
81 | }
|
---|
82 |
|
---|
83 | /// <summary>
/// RemoveItem
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
|
---|
84 | public T RemoveItem(uint index)
|
---|
85 | {
|
---|
86 | if ( index < 0 || items.Count <= index )
|
---|
87 | throw new DomException(DomExceptionType.IndexSizeErr);
|
---|
88 |
|
---|
89 | // cache cast
|
---|
90 | int i = (int) index;
|
---|
91 |
|
---|
92 | // save removed item so we can return it
|
---|
93 | T result = items[i];
|
---|
94 |
|
---|
95 | // item is longer associated with this list, so remove item from itemOwnerMap
|
---|
96 | SvgList<T>.itemOwnerMap.Remove(result);
|
---|
97 |
|
---|
98 | // remove item from this list
|
---|
99 | items.RemoveAt(i);
|
---|
100 |
|
---|
101 | // return removed item
|
---|
102 | return result;
|
---|
103 | }
|
---|
104 |
|
---|
105 | /// <summary>
/// AppendItem
/// </summary>
/// <param name="newItem"></param>
/// <returns></returns>
|
---|
106 | public T AppendItem(T newItem)
{
// if item exists in a list, remove it from that list
|
---|
107 | if (SvgList<T>.itemOwnerMap.ContainsKey(newItem))
|
---|
108 | ((SvgList<T>)SvgList<T>.itemOwnerMap[newItem]).RemoveItem(newItem);
|
---|
109 | // update the itemOwnerMap to associate newItem with this list
|
---|
110 | SvgList<T>.itemOwnerMap[newItem] = this;
|
---|
111 | // add item and return
items.Add(newItem);
|
---|
112 | return newItem;
}
#endregion
|
---|
113 | #region IEnumerable Interface
public IEnumerator<T> GetEnumerator()
{
|
---|
114 | return items.GetEnumerator();
//return new SvgListEnumerator(this);
}
|
---|
115 |
|
---|
116 | IEnumerator IEnumerable.GetEnumerator()
|
---|
117 | {
|
---|
118 | return items.GetEnumerator();
|
---|
119 | }
|
---|
120 |
#endregion
#region Support Methods
/// <summary>
/// RemoveItem - used to remove an item by value as opposed to by position
/// </summary>
/// <param name="item"></param>
private void RemoveItem(T item)
{
|
---|
121 | int index = items.IndexOf(item);
if (index >= 0)
{
|
---|
122 | RemoveItem((uint)index);
}
//for ( int i = 0; i < items.Count; i++ )
//{
// if ( items[i] == item )
// {
// RemoveItem((uint) i);
// break;
// }
//}
}
#endregion
|
---|
123 | }
} |
---|