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