Skip to content

Commit

Permalink
Make it possible to pause sorting of items in the QIO Dashboard by ho…
Browse files Browse the repository at this point in the history
…lding shift
  • Loading branch information
pupnewfster committed Jan 3, 2025
1 parent f34ea72 commit 18bd8d9
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 128 deletions.
28 changes: 15 additions & 13 deletions src/main/java/mekanism/client/gui/element/scroll/GuiSlotScroll.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import mekanism.common.util.MekanismUtils.ResourceType;
import mekanism.common.util.UnitDisplayUtils;
import mekanism.common.util.text.TextUtils;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.Rect2i;
Expand All @@ -33,6 +34,7 @@ public class GuiSlotScroll extends GuiElement implements IRecipeViewerIngredient

private static final ResourceLocation SLOTS = MekanismUtils.getResource(ResourceType.GUI_SLOT, "slots.png");
private static final ResourceLocation SLOTS_DARK = MekanismUtils.getResource(ResourceType.GUI_SLOT, "slots_dark.png");
private static final Component ZERO = TextComponentUtil.build(ChatFormatting.YELLOW, 0);

private final GuiScrollBar scrollBar;

Expand Down Expand Up @@ -130,31 +132,36 @@ private IScrollableSlot getSlot(double mouseX, double mouseY) {
}

private void renderSlot(GuiGraphics guiGraphics, IScrollableSlot slot, int slotX, int slotY) {
// sanity checks
if (isSlotEmpty(slot)) {
ItemStack stack = slot.getInternalStack();
if (stack.isEmpty()) {//Sanity check
return;
}
gui().renderItemWithOverlay(guiGraphics, slot.getInternalStack(), relativeX + slotX + 1, relativeY + slotY + 1, 1, "");
gui().renderItemWithOverlay(guiGraphics, stack, relativeX + slotX + 1, relativeY + slotY + 1, 1, "");
long count = slot.count();
if (count > 1) {
Component text;
Component text = null;
if (count == 0) {
//If there is no items stored, display the text in yellow, similar to what mojang does when it has to display a zero count
// See: AbstractContainerScreen#render(GuiGraphics, int, int, float) and rendering the dragging item
text = ZERO;
} else if (count > 1) {
//Note: For cases like 9,999,999 we intentionally display as 9999.9K instead of 10M so that people
// do not think they have more stored than they actually have just because it is rounding up
if (count < 10_000) {
text = TextComponentUtil.getString(Long.toString(count));
} else {
text = UnitDisplayUtils.getDisplay(count, 1);
}
}
if (text != null) {
renderSlotText(guiGraphics, text, slotX + 1, slotY + 1);
}
}

private void renderSlotTooltip(GuiGraphics guiGraphics, IScrollableSlot slot, int slotX, int slotY) {
// sanity checks
if (isSlotEmpty(slot)) {
ItemStack stack = slot.getInternalStack();
if (stack.isEmpty()) {//Sanity check
return;
}
ItemStack stack = slot.getInternalStack();
long count = slot.count();
if (count < 10_000) {
guiGraphics.renderTooltip(font(), stack, slotX, slotY);
Expand All @@ -165,11 +172,6 @@ private void renderSlotTooltip(GuiGraphics guiGraphics, IScrollableSlot slot, in
}
}

private boolean isSlotEmpty(IScrollableSlot slot) {
//Count is not expected to be zero, but validate it anyway
return slot.count() == 0 || slot.getInternalStack().isEmpty();
}

private void renderSlotText(GuiGraphics guiGraphics, Component text, int x, int y) {
float scale = 0.6F;
float scaledWidth = font().width(text) * scale;
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/mekanism/client/gui/qio/GuiQIOItemViewer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mekanism.client.gui.qio;

import com.google.common.collect.Sets;
import com.mojang.blaze3d.platform.InputConstants;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -36,6 +37,7 @@
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Inventory;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.glfw.GLFW;

public abstract class GuiQIOItemViewer<CONTAINER extends QIOItemViewerContainer> extends GuiMekanism<CONTAINER> implements ResizeController {

Expand Down Expand Up @@ -120,6 +122,7 @@ protected void drawForegroundText(@NotNull GuiGraphics guiGraphics, int mouseX,

@Override
protected void repositionElements() {
boolean wasOnRecipeViewer = switchingToRecipeViewer;
super.repositionElements();
//Validate the height is still valid, and if it isn't recreate it
int maxY = QIOItemViewerContainer.getSlotsYMax();
Expand All @@ -129,6 +132,9 @@ protected void repositionElements() {
// save the updated config info
MekanismConfig.client.save();
recreateViewer();
} else if (wasOnRecipeViewer) {
//When switching back to the QIO Item Viewer from a recipe viewer, we want to ensure that we update the current pause state
menu.pauseSorting(hasShiftDown());
}
}

Expand Down Expand Up @@ -199,4 +205,25 @@ protected void transferWindows(Collection<GuiWindow> windows) {
}

public abstract GuiQIOItemViewer<CONTAINER> recreate(CONTAINER container);

@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (keyCode == GLFW.GLFW_KEY_LEFT_SHIFT || keyCode == GLFW.GLFW_KEY_RIGHT_SHIFT) {
menu.pauseSorting(true);
}
return super.keyPressed(keyCode, scanCode, modifiers);
}

@Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
//Note: We only want to unpause sorting if they aren't pressing shift. If they were pressing both shift keys and then released one
// we want to make sure it stays paused. We just pass the value of if the other key is pressed and let the code that handles
// pausing/unpausing on value change handle determining if we should stay paused
if (keyCode == GLFW.GLFW_KEY_LEFT_SHIFT) {
menu.pauseSorting(InputConstants.isKeyDown(getMinecraft().getWindow().getWindow(), GLFW.GLFW_KEY_RIGHT_SHIFT));
} else if (keyCode == GLFW.GLFW_KEY_RIGHT_SHIFT) {
menu.pauseSorting(InputConstants.isKeyDown(getMinecraft().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_SHIFT));
}
return super.keyReleased(keyCode, scanCode, modifiers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ public QIOCraftingTransferHelper(Collection<? extends IScrollableSlot> cachedInv
isValid = true;
reverseLookup = new HashMap<>();
for (IScrollableSlot source : cachedInventory) {
reverseLookup.computeIfAbsent(source.asRawHashedItem(), item -> new HashedItemSource()).addQIOSlot(source.itemUUID(), source.count());
//Skip any items that are only still in the cache due to sorting being paused, as we don't have any of it available for crafting
if (source.count() > 0) {
reverseLookup.computeIfAbsent(source.asRawHashedItem(), item -> new HashedItemSource()).addQIOSlot(source.itemUUID(), source.count());
}
}
byte inventorySlotIndex = 0;
for (; inventorySlotIndex < 9; inventorySlotIndex++) {
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/mekanism/common/content/qio/SearchQueryParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,20 @@
*/
public class SearchQueryParser {

private static final ISearchQuery INVALID = (level, player, stack) -> false;
private static final Set<Character> TERMINATORS = Set.of('|', '(', '\"', '\'');

public static ISearchQuery parse(String query) {
if (query == null || query.isEmpty()) {
return ISearchQuery.INVALID;
}
return parse(query, new HashSet<>());
}

@VisibleForTesting
public static ISearchQuery parseOrdered(String query) {
if (query == null || query.isEmpty()) {
return ISearchQuery.INVALID;
}
return parse(query, new LinkedHashSet<>());
}

Expand Down Expand Up @@ -69,7 +74,7 @@ private static ISearchQuery parse(String query, Set<SearchQuery> ret) {
// read the key string(s) of the given query type
KeyListResult keyListResult = readKeyList(query, i, type, curQuery);
if (!keyListResult.hasResult()) {
return INVALID;
return ISearchQuery.INVALID;
}
i = keyListResult.index();
}
Expand Down Expand Up @@ -367,6 +372,8 @@ public int hashCode() {
@FunctionalInterface
public interface ISearchQuery {

ISearchQuery INVALID = (level, player, stack) -> false;

boolean test(@Nullable Level level, @Nullable Player player, ItemStack stack);

default boolean isInvalid() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Range;

public interface ISlotClickHandler {

Expand All @@ -26,6 +27,7 @@ default HashedItem asRawHashedItem() {

UUID itemUUID();

@Range(from = 0, to = Long.MAX_VALUE)
long count();

default String getDisplayName() {
Expand Down
Loading

0 comments on commit 18bd8d9

Please sign in to comment.