From 6fd895753bfe317233f68da38ba3460422674475 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Thu, 9 Jun 2022 16:45:30 +0800 Subject: Add accepted stacks to the tooltip --- .../gui/screen/AbstractDisplayViewingScreen.java | 104 +++++++++++++++++++++ .../rei/impl/client/gui/widget/EntryWidget.java | 46 ++++++--- .../rei/impl/client/gui/widget/QueuedTooltip.java | 4 + 3 files changed, 140 insertions(+), 14 deletions(-) (limited to 'runtime/src/main/java/me/shedaniel') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java index cafdb44be..ff1fd37c2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/AbstractDisplayViewingScreen.java @@ -24,10 +24,14 @@ package me.shedaniel.rei.impl.client.gui.screen; import com.google.common.collect.Lists; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.math.Matrix4f; import dev.architectury.fluid.FluidStack; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.screen.DisplayScreen; import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.Widgets; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -42,17 +46,29 @@ import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.client.ClientHelperImpl; import me.shedaniel.rei.impl.client.gui.widget.EntryWidget; +import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget; import me.shedaniel.rei.impl.display.DisplaySpec; +import net.minecraft.ChatFormatting; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.chat.NarratorChatListener; import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.core.Holder; import net.minecraft.core.Registry; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.tags.TagKey; +import net.minecraft.util.Mth; +import net.minecraft.world.inventory.tooltip.TooltipComponent; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.UnaryOperator; import java.util.stream.Stream; public abstract class AbstractDisplayViewingScreen extends Screen implements DisplayScreen { @@ -183,6 +199,8 @@ public abstract class AbstractDisplayViewingScreen extends Screen implements Dis protected void setupTags(List widgets) { outer: for (EntryWidget widget : Widgets.walk(widgets, EntryWidget.class::isInstance)) { + if (widget.getNoticeMark() != EntryWidget.INPUT) continue; + addCyclingTooltip(widget); widget.removeTagMatch = false; if (widget.getEntries().size() <= 1) continue; EntryType type = null; @@ -210,4 +228,90 @@ public abstract class AbstractDisplayViewingScreen extends Screen implements Dis } } } + + private static final int MAX_WIDTH = 200; + + private void addCyclingTooltip(EntryWidget widget) { + class TooltipProcessor implements UnaryOperator, TooltipComponent, ClientTooltipComponent { + @Override + public Tooltip apply(Tooltip tooltip) { + if (widget.getEntries().size() > 1) { + tooltip.add((ClientTooltipComponent) this); + } + return tooltip; + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TooltipProcessor; + } + + @Override + public int getHeight() { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int height = Math.min(6, Mth.ceil(widget.getEntries().size() / (float) w)) * entrySize + 2; + height += 12; + if (widget.tagMatch != null) height += 12; + return height; + } + + @Override + public int getWidth(Font font) { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int size = widget.getEntries().size(); + int width = Math.min(size, w) * entrySize; + width = Math.max(width, font.width(new TranslatableComponent("text.rei.accepts"))); + if (widget.tagMatch != null) width = Math.max(width, font.width(new TranslatableComponent("text.rei.tag_accept", widget.tagMatch.toString()))); + return width; + } + + @Override + public void renderImage(Font font, int x, int y, PoseStack poses, ItemRenderer renderer, int z) { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + int i = 0; + poses.pushPose(); + poses.translate(0, 0, z + 50); + for (EntryStack entry : widget.getEntries()) { + int x1 = x + (i % w) * entrySize; + int y1 = y + 13 + (i / w) * entrySize; + i++; + if (i / w > 5) { + MultiBufferSource.BufferSource source = MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + Component text = new TextComponent("+" + (widget.getEntries().size() - w * 6 + 1)).withStyle(ChatFormatting.GRAY); + font.drawInBatch(text, x1 + entrySize / 2 - font.width(text) / 2, y1 + entrySize / 2 - 1, -1, true, poses.last().pose(), source, false, 0, 15728880); + source.endBatch(); + break; + } else { + entry.render(poses, new Rectangle(x1, y1, entrySize, entrySize), -1000, -1000, 0); + } + } + poses.popPose(); + } + + @Override + public void renderText(Font font, int x, int y, Matrix4f pose, MultiBufferSource.BufferSource buffers) { + font.drawInBatch(new TranslatableComponent("text.rei.accepts").withStyle(ChatFormatting.GRAY), + x, y + 2, -1, true, pose, buffers, false, 0, 15728880); + + if (widget.tagMatch != null) { + int entrySize = EntryListWidget.entrySize(); + int w = Math.max(1, MAX_WIDTH / entrySize); + font.drawInBatch(new TranslatableComponent("text.rei.tag_accept", widget.tagMatch.toString()) + .withStyle(ChatFormatting.GRAY), + x, y + 16 + Math.min(6, Mth.ceil(widget.getEntries().size() / (float) w)) * entrySize, + -1, true, pose, buffers, false, 0, 15728880); + } + } + } + + widget.tooltipProcessor(new TooltipProcessor()); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index 209de8d69..4d343fce3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -31,8 +31,6 @@ import me.shedaniel.clothconfig2.api.animator.NumberAnimator; import me.shedaniel.clothconfig2.api.animator.ValueAnimator; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; -import me.shedaniel.math.impl.PointHelper; -import me.shedaniel.rei.api.client.ClientHelper; import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.config.ConfigManager; import me.shedaniel.rei.api.client.config.ConfigObject; @@ -74,6 +72,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -93,6 +92,8 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { protected boolean wasClicked = false; private Rectangle bounds; private List> entryStacks; + @Nullable + private Set> tooltipProcessors; public ResourceLocation tagMatch; public boolean removeTagMatch = true; @@ -395,18 +396,6 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { protected void queueTooltip(PoseStack matrices, int mouseX, int mouseY, float delta) { Tooltip tooltip = getCurrentTooltip(new Point(mouseX, mouseY)); if (tooltip != null) { - if (interactableFavorites && ConfigObject.getInstance().doDisplayFavoritesTooltip() && !ConfigObject.getInstance().getFavoriteKeyCode().isUnknown()) { - String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName().getString(); - if (reverseFavoritesAction()) - tooltip.addAllTexts(Stream.of(I18n.get("text.rei.remove_favorites_tooltip", name).split("\n")) - .map(TextComponent::new).collect(Collectors.toList())); - else - tooltip.addAllTexts(Stream.of(I18n.get("text.rei.favorites_tooltip", name).split("\n")) - .map(TextComponent::new).collect(Collectors.toList())); - } - if (tagMatch != null) { - tooltip.add(new TranslatableComponent("text.rei.tag_match", tagMatch.toString()).withStyle(ChatFormatting.GRAY)); - } tooltip.queue(); } } @@ -423,6 +412,24 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { tooltip.add(new TranslatableComponent("text.auto_craft.move_items.tooltip").withStyle(ChatFormatting.YELLOW)); } + if (tooltip != null) { + if (interactableFavorites && ConfigObject.getInstance().doDisplayFavoritesTooltip() && !ConfigObject.getInstance().getFavoriteKeyCode().isUnknown()) { + String name = ConfigObject.getInstance().getFavoriteKeyCode().getLocalizedName().getString(); + if (reverseFavoritesAction()) + tooltip.addAllTexts(Stream.of(I18n.get("text.rei.remove_favorites_tooltip", name).split("\n")) + .map(TextComponent::new).collect(Collectors.toList())); + else + tooltip.addAllTexts(Stream.of(I18n.get("text.rei.favorites_tooltip", name).split("\n")) + .map(TextComponent::new).collect(Collectors.toList())); + } + + if (tooltipProcessors != null) { + for (UnaryOperator processor : tooltipProcessors) { + tooltip = processor.apply(tooltip); + } + } + } + return tooltip; } @@ -453,6 +460,17 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { return b; } + public void tooltipProcessor(UnaryOperator operator) { + if (tooltipProcessors == null) { + tooltipProcessors = Collections.singleton(operator); + } else { + if (!(tooltipProcessors instanceof LinkedHashSet)) { + tooltipProcessors = new LinkedHashSet<>(tooltipProcessors); + } + tooltipProcessors.add(operator); + } + } + @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { if (containsMouse(mouseX, mouseY)) diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/QueuedTooltip.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/QueuedTooltip.java index 5c992d197..19ebebadb 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/QueuedTooltip.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/QueuedTooltip.java @@ -149,6 +149,10 @@ public class QueuedTooltip implements Tooltip { @Override public ClientTooltipComponent getAsComponent() { + if (obj instanceof ClientTooltipComponent) { + return (ClientTooltipComponent) obj; + } + if (isTooltipComponent()) { return ClientTooltipComponent.create((TooltipComponent) obj); } -- cgit From 0ec9d4ad3ab50e7ec7c0f6ce2ab65bd7596ee771 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 11 Jun 2022 00:12:55 +0800 Subject: Add default favorite entries --- .../rei/impl/client/config/ConfigManagerImpl.java | 3 - .../rei/impl/client/config/ConfigObjectImpl.java | 5 + .../favorites/FavoriteEntryTypeRegistryImpl.java | 22 ++-- .../rei/impl/client/gui/ScreenOverlayImpl.java | 15 +-- .../rei/impl/client/gui/widget/EntryWidget.java | 19 ++-- .../widget/favorites/FavoritesEntriesManager.java | 119 +++++++++++++++++++++ .../gui/widget/favorites/FavoritesListWidget.java | 2 +- .../listeners/FavoritesRegionListener.java | 14 +-- 8 files changed, 157 insertions(+), 42 deletions(-) create mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesEntriesManager.java (limited to 'runtime/src/main/java/me/shedaniel') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java index 2d82a28c8..a386028bf 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java @@ -270,9 +270,6 @@ public class ConfigManagerImpl implements ConfigManager { @Override public void saveConfig() { - if (getConfig().getFavoriteEntries() != null) { - getConfig().getFavoriteEntries().removeIf(Objects::isNull); - } if (getConfig().getFilteringRules().stream().noneMatch(filteringRule -> filteringRule instanceof ManualFilteringRule)) { getConfig().getFilteringRules().add(new ManualFilteringRule()); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java index 28f45277b..0bfa01856 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java @@ -369,6 +369,10 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Override public List getFavoriteEntries() { return basics.favorites; + } + + public List getHiddenFavoriteEntries() { + return basics.hiddenFavorites; } @Override @@ -526,6 +530,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { public static class Basics { @ConfigEntry.Gui.Excluded public List favorites = new ArrayList<>(); + @ConfigEntry.Gui.Excluded public List hiddenFavorites = new ArrayList<>(); @Comment("Declares whether cheating mode is on.") @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) private CheatingMode cheating = CheatingMode.OFF; private boolean favoritesEnabled = true; diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java index 82439dd62..45e598625 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/favorites/FavoriteEntryTypeRegistryImpl.java @@ -34,6 +34,8 @@ import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; import me.shedaniel.rei.api.client.favorites.SystemFavoriteEntryProvider; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.common.registry.ReloadStage; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import org.apache.commons.lang3.mutable.MutableLong; @@ -113,8 +115,8 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry @Override public void endReload() { if (ConfigObject.getInstance().isFavoritesEnabled()) { - List favorites = ConfigObject.getInstance().getFavoriteEntries(); - favorites.removeIf(FavoriteEntry::isInvalid); + ConfigObject.getInstance().getFavoriteEntries().removeIf(FavoriteEntry::isInvalid); + ConfigManagerImpl.getInstance().getConfig().getHiddenFavoriteEntries().removeIf(FavoriteEntry::isInvalid); ConfigManager.getInstance().saveConfig(); } @@ -122,15 +124,16 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry private static class SectionImpl implements FavoriteEntryType.Section { private final Component text; - private final List entries = new ArrayList<>(); + private final List entries = new ArrayList<>(); public SectionImpl(Component text) { this.text = text; } @Override - public void add(FavoriteEntry... entries) { - Collections.addAll(this.entries, entries); + public void add(boolean defaultFavorited, FavoriteEntry... entries) { + this.entries.addAll(CollectionUtils.map(entries, + entry -> new CompoundEntry(entry, defaultFavorited))); } @Override @@ -140,7 +143,14 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry @Override public List getEntries() { - return entries; + return CollectionUtils.map(entries, CompoundEntry::entry); } + + @Override + public List getDefaultEntries() { + return CollectionUtils.filterAndMap(entries, CompoundEntry::defaultFavorited, CompoundEntry::entry); + } + + public record CompoundEntry(FavoriteEntry entry, boolean defaultFavorited) {} } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index 3b5aaa3b1..98ab45649 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -72,6 +72,7 @@ import me.shedaniel.rei.impl.client.gui.widget.InternalWidgets; import me.shedaniel.rei.impl.client.gui.widget.LateRenderable; import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListSearchManager; import me.shedaniel.rei.impl.client.gui.widget.entrylist.EntryListWidget; +import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesEntriesManager; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; import me.shedaniel.rei.impl.client.gui.widget.search.OverlaySearchField; import me.shedaniel.rei.impl.common.util.Weather; @@ -804,12 +805,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { return ViewSearchBuilder.builder().addUsagesFor(stack).open(); } else if (ConfigObject.getInstance().getFavoriteKeyCode().matchesKey(keyCode, scanCode)) { FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); - ConfigManager.getInstance().saveConfig(); - FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget(); - if (favoritesListWidget != null) - favoritesListWidget.updateSearch(); + FavoritesEntriesManager.INSTANCE.add(favoriteEntry); return true; } } @@ -878,12 +874,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { return ViewSearchBuilder.builder().addUsagesFor(stack).open(); } else if (visible && ConfigObject.getInstance().getFavoriteKeyCode().matchesMouse(button)) { FavoriteEntry favoriteEntry = FavoriteEntry.fromEntryStack(stack); - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); - ConfigManager.getInstance().saveConfig(); - FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget(); - if (favoritesListWidget != null) - favoritesListWidget.updateSearch(); + FavoritesEntriesManager.INSTANCE.add(favoriteEntry); return true; } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java index 4d343fce3..e4d8acd40 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryWidget.java @@ -51,6 +51,7 @@ import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.impl.client.REIRuntimeImpl; import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; +import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesEntriesManager; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; import me.shedaniel.rei.impl.client.view.ViewsImpl; import net.minecraft.ChatFormatting; @@ -510,11 +511,10 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { if (keyCode.matchesMouse(button)) { FavoriteEntry favoriteEntry = asFavoriteEntry(); if (favoriteEntry != null) { - if (reverseFavoritesAction()) - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - else { - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); + if (reverseFavoritesAction()) { + FavoritesEntriesManager.INSTANCE.remove(favoriteEntry); + } else { + FavoritesEntriesManager.INSTANCE.add(favoriteEntry); } ConfigManager.getInstance().saveConfig(); FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget(); @@ -593,11 +593,10 @@ public class EntryWidget extends Slot implements DraggableStackProviderWidget { if (ConfigObject.getInstance().getFavoriteKeyCode().matchesKey(keyCode, scanCode)) { FavoriteEntry favoriteEntry = asFavoriteEntry(); if (favoriteEntry != null) { - if (reverseFavoritesAction()) - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - else { - ConfigObject.getInstance().getFavoriteEntries().remove(favoriteEntry); - ConfigObject.getInstance().getFavoriteEntries().add(favoriteEntry); + if (reverseFavoritesAction()) { + FavoritesEntriesManager.INSTANCE.remove(favoriteEntry); + } else { + FavoritesEntriesManager.INSTANCE.add(favoriteEntry); } ConfigManager.getInstance().saveConfig(); FavoritesListWidget favoritesListWidget = ScreenOverlayImpl.getFavoritesListWidget(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesEntriesManager.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesEntriesManager.java new file mode 100644 index 000000000..c235e29ca --- /dev/null +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesEntriesManager.java @@ -0,0 +1,119 @@ +/* + * 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 me.shedaniel.rei.api.client.config.ConfigManager; +import me.shedaniel.rei.api.client.favorites.FavoriteEntry; +import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.client.config.ConfigManagerImpl; +import me.shedaniel.rei.impl.client.config.ConfigObjectImpl; +import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class FavoritesEntriesManager { + public static final FavoritesEntriesManager INSTANCE = new FavoritesEntriesManager(); + + private Stream getDefaultFavorites() { + return StreamSupport.stream(FavoriteEntryType.registry().sections().spliterator(), false) + .flatMap(section -> section.getDefaultEntries().stream()); + } + + public List getFavorites() { + ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig(); + List defaultFavorites = getDefaultFavorites().collect(Collectors.toList()); + defaultFavorites.removeAll(config.getHiddenFavoriteEntries()); + + List favorites = new ArrayList<>(config.getFavoriteEntries()); + defaultFavorites.removeAll(favorites); + favorites.addAll(0, defaultFavorites); + favorites.removeIf(FavoriteEntry::isInvalid); + return favorites; + } + + public void remove(FavoriteEntry entry) { + ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig(); + + config.getFavoriteEntries().remove(entry); + if (getDefaultFavorites().anyMatch(e -> e.equals(entry)) && !config.getHiddenFavoriteEntries().contains(entry)) { + config.getHiddenFavoriteEntries().add(entry); + } + + ConfigManager.getInstance().saveConfig(); + FavoritesListWidget widget = ScreenOverlayImpl.getFavoritesListWidget(); + if (widget != null) { + widget.updateSearch(); + } + } + + public void add(FavoriteEntry entry) { + ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig(); + List defaultFavorites = getDefaultFavorites().toList(); + + config.getFavoriteEntries().remove(entry); + if (CollectionUtils.anyMatch(defaultFavorites, e -> e.equals(entry)) && !config.getHiddenFavoriteEntries().contains(entry)) { + config.getHiddenFavoriteEntries().add(entry); + } + + for (int i = defaultFavorites.size() - 1; i >= 0; i--) { + FavoriteEntry e = defaultFavorites.get(i); + if (!config.getFavoriteEntries().contains(e) && !config.getHiddenFavoriteEntries().contains(e)) { + config.getFavoriteEntries().add(0, e); + } + } + + config.getHiddenFavoriteEntries().remove(entry); + if (!CollectionUtils.anyMatch(defaultFavorites, e -> e.equals(entry))) { + config.getFavoriteEntries().add(entry); + } + + ConfigManager.getInstance().saveConfig(); + FavoritesListWidget widget = ScreenOverlayImpl.getFavoritesListWidget(); + if (widget != null) { + widget.updateSearch(); + } + } + + public void setEntries(List entries) { + List defaultFavorites = getDefaultFavorites().collect(Collectors.toList()); + List hiddenDefaultFavorites = new ArrayList<>(defaultFavorites); + hiddenDefaultFavorites.removeAll(entries); + ConfigObjectImpl config = ConfigManagerImpl.getInstance().getConfig(); + config.getHiddenFavoriteEntries().clear(); + config.getHiddenFavoriteEntries().addAll(hiddenDefaultFavorites); + config.getFavoriteEntries().clear(); + config.getFavoriteEntries().addAll(entries); + + ConfigManager.getInstance().saveConfig(); + FavoritesListWidget widget = ScreenOverlayImpl.getFavoritesListWidget(); + if (widget != null) { + widget.updateSearch(); + } + } +} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java index dc486b3ac..d77bd67d9 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/FavoritesListWidget.java @@ -281,7 +281,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableCo public void updateSearch() { if (ConfigObject.getInstance().isFavoritesEnabled()) { - region.setEntries(CollectionUtils.map(ConfigObject.getInstance().getFavoriteEntries(), FavoriteEntry::copy), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); + region.setEntries(CollectionUtils.map(FavoritesEntriesManager.INSTANCE.getFavorites(), FavoriteEntry::copy), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); } else region.setEntries(Collections.emptyList(), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/listeners/FavoritesRegionListener.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/listeners/FavoritesRegionListener.java index 96d1de8c7..ef9a4837f 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/listeners/FavoritesRegionListener.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/favorites/listeners/FavoritesRegionListener.java @@ -28,6 +28,7 @@ import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesEntriesManager; import me.shedaniel.rei.impl.client.gui.widget.favorites.FavoritesListWidget; import me.shedaniel.rei.impl.client.gui.widget.region.RealRegionEntry; import me.shedaniel.rei.impl.client.gui.widget.region.RegionEntryWidget; @@ -37,6 +38,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; public class FavoritesRegionListener implements RegionListener { @@ -47,22 +49,14 @@ public class FavoritesRegionListener implements RegionListener { @Override public void onDrop(Stream entries) { if (ConfigObject.getInstance().isFavoritesEnabled()) { - List favorites = ConfigObject.getInstance().getFavoriteEntries(); - favorites.clear(); - entries.forEach(entry -> { - favorites.add(entry.copy()); - }); - - ConfigManager.getInstance().saveConfig(); + FavoritesEntriesManager.INSTANCE.setEntries(entries.collect(Collectors.toList())); } } @Override public void onRemove(RealRegionEntry entry) { if (ConfigObject.getInstance().isFavoritesEnabled()) { - List favorites = ConfigObject.getInstance().getFavoriteEntries(); - favorites.removeIf(favoriteEntry -> Objects.equals(entry.getEntry(), favoriteEntry)); - ConfigManager.getInstance().saveConfig(); + FavoritesEntriesManager.INSTANCE.remove(entry.getEntry()); } } -- cgit From 4a8a83a1bfc68eeb80581cde55ef23d16e59f52c Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 11 Jun 2022 00:18:06 +0800 Subject: Add TransferHandler.Result.tooltip() --- .../shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'runtime/src/main/java/me/shedaniel') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java index 62c297dc9..3c3ddd9cf 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/AutoCraftingEvaluator.java @@ -96,6 +96,7 @@ public class AutoCraftingEvaluator { } List errors = new ArrayList<>(); + TransferHandler.Result successfulResult = null; TransferHandler.Context context = TransferHandler.Context.create(actuallyCrafting, stackedCrafting, containerScreen, display); for (TransferHandler transferHandler : TransferHandlerRegistry.getInstance()) { @@ -127,6 +128,7 @@ public class AutoCraftingEvaluator { if (transferResult.isSuccessful()) { errors.clear(); + successfulResult = transferResult; result.successful = true; result.successfulHandler = transferHandler; break; @@ -152,6 +154,10 @@ public class AutoCraftingEvaluator { if (errors.isEmpty()) { errorTooltip.clear(); errorTooltip.add(new TranslatableComponent("text.auto_craft.move_items")); + + if (successfulResult != null) { + successfulResult.fillTooltip(errorTooltip); + } } else { errorTooltip.clear(); List tooltipsFilled = new ArrayList<>(); -- cgit From a27be9cf41c39eff119be86c035b7611111610b0 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 11 Jun 2022 01:06:08 +0800 Subject: Fix #874 --- .../impl/common/entry/type/EntryRegistryImpl.java | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'runtime/src/main/java/me/shedaniel') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java index 1aa49902b..28baa75c1 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/entry/type/EntryRegistryImpl.java @@ -36,6 +36,11 @@ import me.shedaniel.rei.api.client.overlay.ScreenOverlay; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.entry.EntryRegistry; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext; +import me.shedaniel.rei.api.common.entry.type.EntryDefinition; +import me.shedaniel.rei.api.common.entry.type.EntryType; +import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.api.common.util.EntryStacks; @@ -172,8 +177,19 @@ public class EntryRegistryImpl implements EntryRegistry { @Override public List appendStacksForItem(Item item) { NonNullList list = NonNullList.create(); - CreativeModeTab category = item.getItemCategory(); - item.fillItemCategory(MoreObjects.firstNonNull(category, CreativeModeTab.TAB_SEARCH), list); + LongSet set = new LongOpenHashSet(); + EntryDefinition itemDefinition = VanillaEntryTypes.ITEM.getDefinition(); + for (CreativeModeTab tab : CreativeModeTab.TABS) { + if (tab != CreativeModeTab.TAB_HOTBAR && tab != CreativeModeTab.TAB_INVENTORY) { + NonNullList tabList = NonNullList.create(); + item.fillItemCategory(tab, tabList); + for (ItemStack stack : tabList) { + if (set.add(itemDefinition.hash(null, stack, ComparisonContext.EXACT))) { + list.add(stack); + } + } + } + } if (list.isEmpty()) { return Collections.singletonList(item.getDefaultInstance()); } -- cgit From 0e2a66156d69bb6d8d37a1c05f59abde42d62ebc Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 11 Jun 2022 01:10:40 +0800 Subject: Fix #899 --- .../java/me/shedaniel/rei/impl/client/gui/RecipeDisplayExporter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/src/main/java/me/shedaniel') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/RecipeDisplayExporter.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/RecipeDisplayExporter.java index 9895def4f..755d303df 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/RecipeDisplayExporter.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/RecipeDisplayExporter.java @@ -67,7 +67,7 @@ public final class RecipeDisplayExporter extends Widget { Collection locations = display.provideInternalDisplayIds(); String string = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss").format(new Date()); if (!locations.isEmpty()) { - string = locations.iterator().next().toString().replace('/', '_'); + string = locations.iterator().next().toString().replace('/', '_').replace(':', '_'); } int i = 1; @@ -114,7 +114,7 @@ public final class RecipeDisplayExporter extends Widget { } Util.ioPool().execute(() -> { try { - File export = new File(minecraft.gameDirectory, "rei_exports/" + display.provideInternalDisplay().getCategoryIdentifier().toString().replace('/', '_')); + File export = new File(minecraft.gameDirectory, "rei_exports/" + display.provideInternalDisplay().getCategoryIdentifier().toString().replace('/', '_').replace(':', '_')); export.mkdirs(); strippedImage.writeToFile(getExportFilename(display, export)); } catch (IOException e) { -- cgit