units and tooltips

This commit is contained in:
zelophed 2021-04-16 01:50:35 +02:00
parent 01e5b812c2
commit 6b80ea1d04
6 changed files with 119 additions and 27 deletions

View file

@ -1,15 +1,12 @@
package com.simibubi.create.foundation.config.ui; 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.Arrays;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlocks; 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.GuiGameElement;
import com.simibubi.create.foundation.gui.StencilElement; import com.simibubi.create.foundation.gui.StencilElement;
import com.simibubi.create.foundation.gui.TextStencilElement; 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.ponder.NavigatableSimiScreen;
import com.simibubi.create.foundation.utility.animation.Force; import com.simibubi.create.foundation.utility.animation.Force;
import com.simibubi.create.foundation.utility.animation.PhysicalFloat; 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 { 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 match style with ponderUI
* TODO cache changes before setting values and saving to file * TODO cache changes before setting values and saving to file
* TODO don't exit on ESC * TODO don't exit on ESC

View file

@ -1,8 +1,11 @@
package com.simibubi.create.foundation.config.ui; package com.simibubi.create.foundation.config.ui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.TextStencilElement; 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.MainWindow;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IGuiEventListener; 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.TextFieldWidget;
import net.minecraft.client.gui.widget.list.ExtendedList; import net.minecraft.client.gui.widget.list.ExtendedList;
import net.minecraft.util.text.IFormattableTextComponent; 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<ConfigScreenList.Entry> { public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
@ -71,12 +78,6 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
listeners = new ArrayList<>(); listeners = new ArrayList<>();
} }
public void tick() {}
public List<IGuiEventListener> getGuiListeners() {
return listeners;
}
@Override @Override
public boolean mouseClicked(double x, double y, int button) { public boolean mouseClicked(double x, double y, int button) {
return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button)); return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button));
@ -92,6 +93,12 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code)); return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code));
} }
public void tick() {}
public List<IGuiEventListener> getGuiListeners() {
return listeners;
}
protected void setEditable(boolean b) {} protected void setEditable(boolean b) {}
protected boolean isForServer() { protected boolean isForServer() {
@ -106,9 +113,11 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
protected static final float labelWidthMult = 0.4f; protected static final float labelWidthMult = 0.4f;
protected TextStencilElement label; protected TextStencilElement label;
protected List<ITextComponent> labelTooltip;
public LabeledEntry(String label) { public LabeledEntry(String label) {
this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label); this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label);
labelTooltip = new ArrayList<>();
} }
@Override @Override
@ -119,6 +128,21 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, getLabelWidth(width) - 15).getString() + "..."); label.withText(Minecraft.getInstance().fontRenderer.trimToWidth(component, getLabelWidth(width) - 15).getString() + "...");
} }
label.at(x + 5, y + height/2 - 4, 0).render(ms); 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<ITextComponent> 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<ITextComponent> getLabelTooltip() {
return labelTooltip;
} }
protected int getLabelWidth(int totalWidth) { protected int getLabelWidth(int totalWidth) {

View file

@ -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);
}
}

View file

@ -97,17 +97,15 @@ public class SubMenuConfigScreen extends ConfigScreen {
list.render(ms, mouseX, mouseY, partialTicks); 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 @Override
public void resize(@Nonnull Minecraft client, int width, int height) { public void resize(@Nonnull Minecraft client, int width, int height) {
double scroll = list.getScrollAmount(); double scroll = list.getScrollAmount();
init(client, width, height); init(client, width, height);
list.setScrollAmount(scroll); 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);
}
} }

View file

@ -6,6 +6,7 @@ import java.util.function.Function;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.config.ui.ConfigTextField;
import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.TextStencilElement;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -18,6 +19,7 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
protected int minOffset = 0, maxOffset = 0; protected int minOffset = 0, maxOffset = 0;
protected TextStencilElement minText = null, maxText = null; protected TextStencilElement minText = null, maxText = null;
protected TextFieldWidget textField;
@Nullable @Nullable
public static NumberEntry<? extends Number> create(Object type, String label, ForgeConfigSpec.ConfigValue<?> value, ForgeConfigSpec.ValueSpec spec) { public static NumberEntry<? extends Number> create(Object type, String label, ForgeConfigSpec.ConfigValue<?> value, ForgeConfigSpec.ValueSpec spec) {
@ -32,11 +34,9 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
return null; return null;
} }
protected TextFieldWidget textField;
public NumberEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) { public NumberEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
super(label, value, 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())); textField.setText(String.valueOf(value.get()));
Object range = spec.getRange(); Object range = spec.getRange();

View file

@ -1,5 +1,13 @@
package com.simibubi.create.foundation.config.ui.entries; 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.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket; import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
import com.simibubi.create.foundation.config.ui.ConfigButton; 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 com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
public class ValueEntry<T> extends ConfigScreenList.LabeledEntry { public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
protected static final int resetWidth = 24;//including 2px offset on either side protected static final int resetWidth = 24;//including 2px offset on either side
public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]");
protected ForgeConfigSpec.ConfigValue<T> value; protected ForgeConfigSpec.ConfigValue<T> value;
protected ForgeConfigSpec.ValueSpec spec; protected ForgeConfigSpec.ValueSpec spec;
protected ConfigButton reset; protected ConfigButton reset;
protected boolean editable = true; protected boolean editable = true;
protected String unit = null;
public ValueEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) { public ValueEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
super(label); super(label);
@ -33,6 +45,35 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
}); });
listeners.add(reset); listeners.add(reset);
List<String> 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 @Override