diff options
Diffstat (limited to 'runtime-frontend/favorites-entries/src/main')
20 files changed, 3075 insertions, 0 deletions
diff --git a/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidgetImpl.java b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidgetImpl.java new file mode 100644 index 000000000..ecc652dd1 --- /dev/null +++ b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidgetImpl.java @@ -0,0 +1,259 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget.favorites; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.REIRuntime; +import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.favorites.FavoriteEntry; +import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; +import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponent; +import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentProviderWidget; +import me.shedaniel.rei.api.client.gui.drag.component.DraggableComponentVisitorWidget; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; +import me.shedaniel.rei.api.client.overlay.OverlayListWidget; +import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; +import me.shedaniel.rei.impl.client.gui.overlay.entries.FavoritesListWidget; +import me.shedaniel.rei.impl.client.gui.overlay.widgets.ScaleIndicatorWidget; +import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryManager; +import me.shedaniel.rei.impl.client.gui.widget.favorites.history.DisplayHistoryWidget; +import me.shedaniel.rei.impl.client.gui.widget.favorites.listeners.FavoritesRegionListener; +import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.FavoritesPanel; +import me.shedaniel.rei.impl.client.gui.widget.favorites.panel.FavoritesTogglePanelButton; +import me.shedaniel.rei.impl.client.gui.widget.favorites.trash.TrashWidget; +import me.shedaniel.rei.impl.client.gui.widget.region.EntryStacksRegionWidget; +import me.shedaniel.rei.impl.common.util.RectangleUtils; +import net.minecraft.client.gui.screens.Screen; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; + +@ApiStatus.Internal +public class FavoritesListWidgetImpl extends WidgetWithBounds implements FavoritesListWidget, DraggableComponentProviderWidget<Object>, DraggableComponentVisitorWidget, OverlayListWidget { + public Rectangle fullBounds; + public Rectangle excludedBounds; + public Rectangle favoritesBounds; + private final EntryStacksRegionWidget<FavoriteEntry> region = new EntryStacksRegionWidget<>(new FavoritesRegionListener(this)); + + public final FavoritesPanel favoritePanel = new FavoritesPanel(this, region); + public final TrashWidget trash = new TrashWidget(this); + public final DisplayHistoryWidget displayHistory = new DisplayHistoryWidget(this); + public final FavoritesTogglePanelButton togglePanelButton = new FavoritesTogglePanelButton(this); + private final List<Widget> children = ImmutableList.of(favoritePanel, togglePanelButton, region); + private final ScaleIndicatorWidget scaleIndicator = new ScaleIndicatorWidget(); + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + if (fullBounds.contains(mouseX, mouseY)) { + if (Screen.hasControlDown()) { + ConfigManagerInternal manager = ConfigManagerInternal.getInstance(); + manager.set("advanced.accessibility.entrySize", manager.getConfig().getEntrySize() + amount * 0.075); + scaleIndicator.set(); + } else if (favoritePanel.mouseScrolled(mouseX, mouseY, amount)) { + return true; + } else if (displayHistory.mouseScrolled(mouseX, mouseY, amount)) { + return true; + } + } + return super.mouseScrolled(mouseX, mouseY, amount); + } + + @Override + public Rectangle getBounds() { + return fullBounds; + } + + public EntryStacksRegionWidget<FavoriteEntry> getRegion() { + return region; + } + + @Override + @Nullable + public DraggableComponent<Object> getHovered(DraggingContext<Screen> context, double mouseX, double mouseY) { + DraggableComponent<?> stack = region.getHoveredStack(context, mouseX, mouseY); + if (stack != null) return (DraggableComponent<Object>) stack; + if (favoritePanel.containsMouse(mouseX, mouseY)) { + stack = favoritePanel.getHoveredStack(mouseX, mouseY); + if (stack != null) return (DraggableComponent<Object>) stack; + } + stack = displayHistory.getHovered(context, mouseX, mouseY); + if (stack != null) return (DraggableComponent<Object>) stack; + + return null; + } + + @Override + public DraggedAcceptorResult acceptDragged(DraggingContext<Screen> context, DraggableComponent<?> stack) { + if (favoritePanel.containsMouse(context.getCurrentPosition()) || trash.containsMouse(context.getCurrentPosition())) { + context.renderToVoid(stack); + return DraggedAcceptorResult.CONSUMED; + } + return Stream.of(region, displayHistory) + .map(visitor -> visitor.acceptDragged(context, stack)) + .filter(result -> result != DraggedAcceptorResult.PASS) + .findFirst() + .orElse(DraggedAcceptorResult.PASS); + } + + @Override + public EntryStack<?> getFocusedStack() { + Point mouse = mouse(); + EntryStack<?> stack = region.getFocusedStack(); + if (stack != null && !stack.isEmpty()) return stack; + if (favoritePanel.containsMouse(mouse)) { + EntryStack<?> focusedStack = favoritePanel.getFocusedStack(mouse); + + if (focusedStack != null) { + return focusedStack; + } + } + return EntryStack.empty(); + } + + @Override + public Stream<EntryStack<?>> getEntries() { + return region.getEntries(); + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + if (fullBounds.isEmpty()) + return; + + this.trash.render(matrices, mouseX, mouseY, delta); + double trashHeight = this.trash.getHeight(); + + boolean draggingDisplay = DraggingContext.getInstance().isDraggingComponent() + && DraggingContext.getInstance().getDragged().get() instanceof Display; + int topOffsetHeight = 0; + this.favoritesBounds = DisplayHistoryManager.INSTANCE.getEntries(displayHistory).isEmpty() && !draggingDisplay + ? fullBounds : RectangleUtils.excludeZones(this.fullBounds, Stream.of(displayHistory.createBounds(this.excludedBounds))); + + displayHistory.render(matrices, mouseX, mouseY, delta); + + if (favoritePanel.getBounds().height > 20) { + // Opened favorites panel + region.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + topOffsetHeight, this.favoritesBounds.width, this.favoritesBounds.height - topOffsetHeight - (this.favoritesBounds.getMaxY() - this.favoritePanel.getBounds().y) - 4 - (Math.round(trashHeight) <= 0 ? 0 : trashHeight)); + } else { + region.getBounds().setBounds(this.favoritesBounds.x, this.favoritesBounds.y + topOffsetHeight, this.favoritesBounds.width, this.favoritesBounds.height - topOffsetHeight - (Math.round(trashHeight) <= 0 ? 0 : trashHeight + 24)); + } + + region.render(matrices, mouseX, mouseY, delta); + renderAddFavorite(matrices, mouseX, mouseY, delta); + + this.scaleIndicator.setCenter(favoritesBounds.getCenterX(), favoritesBounds.getCenterY()); + this.scaleIndicator.render(matrices, mouseX, mouseY, delta); + } + + private void renderAddFavorite(PoseStack matrices, int mouseX, int mouseY, float delta) { + this.favoritePanel.render(matrices, mouseX, mouseY, delta); + this.togglePanelButton.render(matrices, mouseX, mouseY, delta); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (containsMouse(mouse())) + for (Widget widget : children()) + if (widget.keyPressed(keyCode, scanCode, modifiers)) + return true; + if (displayHistory.keyPressed(keyCode, scanCode, modifiers)) + return true; + return false; + } + + @Override + public void initBounds() { + this.fullBounds = REIRuntime.getInstance().calculateFavoritesListArea(); + this.excludedBounds = RectangleUtils.excludeZones(this.fullBounds, ScreenRegistry.getInstance().exclusionZones().getExclusionZones(minecraft.screen).stream()); + this.favoritesBounds = RectangleUtils.excludeZones(this.fullBounds, Stream.of(displayHistory.createBounds(this.fullBounds, null))); + this.updateSearch(); + } + + @Override + public void queueReloadSearch() { + updateSearch(); + } + + public void updateSearch() { + if (ConfigObject.getInstance().isFavoritesEnabled()) { + region.setEntries(CollectionUtils.map(ConfigObject.getInstance().getFavoriteEntries(), FavoriteEntry::copy), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); + } else region.setEntries(Collections.emptyList(), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); + } + + @Override + public List<? extends Widget> children() { + return children; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (region.mouseClicked(mouseX, mouseY, button)) + return true; + for (Widget widget : children()) + if (widget.mouseClicked(mouseX, mouseY, button)) + return true; + if (displayHistory.mouseClicked(mouseX, mouseY, button)) + return true; + return false; + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (containsMouse(mouseX, mouseY)) { + for (Widget widget : children()) + if (widget.mouseReleased(mouseX, mouseY, button)) + return true; + } + if (displayHistory.mouseReleased(mouseX, mouseY, button)) + return true; + return false; + } + + @Override + public Widget asWidget() { + return this; + } + + @Override + public Rectangle getFavoritesBounds() { + return favoritesBounds; + } + + @Override + public void submitDisplayHistory(Display display, @Nullable Rectangle fromBounds) { + displayHistory.addDisplay(fromBounds, display); + } +} diff --git a/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java new file mode 100644 index 000000000..7af1d8a8b --- /dev/null +++ b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayEntry.java @@ -0,0 +1,322 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget.favorites.history; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector4f; +import me.shedaniel.clothconfig2.api.LazyResettable; +import me.shedaniel.clothconfig2.api.animator.ValueAnimator; +import me.shedaniel.math.Dimension; +import me.shedaniel.math.FloatingRectangle; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.*; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.client.view.ViewSearchBuilder; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.impl.client.ClientInternals; +import me.shedaniel.rei.impl.client.provider.AutoCraftingEvaluator; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.TextComponent; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +@SuppressWarnings("UnstableApiUsage") +public class DisplayEntry extends WidgetWithBounds { + private final LazyResettable<List<Widget>> widgets = new LazyResettable<>(this::setupWidgets); + private final DisplayHistoryWidget parent; + private final Display display; + private final Dimension size = new Dimension(1, 1); + private boolean hasInitialBounds; + private final ValueAnimator<FloatingRectangle> bounds = ValueAnimator.ofFloatingRectangle(); + private final Button plusButton; + private double xOffset = 0; + private boolean reachedStable = false; + private UUID uuid = UUID.randomUUID(); + + public DisplayEntry(DisplayHistoryWidget parent, Display display, @Nullable Rectangle initialBounds) { + this.display = display; + this.parent = parent; + this.hasInitialBounds = initialBounds != null; + if (this.hasInitialBounds) { + this.bounds.setAs(initialBounds.getFloatingBounds()); + this.plusButton = Widgets.createButton(new Rectangle(initialBounds.getMaxX() - 16, initialBounds.getMaxY() - 16, 10, 10), new TextComponent("+")); + } else { + this.plusButton = Widgets.createButton(new Rectangle(-1000, -1000, 10, 10), new TextComponent("+")); + } + } + + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public void markBoundsDirty() { + widgets.reset(); + } + + private List<Widget> setupWidgets() { + Rectangle parentBounds = parent.getBounds(); + CategoryRegistry.CategoryConfiguration<Display> configuration = CategoryRegistry.getInstance().get((CategoryIdentifier<Display>) display.getCategoryIdentifier()); + DisplayCategory<Display> category = configuration.getCategory(); + Rectangle displayBounds = new Rectangle(0, 0, category.getDisplayWidth(display), category.getDisplayHeight()); + List<Widget> widgets = configuration.getView(display).setupDisplay(display, displayBounds); + float scale = 1.0F; + if (parentBounds.width * scale < displayBounds.width) { + scale = Math.min(scale, parentBounds.width * scale / (float) displayBounds.width); + } + if (parentBounds.height * scale < displayBounds.height) { + scale = Math.min(scale, parentBounds.height * scale / (float) displayBounds.height); + } + float x = parentBounds.getCenterX() - displayBounds.width / 2 * scale; + float y = parentBounds.getCenterY() - displayBounds.height / 2 * scale; + FloatingRectangle newBounds = new Rectangle(x, y, displayBounds.width * scale, displayBounds.height * scale).getFloatingBounds(); + if (hasInitialBounds) { + if (this.size.width == 1 && this.size.height == 1) { + this.bounds.setTo(newBounds, 700); + } else { + this.bounds.setAs(newBounds); + } + } else { + this.bounds.setAs(newBounds); + hasInitialBounds = true; + } + this.size.setSize(displayBounds.getSize()); + return widgets; + } + + @Override + public Rectangle getBounds() { + return bounds.value().getBounds(); + } + + public Dimension getSize() { + return size; + } + + public boolean isStable() { + widgets.get(); + FloatingRectangle target = this.bounds.target(); + FloatingRectangle value = this.bounds.value(); + return reachedStable || Math.abs(value.x - target.x) <= 0.5 && Math.abs(value.y - target.y) <= 0.5 && Math.abs(value.width - target.width) <= 0.5 && Math.abs(value.height - target.height) <= 0.5; + } + + public void setReachedStable(boolean reachedStable) { + this.reachedStable = reachedStable; + } + + @Override + public void render(PoseStack poses, int mouseX, int mouseY, float delta) { + boolean stable = isStable(); + this.bounds.update(delta); + FloatingRectangle target = this.bounds.target(); + FloatingRectangle bounds = this.bounds.value(); + + if (!reachedStable && Math.abs(bounds.x - target.x) <= 0.5 && Math.abs(bounds.y - target.y) <= 0.5 && Math.abs(bounds.width - target.width) <= 0.5 && Math.abs(bounds.height - target.height) <= 0.5) { + reachedStable = true; + } + + if (stable && (bounds.getMaxX() + xOffset < parent.getBounds().x || bounds.x + xOffset > parent.getBounds().getMaxX())) { + return; + } + + poses.pushPose(); + if (!stable || !target.equals(bounds)) { + poses.translate(0, 0, 600); + } + poses.translate(xOffset(), yOffset(), 0); + poses.scale(xScale(), yScale(), 1.0F); + + for (Widget widget : widgets.get()) { + widget.render(poses, transformMouseX(mouseX), transformMouseY(mouseY), delta); + } + poses.popPose(); + + { + poses.pushPose(); + if (stable && target.equals(bounds)) { + poses.translate(this.xOffset, 0, 200); + } else { + poses.translate(0, 0, 800); + } + Vector4f mouse = new Vector4f((float) mouseX, (float) mouseY, 0, 1); + mouse.transform(poses.last().pose()); + + AutoCraftingEvaluator.Result result = ClientInternals.getAutoCraftingEvaluator(display) + .buildRenderer() + .buildTooltipRenderer() + .get(); + + plusButton.setEnabled(result.isSuccessful()); + plusButton.setTint(result.getTint()); + plusButton.getBounds().setBounds(new Rectangle(bounds.getMaxX() - 14, bounds.getMaxY() - 14, 10, 10)); + + if (result.isApplicable()) { + plusButton.setText(new TextComponent("+")); + plusButton.render(poses, Math.round(mouse.x()), Math.round(mouse.y()), delta); + poses.popPose(); + + if (plusButton.containsMouse(Math.round(mouse.x()), Math.round(mouse.y())) && result.getTooltipRenderer() != null) { + result.getTooltipRenderer().accept(new Point(mouseX, mouseY), Tooltip::queue); + } + + if (result.getRenderer() != null) { + poses.pushPose(); + if (!stable || !target.equals(bounds)) { + poses.translate(0, 0, 600); + } + poses.translate(xOffset(), yOffset(), 0); + poses.scale(xScale(), yScale(), 1.0F); + + result.getRenderer().render(poses, mouseX, mouseY, delta, widgets.get(), getBounds(), display); + poses.popPose(); + } + } else { + poses.popPose(); + } + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (containsMouse(mouseX + xOffset, mouseY)) { + for (Widget widget : widgets.get()) { + if (widget.mouseClicked(transformMouseX(mouseX), transformMouseY(mouseY), button)) { + return true; + } + } + } + + return super.mouseClicked(mouseX, mouseY, button); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + if (containsMouse(mouseX + xOffset, mouseY)) { + for (Widget widget : widgets.get()) { + if (widget.mouseReleased(transformMouseX(mouseX), transformMouseY(mouseY), button)) { + return true; + } + } + + if (button == 0 && plusButton.containsMouse(mouseX + xOffset, mouseY)) { + ClientInternals.getAutoCraftingEvaluator(display) + .actuallyCraft() + .stacked(Screen.hasShiftDown()) + .get(); + Widgets.produceClickSound(); + return true; + } + + ViewSearchBuilder.builder().addDisplays(List.of(display)).open(); + Widgets.produceClickSound(); + return true; + } + + return super.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + try { + Widget.pushMouse(new Point(transformMouseX(mouse().x), transformMouseY(mouse().y))); + for (Widget widget : widgets.get()) { + if (widget.keyPressed(keyCode, scanCode, modifiers)) { + return true; + } + } + } finally { + Widget.popMouse(); + } + + return super.keyPressed(keyCode, scanCode, modifiers); + } + + private float xOffset() { + FloatingRectangle bounds = this.bounds.value(); + FloatingRectangle target = this.bounds.target(); + float xOffset = (float) bounds.x; + if (isStable() && target.equals(bounds)) { + xOffset += this.xOffset; + } + return xOffset; + } + + private float yOffset() { + FloatingRectangle bounds = this.bounds.value(); + return (float) bounds.y; + } + + private float xScale() { + FloatingRectangle bounds = this.bounds.value(); + return (float) bounds.width / size.width; + } + + private float yScale() { + FloatingRectangle bounds = this.bounds.value(); + return (float) bounds.height / size.height; + } + + protected int transformMouseX(int mouseX) { + return Math.round((mouseX - xOffset()) / xScale()); + } + + protected int transformMouseY(int mouseY) { + return Math.round((mouseY - yOffset()) / yScale()); + } + + protected double transformMouseX(double mouseX) { + return (mouseX - xOffset()) / xScale(); + } + + protected double transformMouseY(double mouseY) { + return (mouseY - yOffset()) / yScale(); + } + + @Override + public List<? extends GuiEventListener> children() { + return Collections.emptyList(); + } + + public void setScrolled(double xOffset) { + this.xOffset = xOffset; + } + + public List<Widget> getWidgets() { + return widgets.get(); + } + + public Display getDisplay() { + return display; + } +} diff --git a/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java new file mode 100644 index 000000000..d115190ff --- /dev/null +++ b/runtime-frontend/favorites-entries/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/history/DisplayHistoryManager.java @@ -0,0 +1,147 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.impl.client.gui.widget.favorites.history; + +import com.google.common.collect.Iterables; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.config.ConfigManager; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.display.DisplaySerializerRegistry; +import me.shedaniel.rei.api.common.plugins.PluginManager; +import me.shedaniel.rei.impl.client.config.ConfigManagerInternal; +import me.shedaniel.rei.impl.common.InternalLogger; +import net.minecraft.Util; +import net.minecraft.nbt.CompoundTag; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class DisplayHistoryManager { + public static final DisplayHistoryManager INSTANCE = new DisplayHistoryManager(); + private Map<String, DisplayEntry> entries = new LinkedHashMap<>(); + private long lastCheckTime = -1; + + private List<CompoundTag> getDisplayHistory() { + return (List<CompoundTag>) ConfigManagerInternal.getInstance().get("basics.displayHistory"); + } + + public Collection<DisplayEntry> getEntries(DisplayHistoryWidget parent) { + if ((lastCheckTime == -1 || Util.getMillis() - lastCheckTime > 4000) && !PluginManager.areAnyReloading()) { + updateEntries(parent); + lastCheckTime = Util.getMillis(); + } + + return Collections.unmodifiableCollection(entries.values()); + } + + private void update |
