-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPagedList.cs
More file actions
162 lines (138 loc) · 5.28 KB
/
PagedList.cs
File metadata and controls
162 lines (138 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
// FIXME: This should be converted to use TaggedUnion<A, B> instead of
// using nulls to represent empty items.
namespace SubsurfaceStudios.UI.Systems {
[Serializable]
/// <summary>
/// A system for iterating over an array in "pages", fixed-size slices of the backing array.
/// </summary>
/// <typeparam name="T">The type to iterate over. Must be nullable. (no structs)</typeparam>
public sealed class PagedList<T> where T : class {
public ReadOnlyCollection<T> Items {
get {
if(items_cache == null) items_cache = new ReadOnlyCollection<T>(items);
return items_cache;
}
}
private ReadOnlyCollection<T> items_cache;
private IList<T> items = new List<T>();
private int itemsPerPage = 6;
private int pageIndex = 0;
public int PageIndex {
get => pageIndex == 0 ? 1 : (pageIndex / itemsPerPage);
set => pageIndex = value * itemsPerPage;
}
public int PageCount {
get => Mathf.CeilToInt(items.Count / itemsPerPage)+1;
}
/// <summary>
/// Create a new PagedList from a list and a number of items per page.
/// </summary>
/// <param name="items">The IList to iterate over.</param>
/// <param name="itemsPerPage">The number of items per page.</param>
public PagedList(IList<T> items, int itemsPerPage) {
this.items = items;
this.itemsPerPage = itemsPerPage;
this.pageIndex = 0;
}
private PagedList() {} // Prevent instantiation without arguments.
/// <summary>
/// Updates the items in this PagedList.
/// </summary>
/// <param name="items">The new item array.</param>
/// <param name="resetIndex">Whether or not to reset the page index. Defaults to true.</param>
public void RefreshItems(IList<T> items, bool resetIndex = true) {
this.items = items;
if(resetIndex) pageIndex = 0;
}
/// <summary>
/// Increment the current page index.
/// </summary>
/// <returns>Whether or not the page index can be/was incremented.</returns>
public bool IncrementPage() {
if(!CanIncrementPage) return false;
pageIndex += itemsPerPage;
return true;
}
/// <summary>
/// Decrement the current page index.
/// </summary>
/// <returns>Whether or not the page index can be/was decremented.</returns>
public bool DecrementPage() {
if(!CanDecrementPage) return false;
pageIndex -= itemsPerPage;
return true;
}
/// <summary>
/// Resets the current page index to 0.
/// </summary>
public void ResetPage() {
pageIndex = 0;
}
/// <summary>
/// Adds an item to this PagedArray.
/// </summary>
/// <param name="item">The item to add. No duplicate protection!</param>
public void AddItem(T item) {
items.Add(item);
}
/// <summary>
/// Removes an item from this PagedArray.
/// </summary>
/// <param name="item">The item to remove. Will not cause errors if the item is not in this PagedArray.</param>
public void RemoveItem(T item) {
items.Remove(item);
}
public void AddRange(IList<T> item) {
for (int i = 0; i < item.Count; i++)
items.Add(item[i]);
}
/// <summary>
/// Whether or not you can run the IncrementPage method successfully. Useful for UI checks.
/// </summary>
public bool CanIncrementPage { get => pageIndex + itemsPerPage < items.Count; }
/// <summary>
/// Whether or not you can run the DecrementPage method successfully. Useful for UI checks.
/// </summary>
public bool CanDecrementPage { get => pageIndex - itemsPerPage >= 0; }
/// <summary>
/// Reads a page of items from the array.
/// </summary>
/// <remarks>
/// You must handle null objects when reading from this array, as it is not done internally.
/// </remarks>
/// <returns>A read-only collection of the items in this page.</returns>
public ReadOnlyCollection<T> Page() {
List<T> x = new List<T>(itemsPerPage);
for(
int i = pageIndex;
i < pageIndex + itemsPerPage;
i++
) {
if(items.Count <= i) x.Add(null);
else x.Add(items[i] ?? null);
}
return new ReadOnlyCollection<T>(x);
}
public int[] PageIndices() {
int[] x = new int[itemsPerPage];
int a = 0;
for(
int i = pageIndex * itemsPerPage;
i < pageIndex * itemsPerPage + itemsPerPage;
i++
) {
x[a] = i;
a++;
}
return x;
}
public void ForceUpdateInternalList(IList<T> items) {
this.items = items;
this.items_cache = null;
}
}
}