please confirm

This commit is contained in:
zelophed 2021-04-23 18:11:32 +02:00
parent f0dfc5a6bc
commit 33028e1087
18 changed files with 610 additions and 210 deletions

View file

@ -10,6 +10,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.config.ModConfig;
public class BaseConfigScreen extends ConfigScreen { public class BaseConfigScreen extends ConfigScreen {
@ -29,14 +30,14 @@ public class BaseConfigScreen extends ConfigScreen {
TextStencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("CLIENT CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); 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)); 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, (_$, _$$) -> { widgets.add(clientConfigWidget = new PonderButton(width / 2 - 100, height / 2 - 15 - 50, (_$, _$$) -> {
ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.CLIENT.specification)); ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.CLIENT, AllConfigs.CLIENT.specification));
}, 200, 30).showingUnscaled(text)); }, 200, 30).showingUnscaled(text));
clientConfigWidget.fade(1); clientConfigWidget.fade(1);
TextStencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("COMMON CONFIG").formatted(TextFormatting.BOLD)).centered(true, true); 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)); 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, (_$, _$$) -> { widgets.add(commonConfigWidget = new PonderButton(width / 2 - 100, height / 2 - 15, (_$, _$$) -> {
ScreenOpener.transitionTo(new SubMenuConfigScreen(this, AllConfigs.COMMON.specification)); ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.COMMON, AllConfigs.COMMON.specification));
}, 200, 30).showingUnscaled(text2)); }, 200, 30).showingUnscaled(text2));
commonConfigWidget.fade(1); commonConfigWidget.fade(1);
@ -47,7 +48,7 @@ public class BaseConfigScreen extends ConfigScreen {
serverConfigWidget.fade(1); serverConfigWidget.fade(1);
if (Minecraft.getInstance().world != null) { if (Minecraft.getInstance().world != null) {
serverConfigWidget.withCallback(() -> ScreenOpener.transitionTo(new ServerSubMenuConfigScreen(this, AllConfigs.SERVER.specification))); serverConfigWidget.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, AllConfigs.SERVER.specification)));
} else { } else {
serverConfigWidget.active = false; serverConfigWidget.active = false;
text3.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_disable_1, ConfigButton.Palette.button_disable_2)); text3.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, ConfigButton.Palette.button_disable_1, ConfigButton.Palette.button_disable_2));

View file

@ -1,6 +1,8 @@
package com.simibubi.create.foundation.config.ui; package com.simibubi.create.foundation.config.ui;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -11,10 +13,9 @@ 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;
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
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.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;
@ -22,40 +23,32 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
public abstract class ConfigScreen extends NavigatableSimiScreen { public abstract class ConfigScreen extends AbstractSimiScreen {
/* /*
* *
* TODO * TODO
* zelo's list for configUI * zelo's list for configUI
* *
* match style with ponderUI * adjust transition animation of screens -> disabled for now
* cache changes before setting values and saving to file * move config button's animations to ponder button or a new superclass
* don't exit on ESC * get some proper icons for reset button and enum cycle
* reset text field focus for any click inside screen *
* adjust transition animation of screens * some color themes maybe?
* allow backspace in text fields * at least a helper class to unite colors throughout different uis
* move config button's animations to ponder button or a new superclass *
* get some proper icons for reset button and enum cycle * FIXME
* some small shadow effect for top and bottom of the list *
* add the 'think back' button back, just with a different caption * tooltip are hidden underneath the scrollbar, if the bar is near the middle
* add a title to the current config screen, maybe in the form of breadcrumbs * misalignment of the label-streak and textboxes/enum stuff
* * framebuffer blending is incorrect
* some color themes maybe? *
* at least a helper class to unite colors throughout different uis * */
*
* FIXME
*
* tooltip are hidden underneath the scrollbar, if the bar is near the middle
* misalignment of the label-streak and textboxes/enum stuff
*
* */
public static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f));
public static final BlockState cogwheelState = AllBlocks.LARGE_COGWHEEL.getDefaultState().with(CogWheelBlock.AXIS, Direction.Axis.Y);
public static final Map<String, Object> changes = new HashMap<>();
protected final Screen parent; 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);
protected StencilElement testStencil;
public ConfigScreen(Screen parent) { public ConfigScreen(Screen parent) {
this.parent = parent; this.parent = parent;
@ -63,47 +56,24 @@ public abstract class ConfigScreen extends NavigatableSimiScreen {
@Override @Override
public void tick() { public void tick() {
cogSpin.tick();
widgets.stream()
.filter(w -> w instanceof ConfigButton)
.forEach(w -> ((ConfigButton) w).tick());
super.tick(); super.tick();
} cogSpin.tick();
@Override
protected void 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);
} }
@Override @Override
public void renderBackground(@Nonnull MatrixStack ms) { 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)); net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this, ms));
} }
@Override @Override
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
RenderSystem.disableDepthTest(); RenderSystem.disableDepthTest();
if (this.client != null && this.client.world != null){ if (this.client != null && this.client.world != null) {
fill(ms, 0, 0, this.width, this.height, 0xb0_282c34); fill(ms, 0, 0, this.width, this.height, 0xb0_282c34);
} else { } else {
fill(ms, 0, 0, this.width, this.height, 0xff_282c34); 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() { new StencilElement() {
@Override @Override
protected void renderStencil(MatrixStack ms) { protected void renderStencil(MatrixStack ms) {
@ -120,18 +90,6 @@ public abstract class ConfigScreen extends NavigatableSimiScreen {
} }
protected void renderCog(MatrixStack ms, float partialTicks) {
ms.push();
ms.translate(-100, 100, -200);
ms.scale(200, 200, .1f);
GuiGameElement.of(cogwheelState)
.rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5)
.render(ms);
ms.pop();
}
@Override @Override
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
int x = (int) (width * 0.5f); int x = (int) (width * 0.5f);
@ -155,4 +113,16 @@ public abstract class ConfigScreen extends NavigatableSimiScreen {
String s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(key)).map(StringUtils::capitalize).collect(Collectors.joining(" ")); String s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(key)).map(StringUtils::capitalize).collect(Collectors.joining(" "));
return s; return s;
} }
protected void renderCog(MatrixStack ms, float partialTicks) {
ms.push();
ms.translate(-100, 100, -100);
ms.scale(200, 200, .1f);
GuiGameElement.of(cogwheelState)
.rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5)
.render(ms);
ms.pop();
}
} }

View file

@ -7,6 +7,7 @@ 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.config.ui.entries.NumberEntry;
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.UIRenderHelper;
@ -22,7 +23,7 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> { public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
public TextFieldWidget currentText; public static TextFieldWidget currentText;
public boolean isForServer = false; public boolean isForServer = false;
@ -31,12 +32,16 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
func_244605_b(false); func_244605_b(false);
func_244606_c(false); func_244606_c(false);
setRenderSelection(false); setRenderSelection(false);
currentText = null;
} }
@Override @Override
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
//render tmp background //render tmp background
fill(ms, left, top, left + width, top + height, 0x10_000000); //fill(ms, left, top, left + width, top + height, 0x10_000000);
UIRenderHelper.angledGradient(ms, 90, left + width / 2, top, width, 5, 0x60_000000, 0x0);
UIRenderHelper.angledGradient(ms, -90, left + width / 2, bottom, width, 5, 0x60_000000, 0x0);
super.render(ms, mouseX, mouseY, partialTicks); super.render(ms, mouseX, mouseY, partialTicks);
} }
@ -50,6 +55,13 @@ public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
RenderSystem.disableScissor(); RenderSystem.disableScissor();
} }
@Override
public boolean mouseClicked(double x, double y, int button) {
children().stream().filter(e -> e instanceof NumberEntry<?>).forEach(e -> e.mouseClicked(x, y, button));
return super.mouseClicked(x, y, button);
}
@Override @Override
public int getRowWidth() { public int getRowWidth() {
return width - 18; return width - 18;

View file

@ -30,4 +30,21 @@ public class ConfigTextField extends TextFieldWidget {
font.draw(ms, unit, x + getAdjustedWidth() - unitWidth, this.y + (this.height - 8) / 2, 0xcc_aaaaaa); font.draw(ms, unit, x + getAdjustedWidth() - unitWidth, this.y + (this.height - 8) / 2, 0xcc_aaaaaa);
} }
@Override
public void setFocused2(boolean focus) {
super.setFocused2(focus);
if (!focus) {
if (ConfigScreenList.currentText == this)
ConfigScreenList.currentText = null;
return;
}
if (ConfigScreenList.currentText != null && ConfigScreenList.currentText != this)
ConfigScreenList.currentText.setFocused2(false);
ConfigScreenList.currentText = this;
}
} }

View file

@ -1,52 +0,0 @@
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);
}
}

View file

@ -1,8 +1,9 @@
package com.simibubi.create.foundation.config.ui; package com.simibubi.create.foundation.config.ui;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableInt; import org.lwjgl.glfw.GLFW;
import com.electronwill.nightconfig.core.AbstractConfig; import com.electronwill.nightconfig.core.AbstractConfig;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
@ -11,30 +12,93 @@ 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.EnumEntry;
import com.simibubi.create.foundation.config.ui.entries.NumberEntry; import com.simibubi.create.foundation.config.ui.entries.NumberEntry;
import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry; import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry;
import com.simibubi.create.foundation.config.ui.entries.ValueEntry;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.ConfirmationScreen;
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.TextStencilElement;
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.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.IGuiEventListener;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.ITextProperties;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.fml.config.ModConfig;
public class SubMenuConfigScreen extends ConfigScreen { public class SubMenuConfigScreen extends ConfigScreen {
ForgeConfigSpec spec; public final ModConfig.Type type;
UnmodifiableConfig configGroup; protected ForgeConfigSpec spec;
ConfigScreenList list; protected UnmodifiableConfig configGroup;
protected ConfigScreenList list;
protected PonderButton resetAll;
protected PonderButton saveChanges;
protected PonderButton discardChanges;
protected PonderButton goBack;
protected PonderButton serverLocked;
protected int listWidth;
protected String title;
public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) { public SubMenuConfigScreen(Screen parent, String title, ModConfig.Type type, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) {
super(parent); super(parent);
this.type = type;
this.spec = configSpec; this.spec = configSpec;
this.title = title;
this.configGroup = configGroup; this.configGroup = configGroup;
} }
public SubMenuConfigScreen(Screen parent, ForgeConfigSpec configSpec) { public SubMenuConfigScreen(Screen parent, ModConfig.Type type, ForgeConfigSpec configSpec) {
super(parent); super(parent);
this.type = type;
this.spec = configSpec; this.spec = configSpec;
this.title = "root";
this.configGroup = configSpec.getValues(); this.configGroup = configSpec.getValues();
} }
protected void clearChanges() {
changes.clear();
list.children()
.stream()
.filter(e -> e instanceof ValueEntry)
.forEach(e -> ((ValueEntry<?>) e).onValueChange());
}
protected void saveChanges() {
UnmodifiableConfig values = spec.getValues();
changes.forEach((path, value) -> {
ForgeConfigSpec.ConfigValue configValue = values.get(path);
configValue.set(value);
});
clearChanges();
}
protected void resetConfig(UnmodifiableConfig values) {
values.valueMap().forEach((key, obj) -> {
if (obj instanceof AbstractConfig) {
resetConfig((UnmodifiableConfig) obj);
} else if (obj instanceof ForgeConfigSpec.ConfigValue<?>) {
ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) obj;
ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath());
if (!configValue.get().equals(valueSpec.getDefault()))
changes.put(String.join(".", configValue.getPath()), valueSpec.getDefault());
}
});
list.children()
.stream()
.filter(e -> e instanceof ValueEntry)
.forEach(e -> ((ValueEntry<?>) e).onValueChange());
}
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
@ -46,23 +110,88 @@ public class SubMenuConfigScreen extends ConfigScreen {
widgets.clear(); widgets.clear();
super.init(); super.init();
int lWidth = Math.min(width - 66, 500); //leave 40px on either side and dont be wider than 500px
list = new ConfigScreenList(client, lWidth, height - 30, 15, height - 15, 50); listWidth = Math.min(width - 80, 500);
int yCenter = height / 2;
int listL = this.width / 2 - listWidth / 2;
int listR = this.width / 2 + listWidth / 2;
resetAll = new PonderButton(listR + 10, yCenter - 25, (x, y) -> {
new ConfirmationScreen()
.at(x, y)
.withText(ITextProperties.plain("You are about to reset all settings for the " + type.toString() + " config. Are you sure?"))
.withAction(success -> {
if (success)
resetConfig(spec.getValues());
})
.open(this);
})
.showing(AllIcons.I_CONFIG_RESET.asStencil());
resetAll.fade(1);
resetAll.getToolTip().add(new StringTextComponent("Reset All"));
resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all configs to their default value.", TextFormatting.GRAY, TextFormatting.GRAY));
saveChanges = new PonderButton(listL - 30, yCenter - 25, (x, y) -> {
if (changes.isEmpty())
return;
new ConfirmationScreen()
.at(x, y)
.withText(ITextProperties.plain("You are about to change " + changes.size() + " values. Are you sure?"))
.withAction(success -> {
if (success)
saveChanges();
})
.open(this);
})
.showing(AllIcons.I_CONFIG_SAVE.asStencil());
saveChanges.fade(1);
saveChanges.getToolTip().add(new StringTextComponent("Save Changes"));
saveChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to save your current changes.", TextFormatting.GRAY, TextFormatting.GRAY));
discardChanges = new PonderButton(listL - 30, yCenter + 5, (x, y) -> {
if (changes.isEmpty())
return;
new ConfirmationScreen()
.at(x, y)
.withText(ITextProperties.plain("You are about to discard " + changes.size() + " unsaved changes. Are you sure?"))
.withAction(success -> {
if (success)
clearChanges();
})
.open(this);
})
.showing(AllIcons.I_CONFIG_DISCARD.asStencil());
discardChanges.fade(1);
discardChanges.getToolTip().add(new StringTextComponent("Discard Changes"));
discardChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to discard all the changes you made.", TextFormatting.GRAY, TextFormatting.GRAY));
goBack = new PonderButton(listL - 30, yCenter + 65, this::attemptBackstep)
.showing(AllIcons.I_CONFIG_BACK);
goBack.fade(1);
goBack.getToolTip().add(new StringTextComponent("Go Back"));
widgets.add(resetAll);
widgets.add(saveChanges);
widgets.add(discardChanges);
widgets.add(goBack);
list = new ConfigScreenList(client, listWidth, height - 60, 45, height - 15, 50);
list.setLeftPos(this.width / 2 - list.getWidth() / 2); list.setLeftPos(this.width / 2 - list.getWidth() / 2);
children.add(list); children.add(list);
MutableInt y = new MutableInt(15); configGroup.valueMap().forEach((key, obj) -> {
String humanKey = toHumanReadable(key);
configGroup.valueMap().forEach((s, o) -> { if (obj instanceof AbstractConfig) {
String humanKey = toHumanReadable(s); SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) obj);
if (o instanceof AbstractConfig) {
SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) o);
list.children().add(entry); list.children().add(entry);
} else if (o instanceof ForgeConfigSpec.ConfigValue<?>) { } else if (obj instanceof ForgeConfigSpec.ConfigValue<?>) {
ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) o; ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) obj;
ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath()); ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath());
Object value = configValue.get(); Object value = configValue.get();
@ -77,21 +206,58 @@ public class SubMenuConfigScreen extends ConfigScreen {
if (entry != null) { if (entry != null) {
list.children().add(entry); list.children().add(entry);
} else { } else {
list.children().add(new ConfigScreenList.LabeledEntry("n-" + o.getClass().getSimpleName() + " " + humanKey + " : " + value)); list.children().add(new ConfigScreenList.LabeledEntry("n-" + obj.getClass().getSimpleName() + " " + humanKey + " : " + value));
} }
} else { } else {
list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value)); list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value));
} }
} }
y.add(50);
}); });
//extras for sever configs
if (type != ModConfig.Type.SERVER)
return;
list.isForServer = true;
boolean canEdit = client != null && client.player != null && client.player.hasPermissionLevel(2);
int colRed1 = 0xff_f78888;
int colRed2 = 0xff_cc2020;
int colGreen1 = 0xff_88f788;
int colGreen2 = 0xff_20cc20;
DelegatedStencilElement stencil = new DelegatedStencilElement();
serverLocked = new PonderButton(listR + 10, yCenter + 5, () -> {})
.showing(stencil);
serverLocked.fade(1);
if (!canEdit) {
list.children().forEach(e -> e.setEditable(false));
resetAll.active = false;
stencil.withStencilRenderer((ms, w, h) -> AllIcons.I_CONFIG_LOCKED.draw(ms, 0, 0));
stencil.withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, colRed1, colRed2));
serverLocked.customColors(colRed1, colRed2);
serverLocked.getToolTip().add(new StringTextComponent("Locked").formatted(TextFormatting.BOLD));
serverLocked.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));
} else {
stencil.withStencilRenderer((ms, w, h) -> AllIcons.I_CONFIG_UNLOCKED.draw(ms, 0, 0));
stencil.withElementRenderer((ms, w, h) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, colGreen1, colGreen2));
serverLocked.customColors(colGreen1, colGreen2);
serverLocked.getToolTip().add(new StringTextComponent("Unlocked").formatted(TextFormatting.BOLD));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You have enough permissions to edit the server config. Changes you make here will be synced with the server once you saved them.", TextFormatting.GRAY, TextFormatting.GRAY));
}
widgets.add(serverLocked);
} }
@Override @Override
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
super.renderWindow(ms, mouseX, mouseY, partialTicks); super.renderWindow(ms, mouseX, mouseY, partialTicks);
int x = width/2;
drawCenteredString(ms, client.fontRenderer, "Editing config: " + type.toString() + "@" + title, x, 15, 0xff_eaeaea);
list.render(ms, mouseX, mouseY, partialTicks); list.render(ms, mouseX, mouseY, partialTicks);
} }
@ -106,4 +272,65 @@ public class SubMenuConfigScreen extends ConfigScreen {
init(client, width, height); init(client, width, height);
list.setScrollAmount(scroll); list.setScrollAmount(scroll);
} }
@Nullable
@Override
public IGuiEventListener getFocused() {
if (ConfigScreenList.currentText != null)
return ConfigScreenList.currentText;
return super.getFocused();
}
@Override
public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) {
if (super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_))
return true;
if (code == GLFW.GLFW_KEY_BACKSPACE) {
attemptBackstep();
}
return false;
}
private void attemptBackstep() {
if (!changes.isEmpty() && parent instanceof BaseConfigScreen) {
new ConfirmationScreen()
.centered()
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved changes for this config."))
.addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?"))
.withAction(success -> {
if (!success)
return;
changes.clear();
ScreenOpener.open(parent);
})
.open(this);
} else {
ScreenOpener.open(parent);
}
}
@Override
public void onClose() {
if (changes.isEmpty()) {
super.onClose();
return;
}
new ConfirmationScreen()
.centered()
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved changes for this config."))
.addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?"))
.withAction(success -> {
if (!success)
return;
changes.clear();
super.onClose();
})
.open(this);
}
} }

View file

@ -25,10 +25,8 @@ public class BooleanEntry extends ValueEntry<Boolean> {
.centered(true, true) .centered(true, true)
.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_f78888, 0xff_cc2020)); .withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_f78888, 0xff_cc2020));
button = new PonderButton(0, 0, () -> { button = new PonderButton(0, 0, () -> setValue(!getValue()))
value.set(!value.get()); .showingUnscaled(enabled);
onValueChange();
}).showingUnscaled(enabled);
button.fade(1); button.fade(1);
listeners.add(button); listeners.add(button);
@ -58,14 +56,9 @@ public class BooleanEntry extends ValueEntry<Boolean> {
} }
@Override @Override
protected void onValueChange() { public void onValueChange(Boolean newValue) {
super.onValueChange(); super.onValueChange(newValue);
button.showingUnscaled(value.get() ? enabled : disabled); button.showingUnscaled(newValue ? enabled : disabled);
bumpCog(value.get() ? 15f : -16f); bumpCog(newValue ? 15f : -16f);
} }
/*@Override
public boolean mouseClicked(double mX, double mY, int button) {
return this.button.mouseClicked(mX, mY, button) || super.mouseClicked(mX, mY, button);
}*/
} }

View file

@ -35,12 +35,11 @@ public class EnumEntry extends ValueEntry<Enum<?>> {
} }
protected void cycleValue(int direction) { protected void cycleValue(int direction) {
Enum<?> e = value.get(); Enum<?> e = getValue();
Enum<?>[] options = e.getDeclaringClass().getEnumConstants(); Enum<?>[] options = e.getDeclaringClass().getEnumConstants();
e = options[Math.floorMod(e.ordinal() + direction, options.length)]; e = options[Math.floorMod(e.ordinal() + direction, options.length)];
value.set(e); setValue(e);
bumpCog(direction * 15f); bumpCog(direction * 15f);
onValueChange();
} }
@Override @Override
@ -79,8 +78,8 @@ public class EnumEntry extends ValueEntry<Enum<?>> {
} }
@Override @Override
protected void onValueChange() { public void onValueChange(Enum<?> newValue) {
super.onValueChange(); super.onValueChange(newValue);
valueText.withText(value.get().name()); valueText.withText(newValue.name());
} }
} }

View file

@ -39,7 +39,7 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
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 ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, unit); textField = new ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 30, unit);
textField.setText(String.valueOf(value.get())); textField.setText(String.valueOf(getValue()));
Object range = spec.getRange(); Object range = spec.getRange();
try { try {
@ -74,8 +74,7 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
textField.setTextColor(0xff_20cc20); textField.setTextColor(0xff_20cc20);
value.set(number); setValue(number);
onValueChange();
} catch (IllegalArgumentException ignored) { } catch (IllegalArgumentException ignored) {
textField.setTextColor(0xff_cc2020); textField.setTextColor(0xff_cc2020);
@ -105,9 +104,13 @@ public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
} }
@Override @Override
protected void onReset() { public void onValueChange(T newValue) {
super.onReset(); super.onValueChange(newValue);
textField.setText(String.valueOf(value.get())); String newText = String.valueOf(newValue);
if (textField.getText().equals(newText))
return;
textField.setText(newText);
} }
@Override @Override

View file

@ -4,7 +4,6 @@ import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.config.ui.ConfigButton; import com.simibubi.create.foundation.config.ui.ConfigButton;
import com.simibubi.create.foundation.config.ui.ConfigScreenList; 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.config.ui.SubMenuConfigScreen;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.TextStencilElement;
@ -12,21 +11,18 @@ import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.ponder.ui.PonderButton; import com.simibubi.create.foundation.ponder.ui.PonderButton;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
public class SubMenuEntry extends ConfigScreenList.LabeledEntry { public class SubMenuEntry extends ConfigScreenList.LabeledEntry {
protected PonderButton button; protected PonderButton button;
public SubMenuEntry(Screen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) { public SubMenuEntry(SubMenuConfigScreen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) {
super(label); super(label);
TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").centered(true, true); TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Click to open").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)); text.withElementRenderer((ms, width, height) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2));
button = new PonderButton(0, 0, () -> ScreenOpener.transitionTo(isForServer() ? button = new PonderButton(0, 0, () -> ScreenOpener.open(new SubMenuConfigScreen(parent, label, parent.type, spec, config)))
new ServerSubMenuConfigScreen(parent, spec, config) : .showingUnscaled(text);
new SubMenuConfigScreen(parent, spec, config))
).showingUnscaled(text);
button.fade(1); button.fade(1);
listeners.add(button); listeners.add(button);

View file

@ -6,44 +6,49 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import org.apache.commons.lang3.ArrayUtils; 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.ConfigButton; import com.simibubi.create.foundation.config.ui.ConfigButton;
import com.simibubi.create.foundation.config.ui.ConfigScreen;
import com.simibubi.create.foundation.config.ui.ConfigScreenList; import com.simibubi.create.foundation.config.ui.ConfigScreenList;
import com.simibubi.create.foundation.gui.TextStencilElement; 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.gui.UIRenderHelper;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.ponder.ui.PonderButton; import com.simibubi.create.foundation.ponder.ui.PonderButton;
import net.minecraft.client.Minecraft; import net.minecraft.util.text.IFormattableTextComponent;
import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; 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 IFormattableTextComponent modComponent = new StringTextComponent("* ").formatted(TextFormatting.BOLD, TextFormatting.DARK_BLUE).append(StringTextComponent.EMPTY.copy().formatted(TextFormatting.RESET));
protected static final int resetWidth = 28;//including 6px offset on either side protected static final int resetWidth = 28;//including 6px offset on either side
public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]"); public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]");
//public static DelegatedStencilElement.ElementRenderer idle = (ms, w, h) -> UIRenderHelper.angledGradient(ms, 0, 0, h / 2, h, w, ConfigButton.Palette.button_idle_1, ConfigButton.Palette.button_idle_2);
protected ForgeConfigSpec.ConfigValue<T> value; protected ForgeConfigSpec.ConfigValue<T> value;
protected ForgeConfigSpec.ValueSpec spec; protected ForgeConfigSpec.ValueSpec spec;
protected PonderButton resetButton; protected PonderButton resetButton;
protected boolean editable = true; protected boolean editable = true;
protected String unit = null; protected String unit = null;
protected String path;
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);
this.value = value; this.value = value;
this.spec = spec; this.spec = spec;
this.path = String.join(".", value.getPath());
TextStencilElement text = new TextStencilElement(Minecraft.getInstance().fontRenderer, "R").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));
resetButton = new PonderButton(0, 0, (_$, _$$) -> { resetButton = new PonderButton(0, 0, (_$, _$$) -> {
value.set((T) spec.getDefault()); setValue((T) spec.getDefault());
this.onReset(); this.onReset();
}, resetWidth - 12, 16).showingUnscaled(text); }, resetWidth - 12, 16)
.showing(AllIcons.I_CONFIG_RESET.asStencil()/*.withElementRenderer(idle)*/);
resetButton.fade(1); resetButton.fade(1);
listeners.add(resetButton); listeners.add(resetButton);
@ -82,12 +87,20 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
@Override @Override
protected void setEditable(boolean b) { protected void setEditable(boolean b) {
editable = b; editable = b;
resetButton.active = editable && !value.get().equals(spec.getDefault()); resetButton.active = editable && !isCurrentValueDefault();
} }
@Override @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) { 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); if (isCurrentValueChanged()) {
IFormattableTextComponent original = label.getComponent();
IFormattableTextComponent changed = modComponent.copy().append(original);
label.withText(changed);
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
label.withText(original);
} else {
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
}
resetButton.x = x + width - resetWidth + 6; resetButton.x = x + width - resetWidth + 6;
resetButton.y = y + 15; resetButton.y = y + 15;
@ -99,18 +112,40 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
return (int) (totalWidth * labelWidthMult); return (int) (totalWidth * labelWidthMult);
} }
protected void onReset() { public void setValue(@Nonnull T value) {
onValueChange(); if (value.equals(this.value.get())) {
ConfigScreen.changes.remove(path);
onValueChange(value);
return;
}
ConfigScreen.changes.put(path, value);
onValueChange(value);
} }
protected void onValueChange() { @Nonnull
resetButton.active = editable && !value.get().equals(spec.getDefault()); public T getValue() {
//noinspection unchecked
return (T) ConfigScreen.changes.getOrDefault(path, this.value.get());
}
if (!isForServer()) protected boolean isCurrentValueChanged() {
return; return ConfigScreen.changes.containsKey(path);
}
String path = String.join(".", value.getPath()); protected boolean isCurrentValueDefault() {
AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value.get())); return spec.getDefault().equals(getValue());
}
public void onReset() {
onValueChange(getValue());
}
public void onValueChange() {
onValueChange(getValue());
}
public void onValueChange(T newValue) {
resetButton.active = editable && !isCurrentValueDefault();
} }
protected void bumpCog() {bumpCog(10f);} protected void bumpCog() {bumpCog(10f);}

View file

@ -124,7 +124,14 @@ public class AllIcons implements IScreenRenderable {
I_MTD_SCAN = next(), I_MTD_SCAN = next(),
I_MTD_REPLAY = next(), I_MTD_REPLAY = next(),
I_MTD_USER_MODE = next(), I_MTD_USER_MODE = next(),
I_MTD_SLOW_MODE = next(); I_MTD_SLOW_MODE = next(),
I_CONFIG_UNLOCKED = newRow(),
I_CONFIG_LOCKED = next(),
I_CONFIG_DISCARD = next(),
I_CONFIG_SAVE = next(),
I_CONFIG_RESET = next(),
I_CONFIG_BACK = next();
public AllIcons(int x, int y) { public AllIcons(int x, int y) {
iconX = x * 16; iconX = x * 16;
@ -179,6 +186,11 @@ public class AllIcons implements IScreenRenderable {
vertex(peek, builder, j, k, rgb, vec4, u1, v2); vertex(peek, builder, j, k, rgb, vec4, u1, v2);
} }
@OnlyIn(Dist.CLIENT)
public DelegatedStencilElement asStencil() {
return new DelegatedStencilElement().withStencilRenderer((ms, w, h) -> this.draw(ms, 0, 0)).withBounds(16, 16);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u, float v) { private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u, float v) {
builder.vertex(peek.getModel(), (float) vec.x, (float) vec.y, (float) vec.z) builder.vertex(peek.getModel(), (float) vec.x, (float) vec.y, (float) vec.z)

View file

@ -0,0 +1,186 @@
package com.simibubi.create.foundation.gui;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.ITextProperties;
import net.minecraft.util.text.Style;
public class ConfirmationScreen extends AbstractSimiScreen {
private Screen source;
private Consumer<Boolean> action = _success -> {};
private List<ITextProperties> text = new ArrayList<>();
private boolean centered = false;
private int x;
private int y;
private int textWidth;
private int textHeight;
private PonderButton confirm;
private PonderButton cancel;
/*
* Removes text lines from the back of the list
* */
public ConfirmationScreen removeTextLines(int amount) {
if (amount > text.size())
return clearText();
text.subList(text.size() - amount, text.size()).clear();
return this;
}
public ConfirmationScreen clearText() {
this.text.clear();
return this;
}
public ConfirmationScreen addText(ITextProperties text) {
this.text.add(text);
return this;
}
public ConfirmationScreen withText(ITextProperties text) {
return clearText().addText(text);
}
public ConfirmationScreen at(int x, int y) {
this.x = Math.max(x, 0);
this.y = Math.max(y, 0);
this.centered = false;
return this;
}
public ConfirmationScreen centered() {
this.centered = true;
return this;
}
public ConfirmationScreen withAction(Consumer<Boolean> action) {
this.action = action;
return this;
}
public void open(@Nonnull Screen source) {
this.source = source;
Minecraft client = source.getMinecraft();
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
this.client.currentScreen = this;
}
@Override
protected void init() {
widgets.clear();
ArrayList<ITextProperties> copy = new ArrayList<>(text);
text.clear();
copy.forEach(t -> text.addAll(client.fontRenderer.getTextHandler().wrapLines(t, 300, Style.EMPTY)));
textHeight = text.size() * (client.fontRenderer.FONT_HEIGHT + 1) + 4;
textWidth = 300;
if (x + textWidth > width) {
x = width - textWidth;
}
if (y + textHeight + 30 > height) {
y = height - textHeight - 30;
}
if (centered) {
x = width/2 - textWidth/2 - 2;
y = height/2 - textHeight/2 - 16;
}
TextStencilElement confirmText = new TextStencilElement(client.fontRenderer, "Confirm").centered(true, true);
confirm = new PonderButton(x + 4, y + textHeight + 2, (_$, _$$) -> accept(true), textWidth/2 - 10, 20)
.showingUnscaled(confirmText);
confirm.fade(1);
TextStencilElement cancelText = new TextStencilElement(client.fontRenderer, "Cancel").centered(true, true);
cancel = new PonderButton(x + textWidth/2 + 6, y + textHeight + 2, (_$, _$$) -> accept(false), textWidth/2 - 10, 20)
.showingUnscaled(cancelText);
cancel.fade(1);
widgets.add(confirm);
widgets.add(cancel);
}
@Override
public void onClose() {
accept(false);
}
private void accept(boolean success) {
client.currentScreen = source;
action.accept(success);
}
@Override
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
PonderUI.renderBox(ms, x, y, textWidth, textHeight, false);
int offset = client.fontRenderer.FONT_HEIGHT + 1;
int lineY = y - offset;
ms.push();
ms.translate(0, 0, 200);
for (ITextProperties line : text) {
lineY = lineY + offset;
if (line == null)
continue;
client.fontRenderer.draw(ms, line.getString(), x, lineY, 0xeaeaea);
}
ms.pop();
}
@Override
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC);
UIRenderHelper.prepFramebufferSize();
ms.push();
//ms.translate(0, 0, -50);
//ms.scale(1, 1, 0.01f);
UIRenderHelper.framebuffer.bindFramebuffer(true);
source.render(ms, mouseX, mouseY, partialTicks);
UIRenderHelper.framebuffer.unbindFramebuffer();
Minecraft.getInstance().getFramebuffer().bindFramebuffer(true);
ms.pop();
//RenderSystem.disableAlphaTest();
RenderSystem.disableBlend();
UIRenderHelper.drawFramebuffer(1);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
this.fillGradient(ms, 0, 0, this.width, this.height, 0x70101010, 0x80101010);
//RenderSystem.enableAlphaTest();
}
@Override
public void resize(@Nonnull Minecraft client, int width, int height) {
super.resize(client, width, height);
source.resize(client, width, height);
}
}

View file

@ -7,7 +7,6 @@ public class DelegatedStencilElement extends StencilElement {
protected static final ElementRenderer EMPTY_RENDERER = (ms, width, height) -> {}; 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 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 stencil;
protected ElementRenderer element; protected ElementRenderer element;

View file

@ -65,7 +65,7 @@ public class ScreenOpener {
if (screenHistory.isEmpty()) if (screenHistory.isEmpty())
return false; return false;
Screen previouslyRenderedScreen = screenHistory.get(0); Screen previouslyRenderedScreen = screenHistory.get(0);
if (!(previouslyRenderedScreen instanceof AbstractSimiScreen)) if (!(previouslyRenderedScreen instanceof NavigatableSimiScreen))
return false; return false;
if (!screen.isEquivalentTo((NavigatableSimiScreen) previouslyRenderedScreen)) if (!screen.isEquivalentTo((NavigatableSimiScreen) previouslyRenderedScreen))
return false; return false;

View file

@ -4,6 +4,8 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Matrix4f;
import net.minecraft.util.math.vector.Vector3f; import net.minecraft.util.math.vector.Vector3f;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.KHRDebug;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
@ -22,8 +24,6 @@ public class UIRenderHelper {
public static void enableStencil() { public static void enableStencil() {
RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil()); RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil());
if (framebuffer != null)
RenderSystem.recordRenderCall(() -> framebuffer.enableStencil());
} }
public static Framebuffer framebuffer; public static Framebuffer framebuffer;
@ -33,11 +33,13 @@ public class UIRenderHelper {
MainWindow mainWindow = Minecraft.getInstance().getWindow(); MainWindow mainWindow = Minecraft.getInstance().getWindow();
framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, Minecraft.IS_RUNNING_ON_MAC); framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, Minecraft.IS_RUNNING_ON_MAC);
framebuffer.setFramebufferColor(0, 0, 0, 0); framebuffer.setFramebufferColor(0, 0, 0, 0);
KHRDebug.glObjectLabel(GL30.GL_FRAMEBUFFER, framebuffer.framebufferObject, "UIBuffer");
framebuffer.enableStencil();
// framebuffer.deleteFramebuffer(); // framebuffer.deleteFramebuffer();
}); });
} }
public static void prepFramebufferSize() { public static void prepFramebufferSize() {//TODO move this to a mixin
MainWindow window = Minecraft.getInstance().getWindow(); MainWindow window = Minecraft.getInstance().getWindow();
if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) { if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) {
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC); framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC);
@ -54,10 +56,6 @@ public class UIRenderHelper {
float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight; float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight;
RenderSystem.enableTexture(); RenderSystem.enableTexture();
RenderSystem.enableBlend();
RenderSystem.disableLighting();
RenderSystem.disableAlphaTest();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
framebuffer.bindFramebufferTexture(); framebuffer.bindFramebufferTexture();
@ -73,8 +71,6 @@ public class UIRenderHelper {
tessellator.draw(); tessellator.draw();
framebuffer.unbindFramebufferTexture(); framebuffer.unbindFramebufferTexture();
RenderSystem.disableBlend();
RenderSystem.enableAlphaTest();
} }
//angle in degrees; 0° -> fading to the right //angle in degrees; 0° -> fading to the right

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.ponder; package com.simibubi.create.foundation.ponder;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.AbstractSimiScreen;
import com.simibubi.create.foundation.gui.IScreenRenderable; import com.simibubi.create.foundation.gui.IScreenRenderable;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
@ -106,7 +107,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
@Override @Override
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
if (transition.getChaseTarget() == 0) { if (transition.getChaseTarget() == 0 || transition.settled()) {
renderBackground(ms); renderBackground(ms);
return; return;
} }
@ -125,7 +126,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
ms.push();// 2 ms.push();// 2
ms.translate(0, 0, -1000); ms.translate(0, 0, -1000);
UIRenderHelper.framebuffer.bindFramebuffer(true); UIRenderHelper.framebuffer.bindFramebuffer(true);
lastScreen.render(ms, mouseX, mouseY, 10); lastScreen.render(ms, mouseX, mouseY, partialTicks);
ms.pop();// 2 ms.pop();// 2
// use the buffer texture // use the buffer texture
@ -147,7 +148,12 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
ms.translate(dpx, dpy, 0); ms.translate(dpx, dpy, 0);
ms.scale((float) scale, (float) scale, 1); ms.scale((float) scale, (float) scale, 1);
ms.translate(-dpx, -dpy, 0); ms.translate(-dpx, -dpy, 0);
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.disableAlphaTest();
UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue)); UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue));
RenderSystem.disableBlend();
RenderSystem.enableAlphaTest();
ms.pop();// 1 ms.pop();// 1
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 17 KiB