Эх сурвалжийг харах

improved recipe screen type setting

shedaniel 5 жил өмнө
parent
commit
7231cb82af

+ 21 - 8
build.gradle

@@ -58,14 +58,27 @@ dependencies {
     }
     modApi("me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig1u}")
     if (includeDep) {
-        include("me.shedaniel.cloth:cloth-events:${cloth_events_version}") {
-            transitive = false
-        }
-        include("me.shedaniel.cloth:config-2:${cloth_config_version}") {
-            transitive = false
-        }
-        include("me.sargunvohra.mcmods:autoconfig1u:${project.autoconfig1u}") {
-            transitive = false
+        afterEvaluate {
+            def listAdded = []
+            def eachDep = { dep ->
+                for (apiIncludeDepStr in (api_include as String).split(',')) {
+                    def apiIncludeGroup = apiIncludeDepStr.split(':')[0]
+                    def apiIncludeDep = apiIncludeDepStr.split(':')[1]
+                    if (dep.module.id.group == apiIncludeGroup && dep.module.id.name.startsWith(apiIncludeDep)) {
+                        def version = dep.module.id.version.indexOf('@') >= 0 ? dep.module.id.version.substring(0, dep.module.id.version.indexOf('@')) : dep.module.id.version
+                        def mavenDep = "${dep.module.id.group}:${dep.module.id.name}:$version"
+                        if (!(mavenDep in listAdded)) {
+                            include(mavenDep) {
+                                transitive = false
+                            }
+                            listAdded.add(mavenDep)
+                        }
+                        break
+                    }
+                }
+            }
+            configurations.compile.resolvedConfiguration.firstLevelModuleDependencies.each eachDep
+            configurations.runtimeClasspath.resolvedConfiguration.firstLevelModuleDependencies.each eachDep
         }
     }
     modCompileOnly("io.github.prospector:modmenu:${modmenu_version}") {

+ 4 - 2
gradle.properties

@@ -1,9 +1,11 @@
-mod_version=3.3.8
+mod_version=3.3.9
 minecraft_version=1.15.1
 yarn_version=1.15.1+build.1
 fabricloader_version=0.7.2+build.174
 cloth_events_version=1.1.0
-cloth_config_version=2.6.5
+cloth_config_version=2.6.6
 modmenu_version=1.8.0+build.16
 fabric_api=0.4.27+build.286-1.15
 autoconfig1u=1.2.4
+api_include=me.shedaniel.cloth:cloth-events,me.shedaniel.cloth:config-2,me.sargunvohra.mcmods:autoconfig1u
+#api_include=me.shedaniel.cloth:cloth-events,me.shedaniel.cloth:config-2,me.sargunvohra.mcmods:autoconfig1u,net.fabricmc.fabric-api:fabric-

+ 4 - 0
src/main/java/me/shedaniel/rei/api/ConfigObject.java

@@ -141,6 +141,10 @@ public interface ConfigObject {
     @Target({ElementType.FIELD})
     @interface UseEnumSelectorInstead {}
     
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD})
+    @interface UseSpecialRecipeTypeScreen {}
+    
     @Retention(RetentionPolicy.RUNTIME)
     @Target({ElementType.FIELD})
     @interface UsePercentage {

+ 95 - 31
src/main/java/me/shedaniel/rei/gui/PreRecipeViewingScreen.java

@@ -6,84 +6,150 @@
 package me.shedaniel.rei.gui;
 
 import com.google.common.collect.Lists;
+import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
+import me.shedaniel.clothconfig2.gui.widget.DynamicNewSmoothScrollingEntryListWidget;
+import me.shedaniel.clothconfig2.impl.EasingMethod;
+import me.shedaniel.math.api.Point;
 import me.shedaniel.math.api.Rectangle;
-import me.shedaniel.rei.api.*;
 import me.shedaniel.rei.gui.config.RecipeScreenType;
 import me.shedaniel.rei.gui.widget.ButtonWidget;
+import me.shedaniel.rei.gui.widget.LabelWidget;
 import me.shedaniel.rei.gui.widget.Widget;
 import me.shedaniel.rei.gui.widget.WidgetWithBounds;
-import me.shedaniel.rei.impl.ClientHelperImpl;
 import me.shedaniel.rei.impl.ScreenHelper;
 import net.minecraft.client.MinecraftClient;
 import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
 import net.minecraft.client.resource.language.I18n;
-import net.minecraft.client.sound.PositionedSoundInstance;
-import net.minecraft.sound.SoundEvents;
 import net.minecraft.text.TranslatableText;
 import net.minecraft.util.Formatting;
 import net.minecraft.util.Identifier;
+import net.minecraft.util.math.MathHelper;
 
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 
 public class PreRecipeViewingScreen extends Screen {
     
     private static final Identifier IDENTIFIER = new Identifier("roughlyenoughitems", "textures/gui/screenshot.png");
     private final List<Widget> widgets;
+    private boolean isSet;
     private boolean original;
-    private Map<RecipeCategory<?>, List<RecipeDisplay>> map;
-    private EntryStack mainStackToNotice = EntryStack.empty();
+    private double frame = 0;
+    private double target = 0;
+    private BooleanConsumer callback;
+    private Screen parent;
+    private boolean showTips;
+    protected long start;
+    protected long duration;
     
-    public PreRecipeViewingScreen(Map<RecipeCategory<?>, List<RecipeDisplay>> map) {
+    public PreRecipeViewingScreen(Screen parent, RecipeScreenType type, boolean showTips, BooleanConsumer callback) {
         super(new TranslatableText("text.rei.recipe_screen_type.selection"));
         this.widgets = Lists.newArrayList();
-        this.original = true;
-        this.map = map;
+        if (type == RecipeScreenType.UNSET) {
+            this.isSet = false;
+            this.original = true;
+        } else {
+            this.isSet = true;
+            this.original = type == RecipeScreenType.ORIGINAL;
+            moveFrameTo(original ? 0 : 1, false, 0);
+        }
+        this.callback = callback;
+        this.parent = parent;
+        this.showTips = showTips;
+    }
+    
+    public final double clamp(double v) {
+        return clamp(v, 30);
+    }
+    
+    public final double clamp(double v, double clampExtension) {
+        return MathHelper.clamp(v, -clampExtension, 1 + clampExtension);
     }
     
-    public void addMainStackToNotice(EntryStack mainStackToNotice) {
-        this.mainStackToNotice = mainStackToNotice;
+    private void moveFrameTo(double value, boolean animated, long duration) {
+        target = clamp(value);
+        
+        if (animated) {
+            start = System.currentTimeMillis();
+            this.duration = duration;
+        } else
+            frame = target;
     }
     
     @Override
     protected void init() {
         this.children.clear();
         this.widgets.clear();
-        this.widgets.add(new ButtonWidget(new Rectangle(width / 2 - 100, height - 40, 200, 20), I18n.translate("text.rei.select")) {
+        this.widgets.add(new ButtonWidget(new Rectangle(width / 2 - 100, height - 40, 200, 20), "") {
+            @Override
+            public void render(int mouseX, int mouseY, float delta) {
+                enabled = isSet;
+                setText(enabled ? I18n.translate("text.rei.select") : I18n.translate("config.roughlyenoughitems.recipeScreenType.unset"));
+                super.render(mouseX, mouseY, delta);
+            }
+            
             @Override
             public void onPressed() {
-                ConfigObject.getInstance().setRecipeScreenType(original ? RecipeScreenType.ORIGINAL : RecipeScreenType.VILLAGER);
-                ConfigManager.getInstance().saveConfig();
-                ((ClientHelperImpl) ClientHelper.getInstance()).openRecipeViewingScreen(map, mainStackToNotice);
+                callback.accept(original);
             }
         });
         this.widgets.add(new ScreenTypeSelection(width / 2 - 200 - 5, height / 2 - 112 / 2 - 10, 0));
+        this.widgets.add(new LabelWidget(new Point(width / 2 - 200 - 5 + 104, height / 2 - 112 / 2 + 115), I18n.translate("config.roughlyenoughitems.recipeScreenType.original")).noShadow().color(-1124073473));
         this.widgets.add(new ScreenTypeSelection(width / 2 + 5, height / 2 - 112 / 2 - 10, 112));
+        this.widgets.add(new LabelWidget(new Point(width / 2 + 5 + 104, height / 2 - 112 / 2 + 115), I18n.translate("config.roughlyenoughitems.recipeScreenType.villager")).noShadow().color(-1124073473));
         this.children.addAll(widgets);
     }
     
     @Override
     public void render(int int_1, int int_2, float float_1) {
-        this.renderBackground();
+        if (this.minecraft.world != null) {
+            this.fillGradient(0, 0, this.width, this.height, -1072689136, -804253680);
+        } else {
+            this.fillGradient(0, 0, this.width, this.height, -16777216, -16777216);
+        }
         this.drawCenteredString(this.font, this.title.asFormattedString(), this.width / 2, 20, 16777215);
-        int i = 30;
-        for (String s : this.font.wrapStringToWidthAsList(I18n.translate("text.rei.recipe_screen_type.selection.sub"), width - 30)) {
-            this.drawCenteredString(this.font, Formatting.GRAY.toString() + s, width / 2, i, -1);
-            i += 10;
+        if (showTips) {
+            int i = 30;
+            for (String s : this.font.wrapStringToWidthAsList(I18n.translate("text.rei.recipe_screen_type.selection.sub"), width - 30)) {
+                this.drawCenteredString(this.font, Formatting.GRAY.toString() + s, width / 2, i, -1);
+                i += 10;
+            }
         }
         super.render(int_1, int_2, float_1);
         for (Widget widget : widgets) {
             widget.render(int_1, int_2, float_1);
         }
+        if (isSet) {
+            updateFramePosition(float_1);
+            int x = (int) (width / 2 - 205 + (210 * frame));
+            int y = height / 2 - 112 / 2 - 10;
+            fillGradient(x - 2, y - 4, x - 6 + 208, y - 4 + 2, -1778384897, -1778384897);
+            fillGradient(x - 2, y - 4 + 120 - 2, x - 6 + 208, y - 4 + 120, -1778384897, -1778384897);
+            fillGradient(x - 4, y - 4, x - 4 + 2, y - 4 + 120, -1778384897, -1778384897);
+            fillGradient(x - 4 + 208 - 2, y - 4, x - 4 + 208, y - 4 + 120, -1778384897, -1778384897);
+        }
+    }
+    
+    private void updateFramePosition(float delta) {
+        target = clamp(target);
+        if (!DynamicNewSmoothScrollingEntryListWidget.Precision.almostEquals(frame, target, DynamicNewSmoothScrollingEntryListWidget.Precision.FLOAT_EPSILON))
+            frame = ease(frame, target, Math.min((System.currentTimeMillis() - start) / ((double) duration), 1));
+        else
+            frame = target;
+    }
+    
+    private double ease(double start, double end, double amount) {
+        return start + (end - start) * EasingMethod.EasingMethodImpl.LINEAR.apply(amount);
     }
     
     @Override
     public boolean keyPressed(int int_1, int int_2, int int_3) {
-        if ((int_1 == 256 || this.minecraft.options.keyInventory.matchesKey(int_1, int_2)) && this.shouldCloseOnEsc()) {
-            MinecraftClient.getInstance().openScreen(ScreenHelper.getLastContainerScreen());
-            ScreenHelper.getLastOverlay().init();
+        if (int_1 == 256 || this.minecraft.options.keyInventory.matchesKey(int_1, int_2)) {
+            MinecraftClient.getInstance().openScreen(parent);
+            if (parent instanceof AbstractContainerScreen)
+                ScreenHelper.getLastOverlay().init();
             return true;
         }
         return super.keyPressed(int_1, int_2, int_3);
@@ -109,19 +175,17 @@ public class PreRecipeViewingScreen extends Screen {
         public void render(int i, int i1, float delta) {
             MinecraftClient.getInstance().getTextureManager().bindTexture(IDENTIFIER);
             blit(bounds.x + 4, bounds.y + 4, u, v, 200, 112);
-            if (original == (v == 0)) {
-                fillGradient(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y + 2, 0xFFFFFFFF, 0xFFFFFFFF);
-                fillGradient(bounds.x, bounds.y + bounds.height - 2, bounds.x + bounds.width, bounds.y + bounds.height, 0xFFFFFFFF, 0xFFFFFFFF);
-                fillGradient(bounds.x, bounds.y, bounds.x + 2, bounds.y + bounds.height, 0xFFFFFFFF, 0xFFFFFFFF);
-                fillGradient(bounds.x + bounds.width - 2, bounds.y, bounds.x + bounds.width, bounds.y + bounds.height, 0xFFFFFFFF, 0xFFFFFFFF);
-            }
         }
         
         @Override
         public boolean mouseClicked(double double_1, double double_2, int int_1) {
             if (containsMouse(double_1, double_2)) {
-                minecraft.getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
                 original = (v == 0);
+                if (!isSet) {
+                    moveFrameTo(!original ? 0 : 1, false, 0);
+                }
+                isSet = true;
+                moveFrameTo(original ? 0 : 1, true, 1000);
                 return true;
             }
             return false;

+ 5 - 4
src/main/java/me/shedaniel/rei/impl/ClientHelperImpl.java

@@ -42,7 +42,6 @@ import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 
 @Deprecated
 @Internal
@@ -207,9 +206,11 @@ public class ClientHelperImpl implements ClientHelper, ClientModInitializer {
             if (notice != null)
                 ((VillagerRecipeViewingScreen) screen).addMainStackToNotice(notice);
         } else if (ConfigObject.getInstance().getRecipeScreenType() == RecipeScreenType.UNSET) {
-            screen = new PreRecipeViewingScreen(map);
-            if (notice != null)
-                ((PreRecipeViewingScreen) screen).addMainStackToNotice(notice);
+            screen = new PreRecipeViewingScreen(ScreenHelper.getLastContainerScreen(), RecipeScreenType.UNSET, true, original -> {
+                ConfigObject.getInstance().setRecipeScreenType(original ? RecipeScreenType.ORIGINAL : RecipeScreenType.VILLAGER);
+                ConfigManager.getInstance().saveConfig();
+                openRecipeViewingScreen(map, notice);
+            });
         } else {
             screen = new RecipeViewingScreen(map);
             if (notice != null)

+ 68 - 8
src/main/java/me/shedaniel/rei/impl/ConfigManagerImpl.java

@@ -5,6 +5,7 @@
 
 package me.shedaniel.rei.impl;
 
+import com.google.common.collect.ImmutableList;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonElement;
@@ -21,6 +22,8 @@ import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
 import me.shedaniel.clothconfig2.api.Modifier;
 import me.shedaniel.clothconfig2.api.ModifierKeyCode;
 import me.shedaniel.clothconfig2.gui.entries.KeyCodeEntry;
+import me.shedaniel.clothconfig2.gui.entries.TooltipListEntry;
+import me.shedaniel.math.api.Rectangle;
 import me.shedaniel.rei.RoughlyEnoughItemsCore;
 import me.shedaniel.rei.api.ConfigManager;
 import me.shedaniel.rei.api.ConfigObject;
@@ -29,19 +32,25 @@ import me.shedaniel.rei.api.RecipeHelper;
 import me.shedaniel.rei.api.annotations.Internal;
 import me.shedaniel.rei.gui.ConfigReloadingScreen;
 import me.shedaniel.rei.gui.ContainerScreenOverlay;
+import me.shedaniel.rei.gui.PreRecipeViewingScreen;
+import me.shedaniel.rei.gui.config.RecipeScreenType;
 import me.shedaniel.rei.gui.credits.CreditsScreen;
+import me.shedaniel.rei.gui.widget.ButtonWidget;
 import me.shedaniel.rei.gui.widget.ReloadConfigButtonWidget;
 import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.Element;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.widget.AbstractPressableButtonWidget;
 import net.minecraft.client.resource.language.I18n;
 import net.minecraft.client.util.InputUtil;
+import net.minecraft.client.util.Window;
 import net.minecraft.text.LiteralText;
 import net.minecraft.util.math.MathHelper;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 
 import static me.sargunvohra.mcmods.autoconfig1u.util.Utils.getUnsafely;
 import static me.sargunvohra.mcmods.autoconfig1u.util.Utils.setUnsafely;
@@ -98,14 +107,66 @@ public class ConfigManagerImpl implements ConfigManager {
         }, field -> field.getType() == ModifierKeyCode.class, ConfigObject.UsePercentage.class);
         guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> {
             ConfigObject.UsePercentage bounds = field.getAnnotation(ConfigObject.UsePercentage.class);
-            return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(i13n, MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> {
-                return MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100);
-            }).setSaveConsumer((newValue) -> {
+            return Collections.singletonList(ConfigEntryBuilder.create().startIntSlider(i13n, MathHelper.ceil(Utils.getUnsafely(field, config, 0.0) * 100), MathHelper.ceil(bounds.min() * 100), MathHelper.ceil(bounds.max() * 100)).setDefaultValue(() -> MathHelper.ceil((double) Utils.getUnsafely(field, defaults) * 100)).setSaveConsumer((newValue) -> {
                 Utils.setUnsafely(field, config, newValue / 100d);
             }).setTextGetter(integer -> String.format("Size: %d%%", integer)).build());
-        }, (field) -> {
-            return field.getType() == Double.TYPE || field.getType() == Double.class;
-        }, ConfigObject.UsePercentage.class);
+        }, (field) -> field.getType() == Double.TYPE || field.getType() == Double.class, ConfigObject.UsePercentage.class);
+        
+        
+        guiRegistry.registerAnnotationProvider((i13n, field, config, defaults, guiProvider) -> {
+            int width = 220;
+            return Collections.singletonList(new TooltipListEntry<RecipeScreenType>(i13n, null) {
+                private RecipeScreenType type = getUnsafely(field, config, RecipeScreenType.UNSET);
+                private ButtonWidget buttonWidget = new ButtonWidget(new Rectangle(0, 0, 0, 20), "") {
+                    @Override
+                    public void onPressed() {
+                        MinecraftClient.getInstance().openScreen(new PreRecipeViewingScreen(getScreen(), type, false, original -> {
+                            MinecraftClient.getInstance().openScreen(getScreen());
+                            type = original ? RecipeScreenType.ORIGINAL : RecipeScreenType.VILLAGER;
+                            getScreen().setEdited(true, isRequiresRestart());
+                        }));
+                    }
+                    
+                    @Override
+                    public void render(int mouseX, int mouseY, float delta) {
+                        setText(I18n.translate("config.roughlyenoughitems.recipeScreenType.config", type.toString()));
+                        super.render(mouseX, mouseY, delta);
+                    }
+                };
+                private List<ButtonWidget> children = ImmutableList.of(buttonWidget);
+                
+                @Override
+                public RecipeScreenType getValue() {
+                    return type;
+                }
+                
+                @Override
+                public Optional<RecipeScreenType> getDefaultValue() {
+                    return Optional.ofNullable(getUnsafely(field, defaults));
+                }
+                
+                @Override
+                public void save() {
+                    Utils.setUnsafely(field, config, type);
+                }
+                
+                @Override
+                public List<? extends Element> children() {
+                    return children;
+                }
+                
+                @Override
+                public void render(int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
+                    super.render(index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
+                    Window window = MinecraftClient.getInstance().getWindow();
+                    this.buttonWidget.enabled = this.isEditable();
+                    this.buttonWidget.getBounds().y = y;
+                    this.buttonWidget.getBounds().x = x + entryWidth / 2 - width / 2;
+                    this.buttonWidget.getBounds().width = width;
+                    this.buttonWidget.render(mouseX, mouseY, delta);
+                }
+            });
+        }, (field) -> field.getType() == RecipeScreenType.class, ConfigObject.UseSpecialRecipeTypeScreen.class);
         loadFavoredEntries();
         RoughlyEnoughItemsCore.LOGGER.info("[REI] Config is loaded.");
     }
@@ -203,8 +264,7 @@ public class ConfigManagerImpl implements ConfigManager {
                 renderDirtBackground(0);
                 List<String> list = minecraft.textRenderer.wrapStringToWidthAsList(I18n.translate("text.rei.config_api_failed"), width - 100);
                 int y = (int) (height / 2 - minecraft.textRenderer.fontHeight * 1.3f / 2 * list.size());
-                for (int i = 0; i < list.size(); i++) {
-                    String s = list.get(i);
+                for (String s : list) {
                     drawCenteredString(minecraft.textRenderer, s, width / 2, y, -1);
                     y += minecraft.textRenderer.fontHeight;
                 }

+ 1 - 1
src/main/java/me/shedaniel/rei/impl/ConfigObjectImpl.java

@@ -285,10 +285,10 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
     }
     
     public static class Appearance {
+        @UseSpecialRecipeTypeScreen private RecipeScreenType recipeScreenType = RecipeScreenType.UNSET;
         @Comment("The ordering of the items on the item panel.") @UseEnumSelectorInstead
         private ItemListOrderingConfig itemListOrdering = ItemListOrderingConfig.REGISTRY_ASCENDING;
         @Comment("Declares the appearance of REI windows.") private boolean darkTheme = false;
-        @Comment("The ordering of the items on the item panel.") @UseEnumSelectorInstead private RecipeScreenType recipeScreenType = RecipeScreenType.UNSET;
         @Comment("Declares the position of the search field.") @UseEnumSelectorInstead
         private SearchFieldLocation searchFieldLocation = SearchFieldLocation.CENTER;
         @Comment("Declares the position of the item list panel.") private boolean mirrorItemPanel = false;

+ 1 - 0
src/main/resources/assets/roughlyenoughitems/lang/en_us.json

@@ -149,6 +149,7 @@
   "config.roughlyenoughitems.itemListOrdering": "Entry List Ordering:",
   "config.roughlyenoughitems.list_ordering_button": "%s [%s]",
   "config.roughlyenoughitems.recipeScreenType": "Recipe Screen Type:",
+  "config.roughlyenoughitems.recipeScreenType.config": "Recipe Screen Type: %s",
   "config.roughlyenoughitems.recipeScreenType.unset": "Not Set",
   "config.roughlyenoughitems.recipeScreenType.original": "Original",
   "config.roughlyenoughitems.recipeScreenType.villager": "Villager Like",

+ 3 - 3
src/main/resources/fabric.mod.json

@@ -35,9 +35,9 @@
     ]
   },
   "depends": {
-    "fabricloader": ">=0.4.0",
-    "cloth": "*",
-    "cloth-config2": ">=1.1.1"
+    "fabricloader": "*",
+    "cloth": ">=1.1.0",
+    "cloth-config2": ">=2.6.6"
   },
   "mixins": [
     "mixin.roughlyenoughitems.json",