mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
units and tooltips
This commit is contained in:
parent
01e5b812c2
commit
6b80ea1d04
6 changed files with 119 additions and 27 deletions
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue