Update all the UI Library code

This commit is contained in:
Sollace 2019-04-14 13:32:01 +02:00
parent 84dff59a33
commit 85e346b378
21 changed files with 46 additions and 751 deletions

View file

@ -53,12 +53,6 @@ description = project.displayname
archivesBaseName = project.name
sourceSets {
common {
// code shared between HDSkins and MineLP mods
// TODO: Make this into a library? I mean, it's not a lot.
compileClasspath += main.compileClasspath
}
client {
// Client-only code
compileClasspath += main.compileClasspath
@ -67,17 +61,6 @@ sourceSets {
ext.refMap = 'minelp.mixin.refmap.json'
}
main {
// Non-client code. Called main because gradle calls it that
// TODO: HorseLib.java
compileClasspath += common.output
}
// Litemod stuff, separated for future removal
litemod {
compileClasspath += main.compileClasspath
compileClasspath += main.output
compileClasspath += client.output
}
fml {
@ -86,6 +69,8 @@ sourceSets {
compileClasspath += client.output
}
// TODO: Disable the hidden "test" sourceset
// TODO: Disable the resources folders for sourcesets that don't need them
}
minecraft {
@ -129,6 +114,7 @@ repositories {
dependencies {
// TODO: Add HDSkins as a dependency. It won't compile without it.
// TODO: Add KirinUI as a dependency.
minecraft 'net.minecraftforge:forge:1.13.2-25.0.90'

View file

@ -7,9 +7,9 @@ import com.minelittlepony.client.render.entities.MobRenderers;
import com.minelittlepony.common.client.gui.GameGui;
import com.minelittlepony.common.client.gui.GuiHost;
import com.minelittlepony.common.client.gui.IGuiGuest;
import com.minelittlepony.common.client.gui.Label;
import com.minelittlepony.common.client.gui.Slider;
import com.minelittlepony.common.client.gui.Toggle;
import com.minelittlepony.common.client.gui.element.Label;
import com.minelittlepony.common.client.gui.element.Slider;
import com.minelittlepony.common.client.gui.element.Toggle;
import com.minelittlepony.settings.PonyConfig;
import com.minelittlepony.settings.PonyLevel;
import com.minelittlepony.settings.PonyConfig.PonySettings;
@ -40,32 +40,34 @@ public class GuiPonySettings implements IGuiGuest {
int row = host.mustScroll() ? 0 : 32;
if (!host.mustScroll()) {
host.addButton(new Label(host.width / 2, 12, getTitle(), -1, true));
host.addButton(new Label(host.width / 2, 12).setCentered()).getStyle().setText(getTitle());
}
host.addButton(new Label(LEFT, row += 15, PONY_LEVEL, -1));
host.addButton(new Slider(LEFT, row += 15, 0, 2, config.getPonyLevel().ordinal(), v -> {
PonyLevel level = PonyLevel.valueFor(v);
config.setPonyLevel(level);
return (float)level.ordinal();
}).setFormatter(value -> {
return GameGui.format(PONY_LEVEL + "." + PonyLevel.valueFor(value).name().toLowerCase());
}));
host.addButton(new Label(LEFT, row += 15)).getStyle().setText(PONY_LEVEL);
host.addButton(new Slider(LEFT, row += 15, 0, 2, config.getPonyLevel().ordinal())
.onChange(v -> {
PonyLevel level = PonyLevel.valueFor(v);
config.setPonyLevel(level);
return (float)level.ordinal();
})
.setFormatter(value -> GameGui.format(PONY_LEVEL + "." + PonyLevel.valueFor(value).name().toLowerCase())));
if (GuiScreen.isCtrlKeyDown() && GuiScreen.isShiftKeyDown()) {
host.addButton(new Label(LEFT, row += 30, "minelp.debug.scale", -1));
host.addButton(new Slider(LEFT, row += 15, 0.1F, 3, config.getGlobalScaleFactor(), v -> {
config.setGlobalScaleFactor(v);
return config.getGlobalScaleFactor();
}).setFormatter(value -> {
return GameGui.format("minelp.debug.scale.value", GameGui.format(describeCurrentScale(value)));
}));
host.addButton(new Label(LEFT, row += 30)).getStyle().setText("minelp.debug.scale");
host.addButton(new Slider(LEFT, row += 15, 0.1F, 3, config.getGlobalScaleFactor())
.onChange(v -> {
config.setGlobalScaleFactor(v);
return config.getGlobalScaleFactor();
})
.setFormatter(value -> GameGui.format("minelp.debug.scale.value", GameGui.format(describeCurrentScale(value)))));
}
row += 15;
host.addButton(new Label(LEFT, row += 15, OPTIONS_PREFIX + "options", -1));
host.addButton(new Label(LEFT, row += 15)).getStyle().setText(OPTIONS_PREFIX + "options");
for (PonySettings i : PonySettings.values()) {
host.addButton(new Toggle(LEFT, row += 20, i.get(), OPTIONS_PREFIX + i.name().toLowerCase(), i));
host.addButton(new Toggle(LEFT, row += 20, i.get()))
.onChange(i)
.getStyle().setText(OPTIONS_PREFIX + i.name().toLowerCase());
}
if (host.mustScroll()) {
@ -74,9 +76,11 @@ public class GuiPonySettings implements IGuiGuest {
row = 32;
}
host.addButton(new Label(RIGHT, row += 15, MOB_PREFIX + "title", -1));
host.addButton(new Label(RIGHT, row += 15)).getStyle().setText(MOB_PREFIX + "title");
for (MobRenderers i : MobRenderers.values()) {
host.addButton(new Toggle(RIGHT, row += 20, i.get(), MOB_PREFIX + i.name().toLowerCase(), i));
host.addButton(new Toggle(RIGHT, row += 20, i.get()))
.onChange(i)
.getStyle().setText(MOB_PREFIX + i.name().toLowerCase());
}
}

View file

@ -1,8 +1,8 @@
package com.minelittlepony.client.gui.hdskins;
import com.minelittlepony.MineLittlePony;
import com.minelittlepony.common.client.gui.IconicToggle;
import com.minelittlepony.common.client.gui.Style;
import com.minelittlepony.common.client.gui.element.IconicToggle;
import com.minelittlepony.common.client.gui.style.Style;
import com.minelittlepony.hdskins.gui.EntityPlayerModel;
import com.minelittlepony.hdskins.gui.GuiSkins;
import com.minelittlepony.hdskins.net.SkinServer;
@ -28,9 +28,9 @@ public class GuiSkinsMineLP extends GuiSkins {
private boolean isWet = false;
private static final String[] panoramas = new String[] {
"minelittlepony:textures/cubemap/sugarcubecorner_%d.png",
"minelittlepony:textures/cubemap/quillsandsofas_%d.png",
"minelittlepony:textures/cubemap/sweetappleacres_%d.png"
"minelittlepony:textures/cubemap/sugarcubecorner",
"minelittlepony:textures/cubemap/quillsandsofas",
"minelittlepony:textures/cubemap/sweetappleacres"
};
public GuiSkinsMineLP(List<SkinServer> servers) {
@ -46,11 +46,13 @@ public class GuiSkinsMineLP extends GuiSkins {
public void initGui() {
super.initGui();
addButton(new IconicToggle(width - 25, 142, 2, sender -> setWet(sender.getValue() == 1))
.setStyle(new Style().setIcon(new ItemStack(Items.WATER_BUCKET)).setTooltip("minelp.mode.wet"), 1)
.setStyle(new Style().setIcon(new ItemStack(Items.BUCKET)).setTooltip("minelp.mode.dry"), 0)
.setValue(isWet ? 1 : 0)
.setTooltipOffset(0, 10));
addButton(new IconicToggle(width - 25, 142))
.setStyles(
new Style().setIcon(new ItemStack(Items.WATER_BUCKET)).setTooltip("minelp.mode.wet", 0, 10),
new Style().setIcon(new ItemStack(Items.BUCKET)).setTooltip("minelp.mode.dry", 0, 10)
)
.onChange(this::setWet)
.setValue(isWet ? 1 : 0);
}
@Override
@ -60,14 +62,16 @@ public class GuiSkinsMineLP extends GuiSkins {
return new ResourceLocation(panoramas[i]);
}
protected void setWet(boolean wet) {
protected int setWet(int wet) {
playSound(SoundEvents.BLOCK_BREWING_STAND_BREW);
isWet = wet;
isWet = wet == 1;
localPlayer.releaseTextures();
((EntityPonyModel)localPlayer).setWet(isWet);
((EntityPonyModel)remotePlayer).setWet(isWet);
return wet;
}
@Override

View file

@ -1,61 +0,0 @@
package com.minelittlepony.common;
import com.minelittlepony.common.client.gui.IGuiCallback;
/**
* A sensible config container that actually lets us programmatically index values by a key.
*
* Reflection because Mumfrey pls.
*
*/
// Mumfrey pls.
public abstract class SensibleConfig {
private static SensibleConfig instance;
public SensibleConfig() {
instance = this;
}
public abstract void save();
public interface Setting extends IGuiCallback<Boolean> {
String name();
/**
* Gets the config value associated with this entry.
*/
default boolean get() {
return instance.getValue(this);
}
/**
* Sets the config value associated with this entry.
*/
default void set(boolean value) {
instance.setValue(this, value);
}
@Override
default Boolean perform(Boolean v) {
set(v);
return v;
}
}
public boolean getValue(Setting key) {
try {
return this.getClass().getField(key.name().toLowerCase()).getBoolean(this);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignored) {
return true;
}
}
public boolean setValue(Setting key, boolean value) {
try {
this.getClass().getField(key.name().toLowerCase()).setBoolean(this, value);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ignored) {
}
return value;
}
}

View file

@ -1,63 +0,0 @@
package com.minelittlepony.common.client.gui;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
public class Button extends GuiButton implements IGuiTooltipped<Button> {
private int tipX = 0;
private int tipY = 0;
protected IGuiAction<Button> action;
private List<String> tooltip = null;
public Button(int x, int y, String label, IGuiAction<? extends Button> callback) {
this(x, y, 200, 20, label, callback);
}
@SuppressWarnings("unchecked")
public Button(int x, int y, int width, int height, String label, IGuiAction<? extends Button> callback) {
super(5000, x, y, width, height, GameGui.format(label));
action = (IGuiAction<Button>)callback;
}
public Button setEnabled(boolean enable) {
enabled = enable;
return this;
}
@Override
public Button setTooltip(List<String> tooltip) {
this.tooltip = tooltip;
return this;
}
protected List<String> getTooltip() {
return tooltip;
}
@Override
public void renderToolTip(Minecraft mc, int mouseX, int mouseY) {
List<String> tooltip = getTooltip();
if (visible && isMouseOver() && tooltip != null) {
mc.currentScreen.drawHoveringText(tooltip, mouseX + tipX, mouseY + tipY);
}
}
@Override
public Button setTooltipOffset(int x, int y) {
tipX = x;
tipY = y;
return this;
}
@Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
action.perform(this);
}
}

View file

@ -1,61 +0,0 @@
package com.minelittlepony.common.client.gui;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SimpleSound;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.SoundEvent;
public abstract class GameGui extends GuiScreen {
public static String format(String string, Object... pars) {
return string == null ? null : I18n.format(string, pars);
}
/**
* Formats a translation string and returns it in a list wrapped to a given width.
* This can be safely used in initGui, where the fontRenderer is often still null.
*/
public List<String> formatMultiLine(String string, int width, Object...pars) {
FontRenderer fr = fontRenderer;
if (fr == null) {
fr = Minecraft.getInstance().fontRenderer;
}
return fr.listFormattedStringToWidth(format(string, pars), width);
}
protected void playSound(SoundEvent event) {
mc.getSoundHandler().play(SimpleSound.master(event, 1));
}
/**
* Converts a given string to title case regardless of initial case.
*/
@SuppressWarnings("deprecation")
protected static String toTitleCase(String string) {
return org.apache.commons.lang3.text.WordUtils.capitalize(string.toLowerCase());
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
drawContents(mouseX, mouseY, partialTicks);
postDrawContents(mouseX, mouseY, partialTicks);
}
protected void drawContents(int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks);
}
protected void postDrawContents(int mouseX, int mouseY, float partialTicks) {
buttons.forEach(button -> {
if (button instanceof IGuiTooltipped) {
((IGuiTooltipped<?>)button).renderToolTip(mc, mouseX, mouseY);
}
});
}
}

View file

@ -1,42 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.gui.GuiButton;
public class GuiHost extends GameGui {
private final IGuiGuest guest;
public GuiHost(IGuiGuest guest) {
this.guest = guest;
}
@Override
public void initGui() {
guest.initGui(this);
}
@Override
public void drawContents(int mouseX, int mouseY, float partialTicks) {
if (guest.drawContents(this, mouseX, mouseY, partialTicks)) {
super.drawContents(mouseX, mouseY, partialTicks);
}
}
@Override
public void onGuiClosed() {
guest.onGuiClosed(this);
}
public String getTitle() {
return guest.getTitle();
}
@Override
public <T extends GuiButton> T addButton(T button) {
return super.addButton(button);
}
public boolean mustScroll() {
return false;
}
}

View file

@ -1,15 +0,0 @@
package com.minelittlepony.common.client.gui;
/**
* Response actions for UI events.
*/
@FunctionalInterface
public interface IGuiAction<T> {
/**
* Performs this action now.
*
* @param value New Value of the field being changed
* @return Adjusted value the field must take on
*/
void perform(T sender);
}

View file

@ -1,15 +0,0 @@
package com.minelittlepony.common.client.gui;
/**
* Response actions for UI events.
*/
@FunctionalInterface
public interface IGuiCallback<T> {
/**
* Performs this action now.
*
* @param value New Value of the field being changed
* @return Adjusted value the field must take on
*/
T perform(T value);
}

View file

@ -1,16 +0,0 @@
package com.minelittlepony.common.client.gui;
public interface IGuiGuest {
void initGui(GuiHost host);
default boolean drawContents(GuiHost host, int mouseX, int mouseY, float partialTicks) {
return true;
}
default void onGuiClosed(GuiHost host) {
}
String getTitle();
}

View file

@ -1,42 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.Minecraft;
import com.google.common.base.Splitter;
import java.util.List;
/**
* Interface element that renders a tooltip when hovered.
*
* @author Sollace
*
* @param <T> The subclass element.
*/
public interface IGuiTooltipped<T extends IGuiTooltipped<T>> {
/**
* Sets the tooltip text with a multi-line value.
*/
T setTooltip(List<String> tooltip);
/**
* Sets the tooltip offset from the original mouse position.
*/
T setTooltipOffset(int x, int y);
/**
* Sets the tooltip. The passed in value will be automatically
* translated and split into separate lines.
*
* @param tooltip A tooltip translation string.
*/
default T setTooltip(String tooltip) {
return setTooltip(Splitter.onPattern("\r?\n|\\\\n").splitToList(GameGui.format(tooltip)));
}
/**
* Draws this element's tooltip.
*/
void renderToolTip(Minecraft mc, int mouseX, int mouseY);
}

View file

@ -1,6 +0,0 @@
package com.minelittlepony.common.client.gui;
@FunctionalInterface
public interface IStyleFactory {
Style getStyle();
}

View file

@ -1,30 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
public class IconicButton extends Button {
private ItemStack itemStack = ItemStack.EMPTY;
public IconicButton(int x, int y, IGuiAction<? extends IconicButton> callback) {
super(x, y, 20, 20, "", callback);
}
public IconicButton setIcon(ItemStack stack) {
itemStack = stack;
return this;
}
public IconicButton setIcon(ItemStack stack, int colour) {
stack.getOrCreateChildTag("display").putInt("color", colour);
return setIcon(stack);
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks);
Minecraft.getInstance().getItemRenderer().renderItemIntoGUI(itemStack, x + 2, y + 2);
}
}

View file

@ -1,61 +0,0 @@
package com.minelittlepony.common.client.gui;
import com.minelittlepony.common.util.MoreStreams;
public class IconicToggle extends IconicButton {
private Style[] styles;
private int value;
public IconicToggle(int x, int y, int states, IGuiAction<IconicToggle> callback) {
super(x, y, callback);
styles = new Style[states];
for (int i = 0; i < styles.length; i++) {
styles[i] = new Style();
}
}
public int getValue() {
return value;
}
public IconicToggle setValue(int value) {
if (this.value != value) {
this.value = value % styles.length;
styles[this.value].apply(this);
}
return this;
}
public IconicToggle setStyles(IStyleFactory... styles) {
this.styles = MoreStreams.map(styles, IStyleFactory::getStyle, Style[]::new);
return this;
}
public IconicToggle setStyles(Style... styles) {
this.styles = styles;
return this;
}
public IconicToggle setStyle(Style style, int value) {
value %= styles.length;
styles[value] = style;
if (this.value == value) {
style.apply(this);
}
return this;
}
@Override
public void onClick(double mouseX, double mouseY) {
setValue(value + 1);
super.onClick(mouseX, mouseY);
}
}

View file

@ -1,46 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
/**
* A simple label for drawing text to a gui screen.
*
* @author Sollace
*
*/
public class Label extends GuiButton {
private boolean center;
private int color;
private String text;
public Label(int x, int y, String translationString, int color) {
this(x, y, translationString, color, false);
}
public Label(int x, int y, String translationString, int color, boolean center) {
super(0, x, y, "");
this.color = color;
this.center = center;
this.text = translationString;
}
@Override
protected boolean isPressable(double mouseX, double mouseY) {
return false;
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
Minecraft mc = Minecraft.getInstance();
if (center) {
drawCenteredString(mc.fontRenderer, GameGui.format(text), x, y, color);
} else {
drawString(mc.fontRenderer, GameGui.format(text), x, y, color);
}
}
}

View file

@ -1,88 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.gui.GuiButton;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.function.Function;
/**
* A slider for sliding.
*
* @author Sollace
*/
public class Slider extends GuiButton {
private float min;
private float max;
private float value;
protected IGuiCallback<Float> action;
@Nullable
private Function<Float, String> formatter;
public Slider(int x, int y, float min, float max, float value, IGuiCallback<Float> action) {
super(0, x, y, "");
this.min = min;
this.max = max;
this.value = value;
this.action = action;
}
public Slider setFormatter(@Nonnull Function<Float, String> formatter) {
this.formatter = formatter;
this.displayString = formatter.apply(getValue());
return this;
}
public void setValue(float value) {
value = clamp(value, min, max);
value = (value - min) / (max - min);
if (value != this.value) {
this.value = action.perform(value);
}
if (formatter != null) {
displayString = formatter.apply(getValue());
}
}
public float getValue() {
return value;
}
@Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
setValue((float)mouseX - (x + 4) / (float)(width - 8));
}
@Override
protected void onDrag(double mouseX, double mouseY, double mouseDX, double mouseDY) {
setValue((float)mouseX - (x + 4) / (float)(width - 8));
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks);
int i = hovered ? 2 : 1;
drawTexturedModalRect(x + (int)(value * (width - 8)), y, 0, 46 + i * 20, 4, 20);
drawTexturedModalRect(x + (int)(value * (width - 8)) + 4, y, 196, 46 + i * 20, 4, 20);
}
@Override
protected int getHoverState(boolean mouseOver) {
return 0;
}
protected float clamp(float value, float min, float max) {
return value < min ? min : value > max ? max : value;
}
}

View file

@ -1,54 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import java.util.List;
public class Style implements IGuiTooltipped<Style> {
ItemStack icon = ItemStack.EMPTY;
private boolean hasOffset = false;
private int toolTipX = 0;
private int toolTipY = 0;
private List<String> tooltip;
public Style setIcon(ItemStack stack) {
icon = stack;
return this;
}
public Style setIcon(ItemStack stack, int colour) {
stack.getOrCreateChildTag("display").putInt("color", colour);
return setIcon(stack);
}
protected void apply(IconicToggle button) {
button.setIcon(icon)
.setTooltip(tooltip);
if (hasOffset) {
button.setTooltipOffset(toolTipX, toolTipY);
}
}
@Override
public Style setTooltip(List<String> tooltip) {
this.tooltip = tooltip;
return this;
}
@Override
public Style setTooltipOffset(int x, int y) {
hasOffset = true;
toolTipX = x;
toolTipY = y;
return this;
}
@Override
public void renderToolTip(Minecraft mc, int mouseX, int mouseY) {
}
}

View file

@ -1,48 +0,0 @@
package com.minelittlepony.common.client.gui;
import net.minecraft.client.gui.GuiButton;
public class Toggle extends GuiButton {
private boolean on;
protected IGuiCallback<Boolean> action;
public Toggle(int x, int y, boolean value, String label, IGuiCallback<Boolean> callback) {
super(0, x, y, 20, 20, label);
on = value;
action = callback;
}
public boolean getValue() {
return on;
}
public void setValue(boolean value) {
if (value != on) {
on = action.perform(value);
}
}
@Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
setValue(!on);
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
super.render(mouseX, mouseY, partialTicks);
int i = hovered ? 2 : 1;
float value = on ? 1 : 0;
drawTexturedModalRect(x + (int)(value * (width - 8)), y, 0, 46 + i * 20, 4, 20);
drawTexturedModalRect(x + (int)(value * (width - 8)) + 4, y, 196, 46 + i * 20, 4, 20);
}
@Override
protected int getHoverState(boolean mouseOver) {
return 0;
}
}

View file

@ -1,7 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.minelittlepony.common.client.gui;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -1,7 +0,0 @@
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
package com.minelittlepony.common;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View file

@ -1,37 +0,0 @@
package com.minelittlepony.common.util;
import java.util.List;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.google.common.collect.Lists;
import javax.annotation.Nullable;
public class MoreStreams {
public static <T> Stream<T> ofNullable(@Nullable T t) {
return t == null ? Stream.empty() : Stream.of(t);
}
public static <T, V> V[] map(T[] items, Function<T, V> converter, IntFunction<V[]> collector) {
return Lists.newArrayList(items)
.stream()
.map(converter)
.toArray(collector);
}
public static <T, V> List<V> map(List<T> items, Function<T, V> converter) {
return items.stream()
.map(converter)
.collect(Collectors.toList());
}
public static <T> List<T> distinct(List<T> input) {
return input.stream()
.distinct()
.collect(Collectors.toList());
}
}