From de00f90a3700a493f870f24b6a864a45207d449a Mon Sep 17 00:00:00 2001 From: zelophed Date: Tue, 27 Apr 2021 02:48:50 +0200 Subject: [PATCH] pondering all over again --- .../category/BlockzapperUpgradeCategory.java | 2 +- .../jei/category/PolishingCategory.java | 2 +- .../goggles/GoggleConfigScreen.java | 25 ++- .../sequencer/SequencedGearshiftScreen.java | 2 +- .../symmetry/SymmetryWandScreen.java | 2 +- .../curiosities/zapper/ZapperScreen.java | 2 +- .../inventories/AdjustableCrateScreen.java | 2 +- .../block/redstone/StockpileSwitchScreen.java | 7 +- .../item/filter/AbstractFilterScreen.java | 15 +- .../block/SchematicTableScreen.java | 17 +- .../block/SchematicannonScreen.java | 4 +- .../client/SchematicEditScreen.java | 2 +- .../foundation/config/ui/ConfigScreen.java | 14 +- .../config/ui/ConfigScreenList.java | 2 + .../config/ui/SubMenuConfigScreen.java | 4 + .../config/ui/entries/EnumEntry.java | 24 +- .../config/ui/entries/NumberEntry.java | 8 +- .../create/foundation/gui/AllIcons.java | 4 +- .../create/foundation/gui/BoxElement.java | 7 +- .../foundation/gui/ConfirmationScreen.java | 2 +- .../create/foundation/gui/GuiGameElement.java | 24 +- .../create/foundation/gui/RenderElement.java | 30 +++ .../gui/widgets/AbstractSimiWidget.java | 7 + .../foundation/gui/widgets/BoxWidget.java | 72 +++--- .../foundation/gui/widgets/ElementWidget.java | 41 +++- .../ponder/NavigatableSimiScreen.java | 31 +-- .../foundation/ponder/PonderProgressBar.java | 23 +- .../create/foundation/ponder/PonderUI.java | 143 +++++++----- .../ponder/content/PonderIndexScreen.java | 24 +- .../ponder/content/PonderTagScreen.java | 92 +++++--- .../ponder/elements/InputWindowElement.java | 2 +- .../ponder/elements/TextWindowElement.java | 10 +- .../foundation/ponder/ui/ChapterLabel.java | 9 +- .../foundation/ponder/ui/PonderButton.java | 210 +++++------------- .../utility/AnimationTickHolder.java | 12 +- .../foundation/utility/ColorHelper.java | 4 + .../assets/create/textures/gui/icons.png | Bin 17866 -> 18162 bytes 37 files changed, 502 insertions(+), 379 deletions(-) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BlockzapperUpgradeCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BlockzapperUpgradeCategory.java index 581ebc9cd..427f83df2 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/BlockzapperUpgradeCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/BlockzapperUpgradeCategory.java @@ -88,7 +88,7 @@ public class BlockzapperUpgradeCategory extends CreateRecipeCategoryat(90, 0) .scale(3.5) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java index 1c2d29343..99a5cbaf0 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/PolishingCategory.java @@ -73,7 +73,7 @@ public class PolishingCategory extends CreateRecipeCategoryat(getBackground().getWidth() / 2 - 16, 0, 0) .scale(2) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleConfigScreen.java b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleConfigScreen.java index 51113c7db..636496b59 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleConfigScreen.java +++ b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleConfigScreen.java @@ -8,7 +8,7 @@ import com.simibubi.create.AllItems; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.GuiGameElement; -import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.ponder.ui.PonderButton; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.Minecraft; @@ -23,6 +23,8 @@ public class GoggleConfigScreen extends AbstractSimiScreen { private int offsetY; private final List tooltip; + private PonderButton w1, w2, w3; + public GoggleConfigScreen() { ITextComponent componentSpacing = new StringTextComponent(" "); tooltip = new ArrayList<>(); @@ -47,6 +49,16 @@ public class GoggleConfigScreen extends AbstractSimiScreen { offsetX = AllConfigs.CLIENT.overlayOffsetX.get(); offsetY = AllConfigs.CLIENT.overlayOffsetY.get(); + + widgets.clear(); + widgets.add(w1 = new PonderButton(50, 50) + .enableFade(0, 5)); + + widgets.add(w2 = new PonderButton(100, 50) + .enableFade(0, 5)); + + widgets.add(w3 = new PonderButton(150, 50)); + } @Override @@ -80,6 +92,17 @@ public class GoggleConfigScreen extends AbstractSimiScreen { int posY = this.height / 2 + offsetY; renderTooltip(ms, tooltip, posX, posY); + w1.fade().setValue(0.5); + w1.fade().setValue(0.5); + + w2.fade().setValue(0.75); + w2.fade().setValue(0.75); + + w1.flash(); + w2.flash(); + w3.flash(); + + //UIRenderHelper.breadcrumbArrow(ms, 50, 50, 100, 50, 20, 10, 0x80aa9999, 0x10aa9999); //UIRenderHelper.breadcrumbArrow(ms, 100, 80, 0, -50, 20, -10, 0x80aa9999, 0x10aa9999); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java index 157ff3ecc..fb073cbc2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java @@ -153,7 +153,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { 0xffffff); GuiGameElement.of(renderedItem) - .at(guiLeft + background.width + 10, guiTop + 100, -150) + .at(guiLeft + background.width + 10, guiTop + 100, -150) .scale(5) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java index 3c95f62ec..288de4b54 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java @@ -123,7 +123,7 @@ public class SymmetryWandScreen extends AbstractSimiScreen { renderBlock(matrixStack); GuiGameElement.of(wand) - .at(guiLeft + 190, guiTop + 420, -150) + .at(guiLeft + 190, guiTop + 420, -150) .scale(4) .rotate(-70, 20, 20) .render(matrixStack); diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java index bb5a6f3c7..ff58a8bf1 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java @@ -133,7 +133,7 @@ public class ZapperScreen extends AbstractSimiScreen { protected void renderZapper(MatrixStack matrixStack) { GuiGameElement.of(zapper) - .at((this.width - this.sWidth) / 2 + 200, this.height / 2 - this.sHeight / 4 + 25, -150) + .at((this.width - this.sWidth) / 2 + 200, this.height / 2 - this.sHeight / 4 + 25, -150) .scale(4) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java index 3d10ccc62..d8e532662 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java @@ -97,7 +97,7 @@ public class AdjustableCrateScreen extends AbstractSimiContainerScreenat(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 70, -150) .scale(5) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchScreen.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchScreen.java index a7bcdca6e..acca08977 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchScreen.java @@ -1,5 +1,7 @@ package com.simibubi.create.content.logistics.block.redstone; +import static com.simibubi.create.foundation.gui.AllGuiTextures.STOCKSWITCH; + import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; @@ -13,13 +15,12 @@ import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; -import static com.simibubi.create.foundation.gui.AllGuiTextures.STOCKSWITCH; - public class StockpileSwitchScreen extends AbstractSimiScreen { private ScrollInput offBelow; @@ -125,7 +126,7 @@ public class StockpileSwitchScreen extends AbstractSimiScreen { matrixStack.push(); GuiGameElement.of(renderedItem) - .at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250) + .at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250) .scale(5) .render(matrixStack); matrixStack.pop(); diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java index 8615f546a..79cefef17 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java @@ -1,5 +1,11 @@ package com.simibubi.create.content.logistics.item.filter; +import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY; +import static net.minecraft.util.text.TextFormatting.GRAY; + +import java.util.Collections; +import java.util.List; + import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket.Option; @@ -13,6 +19,7 @@ import com.simibubi.create.foundation.gui.widgets.Indicator.State; import com.simibubi.create.foundation.item.ItemDescription.Palette; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; + import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.renderer.Rectangle2d; import net.minecraft.client.resources.I18n; @@ -20,12 +27,6 @@ import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.text.IFormattableTextComponent; import net.minecraft.util.text.ITextComponent; -import java.util.Collections; -import java.util.List; - -import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY; -import static net.minecraft.util.text.TextFormatting.GRAY; - public abstract class AbstractFilterScreen extends AbstractSimiContainerScreen { protected AllGuiTextures background; @@ -68,7 +69,7 @@ public abstract class AbstractFilterScreen ex textRenderer.draw(ms, I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 3, 0xdedede); GuiGameElement.of(container.filterItem) - .at(x + background.width, guiTop + background.height - 60) + .at(x + background.width, guiTop + background.height - 60) .scale(5) .render(ms); diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java index 6ad481db5..93b98c4b7 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java @@ -1,5 +1,12 @@ package com.simibubi.create.content.schematics.block; +import static com.simibubi.create.foundation.gui.AllGuiTextures.SCHEMATIC_TABLE; +import static com.simibubi.create.foundation.gui.AllGuiTextures.SCHEMATIC_TABLE_PROGRESS; + +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; @@ -14,6 +21,7 @@ import com.simibubi.create.foundation.gui.widgets.Label; import com.simibubi.create.foundation.gui.widgets.ScrollInput; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; import com.simibubi.create.foundation.utility.Lang; + import net.minecraft.client.gui.IHasContainer; import net.minecraft.client.renderer.Rectangle2d; import net.minecraft.entity.player.PlayerInventory; @@ -23,13 +31,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -import static com.simibubi.create.foundation.gui.AllGuiTextures.SCHEMATIC_TABLE; -import static com.simibubi.create.foundation.gui.AllGuiTextures.SCHEMATIC_TABLE_PROGRESS; - public class SchematicTableScreen extends AbstractSimiContainerScreen implements IHasContainer { @@ -121,7 +122,7 @@ public class SchematicTableScreen extends AbstractSimiContainerScreenat(mainLeft + 217, mainTop + 50, -150) .scale(3) .render(matrixStack); diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java index 6d08924a9..f1e5a3032 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java @@ -262,7 +262,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreenat(guiLeft + 230, guiTop + 110, -200) .scale(5) .render(matrixStack); @@ -274,7 +274,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreenat(guiLeft + 150, guiTop + 46, 100) .scale(1) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java index aec2fc8c8..b775572c0 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java @@ -152,7 +152,7 @@ public class SchematicEditScreen extends AbstractSimiScreen { x + 93 - textRenderer.getStringWidth(handler.getCurrentSchematicName()) / 2, y + 3, 0xffffff); GuiGameElement.of(AllItems.SCHEMATIC.asStack()) - .at(guiLeft + 200, guiTop + 82, 0) + .at(guiLeft + 200, guiTop + 82, 0) .scale(3) .render(matrixStack); } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java index 64deb5e76..4f52cf885 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreen.java @@ -27,21 +27,15 @@ public abstract class ConfigScreen extends AbstractSimiScreen { /* * - * TODO * zelo's list for configUI + * TODO * - * adjust transition animation of screens -> disabled for now - * move config button's animations to ponder button or a new superclass - * get some proper icons for reset button and enum cycle - * - * some color themes maybe? - * at least a helper class to unite colors throughout different uis + * replace java's awt color with something mutable * * FIXME * - * tooltip are hidden underneath the scrollbar, if the bar is near the middle - * misalignment of the label-streak and textboxes/enum stuff - * framebuffer blending is incorrect + * tooltips are hidden underneath the scrollbar, if the bar is near the middle + * framebuffer blending is incorrect -> wait for jozu's changes to merge * * */ diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java index f5dd5ea9e..a9c0190c6 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/ConfigScreenList.java @@ -43,6 +43,8 @@ public class ConfigScreenList extends ExtendedList { 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); + UIRenderHelper.angledGradient(ms, 0, left, top + height / 2, height, 5, 0x60_000000, 0x0); + UIRenderHelper.angledGradient(ms, 180, right, top + height / 2, height, 5, 0x60_000000, 0x0); super.render(ms, mouseX, mouseY, partialTicks); } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java b/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java index 2858ace02..ace8dc2c0 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/SubMenuConfigScreen.java @@ -23,6 +23,7 @@ import com.simibubi.create.foundation.gui.Theme; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.widgets.BoxWidget; import com.simibubi.create.foundation.item.TooltipHelper; +import com.simibubi.create.foundation.networking.AllPackets; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.IGuiEventListener; @@ -78,6 +79,9 @@ public class SubMenuConfigScreen extends ConfigScreen { changes.forEach((path, value) -> { ForgeConfigSpec.ConfigValue configValue = values.get(path); configValue.set(value); + if (type == ModConfig.Type.SERVER) { + AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value)); + } }); clearChanges(); } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java index e9aae833d..73b03f892 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/EnumEntry.java @@ -1,6 +1,8 @@ package com.simibubi.create.foundation.config.ui.entries; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.DelegatedStencilElement; import com.simibubi.create.foundation.gui.TextStencilElement; import com.simibubi.create.foundation.gui.Theme; import com.simibubi.create.foundation.gui.UIRenderHelper; @@ -23,12 +25,18 @@ public class EnumEntry extends ValueEntry> { valueText = new TextStencilElement(Minecraft.getInstance().fontRenderer, "YEP").centered(true, true); valueText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.i(Theme.Key.TEXT_1), Theme.i(Theme.Key.TEXT_2))); - TextStencilElement l = new TextStencilElement(Minecraft.getInstance().fontRenderer, "<").centered(true, true); - cycleLeft = new BoxWidget(0, 0, 22, 22).showingElement(l).withCallback(() -> cycleValue(-1)); + DelegatedStencilElement l = AllIcons.I_CONFIG_PREV.asStencil(); + cycleLeft = new BoxWidget(0, 0, 22, 22) + .showingElement(l) + .rescaleElement(16, 16) + .withCallback(() -> cycleValue(-1)); l.withElementRenderer(BoxWidget.gradientFactory.apply(cycleLeft)); - TextStencilElement r = new TextStencilElement(Minecraft.getInstance().fontRenderer, ">").centered(true, true); - cycleRight = new BoxWidget(0, 0, 22, 22).showingElement(r).withCallback(() -> cycleValue(1)); + DelegatedStencilElement r = AllIcons.I_CONFIG_NEXT.asStencil(); + cycleRight = new BoxWidget(0, 0, 22, 22) + .showingElement(r) + .rescaleElement(16, 16) + .withCallback(() -> cycleValue(1)); r.withElementRenderer(BoxWidget.gradientFactory.apply(cycleRight)); listeners.add(cycleLeft); @@ -66,16 +74,16 @@ public class EnumEntry extends ValueEntry> { super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks); cycleLeft.x = x + getLabelWidth(width) + 2; - cycleLeft.y = y + 10; + cycleLeft.y = y + 12; cycleLeft.render(ms, mouseX, mouseY, partialTicks); valueText - .at(cycleLeft.x - 2 + cycleWidth, y + 10, 0) - .withBounds(width - getLabelWidth(width) - 2 * cycleWidth - resetWidth, 30) + .at(cycleLeft.x - 4 + cycleWidth, y + 12, 0) + .withBounds(width - getLabelWidth(width) - 2 * cycleWidth - resetWidth - 4, 22) .render(ms); cycleRight.x = x + width - cycleWidth - resetWidth + 2; - cycleRight.y = y + 10; + cycleRight.y = y + 12; cycleRight.render(ms, mouseX, mouseY, partialTicks); } diff --git a/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java index 7634edd0d..237cf8ff4 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java +++ b/src/main/java/com/simibubi/create/foundation/config/ui/entries/NumberEntry.java @@ -38,7 +38,7 @@ public abstract class NumberEntry extends ValueEntry { public NumberEntry(String label, ForgeConfigSpec.ConfigValue value, ForgeConfigSpec.ValueSpec 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, 26, unit); textField.setText(String.valueOf(getValue())); Object range = spec.getRange(); @@ -54,13 +54,13 @@ public abstract class NumberEntry extends ValueEntry { if (!min.equals(getTypeMin())) { StringTextComponent t = new StringTextComponent(formatBound(min) + " < "); minText = new TextStencilElement(font, t).centered(true, false); - minText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.c(Theme.Key.TEXT_ACCENT_1).darker().getRGB(), Theme.c(Theme.Key.TEXT_ACCENT_2).darker().getRGB())); + minText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.c(Theme.Key.TEXT_1).darker().getRGB(), Theme.c(Theme.Key.TEXT_2).darker().getRGB())); minOffset = font.getWidth(t); } if (!max.equals(getTypeMax())) { StringTextComponent t = new StringTextComponent(" < " + formatBound(max)); maxText = new TextStencilElement(font, t).centered(true, false); - maxText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.c(Theme.Key.TEXT_ACCENT_1).darker().getRGB(), Theme.c(Theme.Key.TEXT_ACCENT_2).darker().getRGB())); + maxText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.c(Theme.Key.TEXT_1).darker().getRGB(), Theme.c(Theme.Key.TEXT_2).darker().getRGB())); maxOffset = font.getWidth(t); } } catch (NoSuchFieldException | IllegalAccessException | ClassCastException | NullPointerException ignored) { @@ -126,7 +126,7 @@ public abstract class NumberEntry extends ValueEntry { textField.x = x + getLabelWidth(width) + minOffset; textField.y = y + 10; textField.setWidth(width - getLabelWidth(width) - resetWidth - minOffset - maxOffset); - textField.setHeight(30); + textField.setHeight(26); textField.render(ms, mouseX, mouseY, partialTicks); if (minText != null) diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index 3a4b55d80..99239b56f 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -132,7 +132,9 @@ public class AllIcons implements IScreenRenderable { I_CONFIG_DISCARD = next(), I_CONFIG_SAVE = next(), I_CONFIG_RESET = next(), - I_CONFIG_BACK = next(); + I_CONFIG_BACK = next(), + I_CONFIG_PREV = next(), + I_CONFIG_NEXT = next(); public AllIcons(int x, int y) { iconX = x * 16; diff --git a/src/main/java/com/simibubi/create/foundation/gui/BoxElement.java b/src/main/java/com/simibubi/create/foundation/gui/BoxElement.java index 334ef2490..04e607297 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/BoxElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/BoxElement.java @@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.utility.ColorHelper; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.Tessellator; @@ -85,10 +86,11 @@ public class BoxElement extends RenderElement { RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.shadeModel(GL11.GL_SMOOTH); - RenderSystem.color4f(1, 1, 1, alpha); int f = borderOffset; - Color c1 = background, c2 = borderTop, c3 = borderBot; + Color c1 = ColorHelper.applyAlpha(background, alpha); + Color c2 = ColorHelper.applyAlpha(borderTop, alpha); + Color c3 = ColorHelper.applyAlpha(borderBot, alpha); Tessellator tessellator = Tessellator.getInstance(); BufferBuilder b = tessellator.getBuffer(); Matrix4f model = ms.peek().getModel(); @@ -146,6 +148,5 @@ public class BoxElement extends RenderElement { RenderSystem.shadeModel(GL11.GL_FLAT); RenderSystem.disableBlend(); RenderSystem.enableTexture(); - RenderSystem.color4f(1, 1, 1, 1); } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java b/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java index c7e64981c..ec2990416 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ConfirmationScreen.java @@ -176,7 +176,7 @@ public class ConfirmationScreen extends AbstractSimiScreen { //ms.scale(1, 1, 0.01f); //todo wait for jozu's framebuffer capabilities on the other branch and use them here UIRenderHelper.framebuffer.bindFramebuffer(true); - source.render(ms, mouseX, mouseY, partialTicks); + source.render(ms, mouseX, mouseY, 10); UIRenderHelper.framebuffer.unbindFramebuffer(); Minecraft.getInstance().getFramebuffer().bindFramebuffer(true); ms.pop(); diff --git a/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java b/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java index e87bb3457..4966398e4 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java @@ -63,22 +63,22 @@ public class GuiGameElement { .with(FlowingFluidBlock.LEVEL, 0)); } - public static abstract class GuiRenderBuilder { - double xBeforeScale, yBeforeScale, zBeforeScale = 0; - double x, y, z; + public static abstract class GuiRenderBuilder extends RenderElement { + //double xBeforeScale, yBeforeScale, zBeforeScale = 0; + double xLocal, yLocal, zLocal; double xRot, yRot, zRot; double scale = 1; int color = 0xFFFFFF; Vector3d rotationOffset = Vector3d.ZERO; public GuiRenderBuilder atLocal(double x, double y, double z) { - this.x = x; - this.y = y; - this.z = z; + this.xLocal = x; + this.yLocal = y; + this.zLocal = z; return this; } - public GuiRenderBuilder at(double x, double y) { + /*public GuiRenderBuilder at(double x, double y) { this.xBeforeScale = x; this.yBeforeScale = y; return this; @@ -89,7 +89,7 @@ public class GuiGameElement { this.yBeforeScale = y; this.zBeforeScale = z; return this; - } + }*/ public GuiRenderBuilder rotate(double xRot, double yRot, double zRot) { this.xRot = xRot; @@ -136,9 +136,9 @@ public class GuiGameElement { @Deprecated protected void transform() { - RenderSystem.translated(xBeforeScale, yBeforeScale, 0); + RenderSystem.translated(x, y, 0); RenderSystem.scaled(scale, scale, scale); - RenderSystem.translated(x, y, z); + RenderSystem.translated(xLocal, yLocal, zLocal); RenderSystem.scaled(1, -1, 1); RenderSystem.translated(rotationOffset.x, rotationOffset.y, rotationOffset.z); RenderSystem.rotatef((float) zRot, 0, 0, 1); @@ -148,9 +148,9 @@ public class GuiGameElement { } protected void transformMatrix(MatrixStack matrixStack) { - matrixStack.translate(xBeforeScale, yBeforeScale, zBeforeScale); - matrixStack.scale((float) scale, (float) scale, (float) scale); matrixStack.translate(x, y, z); + matrixStack.scale((float) scale, (float) scale, (float) scale); + matrixStack.translate(xLocal, yLocal, zLocal); matrixStack.scale(1, -1, 1); matrixStack.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z); matrixStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion((float) zRot)); diff --git a/src/main/java/com/simibubi/create/foundation/gui/RenderElement.java b/src/main/java/com/simibubi/create/foundation/gui/RenderElement.java index 5300d8506..dcc6a3a0d 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/RenderElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/RenderElement.java @@ -8,6 +8,10 @@ public abstract class RenderElement implements IScreenRenderable { public static RenderElement EMPTY = new RenderElement() {@Override public void render(MatrixStack ms) {}}; + public static RenderElement of(IScreenRenderable renderable) { + return new SimpleRenderElement(renderable); + } + protected int width = 16, height = 16; protected float x = 0, y = 0, z = 0; protected float alpha = 1f; @@ -48,6 +52,18 @@ public abstract class RenderElement implements IScreenRenderable { return height; } + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public float getZ() { + return z; + } + public abstract void render(MatrixStack ms); @Override @@ -59,4 +75,18 @@ public abstract class RenderElement implements IScreenRenderable { public void draw(MatrixStack ms, int x, int y) { this.at(x, y).render(ms); } + + public static class SimpleRenderElement extends RenderElement { + + private IScreenRenderable renderable; + + public SimpleRenderElement(IScreenRenderable renderable) { + this.renderable = renderable; + } + + @Override + public void render(MatrixStack ms) { + renderable.draw(ms, (int) x, (int) y); + } + } } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java index fe7323783..f8539a3d3 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/AbstractSimiWidget.java @@ -14,6 +14,7 @@ import net.minecraft.util.text.StringTextComponent; public abstract class AbstractSimiWidget extends Widget { + protected float z; protected boolean wasHovered = false; protected List toolTip = new LinkedList<>(); protected BiConsumer onClick = (_$, _$$) -> {}; @@ -40,6 +41,12 @@ public abstract class AbstractSimiWidget extends Widget { return withCallback((_$, _$$) -> cb.run()); } + public T atZLevel(float z) { + this.z = z; + //noinspection unchecked + return (T) this; + } + public List getToolTip() { return toolTip; } diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/BoxWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/BoxWidget.java index b9ad08fb9..cdb80fd8c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/BoxWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/BoxWidget.java @@ -23,8 +23,8 @@ public class BoxWidget extends ElementWidget { protected Color customBorderBot; protected boolean animateColors = true; protected LerpedFloat colorAnimation = LerpedFloat.linear(); - protected Color gradientColor1 = Theme.c(Theme.Key.BUTTON_IDLE_1), gradientColor2 = Theme.c(Theme.Key.BUTTON_IDLE_2); - private Color colorTarget1, colorTarget2; + protected Color gradientColor1, gradientColor2; + private Color colorTarget1 = Theme.c(Theme.Key.BUTTON_IDLE_1), colorTarget2 = Theme.c(Theme.Key.BUTTON_IDLE_2); private Color previousColor1, previousColor2; public BoxWidget() { @@ -34,28 +34,40 @@ public class BoxWidget extends ElementWidget { public BoxWidget(int x, int y) { this(x, y, 16, 16); } + public BoxWidget(int x, int y, int width, int height) { super(x, y, width, height); box = new BoxElement() .at(x, y) .withBounds(width, height); + gradientColor1 = colorTarget1; + gradientColor2 = colorTarget2; } - public BoxWidget withBounds(int width, int height) { + public T withBounds(int width, int height) { this.width = width; this.height = height; - return this; + //noinspection unchecked + return (T) this; } - public BoxWidget withBorderColors(Color top, Color bot) { + public T withBorderColors(Color top, Color bot) { this.customBorderTop = top; this.customBorderBot = bot; updateColorsFromState(); - return this; + //noinspection unchecked + return (T) this; + } + + public T animateColors(boolean b) { + this.animateColors = b; + //noinspection unchecked + return (T) this; } @Override public void tick() { + super.tick(); colorAnimation.tickChaser(); } @@ -68,23 +80,6 @@ public class BoxWidget extends ElementWidget { startGradientAnimation(getColorForState(true), getColorForState(false), true, 0.15); } - @Override - public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { - float fadeValue = fade.getValue(partialTicks); - if (fadeValue < .1f) - return; - - box.withBackground(ColorHelper.applyAlpha(0xdd000000, fadeValue)) - .gradientBorder(gradientColor1, gradientColor2) - .at(x, y) - .withBounds(width, height) - .render(ms); - - super.renderButton(ms, mouseX, mouseY, partialTicks); - - wasHovered = hovered; - } - @Override protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { super.beforeRender(ms, mouseX, mouseY, partialTicks); @@ -97,7 +92,10 @@ public class BoxWidget extends ElementWidget { ); } - if (!colorAnimation.settled()) { + if (colorAnimation.settled()) { + gradientColor1 = colorTarget1; + gradientColor2 = colorTarget2; + } else { float animationValue = 1 - Math.abs(colorAnimation.getValue(partialTicks)); gradientColor1 = ColorHelper.mixColors(previousColor1, colorTarget1, animationValue); gradientColor2 = ColorHelper.mixColors(previousColor2, colorTarget2, animationValue); @@ -105,6 +103,24 @@ public class BoxWidget extends ElementWidget { } + @Override + public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + float fadeValue = fade.getValue(partialTicks); + if (fadeValue < .1f) + return; + + box.withAlpha(fadeValue); + box.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND)) + .gradientBorder(gradientColor1, gradientColor2) + .at(x, y, z) + .withBounds(width, height) + .render(ms); + + super.renderButton(ms, mouseX, mouseY, partialTicks); + + wasHovered = hovered; + } + @Override public boolean isMouseOver(double mX, double mY) { if (!active || !visible) @@ -122,8 +138,8 @@ public class BoxWidget extends ElementWidget { } public void updateColorsFromState() { - gradientColor1 = getColorForState(true); - gradientColor2 = getColorForState(false); + colorTarget1 = getColorForState(true); + colorTarget2 = getColorForState(false); } public void animateGradientFromState() { @@ -135,8 +151,12 @@ public class BoxWidget extends ElementWidget { } private void startGradientAnimation(Color c1, Color c2, boolean positive, double expSpeed) { + if (!animateColors) + return; + colorAnimation.startWithValue(positive ? 1 : -1); colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP); + colorAnimation.tickChaser(); previousColor1 = gradientColor1; previousColor2 = gradientColor2; diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/ElementWidget.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/ElementWidget.java index 985b9216a..96b05f45c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/ElementWidget.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/ElementWidget.java @@ -6,6 +6,7 @@ import java.util.function.UnaryOperator; import javax.annotation.Nonnull; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.IScreenRenderable; import com.simibubi.create.foundation.gui.RenderElement; import com.simibubi.create.foundation.utility.animation.LerpedFloat; @@ -36,6 +37,10 @@ public class ElementWidget extends AbstractSimiWidget { return (T) this; } + public T showing(IScreenRenderable renderable) { + return this.showingElement(RenderElement.of(renderable)); + } + public T modifyElement(Consumer consumer) { if (element != null) consumer.accept(element); @@ -66,6 +71,16 @@ public class ElementWidget extends AbstractSimiWidget { return (T) this; } + public LerpedFloat fade() { + return fade; + } + + public T fade(float target) { + fade.chase(target, 0.1, LerpedFloat.Chaser.EXP); + //noinspection unchecked + return (T) this; + } + public T rescaleElement(float rescaleSizeX, float rescaleSizeY) { this.rescaleElement = true; this.rescaleSizeX = rescaleSizeX; @@ -80,21 +95,39 @@ public class ElementWidget extends AbstractSimiWidget { return (T) this; } + @Override + public void tick() { + super.tick(); + fade.tickChaser(); + } + @Override protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { super.beforeRender(ms, mouseX, mouseY, partialTicks); - //todo fade + float fadeValue = fade.getValue(partialTicks); + element.withAlpha(fadeValue); + if (fadeValue < 1) { + ms.translate((1 - fadeValue) * fadeModX, (1 - fadeValue) * fadeModY, 0); + } } @Override public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { ms.push(); - ms.translate(x, y, 0); + ms.translate(x, y, z); + //element x/y get treated as a border around the element + float eX = element.getX(); + float eY = element.getY(); + float eWidth = width - 2 * eX; + float eHeight = height - 2 * eY; if (rescaleElement) { - ms.scale(width / rescaleSizeX, height / rescaleSizeY, 1); + float xScale = eWidth / rescaleSizeX; + float yScale = eHeight / rescaleSizeY; + ms.scale(xScale, yScale, 1); + element.at(eX / xScale, eY / yScale); } - element.withBounds(width, height).render(ms); + element.withBounds((int) eWidth, (int) eHeight).render(ms); ms.pop(); } diff --git a/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java index b340cd8d8..e9a2487de 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java @@ -13,6 +13,7 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.IScreenRenderable; 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.ponder.content.PonderTagScreen; import com.simibubi.create.foundation.ponder.ui.PonderButton; @@ -77,9 +78,9 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { if (screen instanceof PonderTagScreen) icon = ((PonderTagScreen) screen).getTag(); - widgets.add(backTrack = new PonderButton(31, height - 31 - PonderButton.SIZE, () -> { - ScreenOpener.openPreviousScreen(this, Optional.empty()); - }).fade(0, -1)); + widgets.add(backTrack = new PonderButton(31, height - 31 - 20) + .enableFade(0, 5) + .withCallback(() -> ScreenOpener.openPreviousScreen(this, Optional.empty()))); backTrack.fade(1); if (icon != null) @@ -98,7 +99,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { ms.push(); ms.translate(0, 0, 500); if (backTrack.isHovered()) { - textRenderer.draw(ms, Lang.translate(THINK_BACK), 15, height - 16, 0xffa3a3a3); + textRenderer.draw(ms, Lang.translate(THINK_BACK), 15, height - 16, Theme.i(Theme.Key.TEXT_2)); if (MathHelper.epsilonEquals(arrowAnimation.getValue(), arrowAnimation.getChaseTarget())) { arrowAnimation.setValue(1); arrowAnimation.setValue(1);//called twice to also set the previous value to 1 @@ -109,6 +110,17 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { @Override protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + if (backTrack != null) { + int x = (int) MathHelper.lerp(arrowAnimation.getValue(partialTicks), -9, 21); + int maxX = backTrack.x + backTrack.getWidth(); + + if (x + 30 < backTrack.x) + UIRenderHelper.breadcrumbArrow(ms, x + 30, height - 51, 0, maxX - (x + 30), 20, 5, 0x70aa9999, 0x30aa9999); + + UIRenderHelper.breadcrumbArrow(ms, x, height - 51, 0, 30, 20, 5, 0x70aa9999, 0x30aa9999); + UIRenderHelper.breadcrumbArrow(ms, x - 30, height - 51, 0, 30, 20, 5, 0x70aa9999, 0x30aa9999); + } + if (transition.getChaseTarget() == 0 || transition.settled()) { renderBackground(ms); return; @@ -164,17 +176,6 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen { ms.translate(depthPointX, depthPointY, 0); ms.scale((float) scale, (float) scale, 1); ms.translate(-depthPointX, -depthPointY, 0); - - if (backTrack != null) { - int x = (int) MathHelper.lerp(arrowAnimation.getValue(partialTicks), -9, 21); - int maxX = backTrack.x + backTrack.getWidth(); - - if (x + 30 < backTrack.x) - UIRenderHelper.breadcrumbArrow(ms, x + 30, height - 51, 0, maxX - (x + 30), 20, 5, 0x40aa9999, 0x10aa9999); - - UIRenderHelper.breadcrumbArrow(ms, x, height - 51, 0, 30, 20, 5, 0x40aa9999, 0x10aa9999); - UIRenderHelper.breadcrumbArrow(ms, x - 30, height - 51, 0, 30, 20, 5, 0x40aa9999, 0x10aa9999); - } } @Override diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java index de60e663c..c2ffcb9f5 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java @@ -1,7 +1,12 @@ package com.simibubi.create.foundation.ponder; +import javax.annotation.Nonnull; + +import org.antlr.v4.runtime.misc.IntegerList; + import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.foundation.gui.BoxElement; +import com.simibubi.create.foundation.gui.Theme; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ColorHelper; @@ -12,9 +17,6 @@ import net.minecraft.client.audio.SoundHandler; import net.minecraft.client.gui.FontRenderer; import net.minecraftforge.fml.client.gui.GuiUtils; -import javax.annotation.Nonnull; -import org.antlr.v4.runtime.misc.IntegerList; - public class PonderProgressBar extends AbstractSimiWidget { LerpedFloat progress; @@ -116,9 +118,16 @@ public class PonderProgressBar extends AbstractSimiWidget { * gradients have to be in front of the box so z>+100 * */ - ms.push(); - PonderUI.renderBox(ms, x, y, width, height, false); - ms.pop(); + new BoxElement() + .withBackground(0xff000000) + .gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)) + .at(x, y, 100) + .withBounds(width, height) + .render(ms); + + //ms.push(); + //PonderUI.renderBox(ms, x, y, width, height, false); + //ms.pop(); ms.push(); ms.translate(x - 2, y - 2, 0); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java index 8ccb33911..42698c264 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java @@ -8,7 +8,6 @@ import java.util.List; import java.util.Random; import java.util.stream.IntStream; -import org.apache.commons.lang3.mutable.MutableBoolean; import org.lwjgl.opengl.GL11; import com.mojang.blaze3d.matrix.MatrixStack; @@ -16,8 +15,10 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.BoxElement; import com.simibubi.create.foundation.gui.GuiGameElement; 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.ponder.PonderScene.SceneTransform; import com.simibubi.create.foundation.ponder.content.DebugScenes; @@ -43,14 +44,12 @@ import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.widget.Widget; -import net.minecraft.client.settings.KeyBinding; import net.minecraft.item.ItemStack; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MutableBoundingBox; -import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3f; import net.minecraft.util.text.IFormattableTextComponent; @@ -166,13 +165,16 @@ public class PonderUI extends NavigatableSimiScreen { int i = tagButtons.size(); int x = 31; int y = 81 + i * 30; - PonderButton b = new PonderButton(x, y, (mouseX, mouseY) -> { - centerScalingOn(mouseX, mouseY); - ScreenOpener.transitionTo(new PonderTagScreen(t)); - }).showing(t); - widgets.add(b); - tagButtons.add(b); + PonderButton b2 = new PonderButton(x, y) + .showing(t) + .withCallback((mX, mY) -> { + centerScalingOn(mX, mY); + ScreenOpener.transitionTo(new PonderTagScreen(t)); + }); + + widgets.add(b2); + tagButtons.add(b2); LerpedFloat chase = LerpedFloat.linear() .startWithValue(0) @@ -181,10 +183,10 @@ public class PonderUI extends NavigatableSimiScreen { }); - if (chapter != null) { + /*if (chapter != null) { widgets.add(chap = new PonderButton(width - 31 - 24, 31, () -> { }).showing(chapter)); - } + }*/ GameSettings bindings = client.gameSettings; int spacing = 8; @@ -193,53 +195,63 @@ public class PonderUI extends NavigatableSimiScreen { { int pX = (width / 2) - 110; - int pY = bY + PonderButton.SIZE + 4; + int pY = bY + 20 + 4; int pW = width - 2 * pX; widgets.add(progressBar = new PonderProgressBar(this, pX, pY, pW, 1)); } - widgets.add(scan = new PonderButton(bX, bY, () -> { - identifyMode = !identifyMode; - if (!identifyMode) - scenes.get(index) - .deselect(); - else - ponderPartialTicksPaused = client.getRenderPartialTicks(); - }).showing(AllIcons.I_MTD_SCAN) - .shortcut(bindings.keyBindDrop) - .fade(0, -1)); + widgets.add(scan = new PonderButton(bX, bY) + .withShortcut(bindings.keyBindDrop) + .showing(AllIcons.I_MTD_SCAN) + .enableFade(0, 5) + .withCallback(() -> { + identifyMode = !identifyMode; + if (!identifyMode) + scenes.get(index) + .deselect(); + else + ponderPartialTicksPaused = client.getRenderPartialTicks(); + })); - widgets.add(slowMode = new PonderButton(width - 20 - 31, bY, () -> { - setComfyReadingEnabled(!isComfyReadingEnabled()); - }).showing(AllIcons.I_MTD_SLOW_MODE) - .fade(0, -1)); + widgets.add(slowMode = new PonderButton(width - 20 - 31, bY) + .showing(AllIcons.I_MTD_SLOW_MODE) + .enableFade(0, 5) + .withCallback(() -> setComfyReadingEnabled(!isComfyReadingEnabled()))); if (PonderIndex.EDITOR_MODE) { - widgets.add(userMode = new PonderButton(width - 50 - 31, bY, () -> { - userViewMode = !userViewMode; - }).showing(AllIcons.I_MTD_USER_MODE) - .fade(0, -1)); + widgets.add(userMode = new PonderButton(width - 50 - 31, bY) + .showing(AllIcons.I_MTD_USER_MODE) + .enableFade(0, 5) + .withCallback(() -> userViewMode = !userViewMode)); } bX += 50 + spacing; - widgets.add(left = new PonderButton(bX, bY, () -> this.scroll(false)).showing(AllIcons.I_MTD_LEFT) - .shortcut(bindings.keyBindLeft) - .fade(0, -1)); + widgets.add(left = new PonderButton(bX, bY) + .withShortcut(bindings.keyBindLeft) + .showing(AllIcons.I_MTD_LEFT) + .enableFade(0, 5) + .withCallback(() -> this.scroll(false))); bX += 20 + spacing; - widgets.add(close = new PonderButton(bX, bY, this::onClose).showing(AllIcons.I_MTD_CLOSE) - .shortcut(bindings.keyBindInventory) - .fade(0, -1)); + widgets.add(close = new PonderButton(bX, bY) + .withShortcut(bindings.keyBindInventory) + .showing(AllIcons.I_MTD_CLOSE) + .enableFade(0, 5) + .withCallback(this::onClose)); bX += 20 + spacing; - widgets.add(right = new PonderButton(bX, bY, () -> this.scroll(true)).showing(AllIcons.I_MTD_RIGHT) - .shortcut(bindings.keyBindRight) - .fade(0, -1)); + widgets.add(right = new PonderButton(bX, bY) + .withShortcut(bindings.keyBindRight) + .showing(AllIcons.I_MTD_RIGHT) + .enableFade(0, 5) + .withCallback(() -> this.scroll(true))); bX += 50 + spacing; - widgets.add(replay = new PonderButton(bX, bY, this::replay).showing(AllIcons.I_MTD_REPLAY) - .shortcut(bindings.keyBindBack) - .fade(0, -1)); + widgets.add(replay = new PonderButton(bX, bY) + .withShortcut(bindings.keyBindBack) + .showing(AllIcons.I_MTD_REPLAY) + .enableFade(0, 5) + .withCallback(this::replay)); } @Override @@ -544,10 +556,17 @@ public class PonderUI extends NavigatableSimiScreen { int streakHeight = 35 - 9 + wordWrappedHeight; UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade), 0x101010); UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade), 0x101010); - renderBox(ms, 21, 21, 30, 30, false); + //renderBox(ms, 21, 21, 30, 30, false); + new BoxElement() + .withBackground(0xff000000) + .gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)) + .at(21, 21, 100) + .withBounds(30, 30) + .render(ms); + GuiGameElement.of(stack) - .at(x - 39, y - 11) + .at(x - 39, y - 11) .scale(2) .render(ms); @@ -640,15 +659,14 @@ public class PonderUI extends NavigatableSimiScreen { // Widgets widgets.forEach(w -> { if (w instanceof PonderButton) { - PonderButton mtdButton = (PonderButton) w; - mtdButton.fade(fade); + ((PonderButton) w).fade().startWithValue(fade); } }); if (index == 0 || index == 1 && lazyIndexValue < index) - left.fade(lazyIndexValue); + left.fade().startWithValue(lazyIndexValue); if (index == scenes.size() - 1 || index == scenes.size() - 2 && lazyIndexValue > index) - right.fade(scenes.size() - lazyIndexValue - 1); + right.fade().startWithValue(scenes.size() - lazyIndexValue - 1); boolean finished = activeScene.isFinished(); if (finished) @@ -718,7 +736,7 @@ public class PonderUI extends NavigatableSimiScreen { ms.pop(); } - protected void lowerButtonGroup(MatrixStack ms, int index, int mouseX, int mouseY, float fade, AllIcons icon, KeyBinding key) { + /*protected void lowerButtonGroup(MatrixStack ms, int index, int mouseX, int mouseY, float fade, AllIcons icon, KeyBinding key) { int bWidth = 20; int bHeight = 20; int bX = (width - bWidth) / 2 + (index - 1) * (bWidth + 8); @@ -732,7 +750,7 @@ public class PonderUI extends NavigatableSimiScreen { icon.draw(ms, bX + 2, bY + 2); drawCenteredText(ms, textRenderer, key.getBoundKeyLocalizedText(), bX + bWidth / 2 + 8, bY + bHeight - 6, 0xff606060); ms.pop(); - } + }*/ private void renderOverlay(MatrixStack ms, int i, float partialTicks) { if (identifyMode) @@ -745,7 +763,7 @@ public class PonderUI extends NavigatableSimiScreen { @Override public boolean mouseClicked(double x, double y, int button) { - MutableBoolean handled = new MutableBoolean(false); + /*MutableBoolean handled = new MutableBoolean(false); widgets.forEach(w -> { if (handled.booleanValue()) return; @@ -760,7 +778,7 @@ public class PonderUI extends NavigatableSimiScreen { }); if (handled.booleanValue()) - return true; + return true;*/ if (identifyMode && hoveredBlockPos != null && PonderIndex.EDITOR_MODE) { long handle = client.getWindow() @@ -845,9 +863,9 @@ public class PonderUI extends NavigatableSimiScreen { return hovered; } - public static void renderBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted) { + /*public static void renderBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted) { renderBox(ms, x, y, w, h, 0xff000000, highlighted ? 0xf0ffeedd : 0x40ffeedd, highlighted ? 0x60ffeedd : 0x20ffeedd); - } + }*/ public static void renderSpeechBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted, Pointing pointing, boolean returnWithLocalTransform) { @@ -895,7 +913,18 @@ public class PonderUI extends NavigatableSimiScreen { break; } - renderBox(ms, boxX, boxY, w, h, highlighted); + //renderBox(ms, boxX, boxY, w, h, highlighted); + BoxElement box = new BoxElement() + .withBackground(0xff000000) + .at(boxX, boxY, 100) + .withBounds(w, h); + + if (highlighted) + box.gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)); + else + box.gradientBorder(Theme.i(Theme.Key.PONDER_HIGHLIGHT_1), Theme.i(Theme.Key.PONDER_HIGHLIGHT_2)); + + box.render(ms); ms.push(); AllGuiTextures toRender = highlighted ? AllGuiTextures.SPEECH_TOOLTIP_HIGHLIGHT : AllGuiTextures.SPEECH_TOOLTIP; @@ -914,7 +943,7 @@ public class PonderUI extends NavigatableSimiScreen { } - public static void renderBox(MatrixStack ms, int x, int y, int w, int h, int backgroundColor, int borderColorStart, + /*public static void renderBox(MatrixStack ms, int x, int y, int w, int h, int backgroundColor, int borderColorStart, int borderColorEnd) { int z = 100; Matrix4f model = ms.peek().getModel(); @@ -927,7 +956,7 @@ public class PonderUI extends NavigatableSimiScreen { GuiUtils.drawGradientRect(model, z, x + w + 2, y - 3 + 1, x + w + 3, y + h + 3 - 1, borderColorStart, borderColorEnd); GuiUtils.drawGradientRect(model, z, x - 3, y - 3, x + w + 3, y - 3 + 1, borderColorStart, borderColorStart); GuiUtils.drawGradientRect(model, z, x - 3, y + h + 2, x + w + 3, y + h + 3, borderColorEnd, borderColorEnd); - } + }*/ public ItemStack getHoveredTooltipItem() { return hoveredTooltipItem; diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java index 1bdb5dfd2..1f1be9c0a 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java @@ -5,8 +5,6 @@ import java.util.List; import java.util.Objects; import com.mojang.blaze3d.matrix.MatrixStack; -import org.apache.commons.lang3.mutable.MutableBoolean; - import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlock; import com.simibubi.create.foundation.gui.ScreenOpener; @@ -106,17 +104,17 @@ public class PonderIndexScreen extends NavigatableSimiScreen { int itemCenterY = (int) (height * itemYmult); for (Item item : items) { - PonderButton button = - new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (x, y) -> { - if (!PonderRegistry.all.containsKey(item.getRegistryName())) - return; + PonderButton b = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4) + .showing(new ItemStack(item)) + .withCallback((x, y) -> { + if (!PonderRegistry.all.containsKey(item.getRegistryName())) + return; - centerScalingOn(x, y); - ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item))); - }).showing(new ItemStack(item)); + centerScalingOn(x, y); + ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item))); + }); - button.fade(1); - widgets.add(button); + widgets.add(b); layout.next(); } @@ -189,7 +187,7 @@ public class PonderIndexScreen extends NavigatableSimiScreen { ms.pop(); } - @Override + /*@Override public boolean mouseClicked(double x, double y, int button) { MutableBoolean handled = new MutableBoolean(false); widgets.forEach(w -> { @@ -207,7 +205,7 @@ public class PonderIndexScreen extends NavigatableSimiScreen { if (handled.booleanValue()) return true; return super.mouseClicked(x, y, button); - } + }*/ @Override public boolean isEquivalentTo(NavigatableSimiScreen other) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java index ae9e29c54..1181ccd51 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java @@ -1,15 +1,16 @@ package com.simibubi.create.foundation.ponder.content; +import java.awt.Color; import java.util.ArrayList; import java.util.List; import java.util.Objects; import com.mojang.blaze3d.matrix.MatrixStack; -import org.apache.commons.lang3.mutable.MutableBoolean; - import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.Create; +import com.simibubi.create.foundation.gui.BoxElement; 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.ponder.NavigatableSimiScreen; import com.simibubi.create.foundation.ponder.PonderLocalization; @@ -84,24 +85,26 @@ public class PonderTagScreen extends NavigatableSimiScreen { int itemCenterY = getItemsY(); for (Item i : items) { - final boolean canClick = PonderRegistry.all.containsKey(i.getRegistryName()); - PonderButton button = - new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (mouseX, mouseY) -> { - if (!canClick) - return; + PonderButton b = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4) + .showing(new ItemStack(i)); + + if (PonderRegistry.all.containsKey(i.getRegistryName())) { + b.withCallback((mouseX, mouseY) -> { centerScalingOn(mouseX, mouseY); ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i), tag)); - }).showing(new ItemStack(i)); - if (!canClick) + }); + } else { if (i.getRegistryName() - .getNamespace() - .equals(Create.ID)) - button.customColors(0x70984500, 0x70692400); + .getNamespace() + .equals(Create.ID)) + b.withBorderColors(new Color(0x70984500, true), new Color(0x70692400, true)) + .animateColors(false); else - button.customColors(0x505000FF, 0x50300077); + b.withBorderColors(new Color(0x505000FF, true), new Color(0x50300077, true)) + .animateColors(false); + } - button.fade(1); - widgets.add(button); + widgets.add(b); layout.next(); } @@ -109,23 +112,26 @@ public class PonderTagScreen extends NavigatableSimiScreen { ResourceLocation registryName = tag.getMainItem() .getItem() .getRegistryName(); - final boolean canClick = PonderRegistry.all.containsKey(registryName); - PonderButton button = - new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10, (mouseX, mouseY) -> { - if (!canClick) - return; - centerScalingOn(mouseX, mouseY); - ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag)); - }).showing(tag.getMainItem()); - if (!canClick) + + PonderButton b = new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10) + .showing(tag.getMainItem()); + + if (PonderRegistry.all.containsKey(registryName)) { + b.withCallback((mouseX, mouseY) -> { + centerScalingOn(mouseX, mouseY); + ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag)); + }); + } else { if (registryName.getNamespace() .equals(Create.ID)) - button.customColors(0x70984500, 0x70692400); + b.withBorderColors(new Color(0x70984500, true), new Color(0x70692400, true)) + .animateColors(false); else - button.customColors(0x505000FF, 0x50300077); + b.withBorderColors(new Color(0x505000FF, true), new Color(0x50300077, true)) + .animateColors(false); + } - button.fade(1); - widgets.add(button); + widgets.add(b); } // chapters @@ -188,7 +194,13 @@ public class PonderTagScreen extends NavigatableSimiScreen { int streakHeight = 35; UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, 240, 0x101010); - PonderUI.renderBox(ms, 21, 21, 30, 30, false); + //PonderUI.renderBox(ms, 21, 21, 30, 30, false); + new BoxElement() + .withBackground(0xff000000) + .gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)) + .at(21, 21, 100) + .withBounds(30, 30) + .render(ms); textRenderer.draw(ms, Lang.translate(PonderUI.PONDERING), x, y - 6, 0xffa3a3a3); y += 8; @@ -214,7 +226,14 @@ public class PonderTagScreen extends NavigatableSimiScreen { int h = textRenderer.getWordWrappedHeight(desc, w); - PonderUI.renderBox(ms, x - 3, y - 3, w + 6, h + 6, false); + //PonderUI.renderBox(ms, x - 3, y - 3, w + 6, h + 6, false); + new BoxElement() + .withBackground(0xff000000) + .gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)) + .at(x - 3, y - 3, 90) + .withBounds(w + 6, h + 6) + .render(ms); + ms.translate(0, 0, 100); FontHelper.drawSplitString(ms, textRenderer, desc, x, y, w, 0xeeeeee); ms.pop(); @@ -232,7 +251,14 @@ public class PonderTagScreen extends NavigatableSimiScreen { ms.push(); ms.translate(x, y, 0); - PonderUI.renderBox(ms, (sWidth - stringWidth) / 2 - 5, itemArea.getY() - 21, stringWidth + 10, 10, false); + //PonderUI.renderBox(ms, (sWidth - stringWidth) / 2 - 5, itemArea.getY() - 21, stringWidth + 10, 10, false); + new BoxElement() + .withBackground(0xff000000) + .gradientBorder(Theme.i(Theme.Key.PONDER_IDLE_1), Theme.i(Theme.Key.PONDER_IDLE_2)) + .at((sWidth - stringWidth) / 2f - 5, itemArea.getY() - 21, 100) + .withBounds(stringWidth + 10, 10) + .render(ms); + ms.translate(0, 0, 200); // UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 180, 0x101010); @@ -291,7 +317,7 @@ public class PonderTagScreen extends NavigatableSimiScreen { return hoveredItem; } - @Override + /*@Override public boolean mouseClicked(double x, double y, int button) { MutableBoolean handled = new MutableBoolean(false); widgets.forEach(w -> { @@ -310,7 +336,7 @@ public class PonderTagScreen extends NavigatableSimiScreen { if (handled.booleanValue()) return true; return super.mouseClicked(x, y, button); - } + }*/ @Override public boolean isEquivalentTo(NavigatableSimiScreen other) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java index 7f8badfb3..f87c70c28 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/InputWindowElement.java @@ -136,7 +136,7 @@ public class InputWindowElement extends AnimatedOverlayElement { if (hasItem) { GuiGameElement.of(item) - .at(keyWidth + (hasIcon ? 24 : 0), 0) + .at(keyWidth + (hasIcon ? 24 : 0), 0) .scale(1.5) .render(ms); RenderSystem.disableDepthTest(); diff --git a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java index 865a83100..73273e8d9 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/elements/TextWindowElement.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.function.Supplier; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.gui.BoxElement; import com.simibubi.create.foundation.ponder.PonderLocalization; import com.simibubi.create.foundation.ponder.PonderScene; import com.simibubi.create.foundation.ponder.PonderUI; @@ -110,7 +111,14 @@ public class TextWindowElement extends AnimatedOverlayElement { ms.push(); ms.translate(0, sceneToScreen.y, 400); - PonderUI.renderBox(ms, targetX - 10, 3, boxWidth, boxHeight - 1, 0xaa000000, 0x30eebb00, 0x10eebb00); + new BoxElement() + .withBackground(0xaa000000) + .gradientBorder(0x30eebb00, 0x10eebb00) + .at(targetX - 10, 3, 100) + .withBounds(boxWidth, boxHeight - 1) + .render(ms); + + //PonderUI.renderBox(ms, targetX - 10, 3, boxWidth, boxHeight - 1, 0xaa000000, 0x30eebb00, 0x10eebb00); int brighterColor = ColorHelper.mixAlphaColors(color, 0xFFffffdd, 1 / 2f); if (vec != null) { diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java index f8c5bad15..75772edf3 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java @@ -2,8 +2,9 @@ package com.simibubi.create.foundation.ponder.ui; import java.util.function.BiConsumer; +import javax.annotation.Nonnull; + import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; import com.simibubi.create.foundation.ponder.content.PonderChapter; @@ -11,8 +12,6 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.client.Minecraft; -import javax.annotation.Nonnull; - public class ChapterLabel extends AbstractSimiWidget { private final PonderChapter chapter; @@ -21,7 +20,9 @@ public class ChapterLabel extends AbstractSimiWidget { public ChapterLabel(PonderChapter chapter, int x, int y, BiConsumer onClick) { super(x, y, 175, 38); - this.button = new PonderButton(x + 4, y + 4, onClick, 30, 30).showing(chapter); + this.button = new PonderButton(x + 4, y + 4, 30, 30) + .showing(chapter) + .withCallback(onClick); this.button.fade(1); this.chapter = chapter; diff --git a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java index 220e7b90d..ffc1ecc39 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java @@ -1,191 +1,103 @@ package com.simibubi.create.foundation.ponder.ui; -import java.util.function.BiConsumer; +import java.awt.Color; + +import javax.annotation.Nonnull; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.GuiGameElement; -import com.simibubi.create.foundation.gui.IScreenRenderable; -import com.simibubi.create.foundation.gui.StencilElement; -import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget; -import com.simibubi.create.foundation.ponder.PonderUI; +import com.simibubi.create.foundation.gui.RenderElement; +import com.simibubi.create.foundation.gui.Theme; +import com.simibubi.create.foundation.gui.widgets.BoxWidget; +import com.simibubi.create.foundation.gui.widgets.ElementWidget; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ColorHelper; -import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.animation.LerpedFloat; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; -import javax.annotation.Nonnull; +public class PonderButton extends BoxWidget { -public class PonderButton extends AbstractSimiWidget { + protected ItemStack item; + protected KeyBinding shortcut; + protected LerpedFloat flash = LerpedFloat.linear().startWithValue(0).chase(0, 0.1f, LerpedFloat.Chaser.EXP); - private IScreenRenderable icon; - private boolean scaleIcon = true; - private ItemStack item; - protected boolean pressed; - private int xFadeModifier; - private int yFadeModifier; - private float fade; - private KeyBinding shortcut; - private LerpedFloat flash; - private Couple customPassiveBorder; + public PonderButton(int x, int y) { + this(x, y, 20, 20); + } - public static final int SIZE = 20; - - public PonderButton(int x, int y, BiConsumer onClick, int width, int height) { + public PonderButton(int x, int y, int width, int height) { super(x, y, width, height); - this.onClick = onClick; - flash = LerpedFloat.linear() - .startWithValue(0); + z = 400; } - public PonderButton(int x, int y, BiConsumer onClick) { - this(x, y, onClick, SIZE, SIZE); - } - - public PonderButton(int x, int y, Runnable onClick) { - this(x, y, ($, $$) -> onClick.run()); - } - - /** - * @param icon the icon to be rendered. assumed to be 16x16px in size. will be scaled to fit the button size - * - */ - public PonderButton showing(IScreenRenderable icon) { - this.icon = icon; - return this; - } - - public PonderButton showingUnscaled(IScreenRenderable icon) { - this.icon = icon; - this.scaleIcon = false; - return this; - } - - public PonderButton showing(ItemStack item) { - this.item = item; - return this; - } - - public PonderButton customColors(int start, int end) { - this.customPassiveBorder = Couple.create(start, end); - return this; - } - - public PonderButton shortcut(KeyBinding key) { + public T withShortcut(KeyBinding key) { this.shortcut = key; - return this; + //noinspection unchecked + return (T) this; } - public PonderButton fade(int xModifier, int yModifier) { - this.xFadeModifier = xModifier; - this.yFadeModifier = yModifier; - return this; + public T showing(ItemStack item) { + this.item = item; + return super.showingElement(GuiGameElement.of(item) + .scale(1.5f) + .at(-2, -2)); } - public void fade(float fade) { - this.fade = fade; + @Override + public T showingElement(RenderElement element) { + return super.showingElement(element.at(2, 2)); } public void flash() { - float value = flash.getValue(); - flash.setValue(value + (1 - value) * .2f); + flash.updateChaseTarget(1); } public void dim() { - float value = flash.getValue(); - flash.setValue(value * .5f); + flash.updateChaseTarget(0); + } + + @Override + public void tick() { + super.tick(); + flash.tickChaser(); + } + + @Override + protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + super.beforeRender(ms, mouseX, mouseY, partialTicks); + + float flashValue = flash.getValue(partialTicks); + if (flashValue > .1f) { + float sin = 0.5f + 0.5f * MathHelper.sin((AnimationTickHolder.getTicks(true) + partialTicks) / 6f); + sin *= flashValue; + Color c1 = gradientColor1; + Color c2 = gradientColor2; + Color nc1 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), MathHelper.clamp(c1.getAlpha() + 50, 0, 255)); + Color nc2 = new Color(c2.getRed(), c2.getGreen(), c2.getBlue(), MathHelper.clamp(c2.getAlpha() + 50, 0, 255)); + gradientColor1 = ColorHelper.mixColors(c1, nc1, sin); + gradientColor2 = ColorHelper.mixColors(c2, nc2, sin); + } } @Override public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) { - if (!visible) - return; - if (fade < .1f) + super.renderButton(ms, mouseX, mouseY, partialTicks); + float fadeValue = fade.getValue(); + + if (fadeValue < .1f) return; - hovered = isMouseOver(mouseX, mouseY) && fade > .75f; - - ms.push(); - RenderSystem.disableDepthTest(); - if (fade < 1) - ms.translate((1 - fade) * -5 * xFadeModifier, (1 - fade) * -5 * yFadeModifier, 0); - - float flashValue = flash.getValue(partialTicks); - if (flashValue > .1f) - fade *= 3 * flashValue + Math.sin((PonderUI.ponderTicks + partialTicks) / 6); - - int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade); - int borderColorStart = customPassiveBorder != null ? customPassiveBorder.getFirst() : hovered ? 0x70ffffff : 0x40aa9999; - int borderColorEnd = customPassiveBorder != null ? customPassiveBorder.getSecond() : hovered ? 0x30ffffff : 0x20aa9999; - borderColorStart = ColorHelper.applyAlpha(borderColorStart, fade); - borderColorEnd = ColorHelper.applyAlpha(borderColorEnd, fade); - - ms.translate(0, 0, 300); - PonderUI.renderBox(ms, x, y, width, height, backgroundColor, borderColorStart, borderColorEnd); - ms.translate(0, 0, 100); - - if (icon != null) { - RenderSystem.enableBlend(); - RenderSystem.color4f(1, 1, 1, fade); - ms.push(); - ms.translate(x + 2, y + 2, 0); - if (this.scaleIcon) - ms.scale((width - 4) / 16f, (height - 4) / 16f, 1); - else { - if (icon instanceof StencilElement){ - ((StencilElement) icon).withBounds(width - 4, height - 4); - } - } - - icon.draw(ms, this, 0, 0); - ms.pop(); + if (shortcut != null) { + ms.translate(0, 0, z+50); + drawCenteredText(ms, Minecraft.getInstance().fontRenderer, shortcut.getBoundKeyLocalizedText(), x + width / 2 + 8, y + height - 6, ColorHelper.applyAlpha(Theme.i(Theme.Key.TEXT_2), fadeValue)); } - if (item != null) { - ms.push(); - ms.translate(0, 0, -100); - GuiGameElement.of(item) - .at(x - 2, y - 2) - .scale(1.5f) - .render(ms); - ms.pop(); - } - if (shortcut != null) - drawCenteredText(ms, Minecraft.getInstance().fontRenderer, shortcut.getBoundKeyLocalizedText(), x + width / 2 + 8, - y + height - 6, ColorHelper.applyAlpha(0xff606060, fade)); - - ms.pop(); } - @Override - public void onClick(double p_onClick_1_, double p_onClick_3_) { - super.onClick(p_onClick_1_, p_onClick_3_); - this.pressed = true; - } - - @Override - public void onRelease(double p_onRelease_1_, double p_onRelease_3_) { - super.onRelease(p_onRelease_1_, p_onRelease_3_); - this.pressed = false; - } - - /*public void setToolTip(String text) { - toolTip.clear(); - toolTip.add(text); - }*/ - public ItemStack getItem() { return item; } - - @Override - public boolean isMouseOver(double x, double y) { - double m = 4; - x = Math.floor(x); - y = Math.floor(y); - return active && visible - && !(x < this.x - m || x > this.x + width + m - 1 || y < this.y - m || y > this.y + height + m - 1); - } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java b/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java index e75f5ff1d..0da4d1db6 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java @@ -2,27 +2,35 @@ package com.simibubi.create.foundation.utility; import com.simibubi.create.foundation.ponder.PonderUI; import com.simibubi.create.foundation.ponder.PonderWorld; - import com.simibubi.create.foundation.utility.worldWrappers.WrappedClientWorld; + import net.minecraft.client.Minecraft; import net.minecraft.world.IWorld; public class AnimationTickHolder { private static int ticks; + private static int paused_ticks; public static void reset() { ticks = 0; + paused_ticks = 0; } public static void tick() { if (!Minecraft.getInstance().isGamePaused()) { ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision + } else { + paused_ticks = (paused_ticks + 1) % 1_728_000; } } public static int getTicks() { - return ticks; + return getTicks(false); + } + + public static int getTicks(boolean includePaused) { + return includePaused ? ticks + paused_ticks : ticks; } public static float getRenderTime() { diff --git a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java index 5c2544e77..25a54716b 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/ColorHelper.java @@ -42,6 +42,10 @@ public class ColorHelper { return (color & 0xFFFFFF) | alphaChannel << 24; } + public static Color applyAlpha(Color c, float alpha) { + return new Color(applyAlpha(c.getRGB(), alpha), true); + } + public static int mixColors(int color1, int color2, float w) { int r1 = (color1 >> 16); int g1 = (color1 >> 8) & 0xFF; diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 74fe5caee4e8cf10a66eec7699e8e47d4e6346f4..e27a7e64805274e21956527bae741398ad9aad1f 100644 GIT binary patch delta 12654 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 a=pkSS<+_SAl0O6ehmY@-<*H;%LjE7KOquQg delta 12356 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