Skip to content

Commit 0800495

Browse files
committed
Item selector QoL and delete prompts.
Implements a basic delete confirm prompt so users don't delete groups in a single click. Item Selector now remembers last search term and page, very useful for quickly and repeatedly adding groups. Ctrl+F now focuses the search field.
1 parent b3156a2 commit 0800495

5 files changed

Lines changed: 77 additions & 13 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ changelog.html
2828
\.project
2929
\.settings/
3030
*.launch
31+
/Reference

TODO.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# TODO

src/main/java/mezz/jei/gui/overlay/collapsible/GuiCollapsibleGroups.java

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,15 @@ public class GuiCollapsibleGroups extends GuiScreen {
5353
private static final int BTN_TOGGLE_BASE = 100;
5454
private static final int BTN_CONFIGURE_BASE = 200;
5555
private static final int BTN_DELETE_BASE = 300;
56+
private static final int BTN_DELETE_CONFIRM_BASE = 400;
57+
private static final int BTN_DELETE_CANCEL_BASE = 500;
5658

5759
private final GuiScreen parentScreen;
5860
private final List<GroupCardEntry> cardEntries = new ArrayList<>();
5961
private int currentPage = 0;
6062
private int totalPages = 1;
63+
/** Index into {@code cardEntries} of the custom group awaiting delete confirmation, or -1. */
64+
private int pendingDeleteIdx = -1;
6165
@Nullable private IIngredientListElement<?> tooltipElement = null;
6266

6367
// Drag-to-scroll state for card preview boxes
@@ -152,12 +156,20 @@ private void rebuildPageButtons() {
152156
this.buttonList.add(new GuiButton(BTN_TOGGLE_BASE + i, btnX, btnY, 52, 20, toggleLabel));
153157

154158
if (card.isCustom) {
155-
// Configure button
156-
this.buttonList.add(new GuiButton(BTN_CONFIGURE_BASE + i, btnX, btnY + 22, 24, 20,
157-
"\u270E")); // pencil unicode
158-
// Delete button
159-
this.buttonList.add(new GuiButton(BTN_DELETE_BASE + i, btnX + 26, btnY + 22, 26, 20,
160-
"\u2716")); // cross unicode
159+
if (i == pendingDeleteIdx) {
160+
// Confirm row: ✔ Yes / ✗ No
161+
this.buttonList.add(new GuiButton(BTN_DELETE_CONFIRM_BASE + i, btnX, btnY + 22, 24, 20,
162+
"\u2714")); // ✔ checkmark
163+
this.buttonList.add(new GuiButton(BTN_DELETE_CANCEL_BASE + i, btnX + 26, btnY + 22, 26, 20,
164+
"\u2716")); // ✗ cancel
165+
} else {
166+
// Configure button
167+
this.buttonList.add(new GuiButton(BTN_CONFIGURE_BASE + i, btnX, btnY + 22, 24, 20,
168+
"\u270E")); // pencil unicode
169+
// Delete button
170+
this.buttonList.add(new GuiButton(BTN_DELETE_BASE + i, btnX + 26, btnY + 22, 26, 20,
171+
"\u2716")); // cross unicode
172+
}
161173
}
162174
}
163175

@@ -186,11 +198,13 @@ protected void actionPerformed(GuiButton button) throws IOException {
186198
}
187199
if (button.id == BTN_PREV_PAGE) {
188200
currentPage = Math.max(0, currentPage - 1);
201+
pendingDeleteIdx = -1;
189202
rebuildPageButtons();
190203
return;
191204
}
192205
if (button.id == BTN_NEXT_PAGE) {
193206
currentPage = Math.min(totalPages - 1, currentPage + 1);
207+
pendingDeleteIdx = -1;
194208
rebuildPageButtons();
195209
return;
196210
}
@@ -244,9 +258,20 @@ protected void actionPerformed(GuiButton button) throws IOException {
244258
return;
245259
}
246260

247-
// Delete
248-
if (button.id >= BTN_DELETE_BASE) {
261+
// Delete — first click: arm confirmation
262+
if (button.id >= BTN_DELETE_BASE && button.id < BTN_DELETE_CONFIRM_BASE) {
249263
int idx = button.id - BTN_DELETE_BASE;
264+
if (idx >= 0 && idx < cardEntries.size() && cardEntries.get(idx).isCustom) {
265+
pendingDeleteIdx = idx;
266+
rebuildPageButtons();
267+
}
268+
return;
269+
}
270+
271+
// Delete confirmed — execute the actual removal
272+
if (button.id >= BTN_DELETE_CONFIRM_BASE && button.id < BTN_DELETE_CANCEL_BASE) {
273+
int idx = button.id - BTN_DELETE_CONFIRM_BASE;
274+
pendingDeleteIdx = -1;
250275
if (idx >= 0 && idx < cardEntries.size()) {
251276
GroupCardEntry card = cardEntries.get(idx);
252277
if (card.isCustom) {
@@ -267,6 +292,13 @@ protected void actionPerformed(GuiButton button) throws IOException {
267292
}
268293
}
269294
}
295+
return;
296+
}
297+
298+
// Delete cancelled
299+
if (button.id >= BTN_DELETE_CANCEL_BASE) {
300+
pendingDeleteIdx = -1;
301+
rebuildPageButtons();
270302
}
271303
}
272304

@@ -290,6 +322,15 @@ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
290322
int cardY = layoutContentTop + row * (CARD_HEIGHT + CARD_PADDING);
291323
GroupCardEntry card = cardEntries.get(i);
292324
drawCard(card, cardX, cardY, layoutColWidth, mouseX, mouseY);
325+
326+
// Draw "Delete?" label to the left of the ✔/✗ confirm buttons
327+
if (i == pendingDeleteIdx && card.isCustom) {
328+
int btnX = cardX + layoutColWidth - 56;
329+
int btnY = cardY + 4;
330+
String confirmLabel = Translator.translateToLocal("jei.gui.collapsible.confirmDelete");
331+
int labelX = btnX - this.fontRenderer.getStringWidth(confirmLabel) - 3;
332+
this.fontRenderer.drawStringWithShadow(confirmLabel, labelX, btnY + 27, 0xFFFF4444);
333+
}
293334
}
294335

295336
// Page counter

src/main/java/mezz/jei/gui/overlay/collapsible/GuiCustomGroupEditor.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public class GuiCustomGroupEditor extends GuiScreen {
4646
private final CustomGroupsConfig.CustomGroup group;
4747
private final Set<String> selectedUids = new LinkedHashSet<>();
4848

49+
// Persisted across editor instances, reopening restores last search and page.
50+
private static String savedSearchText = "";
51+
private static int savedFirstItemIndex = 0;
52+
4953
@Nullable
5054
private GuiTextField nameField;
5155
@Nullable
@@ -108,10 +112,10 @@ public void initGui() {
108112
nameField.setMaxStringLength(40);
109113
nameField.setText(group.displayName != null ? group.displayName : "");
110114

111-
// Search field
115+
// Search field — restore saved text so the user's last search carries over
112116
searchField = new GuiTextField(11, this.fontRenderer, 4, topBarHeight - 18, panelDivider - 12, 14);
113117
searchField.setMaxStringLength(128);
114-
searchField.setText("");
118+
searchField.setText(savedSearchText);
115119

116120
// Save & Cancel buttons
117121
this.buttonList.add(new GuiButton(BTN_SAVE, panelDivider + 4, 4, 50, 20,
@@ -147,6 +151,7 @@ public void initGui() {
147151
this.buttonList.add(new GuiButton(BTN_NEXT_SEL_PAGE, this.width - 34, leftNavY, 30, 20, ">"));
148152

149153
updateFilteredItems();
154+
leftPage = Math.max(0, Math.min(savedFirstItemIndex / leftItemsPerPage, leftTotalPages - 1));
150155
updateSelectedStacks();
151156
buildOtherGroupIndex();
152157
}
@@ -155,6 +160,9 @@ public void initGui() {
155160
public void onGuiClosed() {
156161
super.onGuiClosed();
157162
Keyboard.enableRepeatEvents(false);
163+
// Persist the current search text and the absolute index of the first visible item.
164+
savedSearchText = (searchField != null) ? searchField.getText() : "";
165+
savedFirstItemIndex = leftPage * leftItemsPerPage;
158166
}
159167

160168
/**
@@ -262,7 +270,6 @@ private String findCoveringWildcard(String normalUid) {
262270
/**
263271
* Collects all exact UIDs from the full ingredient list that share the given wildcard prefix.
264272
* Used for auto-promote checks and wildcard decomposition.
265-
* Mirrors the sibling-lookup from the legacy blacklist's areAllBlacklisted / getMatches logic.
266273
*/
267274
private List<String> getSiblingUids(String wildcardUid) {
268275
if (!wildcardUid.endsWith(":*") || !Internal.hasIngredientFilter()) return Collections.emptyList();
@@ -281,7 +288,6 @@ private List<String> getSiblingUids(String wildcardUid) {
281288
/**
282289
* Decomposes a wildcard entry into individual exact entries, excluding one item
283290
* (the one the user just clicked to remove).
284-
* Mirrors removeIngredientFromConfigBlacklist's wildcard-decompose behaviour.
285291
*/
286292
private void decomposeWildcard(String wildcardUid, @Nullable String excludeUid) {
287293
selectedUids.remove(wildcardUid);
@@ -296,7 +302,6 @@ private void decomposeWildcard(String wildcardUid, @Nullable String excludeUid)
296302
/**
297303
* After adding an exact UID, checks if every meta variant of that item is now individually
298304
* selected. If so, replaces them all with a single wildcard entry.
299-
* Mirrors addIngredientToConfigBlacklist's auto-promote (areAllBlacklisted) behaviour.
300305
*/
301306
private void maybePromoteToWildcard(Object ingredient, String addedUid) {
302307
String wildcardUid = getIngredientWildcardUid(ingredient);
@@ -689,6 +694,7 @@ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOEx
689694
// Right-click clears search
690695
if (searchField.isFocused() && mouseButton == 1) {
691696
searchField.setText("");
697+
leftPage = 0;
692698
updateFilteredItems();
693699
}
694700
}
@@ -877,10 +883,24 @@ protected void keyTyped(char typedChar, int keyCode) throws IOException {
877883
return;
878884
}
879885
if (searchField != null && searchField.isFocused()) {
886+
String before = searchField.getText();
880887
searchField.textboxKeyTyped(typedChar, keyCode);
888+
if (!searchField.getText().equals(before)) {
889+
leftPage = 0;
890+
}
881891
updateFilteredItems();
882892
return;
883893
}
894+
// Ctrl+F focuses the search field
895+
if (keyCode == Keyboard.KEY_F && isCtrlKeyDown()) {
896+
if (searchField != null) {
897+
searchField.setFocused(true);
898+
if (nameField != null) {
899+
nameField.setFocused(false);
900+
}
901+
}
902+
return;
903+
}
884904
if (keyCode == Keyboard.KEY_ESCAPE) {
885905
this.mc.displayGuiScreen(parentScreen);
886906
return;

src/main/resources/assets/jei/lang/en_us.lang

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,5 @@ jei.gui.collapsible.editor.title=Selected Items
233233
jei.gui.collapsible.editor.name=Name
234234
jei.gui.collapsible.editor.save=Save
235235
jei.gui.collapsible.editor.selected=%d selected
236+
jei.gui.collapsible.confirmDelete=Delete?
236237
hei.tooltip.missing_ingredients=§cMissing Ingredients:

0 commit comments

Comments
 (0)