From 944734e3a5eabfee5efec37e69818a183c35d962 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Tue, 15 Feb 2022 15:09:38 +0800 Subject: Close #110 --- .../rei/impl/client/config/ConfigObjectImpl.java | 6 ++ .../favorites/FavoriteEntryTypeRegistryImpl.java | 13 ++- .../gui/modules/entries/GameModeMenuEntry.java | 92 --------------------- .../gui/modules/entries/WeatherMenuEntry.java | 93 ---------------------- .../client/gui/widget/EntryStacksRegionWidget.java | 31 ++++++-- .../client/gui/widget/FavoritesListWidget.java | 38 +++++++-- .../gui/widget/region/RegionDraggableStack.java | 5 +- .../client/gui/widget/region/RegionListener.java | 2 + 8 files changed, 74 insertions(+), 206 deletions(-) delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/GameModeMenuEntry.java delete mode 100644 runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/WeatherMenuEntry.java (limited to 'runtime/src/main/java') 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 cb63b33ae..99c79f906 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 @@ -184,6 +184,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { return advanced.commands.weatherCommand; } + @Override + public String getTimeCommand() { + return advanced.commands.timeCommand; + } + @Override public int getMaxRecipePerPage() { return advanced.layout.maxRecipesPerPage; @@ -636,6 +641,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData { @Comment("Declares the command used to change gamemode.") private String gamemodeCommand = "/gamemode {gamemode}"; @Comment("Declares the command used in servers to cheat items.") private String giveCommand = "/give {player_name} {item_identifier}{nbt} {count}"; @Comment("Declares the command used to change weather.") private String weatherCommand = "/weather {weather}"; + @Comment("Declares the command used to change time.") private String timeCommand = "/time set {time}"; } public static class Miscellaneous { 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 75e77dc99..82439dd62 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 @@ -37,7 +37,6 @@ import me.shedaniel.rei.api.common.registry.ReloadStage; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import org.apache.commons.lang3.mutable.MutableLong; -import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Triple; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -51,7 +50,8 @@ import java.util.Map; public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry { private final BiMap> registry = HashBiMap.create(); private final List, MutableLong, List>> systemFavorites = Lists.newArrayList(); - private final Map sections = Maps.newLinkedHashMap(); + private final Map sections = Maps.newConcurrentMap(); + private final List sectionsList = Lists.newCopyOnWriteArrayList(); @Override public ReloadStage getStage() { @@ -81,12 +81,16 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry @Override public FavoriteEntryType.Section getOrCrateSection(Component text) { - return sections.computeIfAbsent(text, SectionImpl::new); + return sections.computeIfAbsent(text, $ -> { + SectionImpl section = new SectionImpl($); + sectionsList.add(section); + return section; + }); } @Override public Iterable sections() { - return this.sections.values(); + return sectionsList; } @Override @@ -103,6 +107,7 @@ public class FavoriteEntryTypeRegistryImpl implements FavoriteEntryType.Registry this.registry.clear(); this.systemFavorites.clear(); this.sections.clear(); + this.sectionsList.clear(); } @Override diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/GameModeMenuEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/GameModeMenuEntry.java deleted file mode 100644 index 031519369..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/GameModeMenuEntry.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.modules.entries; - -import com.mojang.blaze3d.vertex.PoseStack; -import me.shedaniel.rei.api.client.REIRuntime; -import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.impl.client.gui.modules.AbstractMenuEntry; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.resources.sounds.SimpleSoundInstance; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.level.GameType; - -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -public class GameModeMenuEntry extends AbstractMenuEntry { - public final String text; - public final GameType gameMode; - private int textWidth = -69; - - public GameModeMenuEntry(GameType gameMode) { - this.text = gameMode.getDisplayName().getString(); - this.gameMode = gameMode; - } - - private int getTextWidth() { - if (textWidth == -69) { - this.textWidth = Math.max(0, font.width(text)); - } - return this.textWidth; - } - - @Override - public int getEntryWidth() { - return getTextWidth() + 4; - } - - @Override - public int getEntryHeight() { - return 12; - } - - @Override - public List children() { - return Collections.emptyList(); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (isSelected()) { - fill(matrices, getX(), getY(), getX() + getWidth(), getY() + getEntryHeight(), -12237499); - } - if (isSelected() && containsMouse()) { - REIRuntime.getInstance().queueTooltip(Tooltip.create(new TranslatableComponent("text.rei.gamemode_button.tooltip.entry", text))); - } - font.draw(matrices, text, getX() + 2, getY() + 2, isSelected() ? 16777215 : 8947848); - } - - @Override - protected boolean onClick(double mouseX, double mouseY, int button) { - Minecraft.getInstance().player.chat(ConfigObject.getInstance().getGamemodeCommand().replaceAll("\\{gamemode}", gameMode.name().toLowerCase(Locale.ROOT))); - minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); - REIRuntime.getInstance().getOverlay().get().closeOverlayMenu(); - return true; - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/WeatherMenuEntry.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/WeatherMenuEntry.java deleted file mode 100644 index 5ef1bc79c..000000000 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/modules/entries/WeatherMenuEntry.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.modules.entries; - -import com.mojang.blaze3d.vertex.PoseStack; -import me.shedaniel.rei.api.client.REIRuntime; -import me.shedaniel.rei.api.client.config.ConfigObject; -import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.impl.client.gui.modules.AbstractMenuEntry; -import me.shedaniel.rei.impl.common.util.Weather; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.components.events.GuiEventListener; -import net.minecraft.client.resources.language.I18n; -import net.minecraft.client.resources.sounds.SimpleSoundInstance; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.sounds.SoundEvents; - -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -public class WeatherMenuEntry extends AbstractMenuEntry { - public final String text; - public final Weather weather; - private int textWidth = -69; - - public WeatherMenuEntry(Weather weather) { - this.text = I18n.get(weather.getTranslateKey()); - this.weather = weather; - } - - private int getTextWidth() { - if (textWidth == -69) { - this.textWidth = Math.max(0, font.width(text)); - } - return this.textWidth; - } - - @Override - public int getEntryWidth() { - return getTextWidth() + 4; - } - - @Override - public int getEntryHeight() { - return 12; - } - - @Override - public List children() { - return Collections.emptyList(); - } - - @Override - public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { - if (isSelected()) { - fill(matrices, getX(), getY(), getX() + getWidth(), getY() + getEntryHeight(), -12237499); - } - if (isSelected() && containsMouse()) { - REIRuntime.getInstance().queueTooltip(Tooltip.create(new TranslatableComponent("text.rei.weather_button.tooltip.entry", text))); - } - font.draw(matrices, text, getX() + 2, getY() + 2, isSelected() ? 16777215 : 8947848); - } - - @Override - protected boolean onClick(double mouseX, double mouseY, int button) { - Minecraft.getInstance().player.chat(ConfigObject.getInstance().getWeatherCommand().replaceAll("\\{weather}", weather.name().toLowerCase(Locale.ROOT))); - minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); - REIRuntime.getInstance().getOverlay().get().closeOverlayMenu(); - return true; - } -} diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java index 91bfe9ad8..64fcbd14b 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryStacksRegionWidget.java @@ -243,7 +243,14 @@ public class EntryStacksRegionWidget> extends WidgetWit return Optional.empty(); } - public void setEntries(List newEntries) { + public enum RemovalMode { + THROW_EXCEPTION, + DISAPPEAR, + MIGRATED, + ; + } + + public void setEntries(List newEntries, RemovalMode removalMode) { newEntries = Lists.newArrayList(newEntries); newEntries.removeIf(entry -> entry == null || entry.isEntryInvalid()); @@ -252,9 +259,13 @@ public class EntryStacksRegionWidget> extends WidgetWit List> removedEntries = Lists.newArrayList(this.entries.values()); removedEntries.removeIf(entry -> newFavoritesHash.contains(entry.hashIgnoreAmount())); - for (RealRegionEntry removedEntry : removedEntries) { - removedEntry.remove(); - this.removedEntries.put(removedEntry.hashIgnoreAmount(), removedEntry); + if (!removedEntries.isEmpty() && removalMode == RemovalMode.THROW_EXCEPTION) { + throw new IllegalStateException("Cannot remove entries from region " + this + ": " + removedEntries); + } else if (removalMode == RemovalMode.DISAPPEAR) { + for (RealRegionEntry removedEntry : removedEntries) { + removedEntry.remove(); + this.removedEntries.put(removedEntry.hashIgnoreAmount(), removedEntry); + } } List> addedEntries = new ArrayList<>(); @@ -459,7 +470,7 @@ public class EntryStacksRegionWidget> extends WidgetWit setEntries(this.entries.values().stream() .map(RealRegionEntry::getEntry) - .collect(Collectors.toList())); + .collect(Collectors.toList()), RemovalMode.THROW_EXCEPTION); return true; } @@ -467,9 +478,13 @@ public class EntryStacksRegionWidget> extends WidgetWit return entriesList.indexOf(entry.getWidget()); } - public void remove(RealRegionEntry entry) { - entries.remove(entry.hashIgnoreAmount()); - setEntries(CollectionUtils.map(entries.values(), RealRegionEntry::getEntry)); + public void remove(RealRegionEntry entry, RemovalMode mode) { + RealRegionEntry currentEntry = entries.get(entry.hashIgnoreAmount()); + if (currentEntry != null) { + List newEntries = CollectionUtils.map(entries.values(), RealRegionEntry::getEntry); + newEntries.remove(currentEntry.getEntry()); + setEntries(newEntries, mode); + } } public double getScrollAmount() { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java index 2e52b5db7..7c901515a 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/FavoritesListWidget.java @@ -178,6 +178,11 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt } } + @Override + public void onConsumed(RealRegionEntry entry) { + setSystemRegionEntries(entry); + } + @Override @Nullable public FavoriteEntry convertDraggableStack(DraggingContext context, DraggableStack stack) { @@ -195,7 +200,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt for (AddFavoritePanel.Row row : favoritePanel.rows.get()) { if (row instanceof AddFavoritePanel.SectionEntriesRow) { for (AddFavoritePanel.SectionEntriesRow.SectionFavoriteWidget widget : ((AddFavoritePanel.SectionEntriesRow) row).widgets) { - if (widget.containsMouse(mouseX, mouseY)) { + if (widget.containsMouse(mouseX, mouseY + favoritePanel.scroller.scrollAmount())) { RealRegionEntry entry = new RealRegionEntry<>(region, widget.entry.copy(), entrySize()); entry.size.setAs(entrySize() * 100); return new RegionDraggableStack<>(entry, widget); @@ -319,11 +324,11 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt if (updated) { lastSystemEntries = CollectionUtils.flatMap(providers, Triple::getRight); - setSystemRegionEntries(); + setSystemRegionEntries(null); } } - private void setSystemRegionEntries() { + private void setSystemRegionEntries(@Nullable RealRegionEntry removed) { systemRegion.setEntries(CollectionUtils.filterToList(lastSystemEntries, entry -> { if (region.has(entry)) return false; if (DraggingContext.getInstance().isDraggingStack()) { @@ -331,16 +336,17 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt if (currentStack instanceof RegionDraggableStack) { RegionDraggableStack stack = (RegionDraggableStack) currentStack; + if (removed != null && stack.getEntry() == removed) return true; return stack.getEntry().region != region || !Objects.equals(stack.getEntry().getEntry(), entry); } } return true; - })); + }), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); } @Override public void onSetNewEntries(List> regionEntryListEntries) { - setSystemRegionEntries(); + setSystemRegionEntries(null); } private void renderAddFavorite(PoseStack matrices, int mouseX, int mouseY, float delta) { @@ -363,8 +369,8 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt public void updateSearch() { if (ConfigObject.getInstance().isFavoritesEnabled()) { - region.setEntries(CollectionUtils.map(ConfigObject.getInstance().getFavoriteEntries(), FavoriteEntry::copy)); - } else region.setEntries(Collections.emptyList()); + region.setEntries(CollectionUtils.map(ConfigObject.getInstance().getFavoriteEntries(), FavoriteEntry::copy), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); + } else region.setEntries(Collections.emptyList(), EntryStacksRegionWidget.RemovalMode.DISAPPEAR); } @Override @@ -571,7 +577,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt matrices.translate(0, -scroller.scrollAmount(), 0); int y = scrollBounds.y; for (Row row : rows.get()) { - row.render(matrices, scrollBounds.x, y, scrollBounds.width, row.getRowHeight(), mouseX, mouseY, delta); + row.render(matrices, scrollBounds.x, y, scrollBounds.width, row.getRowHeight(), mouseX, mouseY + scroller.scrollAmountInt(), delta); y += row.getRowHeight(); } matrices.popPose(); @@ -724,6 +730,21 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt return widgets; } + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return super.mouseClicked(mouseX, mouseY + scroller.scrollAmount(), button); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + return super.mouseDragged(mouseX, mouseY + scroller.scrollAmount(), button, deltaX, deltaY); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + return super.mouseReleased(mouseX, mouseY + scroller.scrollAmount(), button); + } + private class SectionFavoriteWidget extends EntryListEntryWidget { private ValueAnimator pos = ValueAnimator.ofFloatingPoint(); private NumberAnimator size = ValueAnimator.ofDouble(); @@ -752,6 +773,7 @@ public class FavoritesListWidget extends WidgetWithBounds implements DraggableSt @Override @Nullable public Tooltip getCurrentTooltip(Point point) { + point = PointHelper.ofMouse(); if (!scrollBounds.contains(point)) return null; Tooltip tooltip = super.getCurrentTooltip(point); if (tooltip != null) { diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java index 486d16f7f..a85ab39f5 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionDraggableStack.java @@ -30,6 +30,7 @@ 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.widgets.WidgetWithBounds; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.impl.client.gui.widget.EntryStacksRegionWidget; public class RegionDraggableStack> implements DraggableStack { private RealRegionEntry entry; @@ -52,7 +53,7 @@ public class RegionDraggableStack> implements Draggable public void drag() { if (showcaseWidget == null && entry.region.listener.removeOnDrag()) { previousIndex = entry.region.indexOf(entry); - entry.region.remove(entry); + entry.region.remove(entry, EntryStacksRegionWidget.RemovalMode.MIGRATED); } } @@ -77,6 +78,8 @@ public class RegionDraggableStack> implements Draggable } else { entry.region.drop(entry); } + } else { + entry.region.listener.onConsumed(entry); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionListener.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionListener.java index b93d91920..0d582c767 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionListener.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/region/RegionListener.java @@ -65,4 +65,6 @@ public interface RegionListener> { default void onSetNewEntries(List> entries) {} default void onSetNewEntries(Stream entries) {} + + default void onConsumed(RealRegionEntry entry) {} } -- cgit