- Changed the layout of save/discard/leave prompts
- Leaving with unsaved changes now gives you the option to save
- Config tooltips now use standard Create tooltip splitting
This commit is contained in:
simibubi 2021-06-09 13:52:52 +02:00
parent 911aec5a3f
commit 7fae3e4968
3 changed files with 96 additions and 54 deletions

View file

@ -4,6 +4,7 @@ import java.awt.Color;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -25,6 +26,7 @@ import com.simibubi.create.foundation.gui.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.Theme;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.gui.ConfirmationScreen.Response;
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.networking.AllPackets;
@ -161,8 +163,8 @@ public class SubMenuConfigScreen extends ConfigScreen {
.withPadding(2, 2)
.withCallback((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?"))
.centered()
.withText(ITextProperties.plain("Resetting all settings of the " + type.toString() + " config. Are you sure?"))
.withAction(success -> {
if (success)
resetConfig(spec.getValues());
@ -172,7 +174,7 @@ public class SubMenuConfigScreen extends ConfigScreen {
resetAll.showingElement(AllIcons.I_CONFIG_RESET.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(resetAll)));
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));
resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all settings to their default value.", TextFormatting.GRAY, TextFormatting.GRAY));
saveChanges = new BoxWidget(listL - 30, yCenter - 25, 20, 20)
.withPadding(2, 2)
@ -181,8 +183,8 @@ public class SubMenuConfigScreen extends ConfigScreen {
return;
new ConfirmationScreen()
.at(x, y)
.withText(ITextProperties.plain("You are about to change " + changes.size() + " value" + (changes.size() != 1 ? "s" : "") + ". Are you sure?"))
.centered()
.withText(ITextProperties.plain("Saving " + changes.size() + " changed value" + (changes.size() != 1 ? "s" : "") + ""))
.withAction(success -> {
if (success)
saveChanges();
@ -200,8 +202,8 @@ public class SubMenuConfigScreen extends ConfigScreen {
return;
new ConfirmationScreen()
.at(x, y)
.withText(ITextProperties.plain("You are about to discard " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + ". Are you sure?"))
.centered()
.withText(ITextProperties.plain("Discarding " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + ""))
.withAction(success -> {
if (success)
clearChanges();
@ -282,7 +284,7 @@ public class SubMenuConfigScreen extends ConfigScreen {
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, red));
serverLocked.withBorderColors(red);
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));
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You do not 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, alpha) -> AllIcons.I_CONFIG_UNLOCKED.draw(ms, 0, 0));
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, green));
@ -338,24 +340,23 @@ public class SubMenuConfigScreen extends ConfigScreen {
}
private void attemptBackstep() {
if (!changes.isEmpty() && parent instanceof BaseConfigScreen) {
new ConfirmationScreen()
.centered()
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + " 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 {
if (changes.isEmpty() || !(parent instanceof BaseConfigScreen)) {
ScreenOpener.open(parent);
return;
}
Consumer<ConfirmationScreen.Response> action = success -> {
if (success == Response.Cancel)
return;
if (success == Response.Confirm)
saveChanges();
changes.clear();
ScreenOpener.open(parent);
};
showLeavingPrompt(action);
}
@Override
public void onClose() {
if (changes.isEmpty()) {
@ -364,17 +365,24 @@ public class SubMenuConfigScreen extends ConfigScreen {
return;
}
new ConfirmationScreen()
.centered()
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + " 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);
Consumer<ConfirmationScreen.Response> action = success -> {
if (success == Response.Cancel)
return;
if (success == Response.Confirm)
saveChanges();
changes.clear();
super.onClose();
};
showLeavingPrompt(action);
}
public void showLeavingPrompt(Consumer<ConfirmationScreen.Response> action) {
new ConfirmationScreen().centered()
.addText(ITextProperties.plain("Leaving with " + changes.size() + " unsaved change"
+ (changes.size() != 1 ? "s" : "") + " for this config"))
.withThreeActions(action)
.open(this);
}
}

View file

@ -17,6 +17,7 @@ import com.simibubi.create.foundation.config.ui.ConfigScreenList;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
import com.simibubi.create.foundation.item.TooltipHelper;
import net.minecraft.util.text.IFormattableTextComponent;
import net.minecraft.util.text.StringTextComponent;
@ -52,7 +53,7 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
listeners.add(resetButton);
List<String> path = value.getPath();
labelTooltip.add(new StringTextComponent(path.get(path.size()-1)).formatted(TextFormatting.GRAY));
labelTooltip.add(new StringTextComponent(label).formatted(TextFormatting.WHITE));
String comment = spec.getComment();
if (comment == null || comment.isEmpty())
return;
@ -76,8 +77,13 @@ public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
u = "in SU";
unit = u;
}
//add comment to tooltip
labelTooltip.addAll(Arrays.stream(commentLines).map(StringTextComponent::new).collect(Collectors.toList()));
// add comment to tooltip
labelTooltip.addAll(Arrays.stream(commentLines)
.map(StringTextComponent::new)
.flatMap(stc -> TooltipHelper.cutTextComponent(stc, TextFormatting.GRAY, TextFormatting.GRAY)
.stream())
.collect(Collectors.toList()));
labelTooltip.add(new StringTextComponent(ConfigScreen.modID + ":" + path.get(path.size()-1)).formatted(TextFormatting.DARK_GRAY));
}
@Override

View file

@ -12,6 +12,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.util.text.ITextProperties;
@ -20,17 +21,23 @@ import net.minecraft.util.text.Style;
public class ConfirmationScreen extends AbstractSimiScreen {
private Screen source;
private Consumer<Boolean> action = _success -> {};
private Consumer<Response> 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 boolean tristate;
private BoxWidget confirm;
private BoxWidget confirmDontSave;
private BoxWidget cancel;
private BoxElement textBackground;
public enum Response {
Confirm, ConfirmDontSave, Cancel
}
/*
* Removes text lines from the back of the list
@ -70,7 +77,13 @@ public class ConfirmationScreen extends AbstractSimiScreen {
}
public ConfirmationScreen withAction(Consumer<Boolean> action) {
this.action = r -> action.accept(r == Response.Confirm);
return this;
}
public ConfirmationScreen withThreeActions(Consumer<Response> action) {
this.action = action;
this.tristate = true;
return this;
}
@ -115,32 +128,46 @@ public class ConfirmationScreen extends AbstractSimiScreen {
y = height - textHeight - 30;
}
TextStencilElement confirmText = new TextStencilElement(client.fontRenderer, "Confirm").centered(true, true);
confirm = new BoxWidget(x + 4, y + textHeight + 2 , textWidth/2 - 10, 20)
.withCallback(() -> accept(true));
int buttonX = x + textWidth / 2 - 6 - (int) (70 * (tristate ? 1.5f : 1));
TextStencilElement confirmText =
new TextStencilElement(client.fontRenderer, tristate ? "Save" : "Confirm").centered(true, true);
confirm = new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.Confirm));
confirm.showingElement(confirmText.withElementRenderer(BoxWidget.gradientFactory.apply(confirm)));
widgets.add(confirm);
buttonX += 12 + 70;
if (tristate) {
TextStencilElement confirmDontSaveText =
new TextStencilElement(client.fontRenderer, "Don't Save").centered(true, true);
confirmDontSave =
new BoxWidget(buttonX, y + textHeight + 6, 70, 16).withCallback(() -> accept(Response.ConfirmDontSave));
confirmDontSave.showingElement(
confirmDontSaveText.withElementRenderer(BoxWidget.gradientFactory.apply(confirmDontSave)));
widgets.add(confirmDontSave);
buttonX += 12 + 70;
}
TextStencilElement cancelText = new TextStencilElement(client.fontRenderer, "Cancel").centered(true, true);
cancel = new BoxWidget(x + textWidth/2 + 6, y + textHeight + 2, textWidth/2 - 10, 20)
.withCallback(() -> accept(false));
cancel = new BoxWidget(buttonX, y + textHeight + 6, 70, 16)
.withCallback(() -> accept(Response.Cancel));
cancel.showingElement(cancelText.withElementRenderer(BoxWidget.gradientFactory.apply(cancel)));
widgets.add(confirm);
widgets.add(cancel);
textBackground = new BoxElement()
.gradientBorder(Theme.p(Theme.Key.BUTTON_DISABLE))
.withBounds(textWidth, textHeight)
.at(x, y);
.withBounds(width + 10, textHeight + 35)
.at(-5, y - 5);
}
@Override
public void onClose() {
accept(false);
accept(Response.Cancel);
}
private void accept(boolean success) {
private void accept(Response success) {
client.currentScreen = source;
action.accept(success);
}
@ -157,11 +184,12 @@ public class ConfirmationScreen extends AbstractSimiScreen {
for (ITextProperties line : text) {
lineY = lineY + offset;
if (line == null)
continue;
client.fontRenderer.draw(ms, line.getString(), x, lineY, 0xeaeaea);
int textX = x;
if (text.size() == 1)
x = (width - client.fontRenderer.getWidth(line)) / 2;
client.fontRenderer.draw(ms, line.getString(), textX, lineY, 0xeaeaea);
}
ms.pop();
@ -175,7 +203,7 @@ public class ConfirmationScreen extends AbstractSimiScreen {
ms.push();
UIRenderHelper.framebuffer.bindFramebuffer(true);
source.render(ms, mouseX, mouseY, 10);
source.render(ms, 0, 0, 10); // zero mouse coords to prevent further tooltips
UIRenderHelper.framebuffer.unbindFramebuffer();
Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer();
ms.pop();