diff options
| author | shedaniel <daniel@shedaniel.me> | 2021-03-28 02:08:07 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2021-03-28 02:08:07 +0800 |
| commit | 9d835c7823978e04007414cfe3ebf128e23a6494 (patch) | |
| tree | 116461d55ea4b3b233145e739e60437db9ddc569 | |
| parent | c80c345c4fa3def0536bcecbc2223f202af79415 (diff) | |
| download | RoughlyEnoughItems-9d835c7823978e04007414cfe3ebf128e23a6494.tar.gz RoughlyEnoughItems-9d835c7823978e04007414cfe3ebf128e23a6494.tar.bz2 RoughlyEnoughItems-9d835c7823978e04007414cfe3ebf128e23a6494.zip | |
A simpler implementation of stacked favorites
Signed-off-by: shedaniel <daniel@shedaniel.me>
3 files changed, 199 insertions, 94 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/favorites/CompoundFavoriteRenderer.java b/api/src/main/java/me/shedaniel/rei/api/client/favorites/CompoundFavoriteRenderer.java new file mode 100644 index 000000000..623c37606 --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/favorites/CompoundFavoriteRenderer.java @@ -0,0 +1,120 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020 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.api.client.favorites; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector4f; +import me.shedaniel.clothconfig2.api.ScissorsHandler; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.AbstractRenderer; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.common.util.Animator; +import net.minecraft.Util; + +import java.util.List; +import java.util.function.IntFunction; +import java.util.function.IntSupplier; + +public class CompoundFavoriteRenderer extends AbstractRenderer { + protected Animator offset = new Animator(0); + protected Rectangle scissorArea = new Rectangle(); + protected long nextSwitch = -1; + protected IntFunction<Renderer> renderers; + protected int count; + protected boolean showcase; + protected IntSupplier supplier; + + /** + * Showcase + */ + public CompoundFavoriteRenderer(List<Renderer> renderers) { + this(true, renderers, null); + } + + /** + * Non showcase + */ + public CompoundFavoriteRenderer(List<Renderer> renderers, IntSupplier supplier) { + this(false, renderers, supplier); + } + + public CompoundFavoriteRenderer(boolean showcase, List<Renderer> renderers, IntSupplier supplier) { + this(showcase, renderers.size(), renderers::get, supplier); + } + + /** + * Showcase + */ + public CompoundFavoriteRenderer(int count, IntFunction<Renderer> renderers) { + this(true, count, renderers, null); + } + + /** + * Non showcase + */ + public CompoundFavoriteRenderer(int count, IntFunction<Renderer> renderers, IntSupplier supplier) { + this(false, count, renderers, supplier); + } + + public CompoundFavoriteRenderer(boolean showcase, int count, IntFunction<Renderer> renderers, IntSupplier supplier) { + this.count = count; + this.showcase = showcase; + this.renderers = renderers; + this.supplier = supplier; + } + + @Override + public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { + updateAnimator(delta); + Vector4f vector4f = new Vector4f(bounds.x, bounds.y, 0, 1.0F); + vector4f.transform(matrices.last().pose()); + Vector4f vector4f2 = new Vector4f(bounds.getMaxX(), bounds.getMaxY(), 0, 1.0F); + vector4f2.transform(matrices.last().pose()); + scissorArea.setBounds((int) vector4f.x(), (int) vector4f.y(), (int) vector4f2.x() - (int) vector4f.x(), (int) vector4f2.y() - (int) vector4f.y()); + ScissorsHandler.INSTANCE.scissor(scissorArea); + matrices.pushPose(); + matrices.translate(0, this.offset.floatValue() * -bounds.getHeight(), 0); + for (int i = 0; i < count; i++) { + renderers.apply(i).render(matrices, bounds, mouseX, mouseY, delta); + matrices.translate(0, bounds.height, 0); + } + matrices.popPose(); + ScissorsHandler.INSTANCE.removeLastScissor(); + } + + private void updateAnimator(float delta) { + offset.update(delta); + if (showcase) { + if (nextSwitch == -1) { + nextSwitch = Util.getMillis(); + } + if (Util.getMillis() - nextSwitch > 1000) { + nextSwitch = Util.getMillis(); + offset.setTo(((int) offset.target() + 1) % count, 500); + } + } else { + offset.setTo(supplier.getAsInt() % count, 500); + } + } +} diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java index 9be48eff1..78bbe9ca6 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/GameModeFavoriteEntry.java @@ -24,22 +24,19 @@ package me.shedaniel.rei.plugin.client.favorites; import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Vector4f; -import me.shedaniel.clothconfig2.api.ScissorsHandler; import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIHelper; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.favorites.CompoundFavoriteRenderer; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; import me.shedaniel.rei.api.client.favorites.FavoriteMenuEntry; import me.shedaniel.rei.api.client.gui.AbstractRenderer; import me.shedaniel.rei.api.client.gui.Renderer; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; -import me.shedaniel.rei.api.common.util.Animator; import me.shedaniel.rei.api.common.util.CollectionUtils; import net.minecraft.ChatFormatting; -import net.minecraft.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.events.GuiEventListener; @@ -54,6 +51,8 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class GameModeFavoriteEntry extends FavoriteEntry { public static final ResourceLocation ID = new ResourceLocation("roughlyenoughitems", "gamemode"); @@ -73,51 +72,39 @@ public class GameModeFavoriteEntry extends FavoriteEntry { @Override public Renderer getRenderer(boolean showcase) { - return new AbstractRenderer() { - private Animator notSetOffset = new Animator(0); - private Rectangle notSetScissorArea = new Rectangle(); - private long nextSwitch = -1; + if (gameMode == null) { + List<Renderer> renderers = IntStream.range(0, 4).mapToObj(GameModeFavoriteEntry::getRenderer).collect(Collectors.toList()); + return new CompoundFavoriteRenderer(showcase, renderers, () -> Minecraft.getInstance().gameMode.getPlayerMode().getId()) { + @Override + @Nullable + public Tooltip getTooltip(Point mouse) { + return Tooltip.create(mouse, new TranslatableComponent("text.rei.gamemode_button.tooltip.dropdown")); + } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + return hashCode() == o.hashCode(); + } + + @Override + public int hashCode() { + return Objects.hash(getClass(), showcase); + } + }; + } + return getRenderer(gameMode.getId()); + } + + private static Renderer getRenderer(int id) { + GameType type = GameType.byId(id); + return new AbstractRenderer() { @Override public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { int color = bounds.contains(mouseX, mouseY) ? 0xFFEEEEEE : 0xFFAAAAAA; -// fillGradient(matrices, bounds.getX(), bounds.getY(), bounds.getMaxX(), bounds.getY() + 1, color, color); -// fillGradient(matrices, bounds.getX(), bounds.getMaxY() - 1, bounds.getMaxX(), bounds.getMaxY(), color, color); -// fillGradient(matrices, bounds.getX(), bounds.getY(), bounds.getX() + 1, bounds.getMaxY(), color, color); -// fillGradient(matrices, bounds.getMaxX() - 1, bounds.getY(), bounds.getMaxX(), bounds.getMaxY(), color, color); if (bounds.width > 4 && bounds.height > 4) { - if (gameMode == null) { - updateAnimator(delta); - Vector4f vector4f = new Vector4f(bounds.x + 2, bounds.y + 2, 0, 1.0F); - vector4f.transform(matrices.last().pose()); - Vector4f vector4f2 = new Vector4f(bounds.getMaxX() - 2, bounds.getMaxY() - 2, 0, 1.0F); - vector4f2.transform(matrices.last().pose()); - notSetScissorArea.setBounds((int) vector4f.x(), (int) vector4f.y(), (int) vector4f2.x() - (int) vector4f.x(), (int) vector4f2.y() - (int) vector4f.y()); - ScissorsHandler.INSTANCE.scissor(notSetScissorArea); - int offset = Math.round(notSetOffset.floatValue() * bounds.getHeight()); - for (int i = 0; i <= 3; i++) { - GameType type = GameType.byId(i); - renderGameModeText(matrices, type, bounds.getCenterX(), bounds.getCenterY() + bounds.getHeight() * i - offset, color); - } - ScissorsHandler.INSTANCE.removeLastScissor(); - } else { - renderGameModeText(matrices, gameMode, bounds.getCenterX(), bounds.getCenterY(), color); - } - } - } - - private void updateAnimator(float delta) { - notSetOffset.update(delta); - if (showcase) { - if (nextSwitch == -1) { - nextSwitch = Util.getMillis(); - } - if (Util.getMillis() - nextSwitch > 1000) { - nextSwitch = Util.getMillis(); - notSetOffset.setTo(((int) notSetOffset.target() + 1) % 4, 500); - } - } else { - notSetOffset.setTo((Minecraft.getInstance().gameMode.getPlayerMode().getId() + 1) % 4, 500); + renderGameModeText(matrices, type, bounds.getCenterX(), bounds.getCenterY(), color); } } @@ -130,9 +117,7 @@ public class GameModeFavoriteEntry extends FavoriteEntry { @Override @Nullable public Tooltip getTooltip(Point mouse) { - if (gameMode == null) - return Tooltip.create(mouse, new TranslatableComponent("text.rei.gamemode_button.tooltip.dropdown")); - return Tooltip.create(mouse, new TranslatableComponent("text.rei.gamemode_button.tooltip.entry", gameMode.getDisplayName().getString())); + return Tooltip.create(mouse, new TranslatableComponent("text.rei.gamemode_button.tooltip.entry", type.getDisplayName().getString())); } @Override @@ -144,7 +129,7 @@ public class GameModeFavoriteEntry extends FavoriteEntry { @Override public int hashCode() { - return Objects.hash(getClass(), showcase, gameMode); + return Objects.hash(getClass(), false, type); } }; } diff --git a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java index acd9e6a69..b288a2f8f 100644 --- a/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java +++ b/default-plugin/src/main/java/me/shedaniel/rei/plugin/client/favorites/WeatherFavoriteEntry.java @@ -30,6 +30,7 @@ import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.REIHelper; import me.shedaniel.rei.api.client.config.ConfigObject; +import me.shedaniel.rei.api.client.favorites.CompoundFavoriteRenderer; import me.shedaniel.rei.api.client.favorites.FavoriteEntry; import me.shedaniel.rei.api.client.favorites.FavoriteEntryType; import me.shedaniel.rei.api.client.favorites.FavoriteMenuEntry; @@ -40,18 +41,24 @@ import me.shedaniel.rei.api.common.util.Animator; import me.shedaniel.rei.api.common.util.CollectionUtils; import net.minecraft.Util; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.resources.language.I18n; import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.level.GameType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class WeatherFavoriteEntry extends FavoriteEntry { public static final ResourceLocation ID = new ResourceLocation("roughlyenoughitems", "weather"); @@ -72,56 +79,51 @@ public class WeatherFavoriteEntry extends FavoriteEntry { @Override public Renderer getRenderer(boolean showcase) { + if (weather == null) { + List<Renderer> renderers = IntStream.range(0, 3).mapToObj(WeatherFavoriteEntry::getRenderer).collect(Collectors.toList()); + return new CompoundFavoriteRenderer(showcase, renderers, () -> getCurrentWeather().getId()) { + @Override + @Nullable + public Tooltip getTooltip(Point mouse) { + return Tooltip.create(mouse, new TranslatableComponent("text.rei.weather_button.tooltip.dropdown")); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + return hashCode() == o.hashCode(); + } + + @Override + public int hashCode() { + return Objects.hash(getClass(), showcase); + } + }; + } + return getRenderer(weather.getId()); + } + + private static Weather getCurrentWeather() { + ClientLevel world = Minecraft.getInstance().level; + if (world.isThundering()) + return Weather.THUNDER; + if (world.getLevelData().isRaining()) + return Weather.RAIN; + return Weather.CLEAR; + } + + private static Renderer getRenderer(int id) { + Weather weather = Weather.byId(id); return new AbstractRenderer() { - private Animator notSetOffset = new Animator(0); - private Rectangle notSetScissorArea = new Rectangle(); - private long nextSwitch = -1; - @Override public void render(PoseStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { int color = bounds.contains(mouseX, mouseY) ? 0xFFEEEEEE : 0xFFAAAAAA; if (bounds.width > 4 && bounds.height > 4) { - if (weather == null) { - matrices.pushPose(); - updateAnimator(delta); - Vector4f vector4f = new Vector4f(bounds.x, bounds.y, 0, 1.0F); - vector4f.transform(matrices.last().pose()); - Vector4f vector4f2 = new Vector4f(bounds.getMaxX(), bounds.getMaxY(), 0, 1.0F); - vector4f2.transform(matrices.last().pose()); - notSetScissorArea.setBounds((int) vector4f.x(), (int) vector4f.y(), (int) vector4f2.x() - (int) vector4f.x(), (int) vector4f2.y() - (int) vector4f.y()); - ScissorsHandler.INSTANCE.scissor(notSetScissorArea); - int offset = Math.round(notSetOffset.floatValue() * bounds.getHeight()); - for (int i = 0; i <= 2; i++) { - Weather type = Weather.byId(i); - renderWeatherIcon(matrices, type, bounds.getCenterX(), bounds.getCenterY() + bounds.getHeight() * i - offset, color); - } - ScissorsHandler.INSTANCE.removeLastScissor(); - matrices.popPose(); - } else { - renderWeatherIcon(matrices, weather, bounds.getCenterX(), bounds.getCenterY(), color); - } - } -// fillGradient(matrices, bounds.getX(), bounds.getY(), bounds.getMaxX(), bounds.getY() + 1, color, color); -// fillGradient(matrices, bounds.getX(), bounds.getMaxY() - 1, bounds.getMaxX(), bounds.getMaxY(), color, color); -// fillGradient(matrices, bounds.getX(), bounds.getY(), bounds.getX() + 1, bounds.getMaxY(), color, color); -// fillGradient(matrices, bounds.getMaxX() - 1, bounds.getY(), bounds.getMaxX(), bounds.getMaxY(), color, color); - } - - private void updateAnimator(float delta) { - notSetOffset.update(delta); - if (showcase) { - if (nextSwitch == -1) { - nextSwitch = Util.getMillis(); - } - if (Util.getMillis() - nextSwitch > 1000) { - nextSwitch = Util.getMillis(); - notSetOffset.setTo(((int) notSetOffset.target() + 1) % 3, 500); - } - } else { - notSetOffset.setTo((Minecraft.getInstance().gameMode.getPlayerMode().getId() + 1) % 3, 500); + renderWeatherIcon(matrices, weather, bounds.getCenterX(), bounds.getCenterY(), color); } } - + private void renderWeatherIcon(PoseStack matrices, Weather type, int centerX, int centerY, int color) { Minecraft.getInstance().getTextureManager().bind(CHEST_GUI_TEXTURE); blit(matrices, centerX - 7, centerY - 7, type.getId() * 14, 14, 14, 14, 256, 256); @@ -130,8 +132,6 @@ public class WeatherFavoriteEntry extends FavoriteEntry { @Override @Nullable public Tooltip getTooltip(Point mouse) { - if (weather == null) - return Tooltip.create(mouse, new TranslatableComponent("text.rei.weather_button.tooltip.dropdown")); return Tooltip.create(mouse, new TranslatableComponent("text.rei.weather_button.tooltip.entry", new TranslatableComponent(weather.getTranslateKey()))); } @@ -144,7 +144,7 @@ public class WeatherFavoriteEntry extends FavoriteEntry { @Override public int hashCode() { - return Objects.hash(getClass(), showcase, weather); + return Objects.hash(getClass(), false, weather); } }; } |
