mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-05 03:12:38 +01:00
Merge branch 'mc1.16/config-ui' into mc1.16/dev
# Conflicts: # src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleConfigScreen.java # src/main/java/com/simibubi/create/foundation/command/AllCommands.java # src/main/java/com/simibubi/create/foundation/command/FabulousWarningCommand.java # src/main/java/com/simibubi/create/foundation/command/OverlayConfigCommand.java # src/main/java/com/simibubi/create/foundation/command/PonderCommand.java # src/main/java/com/simibubi/create/foundation/command/ToggleDebugCommand.java # src/main/java/com/simibubi/create/foundation/command/ToggleExperimentalRenderingCommand.java # src/main/java/com/simibubi/create/foundation/gui/AbstractSimiContainerScreen.java # src/main/java/com/simibubi/create/foundation/gui/AbstractSimiScreen.java # src/main/java/com/simibubi/create/foundation/gui/AllIcons.java # src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java # src/main/java/com/simibubi/create/foundation/ponder/NavigatableSimiScreen.java # src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java # src/main/java/com/simibubi/create/foundation/ponder/PonderUI.java # src/main/java/com/simibubi/create/foundation/ponder/content/PonderIndexScreen.java # src/main/java/com/simibubi/create/foundation/ponder/content/PonderTagScreen.java # src/main/java/com/simibubi/create/foundation/ponder/ui/ChapterLabel.java # src/main/java/com/simibubi/create/foundation/ponder/ui/PonderButton.java # src/main/resources/create.mixins.json
This commit is contained in:
commit
c36346b97d
72 changed files with 3560 additions and 578 deletions
|
@ -13,6 +13,7 @@ import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivit
|
|||
import com.simibubi.create.content.schematics.ClientSchematicLoader;
|
||||
import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler;
|
||||
import com.simibubi.create.content.schematics.client.SchematicHandler;
|
||||
import com.simibubi.create.events.ClientEvents;
|
||||
import com.simibubi.create.foundation.ResourceReloadHandler;
|
||||
import com.simibubi.create.foundation.block.render.CustomBlockModels;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
||||
|
@ -80,6 +81,7 @@ public class CreateClient {
|
|||
modEventBus.addListener(CreateClient::onModelRegistry);
|
||||
modEventBus.addListener(CreateClient::onTextureStitch);
|
||||
modEventBus.addListener(AllParticleTypes::registerFactories);
|
||||
modEventBus.addListener(ClientEvents::loadCompleted);
|
||||
|
||||
Backend.init();
|
||||
OptifineHandler.init();
|
||||
|
@ -110,11 +112,14 @@ public class CreateClient {
|
|||
PonderIndex.registerTags();
|
||||
|
||||
UIRenderHelper.init();
|
||||
UIRenderHelper.enableStencil();
|
||||
|
||||
IResourceManager resourceManager = Minecraft.getInstance()
|
||||
.getResourceManager();
|
||||
if (resourceManager instanceof IReloadableResourceManager)
|
||||
((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void onTextureStitch(TextureStitchEvent.Pre event) {
|
||||
|
|
|
@ -88,7 +88,7 @@ public class BlockzapperUpgradeCategory extends CreateRecipeCategory<Blockzapper
|
|||
font.drawWithShadow(matrixStack, textComponent, (BLOCKZAPPER_UPGRADE_RECIPE.width - font.getStringWidth(textComponent.getString())) / 2f, 57, 0x8B8B8B);
|
||||
|
||||
GuiGameElement.of(recipe.getRecipeOutput())
|
||||
.at(90, 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(90, 0)
|
||||
.scale(3.5)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
|
|||
tag.put("Polishing", matchingStacks[0].serializeNBT());
|
||||
tag.putBoolean("JEI", true);
|
||||
GuiGameElement.of(renderedSandpaper)
|
||||
.at(getBackground().getWidth() / 2 - 16, 0, 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(getBackground().getWidth() / 2 - 16, 0, 0)
|
||||
.scale(2)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
0xffffff);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + background.width + 10, guiTop + 100, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + background.width + 10, guiTop + 100, -150)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class SymmetryWandScreen extends AbstractSimiScreen {
|
|||
|
||||
renderBlock(matrixStack);
|
||||
GuiGameElement.of(wand)
|
||||
.at(guiLeft + 190, guiTop + 420, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 190, guiTop + 420, -150)
|
||||
.scale(4)
|
||||
.rotate(-70, 20, 20)
|
||||
.render(matrixStack);
|
||||
|
|
|
@ -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)
|
||||
.<GuiGameElement.GuiRenderBuilder>at((this.width - this.sWidth) / 2 + 200, this.height / 2 - this.sHeight / 4 + 25, -150)
|
||||
.scale(4)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public class AdjustableCrateScreen extends AbstractSimiContainerScreen<Adjustabl
|
|||
}
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 70, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 70, -150)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public class StockpileSwitchScreen extends AbstractSimiScreen {
|
|||
|
||||
matrixStack.push();
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
matrixStack.pop();
|
||||
|
|
|
@ -69,7 +69,7 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterContainer> 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)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(x + background.width, guiTop + background.height - 60)
|
||||
.scale(5)
|
||||
.render(ms);
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen<SchematicT
|
|||
textRenderer.drawWithShadow(matrixStack, noSchematics, mainLeft + 54, mainTop + 26, 0xd3d3d3);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(mainLeft + 217, mainTop + 50, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(mainLeft + 217, mainTop + 50, -150)
|
||||
.scale(3)
|
||||
.render(matrixStack);
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
renderBlueprintHighlight(matrixStack);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + 230, guiTop + 110, -200)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 230, guiTop + 110, -200)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
|
||||
|
@ -274,7 +274,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
if (te.missingItem != null) {
|
||||
stringWidth += 15;
|
||||
GuiGameElement.of(te.missingItem)
|
||||
.at(guiLeft + 150, guiTop + 46, 100)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 150, guiTop + 46, 100)
|
||||
.scale(1)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 200, guiTop + 82, 0)
|
||||
.scale(3)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperR
|
|||
import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
@ -78,7 +79,11 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
|||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ExtensionPoint;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ClientEvents {
|
||||
|
@ -310,4 +315,9 @@ public class ClientEvents {
|
|||
}
|
||||
}
|
||||
|
||||
public static void loadCompleted(FMLLoadCompleteEvent event) {
|
||||
ModContainer createContainer = ModList.get().getModContainerById("create").orElseThrow(() -> new IllegalStateException("Create Mod Container missing after loadCompleted"));
|
||||
createContainer.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (mc, previousScreen) -> new BaseConfigScreen(previousScreen));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,20 +21,22 @@ public class AllCommands {
|
|||
LiteralCommandNode<CommandSource> util = buildUtilityCommands();
|
||||
|
||||
LiteralCommandNode<CommandSource> createRoot = dispatcher.register(Commands.literal("create")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
// general purpose
|
||||
.then(new ToggleExperimentalRenderingCommand().register())
|
||||
.then(new ToggleDebugCommand().register())
|
||||
.then(FabulousWarningCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(HighlightCommand.register())
|
||||
.then(CouplingCommand.register())
|
||||
.then(CloneCommand.register())
|
||||
.then(PonderCommand.register())
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
// general purpose
|
||||
.then(new ToggleExperimentalRenderingCommand().register())
|
||||
.then(new ToggleDebugCommand().register())
|
||||
.then(FabulousWarningCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(HighlightCommand.register())
|
||||
.then(CouplingCommand.register())
|
||||
.then(ConfigCommand.register())
|
||||
.then(PonderCommand.register())
|
||||
.then(CloneCommand.register())
|
||||
|
||||
// utility
|
||||
.then(util));
|
||||
// utility
|
||||
.then(util)
|
||||
);
|
||||
|
||||
createRoot.addChild(buildRedirect("u", util));
|
||||
|
||||
|
@ -50,12 +52,12 @@ public class AllCommands {
|
|||
private static LiteralCommandNode<CommandSource> buildUtilityCommands() {
|
||||
|
||||
return Commands.literal("util")
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
.then(FlySpeedCommand.register())
|
||||
// .then(KillTPSCommand.register())
|
||||
.build();
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
.then(FlySpeedCommand.register())
|
||||
//.then(KillTPSCommand.register())
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
|
@ -72,15 +74,15 @@ public class AllCommands {
|
|||
*
|
||||
* @return the built node
|
||||
*/
|
||||
public static LiteralCommandNode<CommandSource> buildRedirect(final String alias,
|
||||
final LiteralCommandNode<CommandSource> destination) {
|
||||
public static LiteralCommandNode<CommandSource> buildRedirect(final String alias, final LiteralCommandNode<CommandSource> destination) {
|
||||
// Redirects only work for nodes with children, but break the top argument-less command.
|
||||
// Manually adding the root command after setting the redirect doesn't fix it.
|
||||
// See https://github.com/Mojang/brigadier/issues/46). Manually clone the node instead.
|
||||
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder.<CommandSource>literal(alias)
|
||||
.requires(destination.getRequirement())
|
||||
.forward(destination.getRedirect(), destination.getRedirectModifier(), destination.isFork())
|
||||
.executes(destination.getCommand());
|
||||
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder
|
||||
.<CommandSource>literal(alias)
|
||||
.requires(destination.getRequirement())
|
||||
.forward(destination.getRedirect(), destination.getRedirectModifier(), destination.isFork())
|
||||
.executes(destination.getCommand());
|
||||
for (CommandNode<CommandSource> child : destination.getChildren()) {
|
||||
builder.then(child);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.foundation.command;
|
||||
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.Commands;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
||||
public class ConfigCommand {
|
||||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("config")
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource().asPlayer();
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.configScreen.name(), "")
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -13,16 +13,18 @@ public class FabulousWarningCommand {
|
|||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("dismissFabulousWarning")
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource()
|
||||
.asPlayer();
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource()
|
||||
.asPlayer();
|
||||
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fabulousWarning.name(), ""));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fabulousWarning.name(), "")
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class FixLightingCommand {
|
|||
.executes(ctx -> {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(
|
||||
|
|
|
@ -15,35 +15,32 @@ public class OverlayConfigCommand {
|
|||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("overlay")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.then(Commands.literal("reset")
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> ConfigureConfigPacket.Actions.overlayReset.performAction(""));
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.then(Commands.literal("reset")
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayReset.performAction(""));
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER,
|
||||
() -> () -> AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayReset.name(), "")));
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayReset.name(), "")));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("reset overlay offset"), true);
|
||||
|
||||
return 1;
|
||||
}))
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> ConfigureConfigPacket.Actions.overlayScreen.performAction(""));
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayScreen.performAction(""));
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER,
|
||||
() -> () -> AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayScreen.name(), "")));
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayScreen.name(), "")));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("window opened"), true);
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("window opened"), true);
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
|
|
@ -21,26 +21,20 @@ import net.minecraftforge.common.util.FakePlayer;
|
|||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class PonderCommand {
|
||||
public static final SuggestionProvider<CommandSource> ITEM_PONDERS = SuggestionProviders.register(
|
||||
new ResourceLocation("all_ponders"),
|
||||
(iSuggestionProviderCommandContext, builder) -> ISuggestionProvider.func_212476_a(PonderRegistry.all.keySet()
|
||||
.stream(), builder));
|
||||
public static final SuggestionProvider<CommandSource> ITEM_PONDERS = SuggestionProviders.register(new ResourceLocation("all_ponders"), (iSuggestionProviderCommandContext, builder) -> ISuggestionProvider.func_212476_a(PonderRegistry.all.keySet().stream(), builder));
|
||||
|
||||
static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("ponder")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.executes(ctx -> openScene("index", ctx.getSource()
|
||||
.asPlayer()))
|
||||
.then(Commands.argument("scene", ResourceLocationArgument.resourceLocation())
|
||||
.suggests(ITEM_PONDERS)
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene")
|
||||
.toString(),
|
||||
ctx.getSource()
|
||||
.asPlayer()))
|
||||
.then(Commands.argument("targets", EntityArgument.players())
|
||||
.requires(cs -> cs.hasPermissionLevel(2))
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene")
|
||||
.toString(), EntityArgument.getPlayers(ctx, "targets")))));
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.executes(ctx -> openScene("index", ctx.getSource().asPlayer()))
|
||||
.then(Commands.argument("scene", ResourceLocationArgument.resourceLocation())
|
||||
.suggests(ITEM_PONDERS)
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene").toString(), ctx.getSource().asPlayer()))
|
||||
.then(Commands.argument("targets", EntityArgument.players())
|
||||
.requires(cs -> cs.hasPermissionLevel(2))
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene").toString(), EntityArgument.getPlayers(ctx, "targets")))
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -53,8 +47,9 @@ public class PonderCommand {
|
|||
if (player instanceof FakePlayer)
|
||||
continue;
|
||||
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.openPonder.name(), sceneId));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.openPonder.name(), sceneId));
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
||||
|
@ -31,17 +32,17 @@ import net.minecraftforge.common.ForgeConfig;
|
|||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
public class ConfigureConfigPacket extends SimplePacketBase {
|
||||
public class SConfigureConfigPacket extends SimplePacketBase {
|
||||
|
||||
private final String option;
|
||||
private final String value;
|
||||
|
||||
public ConfigureConfigPacket(String option, String value) {
|
||||
public SConfigureConfigPacket(String option, String value) {
|
||||
this.option = option;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ConfigureConfigPacket(PacketBuffer buffer) {
|
||||
public SConfigureConfigPacket(PacketBuffer buffer) {
|
||||
this.option = buffer.readString(32767);
|
||||
this.value = buffer.readString(32767);
|
||||
}
|
||||
|
@ -69,7 +70,8 @@ public class ConfigureConfigPacket extends SimplePacketBase {
|
|||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
enum Actions {
|
||||
public enum Actions {
|
||||
configScreen(() -> Actions::configScreen),
|
||||
rainbowDebug(() -> Actions::rainbowDebug),
|
||||
overlayScreen(() -> Actions::overlayScreen),
|
||||
fixLighting(() -> Actions::experimentalLighting),
|
||||
|
@ -91,6 +93,11 @@ public class ConfigureConfigPacket extends SimplePacketBase {
|
|||
.accept(value);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void configScreen(String value) {
|
||||
ScreenOpener.open(new BaseConfigScreen(null));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void rainbowDebug(String value) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
|
@ -13,7 +13,9 @@ public class ToggleDebugCommand extends ConfigureConfigCommand {
|
|||
|
||||
@Override
|
||||
protected void sendPacket(ServerPlayerEntity player, String option) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), option));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.rainbowDebug.name(), option)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ public class ToggleExperimentalRenderingCommand extends ConfigureConfigCommand {
|
|||
|
||||
@Override
|
||||
protected void sendPacket(ServerPlayerEntity player, String option) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), option));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.experimentalRendering.name(), option)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@ public abstract class ConfigBase {
|
|||
if (comment.length > 0) {
|
||||
String[] comments = new String[comment.length + 1];
|
||||
comments[0] = "";
|
||||
for (int i = 0; i < comment.length; i++)
|
||||
comments[i + 1] = comment[i];
|
||||
System.arraycopy(comment, 0, comments, 1, comment.length);
|
||||
builder.comment(comments);
|
||||
} else
|
||||
builder.comment("");
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class BaseConfigScreen extends ConfigScreen {
|
||||
|
||||
BoxWidget clientConfigWidget;
|
||||
BoxWidget commonConfigWidget;
|
||||
BoxWidget serverConfigWidget;
|
||||
|
||||
public BaseConfigScreen(Screen parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
widgets.clear();
|
||||
super.init();
|
||||
|
||||
TextStencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("Client Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(clientConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15 - 30, 200, 16)
|
||||
.showingElement(text)
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.CLIENT, AllConfigs.CLIENT.specification)))
|
||||
);
|
||||
text.withElementRenderer(BoxWidget.gradientFactory.apply(clientConfigWidget));
|
||||
|
||||
TextStencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("World Generation Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(commonConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15, 200, 16)
|
||||
.showingElement(text2)
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.COMMON, AllConfigs.COMMON.specification)))
|
||||
);
|
||||
text2.withElementRenderer(BoxWidget.gradientFactory.apply(commonConfigWidget));
|
||||
|
||||
TextStencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("Gameplay Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(serverConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15 + 30, 200, 16)
|
||||
.showingElement(text3)
|
||||
);
|
||||
|
||||
if (Minecraft.getInstance().world != null) {
|
||||
serverConfigWidget.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, AllConfigs.SERVER.specification)));
|
||||
text3.withElementRenderer(BoxWidget.gradientFactory.apply(serverConfigWidget));
|
||||
} else {
|
||||
serverConfigWidget.active = false;
|
||||
serverConfigWidget.updateColorsFromState();
|
||||
text3.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.i(Theme.Key.BUTTON_DISABLE, true), Theme.i(Theme.Key.BUTTON_DISABLE, false) | 0x40_000000));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class CConfigureConfigPacket<T> extends SimplePacketBase {
|
||||
|
||||
private String path;
|
||||
private String value;
|
||||
|
||||
public CConfigureConfigPacket(String path, T value) {
|
||||
this.path = path;
|
||||
this.value = serialize(value);
|
||||
}
|
||||
|
||||
public CConfigureConfigPacket(PacketBuffer buffer) {
|
||||
this.path = buffer.readString(32767);
|
||||
this.value = buffer.readString(32767);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeString(path);
|
||||
buffer.writeString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<NetworkEvent.Context> context) {
|
||||
ServerPlayerEntity sender = context.get().getSender();
|
||||
if (sender == null || !sender.hasPermissionLevel(2))
|
||||
return;
|
||||
|
||||
ForgeConfigSpec.ValueSpec valueSpec = AllConfigs.SERVER.specification.getRaw(path);
|
||||
ForgeConfigSpec.ConfigValue<T> configValue = AllConfigs.SERVER.specification.getValues().get(path);
|
||||
|
||||
T v = (T) deserialize(configValue.get(), value);
|
||||
if (!valueSpec.test(v))
|
||||
return;
|
||||
|
||||
configValue.set(v);
|
||||
|
||||
}
|
||||
|
||||
public String serialize(T value) {
|
||||
if (value instanceof Boolean)
|
||||
return Boolean.toString((Boolean) value);
|
||||
if (value instanceof Enum<?>)
|
||||
return ((Enum<?>) value).name();
|
||||
if (value instanceof Integer)
|
||||
return Integer.toString((Integer) value);
|
||||
if (value instanceof Float)
|
||||
return Float.toString((Float) value);
|
||||
if (value instanceof Double)
|
||||
return Double.toString((Double) value);
|
||||
|
||||
throw new IllegalArgumentException("unknown type " + value + ": " + value.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public Object deserialize(Object type, String sValue) {
|
||||
if (type instanceof Boolean)
|
||||
return Boolean.parseBoolean(sValue);
|
||||
if (type instanceof Enum<?>)
|
||||
return Enum.valueOf(((Enum<?>) type).getClass(), sValue);
|
||||
if (type instanceof Integer)
|
||||
return Integer.parseInt(sValue);
|
||||
if (type instanceof Float)
|
||||
return Float.parseFloat(sValue);
|
||||
if (type instanceof Double)
|
||||
return Double.parseDouble(sValue);
|
||||
|
||||
throw new IllegalArgumentException("unknown type " + type + ": " + type.getClass().getSimpleName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.StencilElement;
|
||||
import com.simibubi.create.foundation.utility.animation.Force;
|
||||
import com.simibubi.create.foundation.utility.animation.PhysicalFloat;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public abstract class ConfigScreen extends AbstractSimiScreen {
|
||||
|
||||
/*
|
||||
*
|
||||
* zelo's list for configUI
|
||||
* TODO
|
||||
*
|
||||
* replace java's awt color with something mutable
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* tooltips are hidden underneath the scrollbar, if the bar is near the middle
|
||||
* framebuffer blending is incorrect -> wait for jozu's changes to merge
|
||||
*
|
||||
* */
|
||||
|
||||
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;
|
||||
|
||||
public ConfigScreen(Screen parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
cogSpin.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderBackground(@Nonnull MatrixStack ms) {
|
||||
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this, ms));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
//RenderSystem.disableDepthTest();
|
||||
if (this.client != null && this.client.world != null) {
|
||||
fill(ms, 0, 0, this.width, this.height, 0xb0_282c34);
|
||||
} else {
|
||||
fill(ms, 0, 0, this.width, this.height, 0xff_282c34);
|
||||
}
|
||||
|
||||
new StencilElement() {
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
renderCog(ms, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
fill(ms, -200, -200, 200, 200, 0x60_000000);
|
||||
}
|
||||
}.at(width * 0.5f, height * 0.5f, 0).render(ms);
|
||||
|
||||
super.renderWindowBackground(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = (int) (width * 0.5f);
|
||||
int y = (int) (height * 0.5f);
|
||||
//this.drawHorizontalLine(ms, x-25, x+25, y, 0xff_807060);
|
||||
//this.drawVerticalLine(ms, x, y-25, y+25, 0xff_90a0b0);
|
||||
|
||||
//this.testStencil.render(ms);
|
||||
|
||||
//UIRenderHelper.streak(ms, 0, mouseX, mouseY, 16, 50, 0xaa_1e1e1e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
|
||||
cogSpin.bump(3, -delta * 5);
|
||||
|
||||
return super.mouseScrolled(mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
public static String toHumanReadable(String key) {
|
||||
String s = key.replaceAll("_", " ");
|
||||
s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(s)).map(StringUtils::capitalize).collect(Collectors.joining(" "));
|
||||
s = s.replaceAll("\\s\\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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
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.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.IGuiEventListener;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.gui.widget.list.ExtendedList;
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.fml.client.gui.GuiUtils;
|
||||
|
||||
public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
|
||||
|
||||
public static TextFieldWidget currentText;
|
||||
|
||||
public boolean isForServer = false;
|
||||
|
||||
public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) {
|
||||
super(client, width, height, top, bottom, elementHeight);
|
||||
func_244605_b(false);
|
||||
func_244606_c(false);
|
||||
setRenderSelection(false);
|
||||
currentText = null;
|
||||
headerHeight = 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
//render tmp background
|
||||
//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);
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderList(MatrixStack p_238478_1_, int p_238478_2_, int p_238478_3_, int p_238478_4_, int p_238478_5_, float p_238478_6_) {
|
||||
MainWindow window = Minecraft.getInstance().getWindow();
|
||||
double d0 = window.getGuiScaleFactor();
|
||||
RenderSystem.enableScissor((int) (this.left * d0), (int) (window.getFramebufferHeight() - (this.bottom * d0)), (int) (this.width * d0), (int) (this.height * d0));
|
||||
super.renderList(p_238478_1_, p_238478_2_, p_238478_3_, p_238478_4_, p_238478_5_, p_238478_6_);
|
||||
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
|
||||
public int getRowWidth() {
|
||||
return width - 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrollbarPositionX() {
|
||||
return left + this.width - 6;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
//children().forEach(Entry::tick);
|
||||
for(int i = 0; i < getItemCount(); ++i) {
|
||||
int top = this.getRowTop(i);
|
||||
int bot = top + itemHeight;
|
||||
if (bot >= this.top && top <= this.bottom)
|
||||
this.getEntry(i).tick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void bumpCog(float force) {
|
||||
ConfigScreen.cogSpin.bump(3, force);
|
||||
}
|
||||
|
||||
public static abstract class Entry extends ExtendedList.AbstractListEntry<Entry> {
|
||||
protected List<IGuiEventListener> listeners;
|
||||
|
||||
protected Entry() {
|
||||
listeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int code, int keyPressed_2_, int keyPressed_3_) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.keyPressed(code, keyPressed_2_, keyPressed_3_));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char ch, int code) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code));
|
||||
}
|
||||
|
||||
public void tick() {}
|
||||
|
||||
public List<IGuiEventListener> getGuiListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
protected void setEditable(boolean b) {}
|
||||
}
|
||||
|
||||
public static class LabeledEntry extends Entry {
|
||||
|
||||
protected static final float labelWidthMult = 0.4f;
|
||||
|
||||
protected TextStencilElement label;
|
||||
protected List<ITextComponent> labelTooltip;
|
||||
protected String unit = null;
|
||||
|
||||
public LabeledEntry(String label) {
|
||||
this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label);
|
||||
this.label.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.TEXT_ACCENT_STRONG)));
|
||||
labelTooltip = new ArrayList<>();
|
||||
}
|
||||
|
||||
@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) {
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 6, width, 0xdd_000000);
|
||||
IFormattableTextComponent component = label.getComponent();
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
if (font.getWidth(component) > getLabelWidth(width) - 10) {
|
||||
label.withText(font.trimToWidth(component, getLabelWidth(width) - 15).getString() + "...");
|
||||
}
|
||||
if (unit != null) {
|
||||
int unitWidth = font.getStringWidth(unit);
|
||||
font.draw(ms, unit, x + getLabelWidth(width) - unitWidth - 5, y + height / 2 + 2, Theme.i(Theme.Key.TEXT_DARKER));
|
||||
label.at(x + 10, y + height / 2 - 10, 0).render(ms);
|
||||
} else {
|
||||
label.at(x + 10, y + height / 2 - 4, 0).render(ms);
|
||||
}
|
||||
|
||||
|
||||
if (mouseX > x && mouseX < x + getLabelWidth(width) && mouseY > y + 5 && mouseY < y + height - 5) {
|
||||
List<ITextComponent> tooltip = getLabelTooltip();
|
||||
if (tooltip.isEmpty())
|
||||
return;
|
||||
|
||||
GL11.glDisable(GL11.GL_SCISSOR_TEST);
|
||||
Screen screen = Minecraft.getInstance().currentScreen;
|
||||
ms.push();
|
||||
ms.translate(0, 0, 400);
|
||||
GuiUtils.drawHoveringText(ms, tooltip, mouseX, mouseY, screen.width, screen.height, 300, font);
|
||||
ms.pop();
|
||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ITextComponent> getLabelTooltip() {
|
||||
return labelTooltip;
|
||||
}
|
||||
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return totalWidth;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class ConfigTextField extends TextFieldWidget {
|
||||
|
||||
protected FontRenderer font;
|
||||
protected String unit;
|
||||
|
||||
public ConfigTextField(FontRenderer font, int x, int y, int width, int height, String unit) {
|
||||
super(font, x, y, width, height, StringTextComponent.EMPTY);
|
||||
this.font = font;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void 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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.electronwill.nightconfig.core.AbstractConfig;
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
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.NumberEntry;
|
||||
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.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 com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.IGuiEventListener;
|
||||
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.fml.config.ModConfig;
|
||||
|
||||
public class SubMenuConfigScreen extends ConfigScreen {
|
||||
|
||||
public final ModConfig.Type type;
|
||||
protected ForgeConfigSpec spec;
|
||||
protected UnmodifiableConfig configGroup;
|
||||
protected ConfigScreenList list;
|
||||
|
||||
protected BoxWidget resetAll;
|
||||
protected BoxWidget saveChanges;
|
||||
protected BoxWidget discardChanges;
|
||||
protected BoxWidget goBack;
|
||||
protected BoxWidget serverLocked;
|
||||
protected int listWidth;
|
||||
protected String title;
|
||||
|
||||
|
||||
public SubMenuConfigScreen(Screen parent, String title, ModConfig.Type type, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) {
|
||||
super(parent);
|
||||
this.type = type;
|
||||
this.spec = configSpec;
|
||||
this.title = title;
|
||||
this.configGroup = configGroup;
|
||||
}
|
||||
|
||||
public SubMenuConfigScreen(Screen parent, ModConfig.Type type, ForgeConfigSpec configSpec) {
|
||||
super(parent);
|
||||
this.type = type;
|
||||
this.spec = configSpec;
|
||||
this.title = "root";
|
||||
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);
|
||||
if (type == ModConfig.Type.SERVER) {
|
||||
AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, 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
|
||||
public void tick() {
|
||||
super.tick();
|
||||
list.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
widgets.clear();
|
||||
super.init();
|
||||
|
||||
listWidth = Math.min(width - 80, 300);
|
||||
|
||||
int yCenter = height / 2;
|
||||
int listL = this.width / 2 - listWidth / 2;
|
||||
int listR = this.width / 2 + listWidth / 2;
|
||||
|
||||
resetAll = new BoxWidget(listR + 10, yCenter - 25, 20, 20)
|
||||
.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?"))
|
||||
.withAction(success -> {
|
||||
if (success)
|
||||
resetConfig(spec.getValues());
|
||||
})
|
||||
.open(this)
|
||||
);
|
||||
|
||||
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));
|
||||
|
||||
saveChanges = new BoxWidget(listL - 30, yCenter - 25, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback((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);
|
||||
});
|
||||
saveChanges.showingElement(AllIcons.I_CONFIG_SAVE.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(saveChanges)));
|
||||
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 BoxWidget(listL - 30, yCenter + 5, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback((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);
|
||||
});
|
||||
discardChanges.showingElement(AllIcons.I_CONFIG_DISCARD.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(discardChanges)));
|
||||
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 BoxWidget(listL - 30, yCenter + 65, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback(this::attemptBackstep);
|
||||
goBack.showingElement(AllIcons.I_CONFIG_BACK.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(goBack)));
|
||||
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, 40);
|
||||
list.setLeftPos(this.width / 2 - list.getWidth() / 2);
|
||||
|
||||
children.add(list);
|
||||
|
||||
configGroup.valueMap().forEach((key, obj) -> {
|
||||
String humanKey = toHumanReadable(key);
|
||||
|
||||
if (obj instanceof AbstractConfig) {
|
||||
SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) obj);
|
||||
list.children().add(entry);
|
||||
|
||||
} else if (obj instanceof ForgeConfigSpec.ConfigValue<?>) {
|
||||
ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) obj;
|
||||
ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath());
|
||||
Object value = configValue.get();
|
||||
|
||||
if (value instanceof Boolean) {
|
||||
BooleanEntry entry = new BooleanEntry(humanKey, (ForgeConfigSpec.ConfigValue<Boolean>) configValue, valueSpec);
|
||||
list.children().add(entry);
|
||||
} else if (value instanceof Enum) {
|
||||
EnumEntry entry = new EnumEntry(humanKey, (ForgeConfigSpec.ConfigValue<Enum<?>>) configValue, valueSpec);
|
||||
list.children().add(entry);
|
||||
} else if (value instanceof Number) {
|
||||
NumberEntry<? extends Number> entry = NumberEntry.create(value, humanKey, configValue, valueSpec);
|
||||
if (entry != null) {
|
||||
list.children().add(entry);
|
||||
} else {
|
||||
list.children().add(new ConfigScreenList.LabeledEntry("n-" + obj.getClass().getSimpleName() + " " + humanKey + " : " + value));
|
||||
}
|
||||
} else {
|
||||
list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//extras for server configs
|
||||
if (type != ModConfig.Type.SERVER)
|
||||
return;
|
||||
|
||||
list.isForServer = true;
|
||||
boolean canEdit = client != null && client.player != null && client.player.hasPermissionLevel(2);
|
||||
|
||||
Couple<Color> red = Theme.p(Theme.Key.BUTTON_FAIL);
|
||||
Couple<Color> green = Theme.p(Theme.Key.BUTTON_SUCCESS);
|
||||
|
||||
DelegatedStencilElement stencil = new DelegatedStencilElement();
|
||||
|
||||
serverLocked = new BoxWidget(listR + 10, yCenter + 5, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.showingElement(stencil);
|
||||
|
||||
if (!canEdit) {
|
||||
list.children().forEach(e -> e.setEditable(false));
|
||||
resetAll.active = false;
|
||||
stencil.withStencilRenderer((ms, w, h, alpha) -> AllIcons.I_CONFIG_LOCKED.draw(ms, 0, 0));
|
||||
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));
|
||||
} 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));
|
||||
serverLocked.withBorderColors(green);
|
||||
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 when you save them.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
}
|
||||
|
||||
widgets.add(serverLocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderWindow(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
int x = width/2;
|
||||
drawCenteredString(ms, client.fontRenderer, "Editing config: " + type.toString() + "@" + title, x, 15, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
list.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowForeground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderWindowForeground(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(@Nonnull Minecraft client, int width, int height) {
|
||||
double scroll = list.getScrollAmount();
|
||||
init(client, width, height);
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
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.RenderElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class BooleanEntry extends ValueEntry<Boolean> {
|
||||
|
||||
RenderElement enabled;
|
||||
RenderElement disabled;
|
||||
BoxWidget button;
|
||||
|
||||
public BooleanEntry(String label, ForgeConfigSpec.ConfigValue<Boolean> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
|
||||
// enabled = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Enabled")
|
||||
// .centered(true, true)
|
||||
// .withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_88f788, 0xff_20cc20));
|
||||
//
|
||||
// disabled = new TextStencilElement(Minecraft.getInstance().fontRenderer, "Disabled")
|
||||
// .centered(true, true)
|
||||
// .withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height/2, height, width, 0xff_f78888, 0xff_cc2020));
|
||||
|
||||
enabled = AllIcons.I_CONFIRM.asStencil()
|
||||
.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.BUTTON_SUCCESS)))
|
||||
.at(10, 0);
|
||||
|
||||
disabled = AllIcons.I_DISABLE.asStencil()
|
||||
.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.BUTTON_FAIL)))
|
||||
.at(10, 0);
|
||||
|
||||
button = new BoxWidget().showingElement(enabled)
|
||||
.withCallback(() -> setValue(!getValue()));
|
||||
|
||||
listeners.add(button);
|
||||
onReset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
button.active = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
button.tick();
|
||||
}
|
||||
|
||||
@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) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
button.x = x + width - 80 - resetWidth;
|
||||
button.y = y + 10;
|
||||
button.setWidth(35);
|
||||
button.setHeight(height - 20);
|
||||
button.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(Boolean newValue) {
|
||||
super.onValueChange(newValue);
|
||||
button.showingElement(newValue ? enabled : disabled);
|
||||
bumpCog(newValue ? 15f : -16f);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
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.BoxElement;
|
||||
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;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class EnumEntry extends ValueEntry<Enum<?>> {
|
||||
|
||||
protected static final int cycleWidth = 34;
|
||||
|
||||
protected TextStencilElement valueText;
|
||||
protected BoxWidget cycleLeft;
|
||||
protected BoxWidget cycleRight;
|
||||
|
||||
public EnumEntry(String label, ForgeConfigSpec.ConfigValue<Enum<?>> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
|
||||
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.p(Theme.Key.TEXT)));
|
||||
|
||||
DelegatedStencilElement l = AllIcons.I_CONFIG_PREV.asStencil();
|
||||
cycleLeft = new BoxWidget(0, 0, cycleWidth + 8, 16).showingElement(l)
|
||||
.withCallback(() -> cycleValue(-1));
|
||||
l.withElementRenderer(BoxWidget.gradientFactory.apply(cycleLeft));
|
||||
|
||||
DelegatedStencilElement r = AllIcons.I_CONFIG_NEXT.asStencil();
|
||||
cycleRight = new BoxWidget(0, 0, cycleWidth + 8, 16).showingElement(r)
|
||||
.withCallback(() -> cycleValue(1));
|
||||
r.at(cycleWidth - 8, 0);
|
||||
r.withElementRenderer(BoxWidget.gradientFactory.apply(cycleRight));
|
||||
|
||||
listeners.add(cycleLeft);
|
||||
listeners.add(cycleRight);
|
||||
|
||||
onReset();
|
||||
}
|
||||
|
||||
protected void cycleValue(int direction) {
|
||||
Enum<?> e = getValue();
|
||||
Enum<?>[] options = e.getDeclaringClass()
|
||||
.getEnumConstants();
|
||||
e = options[Math.floorMod(e.ordinal() + direction, options.length)];
|
||||
setValue(e);
|
||||
bumpCog(direction * 15f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
cycleLeft.active = b;
|
||||
cycleLeft.animateGradientFromState();
|
||||
cycleRight.active = b;
|
||||
cycleRight.animateGradientFromState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
cycleLeft.tick();
|
||||
cycleRight.tick();
|
||||
}
|
||||
|
||||
@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) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
cycleLeft.x = x + getLabelWidth(width) + 4;
|
||||
cycleLeft.y = y + 10;
|
||||
cycleLeft.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
valueText.at(cycleLeft.x + cycleWidth - 8, y + 10, 200)
|
||||
.withBounds(width - getLabelWidth(width) - 2 * cycleWidth - resetWidth - 4, 16)
|
||||
.render(ms);
|
||||
|
||||
cycleRight.x = x + width - cycleWidth * 2 - resetWidth + 10;
|
||||
cycleRight.y = y + 10;
|
||||
cycleRight.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
new BoxElement()
|
||||
.withBackground(0)
|
||||
.flatBorder(0)
|
||||
.withBounds(10, 10)
|
||||
.at(cycleLeft.x + cycleWidth + 4, cycleLeft.y + 3)
|
||||
.render(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(Enum<?> newValue) {
|
||||
super.onValueChange(newValue);
|
||||
valueText.withText(newValue.name());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigTextField;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
|
||||
|
||||
protected int minOffset = 0, maxOffset = 0;
|
||||
protected TextStencilElement minText = null, maxText = null;
|
||||
protected TextFieldWidget textField;
|
||||
|
||||
@Nullable
|
||||
public static NumberEntry<? extends Number> create(Object type, String label, ForgeConfigSpec.ConfigValue<?> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
if (type instanceof Integer) {
|
||||
return new IntegerEntry(label, (ForgeConfigSpec.ConfigValue<Integer>) value, spec);
|
||||
} else if (type instanceof Float) {
|
||||
return new FloatEntry(label, (ForgeConfigSpec.ConfigValue<Float>) value, spec);
|
||||
} else if (type instanceof Double) {
|
||||
return new DoubleEntry(label, (ForgeConfigSpec.ConfigValue<Double>) value, spec);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public NumberEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
textField = new ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 20, unit);
|
||||
textField.setText(String.valueOf(getValue()));
|
||||
textField.setTextColor(Theme.i(Theme.Key.TEXT));
|
||||
|
||||
Object range = spec.getRange();
|
||||
try {
|
||||
Field minField = range.getClass().getDeclaredField("min");
|
||||
Field maxField = range.getClass().getDeclaredField("max");
|
||||
minField.setAccessible(true);
|
||||
maxField.setAccessible(true);
|
||||
T min = (T) minField.get(range);
|
||||
T max = (T) maxField.get(range);
|
||||
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
if (min.doubleValue() > getTypeMin().doubleValue()) {
|
||||
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.p(Theme.Key.TEXT_DARKER)));
|
||||
minOffset = font.getWidth(t);
|
||||
}
|
||||
if (max.doubleValue() < getTypeMax().doubleValue()) {
|
||||
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.p(Theme.Key.TEXT_DARKER)));
|
||||
maxOffset = font.getWidth(t);
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException | NullPointerException ignored) {
|
||||
|
||||
}
|
||||
|
||||
textField.setResponder(s -> {
|
||||
try {
|
||||
T number = getParser().apply(s);
|
||||
if (!spec.test(number))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
textField.setTextColor(Theme.i(Theme.Key.TEXT));
|
||||
setValue(number);
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
textField.setTextColor(Theme.i(Theme.Key.BUTTON_FAIL));
|
||||
}
|
||||
});
|
||||
|
||||
listeners.add(textField);
|
||||
onReset();
|
||||
}
|
||||
|
||||
protected String formatBound(T bound) {
|
||||
String sci = String.format("%.2E", bound.doubleValue());
|
||||
String str = String.valueOf(bound);
|
||||
return sci.length() < str.length() ? sci : str;
|
||||
}
|
||||
|
||||
protected abstract T getTypeMin();
|
||||
|
||||
protected abstract T getTypeMax();
|
||||
|
||||
protected abstract Function<String, T> getParser();
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
textField.setEnabled(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(T newValue) {
|
||||
super.onValueChange(newValue);
|
||||
String newText = String.valueOf(newValue);
|
||||
if (textField.getText().equals(newText))
|
||||
return;
|
||||
|
||||
textField.setText(newText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
textField.tick();
|
||||
}
|
||||
|
||||
@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) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
textField.x = x + width - 82 - resetWidth;
|
||||
textField.y = y + 8;
|
||||
textField.setWidth(Math.min(width - getLabelWidth(width) - resetWidth - minOffset - maxOffset, 40));
|
||||
textField.setHeight(20);
|
||||
textField.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
if (minText != null)
|
||||
minText
|
||||
.at(textField.x - minOffset, textField.y, 0)
|
||||
.withBounds(minOffset, textField.unusedGetHeight())
|
||||
.render(ms);
|
||||
|
||||
if (maxText != null)
|
||||
maxText
|
||||
.at(textField.x + textField.getWidth(), textField.y, 0)
|
||||
.withBounds(maxOffset, textField.unusedGetHeight())
|
||||
.render(ms);
|
||||
}
|
||||
|
||||
public static class IntegerEntry extends NumberEntry<Integer> {
|
||||
|
||||
public IntegerEntry(String label, ForgeConfigSpec.ConfigValue<Integer> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getTypeMin() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getTypeMax() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Integer> getParser() {
|
||||
return Integer::parseInt;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatEntry extends NumberEntry<Float> {
|
||||
|
||||
public FloatEntry(String label, ForgeConfigSpec.ConfigValue<Float> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Float getTypeMin() {
|
||||
return -Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Float getTypeMax() {
|
||||
return Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Float> getParser() {
|
||||
return Float::parseFloat;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleEntry extends NumberEntry<Double> {
|
||||
|
||||
public DoubleEntry(String label, ForgeConfigSpec.ConfigValue<Double> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double getTypeMin() {
|
||||
return (double) -Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double getTypeMax() {
|
||||
return (double) Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Double> getParser() {
|
||||
return Double::parseDouble;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigScreenList;
|
||||
import com.simibubi.create.foundation.config.ui.SubMenuConfigScreen;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class SubMenuEntry extends ConfigScreenList.LabeledEntry {
|
||||
|
||||
protected BoxWidget button;
|
||||
|
||||
public SubMenuEntry(SubMenuConfigScreen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) {
|
||||
super(label);
|
||||
|
||||
button = new BoxWidget(0, 0, 35, 16)
|
||||
.showingElement(AllIcons.I_CONFIG_OPEN.asStencil().at(10, 0))
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(parent, label, parent.type, spec, config)));
|
||||
button.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BoxWidget.gradientFactory.apply(button)));
|
||||
|
||||
listeners.add(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
button.tick();
|
||||
}
|
||||
|
||||
@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) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
button.x = x + width - 108;
|
||||
button.y = y + 10;
|
||||
button.setHeight(height - 20);
|
||||
button.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return (int) (totalWidth * labelWidthMult) + 30;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigScreen;
|
||||
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 net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
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
|
||||
public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]");
|
||||
|
||||
protected ForgeConfigSpec.ConfigValue<T> value;
|
||||
protected ForgeConfigSpec.ValueSpec spec;
|
||||
protected BoxWidget resetButton;
|
||||
protected boolean editable = true;
|
||||
protected String path;
|
||||
|
||||
public ValueEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label);
|
||||
this.value = value;
|
||||
this.spec = spec;
|
||||
this.path = String.join(".", value.getPath());
|
||||
|
||||
resetButton = new BoxWidget(0, 0, resetWidth - 12, 16)
|
||||
.showingElement(AllIcons.I_CONFIG_RESET.asStencil())
|
||||
.withCallback(() -> {
|
||||
setValue((T) spec.getDefault());
|
||||
this.onReset();
|
||||
});
|
||||
resetButton.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BoxWidget.gradientFactory.apply(resetButton)));
|
||||
|
||||
listeners.add(resetButton);
|
||||
|
||||
List<String> path = value.getPath();
|
||||
labelTooltip.add(new StringTextComponent(path.get(path.size()-1)).formatted(TextFormatting.GRAY));
|
||||
String comment = spec.getComment();
|
||||
if (comment == null || comment.isEmpty())
|
||||
return;
|
||||
String[] commentLines = comment.split("\n");
|
||||
//find unit in the comment
|
||||
for (int i = 0; i < commentLines.length; i++) {
|
||||
if (commentLines[i].isEmpty()) {
|
||||
commentLines = ArrayUtils.remove(commentLines, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher matcher = unitPattern.matcher(commentLines[i]);
|
||||
if (!matcher.matches())
|
||||
continue;
|
||||
|
||||
String u = matcher.group(1);
|
||||
if (u.equals("in Revolutions per Minute"))
|
||||
u = "in RPM";
|
||||
if (u.equals("in Stress Units"))
|
||||
u = "in SU";
|
||||
unit = u;
|
||||
}
|
||||
//add comment to tooltip
|
||||
labelTooltip.addAll(Arrays.stream(commentLines).map(StringTextComponent::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
editable = b;
|
||||
resetButton.active = editable && !isCurrentValueDefault();
|
||||
resetButton.animateGradientFromState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
resetButton.tick();
|
||||
}
|
||||
|
||||
@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) {
|
||||
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.y = y + 10;
|
||||
resetButton.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return (int) (totalWidth * labelWidthMult) + 30;
|
||||
}
|
||||
|
||||
public void setValue(@Nonnull T value) {
|
||||
if (value.equals(this.value.get())) {
|
||||
ConfigScreen.changes.remove(path);
|
||||
onValueChange(value);
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigScreen.changes.put(path, value);
|
||||
onValueChange(value);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public T getValue() {
|
||||
//noinspection unchecked
|
||||
return (T) ConfigScreen.changes.getOrDefault(path, this.value.get());
|
||||
}
|
||||
|
||||
protected boolean isCurrentValueChanged() {
|
||||
return ConfigScreen.changes.containsKey(path);
|
||||
}
|
||||
|
||||
protected boolean isCurrentValueDefault() {
|
||||
return spec.getDefault().equals(getValue());
|
||||
}
|
||||
|
||||
public void onReset() {
|
||||
onValueChange(getValue());
|
||||
}
|
||||
|
||||
public void onValueChange() {
|
||||
onValueChange(getValue());
|
||||
}
|
||||
public void onValueChange(T newValue) {
|
||||
resetButton.active = editable && !isCurrentValueDefault();
|
||||
resetButton.animateGradientFromState();
|
||||
}
|
||||
|
||||
protected void bumpCog() {bumpCog(10f);}
|
||||
protected void bumpCog(float force) {
|
||||
if (list != null && list instanceof ConfigScreenList)
|
||||
((ConfigScreenList) list).bumpCog(force);
|
||||
}
|
||||
}
|
|
@ -69,8 +69,6 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
|||
RenderSystem.disableLighting();
|
||||
RenderSystem.disableDepthTest();
|
||||
renderWindowForeground(matrixStack, mouseX, mouseY, partialTicks);
|
||||
for (Widget widget : widgets)
|
||||
widget.renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,9 +150,12 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
|||
if (!widget.isHovered())
|
||||
continue;
|
||||
|
||||
if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip()
|
||||
.isEmpty()) {
|
||||
renderTooltip(matrixStack, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
if (widget instanceof AbstractSimiWidget) {
|
||||
if (!((AbstractSimiWidget) widget).getToolTip().isEmpty())
|
||||
renderTooltip(matrixStack, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
|
||||
} else {
|
||||
widget.renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
guiTop = (this.height - sHeight) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
widgets.stream().filter(w -> w instanceof AbstractSimiWidget).forEach(w -> ((AbstractSimiWidget) w).tick());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
partialTicks = partialTicks == 10 ? 0
|
||||
|
@ -46,8 +53,6 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
for (Widget widget : widgets)
|
||||
widget.render(ms, mouseX, mouseY, partialTicks);
|
||||
renderWindowForeground(ms, mouseX, mouseY, partialTicks);
|
||||
for (Widget widget : widgets)
|
||||
widget.renderToolTip(ms, mouseX, mouseY);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -62,6 +67,10 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
for (Widget widget : widgets)
|
||||
if (widget.mouseClicked(x, y, button))
|
||||
result = true;
|
||||
|
||||
if (!result) {
|
||||
result = super.mouseClicked(x, y, button);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -127,9 +136,12 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
if (!widget.isHovered())
|
||||
continue;
|
||||
|
||||
if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip()
|
||||
.isEmpty()) {
|
||||
renderTooltip(ms, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
if (widget instanceof AbstractSimiWidget) {
|
||||
if (!((AbstractSimiWidget) widget).getToolTip().isEmpty())
|
||||
renderTooltip(ms, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
|
||||
} else {
|
||||
widget.renderToolTip(ms, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
|
@ -80,8 +82,8 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
INDICATOR_YELLOW("widgets.png", 54, 18, 18, 6),
|
||||
INDICATOR_RED("widgets.png", 72, 18, 18, 6),
|
||||
|
||||
SPEECH_TOOLTIP("widgets.png", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_HIGHLIGHT("widgets.png", 8, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_BACKGROUND("widgets.png", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_COLOR("widgets.png", 8, 24, 8, 8),
|
||||
|
||||
// PlacementIndicator
|
||||
PLACEMENT_INDICATOR_SHEET("placement_indicator.png", 0, 0, 16, 256);
|
||||
|
@ -123,4 +125,9 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
bind();
|
||||
screen.drawTexture(ms, x, y, startX, startY, width, height);
|
||||
}
|
||||
|
||||
public void draw(MatrixStack ms, int x, int y, Color c) {
|
||||
bind();
|
||||
UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,45 +22,121 @@ public class AllIcons implements IScreenRenderable {
|
|||
private int iconX;
|
||||
private int iconY;
|
||||
|
||||
public static final AllIcons I_ADD = newRow(), I_TRASH = next(), I_3x3 = next(), I_TARGET = next(),
|
||||
I_PRIORITY_VERY_LOW = next(), I_PRIORITY_LOW = next(), I_PRIORITY_HIGH = next(), I_PRIORITY_VERY_HIGH = next(),
|
||||
I_BLACKLIST = next(), I_WHITELIST = next(), I_WHITELIST_OR = next(), I_WHITELIST_AND = next(),
|
||||
I_WHITELIST_NOT = next(), I_RESPECT_NBT = next(), I_IGNORE_NBT = next();
|
||||
public static final AllIcons
|
||||
I_ADD = newRow(),
|
||||
I_TRASH = next(),
|
||||
I_3x3 = next(),
|
||||
I_TARGET = next(),
|
||||
I_PRIORITY_VERY_LOW = next(),
|
||||
I_PRIORITY_LOW = next(),
|
||||
I_PRIORITY_HIGH = next(),
|
||||
I_PRIORITY_VERY_HIGH = next(),
|
||||
I_BLACKLIST = next(),
|
||||
I_WHITELIST = next(),
|
||||
I_WHITELIST_OR = next(),
|
||||
I_WHITELIST_AND = next(),
|
||||
I_WHITELIST_NOT = next(),
|
||||
I_RESPECT_NBT = next(),
|
||||
I_IGNORE_NBT = next();
|
||||
|
||||
public static final AllIcons I_CONFIRM = newRow(), I_NONE = next(), I_OPEN_FOLDER = next(), I_REFRESH = next(),
|
||||
I_ACTIVE = next(), I_PASSIVE = next(), I_ROTATE_PLACE = next(), I_ROTATE_PLACE_RETURNED = next(),
|
||||
I_ROTATE_NEVER_PLACE = next(), I_MOVE_PLACE = next(), I_MOVE_PLACE_RETURNED = next(),
|
||||
I_MOVE_NEVER_PLACE = next(), I_CART_ROTATE = next(), I_CART_ROTATE_PAUSED = next(),
|
||||
public static final AllIcons
|
||||
I_CONFIRM = newRow(),
|
||||
I_NONE = next(),
|
||||
I_OPEN_FOLDER = next(),
|
||||
I_REFRESH = next(),
|
||||
I_ACTIVE = next(),
|
||||
I_PASSIVE = next(),
|
||||
I_ROTATE_PLACE = next(),
|
||||
I_ROTATE_PLACE_RETURNED = next(),
|
||||
I_ROTATE_NEVER_PLACE = next(),
|
||||
I_MOVE_PLACE = next(),
|
||||
I_MOVE_PLACE_RETURNED = next(),
|
||||
I_MOVE_NEVER_PLACE = next(),
|
||||
I_CART_ROTATE = next(),
|
||||
I_CART_ROTATE_PAUSED = next(),
|
||||
I_CART_ROTATE_LOCKED = next();
|
||||
|
||||
public static final AllIcons I_DONT_REPLACE = newRow(), I_REPLACE_SOLID = next(), I_REPLACE_ANY = next(),
|
||||
I_REPLACE_EMPTY = next(), I_CENTERED = next(), I_ATTACHED = next(), I_INSERTED = next(), I_FILL = next(),
|
||||
I_PLACE = next(), I_REPLACE = next(), I_CLEAR = next(), I_OVERLAY = next(), I_FLATTEN = next(), I_LMB = next(),
|
||||
I_SCROLL = next(), I_RMB = next();
|
||||
|
||||
public static final AllIcons I_TOOL_DEPLOY = newRow(), I_SKIP_MISSING = next(), I_SKIP_TILES = next(),
|
||||
I_DICE = next(), I_TUNNEL_SPLIT = next(), I_TUNNEL_FORCED_SPLIT = next(), I_TUNNEL_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_FORCED_ROUND_ROBIN = next(), I_TUNNEL_PREFER_NEAREST = next(), I_TUNNEL_RANDOMIZE = next(),
|
||||
|
||||
public static final AllIcons
|
||||
I_DONT_REPLACE = newRow(),
|
||||
I_REPLACE_SOLID = next(),
|
||||
I_REPLACE_ANY = next(),
|
||||
I_REPLACE_EMPTY = next(),
|
||||
I_CENTERED = next(),
|
||||
I_ATTACHED = next(),
|
||||
I_INSERTED = next(),
|
||||
I_FILL = next(),
|
||||
I_PLACE = next(),
|
||||
I_REPLACE = next(),
|
||||
I_CLEAR = next(),
|
||||
I_OVERLAY = next(),
|
||||
I_FLATTEN = next(),
|
||||
I_LMB = next(),
|
||||
I_SCROLL = next(),
|
||||
I_RMB = next();
|
||||
|
||||
public static final AllIcons
|
||||
I_TOOL_DEPLOY = newRow(),
|
||||
I_SKIP_MISSING = next(),
|
||||
I_SKIP_TILES = next(),
|
||||
I_DICE = next(),
|
||||
I_TUNNEL_SPLIT = next(),
|
||||
I_TUNNEL_FORCED_SPLIT = next(),
|
||||
I_TUNNEL_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_FORCED_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_PREFER_NEAREST = next(),
|
||||
I_TUNNEL_RANDOMIZE = next(),
|
||||
I_TUNNEL_SYNCHRONIZE = next(),
|
||||
|
||||
I_TOOL_MOVE_XZ = newRow(), I_TOOL_MOVE_Y = next(), I_TOOL_ROTATE = next(), I_TOOL_MIRROR = next(),
|
||||
I_ARM_ROUND_ROBIN = next(), I_ARM_FORCED_ROUND_ROBIN = next(), I_ARM_PREFER_FIRST = next(),
|
||||
|
||||
I_ADD_INVERTED_ATTRIBUTE = next(), I_FLIP = next(),
|
||||
|
||||
I_PLAY = newRow(), I_PAUSE = next(), I_STOP = next(), I_PLACEMENT_SETTINGS = next(), I_ROTATE_CCW = next(),
|
||||
I_HOUR_HAND_FIRST = next(), I_MINUTE_HAND_FIRST = next(), I_HOUR_HAND_FIRST_24 = next(),
|
||||
|
||||
I_PATTERN_SOLID = newRow(), I_PATTERN_CHECKERED = next(), I_PATTERN_CHECKERED_INVERSED = next(),
|
||||
|
||||
I_TOOL_MOVE_XZ = newRow(),
|
||||
I_TOOL_MOVE_Y = next(),
|
||||
I_TOOL_ROTATE = next(),
|
||||
I_TOOL_MIRROR = next(),
|
||||
I_ARM_ROUND_ROBIN = next(),
|
||||
I_ARM_FORCED_ROUND_ROBIN = next(),
|
||||
I_ARM_PREFER_FIRST = next(),
|
||||
|
||||
I_ADD_INVERTED_ATTRIBUTE = next(),
|
||||
I_FLIP = next(),
|
||||
|
||||
I_PLAY = newRow(),
|
||||
I_PAUSE = next(),
|
||||
I_STOP = next(),
|
||||
I_PLACEMENT_SETTINGS = next(),
|
||||
I_ROTATE_CCW = next(),
|
||||
I_HOUR_HAND_FIRST = next(),
|
||||
I_MINUTE_HAND_FIRST = next(),
|
||||
I_HOUR_HAND_FIRST_24 = next(),
|
||||
|
||||
I_PATTERN_SOLID = newRow(),
|
||||
I_PATTERN_CHECKERED = next(),
|
||||
I_PATTERN_CHECKERED_INVERSED = next(),
|
||||
I_PATTERN_CHANCE_25 = next(),
|
||||
|
||||
I_PATTERN_CHANCE_50 = newRow(), I_PATTERN_CHANCE_75 = next(), I_FOLLOW_DIAGONAL = next(),
|
||||
|
||||
I_PATTERN_CHANCE_50 = newRow(),
|
||||
I_PATTERN_CHANCE_75 = next(),
|
||||
I_FOLLOW_DIAGONAL = next(),
|
||||
I_FOLLOW_MATERIAL = next(),
|
||||
|
||||
|
||||
I_SCHEMATIC = newRow(),
|
||||
|
||||
I_MTD_LEFT = newRow(), I_MTD_CLOSE = next(), I_MTD_RIGHT = next(), I_MTD_SCAN = next(), I_MTD_REPLAY = next(),
|
||||
I_MTD_USER_MODE = next(), I_MTD_SLOW_MODE = next();
|
||||
I_MTD_LEFT = newRow(),
|
||||
I_MTD_CLOSE = next(),
|
||||
I_MTD_RIGHT = next(),
|
||||
I_MTD_SCAN = next(),
|
||||
I_MTD_REPLAY = next(),
|
||||
I_MTD_USER_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(),
|
||||
I_CONFIG_PREV = next(),
|
||||
I_CONFIG_NEXT = next(),
|
||||
I_DISABLE = next(),
|
||||
I_CONFIG_OPEN = next();
|
||||
|
||||
public AllIcons(int x, int y) {
|
||||
iconX = x * 16;
|
||||
|
@ -116,8 +192,12 @@ public class AllIcons implements IScreenRenderable {
|
|||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u,
|
||||
float v) {
|
||||
public DelegatedStencilElement asStencil() {
|
||||
return new DelegatedStencilElement().withStencilRenderer((ms, w, h, alpha) -> this.draw(ms, 0, 0)).withBounds(16, 16);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
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)
|
||||
.color((float) rgb.x, (float) rgb.y, (float) rgb.z, 1)
|
||||
.texture(u, v)
|
||||
|
|
160
src/main/java/com/simibubi/create/foundation/gui/BoxElement.java
Normal file
160
src/main/java/com/simibubi/create/foundation/gui/BoxElement.java
Normal file
|
@ -0,0 +1,160 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
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 com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class BoxElement extends RenderElement {
|
||||
|
||||
protected Color background = new Color(0xff000000, true);
|
||||
protected Color borderTop = new Color(0x40ffeedd, true);
|
||||
protected Color borderBot = new Color(0x20ffeedd, true);
|
||||
protected int borderOffset = 2;
|
||||
|
||||
public <T extends BoxElement> T withBackground(Color color) {
|
||||
this.background = color;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T withBackground(int color) {
|
||||
return withBackground(new Color(color, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T flatBorder(Color color) {
|
||||
this.borderTop = color;
|
||||
this.borderBot = color;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T flatBorder(int color) {
|
||||
return flatBorder(new Color(color, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(Couple<Color> colors) {
|
||||
this.borderTop = colors.getFirst();
|
||||
this.borderBot = colors.getSecond();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(Color top, Color bot) {
|
||||
this.borderTop = top;
|
||||
this.borderBot = bot;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(int top, int bot) {
|
||||
return gradientBorder(new Color(top, true), new Color(bot, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T withBorderOffset(int offset) {
|
||||
this.borderOffset = offset;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms) {
|
||||
renderBox(ms);
|
||||
}
|
||||
|
||||
//total box width = 1 * 2 (outer border) + 1 * 2 (inner color border) + 2 * borderOffset + width
|
||||
//defaults to 2 + 2 + 4 + 16 = 24px
|
||||
//batch everything together to save a bunch of gl calls over GuiUtils
|
||||
protected void renderBox(MatrixStack ms) {
|
||||
/*
|
||||
* _____________
|
||||
* _|_____________|_
|
||||
* | | ___________ | |
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* | | |--* | | | |
|
||||
* | | | h | | |
|
||||
* | | | --w-+ | | |
|
||||
* | | | | | |
|
||||
* | | |_________| | |
|
||||
* |_|_____________|_|
|
||||
* |_____________|
|
||||
*
|
||||
* */
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.shadeModel(GL11.GL_SMOOTH);
|
||||
|
||||
int f = borderOffset;
|
||||
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();
|
||||
b.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
|
||||
//outer top
|
||||
b.vertex(model, x - f - 1 , y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer left
|
||||
b.vertex(model, x - f - 2 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 2 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer bottom
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer right
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 2 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 2 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//inner background - also render behind the inner edges
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
tessellator.draw();
|
||||
b.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
|
||||
//inner top - includes corners
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
//inner left - excludes corners
|
||||
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
//inner bottom - includes corners
|
||||
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
//inner right - excludes corners
|
||||
b.vertex(model, x + f + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
RenderSystem.shadeModel(GL11.GL_FLAT);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
public class CombinedStencilElement extends StencilElement {
|
||||
|
||||
private StencilElement element1;
|
||||
private StencilElement element2;
|
||||
private ElementMode mode;
|
||||
|
||||
private CombinedStencilElement() {}
|
||||
|
||||
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2) {
|
||||
return of(element1, element2, ElementMode.FIRST);
|
||||
}
|
||||
|
||||
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2, ElementMode mode) {
|
||||
CombinedStencilElement e = new CombinedStencilElement();
|
||||
e.element1 = element1;
|
||||
e.element2 = element2;
|
||||
e.mode = mode;
|
||||
return e;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withFirst(StencilElement element) {
|
||||
this.element1 = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withSecond(StencilElement element) {
|
||||
this.element2 = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withMode(ElementMode mode) {
|
||||
this.mode = mode;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
ms.push();
|
||||
element1.transform(ms);
|
||||
element1.withBounds(width, height);
|
||||
element1.renderStencil(ms);
|
||||
ms.pop();
|
||||
ms.push();
|
||||
element2.transform(ms);
|
||||
element2.withBounds(width, height);
|
||||
element2.renderStencil(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
if (mode.rendersFirst())
|
||||
element1.<StencilElement>withBounds(width, height).renderElement(ms);
|
||||
|
||||
if (mode.rendersSecond())
|
||||
element2.<StencilElement>withBounds(width, height).renderElement(ms);
|
||||
}
|
||||
|
||||
public enum ElementMode {
|
||||
FIRST, SECOND, BOTH;
|
||||
|
||||
boolean rendersFirst() {
|
||||
return this == FIRST || this == BOTH;
|
||||
}
|
||||
|
||||
boolean rendersSecond() {
|
||||
return this == SECOND || this == BOTH;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
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.GL30;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
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 BoxWidget confirm;
|
||||
private BoxWidget cancel;
|
||||
private BoxElement textBackground;
|
||||
|
||||
/*
|
||||
* 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
|
||||
public void tick() {
|
||||
super.tick();
|
||||
confirm.tick();
|
||||
cancel.tick();
|
||||
}
|
||||
|
||||
@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 BoxWidget(x + 4, y + textHeight + 2 , textWidth/2 - 10, 20)
|
||||
.withCallback(() -> accept(true));
|
||||
confirm.showingElement(confirmText.withElementRenderer(BoxWidget.gradientFactory.apply(confirm)));
|
||||
|
||||
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.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);
|
||||
|
||||
}
|
||||
|
||||
@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) {
|
||||
|
||||
textBackground.render(ms);
|
||||
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);
|
||||
//todo wait for jozu's framebuffer capabilities on the other branch and use them here
|
||||
UIRenderHelper.framebuffer.bindFramebuffer(true);
|
||||
source.render(ms, mouseX, mouseY, 10);
|
||||
UIRenderHelper.framebuffer.unbindFramebuffer();
|
||||
Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer();
|
||||
ms.pop();
|
||||
|
||||
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, UIRenderHelper.framebuffer.framebufferObject);
|
||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject);
|
||||
GL30.glBlitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL30.GL_LINEAR);
|
||||
mainBuffer.bindFramebuffer(true);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
public class DelegatedStencilElement extends StencilElement {
|
||||
|
||||
protected static final ElementRenderer EMPTY_RENDERER = (ms, width, height, alpha) -> {};
|
||||
protected static final ElementRenderer DEFAULT_ELEMENT = (ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, -3, 5, height+4, width+6, ColorHelper.applyAlpha(0xff_10dd10, alpha), ColorHelper.applyAlpha(0xff_1010dd, alpha));
|
||||
|
||||
protected ElementRenderer stencil;
|
||||
protected ElementRenderer element;
|
||||
|
||||
public DelegatedStencilElement() {
|
||||
stencil = EMPTY_RENDERER;
|
||||
element = DEFAULT_ELEMENT;
|
||||
}
|
||||
|
||||
public DelegatedStencilElement(ElementRenderer stencil, ElementRenderer element) {
|
||||
this.stencil = stencil;
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public <T extends DelegatedStencilElement> T withStencilRenderer(ElementRenderer renderer) {
|
||||
stencil = renderer;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends DelegatedStencilElement> T withElementRenderer(ElementRenderer renderer) {
|
||||
element = renderer;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
stencil.render(ms, width, height, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
element.render(ms, width, height, alpha);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ElementRenderer {
|
||||
void render(MatrixStack ms, int width, int height, float alpha);
|
||||
}
|
||||
|
||||
}
|
|
@ -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));
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.AbstractGui;
|
||||
|
||||
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;
|
||||
|
||||
public <T extends RenderElement> T at(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T at(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T withBounds(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T withAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public abstract void render(MatrixStack ms);
|
||||
|
||||
@Override
|
||||
public void draw(MatrixStack ms, AbstractGui screen, int x, int y) {
|
||||
this.at(x, y).render(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ public class ScreenOpener {
|
|||
if (screenHistory.isEmpty())
|
||||
return false;
|
||||
Screen previouslyRenderedScreen = screenHistory.get(0);
|
||||
if (!(previouslyRenderedScreen instanceof AbstractSimiScreen))
|
||||
if (!(previouslyRenderedScreen instanceof NavigatableSimiScreen))
|
||||
return false;
|
||||
if (!screen.isEquivalentTo((NavigatableSimiScreen) previouslyRenderedScreen))
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public abstract class StencilElement extends RenderElement {
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms) {
|
||||
ms.push();
|
||||
transform(ms);
|
||||
prepareStencil(ms);
|
||||
renderStencil(ms);
|
||||
prepareElement(ms);
|
||||
renderElement(ms);
|
||||
cleanUp(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
protected abstract void renderStencil(MatrixStack ms);
|
||||
|
||||
protected abstract void renderElement(MatrixStack ms);
|
||||
|
||||
protected void transform(MatrixStack ms) {
|
||||
ms.translate(x, y, z);
|
||||
}
|
||||
|
||||
protected void prepareStencil(MatrixStack ms) {
|
||||
GL11.glDisable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilMask(~0);
|
||||
RenderSystem.clear(GL11.GL_STENCIL_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC);
|
||||
GL11.glEnable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilOp(GL11.GL_REPLACE, GL11.GL_KEEP, GL11.GL_KEEP);
|
||||
RenderSystem.stencilMask(0xFF);
|
||||
RenderSystem.stencilFunc(GL11.GL_NEVER, 1, 0xFF);
|
||||
}
|
||||
|
||||
protected void prepareElement(MatrixStack ms) {
|
||||
GL11.glEnable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
|
||||
RenderSystem.stencilFunc(GL11.GL_EQUAL, 1, 0xFF);
|
||||
}
|
||||
|
||||
protected void cleanUp(MatrixStack ms) {
|
||||
GL11.glDisable(GL11.GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class TextStencilElement extends DelegatedStencilElement {
|
||||
|
||||
protected FontRenderer font;
|
||||
protected IFormattableTextComponent component;
|
||||
protected boolean centerVertically = false;
|
||||
protected boolean centerHorizontally = false;
|
||||
|
||||
public TextStencilElement(FontRenderer font) {
|
||||
super();
|
||||
this.font = font;
|
||||
height = 10;
|
||||
}
|
||||
|
||||
public TextStencilElement(FontRenderer font, String text) {
|
||||
this(font);
|
||||
component = new StringTextComponent(text);
|
||||
}
|
||||
|
||||
public TextStencilElement(FontRenderer font, IFormattableTextComponent component) {
|
||||
this(font);
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public TextStencilElement withText(String text) {
|
||||
component = new StringTextComponent(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextStencilElement withText(IFormattableTextComponent component) {
|
||||
this.component = component;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextStencilElement centered(boolean vertical, boolean horizontal) {
|
||||
this.centerVertically = vertical;
|
||||
this.centerHorizontally = horizontal;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
|
||||
float x = 0, y = 0;
|
||||
if (centerHorizontally)
|
||||
x = width / 2f - font.getWidth(component) / 2f;
|
||||
|
||||
if (centerVertically)
|
||||
y = height / 2f - font.FONT_HEIGHT / 2f;
|
||||
|
||||
font.draw(ms, component, x, y, 0xff_000000);
|
||||
//font.draw(ms, component, 0, 0, 0xff_000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
float x = 0, y = 0;
|
||||
if (centerHorizontally)
|
||||
x = width / 2f - font.getWidth(component) / 2f;
|
||||
|
||||
if (centerVertically)
|
||||
y = height / 2f - font.FONT_HEIGHT / 2f;
|
||||
|
||||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
element.render(ms, font.getWidth(component), font.FONT_HEIGHT + 2, alpha);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public IFormattableTextComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
}
|
177
src/main/java/com/simibubi/create/foundation/gui/Theme.java
Normal file
177
src/main/java/com/simibubi/create/foundation/gui/Theme.java
Normal file
|
@ -0,0 +1,177 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
public class Theme {
|
||||
|
||||
private static final Theme base = new Theme();
|
||||
private static Theme custom = null;
|
||||
|
||||
public static void setTheme(@Nullable Theme theme) {
|
||||
custom = theme;
|
||||
}
|
||||
|
||||
private static ColorHolder resolve(String key) {
|
||||
ColorHolder h = null;
|
||||
|
||||
if (custom != null)
|
||||
h = custom.get(key);
|
||||
|
||||
if (h == null)
|
||||
h = base.get(key);
|
||||
|
||||
if (h == null)
|
||||
h = ColorHolder.missing;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
@Nonnull public static Couple<Color> p(@Nonnull Key key) {return p(key.get());}
|
||||
@Nonnull public static Couple<Color> p(String key) {return resolve(key).asPair();}
|
||||
|
||||
@Nonnull public static Color c(@Nonnull Key key, boolean first) {return c(key.get(), first);}
|
||||
@Nonnull public static Color c(String key, boolean first) {return p(key).get(first);}
|
||||
|
||||
public static int i(@Nonnull Key key, boolean first) {return i(key.get(), first);}
|
||||
public static int i(String key, boolean first) {return p(key).get(first).getRGB();}
|
||||
|
||||
@Nonnull public static Color c(@Nonnull Key key) {return c(key.get());}
|
||||
@Nonnull public static Color c(String key) {return resolve(key).get();}
|
||||
|
||||
public static int i(@Nonnull Key key) {return i(key.get());}
|
||||
public static int i(String key) {return resolve(key).get().getRGB();}
|
||||
|
||||
//-----------//
|
||||
|
||||
protected final Map<String, ColorHolder> colors;
|
||||
|
||||
protected Theme() {
|
||||
colors = new HashMap<>();
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
put(Key.BUTTON_IDLE, new Color(0x60_c0c0ff, true), new Color(0x30_c0c0ff, true));
|
||||
put(Key.BUTTON_HOVER, new Color(0xa0_c0c0ff, true), new Color(0x50_c0c0ff, true));
|
||||
put(Key.BUTTON_CLICK, new Color(0xff_4b4bff), new Color(0xff_3b3bdd));
|
||||
put(Key.BUTTON_DISABLE, new Color(0x80_909090, true), new Color(0x20_909090, true));
|
||||
put(Key.BUTTON_SUCCESS, new Color(0xcc_88f788, true), new Color(0xcc_20cc20, true));
|
||||
put(Key.BUTTON_FAIL, new Color(0xcc_f78888, true), new Color(0xcc_cc2020, true));
|
||||
put(Key.TEXT, new Color(0xff_eeeeee), new Color(0xff_a3a3a3));
|
||||
put(Key.TEXT_DARKER, new Color(0xff_a3a3a3), new Color(0xff_808080));
|
||||
put(Key.TEXT_ACCENT_STRONG, new Color(0xff_7b7ba3), new Color(0xff_616192));
|
||||
put(Key.TEXT_ACCENT_SLIGHT, new Color(0xff_ddeeff), new Color(0xff_a0b0c0));
|
||||
put(Key.STREAK, new Color(0x101010, false));
|
||||
|
||||
put(Key.PONDER_BACKGROUND_TRANSPARENT, new Color(0xdd_000000, true));
|
||||
put(Key.PONDER_BACKGROUND_FLAT, new Color(0xff_000000, false));
|
||||
put(Key.PONDER_IDLE, new Color(0x40ffeedd, true), new Color(0x20ffeedd, true));
|
||||
put(Key.PONDER_HOVER, new Color(0x70ffffff, true), new Color(0x30ffffff, true));
|
||||
put(Key.PONDER_HIGHLIGHT, new Color(0xf0ffeedd, true), new Color(0x60ffeedd, true));
|
||||
put(Key.TEXT_WINDOW_BORDER, new Color(0x607a6000, true), new Color(0x207a6000, true));
|
||||
put(Key.PONDER_BACK_ARROW, new Color(0x70aa9999, true), new Color(0x30aa9999, true));
|
||||
put(Key.PONDER_PROGRESSBAR, new Color(0x80ffeedd, true), new Color(0x50ffeedd, true));
|
||||
put(Key.PONDER_MISSING_CREATE, new Color(0x70_984500, true), new Color(0x70_692400, true));
|
||||
put(Key.PONDER_MISSING_VANILLA, new Color(0x50_5000ff, true), new Color(0x50_300077, true));
|
||||
//put(Key., new Color(0x, true), new Color(0x, true));
|
||||
}
|
||||
|
||||
protected void put(String key, Color c) {
|
||||
colors.put(key, ColorHolder.single(c));
|
||||
}
|
||||
|
||||
protected void put(Key key, Color c) {
|
||||
put(key.get(), c);
|
||||
}
|
||||
|
||||
protected void put(String key, Color c1, Color c2) {
|
||||
colors.put(key, ColorHolder.pair(c1, c2));
|
||||
}
|
||||
|
||||
protected void put(Key key, Color c1, Color c2) {
|
||||
put(key.get(), c1 , c2);
|
||||
}
|
||||
|
||||
@Nullable protected ColorHolder get(String key) {
|
||||
return colors.get(key);
|
||||
}
|
||||
|
||||
public static class Key {
|
||||
|
||||
public static Key BUTTON_IDLE = new Key();
|
||||
public static Key BUTTON_HOVER = new Key();
|
||||
public static Key BUTTON_CLICK = new Key();
|
||||
public static Key BUTTON_DISABLE = new Key();
|
||||
public static Key BUTTON_SUCCESS = new Key();
|
||||
public static Key BUTTON_FAIL = new Key();
|
||||
|
||||
public static Key TEXT = new Key();
|
||||
public static Key TEXT_DARKER = new Key();
|
||||
public static Key TEXT_ACCENT_STRONG = new Key();
|
||||
public static Key TEXT_ACCENT_SLIGHT = new Key();
|
||||
|
||||
public static Key STREAK = new Key();
|
||||
|
||||
public static Key PONDER_BACKGROUND_TRANSPARENT = new Key();
|
||||
public static Key PONDER_BACKGROUND_FLAT = new Key();
|
||||
public static Key PONDER_IDLE = new Key();
|
||||
public static Key PONDER_HOVER = new Key();
|
||||
public static Key PONDER_HIGHLIGHT = new Key();
|
||||
public static Key TEXT_WINDOW_BORDER = new Key();
|
||||
public static Key PONDER_BACK_ARROW = new Key();
|
||||
public static Key PONDER_PROGRESSBAR = new Key();
|
||||
public static Key PONDER_MISSING_CREATE = new Key();
|
||||
public static Key PONDER_MISSING_VANILLA = new Key();
|
||||
|
||||
private static int index = 0;
|
||||
|
||||
private final String s;
|
||||
|
||||
protected Key() {
|
||||
this.s = "_" + index++;
|
||||
}
|
||||
|
||||
protected Key(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ColorHolder {
|
||||
|
||||
private static final ColorHolder missing = ColorHolder.single(Color.BLACK);
|
||||
|
||||
private Couple<Color> colors;
|
||||
|
||||
private static ColorHolder single(Color c) {
|
||||
ColorHolder h = new ColorHolder();
|
||||
h.colors = Couple.create(c, c);
|
||||
return h;
|
||||
}
|
||||
|
||||
private static ColorHolder pair(Color first, Color second) {
|
||||
ColorHolder h = new ColorHolder();
|
||||
h.colors = Couple.create(first, second);
|
||||
return h;
|
||||
}
|
||||
|
||||
private Color get() {
|
||||
return colors.getFirst();
|
||||
}
|
||||
|
||||
private Couple<Color> asPair() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,15 +1,21 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
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.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldVertexBufferUploader;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
@ -18,6 +24,10 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
|
|||
|
||||
public class UIRenderHelper {
|
||||
|
||||
public static void enableStencil() {
|
||||
RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil());
|
||||
}
|
||||
|
||||
public static Framebuffer framebuffer;
|
||||
|
||||
public static void init() {
|
||||
|
@ -27,19 +37,17 @@ public class UIRenderHelper {
|
|||
framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true,
|
||||
Minecraft.IS_RUNNING_ON_MAC);
|
||||
framebuffer.setFramebufferColor(0, 0, 0, 0);
|
||||
framebuffer.enableStencil();
|
||||
// framebuffer.deleteFramebuffer();
|
||||
});
|
||||
}
|
||||
|
||||
public static void prepFramebufferSize() {
|
||||
MainWindow window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|
||||
|| framebuffer.framebufferHeight != window.getFramebufferHeight()) {
|
||||
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(),
|
||||
Minecraft.IS_RUNNING_ON_MAC);
|
||||
/*public static void prepFramebufferSize() {
|
||||
MainWindow window = Minecraft.getInstance().getWindow();
|
||||
if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) {
|
||||
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public static void drawFramebuffer(float alpha) {
|
||||
MainWindow window = Minecraft.getInstance()
|
||||
|
@ -51,10 +59,6 @@ public class UIRenderHelper {
|
|||
float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight;
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.disableLighting();
|
||||
RenderSystem.disableAlphaTest();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
framebuffer.bindFramebufferTexture();
|
||||
|
@ -82,14 +86,14 @@ public class UIRenderHelper {
|
|||
|
||||
tessellator.draw();
|
||||
framebuffer.unbindFramebufferTexture();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableAlphaTest();
|
||||
}
|
||||
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length) {streak(ms, angle, x, y, breadth, length, Theme.i(Theme.Key.STREAK));}
|
||||
|
||||
// angle in degrees; 0° -> fading to the right
|
||||
// x and y specify the middle point of the starting edge
|
||||
// width is the total width of the streak
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int width, int length, int color) {
|
||||
// breadth is the total width of the streak
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length, int color) {
|
||||
int a1 = 0xa0 << 24;
|
||||
int a2 = 0x80 << 24;
|
||||
int a3 = 0x10 << 24;
|
||||
|
@ -105,7 +109,7 @@ public class UIRenderHelper {
|
|||
ms.translate(x, y, 0);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90));
|
||||
|
||||
streak(ms, width / 2, length, c1, c2, c3, c4);
|
||||
streak(ms, breadth / 2, length, c1, c2, c3, c4);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -120,9 +124,49 @@ public class UIRenderHelper {
|
|||
GuiUtils.drawGradientRect(model, 0, -width, (int) (split2 * height), width, height, c3, c4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int breadth, int length, Couple<Color> c) {
|
||||
angledGradient(ms, angle, x, y, 0, breadth, length, c);
|
||||
}
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int breadth, int length, Couple<Color> c) {
|
||||
angledGradient(ms, angle, x, y, z, breadth, length, c.getFirst().getRGB(), c.getSecond().getRGB());
|
||||
}
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int breadth, int length, int color1, int color2) {
|
||||
angledGradient(ms, angle, x, y, 0, breadth, length, color1, color2);
|
||||
}
|
||||
/**
|
||||
* x and y specify the middle point of the starting edge
|
||||
*
|
||||
* @param angle the angle of the gradient in degrees; 0° means from left to right
|
||||
* @param color1 the color at the starting edge
|
||||
* @param color2 the color at the ending edge
|
||||
* @param breadth the total width of the gradient
|
||||
*
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int breadth, int length, int color1, int color2) {
|
||||
ms.push();
|
||||
ms.translate(x, y, z);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90));
|
||||
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
int w = breadth / 2;
|
||||
GuiUtils.drawGradientRect(model, 0, -w, 0, w, length, color1, color2);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent, Couple<Color> colors) {breadcrumbArrow(matrixStack, x, y, z, width, height, indent, colors.getFirst().getRGB(), colors.getSecond().getRGB());}
|
||||
|
||||
// draws a wide chevron-style breadcrumb arrow pointing left
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent,
|
||||
int startColor, int endColor) {
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent, int startColor, int endColor) {
|
||||
matrixStack.push();
|
||||
matrixStack.translate(x - indent, y, z);
|
||||
|
||||
|
@ -241,4 +285,30 @@ public class UIRenderHelper {
|
|||
RenderSystem.enableAlphaTest();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
|
||||
//just like AbstractGui#drawTexture, but with a color at every vertex
|
||||
public static void drawColoredTexture(MatrixStack ms, Color c, int x, int y, int tex_left, int tex_top, int width, int height) {
|
||||
drawColoredTexture(ms, c, x, y, 0, (float)tex_left, (float)tex_top, width, height, 256, 256);
|
||||
}
|
||||
|
||||
public static void drawColoredTexture(MatrixStack ms, Color c, int x, int y, int z, float tex_left, float tex_top, int width, int height, int sheet_width, int sheet_height) {
|
||||
drawColoredTexture(ms, c, x, x + width, y, y + height, z, width, height, tex_left, tex_top, sheet_width, sheet_height);
|
||||
}
|
||||
|
||||
private static void drawColoredTexture(MatrixStack ms, Color c, int left, int right, int top, int bot, int z, int tex_width, int tex_height, float tex_left, float tex_top, int sheet_width, int sheet_height) {
|
||||
drawTexturedQuad(ms.peek().getModel(), c, left, right, top, bot, z, (tex_left + 0.0F) / (float)sheet_width, (tex_left + (float)tex_width) / (float)sheet_width, (tex_top + 0.0F) / (float)sheet_height, (tex_top + (float)tex_height) / (float)sheet_height);
|
||||
}
|
||||
|
||||
private static void drawTexturedQuad(Matrix4f m, Color c, int left, int right, int top, int bot, int z, float u1, float u2, float v1, float v2) {
|
||||
RenderSystem.enableBlend();
|
||||
BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
|
||||
bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR_TEXTURE);
|
||||
bufferbuilder.vertex(m, (float)left , (float)bot, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u1, v2).endVertex();
|
||||
bufferbuilder.vertex(m, (float)right, (float)bot, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u2, v2).endVertex();
|
||||
bufferbuilder.vertex(m, (float)right, (float)top, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u2, v1).endVertex();
|
||||
bufferbuilder.vertex(m, (float)left , (float)top, (float)z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u1, v1).endVertex();
|
||||
bufferbuilder.finishDrawing();
|
||||
RenderSystem.enableAlphaTest();
|
||||
WorldVertexBufferUploader.draw(bufferbuilder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.simibubi.create.foundation.gui.widgets;
|
|||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
|
@ -11,19 +14,78 @@ import net.minecraft.util.text.StringTextComponent;
|
|||
|
||||
public abstract class AbstractSimiWidget extends Widget {
|
||||
|
||||
protected List<ITextComponent> toolTip;
|
||||
|
||||
public AbstractSimiWidget(int xIn, int yIn, int widthIn, int heightIn) {
|
||||
super(xIn, yIn, widthIn, heightIn, StringTextComponent.EMPTY);
|
||||
toolTip = new LinkedList<>();
|
||||
protected float z;
|
||||
protected boolean wasHovered = false;
|
||||
protected List<ITextComponent> toolTip = new LinkedList<>();
|
||||
protected BiConsumer<Integer, Integer> onClick = (_$, _$$) -> {};
|
||||
|
||||
protected AbstractSimiWidget() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
|
||||
protected AbstractSimiWidget(int x, int y) {
|
||||
this(x, y, 16, 16);
|
||||
}
|
||||
|
||||
protected AbstractSimiWidget(int x, int y, int width, int height) {
|
||||
super(x, y, width, height, StringTextComponent.EMPTY);
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T withCallback(BiConsumer<Integer, Integer> cb) {
|
||||
this.onClick = cb;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T withCallback(Runnable cb) {
|
||||
return withCallback((_$, _$$) -> cb.run());
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T atZLevel(float z) {
|
||||
this.z = z;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public List<ITextComponent> getToolTip() {
|
||||
return toolTip;
|
||||
}
|
||||
|
||||
|
||||
public void tick() {}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrixStack, int p_renderButton_1_, int p_renderButton_2_, float p_renderButton_3_) {
|
||||
public void render(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (visible) {
|
||||
hovered = isMouseOver(mouseX, mouseY);
|
||||
beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
afterRender(ms, mouseX, mouseY, partialTicks);
|
||||
wasHovered = isHovered();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {}
|
||||
|
||||
@Override
|
||||
protected boolean clicked(double mouseX, double mouseY) {
|
||||
return active && visible && isMouseOver(mouseX, mouseY);
|
||||
}
|
||||
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
ms.push();
|
||||
}
|
||||
|
||||
protected void afterRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public void runCallback(double mouseX, double mouseY) {
|
||||
onClick.accept((int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double mouseX, double mouseY) {
|
||||
runCallback(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
public class BoxWidget extends ElementWidget {
|
||||
|
||||
public static final Function<BoxWidget, DelegatedStencilElement.ElementRenderer> gradientFactory = (box) -> (ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, w/2, -2, w + 4, h + 4, box.gradientColor1.getRGB(), box.gradientColor2.getRGB());
|
||||
|
||||
protected BoxElement box;
|
||||
|
||||
protected Color customBorderTop;
|
||||
protected Color customBorderBot;
|
||||
protected boolean animateColors = true;
|
||||
protected LerpedFloat colorAnimation = LerpedFloat.linear();
|
||||
protected Color gradientColor1, gradientColor2;
|
||||
private Color colorTarget1 = Theme.c(Theme.Key.BUTTON_IDLE, true), colorTarget2 = Theme.c(Theme.Key.BUTTON_IDLE, false);
|
||||
private Color previousColor1, previousColor2;
|
||||
|
||||
public BoxWidget() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
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 <T extends BoxWidget> T withBounds(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T withBorderColors(Couple<Color> colors) {
|
||||
this.customBorderTop = colors.getFirst();
|
||||
this.customBorderBot = colors.getSecond();
|
||||
updateColorsFromState();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T withBorderColors(Color top, Color bot) {
|
||||
this.customBorderTop = top;
|
||||
this.customBorderBot = bot;
|
||||
updateColorsFromState();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T animateColors(boolean b) {
|
||||
this.animateColors = b;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
colorAnimation.tickChaser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double x, double y) {
|
||||
super.onClick(x, y);
|
||||
|
||||
gradientColor1 = Theme.c(Theme.Key.BUTTON_CLICK, true);
|
||||
gradientColor2 = Theme.c(Theme.Key.BUTTON_CLICK, true);
|
||||
startGradientAnimation(getColorForState(true), getColorForState(false), true, 0.15);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
if (hovered != wasHovered) {
|
||||
startGradientAnimation(
|
||||
getColorForState(true),
|
||||
getColorForState(false),
|
||||
hovered
|
||||
);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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_TRANSPARENT))
|
||||
.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)
|
||||
return false;
|
||||
|
||||
return
|
||||
x - 4 <= mX &&
|
||||
y - 4 <= mY &&
|
||||
mX <= x + 4 + width &&
|
||||
mY <= y + 4 + height;
|
||||
}
|
||||
|
||||
public BoxElement getBox() {
|
||||
return box;
|
||||
}
|
||||
|
||||
public void updateColorsFromState() {
|
||||
colorTarget1 = getColorForState(true);
|
||||
colorTarget2 = getColorForState(false);
|
||||
}
|
||||
|
||||
public void animateGradientFromState() {
|
||||
startGradientAnimation(
|
||||
getColorForState(true),
|
||||
getColorForState(false),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
colorTarget1 = c1;
|
||||
colorTarget2 = c2;
|
||||
}
|
||||
|
||||
private void startGradientAnimation(Color c1, Color c2, boolean positive) {
|
||||
startGradientAnimation(c1, c2, positive, 0.3);
|
||||
}
|
||||
|
||||
private Color getColorForState(boolean first) {
|
||||
if (!active)
|
||||
return Theme.p(Theme.Key.BUTTON_DISABLE).get(first);
|
||||
|
||||
if (hovered) {
|
||||
if (first)
|
||||
return customBorderTop != null ? customBorderTop.darker() : Theme.c(Theme.Key.BUTTON_HOVER, true);
|
||||
else
|
||||
return customBorderBot != null ? customBorderBot.darker() : Theme.c(Theme.Key.BUTTON_HOVER, false);
|
||||
}
|
||||
|
||||
if (first)
|
||||
return customBorderTop != null ? customBorderTop : Theme.c(Theme.Key.BUTTON_IDLE, true);
|
||||
else
|
||||
return customBorderBot != null ? customBorderBot : Theme.c(Theme.Key.BUTTON_IDLE, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
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;
|
||||
|
||||
public class ElementWidget extends AbstractSimiWidget {
|
||||
|
||||
protected RenderElement element = RenderElement.EMPTY;
|
||||
|
||||
protected boolean usesFade = false;
|
||||
protected int fadeModX;
|
||||
protected int fadeModY;
|
||||
protected LerpedFloat fade = LerpedFloat.linear().startWithValue(1);
|
||||
|
||||
protected boolean rescaleElement = false;
|
||||
protected float rescaleSizeX;
|
||||
protected float rescaleSizeY;
|
||||
|
||||
protected float paddingX = 0;
|
||||
protected float paddingY = 0;
|
||||
|
||||
public ElementWidget(int x, int y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
public ElementWidget(int x, int y, int width, int height) {
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T showingElement(RenderElement element) {
|
||||
this.element = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T showing(IScreenRenderable renderable) {
|
||||
return this.showingElement(RenderElement.of(renderable));
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T modifyElement(Consumer<RenderElement> consumer) {
|
||||
if (element != null)
|
||||
consumer.accept(element);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T mapElement(UnaryOperator<RenderElement> function) {
|
||||
if (element != null)
|
||||
element = function.apply(element);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T withPadding(float paddingX, float paddingY) {
|
||||
this.paddingX = paddingX;
|
||||
this.paddingY = paddingY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T enableFade(int fadeModifierX, int fadeModifierY) {
|
||||
this.fade.startWithValue(0);
|
||||
this.usesFade = true;
|
||||
this.fadeModX = fadeModifierX;
|
||||
this.fadeModY = fadeModifierY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T disableFade() {
|
||||
this.fade.startWithValue(1);
|
||||
this.usesFade = false;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public LerpedFloat fade() {
|
||||
return fade;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T fade(float target) {
|
||||
fade.chase(target, 0.1, LerpedFloat.Chaser.EXP);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T rescaleElement(float rescaleSizeX, float rescaleSizeY) {
|
||||
this.rescaleElement = true;
|
||||
this.rescaleSizeX = rescaleSizeX;
|
||||
this.rescaleSizeY = rescaleSizeY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T disableRescale() {
|
||||
this.rescaleElement = false;
|
||||
//noinspection unchecked
|
||||
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);
|
||||
|
||||
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 + paddingX, y + paddingY, z);
|
||||
float innerWidth = width - 2 * paddingX;
|
||||
float innerHeight = height - 2 * paddingY;
|
||||
if (rescaleElement) {
|
||||
float xScale = innerWidth / rescaleSizeX;
|
||||
float yScale = innerHeight / rescaleSizeY;
|
||||
ms.scale(xScale, yScale, 1);
|
||||
element.at(element.getX() / xScale, element.getY() / yScale);
|
||||
}
|
||||
element.withBounds((int) innerWidth, (int) innerHeight).render(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public RenderElement getRenderElement() {
|
||||
return element;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import com.simibubi.create.foundation.gui.AllIcons;
|
|||
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class IconButton extends AbstractSimiWidget {
|
||||
|
||||
private AllIcons icon;
|
||||
|
@ -18,7 +20,7 @@ public class IconButton extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
public void renderButton(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
if (this.visible) {
|
||||
this.hovered =
|
||||
mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
|
@ -22,7 +24,7 @@ public class Indicator extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks ) {
|
||||
public void render(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks ) {
|
||||
AllGuiTextures toDraw;
|
||||
switch(state) {
|
||||
case ON: toDraw = AllGuiTextures.INDICATOR_WHITE; break;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
|
@ -69,7 +71,7 @@ public class Label extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
public void render(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
if (!visible)
|
||||
return;
|
||||
if (text == null || text.getString().isEmpty())
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Mixin(Minecraft.class)
|
||||
public class WindowResizeMixin {
|
||||
|
||||
@Shadow @Final private MainWindow mainWindow;
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "updateWindowSize")
|
||||
private void updateWindowSize(CallbackInfo ci) {
|
||||
if (UIRenderHelper.framebuffer != null)
|
||||
UIRenderHelper.framebuffer.func_216491_a(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC);
|
||||
}
|
||||
|
||||
}
|
|
@ -38,8 +38,9 @@ import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
|||
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
|
||||
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.command.HighlightPacket;
|
||||
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
@ -80,12 +81,13 @@ public enum AllPackets {
|
|||
PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER),
|
||||
TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER),
|
||||
EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER),
|
||||
C_CONFIGURE_CONFIG(CConfigureConfigPacket.class, CConfigureConfigPacket::new, PLAY_TO_SERVER),
|
||||
|
||||
// Server to Client
|
||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
||||
SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT),
|
||||
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT),
|
||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT),
|
||||
S_CONFIGURE_CONFIG(SConfigureConfigPacket.class, SConfigureConfigPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT),
|
||||
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT),
|
||||
|
|
|
@ -9,9 +9,11 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
|||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
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.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;
|
||||
|
@ -76,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)
|
||||
|
@ -97,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_DARKER));
|
||||
if (MathHelper.epsilonEquals(arrowAnimation.getValue(), arrowAnimation.getChaseTarget())) {
|
||||
arrowAnimation.setValue(1);
|
||||
arrowAnimation.setValue(1);// called twice to also set the previous value to 1
|
||||
|
@ -108,7 +110,18 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
|
||||
@Override
|
||||
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (transition.getChaseTarget() == 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, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
|
||||
UIRenderHelper.breadcrumbArrow(ms, x, height - 51, 0, 30, 20, 5, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
UIRenderHelper.breadcrumbArrow(ms, x - 30, height - 51, 0, 30, 20, 5, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
}
|
||||
|
||||
if (transition.getChaseTarget() == 0 || transition.settled()) {
|
||||
renderBackground(ms);
|
||||
return;
|
||||
}
|
||||
|
@ -123,11 +136,11 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
if (lastScreen != null && lastScreen != this && !transition.settled()) {
|
||||
ms.push();// 1
|
||||
UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC);
|
||||
UIRenderHelper.prepFramebufferSize();
|
||||
//UIRenderHelper.prepFramebufferSize();
|
||||
ms.push();// 2
|
||||
ms.translate(0, 0, -1000);
|
||||
UIRenderHelper.framebuffer.bindFramebuffer(true);
|
||||
lastScreen.render(ms, mouseX, mouseY, 10);
|
||||
lastScreen.render(ms, mouseX, mouseY, partialTicks);
|
||||
ms.pop();// 2
|
||||
|
||||
// use the buffer texture
|
||||
|
@ -149,7 +162,12 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
ms.translate(dpx, dpy, 0);
|
||||
ms.scale((float) scale, (float) scale, 1);
|
||||
ms.translate(-dpx, -dpy, 0);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableAlphaTest();
|
||||
UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue));
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableAlphaTest();
|
||||
ms.pop();// 1
|
||||
}
|
||||
|
||||
|
@ -158,18 +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
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
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.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;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
@ -15,7 +19,6 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
|
|||
public class PonderProgressBar extends AbstractSimiWidget {
|
||||
|
||||
LerpedFloat progress;
|
||||
LerpedFloat flash;
|
||||
|
||||
PonderUI ponder;
|
||||
|
||||
|
@ -25,27 +28,12 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
this.ponder = ponder;
|
||||
progress = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
flash = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
progress.chase(ponder.getActiveScene()
|
||||
.getSceneProgress(), .5f, LerpedFloat.Chaser.EXP);
|
||||
progress.tickChaser();
|
||||
|
||||
if (hovered)
|
||||
flash();
|
||||
}
|
||||
|
||||
public void flash() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value + (1 - value) * .2f);
|
||||
}
|
||||
|
||||
public void dim() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value * .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,58 +90,47 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
|
||||
hovered = clicked(mouseX, mouseY);
|
||||
|
||||
ms.push();
|
||||
ms.translate(0, 0, 250);
|
||||
/*
|
||||
* ponderButtons are at z+400
|
||||
* renderBox is at z+100
|
||||
* gradients have to be in front of the box so z>+100
|
||||
*/
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(x, y, 250)
|
||||
.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);
|
||||
ms.translate(x - 2, y - 2, 150);
|
||||
|
||||
ms.push();
|
||||
ms.scale((width + 4) * progress.getValue(partialTicks), 1, 1);
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 110, 0, 3, 1, 4, 0x80ffeedd, 0x80ffeedd);
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 110, 0, 4, 1, 5, 0x50ffeedd, 0x50ffeedd);
|
||||
int c1 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, true);
|
||||
int c2 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, false);
|
||||
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 3, 1, 4, c1, c1);
|
||||
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 4, 1, 5, c2, c2);
|
||||
ms.pop();
|
||||
|
||||
renderKeyframes(ms, mouseX, partialTicks);
|
||||
|
||||
ms.pop();
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private void renderKeyframes(MatrixStack ms, int mouseX, float partialTicks) {
|
||||
PonderScene activeScene = ponder.getActiveScene();
|
||||
|
||||
int hoverStartColor;
|
||||
int hoverEndColor;
|
||||
int hoverStartColor = Theme.i(Theme.Key.PONDER_HOVER, true) | 0xa0_000000;
|
||||
int hoverEndColor = Theme.i(Theme.Key.PONDER_HOVER, false) | 0xa0_000000;
|
||||
int idleStartColor = Theme.i(Theme.Key.PONDER_IDLE, true) | 0x40_000000;
|
||||
int idleEndColor = Theme.i(Theme.Key.PONDER_IDLE, false) | 0x40_000000;
|
||||
int hoverIndex;
|
||||
|
||||
if (hovered) {
|
||||
hoverIndex = getHoveredKeyframeIndex(activeScene, mouseX);
|
||||
float flashValue = flash.getValue(partialTicks) * 3
|
||||
+ (float) Math.sin((AnimationTickHolder.getTicks() + partialTicks) / 6);
|
||||
|
||||
hoverEndColor = ColorHelper.applyAlpha(0x70ffffff, flashValue);
|
||||
hoverStartColor = ColorHelper.applyAlpha(0x30ffffff, flashValue);
|
||||
} else {
|
||||
hoverIndex = -2;
|
||||
hoverEndColor = 0;
|
||||
hoverStartColor = 0;
|
||||
}
|
||||
IntList keyframeTimes = activeScene.keyframeTimes;
|
||||
|
||||
|
@ -167,8 +144,8 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
int keyframePos = (int) (((float) keyframeTime) / ((float) activeScene.totalTime) * (width + 4));
|
||||
|
||||
boolean selected = i == hoverIndex;
|
||||
int startColor = selected ? hoverStartColor : 0x30ffeedd;
|
||||
int endColor = selected ? hoverEndColor : 0x60ffeedd;
|
||||
int startColor = selected ? hoverStartColor : idleStartColor;
|
||||
int endColor = selected ? hoverEndColor : idleEndColor;
|
||||
int height = selected ? 8 : 4;
|
||||
|
||||
drawKeyframe(ms, activeScene, selected, keyframeTime, keyframePos, startColor, endColor, height);
|
||||
|
@ -176,8 +153,7 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
}
|
||||
}
|
||||
|
||||
private void drawKeyframe(MatrixStack ms, PonderScene activeScene, boolean selected, int keyframeTime,
|
||||
int keyframePos, int startColor, int endColor, int height) {
|
||||
private void drawKeyframe(MatrixStack ms, PonderScene activeScene, boolean selected, int keyframeTime, int keyframePos, int startColor, int endColor, int height) {
|
||||
if (selected) {
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
|
|
|
@ -2,13 +2,13 @@ package com.simibubi.create.foundation.ponder;
|
|||
|
||||
import static com.simibubi.create.foundation.ponder.PonderLocalization.LANG_PREFIX;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
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 +16,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;
|
||||
|
@ -29,6 +31,7 @@ import com.simibubi.create.foundation.ponder.elements.TextWindowElement;
|
|||
import com.simibubi.create.foundation.ponder.ui.PonderButton;
|
||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.FontHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -43,14 +46,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 +167,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 +185,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 +197,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(slowMode = new PonderButton(width - 20 - 31, bY, () -> {
|
||||
setComfyReadingEnabled(!isComfyReadingEnabled());
|
||||
}).showing(AllIcons.I_MTD_SLOW_MODE)
|
||||
.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)
|
||||
.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
|
||||
|
@ -527,17 +541,16 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
float lazyIndexValue = lazyIndex.getValue(partialTicks);
|
||||
float indexDiff = Math.abs(lazyIndexValue - index);
|
||||
PonderScene activeScene = scenes.get(index);
|
||||
int textColor = 0xeeeeee;
|
||||
|
||||
boolean noWidgetsHovered = true;
|
||||
for (Widget widget : widgets)
|
||||
noWidgetsHovered &= !widget.isMouseOver(mouseX, mouseY);
|
||||
|
||||
int tooltipColor = 0xffa3a3a3;
|
||||
int tooltipColor = Theme.i(Theme.Key.TEXT_DARKER);
|
||||
{
|
||||
// Chapter title
|
||||
ms.push();
|
||||
ms.translate(0, 0, 300);
|
||||
ms.translate(0, 0, 100);
|
||||
int x = 31 + 20 + 8;
|
||||
int y = 31;
|
||||
|
||||
|
@ -545,14 +558,21 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
int wordWrappedHeight = textRenderer.getWordWrappedHeight(title, left.x - 51);
|
||||
|
||||
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);
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade));
|
||||
UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade));
|
||||
//renderBox(ms, 21, 21, 30, 30, false);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(21, 21, 100)
|
||||
.withBounds(30, 30)
|
||||
.render(ms);
|
||||
|
||||
|
||||
GuiGameElement.of(stack)
|
||||
.at(x - 39, y - 11)
|
||||
.scale(2)
|
||||
.render(ms);
|
||||
.scale(2)
|
||||
.at(x - 39, y - 11)
|
||||
.render(ms);
|
||||
|
||||
textRenderer.draw(ms, Lang.translate(PONDERING), x, y - 6, tooltipColor);
|
||||
y += 8;
|
||||
|
@ -562,19 +582,18 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.multiply(Vector3f.NEGATIVE_X.getDegreesQuaternion(indexDiff * -75));
|
||||
ms.translate(0, 0, 5);
|
||||
FontHelper.drawSplitString(ms, textRenderer, title, 0, 0, left.x - 51,
|
||||
ColorHelper.applyAlpha(textColor, 1 - indexDiff));
|
||||
ColorHelper.applyAlpha(Theme.i(Theme.Key.TEXT), 1 - indexDiff));
|
||||
ms.pop();
|
||||
|
||||
if (chapter != null) {
|
||||
ms.push();
|
||||
|
||||
ms.translate(chap.x - 4 - 4, chap.y, 0);
|
||||
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade), 0x101010);
|
||||
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade));
|
||||
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(IN_CHAPTER)
|
||||
.getString(), 0, 0, tooltipColor);
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(LANG_PREFIX + "chapter." + chapter.getId())
|
||||
.getString(), 0, 12, 0xffeeeeee);
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(IN_CHAPTER).getString(), 0, 0, tooltipColor);
|
||||
drawRightAlignedString(textRenderer, ms,
|
||||
Lang.translate(LANG_PREFIX + "chapter." + chapter.getId()).getString(), 0, 12, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -590,29 +609,24 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(mouseX, mouseY, 100);
|
||||
if (hoveredTooltipItem.isEmpty()) {
|
||||
IFormattableTextComponent text = Lang
|
||||
.translate(IDENTIFY_MODE,
|
||||
((IFormattableTextComponent) client.gameSettings.keyBindDrop.getBoundKeyLocalizedText())
|
||||
.formatted(TextFormatting.WHITE))
|
||||
.formatted(TextFormatting.GRAY);
|
||||
IFormattableTextComponent text = Lang.translate(
|
||||
IDENTIFY_MODE,
|
||||
((IFormattableTextComponent) client.gameSettings.keyBindDrop.getBoundKeyLocalizedText()).formatted(TextFormatting.WHITE)
|
||||
).formatted(TextFormatting.GRAY);
|
||||
|
||||
// renderOrderedTooltip(ms, textRenderer.wrapLines(text, width / 3), 0, 0);
|
||||
renderWrappedToolTip(ms, textRenderer.getTextHandler()
|
||||
.wrapLines(text, width / 3, Style.EMPTY), 0, 0, textRenderer);
|
||||
/*
|
||||
* String tooltip = Lang
|
||||
* .createTranslationTextComponent(IDENTIFY_MODE, client.gameSettings.keyBindDrop.getBoundKeyLocalizedText().applyTextStyle(TextFormatting.WHITE))
|
||||
* .applyTextStyle(TextFormatting.GRAY)
|
||||
* .getFormattedText();
|
||||
* renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);
|
||||
*/
|
||||
//renderOrderedTooltip(ms, textRenderer.wrapLines(text, width / 3), 0, 0);
|
||||
renderWrappedToolTip(ms, textRenderer.getTextHandler().wrapLines(text, width / 3, Style.EMPTY), 0, 0, textRenderer);
|
||||
/*String tooltip = Lang
|
||||
.createTranslationTextComponent(IDENTIFY_MODE, client.gameSettings.keyBindDrop.getBoundKeyLocalizedText().applyTextStyle(TextFormatting.WHITE))
|
||||
.applyTextStyle(TextFormatting.GRAY)
|
||||
.getFormattedText();
|
||||
renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);*/
|
||||
} else
|
||||
renderTooltip(ms, hoveredTooltipItem, 0, 0);
|
||||
if (hoveredBlockPos != null && PonderIndex.EDITOR_MODE && !userViewMode) {
|
||||
ms.translate(0, -15, 0);
|
||||
boolean copied = copiedBlockPos != null && hoveredBlockPos.equals(copiedBlockPos);
|
||||
IFormattableTextComponent coords = new StringTextComponent(
|
||||
hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
IFormattableTextComponent coords = new StringTextComponent(hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
.formatted(copied ? TextFormatting.GREEN : TextFormatting.GOLD);
|
||||
renderTooltip(ms, coords, 0, 0);
|
||||
}
|
||||
|
@ -649,15 +663,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)
|
||||
|
@ -693,14 +706,14 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.translate(x, y + 5 * (1 - fade), 800);
|
||||
|
||||
float fadedWidth = 200 * chase.getValue(partialTicks);
|
||||
UIRenderHelper.streak(ms, 0, 0, 12, 26, (int) fadedWidth, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, 0, 12, 26, (int) fadedWidth);
|
||||
|
||||
GL11.glScissor((int) (x * s), 0, (int) (fadedWidth * s), (int) (height * s));
|
||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
String tagName = this.tags.get(i)
|
||||
.getTitle();
|
||||
textRenderer.draw(ms, tagName, 3, 8, 0xffeedd);
|
||||
textRenderer.draw(ms, tagName, 3, 8, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
GL11.glDisable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
|
@ -727,8 +740,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);
|
||||
|
@ -740,10 +752,9 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boolean hovered = isMouseOver(mouseX, mouseY, bX, bY, bWidth, bHeight);
|
||||
renderBox(ms, bX, bY, bWidth, bHeight, hovered);
|
||||
icon.draw(ms, bX + 2, bY + 2);
|
||||
drawCenteredText(ms, textRenderer, key.getBoundKeyLocalizedText(), bX + bWidth / 2 + 8, bY + bHeight - 6,
|
||||
0xff606060);
|
||||
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)
|
||||
|
@ -756,7 +767,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;
|
||||
|
@ -771,7 +782,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
});
|
||||
|
||||
if (handled.booleanValue())
|
||||
return true;
|
||||
return true;*/
|
||||
|
||||
if (identifyMode && hoveredBlockPos != null && PonderIndex.EDITOR_MODE) {
|
||||
long handle = client.getWindow()
|
||||
|
@ -843,8 +854,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
.getString();
|
||||
|
||||
return stack.getItem()
|
||||
.getName()
|
||||
.getString();
|
||||
.getName()
|
||||
.getString();
|
||||
}
|
||||
|
||||
public FontRenderer getFontRenderer() {
|
||||
|
@ -857,13 +868,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
return hovered;
|
||||
}
|
||||
|
||||
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) {
|
||||
public static void renderSpeechBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted, Pointing pointing,
|
||||
boolean returnWithLocalTransform) {
|
||||
if (!returnWithLocalTransform)
|
||||
ms.push();
|
||||
|
||||
|
@ -875,6 +881,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
int divotSize = 8;
|
||||
int distance = 1;
|
||||
int divotRadius = divotSize / 2;
|
||||
Couple<Color> borderColors = Theme.p(highlighted ? Theme.Key.PONDER_HIGHLIGHT : Theme.Key.PONDER_IDLE);
|
||||
Color c;
|
||||
|
||||
switch (pointing) {
|
||||
default:
|
||||
|
@ -884,6 +892,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h + divotSize + 1 + distance;
|
||||
divotX -= divotRadius;
|
||||
divotY -= divotSize + distance;
|
||||
c = borderColors.getSecond();
|
||||
break;
|
||||
case LEFT:
|
||||
divotRotation = 90;
|
||||
|
@ -891,6 +900,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h / 2;
|
||||
divotX += distance;
|
||||
divotY -= divotRadius;
|
||||
c = ColorHelper.mixColors(borderColors, 0.5f);
|
||||
break;
|
||||
case RIGHT:
|
||||
divotRotation = 270;
|
||||
|
@ -898,6 +908,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h / 2;
|
||||
divotX -= divotSize + distance;
|
||||
divotY -= divotRadius;
|
||||
c = ColorHelper.mixColors(borderColors, 0.5f);
|
||||
break;
|
||||
case UP:
|
||||
divotRotation = 180;
|
||||
|
@ -905,17 +916,24 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY += divotSize + 1 + distance;
|
||||
divotX -= divotRadius;
|
||||
divotY += distance;
|
||||
c = borderColors.getFirst();
|
||||
break;
|
||||
}
|
||||
|
||||
renderBox(ms, boxX, boxY, w, h, highlighted);
|
||||
//renderBox(ms, boxX, boxY, w, h, highlighted);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(borderColors)
|
||||
.at(boxX, boxY, 100)
|
||||
.withBounds(w, h)
|
||||
.render(ms);
|
||||
|
||||
ms.push();
|
||||
AllGuiTextures toRender = highlighted ? AllGuiTextures.SPEECH_TOOLTIP_HIGHLIGHT : AllGuiTextures.SPEECH_TOOLTIP;
|
||||
ms.translate(divotX + divotRadius, divotY + divotRadius, 10);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(divotRotation));
|
||||
ms.translate(-divotRadius, -divotRadius, 0);
|
||||
toRender.draw(ms, 0, 0);
|
||||
AllGuiTextures.SPEECH_TOOLTIP_BACKGROUND.draw(ms, 0, 0);
|
||||
AllGuiTextures.SPEECH_TOOLTIP_COLOR.draw(ms, 0, 0, c);
|
||||
ms.pop();
|
||||
|
||||
if (returnWithLocalTransform) {
|
||||
|
@ -927,23 +945,20 @@ 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();
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 4, x + w + 3, y - 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y + h + 3, x + w + 3, y + h + 4, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 3, x + w + 3, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 4, y - 3, x - 3, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x + w + 3, y - 3, x + w + 4, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 3 + 1, x - 3 + 1, y + h + 3 - 1, borderColorStart,
|
||||
borderColorEnd);
|
||||
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 + 1, x - 3 + 1, y + h + 3 - 1, borderColorStart, borderColorEnd);
|
||||
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;
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlock;
|
||||
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.PonderRegistry;
|
||||
|
@ -106,17 +107,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();
|
||||
}
|
||||
|
||||
|
@ -158,8 +159,8 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -170,8 +171,8 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -189,7 +190,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 +208,7 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
if (handled.booleanValue())
|
||||
return true;
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(NavigatableSimiScreen other) {
|
||||
|
|
|
@ -9,7 +9,9 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
|
|||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
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 +86,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(Theme.p(Theme.Key.PONDER_MISSING_CREATE))
|
||||
.animateColors(false);
|
||||
else
|
||||
button.customColors(0x505000FF, 0x50300077);
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_VANILLA))
|
||||
.animateColors(false);
|
||||
}
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
widgets.add(b);
|
||||
layout.next();
|
||||
}
|
||||
|
||||
|
@ -109,23 +113,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(Theme.p(Theme.Key.PONDER_MISSING_CREATE))
|
||||
.animateColors(false);
|
||||
else
|
||||
button.customColors(0x505000FF, 0x50300077);
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_VANILLA))
|
||||
.animateColors(false);
|
||||
}
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
widgets.add(b);
|
||||
}
|
||||
|
||||
// chapters
|
||||
|
@ -187,15 +194,21 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
String title = tag.getTitle();
|
||||
|
||||
int streakHeight = 35;
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, 240, 0x101010);
|
||||
PonderUI.renderBox(ms, 21, 21, 30, 30, false);
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, 240);
|
||||
//PonderUI.renderBox(ms, 21, 21, 30, 30, false);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(21, 21, 100)
|
||||
.withBounds(30, 30)
|
||||
.render(ms);
|
||||
|
||||
textRenderer.draw(ms, Lang.translate(PonderUI.PONDERING), x, y - 6, 0xffa3a3a3);
|
||||
textRenderer.draw(ms, Lang.translate(PonderUI.PONDERING), x, y - 6, Theme.i(Theme.Key.TEXT_DARKER));
|
||||
y += 8;
|
||||
x += 0;
|
||||
ms.translate(x, y, 0);
|
||||
ms.translate(0, 0, 5);
|
||||
textRenderer.draw(ms, title, 0, 0, 0xeeeeee);
|
||||
textRenderer.draw(ms, title, 0, 0, Theme.i(Theme.Key.TEXT));
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
|
@ -214,9 +227,16 @@ 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(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.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);
|
||||
FontHelper.drawSplitString(ms, textRenderer, desc, x, y, w, Theme.i(Theme.Key.TEXT));
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
|
@ -232,16 +252,23 @@ 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(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.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);
|
||||
drawCenteredString(ms, textRenderer, relatedTitle, sWidth / 2, itemArea.getY() - 20, 0xeeeeee);
|
||||
drawCenteredString(ms, textRenderer, relatedTitle, sWidth / 2, itemArea.getY() - 20, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.translate(0,0, -200);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010);
|
||||
UIRenderHelper.streak(ms, 180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75);
|
||||
UIRenderHelper.streak(ms, 180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75);
|
||||
|
||||
ms.pop();
|
||||
|
||||
|
@ -261,8 +288,8 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(chapterX, chapterY, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -291,7 +318,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 +337,7 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
if (handled.booleanValue())
|
||||
return true;
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(NavigatableSimiScreen other) {
|
||||
|
|
|
@ -136,7 +136,7 @@ public class InputWindowElement extends AnimatedOverlayElement {
|
|||
|
||||
if (hasItem) {
|
||||
GuiGameElement.of(item)
|
||||
.at(keyWidth + (hasIcon ? 24 : 0), 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(keyWidth + (hasIcon ? 24 : 0), 0)
|
||||
.scale(1.5)
|
||||
.render(ms);
|
||||
RenderSystem.disableDepthTest();
|
||||
|
|
|
@ -4,6 +4,8 @@ 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.gui.Theme;
|
||||
import com.simibubi.create.foundation.ponder.PonderLocalization;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
|
@ -110,7 +112,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(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.TEXT_WINDOW_BORDER))
|
||||
.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) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.function.BiConsumer;
|
|||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.ponder.content.PonderChapter;
|
||||
|
@ -20,17 +21,18 @@ public class ChapterLabel extends AbstractSimiWidget {
|
|||
public ChapterLabel(PonderChapter chapter, int x, int y, BiConsumer<Integer, Integer> onClick) {
|
||||
super(x, y, 175, 38);
|
||||
|
||||
this.button = new PonderButton(x + 4, y + 4, onClick, 30, 30).showing(chapter);
|
||||
this.button.fade(1);
|
||||
this.button = new PonderButton(x + 4, y + 4, 30, 30)
|
||||
.showing(chapter)
|
||||
.withCallback(onClick);
|
||||
|
||||
this.chapter = chapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 2, width, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 2, width);
|
||||
Minecraft.getInstance().fontRenderer.draw(ms, Lang.translate("ponder.chapter." + chapter.getId()), x + 50,
|
||||
y + 20, 0xffddeeff);
|
||||
y + 20, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
button.renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
super.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
|
|
@ -1,175 +1,105 @@
|
|||
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.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;
|
||||
|
||||
public class PonderButton extends AbstractSimiWidget {
|
||||
public class PonderButton extends BoxWidget {
|
||||
|
||||
private IScreenRenderable icon;
|
||||
private ItemStack item;
|
||||
protected boolean pressed;
|
||||
private BiConsumer<Integer, Integer> onClick;
|
||||
private int xFadeModifier;
|
||||
private int yFadeModifier;
|
||||
private float fade;
|
||||
private KeyBinding shortcut;
|
||||
private LerpedFloat flash;
|
||||
private Couple<Integer> customPassiveBorder;
|
||||
protected ItemStack item;
|
||||
protected KeyBinding shortcut;
|
||||
protected LerpedFloat flash = LerpedFloat.linear().startWithValue(0).chase(0, 0.1f, LerpedFloat.Chaser.EXP);
|
||||
|
||||
public static final int SIZE = 20;
|
||||
public PonderButton(int x, int y) {
|
||||
this(x, y, 20, 20);
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, BiConsumer<Integer, Integer> 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;
|
||||
paddingX = 2;
|
||||
paddingY = 2;
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, BiConsumer<Integer, Integer> onClick) {
|
||||
this(x, y, onClick, SIZE, SIZE);
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, Runnable onClick) {
|
||||
this(x, y, ($, $$) -> onClick.run());
|
||||
}
|
||||
|
||||
public PonderButton showing(IScreenRenderable icon) {
|
||||
this.icon = icon;
|
||||
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 extends PonderButton> 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 extends PonderButton> T showing(ItemStack item) {
|
||||
this.item = item;
|
||||
return super.showingElement(GuiGameElement.of(item)
|
||||
.scale(1.5f)
|
||||
.at(-4, -4));
|
||||
}
|
||||
|
||||
public void fade(float fade) {
|
||||
this.fade = fade;
|
||||
@Override
|
||||
public <T extends ElementWidget> T showingElement(RenderElement element) {
|
||||
return super.showingElement(element);
|
||||
}
|
||||
|
||||
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 renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (!visible)
|
||||
return;
|
||||
if (fade < .1f)
|
||||
return;
|
||||
public void tick() {
|
||||
super.tick();
|
||||
flash.tickChaser();
|
||||
}
|
||||
|
||||
hovered = isMouseOver(mouseX, mouseY) && fade > .75f;
|
||||
|
||||
ms.push();
|
||||
RenderSystem.disableDepthTest();
|
||||
if (fade < 1)
|
||||
ms.translate((1 - fade) * -5 * xFadeModifier, (1 - fade) * -5 * yFadeModifier, 0);
|
||||
@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)
|
||||
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, 400);
|
||||
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);
|
||||
ms.scale((width - 4) / 16f, (height - 4) / 16f, 1);
|
||||
icon.draw(ms, this, 0, 0);
|
||||
ms.pop();
|
||||
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);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
public void runCallback(double mouseX, double mouseY) {
|
||||
onClick.accept((int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double p_onClick_1_, double p_onClick_3_) {
|
||||
super.onClick(p_onClick_1_, p_onClick_3_);
|
||||
this.pressed = true;
|
||||
}
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
float fadeValue = fade.getValue();
|
||||
|
||||
@Override
|
||||
public void onRelease(double p_onRelease_1_, double p_onRelease_3_) {
|
||||
super.onRelease(p_onRelease_1_, p_onRelease_3_);
|
||||
this.pressed = false;
|
||||
}
|
||||
if (fadeValue < .1f)
|
||||
return;
|
||||
|
||||
/*public void setToolTip(String text) {
|
||||
toolTip.clear();
|
||||
toolTip.add(text);
|
||||
}*/
|
||||
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_DARKER), fadeValue));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,20 +10,28 @@ 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() {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -39,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;
|
||||
|
@ -52,6 +59,23 @@ public class ColorHelper {
|
|||
return color;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Color mixColors(@Nonnull Color c1, @Nonnull Color c2, float w) {
|
||||
float[] cmp1 = c1.getRGBComponents(null);
|
||||
float[] cmp2 = c2.getRGBComponents(null);
|
||||
return new Color(
|
||||
cmp1[0] + (cmp2[0] - cmp1[0]) * w,
|
||||
cmp1[1] + (cmp2[1] - cmp1[1]) * w,
|
||||
cmp1[2] + (cmp2[2] - cmp1[2]) * w,
|
||||
cmp1[3] + (cmp2[3] - cmp1[3]) * w
|
||||
);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Color mixColors(@Nonnull Couple<Color> colors, float w) {
|
||||
return mixColors(colors.getFirst(), colors.getSecond(), w);
|
||||
}
|
||||
|
||||
public static int mixAlphaColors(int color1, int color2, float w) {
|
||||
int a1 = (color1 >> 24);
|
||||
int r1 = (color1 >> 16) & 0xFF;
|
||||
|
|
|
@ -81,4 +81,22 @@ public interface Force {
|
|||
return timeRemaining <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Static implements Force {
|
||||
float force;
|
||||
|
||||
public Static(float force) {
|
||||
this.force = force;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float get(float mass, float value, float speed) {
|
||||
return force;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finished() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.2 KiB |
|
@ -1,23 +1,24 @@
|
|||
{
|
||||
"required": true,
|
||||
"priority": 1100,
|
||||
"package": "com.simibubi.create.foundation.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"refmap": "create.refmap.json",
|
||||
"client": [
|
||||
"TileWorldHookMixin",
|
||||
"CancelTileEntityRenderMixin",
|
||||
"FogColorTrackerMixin",
|
||||
"LightUpdateMixin",
|
||||
"NetworkLightUpdateMixin",
|
||||
"RenderHooksMixin",
|
||||
"ShaderCloseMixin",
|
||||
"TileRemoveMixin",
|
||||
"EntityContraptionInteractionMixin",
|
||||
"StoreProjectionMatrixMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"minVersion": "0.8"
|
||||
}
|
||||
"required": true,
|
||||
"priority": 1100,
|
||||
"package": "com.simibubi.create.foundation.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"refmap": "create.refmap.json",
|
||||
"client": [
|
||||
"CancelTileEntityRenderMixin",
|
||||
"EntityContraptionInteractionMixin",
|
||||
"FogColorTrackerMixin",
|
||||
"LightUpdateMixin",
|
||||
"NetworkLightUpdateMixin",
|
||||
"RenderHooksMixin",
|
||||
"ShaderCloseMixin",
|
||||
"StoreProjectionMatrixMixin",
|
||||
"TileRemoveMixin",
|
||||
"TileWorldHookMixin",
|
||||
"WindowResizeMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
},
|
||||
"minVersion": "0.8"
|
||||
}
|
Loading…
Reference in a new issue