Skip to content

Commit 586c793

Browse files
1.4.0 pagination
1 parent 35e4d96 commit 586c793

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package me.flame.menus.menu.iterator;
2+
3+
import me.flame.menus.items.MenuItem;
4+
import me.flame.menus.menu.IterationDirection;
5+
import me.flame.menus.menu.Slot;
6+
import me.flame.menus.menu.Page;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.jetbrains.annotations.Nullable;
9+
10+
import java.util.Iterator;
11+
import java.util.NoSuchElementException;
12+
import java.util.Optional;
13+
14+
public class PageIterator implements Iterator<MenuItem> {
15+
@NotNull
16+
private final Page page;
17+
18+
@NotNull
19+
private final IterationDirection direction;
20+
21+
@NotNull
22+
private Slot position;
23+
24+
private Slot next;
25+
26+
private boolean isFirst = true;
27+
28+
private final int rows;
29+
30+
private static final String NOTHING_MORE_NEXT =
31+
"Used PageIterator#next() but nothing more" +
32+
"\nFix: Use hasNext() beforehand to avoid this error.";
33+
34+
private static final String NOTHING_MORE_NEXT_OPTIONAL =
35+
"Used PageIterator#nextOptional() but nothing more" +
36+
"\nFix: Use hasNext() beforehand to avoid this error.";
37+
38+
private static final String NOTHING_MORE_NEXT_NOT_NULL =
39+
"Used PageIterator#nextNotNull() but nothing more";
40+
41+
private static final String GREATER_THAN_ONE_ONLY =
42+
"Starting row and column must be 1 or greater only." +
43+
"\nFix: If you're using an algorithm for rows/cols, you might wanna check it";
44+
45+
public PageIterator(int startingRow, int startingCol,
46+
@NotNull IterationDirection direction,
47+
@NotNull Page page) {
48+
Slot prepos = new Slot(startingRow, startingCol);
49+
if (!prepos.isSlot()) throw new IllegalArgumentException(GREATER_THAN_ONE_ONLY);
50+
this.page = page;
51+
this.rows = page.rows();
52+
this.position = prepos;
53+
this.direction = direction;
54+
}
55+
56+
public PageIterator(@NotNull IterationDirection direction,
57+
@NotNull Page page) {
58+
this.page = page;
59+
this.rows = page.rows();
60+
this.position = Slot.FIRST.copy();
61+
this.direction = direction;
62+
}
63+
64+
/**
65+
* Retrieves the next slot in the menu.
66+
*
67+
* @param emptyOnly a boolean indicating whether to retrieve only empty slots
68+
* @return the next empty slot in the menu, or null if no empty slot is found
69+
*/
70+
public Slot nextSlot(boolean emptyOnly) {
71+
if (!emptyOnly) return nextSlot();
72+
73+
while (true) {
74+
MenuItem item = page.getItem(position);
75+
if (item == null) break;
76+
77+
position = direction.shift(position, this.rows);
78+
if (!position.isSlot()) return null;
79+
}
80+
81+
// when it becomes empty
82+
return position;
83+
}
84+
85+
/**
86+
* Retrieves the next slot in the menu.
87+
* @return the next empty slot in the menu, or null if no empty slot is found
88+
*/
89+
public @Nullable Slot nextSlot() {
90+
if (!isFirst) {
91+
position = next;
92+
next = null;
93+
return position;
94+
}
95+
isFirst = false;
96+
return position;
97+
}
98+
99+
@Override
100+
public boolean hasNext() {
101+
if (next != null) return true;
102+
next = direction.shift(position, this.rows);
103+
return next.isSlot();
104+
}
105+
106+
@Override
107+
public MenuItem next() {
108+
Slot slot = nextSlot();
109+
if (slot != null) return page.getItem(slot.getSlot());
110+
throw new NoSuchElementException(NOTHING_MORE_NEXT);
111+
}
112+
113+
/**
114+
* Retrieves the next non-null MenuItem in the menu.
115+
*
116+
* @return the next non-null MenuItem in the menu
117+
*/
118+
public MenuItem nextNotNull() {
119+
while (hasNext()) {
120+
Slot slot = nextSlot();
121+
if (slot == null)
122+
throw new NoSuchElementException(
123+
NOTHING_MORE_NEXT_NOT_NULL +
124+
"\nFix: Everything after slot " + position.getSlot() + " is empty/null."
125+
);
126+
127+
MenuItem item = page.getItem(slot.getSlot());
128+
if (item != null) return item;
129+
}
130+
131+
throw new NoSuchElementException(
132+
NOTHING_MORE_NEXT_NOT_NULL +
133+
"\nFix: Everything after slot " + position.getSlot() + " is empty/null."
134+
);
135+
}
136+
137+
/**
138+
* Retrieves the next optional menu item.
139+
*
140+
* @return an Optional object containing the next MenuItem, if available.
141+
* Returns an empty Optional if the slot in the menu is empty.
142+
* Returns an empty Optional if there are no more items.
143+
* @throws NoSuchElementException if there are no more items in the menu.
144+
*/
145+
public Optional<MenuItem> nextOptional() {
146+
Slot slot = nextSlot();
147+
if (slot != null) return page.get(slot);
148+
throw new NoSuchElementException(NOTHING_MORE_NEXT_OPTIONAL);
149+
}
150+
}

0 commit comments

Comments
 (0)