diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java index 545548153..36e75d18b 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java @@ -10,6 +10,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.config.ModConfig; public class BaseConfigScreen extends ConfigScreen { @@ -29,14 +30,14 @@ public class BaseConfigScreen extends ConfigScreen { TextStencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); text.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2)); widgets.add(clientConfigWidget = new PonderButton(width / 2 - 100, height / 2 - 15 - 50, (_$, _$$) -> { - ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.CLIENT.specification)); + ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.CLIENT, AllConfigs.CLIENT.specification)); }, 200, 30).showingUnscaled(text)); clientConfigWidget.fade(1); TextStencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); text2.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2)); widgets.add(commonConfigWidget = new PonderButton(width / 2 - 100, height / 2 - 15, (_$, _$$) -> { - ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.COMMON.specification)); + ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.COMMON, AllConfigs.COMMON.specification)); }, 200, 30).showingUnscaled(text2)); commonConfigWidget.fade(1); @@ -47,7 +48,7 @@ public class BaseConfigScreen extends ConfigScreen { serverConfigWidget.fade(1); if (Minecraft.getInstance().world != null) { - serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new ServerSubMenuConfigScreen(this, AllConfigs.SERVER.specification))); + serverConfigWidget.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, AllConfigs.SERVER.specification))); } else { serverConfigWidget.active = false; text3.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_disable_1, ConfigButton.Palette.button_disable_2)); diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java index 93a5d571b..64deb5e76 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java @@ -1,6 +1,8 @@ package com.simibubi.create.foundation.config.ui; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -11,10 +13,9 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.GuiGameElement; import com.simibubi.create.foundation.gui.StencilElement; -import com.simibubi.create.foundation.gui.TextStencilElement; -import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; import com.simibubi.create.foundation.utility.animation.Force; import com.simibubi.create.foundation.utility.animation.PhysicalFloat; @@ -22,40 +23,32 @@ import net.minecraft.block.BlockState; import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.Direction; -public abstract class ConfigScreen extends NavigatableSimiScreen { +public abstract class ConfigScreen extends AbstractSimiScreen { /* - * - * TODO - * zelo's list for configUI - * - * match style with ponderUI - * cache changes before setting values and saving to file - * don't exit on ESC - * reset text field focus for any click inside screen - * adjust transition animation of screens - * allow backspace in text fields - * move config button's animations to ponder button or a new superclass - * get some proper icons for reset button and enum cycle - * some small shadow effect for top and bottom of the list - * add the 'think back' button back, just with a different caption - * add a title to the current config screen, maybe in the form of breadcrumbs - * - * some color themes maybe? - * at least a helper class to unite colors throughout different uis - * - * FIXME - * - * tooltip are hidden underneath the scrollbar, if the bar is near the middle - * misalignment of the label-streak and textboxes/enum stuff - * - * */ + * + * TODO + * zelo's list for configUI + * + * adjust transition animation of screens -> disabled for now + * move config button's animations to ponder button or a new superclass + * get some proper icons for reset button and enum cycle + * + * some color themes maybe? + * at least a helper class to unite colors throughout different uis + * + * FIXME + * + * tooltip are hidden underneath the scrollbar, if the bar is near the middle + * misalignment of the label-streak and textboxes/enum stuff + * framebuffer blending is incorrect + * + * */ + public static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f)); + public static final BlockState cogwheelState = AllBlocks.LARGE_COGWHEEL.getDefaultState().with(CogWheelBlock.AXIS, Direction.Axis.Y); + public static final Map changes = new HashMap<>(); protected final Screen parent; - protected static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f)); - protected static final BlockState cogwheelState = AllBlocks.LARGE_COGWHEEL.getDefaultState().with(CogWheelBlock.AXIS, Direction.Axis.Y); - - protected StencilElement testStencil; public ConfigScreen(Screen parent) { this.parent = parent; @@ -63,47 +56,24 @@ public abstract class ConfigScreen extends NavigatableSimiScreen { @Override public void tick() { - cogSpin.tick(); - - widgets.stream() - .filter(w -> w instanceof ConfigButton) - .forEach(w -> ((ConfigButton) w).tick()); - super.tick(); - } - - @Override - protected void init() { - /*super.init(); - if (backTrack != null) { - widgets.remove(backTrack); - backTrack = null; - }*/ - - - testStencil = new TextStencilElement(client.fontRenderer, "POGGERS").at(width*0.5f, height*0.5f, 0); + cogSpin.tick(); } @Override public void renderBackground(@Nonnull MatrixStack ms) { - //fill(ms, 0, 0, this.width, this.height, 0xe8_101010); net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this, ms)); } @Override protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { RenderSystem.disableDepthTest(); - if (this.client != null && this.client.world != null){ + if (this.client != null && this.client.world != null) { fill(ms, 0, 0, this.width, this.height, 0xb0_282c34); } else { fill(ms, 0, 0, this.width, this.height, 0xff_282c34); } - /*ms.push(); - ms.translate(width*0.5f, height*0.5f, 0); - renderCog(ms, partialTicks); - ms.pop();*/ - new StencilElement() { @Override protected void renderStencil(MatrixStack ms) { @@ -120,18 +90,6 @@ public abstract class ConfigScreen extends NavigatableSimiScreen { } - protected void renderCog(MatrixStack ms, float partialTicks) { - ms.push(); - - ms.translate(-100, 100, -200); - ms.scale(200, 200, .1f); - GuiGameElement.of(cogwheelState) - .rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5) - .render(ms); - - ms.pop(); - } - @Override protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { int x = (int) (width * 0.5f); @@ -155,4 +113,16 @@ public abstract class ConfigScreen extends NavigatableSimiScreen { String s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(key)).map(StringUtils::capitalize).collect(Collectors.joining(" ")); return s; } + + protected void renderCog(MatrixStack ms, float partialTicks) { + ms.push(); + + ms.translate(-100, 100, -100); + ms.scale(200, 200, .1f); + GuiGameElement.of(cogwheelState) + .rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5) + .render(ms); + + ms.pop(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java index 237ba65f2..304ae9cce 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java @@ -7,6 +7,7 @@ import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.config.ui.entries.NumberEntry; import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.UIRenderHelper; @@ -22,7 +23,7 @@ import net.minecraftforge.fml.client.gui.GuiUtils; public class ConfigScreenList extends ExtendedList { - public TextFieldWidget currentText; + public static TextFieldWidget currentText; public boolean isForServer = false; @@ -31,12 +32,16 @@ public class ConfigScreenList extends ExtendedList { func_244605_b(false); func_244606_c(false); setRenderSelection(false); + currentText = null; } @Override public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { //render tmp background - fill(ms, left, top, left + width, top + height, 0x10_000000); + //fill(ms, left, top, left + width, top + height, 0x10_000000); + + UIRenderHelper.angledGradient(ms, 90, left + width / 2, top, width, 5, 0x60_000000, 0x0); + UIRenderHelper.angledGradient(ms, -90, left + width / 2, bottom, width, 5, 0x60_000000, 0x0); super.render(ms, mouseX, mouseY, partialTicks); } @@ -50,6 +55,13 @@ public class ConfigScreenList extends ExtendedList { RenderSystem.disableScissor(); } + @Override + public boolean mouseClicked(double x, double y, int button) { + children().stream().filter(e -> e instanceof NumberEntry).forEach(e -> e.mouseClicked(x, y, button)); + + return super.mouseClicked(x, y, button); + } + @Override public int getRowWidth() { return width - 18; diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java index 27655f40b..a0dc991ab 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java @@ -30,4 +30,21 @@ public class ConfigTextField extends TextFieldWidget { font.draw(ms, unit, x + getAdjustedWidth() - unitWidth, this.y + (this.height - 8) / 2, 0xcc_aaaaaa); } + + @Override + public void setFocused2(boolean focus) { + super.setFocused2(focus); + + if (!focus) { + if (ConfigScreenList.currentText == this) + ConfigScreenList.currentText = null; + + return; + } + + if (ConfigScreenList.currentText != null && ConfigScreenList.currentText != this) + ConfigScreenList.currentText.setFocused2(false); + + ConfigScreenList.currentText = this; + } } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ServerSubMenuConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/ServerSubMenuConfigScreen.java deleted file mode 100644 index 023cd9ddb..000000000 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ServerSubMenuConfigScreen.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.simibubi.create.foundation.config.ui; - -import com.electronwill.nightconfig.core.UnmodifiableConfig; -import com.simibubi.create.foundation.gui.AllIcons; -import com.simibubi.create.foundation.gui.DelegatedStencilElement; -import com.simibubi.create.foundation.gui.UIRenderHelper; -import com.simibubi.create.foundation.item.TooltipHelper; -import com.simibubi.create.foundation.ponder.ui.PonderButton; - -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.util.text.StringTextComponent; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.common.ForgeConfigSpec; - -public class ServerSubMenuConfigScreen extends SubMenuConfigScreen { - - protected PonderButton missingPermissions = null; - - public ServerSubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec) { - super(parent, configSpec); - } - - public ServerSubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) { - super(parent, configSpec, configGroup); - } - - @Override - protected void init() { - super.init(); - - list.isForServer = true; - - if (client != null && client.player != null && client.player.hasPermissionLevel(2)) - return; - - list.children().forEach(e -> e.setEditable(false)); - - int col1 = 0xff_f78888; - int col2 = 0xff_cc2020; - - missingPermissions = new PonderButton(width - 30, height - 50, () -> {}) - .showing(new DelegatedStencilElement() - .withStencilRenderer((ms, w, h) -> AllIcons.I_MTD_CLOSE.draw(ms, 0, 0)) - .withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, col1, col2)) - ).customColors(col1, col2); - missingPermissions.fade(1); - missingPermissions.getToolTip().add(new StringTextComponent("Locked").formatted(TextFormatting.BOLD)); - missingPermissions.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You don't have enough permissions to edit the server config. You can still look at the current values here though.", TextFormatting.GRAY, TextFormatting.GRAY)); - - widgets.add(missingPermissions); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java index 58de335ac..408343255 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java @@ -1,8 +1,9 @@ package com.simibubi.create.foundation.config.ui; import javax.annotation.Nonnull; +import javax.annotation.Nullable; -import org.apache.commons.lang3.mutable.MutableInt; +import org.lwjgl.glfw.GLFW; import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; @@ -11,30 +12,93 @@ import com.simibubi.create.foundation.config.ui.entries.BooleanEntry; import com.simibubi.create.foundation.config.ui.entries.EnumEntry; import com.simibubi.create.foundation.config.ui.entries.NumberEntry; import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry; +import com.simibubi.create.foundation.config.ui.entries.ValueEntry; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.ConfirmationScreen; +import com.simibubi.create.foundation.gui.DelegatedStencilElement; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.item.TooltipHelper; +import com.simibubi.create.foundation.ponder.ui.PonderButton; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.text.ITextProperties; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.config.ModConfig; public class SubMenuConfigScreen extends ConfigScreen { - ForgeConfigSpec spec; - UnmodifiableConfig configGroup; - ConfigScreenList list; + public final ModConfig.Type type; + protected ForgeConfigSpec spec; + protected UnmodifiableConfig configGroup; + protected ConfigScreenList list; + + protected PonderButton resetAll; + protected PonderButton saveChanges; + protected PonderButton discardChanges; + protected PonderButton goBack; + protected PonderButton serverLocked; + protected int listWidth; + protected String title; - public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) { + public SubMenuConfigScreen(Screen parent, String title, ModConfig.Type type, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) { super(parent); + this.type = type; this.spec = configSpec; + this.title = title; this.configGroup = configGroup; } - public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec) { + public SubMenuConfigScreen(Screen parent, ModConfig.Type type, ForgeConfigSpec configSpec) { super(parent); + this.type = type; this.spec = configSpec; + this.title = "root"; this.configGroup = configSpec.getValues(); } + protected void clearChanges() { + changes.clear(); + list.children() + .stream() + .filter(e -> e instanceof ValueEntry) + .forEach(e -> ((ValueEntry) e).onValueChange()); + } + + protected void saveChanges() { + UnmodifiableConfig values = spec.getValues(); + changes.forEach((path, value) -> { + ForgeConfigSpec.ConfigValue configValue = values.get(path); + configValue.set(value); + }); + clearChanges(); + } + + protected void resetConfig(UnmodifiableConfig values) { + values.valueMap().forEach((key, obj) -> { + if (obj instanceof AbstractConfig) { + resetConfig((UnmodifiableConfig) obj); + } else if (obj instanceof ForgeConfigSpec.ConfigValue) { + ForgeConfigSpec.ConfigValue configValue = (ForgeConfigSpec.ConfigValue) obj; + ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath()); + + if (!configValue.get().equals(valueSpec.getDefault())) + changes.put(String.join(".", configValue.getPath()), valueSpec.getDefault()); + } + }); + + list.children() + .stream() + .filter(e -> e instanceof ValueEntry) + .forEach(e -> ((ValueEntry) e).onValueChange()); + } + @Override public void tick() { super.tick(); @@ -46,23 +110,88 @@ public class SubMenuConfigScreen extends ConfigScreen { widgets.clear(); super.init(); - int lWidth = Math.min(width - 66, 500); - list = new ConfigScreenList(client, lWidth, height - 30, 15, height - 15, 50); + //leave 40px on either side and dont be wider than 500px + listWidth = Math.min(width - 80, 500); + + int yCenter = height / 2; + int listL = this.width / 2 - listWidth / 2; + int listR = this.width / 2 + listWidth / 2; + + resetAll = new PonderButton(listR + 10, yCenter - 25, (x, y) -> { + new ConfirmationScreen() + .at(x, y) + .withText(ITextProperties.plain("You are about to reset all settings for the " + type.toString() + " config. Are you sure?")) + .withAction(success -> { + if (success) + resetConfig(spec.getValues()); + }) + .open(this); + }) + .showing(AllIcons.I_CONFIG_RESET.asStencil()); + resetAll.fade(1); + resetAll.getToolTip().add(new StringTextComponent("Reset All")); + resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all configs to their default value.", TextFormatting.GRAY, TextFormatting.GRAY)); + + saveChanges = new PonderButton(listL - 30, yCenter - 25, (x, y) -> { + if (changes.isEmpty()) + return; + + new ConfirmationScreen() + .at(x, y) + .withText(ITextProperties.plain("You are about to change " + changes.size() + " values. Are you sure?")) + .withAction(success -> { + if (success) + saveChanges(); + }) + .open(this); + }) + .showing(AllIcons.I_CONFIG_SAVE.asStencil()); + saveChanges.fade(1); + saveChanges.getToolTip().add(new StringTextComponent("Save Changes")); + saveChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to save your current changes.", TextFormatting.GRAY, TextFormatting.GRAY)); + + discardChanges = new PonderButton(listL - 30, yCenter + 5, (x, y) -> { + if (changes.isEmpty()) + return; + + new ConfirmationScreen() + .at(x, y) + .withText(ITextProperties.plain("You are about to discard " + changes.size() + " unsaved changes. Are you sure?")) + .withAction(success -> { + if (success) + clearChanges(); + }) + .open(this); + }) + .showing(AllIcons.I_CONFIG_DISCARD.asStencil()); + discardChanges.fade(1); + discardChanges.getToolTip().add(new StringTextComponent("Discard Changes")); + discardChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to discard all the changes you made.", TextFormatting.GRAY, TextFormatting.GRAY)); + + goBack = new PonderButton(listL - 30, yCenter + 65, this::attemptBackstep) + .showing(AllIcons.I_CONFIG_BACK); + goBack.fade(1); + goBack.getToolTip().add(new StringTextComponent("Go Back")); + + widgets.add(resetAll); + widgets.add(saveChanges); + widgets.add(discardChanges); + widgets.add(goBack); + + list = new ConfigScreenList(client, listWidth, height - 60, 45, height - 15, 50); list.setLeftPos(this.width / 2 - list.getWidth() / 2); children.add(list); - MutableInt y = new MutableInt(15); + configGroup.valueMap().forEach((key, obj) -> { + String humanKey = toHumanReadable(key); - configGroup.valueMap().forEach((s, o) -> { - String humanKey = toHumanReadable(s); - - if (o instanceof AbstractConfig) { - SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) o); + if (obj instanceof AbstractConfig) { + SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) obj); list.children().add(entry); - } else if (o instanceof ForgeConfigSpec.ConfigValue) { - ForgeConfigSpec.ConfigValue configValue = (ForgeConfigSpec.ConfigValue) o; + } else if (obj instanceof ForgeConfigSpec.ConfigValue) { + ForgeConfigSpec.ConfigValue configValue = (ForgeConfigSpec.ConfigValue) obj; ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath()); Object value = configValue.get(); @@ -77,21 +206,58 @@ public class SubMenuConfigScreen extends ConfigScreen { if (entry != null) { list.children().add(entry); } else { - list.children().add(new ConfigScreenList.LabeledEntry("n-" + o.getClass().getSimpleName() + " " + humanKey + " : " + value)); + list.children().add(new ConfigScreenList.LabeledEntry("n-" + obj.getClass().getSimpleName() + " " + humanKey + " : " + value)); } } else { list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value)); } } - - y.add(50); }); + + //extras for sever configs + if (type != ModConfig.Type.SERVER) + return; + + list.isForServer = true; + boolean canEdit = client != null && client.player != null && client.player.hasPermissionLevel(2); + + int colRed1 = 0xff_f78888; + int colRed2 = 0xff_cc2020; + int colGreen1 = 0xff_88f788; + int colGreen2 = 0xff_20cc20; + + DelegatedStencilElement stencil = new DelegatedStencilElement(); + + serverLocked = new PonderButton(listR + 10, yCenter + 5, () -> {}) + .showing(stencil); + serverLocked.fade(1); + + if (!canEdit) { + list.children().forEach(e -> e.setEditable(false)); + resetAll.active = false; + stencil.withStencilRenderer((ms, w, h) -> AllIcons.I_CONFIG_LOCKED.draw(ms, 0, 0)); + stencil.withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, colRed1, colRed2)); + serverLocked.customColors(colRed1, colRed2); + serverLocked.getToolTip().add(new StringTextComponent("Locked").formatted(TextFormatting.BOLD)); + serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You don't have enough permissions to edit the server config. You can still look at the current values here though.", TextFormatting.GRAY, TextFormatting.GRAY)); + } else { + stencil.withStencilRenderer((ms, w, h) -> AllIcons.I_CONFIG_UNLOCKED.draw(ms, 0, 0)); + stencil.withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, colGreen1, colGreen2)); + serverLocked.customColors(colGreen1, colGreen2); + serverLocked.getToolTip().add(new StringTextComponent("Unlocked").formatted(TextFormatting.BOLD)); + serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You have enough permissions to edit the server config. Changes you make here will be synced with the server once you saved them.", TextFormatting.GRAY, TextFormatting.GRAY)); + } + + widgets.add(serverLocked); } @Override protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { super.renderWindow(ms, mouseX, mouseY, partialTicks); + int x = width/2; + drawCenteredString(ms, client.fontRenderer, "Editing config: " + type.toString() + "@" + title, x, 15, 0xff_eaeaea); + list.render(ms, mouseX, mouseY, partialTicks); } @@ -106,4 +272,65 @@ public class SubMenuConfigScreen extends ConfigScreen { init(client, width, height); list.setScrollAmount(scroll); } + + @Nullable + @Override + public IGuiEventListener getFocused() { + if (ConfigScreenList.currentText != null) + return ConfigScreenList.currentText; + + return super.getFocused(); + } + + @Override + public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) { + if (super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_)) + return true; + + if (code == GLFW.GLFW_KEY_BACKSPACE) { + attemptBackstep(); + } + + return false; + } + + private void attemptBackstep() { + if (!changes.isEmpty() && parent instanceof BaseConfigScreen) { + new ConfirmationScreen() + .centered() + .addText(ITextProperties.plain("You still have " + changes.size() + " unsaved changes for this config.")) + .addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?")) + .withAction(success -> { + if (!success) + return; + + changes.clear(); + ScreenOpener.open(parent); + }) + .open(this); + } else { + ScreenOpener.open(parent); + } + } + + @Override + public void onClose() { + if (changes.isEmpty()) { + super.onClose(); + return; + } + + new ConfirmationScreen() + .centered() + .addText(ITextProperties.plain("You still have " + changes.size() + " unsaved changes for this config.")) + .addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?")) + .withAction(success -> { + if (!success) + return; + + changes.clear(); + super.onClose(); + }) + .open(this); + } } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java index 6aa6693d6..2c9e37338 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java @@ -25,10 +25,8 @@ public class BooleanEntry extends ValueEntry { .centered(true, true) .withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_f78888, 0xff_cc2020)); - button = new PonderButton(0, 0, () -> { - value.set(!value.get()); - onValueChange(); - }).showingUnscaled(enabled); + button = new PonderButton(0, 0, () -> setValue(!getValue())) + .showingUnscaled(enabled); button.fade(1); listeners.add(button); @@ -58,14 +56,9 @@ public class BooleanEntry extends ValueEntry { } @Override - protected void onValueChange() { - super.onValueChange(); - button.showingUnscaled(value.get() ? enabled : disabled); - bumpCog(value.get() ? 15f : -16f); + public void onValueChange(Boolean newValue) { + super.onValueChange(newValue); + button.showingUnscaled(newValue ? enabled : disabled); + bumpCog(newValue ? 15f : -16f); } - - /*@Override - public boolean mouseClicked(double mX, double mY, int button) { - return this.button.mouseClicked(mX, mY, button) || super.mouseClicked(mX, mY, button); - }*/ } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java index 0c9eddec7..e4df547e3 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java @@ -35,12 +35,11 @@ public class EnumEntry extends ValueEntry> { } protected void cycleValue(int direction) { - Enum e = value.get(); + Enum e = getValue(); Enum[] options = e.getDeclaringClass().getEnumConstants(); e = options[Math.floorMod(e.ordinal() + direction, options.length)]; - value.set(e); + setValue(e); bumpCog(direction * 15f); - onValueChange(); } @Override @@ -79,8 +78,8 @@ public class EnumEntry extends ValueEntry> { } @Override - protected void onValueChange() { - super.onValueChange(); - valueText.withText(value.get().name()); + public void onValueChange(Enum newValue) { + super.onValueChange(newValue); + valueText.withText(newValue.name()); } } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java index 1d8c95537..f4a1b6115 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java @@ -39,7 +39,7 @@ public abstract class NumberEntry extends ValueEntry { public NumberEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { super(label, value, spec); textField = new ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, unit); - textField.setText(String.valueOf(value.get())); + textField.setText(String.valueOf(getValue())); Object range = spec.getRange(); try { @@ -74,8 +74,7 @@ public abstract class NumberEntry extends ValueEntry { throw new IllegalArgumentException(); textField.setTextColor(0xff_20cc20); - value.set(number); - onValueChange(); + setValue(number); } catch (IllegalArgumentException ignored) { textField.setTextColor(0xff_cc2020); @@ -105,9 +104,13 @@ public abstract class NumberEntry extends ValueEntry { } @Override - protected void onReset() { - super.onReset(); - textField.setText(String.valueOf(value.get())); + public void onValueChange(T newValue) { + super.onValueChange(newValue); + String newText = String.valueOf(newValue); + if (textField.getText().equals(newText)) + return; + + textField.setText(newText); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java index 68f315f3a..131ce5c48 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java @@ -4,7 +4,6 @@ import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.config.ui.ConfigButton; import com.simibubi.create.foundation.config.ui.ConfigScreenList; -import com.simibubi.create.foundation.config.ui.ServerSubMenuConfigScreen; import com.simibubi.create.foundation.config.ui.SubMenuConfigScreen; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.TextStencilElement; @@ -12,21 +11,18 @@ import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.ponder.ui.PonderButton; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screen.Screen; import net.minecraftforge.common.ForgeConfigSpec; public class SubMenuEntry extends ConfigScreenList.LabeledEntry { protected PonderButton button; - public SubMenuEntry(Screen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) { + public SubMenuEntry(SubMenuConfigScreen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) { super(label); TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true); text.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2)); - button = new PonderButton(0, 0, () -> ScreenOpener.transitionTo(isForServer() ? - new ServerSubMenuConfigScreen(parent, spec, config) : - new SubMenuConfigScreen(parent, spec, config)) - ).showingUnscaled(text); + button = new PonderButton(0, 0, () -> ScreenOpener.open(new SubMenuConfigScreen(parent, label, parent.type, spec, config))) + .showingUnscaled(text); button.fade(1); listeners.add(button); diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java index 998b7f98c..ff015c702 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java @@ -6,44 +6,49 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import javax.annotation.Nonnull; + import org.apache.commons.lang3.ArrayUtils; import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket; import com.simibubi.create.foundation.config.ui.ConfigButton; +import com.simibubi.create.foundation.config.ui.ConfigScreen; import com.simibubi.create.foundation.config.ui.ConfigScreenList; -import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.DelegatedStencilElement; import com.simibubi.create.foundation.gui.UIRenderHelper; -import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.ponder.ui.PonderButton; -import net.minecraft.client.Minecraft; +import net.minecraft.util.text.IFormattableTextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.common.ForgeConfigSpec; public class ValueEntry extends ConfigScreenList.LabeledEntry { + protected static final IFormattableTextComponent modComponent = new StringTextComponent("* ").formatted(TextFormatting.BOLD, TextFormatting.DARK_BLUE).append(StringTextComponent.EMPTY.copy().formatted(TextFormatting.RESET)); protected static final int resetWidth = 28;//including 6px offset on either side public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]"); + //public static DelegatedStencilElement.ElementRenderer idle = (ms, w, h) -> UIRenderHelper.angledGradient(ms, 0, 0, h / 2, h, w, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2); protected ForgeConfigSpec.ConfigValue value; protected ForgeConfigSpec.ValueSpec spec; protected PonderButton resetButton; protected boolean editable = true; protected String unit = null; + protected String path; public ValueEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { super(label); this.value = value; this.spec = spec; + this.path = String.join(".", value.getPath()); - TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "R").centered(true, true); - text.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2)); resetButton = new PonderButton(0, 0, (_$, _$$) -> { - value.set((T) spec.getDefault()); + setValue((T) spec.getDefault()); this.onReset(); - }, resetWidth - 12, 16).showingUnscaled(text); + }, resetWidth - 12, 16) + .showing(AllIcons.I_CONFIG_RESET.asStencil()/*.withElementRenderer(idle)*/); resetButton.fade(1); listeners.add(resetButton); @@ -82,12 +87,20 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { @Override protected void setEditable(boolean b) { editable = b; - resetButton.active = editable && !value.get().equals(spec.getDefault()); + resetButton.active = editable && !isCurrentValueDefault(); } @Override public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean p_230432_9_, float partialTicks) { - super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks); + if (isCurrentValueChanged()) { + IFormattableTextComponent original = label.getComponent(); + IFormattableTextComponent changed = modComponent.copy().append(original); + label.withText(changed); + super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks); + label.withText(original); + } else { + super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks); + } resetButton.x = x + width - resetWidth + 6; resetButton.y = y + 15; @@ -99,18 +112,40 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { return (int) (totalWidth * labelWidthMult); } - protected void onReset() { - onValueChange(); + public void setValue(@Nonnull T value) { + if (value.equals(this.value.get())) { + ConfigScreen.changes.remove(path); + onValueChange(value); + return; + } + + ConfigScreen.changes.put(path, value); + onValueChange(value); } - protected void onValueChange() { - resetButton.active = editable && !value.get().equals(spec.getDefault()); + @Nonnull + public T getValue() { + //noinspection unchecked + return (T) ConfigScreen.changes.getOrDefault(path, this.value.get()); + } - if (!isForServer()) - return; + protected boolean isCurrentValueChanged() { + return ConfigScreen.changes.containsKey(path); + } - String path = String.join(".", value.getPath()); - AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value.get())); + protected boolean isCurrentValueDefault() { + return spec.getDefault().equals(getValue()); + } + + public void onReset() { + onValueChange(getValue()); + } + + public void onValueChange() { + onValueChange(getValue()); + } + public void onValueChange(T newValue) { + resetButton.active = editable && !isCurrentValueDefault(); } protected void bumpCog() {bumpCog(10f);} diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index fc489f449..f81cceb59 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -124,8 +124,15 @@ public class AllIcons implements IScreenRenderable { I_MTD_SCAN = next(), I_MTD_REPLAY = next(), I_MTD_USER_MODE = next(), - I_MTD_SLOW_MODE = next(); - + I_MTD_SLOW_MODE = next(), + + I_CONFIG_UNLOCKED = newRow(), + I_CONFIG_LOCKED = next(), + I_CONFIG_DISCARD = next(), + I_CONFIG_SAVE = next(), + I_CONFIG_RESET = next(), + I_CONFIG_BACK = next(); + public AllIcons(int x, int y) { iconX = x * 16; iconY = y * 16; @@ -179,6 +186,11 @@ public class AllIcons implements IScreenRenderable { vertex(peek, builder, j, k, rgb, vec4, u1, v2); } + @OnlyIn(Dist.CLIENT) + public DelegatedStencilElement asStencil() { + return new DelegatedStencilElement().withStencilRenderer((ms, w, h) -> this.draw(ms, 0, 0)).withBounds(16, 16); + } + @OnlyIn(Dist.CLIENT) private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u, float v) { builder.vertex(peek.getModel(), (float) vec.x, (float) vec.y, (float) vec.z) diff --git a/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java b/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java new file mode 100644 index 000000000..807dc91a0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java @@ -0,0 +1,186 @@ +package com.simibubi.create.foundation.gui; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import javax.annotation.Nonnull; + +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.ponder.ui.PonderButton; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.text.ITextProperties; +import net.minecraft.util.text.Style; + +public class ConfirmationScreen extends AbstractSimiScreen { + + private Screen source; + private Consumer action = _success -> {}; + private List text = new ArrayList<>(); + private boolean centered = false; + private int x; + private int y; + private int textWidth; + private int textHeight; + + private PonderButton confirm; + private PonderButton cancel; + + /* + * Removes text lines from the back of the list + * */ + public ConfirmationScreen removeTextLines(int amount) { + if (amount > text.size()) + return clearText(); + + text.subList(text.size() - amount, text.size()).clear(); + return this; + } + + public ConfirmationScreen clearText() { + this.text.clear(); + return this; + } + + public ConfirmationScreen addText(ITextProperties text) { + this.text.add(text); + return this; + } + + public ConfirmationScreen withText(ITextProperties text) { + return clearText().addText(text); + } + + public ConfirmationScreen at(int x, int y) { + this.x = Math.max(x, 0); + this.y = Math.max(y, 0); + this.centered = false; + return this; + } + + public ConfirmationScreen centered() { + this.centered = true; + return this; + } + + public ConfirmationScreen withAction(Consumer action) { + this.action = action; + return this; + } + + public void open(@Nonnull Screen source) { + this.source = source; + Minecraft client = source.getMinecraft(); + this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight()); + this.client.currentScreen = this; + } + + @Override + protected void init() { + widgets.clear(); + + ArrayList copy = new ArrayList<>(text); + text.clear(); + copy.forEach(t -> text.addAll(client.fontRenderer.getTextHandler().wrapLines(t, 300, Style.EMPTY))); + + textHeight = text.size() * (client.fontRenderer.FONT_HEIGHT + 1) + 4; + textWidth = 300; + + if (x + textWidth > width) { + x = width - textWidth; + } + + if (y + textHeight + 30 > height) { + y = height - textHeight - 30; + } + + if (centered) { + x = width/2 - textWidth/2 - 2; + y = height/2 - textHeight/2 - 16; + } + + TextStencilElement confirmText = new TextStencilElement(client.fontRenderer, "Confirm").centered(true, true); + confirm = new PonderButton(x + 4, y + textHeight + 2, (_$, _$$) -> accept(true), textWidth/2 - 10, 20) + .showingUnscaled(confirmText); + confirm.fade(1); + + TextStencilElement cancelText = new TextStencilElement(client.fontRenderer, "Cancel").centered(true, true); + cancel = new PonderButton(x + textWidth/2 + 6, y + textHeight + 2, (_$, _$$) -> accept(false), textWidth/2 - 10, 20) + .showingUnscaled(cancelText); + cancel.fade(1); + + widgets.add(confirm); + widgets.add(cancel); + + } + + @Override + public void onClose() { + accept(false); + } + + private void accept(boolean success) { + client.currentScreen = source; + action.accept(success); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + + PonderUI.renderBox(ms, x, y, textWidth, textHeight, false); + int offset = client.fontRenderer.FONT_HEIGHT + 1; + int lineY = y - offset; + + ms.push(); + ms.translate(0, 0, 200); + + for (ITextProperties line : text) { + lineY = lineY + offset; + + if (line == null) + continue; + + client.fontRenderer.draw(ms, line.getString(), x, lineY, 0xeaeaea); + } + + ms.pop(); + + } + + @Override + protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + + UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC); + UIRenderHelper.prepFramebufferSize(); + + ms.push(); + //ms.translate(0, 0, -50); + //ms.scale(1, 1, 0.01f); + UIRenderHelper.framebuffer.bindFramebuffer(true); + source.render(ms, mouseX, mouseY, partialTicks); + UIRenderHelper.framebuffer.unbindFramebuffer(); + Minecraft.getInstance().getFramebuffer().bindFramebuffer(true); + ms.pop(); + + //RenderSystem.disableAlphaTest(); + RenderSystem.disableBlend(); + UIRenderHelper.drawFramebuffer(1); + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + this.fillGradient(ms, 0, 0, this.width, this.height, 0x70101010, 0x80101010); + //RenderSystem.enableAlphaTest(); + } + + @Override + public void resize(@Nonnull Minecraft client, int width, int height) { + super.resize(client, width, height); + source.resize(client, width, height); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java index 9feb61f84..2d0397065 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java @@ -7,7 +7,6 @@ public class DelegatedStencilElement extends StencilElement { protected static final ElementRenderer EMPTY_RENDERER = (ms, width, height) -> {}; protected static final ElementRenderer DEFAULT_ELEMENT = (ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, -3, 5, height+4, width+6, 0xff_10dd10, 0xff_1010dd); - protected ElementRenderer stencil; protected ElementRenderer element; diff --git a/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java b/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java index 9687042ab..cfe1aa1d1 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ScreenOpener.java @@ -65,7 +65,7 @@ public class ScreenOpener { if (screenHistory.isEmpty()) return false; Screen previouslyRenderedScreen = screenHistory.get(0); - if (!(previouslyRenderedScreen instanceof AbstractSimiScreen)) + if (!(previouslyRenderedScreen instanceof NavigatableSimiScreen)) return false; if (!screen.isEquivalentTo((NavigatableSimiScreen) previouslyRenderedScreen)) return false; diff --git a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java index 28b5e77ac..e89d49797 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -4,6 +4,8 @@ import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3f; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.KHRDebug; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.utility.ColorHelper; @@ -22,8 +24,6 @@ public class UIRenderHelper { public static void enableStencil() { RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); - if (framebuffer != null) - RenderSystem.recordRenderCall(() -> framebuffer.enableStencil()); } public static Framebuffer framebuffer; @@ -33,11 +33,13 @@ public class UIRenderHelper { MainWindow mainWindow = Minecraft.getInstance().getWindow(); framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, Minecraft.IS_RUNNING_ON_MAC); framebuffer.setFramebufferColor(0, 0, 0, 0); + KHRDebug.glObjectLabel(GL30.GL_FRAMEBUFFER, framebuffer.framebufferObject, "UIBuffer"); + framebuffer.enableStencil(); // framebuffer.deleteFramebuffer(); }); } - public static void prepFramebufferSize() { + public static void prepFramebufferSize() {//TODO move this to a mixin MainWindow window = Minecraft.getInstance().getWindow(); if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) { framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC); @@ -54,10 +56,6 @@ public class UIRenderHelper { float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight; RenderSystem.enableTexture(); - RenderSystem.enableBlend(); - RenderSystem.disableLighting(); - RenderSystem.disableAlphaTest(); - RenderSystem.defaultBlendFunc(); RenderSystem.enableDepthTest(); framebuffer.bindFramebufferTexture(); @@ -73,8 +71,6 @@ public class UIRenderHelper { tessellator.draw(); framebuffer.unbindFramebufferTexture(); - RenderSystem.disableBlend(); - RenderSystem.enableAlphaTest(); } //angle in degrees; 0° -> fading to the right diff --git a/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java index 124a4967e..73f354c44 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.ponder; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.IScreenRenderable; import com.simibubi.create.foundation.gui.ScreenOpener; @@ -106,7 +107,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { @Override protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { - if (transition.getChaseTarget() == 0) { + if (transition.getChaseTarget() == 0 || transition.settled()) { renderBackground(ms); return; } @@ -125,7 +126,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { ms.push();// 2 ms.translate(0, 0, -1000); UIRenderHelper.framebuffer.bindFramebuffer(true); - lastScreen.render(ms, mouseX, mouseY, 10); + lastScreen.render(ms, mouseX, mouseY, partialTicks); ms.pop();// 2 // use the buffer texture @@ -147,7 +148,12 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { ms.translate(dpx, dpy, 0); ms.scale((float) scale, (float) scale, 1); ms.translate(-dpx, -dpy, 0); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + RenderSystem.disableAlphaTest(); UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue)); + RenderSystem.disableBlend(); + RenderSystem.enableAlphaTest(); ms.pop();// 1 } diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 1dff79b36..74fe5caee 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ