2014-06-29 20:31:37 +10:00
|
|
|
package codechicken.nei;
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
import static codechicken.nei.NEIClientUtils.translate;
|
|
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
import codechicken.core.gui.GuiScrollSlot;
|
|
|
|
|
import codechicken.lib.gui.GuiDraw;
|
|
|
|
|
import codechicken.lib.vec.Rectangle4i;
|
2014-12-14 17:10:00 +10:00
|
|
|
import codechicken.nei.ItemList.AnyMultiItemFilter;
|
2014-06-29 20:31:37 +10:00
|
|
|
import codechicken.nei.ItemList.ItemsLoadedCallback;
|
|
|
|
|
import codechicken.nei.ItemList.NothingItemFilter;
|
|
|
|
|
import codechicken.nei.SearchField.ISearchProvider;
|
|
|
|
|
import codechicken.nei.api.API;
|
|
|
|
|
import codechicken.nei.api.ItemFilter;
|
|
|
|
|
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
2014-08-20 01:37:12 +10:00
|
|
|
import codechicken.nei.api.ItemInfo;
|
2014-06-29 20:31:37 +10:00
|
|
|
import codechicken.nei.guihook.GuiContainerManager;
|
2019-12-24 13:37:41 -08:00
|
|
|
import java.awt.Point;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.LinkedList;
|
2014-06-29 20:31:37 +10:00
|
|
|
import java.util.List;
|
2019-12-24 13:37:41 -08:00
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.TreeMap;
|
2021-02-20 09:51:28 -08:00
|
|
|
import java.util.concurrent.TimeUnit;
|
2014-07-23 21:03:03 +10:00
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
2021-02-20 09:51:28 -08:00
|
|
|
import java.util.concurrent.locks.Lock;
|
|
|
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
2014-12-14 17:10:00 +10:00
|
|
|
import java.util.regex.Pattern;
|
2022-06-24 12:32:13 +01:00
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
|
|
|
import net.minecraft.nbt.NBTTagList;
|
|
|
|
|
import net.minecraft.util.EnumChatFormatting;
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoadedCallback, ISearchProvider {
|
2021-02-20 09:51:28 -08:00
|
|
|
public static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock();
|
|
|
|
|
public static Lock writeLock = hiddenItemLock.writeLock();
|
|
|
|
|
public static Lock readLock = hiddenItemLock.readLock();
|
2022-06-24 12:32:13 +01:00
|
|
|
|
|
|
|
|
public static class SubsetState {
|
2014-06-29 20:31:37 +10:00
|
|
|
int state = 2;
|
2019-12-30 20:19:16 -08:00
|
|
|
ArrayList<ItemStack> items = new ArrayList<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
public static class SubsetTag {
|
|
|
|
|
protected class SubsetSlot extends GuiScrollSlot {
|
2014-06-29 20:31:37 +10:00
|
|
|
public SubsetSlot() {
|
|
|
|
|
super(0, 0, 0, 0);
|
|
|
|
|
setSmoothScroll(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int getSlotHeight(int slot) {
|
|
|
|
|
return 18;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected int getNumSlots() {
|
2022-06-24 12:32:13 +01:00
|
|
|
return children.size() + state.items.size();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void slotClicked(int slot, int button, int mx, int my, int count) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot < sorted.size()) {
|
2014-06-29 20:31:37 +10:00
|
|
|
SubsetTag tag = sorted.get(slot);
|
|
|
|
|
if (NEIClientUtils.shiftKey())
|
2019-12-24 13:37:41 -08:00
|
|
|
codechicken.nei.LayoutManager.searchField.setText("@" + tag.fullname);
|
2022-06-24 12:32:13 +01:00
|
|
|
else if (button == 0 && count >= 2) SubsetWidget.showOnly(tag);
|
|
|
|
|
else SubsetWidget.setHidden(tag, button == 1);
|
2014-07-03 15:50:24 +10:00
|
|
|
} else {
|
2022-06-24 12:32:13 +01:00
|
|
|
ItemStack item = state.items.get(slot - sorted.size());
|
|
|
|
|
if (NEIClientUtils.controlKey()) NEIClientUtils.cheatItem(item, button, -1);
|
|
|
|
|
else SubsetWidget.setHidden(state.items.get(slot - sorted.size()), button == 1);
|
2014-07-03 15:50:24 +10:00
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void drawSlot(int slot, int x, int y, int mx, int my, float frame) {
|
|
|
|
|
int w = windowBounds().width;
|
|
|
|
|
Rectangle4i r = new Rectangle4i(x, y, w, getSlotHeight(slot));
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot < sorted.size()) {
|
2014-06-29 20:31:37 +10:00
|
|
|
SubsetTag tag = sorted.get(slot);
|
2022-06-24 12:32:13 +01:00
|
|
|
codechicken.nei.LayoutManager.getLayoutStyle()
|
|
|
|
|
.drawSubsetTag(tag.displayName(), x, y, r.w, r.h, tag.state.state, r.contains(mx, my));
|
|
|
|
|
} else {
|
|
|
|
|
ItemStack stack = state.items.get(slot - sorted.size());
|
2014-06-29 20:31:37 +10:00
|
|
|
boolean hidden = SubsetWidget.isHidden(stack);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
int itemx = w / 2 - 8;
|
2014-06-29 20:31:37 +10:00
|
|
|
int itemy = 1;
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
codechicken.nei.LayoutManager.getLayoutStyle()
|
|
|
|
|
.drawSubsetTag(null, x, y, r.w, r.h, hidden ? 0 : 2, false);
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
GuiContainerManager.drawItem(x + itemx, y + itemy, stack);
|
|
|
|
|
if (new Rectangle4i(itemx, itemy, 16, 16).contains(mx, my)) SubsetWidget.hoverStack = stack;
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2022-06-24 12:32:13 +01:00
|
|
|
public void drawOverlay(float frame) {}
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void drawBackground(float frame) {
|
2022-06-24 12:32:13 +01:00
|
|
|
drawRect(x, y, x + width, y + height, 0xFF202020);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int scrollbarAlignment() {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void drawScrollbar(float frame) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (hasScrollbar()) super.drawScrollbar(frame);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public int scrollbarGuideAlignment() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public final String fullname;
|
|
|
|
|
public final ItemFilter filter;
|
2019-12-30 20:19:16 -08:00
|
|
|
public TreeMap<String, SubsetTag> children = new TreeMap<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
public List<SubsetTag> sorted = Collections.emptyList();
|
|
|
|
|
private int childwidth;
|
|
|
|
|
|
|
|
|
|
protected SubsetState state = new SubsetState();
|
|
|
|
|
protected final SubsetSlot slot = new SubsetSlot();
|
|
|
|
|
private SubsetTag selectedChild;
|
|
|
|
|
private int visible;
|
|
|
|
|
|
|
|
|
|
public SubsetTag(String fullname) {
|
|
|
|
|
this(fullname, new NothingItemFilter());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public SubsetTag(String fullname, ItemFilter filter) {
|
|
|
|
|
assert filter != null : "Filter cannot be null";
|
|
|
|
|
this.fullname = EnumChatFormatting.getTextWithoutFormattingCodes(fullname);
|
|
|
|
|
this.filter = filter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String displayName() {
|
2022-06-24 12:32:13 +01:00
|
|
|
String translated = translate("subsets." + fullname);
|
|
|
|
|
if (!translated.startsWith("nei.")) return translated;
|
2015-04-25 23:41:18 +10:00
|
|
|
|
|
|
|
|
int idx = fullname.lastIndexOf('.');
|
|
|
|
|
return idx < 0 ? fullname : fullname.substring(idx + 1);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String name() {
|
|
|
|
|
int idx = fullname.indexOf('.');
|
2022-06-24 12:32:13 +01:00
|
|
|
return idx < 0 ? fullname : fullname.substring(idx + 1);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String parent() {
|
|
|
|
|
int idx = fullname.lastIndexOf('.');
|
|
|
|
|
return idx < 0 ? null : fullname.substring(0, idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private SubsetTag getTag(String name) {
|
|
|
|
|
int idx = name.indexOf('.');
|
|
|
|
|
String childname = idx > 0 ? name.substring(0, idx) : name;
|
|
|
|
|
SubsetTag child = children.get(childname.toLowerCase());
|
2022-06-24 12:32:13 +01:00
|
|
|
if (child == null) return null;
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
return idx > 0 ? child.getTag(name.substring(idx + 1)) : child;
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void recacheChildren() {
|
2019-12-30 20:19:16 -08:00
|
|
|
sorted = new ArrayList<>(children.values());
|
2014-06-29 20:31:37 +10:00
|
|
|
childwidth = 0;
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag tag : sorted) childwidth = Math.max(childwidth, tag.nameWidth() + 2);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void addTag(SubsetTag tag) {
|
2022-06-24 12:32:13 +01:00
|
|
|
String name = fullname == null ? tag.fullname : tag.fullname.substring(fullname.length() + 1);
|
2014-06-29 20:31:37 +10:00
|
|
|
int idx = name.indexOf('.');
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (idx < 0) { // add or replace tag
|
2014-06-29 20:31:37 +10:00
|
|
|
SubsetTag prev = children.put(name.toLowerCase(), tag);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (prev != null) { // replaced, load children
|
2014-06-29 20:31:37 +10:00
|
|
|
tag.children = prev.children;
|
|
|
|
|
tag.sorted = prev.sorted;
|
|
|
|
|
}
|
|
|
|
|
recacheChildren();
|
2022-06-24 12:32:13 +01:00
|
|
|
} else {
|
2014-06-29 20:31:37 +10:00
|
|
|
String childname = name.substring(0, idx);
|
|
|
|
|
SubsetTag child = children.get(childname.toLowerCase());
|
2022-06-24 12:32:13 +01:00
|
|
|
if (child == null)
|
|
|
|
|
children.put(
|
|
|
|
|
childname.toLowerCase(),
|
|
|
|
|
child = new SubsetTag(fullname == null ? childname : fullname + '.' + childname));
|
2014-06-29 20:31:37 +10:00
|
|
|
recacheChildren();
|
|
|
|
|
child.addTag(tag);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void cacheState() {
|
|
|
|
|
state = SubsetWidget.getState(this);
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag tag : sorted) tag.cacheState();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
2022-05-06 22:41:45 +03:00
|
|
|
|
2021-04-10 15:32:59 -07:00
|
|
|
public void addFiltersWithItem(List<ItemFilter> filters, String itemSearch) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (itemSearch == null) {
|
2021-04-10 15:32:59 -07:00
|
|
|
addFilters(filters);
|
|
|
|
|
} else {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (filter != null) filters.add(new DoubleFilteredFilter(filter, itemSearch));
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag child : sorted) child.addFiltersWithItem(filters, itemSearch);
|
2021-04-10 15:32:59 -07:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-24 12:32:13 +01:00
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
public void addFilters(List<ItemFilter> filters) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (filter != null) filters.add(filter);
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag child : sorted) child.addFilters(filters);
|
2014-12-14 17:10:00 +10:00
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
public void search(List<SubsetTag> tags, Pattern p) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (fullname != null && p.matcher(fullname.toLowerCase()).find()) tags.add(this);
|
|
|
|
|
else for (SubsetTag child : sorted) child.search(tags, p);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void updateVisiblity(int mx, int my) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null) {
|
2014-06-29 20:31:37 +10:00
|
|
|
selectedChild.updateVisiblity(mx, my);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!selectedChild.isVisible()) selectedChild = null;
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot.contains(mx, my) && (selectedChild == null || !selectedChild.contains(mx, my))) {
|
2014-06-29 20:31:37 +10:00
|
|
|
int mslot = slot.getClickedSlot(my);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (mslot >= 0 && mslot < sorted.size()) {
|
2014-06-29 20:31:37 +10:00
|
|
|
SubsetTag mtag = sorted.get(mslot);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (mtag != null) {
|
|
|
|
|
if (mtag != selectedChild && selectedChild != null) selectedChild.setHidden();
|
2014-06-29 20:31:37 +10:00
|
|
|
selectedChild = mtag;
|
|
|
|
|
selectedChild.setVisible();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setVisible();
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild == null) countdownVisible();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setHidden() {
|
|
|
|
|
visible = 0;
|
2022-06-24 12:32:13 +01:00
|
|
|
slot.mouseMovedOrUp(0, 0, 0); // cancel any scrolling
|
|
|
|
|
if (selectedChild != null) {
|
2014-06-29 20:31:37 +10:00
|
|
|
selectedChild.setHidden();
|
|
|
|
|
selectedChild = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setVisible() {
|
|
|
|
|
visible = 10;
|
|
|
|
|
cacheState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void countdownVisible() {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (visible > 0 && --visible == 0) setHidden();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void resize(int x, int pwidth, int y) {
|
|
|
|
|
int mheight = area.h;
|
2022-06-24 12:32:13 +01:00
|
|
|
int dheight = area.y2() - y;
|
2014-06-29 20:31:37 +10:00
|
|
|
int cheight = slot.contentHeight();
|
|
|
|
|
int height = cheight;
|
2022-06-24 12:32:13 +01:00
|
|
|
if (cheight > mheight) {
|
2014-06-29 20:31:37 +10:00
|
|
|
y = area.y;
|
|
|
|
|
height = mheight;
|
2022-06-24 12:32:13 +01:00
|
|
|
} else if (cheight > dheight) {
|
2014-06-29 20:31:37 +10:00
|
|
|
y = area.y2() - cheight;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
height = height / slot.getSlotHeight(0) * slot.getSlotHeight(0); // floor to a multiple of slot height
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
int width = childwidth;
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!state.items.isEmpty()) width = Math.max(childwidth, 18);
|
|
|
|
|
if (slot.contentHeight() > height) width += slot.scrollbarDim().width;
|
|
|
|
|
|
|
|
|
|
boolean fitLeft = x - width >= area.x1();
|
|
|
|
|
boolean fitRight = x + width + pwidth <= area.x2();
|
|
|
|
|
if (pwidth >= 0 ? !fitRight && fitLeft : !fitLeft) pwidth *= -1; // swap
|
2014-06-29 20:31:37 +10:00
|
|
|
x += pwidth >= 0 ? pwidth : -width;
|
|
|
|
|
|
|
|
|
|
slot.setSize(x, y, width, height);
|
|
|
|
|
slot.setMargins(slot.hasScrollbar() ? slot.scrollbarDim().width : 0, 0, 0, 0);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null) {
|
|
|
|
|
y = slot.getSlotY(sorted.indexOf(selectedChild)) - slot.scrolledPixels() + slot.y;
|
2014-06-29 20:31:37 +10:00
|
|
|
selectedChild.resize(x, pwidth >= 0 ? width : -width, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected int nameWidth() {
|
|
|
|
|
return Minecraft.getMinecraft().fontRenderer.getStringWidth(displayName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isVisible() {
|
|
|
|
|
return visible > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void draw(int mx, int my) {
|
|
|
|
|
slot.draw(mx, my, 0);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null) selectedChild.draw(mx, my);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean contains(int px, int py) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return slot.contains(px, py) || selectedChild != null && selectedChild.contains(px, py);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void mouseClicked(int mx, int my, int button) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null && selectedChild.contains(mx, my)) selectedChild.mouseClicked(mx, my, button);
|
|
|
|
|
else if (slot.contains(mx, my)) slot.mouseClicked(mx, my, button);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void mouseDragged(int mx, int my, int button, long heldTime) {
|
|
|
|
|
slot.mouseDragged(mx, my, button, heldTime);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null) selectedChild.mouseDragged(mx, my, button, heldTime);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void mouseUp(int mx, int my, int button) {
|
|
|
|
|
slot.mouseMovedOrUp(mx, my, button);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null) selectedChild.mouseUp(mx, my, button);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean mouseScrolled(int mx, int my, int scroll) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot.hasScrollbar() && slot.contains(mx, my)) {
|
2014-06-29 20:31:37 +10:00
|
|
|
slot.scroll(scroll);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (selectedChild != null && selectedChild.mouseScrolled(mx, my, scroll)) return true;
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (slot.hasScrollbar() && !contains(mx, my)) {
|
2014-06-29 20:31:37 +10:00
|
|
|
slot.scroll(scroll);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isScrolling() {
|
2022-06-24 12:32:13 +01:00
|
|
|
return slot.isScrolling() || selectedChild != null && selectedChild.isScrolling();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected static final SubsetTag root = new SubsetTag(null);
|
|
|
|
|
public static Rectangle4i area = new Rectangle4i();
|
|
|
|
|
public static ItemStack hoverStack;
|
|
|
|
|
|
2019-12-30 20:19:16 -08:00
|
|
|
private static HashMap<String, SubsetState> subsetState = new HashMap<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
/**
|
|
|
|
|
* All operations on this variable should be synchronised.
|
|
|
|
|
*/
|
2014-07-03 19:28:59 +10:00
|
|
|
private static final ItemStackSet hiddenItems = new ItemStackSet();
|
2022-06-24 12:32:13 +01:00
|
|
|
|
2019-12-30 20:19:16 -08:00
|
|
|
private static final AtomicReference<NBTTagList> dirtyHiddenItems = new AtomicReference<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
public static SubsetState getState(SubsetTag tag) {
|
|
|
|
|
SubsetState state = subsetState.get(tag.fullname);
|
|
|
|
|
return state == null ? new SubsetState() : state;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void addTag(SubsetTag tag) {
|
2014-07-23 21:03:03 +10:00
|
|
|
updateState.stop();
|
2014-06-29 20:31:37 +10:00
|
|
|
synchronized (root) {
|
|
|
|
|
root.addTag(tag);
|
2014-07-23 21:03:03 +10:00
|
|
|
updateState.reallocate();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static SubsetTag getTag(String name) {
|
|
|
|
|
return name == null ? root : root.getTag(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static boolean isHidden(ItemStack item) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (readLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
return hiddenItems.contains(item);
|
|
|
|
|
} finally {
|
|
|
|
|
readLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain read lock in 'isHidden'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
2021-02-20 09:51:28 -08:00
|
|
|
return false;
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void _setHidden(SubsetTag tag, boolean hidden) {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemStack item : getState(tag).items) _setHidden(item, hidden);
|
|
|
|
|
for (SubsetTag child : tag.sorted) _setHidden(child, hidden);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void _setHidden(ItemStack item, boolean hidden) {
|
2021-02-20 09:51:28 -08:00
|
|
|
if (hiddenItemLock.isWriteLockedByCurrentThread()) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (hidden) hiddenItems.add(item);
|
|
|
|
|
else hiddenItems.remove(item);
|
2021-02-20 09:51:28 -08:00
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void showOnly(SubsetTag tag) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemStack item : ItemList.items) _setHidden(item, true);
|
2021-02-20 09:51:28 -08:00
|
|
|
setHidden(tag, false);
|
|
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain write lock in 'showOnly'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setHidden(SubsetTag tag, boolean hidden) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
_setHidden(tag, hidden);
|
|
|
|
|
updateHiddenItems();
|
|
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void setHidden(ItemStack item, boolean hidden) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
_setHidden(item, hidden);
|
|
|
|
|
updateHiddenItems();
|
|
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-03 19:28:59 +10:00
|
|
|
public static void unhideAll() {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
hiddenItems.clear();
|
|
|
|
|
updateHiddenItems();
|
|
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain write lock in 'unhideAll'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void updateHiddenItems() {
|
|
|
|
|
prepareDirtyHiddenItems.restart();
|
|
|
|
|
updateState.restart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void loadHidden() {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
hiddenItems.clear();
|
|
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain write lock in 'loadHidden'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
return;
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
2019-12-30 20:19:16 -08:00
|
|
|
List<ItemStack> itemList = new LinkedList<>();
|
2014-07-23 21:03:03 +10:00
|
|
|
try {
|
|
|
|
|
NBTTagList list = NEIClientConfig.world.nbt.getTagList("hiddenItems", 10);
|
2022-06-24 12:32:13 +01:00
|
|
|
for (int i = 0; i < list.tagCount(); i++)
|
2014-07-23 21:03:03 +10:00
|
|
|
itemList.add(ItemStack.loadItemStackFromNBT(list.getCompoundTagAt(i)));
|
2022-06-24 12:32:13 +01:00
|
|
|
} catch (Exception e) {
|
2014-07-23 21:03:03 +10:00
|
|
|
NEIClientConfig.logger.error("Error loading hiddenItems", e);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (writeLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemStack item : itemList) hiddenItems.add(item);
|
2021-02-20 09:51:28 -08:00
|
|
|
} finally {
|
|
|
|
|
writeLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain second write lock in 'loadHidden'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
updateState.restart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void saveHidden() {
|
|
|
|
|
NBTTagList list = dirtyHiddenItems.getAndSet(null);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (list != null) {
|
2014-07-23 21:03:03 +10:00
|
|
|
NEIClientConfig.world.nbt.setTag("hiddenItems", list);
|
|
|
|
|
NEIClientConfig.world.saveNBT();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
private static final RestartableTask prepareDirtyHiddenItems = new RestartableTask("NEI Subset Save Thread") {
|
2014-07-23 21:03:03 +10:00
|
|
|
private List<ItemStack> getList() {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (readLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
return hiddenItems.values();
|
|
|
|
|
} finally {
|
|
|
|
|
readLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain read lock in 'NEI Subset Save Thread'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
2021-02-20 09:51:28 -08:00
|
|
|
return new ArrayList<>();
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void execute() {
|
|
|
|
|
NBTTagList list = new NBTTagList();
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemStack item : getList()) {
|
|
|
|
|
if (interrupted()) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
NBTTagCompound tag = new NBTTagCompound();
|
|
|
|
|
item.writeToNBT(tag);
|
|
|
|
|
list.appendTag(tag);
|
|
|
|
|
}
|
|
|
|
|
dirtyHiddenItems.set(list);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private static final UpdateStateTask updateState = new UpdateStateTask();
|
2022-06-24 12:32:13 +01:00
|
|
|
|
|
|
|
|
private static class UpdateStateTask extends RestartableTask {
|
2014-07-23 21:03:03 +10:00
|
|
|
private volatile boolean reallocate;
|
|
|
|
|
|
|
|
|
|
public UpdateStateTask() {
|
|
|
|
|
super("NEI Subset Item Allocation");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void clearTasks() {
|
|
|
|
|
super.clearTasks();
|
|
|
|
|
reallocate = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public synchronized void reallocate() {
|
2020-01-08 21:32:53 -08:00
|
|
|
// System.out.println("NEI Subset - Reallocate");
|
|
|
|
|
// Thread.dumpStack();
|
2014-07-23 21:03:03 +10:00
|
|
|
reallocate = true;
|
|
|
|
|
restart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void execute() {
|
2020-01-08 21:32:53 -08:00
|
|
|
// System.out.println("Executing NEI Subset Item Allocation");
|
2019-12-30 20:19:16 -08:00
|
|
|
HashMap<String, SubsetState> state = new HashMap<>();
|
|
|
|
|
List<SubsetTag> tags = new LinkedList<>();
|
2014-07-23 21:03:03 +10:00
|
|
|
synchronized (root) {
|
|
|
|
|
cloneStates(root, tags, state);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (interrupted()) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (reallocate) {
|
2014-07-23 21:03:03 +10:00
|
|
|
for (ItemStack item : ItemList.items) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (interrupted()) return;
|
|
|
|
|
if (ItemInfo.isHidden(item)) continue;
|
2014-07-23 21:03:03 +10:00
|
|
|
for (SubsetTag tag : tags)
|
|
|
|
|
if (tag.filter.matches(item))
|
|
|
|
|
state.get(tag.fullname).items.add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
synchronized (root) {
|
|
|
|
|
calculateVisibility(root, state);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (interrupted()) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
subsetState = state;
|
|
|
|
|
ItemList.updateFilter.restart();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void cloneStates(SubsetTag tag, List<SubsetTag> tags, HashMap<String, SubsetState> state) {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag child : tag.sorted) {
|
|
|
|
|
if (interrupted()) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
cloneStates(child, tags, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tags.add(tag);
|
|
|
|
|
SubsetState sstate = new SubsetState();
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!reallocate) sstate.items = SubsetWidget.getState(tag).items;
|
2014-07-23 21:03:03 +10:00
|
|
|
state.put(tag.fullname, sstate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void calculateVisibility(SubsetTag tag, Map<String, SubsetState> state) {
|
|
|
|
|
SubsetState sstate = state.get(tag.fullname);
|
|
|
|
|
int hidden = 0;
|
2022-06-24 12:32:13 +01:00
|
|
|
for (SubsetTag child : tag.sorted) {
|
|
|
|
|
if (interrupted()) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
calculateVisibility(child, state);
|
|
|
|
|
int cstate = state.get(child.fullname).state;
|
2022-06-24 12:32:13 +01:00
|
|
|
if (cstate == 1) sstate.state = 1;
|
|
|
|
|
else if (cstate == 0) hidden++;
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (sstate.state == 1) return;
|
2014-07-23 21:03:03 +10:00
|
|
|
|
|
|
|
|
List<ItemStack> items = sstate.items;
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemStack item : items) {
|
|
|
|
|
if (interrupted()) return;
|
|
|
|
|
if (isHidden(item)) hidden++;
|
2014-07-23 21:03:03 +10:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (hidden == tag.sorted.size() + items.size()) sstate.state = 0;
|
|
|
|
|
else if (hidden > 0) sstate.state = 1;
|
2014-07-03 19:28:59 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
private long lastclicktime;
|
|
|
|
|
|
|
|
|
|
public SubsetWidget() {
|
|
|
|
|
super("NEI Subsets");
|
|
|
|
|
API.addItemFilter(this);
|
|
|
|
|
API.addSearchProvider(this);
|
|
|
|
|
ItemList.loadCallbacks.add(this);
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-25 23:41:18 +10:00
|
|
|
@Override
|
|
|
|
|
public String getRenderLabel() {
|
|
|
|
|
return translate("inventory.item_subsets");
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
@Override
|
|
|
|
|
public void draw(int mx, int my) {
|
|
|
|
|
super.draw(mx, my);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
area.set(x, y + h, w, LayoutManager.searchField.y - h - y); // 23 for the search box
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
hoverStack = null;
|
|
|
|
|
if (root.isVisible()) {
|
|
|
|
|
root.resize(area.x, 0, area.y);
|
|
|
|
|
root.cacheState();
|
|
|
|
|
root.draw(mx, my);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void update() {
|
|
|
|
|
Point mouse = GuiDraw.getMousePosition();
|
|
|
|
|
updateVisiblity(mouse.x, mouse.y);
|
2014-07-03 19:28:59 +10:00
|
|
|
saveHidden();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateVisiblity(int mx, int my) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!root.isVisible() || root.isScrolling()) return;
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
root.updateVisiblity(mx, my);
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!root.isVisible() && bounds().contains(mx, my)) root.setVisible();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean contains(int px, int py) {
|
2022-06-24 12:32:13 +01:00
|
|
|
return super.contains(px, py) || root.isVisible() && root.contains(px, py);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean handleClick(int mx, int my, int button) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (root.isVisible() && root.contains(mx, my)) {
|
2014-06-29 20:31:37 +10:00
|
|
|
root.mouseClicked(mx, my, button);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
if (button == 0) {
|
|
|
|
|
if (System.currentTimeMillis() - lastclicktime < 500) unhideAll();
|
|
|
|
|
else root.setVisible();
|
2014-06-29 20:31:37 +10:00
|
|
|
|
|
|
|
|
NEIClientUtils.playClickSound();
|
|
|
|
|
lastclicktime = System.currentTimeMillis();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Not called
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onButtonPress(boolean rightclick) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseDragged(int mx, int my, int button, long heldTime) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (root.isVisible()) root.mouseDragged(mx, my, button, heldTime);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void mouseUp(int mx, int my, int button) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (root.isVisible()) root.mouseUp(mx, my, button);
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onMouseWheel(int i, int mx, int my) {
|
|
|
|
|
return root.isVisible() && root.mouseScrolled(mx, my, -i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onGuiClick(int mx, int my) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!contains(mx, my)) root.setHidden();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ItemStack getStackMouseOver(int mx, int my) {
|
|
|
|
|
return hoverStack;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public ItemFilter getFilter() {
|
2022-06-24 12:32:13 +01:00
|
|
|
// synchronise access on hiddenItems
|
2019-12-24 13:37:41 -08:00
|
|
|
return item -> {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (readLock.tryLock(5, TimeUnit.SECONDS)) {
|
2021-02-20 09:51:28 -08:00
|
|
|
try {
|
|
|
|
|
return !hiddenItems.matches(item);
|
|
|
|
|
} finally {
|
|
|
|
|
readLock.unlock();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NEIClientConfig.logger.error("Unable to obtain read lock in 'getFilter'");
|
|
|
|
|
}
|
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
|
e.printStackTrace();
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
2021-02-20 09:51:28 -08:00
|
|
|
return false;
|
2014-06-29 20:31:37 +10:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-26 12:39:37 +10:00
|
|
|
@Override
|
|
|
|
|
public boolean isPrimary() {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
@Override
|
|
|
|
|
public ItemFilter getFilter(String searchText) {
|
2022-06-24 12:32:13 +01:00
|
|
|
if (!searchText.startsWith("@")) return null;
|
2014-06-29 20:31:37 +10:00
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
searchText = searchText.substring(1);
|
2021-04-10 15:32:59 -07:00
|
|
|
String itemSearch = null;
|
2022-06-24 12:32:13 +01:00
|
|
|
if (searchText.contains("->")) {
|
2021-04-10 15:32:59 -07:00
|
|
|
String[] split = searchText.split("->");
|
|
|
|
|
searchText = split[0];
|
2022-06-24 12:32:13 +01:00
|
|
|
if (split.length > 1) itemSearch = split[1];
|
2021-04-10 15:32:59 -07:00
|
|
|
}
|
2022-06-24 12:32:13 +01:00
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
AnyMultiItemFilter filter = new AnyMultiItemFilter();
|
|
|
|
|
SubsetTag tag = getTag(searchText);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (tag != null) {
|
2021-04-10 15:32:59 -07:00
|
|
|
// We've got an exact match
|
|
|
|
|
tag.addFiltersWithItem(filter.filters, itemSearch);
|
2022-06-24 12:32:13 +01:00
|
|
|
} else {
|
2021-04-10 15:32:59 -07:00
|
|
|
// Try searching for a substring
|
2014-12-14 17:10:00 +10:00
|
|
|
Pattern p = SearchField.getPattern(searchText);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (p == null) return null;
|
2014-12-14 17:10:00 +10:00
|
|
|
|
2019-12-30 20:19:16 -08:00
|
|
|
List<SubsetTag> matching = new LinkedList<>();
|
2014-12-14 17:10:00 +10:00
|
|
|
root.search(matching, p);
|
2022-06-24 12:32:13 +01:00
|
|
|
if (matching.isEmpty()) return null;
|
|
|
|
|
for (SubsetTag tag2 : matching) {
|
2021-04-10 15:32:59 -07:00
|
|
|
tag2.addFiltersWithItem(filter.filters, itemSearch);
|
|
|
|
|
}
|
2014-12-14 17:10:00 +10:00
|
|
|
}
|
2022-06-24 12:32:13 +01:00
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
return filter;
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void itemsLoaded() {
|
2014-07-23 21:03:03 +10:00
|
|
|
updateState.reallocate();
|
2014-07-03 19:28:59 +10:00
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
}
|