From d4994ddc8b275c339169dcf4f844165a1d3621ba Mon Sep 17 00:00:00 2001 From: zelophed Date: Tue, 6 Apr 2021 00:05:29 +0200 Subject: [PATCH 01/17] entry point --- .../com/simibubi/create/CreateClient.java | 4 + .../simibubi/create/events/ClientEvents.java | 10 +++ .../foundation/command/AllCommands.java | 1 + .../foundation/command/ConfigCommand.java | 27 ++++++ .../command/ConfigureConfigPacket.java | 7 ++ .../create/foundation/config/ConfigBase.java | 3 +- .../foundation/config/ui/ConfigScreen.java | 90 +++++++++++++++++++ .../foundation/utility/animation/Force.java | 18 ++++ 8 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 9a7038edb..d8c61294d 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -6,6 +6,7 @@ import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivit import com.simibubi.create.content.schematics.ClientSchematicLoader; import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler; import com.simibubi.create.content.schematics.client.SchematicHandler; +import com.simibubi.create.events.ClientEvents; import com.simibubi.create.foundation.ResourceReloadHandler; import com.simibubi.create.foundation.block.render.CustomBlockModels; import com.simibubi.create.foundation.block.render.SpriteShifter; @@ -78,6 +79,7 @@ public class CreateClient { modEventBus.addListener(CreateClient::onModelRegistry); modEventBus.addListener(CreateClient::onTextureStitch); modEventBus.addListener(AllParticleTypes::registerFactories); + modEventBus.addListener(ClientEvents::loadCompleted); Backend.init(); OptifineHandler.init(); @@ -113,6 +115,8 @@ public class CreateClient { .getResourceManager(); if (resourceManager instanceof IReloadableResourceManager) ((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler()); + + } public static void onTextureStitch(TextureStitchEvent.Pre event) { diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 61200ad51..3633ad869 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -29,6 +29,7 @@ import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperR import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler; import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.config.ui.ConfigScreen; import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; @@ -76,7 +77,11 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ExtensionPoint; +import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; @EventBusSubscriber(value = Dist.CLIENT) public class ClientEvents { @@ -305,4 +310,9 @@ public class ClientEvents { } } + public static void loadCompleted(FMLLoadCompleteEvent event) { + ModContainer createContainer = ModList.get().getModContainerById("create").orElseThrow(() -> new IllegalStateException("Create Mod Container missing after loadCompleted")); + createContainer.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (mc, previousScreen) -> new ConfigScreen(previousScreen)); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java index 7e1e91774..b6082f993 100644 --- a/src/main/java/com/simibubi/create/foundation/command/AllCommands.java +++ b/src/main/java/com/simibubi/create/foundation/command/AllCommands.java @@ -29,6 +29,7 @@ public class AllCommands { .then(FixLightingCommand.register()) .then(HighlightCommand.register()) .then(CouplingCommand.register()) + .then(ConfigCommand.register()) .then(CloneCommand.register()) .then(PonderCommand.register()) diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java b/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java new file mode 100644 index 000000000..94b82a269 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java @@ -0,0 +1,27 @@ +package com.simibubi.create.foundation.command; + +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraftforge.fml.network.PacketDistributor; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.builder.ArgumentBuilder; +import com.simibubi.create.foundation.networking.AllPackets; + +public class ConfigCommand { + + public static ArgumentBuilder register() { + return Commands.literal("config") + .executes(ctx -> { + ServerPlayerEntity player = ctx.getSource().asPlayer(); + AllPackets.channel.send( + PacketDistributor.PLAYER.with(() -> player), + new ConfigureConfigPacket(ConfigureConfigPacket.Actions.configScreen.name(), "") + ); + + return Command.SINGLE_SUCCESS; + }); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java index 70fd35984..2482b4155 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.command; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen; import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.config.ui.ConfigScreen; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.ponder.PonderRegistry; @@ -68,6 +69,7 @@ public class ConfigureConfigPacket extends SimplePacketBase { } enum Actions { + configScreen(() -> Actions::configScreen), rainbowDebug(() -> Actions::rainbowDebug), overlayScreen(() -> Actions::overlayScreen), fixLighting(() -> Actions::experimentalLighting), @@ -89,6 +91,11 @@ public class ConfigureConfigPacket extends SimplePacketBase { .accept(value); } + @OnlyIn(Dist.CLIENT) + private static void configScreen(String value) { + ScreenOpener.open(new ConfigScreen(null)); + } + @OnlyIn(Dist.CLIENT) private static void rainbowDebug(String value) { ClientPlayerEntity player = Minecraft.getInstance().player; diff --git a/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java b/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java index e9a84e696..2b5a0c1e2 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java +++ b/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java @@ -107,8 +107,7 @@ public abstract class ConfigBase { if (comment.length > 0) { String[] comments = new String[comment.length + 1]; comments[0] = ""; - for (int i = 0; i < comment.length; i++) - comments[i + 1] = comment[i]; + System.arraycopy(comment, 0, comments, 1, comment.length); builder.comment(comments); } else builder.comment(""); 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 new file mode 100644 index 000000000..3848f917f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java @@ -0,0 +1,90 @@ +package com.simibubi.create.foundation.config.ui; + +import net.minecraft.block.BlockState; +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.Direction; + +import javax.annotation.Nonnull; +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.GuiGameElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; +import com.simibubi.create.foundation.utility.animation.Force; +import com.simibubi.create.foundation.utility.animation.PhysicalFloat; + +public class ConfigScreen extends NavigatableSimiScreen { + + private 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); + + public ConfigScreen(Screen parent) { + this.parent = parent; + } + + @Override + public void tick() { + cogSpin.tick(); + super.tick(); + } + + @Override + protected void init() { + super.init(); + + } + + @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){ + fill(ms, 0, 0, this.width, this.height, 0xb0_282c34); + } else { + fill(ms, 0, 0, this.width, this.height, 0xff_282c34); + } + + renderCog(ms, partialTicks); + + super.renderWindowBackground(ms, mouseX, mouseY, partialTicks); + + } + + protected void renderCog(MatrixStack ms, float partialTicks) { + ms.push(); + + ms.translate(.5 * width - 100, .5 * height + 110, -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); + int y = (int) (height * 0.5f); + this.drawHorizontalLine(ms, x-25, x+25, y, 0xff_807060); + this.drawVerticalLine(ms, x, y-25, y+25, 0xff_90a0b0); + + //UIRenderHelper.streak(ms, 0, mouseX, mouseY, 16, 50, 0xaa_1e1e1e); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double delta) { + cogSpin.bump(3, -delta * 5); + + return super.mouseScrolled(mouseX, mouseY, delta); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/animation/Force.java b/src/main/java/com/simibubi/create/foundation/utility/animation/Force.java index 23e7d0080..d15b3e627 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/animation/Force.java +++ b/src/main/java/com/simibubi/create/foundation/utility/animation/Force.java @@ -81,4 +81,22 @@ public interface Force { return timeRemaining <= 0; } } + + class Static implements Force { + float force; + + public Static(float force) { + this.force = force; + } + + @Override + public float get(float mass, float value, float speed) { + return force; + } + + @Override + public boolean finished() { + return false; + } + } } From 7ad05756184482a2e47a07a3a4f8843dbd915070 Mon Sep 17 00:00:00 2001 From: zelophed Date: Wed, 7 Apr 2021 02:17:55 +0200 Subject: [PATCH 02/17] fancy text --- .../com/simibubi/create/CreateClient.java | 1 + .../simibubi/create/events/ClientEvents.java | 4 +- .../command/ConfigureConfigPacket.java | 4 +- .../config/ui/BaseConfigScreen.java | 62 +++++++++++++ .../foundation/config/ui/ConfigButton.java | 56 ++++++++++++ .../foundation/config/ui/ConfigScreen.java | 8 +- .../gui/CombinedStencilElement.java | 58 +++++++++++++ .../create/foundation/gui/StencilElement.java | 55 ++++++++++++ .../foundation/gui/TextStencilElement.java | 87 +++++++++++++++++++ .../create/foundation/gui/UIRenderHelper.java | 33 +++++++ .../gui/widgets/AbstractSimiWidget.java | 4 +- .../foundation/gui/widgets/IconButton.java | 4 +- .../foundation/gui/widgets/StencilWidget.java | 33 +++++++ .../foundation/ponder/PonderProgressBar.java | 4 +- .../foundation/ponder/ui/PonderButton.java | 4 +- 15 files changed, 408 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java create mode 100644 src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java create mode 100644 src/main/java/com/simibubi/create/foundation/gui/StencilElement.java create mode 100644 src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java create mode 100644 src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index d8c61294d..80c6141e9 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -110,6 +110,7 @@ public class CreateClient { PonderIndex.registerTags(); UIRenderHelper.init(); + UIRenderHelper.enableStencil(); IResourceManager resourceManager = Minecraft.getInstance() .getResourceManager(); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index 3633ad869..d5861bde4 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -29,7 +29,7 @@ import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperR import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler; import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.config.ui.ConfigScreen; +import com.simibubi.create.foundation.config.ui.BaseConfigScreen; import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; @@ -312,7 +312,7 @@ public class ClientEvents { public static void loadCompleted(FMLLoadCompleteEvent event) { ModContainer createContainer = ModList.get().getModContainerById("create").orElseThrow(() -> new IllegalStateException("Create Mod Container missing after loadCompleted")); - createContainer.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (mc, previousScreen) -> new ConfigScreen(previousScreen)); + createContainer.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (mc, previousScreen) -> new BaseConfigScreen(previousScreen)); } } diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java index 2482b4155..b84fed0a1 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java @@ -3,7 +3,7 @@ package com.simibubi.create.foundation.command; import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen; import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.config.ui.ConfigScreen; +import com.simibubi.create.foundation.config.ui.BaseConfigScreen; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.ponder.PonderRegistry; @@ -93,7 +93,7 @@ public class ConfigureConfigPacket extends SimplePacketBase { @OnlyIn(Dist.CLIENT) private static void configScreen(String value) { - ScreenOpener.open(new ConfigScreen(null)); + ScreenOpener.open(new BaseConfigScreen(null)); } @OnlyIn(Dist.CLIENT) 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 new file mode 100644 index 000000000..849792f5d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/BaseConfigScreen.java @@ -0,0 +1,62 @@ +package com.simibubi.create.foundation.config.ui; + +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.CombinedStencilElement; +import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.gui.widgets.StencilWidget; + +public class BaseConfigScreen extends ConfigScreen { + + StencilWidget clientConfigWidget; + StencilWidget commonConfigWidget; + StencilWidget serverConfigWidget; + + public BaseConfigScreen(Screen parent) { + super(parent); + } + + @Override + protected void init() { + widgets.clear(); + super.init(); + + StencilElement text = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); + widgets.add(clientConfigWidget = ConfigButton.createFromTextElement( + width/2 - 100, + height/2 - 15 - 50, + 200, + 30, + text + )); + + StencilElement text2 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); + widgets.add(commonConfigWidget = ConfigButton.createFromTextElement( + width/2 - 100, + height/2 - 15, + 200, + 30, + text2 + )); + + StencilElement text3 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); + widgets.add(serverConfigWidget = ConfigButton.createFromTextElement( + width/2 - 100, + height/2 - 15 + 50, + 200, + 30, + text3 + )); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + super.renderWindow(ms, mouseX, mouseY, partialTicks); + + } +} diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java new file mode 100644 index 000000000..de4aabeb0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java @@ -0,0 +1,56 @@ +package com.simibubi.create.foundation.config.ui; + +import net.minecraft.client.gui.AbstractGui; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.text.StringTextComponent; + +import javax.annotation.Nonnull; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.CombinedStencilElement; +import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.gui.widgets.StencilWidget; + +public class ConfigButton extends StencilWidget { + + protected int gradientColor1 = 0xff_c0c0ff, gradientColor2 = 0xff_7b7ba3; + + public static ConfigButton createFromTextElement(int x, int y, int width, int height, StencilElement text) { + ConfigButton button = new ConfigButton(x, y, width, height); + StencilElement box = new StencilElement() { + @Override + protected void renderStencil(MatrixStack ms) { + fill(ms, 0, 0 , width, 0 + 1, 0xff_000000); + fill(ms, 0, height, width +1, height + 1, 0xff_000000); + fill(ms, 0 , 0, 0 + 1, height, 0xff_000000); + fill(ms, width, 0, width + 1, height, 0xff_000000); + } + + @Override + protected void renderElement(MatrixStack ms) { + UIRenderHelper.angledGradient(ms, 0, 0, 15, 32, 201, button.gradientColor1, button.gradientColor2); + } + }; + button.stencilElement = CombinedStencilElement.of(box, text); + return button; + } + + protected ConfigButton(int x, int y, int width, int height) { + super(x, y, width, height); + } + + public ConfigButton(int x, int y, int width, int height, StencilElement stencilElement) { + super(x, y, width, height, stencilElement); + } + + @Override + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); + fill(ms, x, y, x + width, y + height, 0x30_ffffff); + RenderSystem.defaultBlendFunc(); + super.renderButton(ms, mouseX, mouseY, partialTicks); + } +} 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 3848f917f..a02bc1cca 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 @@ -11,6 +11,8 @@ 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.GuiGameElement; +import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; import com.simibubi.create.foundation.utility.animation.Force; @@ -22,6 +24,8 @@ public class ConfigScreen extends NavigatableSimiScreen { 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; } @@ -35,7 +39,7 @@ public class ConfigScreen extends NavigatableSimiScreen { @Override protected void init() { super.init(); - + testStencil = new TextStencilElement(client.fontRenderer, "POGGERS").at(width*0.5f, height*0.5f, 0); } @Override @@ -78,6 +82,8 @@ public class ConfigScreen extends NavigatableSimiScreen { this.drawHorizontalLine(ms, x-25, x+25, y, 0xff_807060); this.drawVerticalLine(ms, x, y-25, y+25, 0xff_90a0b0); + //this.testStencil.render(ms); + //UIRenderHelper.streak(ms, 0, mouseX, mouseY, 16, 50, 0xaa_1e1e1e); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java new file mode 100644 index 000000000..7a8077ea8 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java @@ -0,0 +1,58 @@ +package com.simibubi.create.foundation.gui; + +import javax.annotation.Nonnull; +import com.mojang.blaze3d.matrix.MatrixStack; + +public class CombinedStencilElement extends StencilElement { + + private StencilElement element1; + private StencilElement element2; + private ElementMode mode; + + private CombinedStencilElement() {} + + public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2) { + return of(element1, element2, ElementMode.FIRST); + } + + public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2, ElementMode mode) { + CombinedStencilElement e = new CombinedStencilElement(); + e.element1 = element1; + e.element2 = element2; + e.mode = mode; + return e; + } + + @Override + protected void renderStencil(MatrixStack ms) { + ms.push(); + element1.transform(ms); + element1.renderStencil(ms); + ms.pop(); + ms.push(); + element2.transform(ms); + element2.renderStencil(ms); + ms.pop(); + } + + @Override + protected void renderElement(MatrixStack ms) { + if (mode.rendersFirst()) + element1.renderElement(ms); + + if (mode.rendersSecond()) + element2.renderElement(ms); + } + + public enum ElementMode { + FIRST, SECOND, BOTH; + + boolean rendersFirst() { + return this == FIRST || this == BOTH; + } + + boolean rendersSecond() { + return this == SECOND || this == BOTH; + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java new file mode 100644 index 000000000..814ab2ff3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java @@ -0,0 +1,55 @@ +package com.simibubi.create.foundation.gui; + +import org.lwjgl.opengl.GL11; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; + +public abstract class StencilElement { + + float x, y , z; + + public StencilElement at(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + return this; + } + + public void render(MatrixStack ms) { + ms.push(); + transform(ms); + prepareStencil(ms); + renderStencil(ms); + prepareElement(ms); + renderElement(ms); + cleanUp(ms); + ms.pop(); + } + + protected abstract void renderStencil(MatrixStack ms); + + protected abstract void renderElement(MatrixStack ms); + + protected void transform(MatrixStack ms) { + ms.translate(x, y, z); + } + + protected void prepareStencil(MatrixStack ms) { + GL11.glEnable(GL11.GL_STENCIL_TEST); + RenderSystem.clearStencil(0); + RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE); + RenderSystem.stencilMask(0xFF); + RenderSystem.stencilFunc(GL11.GL_ALWAYS, 1, 0xFF); + } + + protected void prepareElement(MatrixStack ms) { + GL11.glEnable(GL11.GL_STENCIL_TEST); + RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP); + RenderSystem.stencilFunc(GL11.GL_EQUAL, 1, 0xFF); + } + + protected void cleanUp(MatrixStack ms) { + GL11.glDisable(GL11.GL_STENCIL_TEST); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java new file mode 100644 index 000000000..c1382507a --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java @@ -0,0 +1,87 @@ +package com.simibubi.create.foundation.gui; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.util.text.IFormattableTextComponent; +import net.minecraft.util.text.StringTextComponent; + +import com.mojang.blaze3d.matrix.MatrixStack; + +public class TextStencilElement extends StencilElement { + + protected static final ElementRenderer DEFAULT_RENDERER = ((ms, width, _height) -> UIRenderHelper.angledGradient(ms, 15, -3, 5, 14, width+6, 0xff_10dd10, 0x1010dd)); + + protected FontRenderer font; + protected IFormattableTextComponent component; + protected ElementRenderer elementRenderer = DEFAULT_RENDERER; + + public TextStencilElement(FontRenderer font) { + super(); + this.font = font; + } + + public TextStencilElement(FontRenderer font, String text) { + this(font); + component = new StringTextComponent(text); + } + + public TextStencilElement(FontRenderer font, IFormattableTextComponent component) { + this(font); + this.component = component; + } + + public TextStencilElement withElementRenderer(ElementRenderer renderer) { + elementRenderer = renderer; + return this; + } + + public TextStencilElement withText(String text) { + component = new StringTextComponent(text); + return this; + } + + public TextStencilElement withText(IFormattableTextComponent component) { + this.component = component; + return this; + } + + @Override + protected void renderStencil(MatrixStack ms) { + font.draw(ms, component, 0, 0, 0xff_000000); + } + + @Override + protected void renderElement(MatrixStack ms) { + elementRenderer.render(ms, font.getWidth(component), 10); + } + + @FunctionalInterface + public interface ElementRenderer { + void render(MatrixStack ms, int width, int height); + } + + public static class Centered extends TextStencilElement { + + int width; + + public Centered(FontRenderer font, String text, int width) { + super(font, text); + this.width = width; + } + + public Centered(FontRenderer font, IFormattableTextComponent component, int width) { + super(font, component); + this.width = width; + } + + @Override + protected void renderStencil(MatrixStack ms) { + int textWidth = font.getWidth(component); + font.draw(ms, component, width / 2f - textWidth / 2f, 0, 0xff_000000); + } + + @Override + protected void renderElement(MatrixStack ms) { + elementRenderer.render(ms, width, 10); + } + } +} 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 b8dfbb8a2..c409480bd 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -16,8 +16,14 @@ import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.shader.Framebuffer; import net.minecraftforge.fml.client.gui.GuiUtils; +import javax.annotation.Nonnull; + public class UIRenderHelper { + public static void enableStencil() { + RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); + } + public static Framebuffer framebuffer; public static void init() { @@ -102,6 +108,33 @@ public class UIRenderHelper { GuiUtils.drawGradientRect(model, 0, -width, (int) (split2 * height), width, height, c3, c4); } + /** + * @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int) + */ + public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int width, int length, int color1, int color2) { + angledGradient(ms, angle, x, y, 0, width, length, color1, color2); + } + /** + * x and y specify the middle point of the starting edge + * + * @param angle the angle of the gradient in degrees; 0° means from left to right + * @param color1 the color at the starting edge + * @param color2 the color at the ending edge + * @param width the total width of the gradient + * + */ + public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int width, int length, int color1, int color2) { + ms.push(); + ms.translate(x, y, z); + ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90)); + + Matrix4f model = ms.peek().getModel(); + int w = width / 2; + GuiUtils.drawGradientRect(model, 0, -w, 0, w, length, color1, color2); + + ms.pop(); + } + //draws a wide chevron-style breadcrumb arrow pointing left public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent, int startColor, int endColor) { matrixStack.push(); diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java index 2c84c9ccf..f6ba1668c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java @@ -9,6 +9,8 @@ import net.minecraft.client.gui.widget.Widget; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; +import javax.annotation.Nonnull; + public abstract class AbstractSimiWidget extends Widget { protected List toolTip; @@ -23,7 +25,7 @@ public abstract class AbstractSimiWidget extends Widget { } @Override - public void renderButton(MatrixStack matrixStack, int p_renderButton_1_, int p_renderButton_2_, float p_renderButton_3_) { + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/IconButton.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/IconButton.java index 83049c1de..dcd54ac69 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/IconButton.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/IconButton.java @@ -7,6 +7,8 @@ import com.simibubi.create.foundation.gui.AllIcons; import net.minecraft.util.text.ITextComponent; +import javax.annotation.Nonnull; + public class IconButton extends AbstractSimiWidget { private AllIcons icon; @@ -18,7 +20,7 @@ public class IconButton extends AbstractSimiWidget { } @Override - public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + public void renderButton(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { if (this.visible) { this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height; diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java new file mode 100644 index 000000000..b58638d1e --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java @@ -0,0 +1,33 @@ +package com.simibubi.create.foundation.gui.widgets; + +import javax.annotation.Nonnull; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.StencilElement; + +public class StencilWidget extends AbstractSimiWidget { + + protected StencilElement stencilElement; + + protected StencilWidget(int x, int y, int width, int height) { + super(x, y, width, height); + } + + public StencilWidget(int x, int y, int width, int height, StencilElement stencilElement) { + super(x, y, width, height); + this.stencilElement = stencilElement; + } + + @Override + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + ms.push(); + + ms.translate(x, y, 0); + stencilElement.render(ms); + + ms.pop(); + } + + public StencilElement getStencilElement() { + return stencilElement; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java index fc2921ef2..de60e663c 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java @@ -11,6 +11,8 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.audio.SoundHandler; import net.minecraft.client.gui.FontRenderer; import net.minecraftforge.fml.client.gui.GuiUtils; + +import javax.annotation.Nonnull; import org.antlr.v4.runtime.misc.IntegerList; public class PonderProgressBar extends AbstractSimiWidget { @@ -103,7 +105,7 @@ public class PonderProgressBar extends AbstractSimiWidget { } @Override - public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { hovered = clicked(mouseX, mouseY); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java index deb018c6e..a5e31246c 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java @@ -16,6 +16,8 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.item.ItemStack; +import javax.annotation.Nonnull; + public class PonderButton extends AbstractSimiWidget { private IScreenRenderable icon; @@ -87,7 +89,7 @@ public class PonderButton extends AbstractSimiWidget { } @Override - public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { if (!visible) return; if (fade < .1f) From b1773e9e6ba300731bdc21ed991a237d363e155c Mon Sep 17 00:00:00 2001 From: zelophed Date: Wed, 7 Apr 2021 15:18:37 +0200 Subject: [PATCH 03/17] shadow cog --- .../foundation/config/ui/ConfigScreen.java | 19 +++++++++++++++++-- .../create/foundation/gui/StencilElement.java | 10 +++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) 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 a02bc1cca..0a7d55628 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 @@ -44,7 +44,7 @@ public class ConfigScreen extends NavigatableSimiScreen { @Override public void renderBackground(@Nonnull MatrixStack ms) { - fill(ms, 0, 0, this.width, this.height, 0xe8_101010); + //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)); } @@ -57,7 +57,22 @@ public class ConfigScreen extends NavigatableSimiScreen { 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) { + renderCog(ms, partialTicks); + } + + @Override + protected void renderElement(MatrixStack ms) { + fill(ms, -200, -200, 200, 200, 0x40_000000); + } + }.at(width * 0.5f, height * 0.5f, 0).render(ms); super.renderWindowBackground(ms, mouseX, mouseY, partialTicks); @@ -66,7 +81,7 @@ public class ConfigScreen extends NavigatableSimiScreen { protected void renderCog(MatrixStack ms, float partialTicks) { ms.push(); - ms.translate(.5 * width - 100, .5 * height + 110, -200); + ms.translate(-100, 100, -200); ms.scale(200, 200, .1f); GuiGameElement.of(cogwheelState) .rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5) diff --git a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java index 814ab2ff3..161de3618 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java @@ -1,5 +1,7 @@ package com.simibubi.create.foundation.gui; +import net.minecraft.client.Minecraft; + import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; @@ -36,11 +38,13 @@ public abstract class StencilElement { } protected void prepareStencil(MatrixStack ms) { + GL11.glDisable(GL11.GL_STENCIL_TEST); + RenderSystem.stencilMask(~0); + RenderSystem.clear(GL11.GL_STENCIL_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC); GL11.glEnable(GL11.GL_STENCIL_TEST); - RenderSystem.clearStencil(0); - RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE); + RenderSystem.stencilOp(GL11.GL_REPLACE, GL11.GL_KEEP, GL11.GL_KEEP); RenderSystem.stencilMask(0xFF); - RenderSystem.stencilFunc(GL11.GL_ALWAYS, 1, 0xFF); + RenderSystem.stencilFunc(GL11.GL_NEVER, 1, 0xFF); } protected void prepareElement(MatrixStack ms) { From f9179b3b1dae46918465f69706c66fc0fd874b9c Mon Sep 17 00:00:00 2001 From: zelophed Date: Wed, 7 Apr 2021 18:47:19 +0200 Subject: [PATCH 04/17] animated colors --- .../config/ui/BaseConfigScreen.java | 19 +++- .../foundation/config/ui/ConfigButton.java | 89 +++++++++++++++++-- 2 files changed, 100 insertions(+), 8 deletions(-) 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 849792f5d..4063c63b2 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 @@ -13,9 +13,9 @@ import com.simibubi.create.foundation.gui.widgets.StencilWidget; public class BaseConfigScreen extends ConfigScreen { - StencilWidget clientConfigWidget; - StencilWidget commonConfigWidget; - StencilWidget serverConfigWidget; + ConfigButton clientConfigWidget; + ConfigButton commonConfigWidget; + ConfigButton serverConfigWidget; public BaseConfigScreen(Screen parent) { super(parent); @@ -43,6 +43,8 @@ public class BaseConfigScreen extends ConfigScreen { 30, text2 )); + commonConfigWidget.active = false; + commonConfigWidget.updateColorsFromState(); StencilElement text3 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); widgets.add(serverConfigWidget = ConfigButton.createFromTextElement( @@ -52,6 +54,17 @@ public class BaseConfigScreen extends ConfigScreen { 30, text3 )); + serverConfigWidget.active = false; + serverConfigWidget.updateColorsFromState(); + } + + @Override + public void tick() { + super.tick(); + + widgets.stream() + .filter(w -> w instanceof ConfigButton) + .forEach(w -> ((ConfigButton) w).tick()); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java index de4aabeb0..ffe8a18f4 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java @@ -1,9 +1,5 @@ package com.simibubi.create.foundation.config.ui; -import net.minecraft.client.gui.AbstractGui; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.util.text.StringTextComponent; - import javax.annotation.Nonnull; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; @@ -12,10 +8,17 @@ import com.simibubi.create.foundation.gui.CombinedStencilElement; import com.simibubi.create.foundation.gui.StencilElement; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.widgets.StencilWidget; +import com.simibubi.create.foundation.utility.ColorHelper; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; public class ConfigButton extends StencilWidget { - protected int gradientColor1 = 0xff_c0c0ff, gradientColor2 = 0xff_7b7ba3; + LerpedFloat colorAnimation = LerpedFloat.linear(); + protected int gradientColor1 = Palette.button_idle_1, gradientColor2 = Palette.button_idle_2; + private int colorTarget1, colorTarget2; + private int previousColor1, previousColor2; + + protected boolean wasHovered; public static ConfigButton createFromTextElement(int x, int y, int width, int height, StencilElement text) { ConfigButton button = new ConfigButton(x, y, width, height); @@ -45,12 +48,88 @@ public class ConfigButton extends StencilWidget { super(x, y, width, height, stencilElement); } + public void tick() { + colorAnimation.tickChaser(); + } + + @Override + public void onClick(double x, double y) { + gradientColor1 = Palette.button_click_1; + gradientColor2 = Palette.button_click_2; + startGradientAnimation(Palette.getColorForButtonState(true, active, hovered), Palette.getColorForButtonState(false, active, hovered), true, 0.15); + } + @Override public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + //update hover status + //hovered = isMouseOver(mouseX, mouseY); + if (hovered != wasHovered) { + startGradientAnimation( + Palette.getColorForButtonState(true, active, hovered), + Palette.getColorForButtonState(false, active, hovered), + hovered + ); + } + + //update color animations + if (!colorAnimation.settled()) { + float animationValue = 1 - Math.abs(colorAnimation.getValue(partialTicks)); + gradientColor1 = ColorHelper.mixAlphaColors(previousColor1, colorTarget1, animationValue); + gradientColor2 = ColorHelper.mixAlphaColors(previousColor2, colorTarget2, animationValue); + } + RenderSystem.enableBlend(); RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); fill(ms, x, y, x + width, y + height, 0x30_ffffff); RenderSystem.defaultBlendFunc(); super.renderButton(ms, mouseX, mouseY, partialTicks); + wasHovered = hovered; + } + + public void updateColorsFromState() { + gradientColor1 = Palette.getColorForButtonState(true, active, hovered); + gradientColor2 = Palette.getColorForButtonState(false, active, hovered); + } + + private void startGradientAnimation(int c1, int c2, boolean positive, double expSpeed) { + colorAnimation.startWithValue(positive ? 1 : -1); + colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP); + + previousColor1 = gradientColor1; + previousColor2 = gradientColor2; + + colorTarget1 = c1; + colorTarget2 = c2; + } + + private void startGradientAnimation(int c1, int c2, boolean positive) { + startGradientAnimation(c1, c2, positive, 0.3); + } + + public static class Palette { + public static int button_idle_1 = 0xff_c0c0ff; + public static int button_idle_2 = 0xff_7b7ba3; + + public static int button_hover_1 = 0xff_7b7ba3; + public static int button_hover_2 = 0xff_616192; + + public static int button_click_1 = 0xff_4b4bff; + public static int button_click_2 = 0xff_3b3bdd; + + public static int button_disable_1 = 0xff_909090; + public static int button_disable_2 = 0xff_606060; + + public static int getColorForButtonState(boolean first, boolean active, boolean hovered) { + if (!active) { + return first ? button_disable_1 : button_disable_2; + } + + if (!hovered) { + return first ? button_idle_1 : button_idle_2; + } + + return first ? button_hover_1 : button_hover_2; + } + } } From 3de3de89dbc71aee4edf974b5e4c5006b833bf5a Mon Sep 17 00:00:00 2001 From: zelophed Date: Sat, 10 Apr 2021 20:00:32 +0200 Subject: [PATCH 05/17] finally some content --- .../config/ui/BaseConfigScreen.java | 65 ++++++------- .../foundation/config/ui/ConfigButton.java | 23 ++++- .../foundation/config/ui/ConfigScreen.java | 25 ++++- .../config/ui/ConfigScreenList.java | 91 +++++++++++++++++ .../config/ui/SubMenuConfigScreen.java | 97 +++++++++++++++++++ .../config/ui/entries/SubMenuEntry.java | 46 +++++++++ .../foundation/gui/AbstractSimiScreen.java | 4 + .../gui/CombinedStencilElement.java | 8 +- .../gui/DelegatedStencilElement.java | 49 ++++++++++ .../create/foundation/gui/StencilElement.java | 44 ++++++++- .../foundation/gui/TextStencilElement.java | 41 ++++---- .../create/foundation/gui/UIRenderHelper.java | 8 +- .../gui/widgets/AbstractSimiWidget.java | 17 +++- .../foundation/gui/widgets/StencilWidget.java | 23 ++++- .../foundation/ponder/ui/PonderButton.java | 20 ++-- 15 files changed, 481 insertions(+), 80 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java create mode 100644 src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java 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 4063c63b2..b2e9a3edd 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 @@ -1,16 +1,15 @@ package com.simibubi.create.foundation.config.ui; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.TextStencilElement; + import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; -import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.foundation.gui.CombinedStencilElement; -import com.simibubi.create.foundation.gui.StencilElement; -import com.simibubi.create.foundation.gui.TextStencilElement; -import com.simibubi.create.foundation.gui.UIRenderHelper; -import com.simibubi.create.foundation.gui.widgets.StencilWidget; - public class BaseConfigScreen extends ConfigScreen { ConfigButton clientConfigWidget; @@ -26,50 +25,44 @@ public class BaseConfigScreen extends ConfigScreen { widgets.clear(); super.init(); - StencilElement text = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); - widgets.add(clientConfigWidget = ConfigButton.createFromTextElement( - width/2 - 100, - height/2 - 15 - 50, - 200, - 30, + StencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); + widgets.add(clientConfigWidget = ConfigButton.createFromStencilElement( + width / 2 - 100, + height / 2 - 15 - 50, text - )); + ) + .withBounds(200, 30) + .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.CLIENT.specification))) + ); - StencilElement text2 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); - widgets.add(commonConfigWidget = ConfigButton.createFromTextElement( - width/2 - 100, - height/2 - 15, - 200, - 30, + StencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(false, true).at(0, 11, 0); + widgets.add(commonConfigWidget = ConfigButton.createFromStencilElement( + width / 2 - 100, + height / 2 - 15, text2 - )); + ) + .withBounds(200, 30) + ); commonConfigWidget.active = false; commonConfigWidget.updateColorsFromState(); StencilElement text3 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); - widgets.add(serverConfigWidget = ConfigButton.createFromTextElement( - width/2 - 100, - height/2 - 15 + 50, - 200, - 30, + widgets.add(serverConfigWidget = ConfigButton.createFromStencilElement( + width / 2 - 100, + height / 2 - 15 + 50, text3 - )); + ) + .withBounds(200, 30) + ); serverConfigWidget.active = false; serverConfigWidget.updateColorsFromState(); } - @Override - public void tick() { - super.tick(); - - widgets.stream() - .filter(w -> w instanceof ConfigButton) - .forEach(w -> ((ConfigButton) w).tick()); - } - @Override protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { super.renderWindow(ms, mouseX, mouseY, partialTicks); + + testStencil.at(200, 200, 0).render(ms); } } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java index ffe8a18f4..4017283d7 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.config.ui; import javax.annotation.Nonnull; + import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; @@ -20,26 +21,30 @@ public class ConfigButton extends StencilWidget { protected boolean wasHovered; - public static ConfigButton createFromTextElement(int x, int y, int width, int height, StencilElement text) { - ConfigButton button = new ConfigButton(x, y, width, height); + public static ConfigButton createFromStencilElement(int x, int y, StencilElement text) { + ConfigButton button = new ConfigButton(x, y); StencilElement box = new StencilElement() { @Override protected void renderStencil(MatrixStack ms) { - fill(ms, 0, 0 , width, 0 + 1, 0xff_000000); - fill(ms, 0, height, width +1, height + 1, 0xff_000000); + fill(ms, 0, 0 , width , 0 + 1, 0xff_000000); + fill(ms, 0, height, width + 1, height + 1, 0xff_000000); fill(ms, 0 , 0, 0 + 1, height, 0xff_000000); fill(ms, width, 0, width + 1, height, 0xff_000000); } @Override protected void renderElement(MatrixStack ms) { - UIRenderHelper.angledGradient(ms, 0, 0, 15, 32, 201, button.gradientColor1, button.gradientColor2); + UIRenderHelper.angledGradient(ms, 0, 0, height/2, height+2, width+2, button.gradientColor1, button.gradientColor2); } }; button.stencilElement = CombinedStencilElement.of(box, text); return button; } + protected ConfigButton(int x, int y) { + super(x, y); + } + protected ConfigButton(int x, int y, int width, int height) { super(x, y, width, height); } @@ -48,12 +53,20 @@ public class ConfigButton extends StencilWidget { super(x, y, width, height, stencilElement); } + public ConfigButton withBounds(int width, int height) { + this.width = width; + this.height = height; + return this; + } + public void tick() { colorAnimation.tickChaser(); } @Override public void onClick(double x, double y) { + runCallback(x, y); + gradientColor1 = Palette.button_click_1; gradientColor2 = Palette.button_click_2; startGradientAnimation(Palette.getColorForButtonState(true, active, hovered), Palette.getColorForButtonState(false, active, hovered), true, 0.15); 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 0a7d55628..95a7ea2e8 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 @@ -4,8 +4,12 @@ import net.minecraft.block.BlockState; import net.minecraft.client.gui.AbstractGui; import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.Direction; +import net.minecraftforge.common.ForgeConfigSpec; +import java.util.Arrays; +import java.util.stream.Collectors; import javax.annotation.Nonnull; +import org.apache.commons.lang3.StringUtils; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; @@ -14,11 +18,12 @@ 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.gui.UIRenderHelper; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; import com.simibubi.create.foundation.utility.animation.Force; import com.simibubi.create.foundation.utility.animation.PhysicalFloat; -public class ConfigScreen extends NavigatableSimiScreen { +public abstract class ConfigScreen extends NavigatableSimiScreen { private final Screen parent; protected static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f)); @@ -33,12 +38,23 @@ public 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(); + /*super.init(); + if (backTrack != null) { + widgets.remove(backTrack); + backTrack = null; + }*/ + + testStencil = new TextStencilElement(client.fontRenderer, "POGGERS").at(width*0.5f, height*0.5f, 0); } @@ -108,4 +124,9 @@ public class ConfigScreen extends NavigatableSimiScreen { return super.mouseScrolled(mouseX, mouseY, delta); } + + public static String toHumanReadable(String key) { + String s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(key)).map(StringUtils::capitalize).collect(Collectors.joining(" ")); + return s; + } } 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 new file mode 100644 index 000000000..9b4d62b98 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java @@ -0,0 +1,91 @@ +package com.simibubi.create.foundation.config.ui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.StencilElement; +import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.widget.list.ExtendedList; + +public class ConfigScreenList extends ExtendedList { + + + public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) { + super(client, width, height, top, bottom, elementHeight); + func_244605_b(false); + func_244606_c(false); + } + + @Override + public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + //render tmp background + fill(ms, left, top, left+width, top+height, 0x44_000000); + + super.render(ms, mouseX, mouseY, partialTicks); + } + + @Override + public int getRowWidth() { + return width-10; + } + + @Override + protected int getScrollbarPositionX() { + return left + this.width; + } + + public void tick() { + children().forEach(Entry::tick); + } + + public static abstract class Entry extends ExtendedList.AbstractListEntry { + public void tick() { + + } + } + + public static class LabeledEntry extends Entry { + protected StencilElement label; + + public LabeledEntry(String label) { + this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label); + } + + @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) { + UIRenderHelper.streak(ms, 0, x, y+height/2, height, width/2, 0x0); + label.at(x + 5, y + height/2 - 4, 0).render(ms); + } + } + + public static class WrappedEntry extends Entry { + + AbstractSimiWidget widget; + + public WrappedEntry(AbstractSimiWidget widget) { + this.widget = widget; + } + + @Override + public void tick() { + if (widget instanceof ConfigButton) + ((ConfigButton) widget).tick(); + } + + @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) { + widget.x = x; + widget.y = y; + widget.setWidth(width); + widget.setHeight(height); + widget.render(ms, mouseX, mouseY, partialTicks); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + return widget.mouseClicked(x, y, button); + } + } +} 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 new file mode 100644 index 000000000..d469b1bcb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java @@ -0,0 +1,97 @@ +package com.simibubi.create.foundation.config.ui; + +import javax.annotation.Nonnull; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraftforge.common.ForgeConfigSpec; + +import org.apache.commons.lang3.mutable.MutableInt; +import com.electronwill.nightconfig.core.AbstractConfig; +import com.electronwill.nightconfig.core.UnmodifiableConfig; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; + +public class SubMenuConfigScreen extends ConfigScreen { + + ForgeConfigSpec spec; + UnmodifiableConfig configGroup; + ConfigScreenList list; + + + public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) { + super(parent); + this.spec = configSpec; + this.configGroup = configGroup; + } + + public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec) { + super(parent); + this.spec = configSpec; + this.configGroup = configSpec.getValues(); + } + + @Override + public void tick() { + super.tick(); + list.tick(); + } + + @Override + protected void init() { + widgets.clear(); + super.init(); + + int lWidth = width - 66; + list = new ConfigScreenList(client, lWidth, height - 30, 15, height - 15, 50); + list.setLeftPos(this.width /2 - list.getWidth()/2); + + children.add(list); + + MutableInt y = new MutableInt(15); + + configGroup.valueMap().forEach((s, o) -> { + if (o instanceof AbstractConfig) { + SubMenuEntry entry = new SubMenuEntry(this, toHumanReadable(s), spec, (UnmodifiableConfig) o); + list.children().add(entry); + + } else if (o instanceof ForgeConfigSpec.ConfigValue) { + ForgeConfigSpec.ConfigValue configValue = (ForgeConfigSpec.ConfigValue) o; + ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath()); + Object value = configValue.get(); + + AbstractSimiWidget widget = createWidgetForValue(configValue, valueSpec, value, s, this); + widget.y = y.getValue(); + //list.children().add(new ConfigScreenList.WrappedEntry(widget)); + list.children().add(new ConfigScreenList.LabeledEntry(toHumanReadable(s) + " : " + value)); + //widgets.add(widget); + } + + y.add(50); + }); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + super.renderWindow(ms, mouseX, mouseY, partialTicks); + + list.render(ms, mouseX, mouseY, partialTicks); + } + + @Override + public void resize(@Nonnull Minecraft client, int width, int height) { + double scroll = list.getScrollAmount(); + init(client, width, height); + list.setScrollAmount(scroll); + } + + public static AbstractSimiWidget createWidgetForValue(ForgeConfigSpec.ConfigValue configValue, ForgeConfigSpec.ValueSpec valueSpec, Object value, String key, SubMenuConfigScreen parent) { + String title = toHumanReadable(key); + title += " : " + value; + TextStencilElement text = new TextStencilElement(parent.client.fontRenderer, title).at(5, 11, 0); + return ConfigButton.createFromStencilElement(parent.width/2 - 100, 0, text); + } +} 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 new file mode 100644 index 000000000..18a75d5d4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/SubMenuEntry.java @@ -0,0 +1,46 @@ +package com.simibubi.create.foundation.config.ui.entries; + +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.SubMenuConfigScreen; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.gui.TextStencilElement; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screen.Screen; +import net.minecraftforge.common.ForgeConfigSpec; + +public class SubMenuEntry extends ConfigScreenList.LabeledEntry { + + protected ConfigButton button; + + public SubMenuEntry(Screen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) { + super(label); + TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true); + button = ConfigButton.createFromStencilElement(0, 0, text) + .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(parent, spec, config))); + } + + @Override + public void tick() { + super.tick(); + button.tick(); + } + + @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); + + button.x = x + width/2; + button.y = y; + button.withBounds(width/2, height); + button.render(ms, mouseX, mouseY, partialTicks); + } + + @Override + public boolean mouseClicked(double p_231044_1_, double p_231044_3_, int p_231044_5_) { + return button.mouseClicked(p_231044_1_, p_231044_3_, p_231044_5_); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java index 1e2174214..066ff0993 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java @@ -62,6 +62,10 @@ public abstract class AbstractSimiScreen extends Screen { for (Widget widget : widgets) if (widget.mouseClicked(x, y, button)) result = true; + + if (!result) { + result = super.mouseClicked(x, y, button); + } return result; } diff --git a/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java index 7a8077ea8..caa577f58 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java @@ -27,21 +27,21 @@ public class CombinedStencilElement extends StencilElement { protected void renderStencil(MatrixStack ms) { ms.push(); element1.transform(ms); - element1.renderStencil(ms); + element1.withBounds(width, height).renderStencil(ms); ms.pop(); ms.push(); element2.transform(ms); - element2.renderStencil(ms); + element2.withBounds(width, height).renderStencil(ms); ms.pop(); } @Override protected void renderElement(MatrixStack ms) { if (mode.rendersFirst()) - element1.renderElement(ms); + element1.withBounds(width, height).renderElement(ms); if (mode.rendersSecond()) - element2.renderElement(ms); + element2.withBounds(width, height).renderElement(ms); } public enum ElementMode { diff --git a/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java new file mode 100644 index 000000000..08973b0b2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; + +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; + + public DelegatedStencilElement() { + stencil = EMPTY_RENDERER; + element = DEFAULT_ELEMENT; + } + + public DelegatedStencilElement(ElementRenderer stencil, ElementRenderer element) { + this.stencil = stencil; + this.element = element; + } + + public DelegatedStencilElement withStencilRenderer(ElementRenderer renderer) { + stencil = renderer; + return this; + } + + public DelegatedStencilElement withElementRenderer(ElementRenderer renderer) { + element = renderer; + return this; + } + + @Override + protected void renderStencil(MatrixStack ms) { + stencil.render(ms, width, height); + } + + @Override + protected void renderElement(MatrixStack ms) { + element.render(ms, width, height); + } + + @FunctionalInterface + public interface ElementRenderer { + void render(MatrixStack ms, int width, int height); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java index 161de3618..220b5fa8c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/StencilElement.java @@ -1,21 +1,41 @@ package com.simibubi.create.foundation.gui; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.AbstractGui; import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; -public abstract class StencilElement { +public abstract class StencilElement implements IScreenRenderable { + protected int width = 0; + protected int height = 0; float x, y , z; - public StencilElement at(float x, float y, float z) { + public T at(float x, float y, float z) { this.x = x; this.y = y; this.z = z; - return this; + //noinspection unchecked + return (T) this; + } + + public T withBounds(int width, int height) { + this.width = width; + this.height = height; + //noinspection unchecked + return (T) this; + } + + @Override + public void draw(MatrixStack ms, AbstractGui screen, int x, int y) { + this.at(x, y, 0).render(ms); + } + + @Override + public void draw(MatrixStack ms, int x, int y) { + this.at(x, y, 0).render(ms); } public void render(MatrixStack ms) { @@ -29,6 +49,22 @@ public abstract class StencilElement { ms.pop(); } + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + protected abstract void renderStencil(MatrixStack ms); protected abstract void renderElement(MatrixStack ms); diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java index c1382507a..b278c7151 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java @@ -6,17 +6,17 @@ import net.minecraft.util.text.StringTextComponent; import com.mojang.blaze3d.matrix.MatrixStack; -public class TextStencilElement extends StencilElement { - - protected static final ElementRenderer DEFAULT_RENDERER = ((ms, width, _height) -> UIRenderHelper.angledGradient(ms, 15, -3, 5, 14, width+6, 0xff_10dd10, 0x1010dd)); +public class TextStencilElement extends DelegatedStencilElement { protected FontRenderer font; protected IFormattableTextComponent component; - protected ElementRenderer elementRenderer = DEFAULT_RENDERER; + protected boolean centerVertically = false; + protected boolean centerHorizontally = false; public TextStencilElement(FontRenderer font) { super(); this.font = font; + height = 10; } public TextStencilElement(FontRenderer font, String text) { @@ -29,11 +29,6 @@ public class TextStencilElement extends StencilElement { this.component = component; } - public TextStencilElement withElementRenderer(ElementRenderer renderer) { - elementRenderer = renderer; - return this; - } - public TextStencilElement withText(String text) { component = new StringTextComponent(text); return this; @@ -44,25 +39,35 @@ public class TextStencilElement extends StencilElement { return this; } + public TextStencilElement centered(boolean vertical, boolean horizontal) { + this.centerVertically = vertical; + this.centerHorizontally = horizontal; + return this; + } + @Override protected void renderStencil(MatrixStack ms) { - font.draw(ms, component, 0, 0, 0xff_000000); + + float x = 0, y = 0; + if (centerHorizontally) + x = width / 2f - font.getWidth(component) / 2f; + + if (centerVertically) + y = height / 2f - font.FONT_HEIGHT / 2f; + + font.draw(ms, component, x, y, 0xff_000000); + //font.draw(ms, component, 0, 0, 0xff_000000); } @Override protected void renderElement(MatrixStack ms) { - elementRenderer.render(ms, font.getWidth(component), 10); + element.render(ms, font.getWidth(component), height); } - @FunctionalInterface - public interface ElementRenderer { - void render(MatrixStack ms, int width, int height); - } + public static class Centered extends TextStencilElement { - int width; - public Centered(FontRenderer font, String text, int width) { super(font, text); this.width = width; @@ -81,7 +86,7 @@ public class TextStencilElement extends StencilElement { @Override protected void renderElement(MatrixStack ms) { - elementRenderer.render(ms, width, 10); + element.render(ms, width, 10); } } } 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 c409480bd..5fca88e7c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -22,6 +22,8 @@ public class UIRenderHelper { public static void enableStencil() { RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); + if (framebuffer != null) + RenderSystem.recordRenderCall(() -> framebuffer.enableStencil()); } public static Framebuffer framebuffer; @@ -77,8 +79,8 @@ public class UIRenderHelper { //angle in degrees; 0° -> fading to the right //x and y specify the middle point of the starting edge - //width is the total width of the streak - public static void streak(MatrixStack ms, float angle, int x, int y, int width, int length, int color) { + //breadth is the total width of the streak + public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length, int color) { int a1 = 0xa0 << 24; int a2 = 0x80 << 24; int a3 = 0x10 << 24; @@ -94,7 +96,7 @@ public class UIRenderHelper { ms.translate(x, y, 0); ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90)); - streak(ms, width/2, length, c1, c2, c3, c4); + streak(ms, breadth/2, length, c1, c2, c3, c4); ms.pop(); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java index f6ba1668c..f48ebcb51 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.gui.widgets; import java.util.LinkedList; import java.util.List; +import java.util.function.BiConsumer; import com.mojang.blaze3d.matrix.MatrixStack; @@ -14,7 +15,8 @@ import javax.annotation.Nonnull; public abstract class AbstractSimiWidget extends Widget { protected List toolTip; - + protected BiConsumer onClick = (_$, _$$) -> {}; + public AbstractSimiWidget(int xIn, int yIn, int widthIn, int heightIn) { super(xIn, yIn, widthIn, heightIn, StringTextComponent.EMPTY); toolTip = new LinkedList<>(); @@ -28,4 +30,17 @@ public abstract class AbstractSimiWidget extends Widget { public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { } + public T withCallback(BiConsumer cb) { + this.onClick = cb; + //noinspection unchecked + return (T) this; + } + + public T withCallback(Runnable cb) { + return withCallback((_$, _$$) -> cb.run()); + } + + public void runCallback(double mouseX, double mouseY) { + onClick.accept((int) mouseX, (int) mouseY); + } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java index b58638d1e..5e8a464af 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/StencilWidget.java @@ -1,5 +1,8 @@ package com.simibubi.create.foundation.gui.widgets; +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + import javax.annotation.Nonnull; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.gui.StencilElement; @@ -8,6 +11,10 @@ public class StencilWidget extends AbstractSimiWidget { protected StencilElement stencilElement; + protected StencilWidget(int x, int y) { + super(x, y, 42, 42); + } + protected StencilWidget(int x, int y, int width, int height) { super(x, y, width, height); } @@ -22,11 +29,25 @@ public class StencilWidget extends AbstractSimiWidget { ms.push(); ms.translate(x, y, 0); - stencilElement.render(ms); + stencilElement.withBounds(width, height).render(ms); ms.pop(); } + public T modifyElement(Consumer consumer) { + if (stencilElement != null) + consumer.accept(stencilElement); + //noinspection unchecked + return (T) this; + } + + public T mapElement(UnaryOperator function) { + if (stencilElement != null) + stencilElement = function.apply(stencilElement); + //noinspection unchecked + return (T) this; + } + public StencilElement getStencilElement() { return stencilElement; } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java index a5e31246c..3067d8c75 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java @@ -21,9 +21,9 @@ import javax.annotation.Nonnull; public class PonderButton extends AbstractSimiWidget { private IScreenRenderable icon; + private boolean scaleIcon = true; private ItemStack item; protected boolean pressed; - private BiConsumer onClick; private int xFadeModifier; private int yFadeModifier; private float fade; @@ -48,11 +48,21 @@ public class PonderButton extends AbstractSimiWidget { this(x, y, ($, $$) -> onClick.run()); } + /** + * @param icon the icon to be rendered. assumed to be 16x16px in size. will be scaled to fit the button size + * + */ public PonderButton showing(IScreenRenderable icon) { this.icon = icon; return this; } + public PonderButton showingUnscaled(IScreenRenderable icon) { + this.icon = icon; + this.scaleIcon = false; + return this; + } + public PonderButton showing(ItemStack item) { this.item = item; return this; @@ -121,7 +131,9 @@ public class PonderButton extends AbstractSimiWidget { RenderSystem.color4f(1, 1, 1, fade); ms.push(); ms.translate(x + 2, y + 2, 0); - ms.scale((width - 4) / 16f, (height - 4) / 16f, 1); + if (this.scaleIcon) + ms.scale((width - 4) / 16f, (height - 4) / 16f, 1); + icon.draw(ms, this, 0, 0); ms.pop(); } @@ -141,10 +153,6 @@ public class PonderButton extends AbstractSimiWidget { ms.pop(); } - public void runCallback(double mouseX, double mouseY) { - onClick.accept((int) mouseX, (int) mouseY); - } - @Override public void onClick(double p_onClick_1_, double p_onClick_3_) { super.onClick(p_onClick_1_, p_onClick_3_); From 5b04e821635fea8211b8fa40236ae070da319425 Mon Sep 17 00:00:00 2001 From: zelophed Date: Sun, 11 Apr 2021 03:12:43 +0200 Subject: [PATCH 06/17] boolean toggle --- .../config/ui/ConfigScreenList.java | 15 +++-- .../config/ui/SubMenuConfigScreen.java | 20 ++++-- .../config/ui/entries/BooleanEntry.java | 65 +++++++++++++++++++ .../config/ui/entries/ValueEntry.java | 51 +++++++++++++++ .../gui/CombinedStencilElement.java | 18 +++++ .../gui/DelegatedStencilElement.java | 10 +-- .../foundation/gui/TextStencilElement.java | 16 ++++- .../create/foundation/gui/UIRenderHelper.java | 10 +-- 8 files changed, 182 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java 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 9b4d62b98..b06b70396 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 @@ -8,6 +8,7 @@ import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.widget.list.ExtendedList; +import net.minecraft.util.text.IFormattableTextComponent; public class ConfigScreenList extends ExtendedList { @@ -28,12 +29,12 @@ public class ConfigScreenList extends ExtendedList { @Override public int getRowWidth() { - return width-10; + return width-18; } @Override protected int getScrollbarPositionX() { - return left + this.width; + return left + this.width-5; } public void tick() { @@ -41,13 +42,11 @@ public class ConfigScreenList extends ExtendedList { } public static abstract class Entry extends ExtendedList.AbstractListEntry { - public void tick() { - - } + public void tick() {} } public static class LabeledEntry extends Entry { - protected StencilElement label; + protected TextStencilElement label; public LabeledEntry(String label) { this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label); @@ -56,6 +55,10 @@ public class ConfigScreenList extends ExtendedList { @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) { UIRenderHelper.streak(ms, 0, x, y+height/2, height, width/2, 0x0); + IFormattableTextComponent component = label.getComponent(); + if (Minecraft.getInstance().fontRenderer.getWidth(component) > width/2 - 10) { + label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, width / 2 - 15).getString() + "..."); + } label.at(x + 5, y + height/2 - 4, 0).render(ms); } } 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 d469b1bcb..eb232bf5c 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 @@ -10,6 +10,7 @@ import org.apache.commons.lang3.mutable.MutableInt; import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.ui.entries.BooleanEntry; import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.TextStencilElement; @@ -54,8 +55,10 @@ public class SubMenuConfigScreen extends ConfigScreen { MutableInt y = new MutableInt(15); configGroup.valueMap().forEach((s, o) -> { + String humanKey = toHumanReadable(s); + if (o instanceof AbstractConfig) { - SubMenuEntry entry = new SubMenuEntry(this, toHumanReadable(s), spec, (UnmodifiableConfig) o); + SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) o); list.children().add(entry); } else if (o instanceof ForgeConfigSpec.ConfigValue) { @@ -63,11 +66,16 @@ public class SubMenuConfigScreen extends ConfigScreen { ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath()); Object value = configValue.get(); - AbstractSimiWidget widget = createWidgetForValue(configValue, valueSpec, value, s, this); - widget.y = y.getValue(); - //list.children().add(new ConfigScreenList.WrappedEntry(widget)); - list.children().add(new ConfigScreenList.LabeledEntry(toHumanReadable(s) + " : " + value)); - //widgets.add(widget); + if (value instanceof Boolean) { + BooleanEntry entry = new BooleanEntry(humanKey, (ForgeConfigSpec.ConfigValue) configValue, valueSpec); + list.children().add(entry); + } else { + AbstractSimiWidget widget = createWidgetForValue(configValue, valueSpec, value, s, this); + widget.y = y.getValue(); + //list.children().add(new ConfigScreenList.WrappedEntry(widget)); + list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value)); + //widgets.add(widget); + } } y.add(50); 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 new file mode 100644 index 000000000..94f702df2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java @@ -0,0 +1,65 @@ +package com.simibubi.create.foundation.config.ui.entries; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.ui.ConfigButton; +import com.simibubi.create.foundation.gui.CombinedStencilElement; +import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.gui.UIRenderHelper; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.ForgeConfigSpec; + +public class BooleanEntry extends ValueEntry { + + TextStencilElement enabled; + TextStencilElement disabled; + CombinedStencilElement buttonStencil; + ConfigButton button; + + public BooleanEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + + enabled = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Enabled") + .centered(true, true) + .withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_88f788, 0xff_20cc20)); + + disabled = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Disabled") + .centered(true, true) + .withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_f78888, 0xff_cc2020)); + + button = ConfigButton.createFromStencilElement(0, 0, enabled) + .withCallback(() -> { + value.set(!value.get()); + buttonStencil.withSecond(value.get() ? enabled : disabled); + }); + + buttonStencil = ((CombinedStencilElement) button.getStencilElement()) + .withMode(CombinedStencilElement.ElementMode.BOTH) + .withSecond(value.get() ? enabled : disabled); + } + + @Override + public void tick() { + super.tick(); + button.tick(); + } + + @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); + + button.x = x + width/2; + button.y = y; + button.withBounds(width/2 - 34, height).render(ms, mouseX, mouseY, partialTicks); + } + + @Override + protected void onReset() { + buttonStencil.withSecond(value.get() ? enabled : disabled); + } + + @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/ValueEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java new file mode 100644 index 000000000..7a05ad41c --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/ValueEntry.java @@ -0,0 +1,51 @@ +package com.simibubi.create.foundation.config.ui.entries; + +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.gui.TextStencilElement; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.ForgeConfigSpec; + +public class ValueEntry extends ConfigScreenList.LabeledEntry { + + protected ForgeConfigSpec.ConfigValue value; + protected ForgeConfigSpec.ValueSpec spec; + protected ConfigButton reset; + + public ValueEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label); + this.value = value; + this.spec = spec; + + TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "R").centered(true, true); + reset = ConfigButton.createFromStencilElement(0, 0, text) + .withBounds(30, 30) + .withCallback(() -> { + value.set((T) spec.getDefault()); + this.onReset(); + }); + } + + @Override + public void tick() { + reset.tick(); + } + + @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); + + reset.x = x + width - 32; + reset.y = y + 10; + reset.render(ms, mouseX, mouseY, partialTicks); + } + + @Override + public boolean mouseClicked(double mX, double mY, int button) { + return reset.mouseClicked(mX, mY, button); + } + + protected void onReset() {} +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java index caa577f58..07789469f 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/CombinedStencilElement.java @@ -23,6 +23,24 @@ public class CombinedStencilElement extends StencilElement { return e; } + public T withFirst(StencilElement element) { + this.element1 = element; + //noinspection unchecked + return (T) this; + } + + public T withSecond(StencilElement element) { + this.element2 = element; + //noinspection unchecked + return (T) this; + } + + public T withMode(ElementMode mode) { + this.mode = mode; + //noinspection unchecked + return (T) this; + } + @Override protected void renderStencil(MatrixStack ms) { ms.push(); 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 08973b0b2..9feb61f84 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/DelegatedStencilElement.java @@ -21,14 +21,16 @@ public class DelegatedStencilElement extends StencilElement { this.element = element; } - public DelegatedStencilElement withStencilRenderer(ElementRenderer renderer) { + public T withStencilRenderer(ElementRenderer renderer) { stencil = renderer; - return this; + //noinspection unchecked + return (T) this; } - public DelegatedStencilElement withElementRenderer(ElementRenderer renderer) { + public T withElementRenderer(ElementRenderer renderer) { element = renderer; - return this; + //noinspection unchecked + return (T) this; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java index b278c7151..f7f5a556e 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java @@ -61,10 +61,22 @@ public class TextStencilElement extends DelegatedStencilElement { @Override protected void renderElement(MatrixStack ms) { - element.render(ms, font.getWidth(component), height); + float x = 0, y = 0; + if (centerHorizontally) + x = width / 2f - font.getWidth(component) / 2f; + + if (centerVertically) + y = height / 2f - font.FONT_HEIGHT / 2f; + + ms.push(); + ms.translate(x, y, 0); + element.render(ms, font.getWidth(component), font.FONT_HEIGHT + 2); + ms.pop(); } - + public IFormattableTextComponent getComponent() { + return component; + } public static class Centered extends TextStencilElement { 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 5fca88e7c..28b5e77ac 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -113,8 +113,8 @@ public class UIRenderHelper { /** * @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int) */ - public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int width, int length, int color1, int color2) { - angledGradient(ms, angle, x, y, 0, width, length, color1, color2); + public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int breadth, int length, int color1, int color2) { + angledGradient(ms, angle, x, y, 0, breadth, length, color1, color2); } /** * x and y specify the middle point of the starting edge @@ -122,16 +122,16 @@ public class UIRenderHelper { * @param angle the angle of the gradient in degrees; 0° means from left to right * @param color1 the color at the starting edge * @param color2 the color at the ending edge - * @param width the total width of the gradient + * @param breadth the total width of the gradient * */ - public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int width, int length, int color1, int color2) { + public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int breadth, int length, int color1, int color2) { ms.push(); ms.translate(x, y, z); ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90)); Matrix4f model = ms.peek().getModel(); - int w = width / 2; + int w = breadth / 2; GuiUtils.drawGradientRect(model, 0, -w, 0, w, length, color1, color2); ms.pop(); From bb8153f1404056be167b1f06e0c9951aca6c83f2 Mon Sep 17 00:00:00 2001 From: zelophed Date: Tue, 13 Apr 2021 23:54:26 +0200 Subject: [PATCH 07/17] texting numbers --- .../config/ui/BaseConfigScreen.java | 4 +- .../foundation/config/ui/ConfigButton.java | 8 + .../foundation/config/ui/ConfigScreen.java | 4 +- .../config/ui/ConfigScreenList.java | 56 ++++- .../config/ui/SubMenuConfigScreen.java | 12 +- .../config/ui/entries/BooleanEntry.java | 13 +- .../config/ui/entries/NumberEntry.java | 197 ++++++++++++++++++ .../config/ui/entries/SubMenuEntry.java | 10 +- .../config/ui/entries/ValueEntry.java | 21 +- .../foundation/gui/TextStencilElement.java | 24 --- 10 files changed, 300 insertions(+), 49 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java 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 b2e9a3edd..0e5f61c4a 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 @@ -35,7 +35,7 @@ public class BaseConfigScreen extends ConfigScreen { .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.CLIENT.specification))) ); - StencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(false, true).at(0, 11, 0); + StencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); widgets.add(commonConfigWidget = ConfigButton.createFromStencilElement( width / 2 - 100, height / 2 - 15, @@ -46,7 +46,7 @@ public class BaseConfigScreen extends ConfigScreen { commonConfigWidget.active = false; commonConfigWidget.updateColorsFromState(); - StencilElement text3 = new TextStencilElement.Centered(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD), 200).at(0, 11, 0); + StencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); widgets.add(serverConfigWidget = ConfigButton.createFromStencilElement( width / 2 - 100, height / 2 - 15 + 50, diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java index 4017283d7..7b776bce7 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigButton.java @@ -104,6 +104,14 @@ public class ConfigButton extends StencilWidget { gradientColor2 = Palette.getColorForButtonState(false, active, hovered); } + public void animateGradientFromState() { + startGradientAnimation( + Palette.getColorForButtonState(true, active, hovered), + Palette.getColorForButtonState(false, active, hovered), + true + ); + } + private void startGradientAnimation(int c1, int c2, boolean positive, double expSpeed) { colorAnimation.startWithValue(positive ? 1 : -1); colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP); 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 95a7ea2e8..8f854c63e 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 @@ -110,8 +110,8 @@ public abstract class ConfigScreen extends NavigatableSimiScreen { protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { int x = (int) (width * 0.5f); int y = (int) (height * 0.5f); - this.drawHorizontalLine(ms, x-25, x+25, y, 0xff_807060); - this.drawVerticalLine(ms, x, y-25, y+25, 0xff_90a0b0); + //this.drawHorizontalLine(ms, x-25, x+25, y, 0xff_807060); + //this.drawVerticalLine(ms, x, y-25, y+25, 0xff_90a0b0); //this.testStencil.render(ms); 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 b06b70396..9e64a5491 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 @@ -1,12 +1,18 @@ package com.simibubi.create.foundation.config.ui; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.foundation.gui.StencilElement; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; +import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.IGuiEventListener; import net.minecraft.client.gui.widget.list.ExtendedList; import net.minecraft.util.text.IFormattableTextComponent; @@ -17,6 +23,7 @@ public class ConfigScreenList extends ExtendedList { super(client, width, height, top, bottom, elementHeight); func_244605_b(false); func_244606_c(false); + setRenderSelection(false); } @Override @@ -27,6 +34,15 @@ public class ConfigScreenList extends ExtendedList { super.render(ms, mouseX, mouseY, partialTicks); } + @Override + protected void renderList(MatrixStack p_238478_1_, int p_238478_2_, int p_238478_3_, int p_238478_4_, int p_238478_5_, float p_238478_6_) { + MainWindow window = Minecraft.getInstance().getWindow(); + double d0 = window.getGuiScaleFactor(); + RenderSystem.enableScissor((int) (this.left * d0), (int) (window.getFramebufferHeight() - (this.bottom* d0)), (int)(this.width * d0), (int)(this.height * d0)); + super.renderList(p_238478_1_, p_238478_2_, p_238478_3_, p_238478_4_, p_238478_5_, p_238478_6_); + RenderSystem.disableScissor(); + } + @Override public int getRowWidth() { return width-18; @@ -42,10 +58,38 @@ public class ConfigScreenList extends ExtendedList { } public static abstract class Entry extends ExtendedList.AbstractListEntry { + protected List listeners; + + protected Entry() { + listeners = new ArrayList<>(); + } + public void tick() {} + + public List getGuiListeners() { + return listeners; + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button)); + } + + @Override + public boolean keyPressed(int code, int keyPressed_2_, int keyPressed_3_) { + return getGuiListeners().stream().anyMatch(l -> l.keyPressed(code, keyPressed_2_, keyPressed_3_)); + } + + @Override + public boolean charTyped(char ch, int code) { + return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code)); + } } public static class LabeledEntry extends Entry { + + protected static final float labelWidthMult = 0.4f; + protected TextStencilElement label; public LabeledEntry(String label) { @@ -54,13 +98,17 @@ public class ConfigScreenList extends ExtendedList { @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) { - UIRenderHelper.streak(ms, 0, x, y+height/2, height, width/2, 0x0); + UIRenderHelper.streak(ms, 0, x, y+height/2, height - 10, width/2, 0x0); IFormattableTextComponent component = label.getComponent(); - if (Minecraft.getInstance().fontRenderer.getWidth(component) > width/2 - 10) { - label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, width / 2 - 15).getString() + "..."); + if (Minecraft.getInstance().fontRenderer.getWidth(component) > getLabelWidth(width) - 10) { + label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, getLabelWidth(width) - 15).getString() + "..."); } label.at(x + 5, y + height/2 - 4, 0).render(ms); } + + protected static int getLabelWidth(int totalWidth) { + return (int) (totalWidth * labelWidthMult); + } } public static class WrappedEntry extends Entry { 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 eb232bf5c..a4c81b70c 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 @@ -11,6 +11,7 @@ import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.config.ui.entries.BooleanEntry; +import com.simibubi.create.foundation.config.ui.entries.NumberEntry; import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.TextStencilElement; @@ -69,12 +70,15 @@ public class SubMenuConfigScreen extends ConfigScreen { if (value instanceof Boolean) { BooleanEntry entry = new BooleanEntry(humanKey, (ForgeConfigSpec.ConfigValue) configValue, valueSpec); list.children().add(entry); + } else if (value instanceof Number) { + NumberEntry entry = NumberEntry.create(value, humanKey, configValue, valueSpec); + if (entry != null) { + list.children().add(entry); + } else { + list.children().add(new ConfigScreenList.LabeledEntry("n-" + o.getClass().getSimpleName() + " " + humanKey + " : " + value)); + } } else { - AbstractSimiWidget widget = createWidgetForValue(configValue, valueSpec, value, s, this); - widget.y = y.getValue(); - //list.children().add(new ConfigScreenList.WrappedEntry(widget)); list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value)); - //widgets.add(widget); } } 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 94f702df2..f1426be76 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 @@ -31,11 +31,15 @@ public class BooleanEntry extends ValueEntry { .withCallback(() -> { value.set(!value.get()); buttonStencil.withSecond(value.get() ? enabled : disabled); + onValueChange(); }); buttonStencil = ((CombinedStencilElement) button.getStencilElement()) .withMode(CombinedStencilElement.ElementMode.BOTH) .withSecond(value.get() ? enabled : disabled); + + listeners.add(button); + onReset(); } @Override @@ -48,18 +52,19 @@ public class BooleanEntry extends ValueEntry { 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); - button.x = x + width/2; + button.x = x + getLabelWidth(width); button.y = y; - button.withBounds(width/2 - 34, height).render(ms, mouseX, mouseY, partialTicks); + button.withBounds(width - getLabelWidth(width) - resetWidth, height).render(ms, mouseX, mouseY, partialTicks); } @Override protected void onReset() { + super.onReset(); buttonStencil.withSecond(value.get() ? enabled : disabled); } - @Override + /*@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/NumberEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java new file mode 100644 index 000000000..8569a1a10 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java @@ -0,0 +1,197 @@ +package com.simibubi.create.foundation.config.ui.entries; + +import java.lang.reflect.Field; +import java.util.function.Function; + +import javax.annotation.Nullable; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.TextStencilElement; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.common.ForgeConfigSpec; + +public abstract class NumberEntry extends ValueEntry { + + protected int minOffset = 0, maxOffset = 0; + protected TextStencilElement minText = null, maxText = null; + + @Nullable + public static NumberEntry create(Object type, String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + if (type instanceof Integer) { + return new IntegerEntry(label, (ForgeConfigSpec.ConfigValue) value, spec); + } else if (type instanceof Float) { + return new FloatEntry(label, (ForgeConfigSpec.ConfigValue) value, spec); + } else if (type instanceof Double) { + return new DoubleEntry(label, (ForgeConfigSpec.ConfigValue) value, spec); + } + + return null; + } + + protected TextFieldWidget textField; + + public NumberEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + textField = new TextFieldWidget(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, StringTextComponent.EMPTY); + textField.setText(String.valueOf(value.get())); + + Object range = spec.getRange(); + try { + Field minField = range.getClass().getDeclaredField("min"); + Field maxField = range.getClass().getDeclaredField("max"); + minField.setAccessible(true); + maxField.setAccessible(true); + T min = (T) minField.get(range); + T max = (T) maxField.get(range); + + FontRenderer font = Minecraft.getInstance().fontRenderer; + if (!min.equals(getTypeMin())) { + StringTextComponent t = new StringTextComponent(formatBound(min) + " < "); + minText = new TextStencilElement(font, t).centered(true, false); + minOffset = font.getWidth(t); + } + if (!max.equals(getTypeMax())) { + StringTextComponent t = new StringTextComponent(" < " + formatBound(max)); + maxText = new TextStencilElement(font, t).centered(true, false); + maxOffset = font.getWidth(t); + } + } catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) { + e.printStackTrace(); + } + + textField.setResponder(s -> { + try { + T number = getParser().apply(s); + if (!spec.test(number)) + throw new IllegalArgumentException(); + + textField.setTextColor(0xff_20cc20); + value.set(number); + onValueChange(); + + } catch (IllegalArgumentException ignored) { + textField.setTextColor(0xff_cc2020); + } + }); + + listeners.add(textField); + onReset(); + } + + protected String formatBound(T bound) { + String sci = String.format("%.2E", bound); + String str = String.valueOf(bound); + return sci.length() < str.length() ? sci : str; + } + + protected abstract T getTypeMin(); + + protected abstract T getTypeMax(); + + protected abstract Function getParser(); + + @Override + protected void onReset() { + super.onReset(); + textField.setText(String.valueOf(value.get())); + } + + @Override + public void tick() { + super.tick(); + textField.tick(); + } + + @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); + + textField.x = x + getLabelWidth(width) + minOffset; + textField.y = y + 10; + textField.setWidth(width - getLabelWidth(width) - resetWidth - minOffset - maxOffset); + textField.setHeight(30); + textField.render(ms, mouseX, mouseY, partialTicks); + + if (minText != null) + minText + .at(textField.x - minOffset, textField.y, 0) + .withBounds(minOffset, textField.unusedGetHeight()) + .render(ms); + + if (maxText != null) + maxText + .at(textField.x + textField.getWidth(), textField.y, 0) + .withBounds(maxOffset, textField.unusedGetHeight()) + .render(ms); + } + + public static class IntegerEntry extends NumberEntry { + + public IntegerEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + } + + @Override + protected Integer getTypeMin() { + return Integer.MIN_VALUE; + } + + @Override + protected Integer getTypeMax() { + return Integer.MAX_VALUE; + } + + @Override + protected Function getParser() { + return Integer::parseInt; + } + } + + public static class FloatEntry extends NumberEntry { + + public FloatEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + } + + @Override + protected Float getTypeMin() { + return Float.MIN_VALUE; + } + + @Override + protected Float getTypeMax() { + return Float.MAX_VALUE; + } + + @Override + protected Function getParser() { + return Float::parseFloat; + } + } + + public static class DoubleEntry extends NumberEntry { + + public DoubleEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + } + + @Override + protected Double getTypeMin() { + return Double.MIN_VALUE; + } + + @Override + protected Double getTypeMax() { + return Double.MAX_VALUE; + } + + @Override + protected Function getParser() { + return Double::parseDouble; + } + } +} 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 18a75d5d4..28f5762d1 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 @@ -21,6 +21,8 @@ public class SubMenuEntry extends ConfigScreenList.LabeledEntry { TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true); button = ConfigButton.createFromStencilElement(0, 0, text) .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(parent, spec, config))); + + listeners.add(button); } @Override @@ -33,14 +35,14 @@ public class SubMenuEntry extends ConfigScreenList.LabeledEntry { 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); - button.x = x + width/2; + button.x = x + getLabelWidth(width); button.y = y; - button.withBounds(width/2, height); + button.withBounds(width - getLabelWidth(width), height); button.render(ms, mouseX, mouseY, partialTicks); } - @Override + /*@Override public boolean mouseClicked(double p_231044_1_, double p_231044_3_, int p_231044_5_) { return button.mouseClicked(p_231044_1_, p_231044_3_, p_231044_5_); - } + }*/ } 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 7a05ad41c..bde5066dc 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 @@ -10,6 +10,8 @@ import net.minecraftforge.common.ForgeConfigSpec; public class ValueEntry extends ConfigScreenList.LabeledEntry { + protected static final int resetWidth = 24;//including 2px offset on each side + protected ForgeConfigSpec.ConfigValue value; protected ForgeConfigSpec.ValueSpec spec; protected ConfigButton reset; @@ -21,11 +23,13 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "R").centered(true, true); reset = ConfigButton.createFromStencilElement(0, 0, text) - .withBounds(30, 30) + .withBounds(resetWidth - 4, 20) .withCallback(() -> { value.set((T) spec.getDefault()); this.onReset(); }); + + listeners.add(reset); } @Override @@ -37,15 +41,22 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { 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); - reset.x = x + width - 32; - reset.y = y + 10; + reset.x = x + width - resetWidth + 2; + reset.y = y + 15; reset.render(ms, mouseX, mouseY, partialTicks); } - @Override + /*@Override public boolean mouseClicked(double mX, double mY, int button) { return reset.mouseClicked(mX, mY, button); + }*/ + + protected void onReset() { + onValueChange(); } - protected void onReset() {} + protected void onValueChange() { + reset.active = !value.get().equals(spec.getDefault()); + reset.animateGradientFromState(); + } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java index f7f5a556e..3fc0c4e24 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/TextStencilElement.java @@ -77,28 +77,4 @@ public class TextStencilElement extends DelegatedStencilElement { public IFormattableTextComponent getComponent() { return component; } - - public static class Centered extends TextStencilElement { - - public Centered(FontRenderer font, String text, int width) { - super(font, text); - this.width = width; - } - - public Centered(FontRenderer font, IFormattableTextComponent component, int width) { - super(font, component); - this.width = width; - } - - @Override - protected void renderStencil(MatrixStack ms) { - int textWidth = font.getWidth(component); - font.draw(ms, component, width / 2f - textWidth / 2f, 0, 0xff_000000); - } - - @Override - protected void renderElement(MatrixStack ms) { - element.render(ms, width, 10); - } - } } From fdbdf0ec8d2dca45ae406dbe5027d149dc9f0d9e Mon Sep 17 00:00:00 2001 From: zelophed Date: Wed, 14 Apr 2021 03:27:11 +0200 Subject: [PATCH 08/17] completing the set --- .../config/ui/BaseConfigScreen.java | 15 ++-- .../foundation/config/ui/ConfigButton.java | 7 ++ .../config/ui/ConfigScreenList.java | 11 ++- .../config/ui/SubMenuConfigScreen.java | 6 +- .../config/ui/entries/BooleanEntry.java | 5 +- .../config/ui/entries/EnumEntry.java | 75 +++++++++++++++++++ .../config/ui/entries/NumberEntry.java | 2 +- .../config/ui/entries/SubMenuEntry.java | 5 ++ .../config/ui/entries/ValueEntry.java | 13 +++- 9 files changed, 125 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java 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 0e5f61c4a..f3975142e 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 @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.StencilElement; import com.simibubi.create.foundation.gui.TextStencilElement; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; @@ -42,9 +43,8 @@ public class BaseConfigScreen extends ConfigScreen { text2 ) .withBounds(200, 30) + .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.COMMON.specification))) ); - commonConfigWidget.active = false; - commonConfigWidget.updateColorsFromState(); StencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); widgets.add(serverConfigWidget = ConfigButton.createFromStencilElement( @@ -54,8 +54,13 @@ public class BaseConfigScreen extends ConfigScreen { ) .withBounds(200, 30) ); - serverConfigWidget.active = false; - serverConfigWidget.updateColorsFromState(); + + if (Minecraft.getInstance().world != null) { + serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.SERVER.specification))); + } else { + serverConfigWidget.active = false; + serverConfigWidget.updateColorsFromState(); + } } @Override @@ -63,6 +68,6 @@ public class BaseConfigScreen extends ConfigScreen { super.renderWindow(ms, mouseX, mouseY, partialTicks); - testStencil.at(200, 200, 0).render(ms); + // UIRenderHelper.angledGradient(ms, 0, 0, $height/2, $height+2, $width+2, button.gradientColor1, button.gradientColor2)); + return button; + } + protected ConfigButton(int x, int y) { super(x, y); } 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 9e64a5491..c4af6fbeb 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 @@ -18,7 +18,6 @@ import net.minecraft.util.text.IFormattableTextComponent; public class ConfigScreenList extends ExtendedList { - public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) { super(client, width, height, top, bottom, elementHeight); func_244605_b(false); @@ -57,6 +56,10 @@ public class ConfigScreenList extends ExtendedList { children().forEach(Entry::tick); } + public void bumpCog(float force) { + ConfigScreen.cogSpin.bump(3, force); + } + public static abstract class Entry extends ExtendedList.AbstractListEntry { protected List listeners; @@ -98,7 +101,7 @@ public class ConfigScreenList extends ExtendedList { @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) { - UIRenderHelper.streak(ms, 0, x, y+height/2, height - 10, width/2, 0x0); + UIRenderHelper.streak(ms, 0, x, y+height/2, height - 10, getLabelWidth(width), 0x0); IFormattableTextComponent component = label.getComponent(); if (Minecraft.getInstance().fontRenderer.getWidth(component) > getLabelWidth(width) - 10) { label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, getLabelWidth(width) - 15).getString() + "..."); @@ -106,8 +109,8 @@ public class ConfigScreenList extends ExtendedList { label.at(x + 5, y + height/2 - 4, 0).render(ms); } - protected static int getLabelWidth(int totalWidth) { - return (int) (totalWidth * labelWidthMult); + protected int getLabelWidth(int totalWidth) { + return totalWidth; } } 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 a4c81b70c..a0c4f967f 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 @@ -11,6 +11,7 @@ import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.mojang.blaze3d.matrix.MatrixStack; 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.gui.ScreenOpener; @@ -47,7 +48,7 @@ public class SubMenuConfigScreen extends ConfigScreen { widgets.clear(); super.init(); - int lWidth = width - 66; + int lWidth = Math.min(width - 66, 500); list = new ConfigScreenList(client, lWidth, height - 30, 15, height - 15, 50); list.setLeftPos(this.width /2 - list.getWidth()/2); @@ -70,6 +71,9 @@ public class SubMenuConfigScreen extends ConfigScreen { if (value instanceof Boolean) { BooleanEntry entry = new BooleanEntry(humanKey, (ForgeConfigSpec.ConfigValue) configValue, valueSpec); list.children().add(entry); + } else if (value instanceof Enum) { + EnumEntry entry = new EnumEntry(humanKey, (ForgeConfigSpec.ConfigValue>) configValue, valueSpec); + list.children().add(entry); } else if (value instanceof Number) { NumberEntry entry = NumberEntry.create(value, humanKey, configValue, valueSpec); if (entry != null) { 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 f1426be76..3d620607b 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 @@ -58,9 +58,10 @@ public class BooleanEntry extends ValueEntry { } @Override - protected void onReset() { - super.onReset(); + protected void onValueChange() { + super.onValueChange(); buttonStencil.withSecond(value.get() ? enabled : disabled); + bumpCog(value.get() ? 15f : -16f); } /*@Override 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 new file mode 100644 index 000000000..ceff6eead --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java @@ -0,0 +1,75 @@ +package com.simibubi.create.foundation.config.ui.entries; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.ui.ConfigButton; +import com.simibubi.create.foundation.gui.TextStencilElement; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.common.ForgeConfigSpec; + +public class EnumEntry extends ValueEntry> { + + protected static final int cycleWidth = 34;//including 2px offset on either side + + protected TextStencilElement valueText; + protected ConfigButton cycleLeft; + protected ConfigButton cycleRight; + + public EnumEntry(String label, ForgeConfigSpec.ConfigValue> value, ForgeConfigSpec.ValueSpec spec) { + super(label, value, spec); + + valueText = new TextStencilElement(Minecraft.getInstance().fontRenderer, "YEP").centered(true, true); + + TextStencilElement l = new TextStencilElement(Minecraft.getInstance().fontRenderer, "<").centered(true, true); + cycleLeft = ConfigButton.createAndInjectElementRenderer(0, 0, l).withBounds(30, 30).withCallback(() -> cycleValue(-1)); + + TextStencilElement r = new TextStencilElement(Minecraft.getInstance().fontRenderer, ">").centered(true, true); + cycleRight = ConfigButton.createAndInjectElementRenderer(0, 0, r).withBounds(30, 30).withCallback(() -> cycleValue(1)); + + listeners.add(cycleLeft); + listeners.add(cycleRight); + + onReset(); + } + + protected void cycleValue(int direction) { + Enum e = value.get(); + Enum[] options = e.getDeclaringClass().getEnumConstants(); + e = options[Math.floorMod(e.ordinal() + direction, options.length)]; + value.set(e); + bumpCog(direction * 15f); + onValueChange(); + } + + @Override + public void tick() { + super.tick(); + cycleLeft.tick(); + cycleRight.tick(); + } + + @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); + + cycleLeft.x = x + getLabelWidth(width) + 2; + cycleLeft.y = y + 10; + cycleLeft.render(ms, mouseX, mouseY, partialTicks); + + valueText + .at(cycleLeft.x - 2 + cycleWidth, y + 10, 0) + .withBounds(width - getLabelWidth(width) - 2 * cycleWidth - resetWidth, 30) + .render(ms); + + cycleRight.x = x + width - cycleWidth - resetWidth + 2; + cycleRight.y = y + 10; + cycleRight.render(ms, mouseX, mouseY, partialTicks); + + } + + @Override + protected void onValueChange() { + super.onValueChange(); + valueText.withText(value.get().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 8569a1a10..b1d3b9a9a 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 @@ -83,7 +83,7 @@ public abstract class NumberEntry extends ValueEntry { } protected String formatBound(T bound) { - String sci = String.format("%.2E", bound); + String sci = String.format("%.2E", bound.doubleValue()); String str = String.valueOf(bound); return sci.length() < str.length() ? sci : str; } 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 28f5762d1..661db2a3b 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 @@ -41,6 +41,11 @@ public class SubMenuEntry extends ConfigScreenList.LabeledEntry { button.render(ms, mouseX, mouseY, partialTicks); } + @Override + protected int getLabelWidth(int totalWidth) { + return (int) (totalWidth * labelWidthMult); + } + /*@Override public boolean mouseClicked(double p_231044_1_, double p_231044_3_, int p_231044_5_) { return button.mouseClicked(p_231044_1_, p_231044_3_, p_231044_5_); 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 bde5066dc..504fce2e0 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 @@ -10,7 +10,7 @@ import net.minecraftforge.common.ForgeConfigSpec; public class ValueEntry extends ConfigScreenList.LabeledEntry { - protected static final int resetWidth = 24;//including 2px offset on each side + protected static final int resetWidth = 24;//including 2px offset on either side protected ForgeConfigSpec.ConfigValue value; protected ForgeConfigSpec.ValueSpec spec; @@ -46,6 +46,11 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { reset.render(ms, mouseX, mouseY, partialTicks); } + @Override + protected int getLabelWidth(int totalWidth) { + return (int) (totalWidth * labelWidthMult); + } + /*@Override public boolean mouseClicked(double mX, double mY, int button) { return reset.mouseClicked(mX, mY, button); @@ -59,4 +64,10 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { reset.active = !value.get().equals(spec.getDefault()); reset.animateGradientFromState(); } + + protected void bumpCog() {bumpCog(10f);} + protected void bumpCog(float force) { + if (list != null && list instanceof ConfigScreenList) + ((ConfigScreenList) list).bumpCog(force); + } } From 01e5b812c2c68e1c128c9382f5af2d275223d465 Mon Sep 17 00:00:00 2001 From: zelophed Date: Thu, 15 Apr 2021 15:44:26 +0200 Subject: [PATCH 09/17] changing the server --- .../foundation/command/ConfigCommand.java | 2 +- .../command/FabulousWarningCommand.java | 2 +- .../command/FixLightingCommand.java | 2 +- .../command/OverlayConfigCommand.java | 8 +- .../foundation/command/PonderCommand.java | 2 +- ...acket.java => SConfigureConfigPacket.java} | 8 +- .../command/ToggleDebugCommand.java | 2 +- .../ToggleExperimentalRenderingCommand.java | 2 +- .../config/ui/BaseConfigScreen.java | 2 +- .../config/ui/CConfigureConfigPacket.java | 83 +++++++++++++++++++ .../foundation/config/ui/ConfigScreen.java | 17 +++- .../config/ui/ConfigScreenList.java | 14 +++- .../config/ui/ServerSubMenuConfigScreen.java | 52 ++++++++++++ .../config/ui/entries/BooleanEntry.java | 7 ++ .../config/ui/entries/EnumEntry.java | 9 ++ .../config/ui/entries/NumberEntry.java | 10 ++- .../config/ui/entries/SubMenuEntry.java | 6 +- .../config/ui/entries/ValueEntry.java | 25 ++++-- .../foundation/networking/AllPackets.java | 6 +- 19 files changed, 230 insertions(+), 29 deletions(-) rename src/main/java/com/simibubi/create/foundation/command/{ConfigureConfigPacket.java => SConfigureConfigPacket.java} (96%) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/CConfigureConfigPacket.java create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/ServerSubMenuConfigScreen.java diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java b/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java index 94b82a269..24a45110a 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/ConfigCommand.java @@ -17,7 +17,7 @@ public class ConfigCommand { ServerPlayerEntity player = ctx.getSource().asPlayer(); AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> player), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.configScreen.name(), "") + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.configScreen.name(), "") ); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/com/simibubi/create/foundation/command/FabulousWarningCommand.java b/src/main/java/com/simibubi/create/foundation/command/FabulousWarningCommand.java index 9a417a1a4..a52b24fca 100644 --- a/src/main/java/com/simibubi/create/foundation/command/FabulousWarningCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/FabulousWarningCommand.java @@ -19,7 +19,7 @@ public class FabulousWarningCommand { AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> player), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fabulousWarning.name(), "") + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fabulousWarning.name(), "") ); return Command.SINGLE_SUCCESS; diff --git a/src/main/java/com/simibubi/create/foundation/command/FixLightingCommand.java b/src/main/java/com/simibubi/create/foundation/command/FixLightingCommand.java index 7a128bced..4557c07ad 100644 --- a/src/main/java/com/simibubi/create/foundation/command/FixLightingCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/FixLightingCommand.java @@ -17,7 +17,7 @@ public class FixLightingCommand { .executes(ctx -> { AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource() .getEntity()), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true))); + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true))); ctx.getSource() .sendFeedback( diff --git a/src/main/java/com/simibubi/create/foundation/command/OverlayConfigCommand.java b/src/main/java/com/simibubi/create/foundation/command/OverlayConfigCommand.java index 850b910e5..f66d84f90 100644 --- a/src/main/java/com/simibubi/create/foundation/command/OverlayConfigCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/OverlayConfigCommand.java @@ -18,12 +18,12 @@ public class OverlayConfigCommand { .requires(cs -> cs.hasPermissionLevel(0)) .then(Commands.literal("reset") .executes(ctx -> { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.overlayReset.performAction("")); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayReset.performAction("")); DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayReset.name(), ""))); + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayReset.name(), ""))); ctx.getSource().sendFeedback(new StringTextComponent("reset overlay offset"), true); @@ -31,12 +31,12 @@ public class OverlayConfigCommand { }) ) .executes(ctx -> { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.overlayScreen.performAction("")); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayScreen.performAction("")); DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayScreen.name(), ""))); + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayScreen.name(), ""))); ctx.getSource().sendFeedback(new StringTextComponent("window opened"), true); diff --git a/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java b/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java index f4e2cfb90..0ed417490 100644 --- a/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/PonderCommand.java @@ -48,7 +48,7 @@ public class PonderCommand { AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> player), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.openPonder.name(), sceneId)); + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.openPonder.name(), sceneId)); } return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/command/SConfigureConfigPacket.java similarity index 96% rename from src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java rename to src/main/java/com/simibubi/create/foundation/command/SConfigureConfigPacket.java index b84fed0a1..b6159302e 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ConfigureConfigPacket.java +++ b/src/main/java/com/simibubi/create/foundation/command/SConfigureConfigPacket.java @@ -30,17 +30,17 @@ import org.apache.logging.log4j.LogManager; import java.util.function.Consumer; import java.util.function.Supplier; -public class ConfigureConfigPacket extends SimplePacketBase { +public class SConfigureConfigPacket extends SimplePacketBase { private final String option; private final String value; - public ConfigureConfigPacket(String option, String value) { + public SConfigureConfigPacket(String option, String value) { this.option = option; this.value = value; } - public ConfigureConfigPacket(PacketBuffer buffer) { + public SConfigureConfigPacket(PacketBuffer buffer) { this.option = buffer.readString(32767); this.value = buffer.readString(32767); } @@ -68,7 +68,7 @@ public class ConfigureConfigPacket extends SimplePacketBase { .setPacketHandled(true); } - enum Actions { + public enum Actions { configScreen(() -> Actions::configScreen), rainbowDebug(() -> Actions::rainbowDebug), overlayScreen(() -> Actions::overlayScreen), diff --git a/src/main/java/com/simibubi/create/foundation/command/ToggleDebugCommand.java b/src/main/java/com/simibubi/create/foundation/command/ToggleDebugCommand.java index d8953c8f1..bb6a70c34 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ToggleDebugCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/ToggleDebugCommand.java @@ -14,7 +14,7 @@ public class ToggleDebugCommand extends ConfigureConfigCommand { protected void sendPacket(ServerPlayerEntity player, String option) { AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> player), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), option) + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.rainbowDebug.name(), option) ); } } diff --git a/src/main/java/com/simibubi/create/foundation/command/ToggleExperimentalRenderingCommand.java b/src/main/java/com/simibubi/create/foundation/command/ToggleExperimentalRenderingCommand.java index e80862f33..bc0a17b5d 100644 --- a/src/main/java/com/simibubi/create/foundation/command/ToggleExperimentalRenderingCommand.java +++ b/src/main/java/com/simibubi/create/foundation/command/ToggleExperimentalRenderingCommand.java @@ -14,7 +14,7 @@ public class ToggleExperimentalRenderingCommand extends ConfigureConfigCommand { protected void sendPacket(ServerPlayerEntity player, String option) { AllPackets.channel.send( PacketDistributor.PLAYER.with(() -> player), - new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), option) + new SConfigureConfigPacket(SConfigureConfigPacket.Actions.experimentalRendering.name(), option) ); } } 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 f3975142e..6c79e3fe9 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 @@ -56,7 +56,7 @@ public class BaseConfigScreen extends ConfigScreen { ); if (Minecraft.getInstance().world != null) { - serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.SERVER.specification))); + serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new ServerSubMenuConfigScreen(this, AllConfigs.SERVER.specification))); } else { serverConfigWidget.active = false; serverConfigWidget.updateColorsFromState(); diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/CConfigureConfigPacket.java b/src/main/java/com/simibubi/create/foundation/config/ui/CConfigureConfigPacket.java new file mode 100644 index 000000000..c1a475d29 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/CConfigureConfigPacket.java @@ -0,0 +1,83 @@ +package com.simibubi.create.foundation.config.ui; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.command.SConfigureConfigPacket; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.network.NetworkEvent; +import net.minecraftforge.fml.network.PacketDistributor; + +public class CConfigureConfigPacket extends SimplePacketBase { + + private String path; + private String value; + + public CConfigureConfigPacket(String path, T value) { + this.path = path; + this.value = serialize(value); + } + + public CConfigureConfigPacket(PacketBuffer buffer) { + this.path = buffer.readString(32767); + this.value = buffer.readString(32767); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeString(path); + buffer.writeString(value); + } + + @Override + public void handle(Supplier context) { + ServerPlayerEntity sender = context.get().getSender(); + if (sender == null || !sender.hasPermissionLevel(2)) + return; + + ForgeConfigSpec.ValueSpec valueSpec = AllConfigs.SERVER.specification.getRaw(path); + ForgeConfigSpec.ConfigValue configValue = AllConfigs.SERVER.specification.getValues().get(path); + + T v = (T) deserialize(configValue.get(), value); + if (!valueSpec.test(v)) + return; + + configValue.set(v); + + } + + public String serialize(T value) { + if (value instanceof Boolean) + return Boolean.toString((Boolean) value); + if (value instanceof Enum) + return ((Enum) value).name(); + if (value instanceof Integer) + return Integer.toString((Integer) value); + if (value instanceof Float) + return Float.toString((Float) value); + if (value instanceof Double) + return Double.toString((Double) value); + + throw new IllegalArgumentException("unknown type " + value + ": " + value.getClass().getSimpleName()); + } + + public Object deserialize(Object type, String sValue) { + if (type instanceof Boolean) + return Boolean.parseBoolean(sValue); + if (type instanceof Enum) + return Enum.valueOf(((Enum) type).getClass(), sValue); + if (type instanceof Integer) + return Integer.parseInt(sValue); + if (type instanceof Float) + return Float.parseFloat(sValue); + if (type instanceof Double) + return Double.parseDouble(sValue); + + throw new IllegalArgumentException("unknown type " + type + ": " + type.getClass().getSimpleName()); + } +} 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 8f854c63e..3309f81e8 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 @@ -25,7 +25,22 @@ import com.simibubi.create.foundation.utility.animation.PhysicalFloat; public abstract class ConfigScreen extends NavigatableSimiScreen { - private final Screen parent; + /* + * TODO unable to edit feedback message + * TODO overlays for better descriptions + * TODO units at the end of the text box + * TODO match style with ponderUI + * TODO cache changes before setting values and saving to file + * TODO don't exit on ESC + * TODO reset text field focus for any click inside screen + * TODO adjust transition animation of screens + * TODO allow backspace in text fields + * + * TODO some color themes maybe? + * + * */ + + 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); 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 c4af6fbeb..410144bc9 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 @@ -1,7 +1,6 @@ package com.simibubi.create.foundation.config.ui; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import com.mojang.blaze3d.matrix.MatrixStack; @@ -13,11 +12,16 @@ import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.list.ExtendedList; import net.minecraft.util.text.IFormattableTextComponent; public class ConfigScreenList extends ExtendedList { + public TextFieldWidget currentText; + + public boolean isForServer = false; + public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) { super(client, width, height, top, bottom, elementHeight); func_244605_b(false); @@ -87,6 +91,14 @@ public class ConfigScreenList extends ExtendedList { public boolean charTyped(char ch, int code) { return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code)); } + + protected void setEditable(boolean b) {} + + protected boolean isForServer() { + if (list == null) + return false; + return ((ConfigScreenList) list).isForServer; + } } public static class LabeledEntry extends Entry { 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 new file mode 100644 index 000000000..023cd9ddb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ServerSubMenuConfigScreen.java @@ -0,0 +1,52 @@ +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/entries/BooleanEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/BooleanEntry.java index 3d620607b..e09c153a0 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 @@ -42,6 +42,13 @@ public class BooleanEntry extends ValueEntry { onReset(); } + @Override + protected void setEditable(boolean b) { + super.setEditable(b); + button.active = b; + button.animateGradientFromState(); + } + @Override public void tick() { super.tick(); 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 ceff6eead..798a57bd2 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 @@ -41,6 +41,15 @@ public class EnumEntry extends ValueEntry> { onValueChange(); } + @Override + protected void setEditable(boolean b) { + super.setEditable(b); + cycleLeft.active = b; + cycleLeft.animateGradientFromState(); + cycleRight.active = b; + cycleRight.animateGradientFromState(); + } + @Override public void tick() { super.tick(); 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 b1d3b9a9a..2810fcd79 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 @@ -59,8 +59,8 @@ public abstract class NumberEntry extends ValueEntry { maxText = new TextStencilElement(font, t).centered(true, false); maxOffset = font.getWidth(t); } - } catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) { - e.printStackTrace(); + } catch (NoSuchFieldException | IllegalAccessException | ClassCastException | NullPointerException ignored) { + } textField.setResponder(s -> { @@ -94,6 +94,12 @@ public abstract class NumberEntry extends ValueEntry { protected abstract Function getParser(); + @Override + protected void setEditable(boolean b) { + super.setEditable(b); + textField.setEnabled(b); + } + @Override protected void onReset() { super.onReset(); 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 661db2a3b..e0679dc68 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,6 +4,7 @@ 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; @@ -20,7 +21,10 @@ public class SubMenuEntry extends ConfigScreenList.LabeledEntry { super(label); TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true); button = ConfigButton.createFromStencilElement(0, 0, text) - .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(parent, spec, config))); + .withCallback(() -> ScreenOpener.transitionTo(isForServer() ? + new ServerSubMenuConfigScreen(parent, spec, config) : + new SubMenuConfigScreen(parent, spec, config) + )); 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 504fce2e0..b352fdba4 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 @@ -1,9 +1,11 @@ package com.simibubi.create.foundation.config.ui.entries; 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.ConfigScreenList; import com.simibubi.create.foundation.gui.TextStencilElement; +import com.simibubi.create.foundation.networking.AllPackets; import net.minecraft.client.Minecraft; import net.minecraftforge.common.ForgeConfigSpec; @@ -15,6 +17,7 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { protected ForgeConfigSpec.ConfigValue value; protected ForgeConfigSpec.ValueSpec spec; protected ConfigButton reset; + protected boolean editable = true; public ValueEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { super(label); @@ -32,6 +35,13 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { listeners.add(reset); } + @Override + protected void setEditable(boolean b) { + editable = b; + reset.active = editable && !value.get().equals(spec.getDefault()); + reset.animateGradientFromState(); + } + @Override public void tick() { reset.tick(); @@ -51,23 +61,24 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { return (int) (totalWidth * labelWidthMult); } - /*@Override - public boolean mouseClicked(double mX, double mY, int button) { - return reset.mouseClicked(mX, mY, button); - }*/ - protected void onReset() { onValueChange(); } protected void onValueChange() { - reset.active = !value.get().equals(spec.getDefault()); + reset.active = editable && !value.get().equals(spec.getDefault()); reset.animateGradientFromState(); + + if (!isForServer()) + return; + + String path = String.join(".", value.getPath()); + AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value.get())); } protected void bumpCog() {bumpCog(10f);} protected void bumpCog(float force) { if (list != null && list instanceof ConfigScreenList) - ((ConfigScreenList) list).bumpCog(force); + ((ConfigScreenList) list).bumpCog(force); } } diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index da35f421f..44d39c6df 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -38,8 +38,9 @@ import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; -import com.simibubi.create.foundation.command.ConfigureConfigPacket; +import com.simibubi.create.foundation.command.SConfigureConfigPacket; import com.simibubi.create.foundation.command.HighlightPacket; +import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; import com.simibubi.create.foundation.utility.ServerSpeedProvider; @@ -79,12 +80,13 @@ public enum AllPackets { PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER), TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER), EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER), + C_CONFIGURE_CONFIG(CConfigureConfigPacket.class, CConfigureConfigPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT), BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT), - CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT), + S_CONFIGURE_CONFIG(SConfigureConfigPacket.class, SConfigureConfigPacket::new, PLAY_TO_CLIENT), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT), CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT), GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT), From 6b80ea1d04a77a14d2e19a6a5f903f48dba6a0e3 Mon Sep 17 00:00:00 2001 From: zelophed Date: Fri, 16 Apr 2021 01:50:35 +0200 Subject: [PATCH 10/17] units and tooltips --- .../foundation/config/ui/ConfigScreen.java | 18 ++++---- .../config/ui/ConfigScreenList.java | 36 +++++++++++++--- .../foundation/config/ui/ConfigTextField.java | 33 +++++++++++++++ .../config/ui/SubMenuConfigScreen.java | 12 +++--- .../config/ui/entries/NumberEntry.java | 6 +-- .../config/ui/entries/ValueEntry.java | 41 +++++++++++++++++++ 6 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java 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 3309f81e8..4f4f0d9b2 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,15 +1,12 @@ package com.simibubi.create.foundation.config.ui; -import net.minecraft.block.BlockState; -import net.minecraft.client.gui.AbstractGui; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.util.Direction; -import net.minecraftforge.common.ForgeConfigSpec; - import java.util.Arrays; import java.util.stream.Collectors; + import javax.annotation.Nonnull; + import org.apache.commons.lang3.StringUtils; + import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; @@ -17,18 +14,17 @@ import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; 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.gui.UIRenderHelper; -import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import com.simibubi.create.foundation.ponder.NavigatableSimiScreen; import com.simibubi.create.foundation.utility.animation.Force; import com.simibubi.create.foundation.utility.animation.PhysicalFloat; +import net.minecraft.block.BlockState; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.util.Direction; + public abstract class ConfigScreen extends NavigatableSimiScreen { /* - * TODO unable to edit feedback message - * TODO overlays for better descriptions - * TODO units at the end of the text box * TODO match style with ponderUI * TODO cache changes before setting values and saving to file * TODO don't exit on ESC 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 410144bc9..f7268306b 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 @@ -1,8 +1,11 @@ package com.simibubi.create.foundation.config.ui; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import org.lwjgl.opengl.GL11; + import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.TextStencilElement; @@ -12,9 +15,13 @@ import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.IGuiEventListener; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.list.ExtendedList; import net.minecraft.util.text.IFormattableTextComponent; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.fml.client.gui.GuiUtils; public class ConfigScreenList extends ExtendedList { @@ -71,12 +78,6 @@ public class ConfigScreenList extends ExtendedList { listeners = new ArrayList<>(); } - public void tick() {} - - public List getGuiListeners() { - return listeners; - } - @Override public boolean mouseClicked(double x, double y, int button) { return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button)); @@ -92,6 +93,12 @@ public class ConfigScreenList extends ExtendedList { return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code)); } + public void tick() {} + + public List getGuiListeners() { + return listeners; + } + protected void setEditable(boolean b) {} protected boolean isForServer() { @@ -106,9 +113,11 @@ public class ConfigScreenList extends ExtendedList { protected static final float labelWidthMult = 0.4f; protected TextStencilElement label; + protected List labelTooltip; public LabeledEntry(String label) { this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label); + labelTooltip = new ArrayList<>(); } @Override @@ -119,6 +128,21 @@ public class ConfigScreenList extends ExtendedList { label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, getLabelWidth(width) - 15).getString() + "..."); } label.at(x + 5, y + height/2 - 4, 0).render(ms); + + if (mouseX > x && mouseX < x + getLabelWidth(width) && mouseY > y + 5 && mouseY < y + height - 5) { + List tooltip = getLabelTooltip(); + if (tooltip.isEmpty()) + return; + + GL11.glDisable(GL11.GL_SCISSOR_TEST); + Screen screen = Minecraft.getInstance().currentScreen; + GuiUtils.drawHoveringText(ms, tooltip, mouseX, mouseY, screen.width, screen.height, 300, Minecraft.getInstance().fontRenderer); + GL11.glEnable(GL11.GL_SCISSOR_TEST); + } + } + + public List getLabelTooltip() { + return labelTooltip; } protected int getLabelWidth(int totalWidth) { 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 new file mode 100644 index 000000000..27655f40b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigTextField.java @@ -0,0 +1,33 @@ +package com.simibubi.create.foundation.config.ui; + +import com.mojang.blaze3d.matrix.MatrixStack; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.util.text.StringTextComponent; + +public class ConfigTextField extends TextFieldWidget { + + protected FontRenderer font; + protected String unit; + + public ConfigTextField(FontRenderer font, int x, int y, int width, int height, String unit) { + super(font, x, y, width, height, StringTextComponent.EMPTY); + this.font = font; + this.unit = unit; + } + + @Override + public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + super.renderButton(ms, mouseX, mouseY, partialTicks); + + if (unit == null || unit.isEmpty()) + return; + + int unitWidth = font.getStringWidth(unit); + if (this.font.getStringWidth(getText()) > (getAdjustedWidth() - unitWidth)) + return; + + font.draw(ms, unit, x + getAdjustedWidth() - unitWidth, this.y + (this.height - 8) / 2, 0xcc_aaaaaa); + } +} 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 a0c4f967f..7d9c2767d 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 @@ -97,17 +97,15 @@ public class SubMenuConfigScreen extends ConfigScreen { list.render(ms, mouseX, mouseY, partialTicks); } + @Override + protected void renderWindowForeground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + super.renderWindowForeground(ms, mouseX, mouseY, partialTicks); + } + @Override public void resize(@Nonnull Minecraft client, int width, int height) { double scroll = list.getScrollAmount(); init(client, width, height); list.setScrollAmount(scroll); } - - public static AbstractSimiWidget createWidgetForValue(ForgeConfigSpec.ConfigValue configValue, ForgeConfigSpec.ValueSpec valueSpec, Object value, String key, SubMenuConfigScreen parent) { - String title = toHumanReadable(key); - title += " : " + value; - TextStencilElement text = new TextStencilElement(parent.client.fontRenderer, title).at(5, 11, 0); - return ConfigButton.createFromStencilElement(parent.width/2 - 100, 0, text); - } } 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 2810fcd79..f7dedaa15 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 @@ -6,6 +6,7 @@ import java.util.function.Function; import javax.annotation.Nullable; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.config.ui.ConfigTextField; import com.simibubi.create.foundation.gui.TextStencilElement; import net.minecraft.client.Minecraft; @@ -18,6 +19,7 @@ public abstract class NumberEntry extends ValueEntry { protected int minOffset = 0, maxOffset = 0; protected TextStencilElement minText = null, maxText = null; + protected TextFieldWidget textField; @Nullable public static NumberEntry create(Object type, String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { @@ -32,11 +34,9 @@ public abstract class NumberEntry extends ValueEntry { return null; } - protected TextFieldWidget textField; - public NumberEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { super(label, value, spec); - textField = new TextFieldWidget(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, StringTextComponent.EMPTY); + textField = new ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, unit); textField.setText(String.valueOf(value.get())); Object range = spec.getRange(); 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 b352fdba4..d4315966d 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 @@ -1,5 +1,13 @@ package com.simibubi.create.foundation.config.ui.entries; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +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; @@ -8,16 +16,20 @@ import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.networking.AllPackets; import net.minecraft.client.Minecraft; +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 int resetWidth = 24;//including 2px offset on either side + public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]"); protected ForgeConfigSpec.ConfigValue value; protected ForgeConfigSpec.ValueSpec spec; protected ConfigButton reset; protected boolean editable = true; + protected String unit = null; public ValueEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec spec) { super(label); @@ -33,6 +45,35 @@ public class ValueEntry extends ConfigScreenList.LabeledEntry { }); listeners.add(reset); + List path = value.getPath(); + labelTooltip.add(new StringTextComponent(path.get(path.size()-1)).formatted(TextFormatting.GRAY)); + String comment = spec.getComment(); + if (comment == null || comment.isEmpty()) + return; + String[] commentLines = comment.split("\n"); + //find unit in the comment + for (int i = 0; i < commentLines.length; i++) { + if (commentLines[i].isEmpty()) { + commentLines = ArrayUtils.remove(commentLines, i); + i--; + continue; + } + + Matcher matcher = unitPattern.matcher(commentLines[i]); + if (!matcher.matches()) + continue; + + String u = matcher.group(1); + if (u.equals("in Revolutions per Minute")) + u = "in RPM"; + if (u.equals("in Stress Units")) + u = "in SU"; + unit = u; + commentLines = ArrayUtils.remove(commentLines, i); + break; + } + //add comment to tooltip + labelTooltip.addAll(Arrays.stream(commentLines).map(StringTextComponent::new).collect(Collectors.toList())); } @Override From f0dfc5a6bc2ebc671958e23161ba181814247675 Mon Sep 17 00:00:00 2001 From: zelophed Date: Fri, 16 Apr 2021 04:22:38 +0200 Subject: [PATCH 11/17] align style with ponderUI --- .../config/ui/BaseConfigScreen.java | 63 +++++++------------ .../foundation/config/ui/ConfigButton.java | 2 +- .../foundation/config/ui/ConfigScreen.java | 31 ++++++--- .../config/ui/ConfigScreenList.java | 48 +++----------- .../config/ui/SubMenuConfigScreen.java | 16 +++-- .../config/ui/entries/BooleanEntry.java | 31 ++++----- .../config/ui/entries/EnumEntry.java | 2 + .../config/ui/entries/NumberEntry.java | 4 ++ .../config/ui/entries/SubMenuEntry.java | 26 ++++---- .../config/ui/entries/ValueEntry.java | 38 +++++------ .../gui/widgets/AbstractSimiWidget.java | 5 ++ .../foundation/ponder/ui/PonderButton.java | 6 ++ 12 files changed, 122 insertions(+), 150 deletions(-) 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 6c79e3fe9..545548153 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 @@ -1,10 +1,10 @@ package com.simibubi.create.foundation.config.ui; -import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.ScreenOpener; -import com.simibubi.create.foundation.gui.StencilElement; import com.simibubi.create.foundation.gui.TextStencilElement; +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; @@ -13,9 +13,9 @@ import net.minecraft.util.text.TextFormatting; public class BaseConfigScreen extends ConfigScreen { - ConfigButton clientConfigWidget; - ConfigButton commonConfigWidget; - ConfigButton serverConfigWidget; + PonderButton clientConfigWidget; + PonderButton commonConfigWidget; + PonderButton serverConfigWidget; public BaseConfigScreen(Screen parent) { super(parent); @@ -26,48 +26,31 @@ public class BaseConfigScreen extends ConfigScreen { widgets.clear(); super.init(); - StencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); - widgets.add(clientConfigWidget = ConfigButton.createFromStencilElement( - width / 2 - 100, - height / 2 - 15 - 50, - text - ) - .withBounds(200, 30) - .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.CLIENT.specification))) - ); + 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)); + }, 200, 30).showingUnscaled(text)); + clientConfigWidget.fade(1); - StencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); - widgets.add(commonConfigWidget = ConfigButton.createFromStencilElement( - width / 2 - 100, - height / 2 - 15, - text2 - ) - .withBounds(200, 30) - .withCallback(() -> ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.COMMON.specification))) - ); + 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)); + }, 200, 30).showingUnscaled(text2)); + commonConfigWidget.fade(1); - StencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); - widgets.add(serverConfigWidget = ConfigButton.createFromStencilElement( - width / 2 - 100, - height / 2 - 15 + 50, - text3 - ) - .withBounds(200, 30) - ); + TextStencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("SERVER CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); + text3.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(serverConfigWidget = new PonderButton(width / 2 - 100, height / 2 - 15 + 50, (_$, _$$) -> { + }, 200, 30).showingUnscaled(text3)); + serverConfigWidget.fade(1); if (Minecraft.getInstance().world != null) { serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new ServerSubMenuConfigScreen(this, AllConfigs.SERVER.specification))); } else { serverConfigWidget.active = false; - serverConfigWidget.updateColorsFromState(); + text3.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_disable_1, ConfigButton.Palette.button_disable_2)); } } - - @Override - protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { - super.renderWindow(ms, mouseX, mouseY, partialTicks); - - - //