diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 30ca80e7e25..a2e3babae24 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -1938,8 +1938,8 @@ "config.gtceu.option.treeFellingDelay": "ʎɐןǝᗡbuıןןǝℲǝǝɹʇ", "config.gtceu.option.tungstensteelBoilerHeatSpeed": "pǝǝdSʇɐǝHɹǝןıoᗺןǝǝʇsuǝʇsbunʇ", "config.gtceu.option.tungstensteelBoilerMaxTemperature": "ǝɹnʇɐɹǝdɯǝ⟘xɐWɹǝןıoᗺןǝǝʇsuǝʇsbunʇ", - "config.gtceu.option.ui": "ın", "config.gtceu.option.type": "ǝdʎʇ", + "config.gtceu.option.ui": "ın", "config.gtceu.option.universalHazards": "spɹɐzɐHןɐsɹǝʌıun", "config.gtceu.option.updateIntervals": "sןɐʌɹǝʇuIǝʇɐpdn", "config.gtceu.option.useDarkThemeByDefault": "ʇןnɐɟǝᗡʎᗺǝɯǝɥ⟘ʞɹɐᗡǝsn", @@ -3572,7 +3572,7 @@ "gtceu.packer": "ɹǝʞɔɐԀ", "gtceu.part_sharing.disabled": "pǝןqɐsıᗡㄣ§ buıɹɐɥS ʞɔoןqıʇןnW", "gtceu.part_sharing.enabled": "pǝןqɐuƎɐ§ buıɹɐɥS ʞɔoןqıʇןnW", - "gtceu.placeholder_editor.constant_value": "˙ʇuɐʇsuoɔ ɐ ɥʇıʍ ʇı buıɔɐןdǝɹ ɹǝpısuoƆ\n˙ʇןnsǝɹ ǝɯɐs ǝɥʇ oʇ sǝʇɐnןɐʌǝ sʎɐʍןɐ uoıssǝɹdxǝ sıɥ⟘", + "gtceu.placeholder_editor.constant_value": "˙ʇuɐʇsuoɔ ɐ ɥʇıʍ ʇı buıɔɐןdǝɹ ɹǝpısuoƆ\n˙,%s, oʇ sǝʇɐnןɐʌǝ sʎɐʍןɐ uoıssǝɹdxǝ sıɥ⟘", "gtceu.placeholder_editor.extra_closing_bracket": "ʇǝʞɔɐɹq buısoןɔ ɐɹʇxƎ", "gtceu.placeholder_editor.no_placeholder": "ʇsıxǝ ʇou sǝop ,%s, ǝɯɐu ɥʇıʍ ɹǝpןoɥǝɔɐןԀ", "gtceu.placeholder_editor.unclosed_bracket": ")\"}\"( ʇǝʞɔɐɹq pǝsoןɔu∩", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 7bec3eb3705..4a7daf4b876 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -1938,8 +1938,8 @@ "config.gtceu.option.treeFellingDelay": "treeFellingDelay", "config.gtceu.option.tungstensteelBoilerHeatSpeed": "tungstensteelBoilerHeatSpeed", "config.gtceu.option.tungstensteelBoilerMaxTemperature": "tungstensteelBoilerMaxTemperature", - "config.gtceu.option.ui": "ui", "config.gtceu.option.type": "type", + "config.gtceu.option.ui": "ui", "config.gtceu.option.universalHazards": "universalHazards", "config.gtceu.option.updateIntervals": "updateIntervals", "config.gtceu.option.useDarkThemeByDefault": "useDarkThemeByDefault", @@ -3572,7 +3572,7 @@ "gtceu.packer": "Packer", "gtceu.part_sharing.disabled": "Multiblock Sharing §4Disabled", "gtceu.part_sharing.enabled": "Multiblock Sharing §aEnabled", - "gtceu.placeholder_editor.constant_value": "This expression always evaluates to the same result.\nConsider replacing it with a constant.", + "gtceu.placeholder_editor.constant_value": "This expression always evaluates to '%s'.\nConsider replacing it with a constant.", "gtceu.placeholder_editor.extra_closing_bracket": "Extra closing bracket", "gtceu.placeholder_editor.no_placeholder": "Placeholder with name '%s' does not exist", "gtceu.placeholder_editor.unclosed_bracket": "Unclosed bracket (\"}\")", diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java index b02c293ac03..97277d0c7ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java @@ -6,7 +6,6 @@ import com.gregtechceu.gtceu.api.placeholder.exceptions.UnexpectedBracketException; import com.gregtechceu.gtceu.api.placeholder.exceptions.UnknownPlaceholderException; import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer; -import com.gregtechceu.gtceu.common.mui.drawable.BorderDrawable; import com.gregtechceu.gtceu.common.mui.widgets.textfield.CodeEditorWidget; import com.gregtechceu.gtceu.data.lang.LangHandler; import com.gregtechceu.gtceu.utils.GTUtil; @@ -23,18 +22,15 @@ import brachy.modularui.api.drawable.IDrawable; import brachy.modularui.api.drawable.Text; import brachy.modularui.api.value.IBoolValue; -import brachy.modularui.api.value.IIntValue; import brachy.modularui.api.value.IStringValue; +import brachy.modularui.api.widget.IWidget; import brachy.modularui.drawable.GuiTextures; import brachy.modularui.screen.ModularPanel; import brachy.modularui.screen.RichTooltip; import brachy.modularui.screen.viewport.GuiContext; import brachy.modularui.value.StringValue; import brachy.modularui.value.sync.*; -import brachy.modularui.widgets.ButtonWidget; -import brachy.modularui.widgets.SortableListWidget; -import brachy.modularui.widgets.TextWidget; -import brachy.modularui.widgets.ToggleButton; +import brachy.modularui.widgets.*; import brachy.modularui.widgets.layout.Flow; import brachy.modularui.widgets.slot.ItemSlot; import brachy.modularui.widgets.textfield.TextFieldWidget; @@ -246,18 +242,30 @@ public static IPanelHandler createPlaceholderEditor(String name, PanelSyncManage PlaceholderContext ctx, IStringValue code, @Nullable DoubleSyncValue scaleDouble, - @Nullable IIntValue updateInterval, + @Nullable IStringValue updateInterval, @Nullable IBoolValue pause, @Nullable Runnable updateText) { IPanelHandler helpPanel = syncManager.syncedPanel("placeholder_language_help", true, (syncManager1, panelHandler1) -> createHelpPanel()); - InteractionSyncHandler runCodeOnce = new InteractionSyncHandler(); - if (updateText != null) runCodeOnce.setOnMousePressed(mouseData -> updateText.run()); - syncManager.syncValue("run_code_sync_handler", runCodeOnce); - // because the args are nullable, intellij complains about everything, even though childIf is used - // noinspection DataFlowIssue - return syncManager.syncedPanel(name, true, (psm, handler) -> new ModularPanel<>(name) + InteractionSyncHandler runCodeOnce = updateText == null ? null : new InteractionSyncHandler(); + if (updateText != null) runCodeOnce.setOnMousePressed(mouseData -> { + if (!mouseData.isClient()) + updateText.run(); + }); + return syncManager.syncedPanel(name, true, (psm, handler) -> createPlaceholderEditorPanel( + name, ctx, code, scaleDouble, updateInterval, pause, helpPanel, runCodeOnce)); + } + + public static ModularPanel createPlaceholderEditorPanel(String name, + PlaceholderContext ctx, + IStringValue code, + @Nullable DoubleSyncValue scaleDouble, + @Nullable IStringValue updateInterval, + @Nullable IBoolValue pause, + IPanelHandler helpPanel, + @Nullable InteractionSyncHandler runCodeOnce) { + return new ModularPanel<>(name) .size(400, 250) .resizeableOnDrag(true) .excludeAreaInRecipeViewer() @@ -272,7 +280,7 @@ public static IPanelHandler createPlaceholderEditor(String name, PanelSyncManage .addTooltipLine( Text.lang("gtceu.gui.computer_monitor_cover.slot_tooltip", i)))) .child(Flow.column() - .widthRel(.8f) + .widthRel(.7f) .padding(5) .child(Flow.row() .height(20) @@ -290,56 +298,57 @@ public static IPanelHandler createPlaceholderEditor(String name, PanelSyncManage .childIf(updateInterval != null, () -> new TextFieldWidget() .setNumbers(1, 1000) .setDefaultNumber(1) - .value(SyncHandlers.string( - () -> String.valueOf(updateInterval.getIntValue()), - s -> updateInterval.setIntValue(Integer.parseInt(s)))) + .value(updateInterval) .marginLeft(4)) .childIf(pause != null, () -> new ToggleButton() .value(pause) - .background(false, GuiTextures.PAUSE) - .background(true, GuiTextures.PLAY) + .marginLeft(10) + .marginRight(10) + .background(true, GuiTextures.MC_BUTTON) + .hoverBackground(true, GuiTextures.MC_BUTTON_HOVERED) + .background(false, GuiTextures.MC_BUTTON) + .hoverBackground(false, GuiTextures.MC_BUTTON_HOVERED) + .overlay(false, GuiTextures.PAUSE) + .overlay(true, GuiTextures.PLAY) .addTooltip(false, Text.lang("gtceu.gui.central_monitor.pause")) - .addTooltip(true, Text.lang("gtceu.gui.central_monitor.resume")) - .margin(4)) - .childIf(updateText != null, () -> new ButtonWidget<>() - .background(GuiTextures.RIGHTLOAD) - .hoverBackground(GuiTextures.RIGHTLOAD, new BorderDrawable()) + .addTooltip(true, Text.lang("gtceu.gui.central_monitor.resume"))) + .childIf(runCodeOnce != null, () -> new ButtonWidget<>() + .overlay(GuiTextures.RIGHTLOAD) .addTooltipLine(Text.lang("gtceu.gui.central_monitor.update_once")) - .syncHandler("run_code_sync_handler")) + .syncHandler(runCodeOnce)) .child(new ButtonWidget<>() - .background(GuiTextures.HELP) - .hoverBackground(GuiTextures.HELP, new BorderDrawable()) - .margin(4) + .right(0) + .overlay(GuiTextures.HELP) .onMousePressed((GuiContext context, int button) -> { helpPanel.openPanel(); return true; }))) - .child(new CodeEditorWidget<>(PlaceholderHandler.LANG_DEFINITION) + .child(new CodeEditorWidget<>(LANG_DEFINITION) .value(code) .langContext(ctx) - .widthRel(.95f) + .fullWidth() .heightRelOffset(1, -25))) - .child(new SortableListWidget() - .widthRel(.2f) + .child(new ListWidget<>() + .widthRel(.25f) + .right(0) .paddingBottom(5) - .excludeAreaInRecipeViewer() + .fullHeight() .children(PlaceholderHandler.getAllPlaceholderNames() .stream() .sorted() - .map(SortableListWidget.Item::new) - .map(w -> w - .child(new TextWidget<>(w.getWidgetValue()) - .sizeRel(1) + .map(s -> (IWidget) Flow.row() + .coverChildren() + .child(new TextWidget<>(s) .center()) .tooltip(new RichTooltip() .addDrawableLines(LangHandler .getSingleOrMultiLang( - "gtceu.placeholder_info." + w.getWidgetValue()) + "gtceu.placeholder_info." + s) .stream() .map(Text::of) .map(key -> (IDrawable) key) .toList()))) - .toList())))); + .toList()))); } public static ModularPanel createHelpPanel() { @@ -377,7 +386,6 @@ public static class TokenFormatter implements CodeEditorWidget.ITokenFormatter

viewStarts = new Stack<>(); private final Stack openPlaceholders = new Stack<>(); private int ifDepth = 0; - private Component endOfLineValue = null; @Override public Component apply(String s, @Nullable PlaceholderContext ctx) { @@ -469,36 +477,20 @@ public Component apply(String s, @Nullable PlaceholderContext ctx) { openPlaceholders.pop(); } if (!pureStarts.empty()) { - String result = processPlaceholders(everything.substring(pureStarts.peek()), ctx).toString(); - result = result.replaceAll("\\n", "\\\\n"); + String result = processPlaceholders(everything.substring(pureStarts.peek()), ctx) + .toString() + .replaceAll("\\n", "\\\\n"); int popped = pureStarts.peek(); pureStarts.pop(); viewStarts.pop(); if (!everything.substring(popped).contains(" ")) return Component.literal(s); - if (result.length() > 10) { - result = result.substring(0, 10) + "…"; - } - endOfLineValue = null; return Component.literal(s) - .append(Component.literal("='%s'".formatted(result)) - .withStyle(ChatFormatting.GRAY, ChatFormatting.UNDERLINE) - .withStyle(style -> style.withHoverEvent(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, - Component.translatable("gtceu.placeholder_editor.constant_value"))) - .withInsertion(""))); + .withStyle(style -> style.withHoverEvent(new HoverEvent( + HoverEvent.Action.SHOW_TEXT, + Component.translatable("gtceu.placeholder_editor.constant_value", result))) + .withInsertion("")); } - if (!viewStarts.empty() && ctx != null && !ctx.level().isClientSide()) { - String result = processPlaceholders(everything.substring(viewStarts.peek()), ctx).toString(); - result = result.replaceAll("\\n", "\\\\n"); - if (result.length() > 10) { - result = result.substring(0, 10) + "…"; - } - viewStarts.pop(); - endOfLineValue = Component.literal("='%s'".formatted(result)) - .withStyle(ChatFormatting.DARK_GRAY) - .withStyle(style -> style.withInsertion("")); - return Component.literal(s); - } else if (!viewStarts.empty()) viewStarts.pop(); + if (!viewStarts.empty()) viewStarts.pop(); return Component.literal(s); } } @@ -533,13 +525,6 @@ else if (ifDepth > 0 && !placeholders.get(s).isView()) { } } everything.append(s); - if (s.contains("\n") && endOfLineValue != null) { - String start = s.substring(0, s.indexOf('\n')); - String end = s.substring(s.indexOf('\n')); - Component ret = Component.literal(start).append(endOfLineValue).append(end); - endOfLineValue = null; - return ret; - } return Component.literal(s); } @@ -547,7 +532,6 @@ private void onEncounteredError() { viewStarts.clear(); pureStarts.clear(); openPlaceholders.clear(); - endOfLineValue = null; ifDepth = 0; unclosedSingleEscapes = 0; } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java index a76b37ccf7d..dd33caeedd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java @@ -26,6 +26,7 @@ public MonitorImageRenderer(String url) { @Override public void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) { + if (group.isEmpty()) return; BlockPos rel = group.getRow(0, machine::toRelative).get(0); BlockPos size = GTUtil.getLast(group.getRow(-1, machine::toRelative)) .offset(-rel.getX() + 1, -rel.getY() + 1, -rel.getZ() + 1); diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java index 103a8109c59..e6aeae07d9f 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java @@ -30,65 +30,64 @@ public MonitorTextRenderer(MultiLineComponent text, double scale) { @Override public void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack, MultiBufferSource buffer, int packedLight, int packedOverlay) { - try { - BlockPos rel = group.getRow(0, machine::toRelative).get(0); - int row = 0; - int columns = group.getRow(0, machine::toRelative).size(); - poseStack.translate(rel.getX(), rel.getY(), rel.getZ()); - int layer = 0; - for (GraphicsComponent graphics : text.getGraphics()) { - if (graphics.x() < 0 || graphics.y() < 0) continue; - float maxX = graphics.x2(); - float maxY = graphics.y2(); - if (maxX == Math.floor(maxX)) maxX--; - if (maxY == Math.floor(maxY)) maxY--; - BlockPos relativePos = rel.offset(Mth.floor(maxX), Mth.floor(maxY), 0); - if (!group.getMonitorPositions().stream().map(machine::toRelative).toList().contains(relativePos)) - continue; - poseStack.pushPose(); - poseStack.translate(graphics.x(), graphics.y(), layer * .001f); - graphics.get().render(machine, group, partialTick, poseStack, buffer, packedLight, packedOverlay); - poseStack.popPose(); - layer++; - } - poseStack.translate(0, 0, layer * .001f); - poseStack.scale(TEXT_SCALE * scale, TEXT_SCALE * scale, TEXT_SCALE * scale); - float y = 9; - for (Component s : text) { - boolean didAnything = false; - for (FormattedCharSequence line : Minecraft.getInstance().font.split(s, - Math.round(columns * 135 / scale))) { - if (y >= 144) { - try { - row++; - columns = group.getRow(row, machine::toRelative).size(); - y -= 144; - poseStack.translate(-rel.getX() / (TEXT_SCALE * scale), -rel.getY() / (TEXT_SCALE * scale), - -rel.getZ() / (TEXT_SCALE * scale)); - rel = group.getRow(row, machine::toRelative).get(0); - poseStack.translate(rel.getX() / (TEXT_SCALE * scale), rel.getY() / (TEXT_SCALE * scale), - rel.getZ() / (TEXT_SCALE * scale)); - } catch (IndexOutOfBoundsException e) { - return; - } + if (group.isEmpty()) return; + BlockPos rel = group.getRow(0, machine::toRelative).get(0); + int row = 0; + int columns = group.getRow(0, machine::toRelative).size(); + poseStack.translate(rel.getX(), rel.getY(), rel.getZ()); + int layer = 0; + for (GraphicsComponent graphics : text.getGraphics()) { + if (graphics.x() < 0 || graphics.y() < 0) continue; + float maxX = graphics.x2(); + float maxY = graphics.y2(); + if (maxX == Math.floor(maxX)) maxX--; + if (maxY == Math.floor(maxY)) maxY--; + BlockPos relativePos = rel.offset(Mth.floor(maxX), Mth.floor(maxY), 0); + if (!group.getMonitorPositions().stream().map(machine::toRelative).toList().contains(relativePos)) + continue; + poseStack.pushPose(); + poseStack.translate(graphics.x(), graphics.y(), layer * .001f); + graphics.get().render(machine, group, partialTick, poseStack, buffer, packedLight, packedOverlay); + poseStack.popPose(); + layer++; + } + poseStack.translate(0, 0, layer * .001f); + poseStack.scale(TEXT_SCALE * scale, TEXT_SCALE * scale, TEXT_SCALE * scale); + float y = 9; + for (Component s : text) { + boolean didAnything = false; + for (FormattedCharSequence line : Minecraft.getInstance().font.split(s, + Math.round(columns * 135 / scale))) { + if (y >= 144) { + try { + row++; + columns = group.getRow(row, machine::toRelative).size(); + y -= 144; + poseStack.translate(-rel.getX() / (TEXT_SCALE * scale), -rel.getY() / (TEXT_SCALE * scale), + -rel.getZ() / (TEXT_SCALE * scale)); + rel = group.getRow(row, machine::toRelative).get(0); + poseStack.translate(rel.getX() / (TEXT_SCALE * scale), rel.getY() / (TEXT_SCALE * scale), + rel.getZ() / (TEXT_SCALE * scale)); + } catch (IndexOutOfBoundsException e) { + return; } - Minecraft.getInstance().font.drawInBatch( - line, - 9, y, - 0xFFFFFF, - false, - poseStack.last().pose(), - buffer, - Font.DisplayMode.NORMAL, - 0, - LightTexture.FULL_BRIGHT); - y += Minecraft.getInstance().font.lineHeight * scale; - didAnything = true; - } - if (!didAnything) { - y += Minecraft.getInstance().font.lineHeight * scale; } + Minecraft.getInstance().font.drawInBatch( + line, + 9, y, + 0xFFFFFF, + false, + poseStack.last().pose(), + buffer, + Font.DisplayMode.NORMAL, + 0, + LightTexture.FULL_BRIGHT); + y += Minecraft.getInstance().font.lineHeight * scale; + didAnything = true; + } + if (!didAnything) { + y += Minecraft.getInstance().font.lineHeight * scale; } - } catch (IndexOutOfBoundsException ignored) {} + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java index 874ca702c72..362ffe35d0b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.cover.IMuiCover; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; import com.gregtechceu.gtceu.api.placeholder.IPlaceholderInfoProviderCover; @@ -15,6 +16,7 @@ import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.client.renderer.cover.CoverTextRenderer; import com.gregtechceu.gtceu.client.renderer.cover.IDynamicCoverRenderer; +import com.gregtechceu.gtceu.common.mui.GTMuiWidgets; import com.gregtechceu.gtceu.integration.create.GTCreateIntegration; import com.gregtechceu.gtceu.utils.GTStringUtils; import com.gregtechceu.gtceu.utils.GTUtil; @@ -32,8 +34,15 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import brachy.modularui.api.IPanelHandler; +import brachy.modularui.factory.SidedPosGuiData; +import brachy.modularui.screen.ModularPanel; +import brachy.modularui.screen.UISettings; +import brachy.modularui.value.sync.PanelSyncManager; +import brachy.modularui.value.sync.SyncHandlers; import lombok.Getter; import lombok.Setter; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Supplier; @@ -43,9 +52,9 @@ @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class ComputerMonitorCover extends CoverBehavior - implements IDataStickInteractable, IPlaceholderInfoProviderCover { + implements IDataStickInteractable, IPlaceholderInfoProviderCover, IMuiCover { - private TickableSubscription subscription; + private @Nullable TickableSubscription subscription; private final CoverTextRenderer renderer; @SaveField @Getter @@ -60,8 +69,6 @@ public class ComputerMonitorCover extends CoverBehavior @SaveField public CustomItemStackHandler itemStackHandler = new CustomItemStackHandler(8); @Setter - private String placeholderSearch = ""; - @Setter @Getter @SaveField private int updateInterval = 100; @@ -88,15 +95,26 @@ public ComputerMonitorCover(CoverDefinition definition, ICoverable coverHolder, } } + public PlaceholderContext createPlaceholderContext() { + return new PlaceholderContext(coverHolder.getLevel(), coverHolder.getBlockPos(), attachedSide, + itemStackHandler, + this, null, new MultiLineComponent(text), placeholderUUID); + } + + public String getCode() { + return formatStringLines.stream().reduce((a, b) -> a + "\n" + b).orElse(""); + } + + public void setCode(String code) { + formatStringLines.clear(); + formatStringLines.addAll(List.of(code.split("\n"))); + } + public List getRenderedText() { - String s = formatStringLines.stream().reduce((a, b) -> a + "\n" + b).orElse(""); List tmp = new ArrayList<>(formatStringArgs); tmp = tmp.stream().map(str -> '{' + str + '}').toList(); return PlaceholderHandler.processPlaceholders( - GTStringUtils.replace(s, "\\{}", tmp), - new PlaceholderContext(coverHolder.getLevel(), coverHolder.getBlockPos(), attachedSide, - itemStackHandler, - this, null, new MultiLineComponent(text), placeholderUUID)); + GTStringUtils.replace(getCode(), "\\{}", tmp), createPlaceholderContext()); } public void setDisplayTargetBufferLine(int line, MutableComponent component) { @@ -136,6 +154,7 @@ private void update() { text = GTUtil .list(Component.translatable("gtceu.computer_monitor_cover.error.exception", e.getMessage())); } + syncDataHolder.markClientSyncFieldDirty("text"); } } @@ -192,4 +211,19 @@ public InteractionResult onDataStickShiftUse(Player player, ItemStack dataStick) tag.putInt("updateInterval", updateInterval); return InteractionResult.SUCCESS; } + + @Override + public ModularPanel buildUI(SidedPosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var codeSync = SyncHandlers.string(this::getCode, this::setCode).allowC2S(); + var intervalSync = SyncHandlers.intNumber(this::getUpdateInterval, this::setUpdateInterval).allowC2S(); + IPanelHandler helpPanel = syncManager.syncedPanel("placeholder_language_help", + true, + (syncManager1, panelHandler1) -> PlaceholderHandler.createHelpPanel()); + return PlaceholderHandler.createPlaceholderEditorPanel( + "main", createPlaceholderContext(), + codeSync, null, intervalSync, null, helpPanel, null) + .child(GTMuiWidgets.verticalPlayerInventory((index, slot) -> slot) + .verticalCenter() + .left(-80)); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java index b864374217f..c344c67f84d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java @@ -44,7 +44,8 @@ public IPanelHandler createModularPanel(ItemStack stack, CentralMonitorMachine m .widthRel(1) .child(new TextWidget<>(Text.lang("gtceu.gui.central_monitor.url"))) .child(new TextFieldWidget() - .value(SyncHandlers.string(() -> getUrl(stack), s -> setUrl(stack, s))) + .value(SyncHandlers.string(() -> getUrl(stack), s -> setUrl(stack, s)) + .allowC2S()) .center() .widthRel(.8f)))); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java index c9e35799317..9e3640afcd3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java @@ -30,6 +30,9 @@ public class TextModuleBehaviour implements IMonitorModuleItem, IAddInformation { private PlaceholderContext getContext(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + if (!stack.getOrCreateTag().contains("placeholderUUID")) { + stack.getOrCreateTag().putUUID("placeholderUUID", UUID.randomUUID()); + } return new PlaceholderContext( group.getTargetLevel(machine.getLevel()), group.getTarget(machine.getLevel()), @@ -42,9 +45,6 @@ private PlaceholderContext getContext(ItemStack stack, CentralMonitorMachine mac } private void updateText(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { - if (!stack.getOrCreateTag().contains("placeholderUUID")) { - stack.getOrCreateTag().putUUID("placeholderUUID", UUID.randomUUID()); - } MultiLineComponent text = PlaceholderHandler.processPlaceholders( getPlaceholderText(stack), getContext(stack, machine, group)); stack.getOrCreateTag().put("text", @@ -70,11 +70,14 @@ public IPanelHandler createModularPanel(ItemStack stack, CentralMonitorMachine m PlaceholderContext ctx = getContext(stack, machine, group); StringSyncValue code = SyncHandlers.string( () -> getPlaceholderText(stack), - s -> setPlaceholderText(stack, s)); + s -> setPlaceholderText(stack, s)) + .allowC2S(); DoubleSyncValue scale = SyncHandlers.doubleNumber( () -> getScale(stack), - s -> setScale(stack, s)); - BooleanSyncValue pause = SyncHandlers.bool(() -> isPaused(stack), p -> setPaused(stack, p)); + s -> setScale(stack, s)) + .allowC2S(); + BooleanSyncValue pause = SyncHandlers.bool(() -> isPaused(stack), p -> setPaused(stack, p)) + .allowC2S(); Runnable updateText = () -> updateText(stack, machine, group); assert ctx.itemStackHandler() != null; return PlaceholderHandler.createPlaceholderEditor("text_module_" + group.getName(), syncManager, ctx, code, diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/GTMuiWidgets.java b/src/main/java/com/gregtechceu/gtceu/common/mui/GTMuiWidgets.java index b4e93736ffe..b14f1cca833 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/mui/GTMuiWidgets.java +++ b/src/main/java/com/gregtechceu/gtceu/common/mui/GTMuiWidgets.java @@ -601,6 +601,25 @@ public boolean onMouseScrolled(double delta) { .stateOverlay(1, BucketMode.MILLI_BUCKET.icon.asIcon().size(16))); } + public static SlotGroupWidget verticalPlayerInventory(SlotGroupWidget.SlotConsumer slotConsumer) { + SlotGroupWidget slotGroupWidget = new SlotGroupWidget(); + slotGroupWidget.coverChildren(); + slotGroupWidget.name("player_inventory"); + String key = "player"; + + for (int i = 0; i < 9; ++i) { + slotGroupWidget + .child(slotConsumer.apply(i, new ItemSlot()).syncHandler(key, i).pos(0, i * 18).name("slot_" + i)); + } + + for (int i = 0; i < 27; ++i) { + slotGroupWidget.child(slotConsumer.apply(i + 9, new ItemSlot()).syncHandler(key, i + 9) + .pos(22 + i / 9 * 18, i % 9 * 18).name("slot_" + (i + 9))); + } + + return slotGroupWidget; + } + public static class EnumRowBuilder> { private @Nullable EnumSyncValue syncValue; diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/factory/CentralMonitorUIFactory.java b/src/main/java/com/gregtechceu/gtceu/common/mui/factory/CentralMonitorUIFactory.java index ee04d09eccf..aa988be61b0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/mui/factory/CentralMonitorUIFactory.java +++ b/src/main/java/com/gregtechceu/gtceu/common/mui/factory/CentralMonitorUIFactory.java @@ -1,6 +1,5 @@ package com.gregtechceu.gtceu.common.mui.factory; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.IMonitorComponent; import com.gregtechceu.gtceu.api.item.IComponentItem; import com.gregtechceu.gtceu.api.item.component.IItemComponent; @@ -25,12 +24,10 @@ import brachy.modularui.api.drawable.Text; import brachy.modularui.api.value.IValue; import brachy.modularui.api.widget.IWidget; -import brachy.modularui.drawable.DynamicDrawable; import brachy.modularui.drawable.GuiTextures; import brachy.modularui.factory.PosGuiData; import brachy.modularui.screen.ModularPanel; import brachy.modularui.screen.UISettings; -import brachy.modularui.utils.Alignment; import brachy.modularui.value.BoolValue; import brachy.modularui.value.sync.*; import brachy.modularui.widgets.*; @@ -56,6 +53,7 @@ public class CentralMonitorUIFactory implements PanelFactory { public ModularPanel buildUIFunction(PosGuiData data, PanelSyncManager syncManager, UISettings settings, MetaMachine metaMachine) { if (!(metaMachine instanceof CentralMonitorMachine machine)) return new ModularPanel<>("main"); + // avoid .allowC2S() here since that will allow unchecked item stack modifying from client-side GenericListSyncHandler groupSync = new GenericListSyncHandler<>(machine::getMonitorGroups, machine::setMonitorGroups, MONITOR_GROUPS, MONITOR_GROUPS, MONITOR_GROUPS, null); @@ -64,44 +62,73 @@ public ModularPanel buildUIFunction(PosGuiData data, PanelSyncManager syncMan IPanelHandler helpPanel = syncManager.syncedPanel( "help_panel", true, (syncManager1, panelHandler1) -> createHelpPanel()); - Function, SortableListWidget.Item> processGroupItem = item -> { + IPanelHandler inventoryPanel = syncManager.syncedPanel( + "inventory", true, + this::createInventoryPanel); + Function processGroupItem = group -> { + int index = groupSync.getValue().indexOf(group); + IPanelHandler moduleEditor = createModulePanelHandler( + syncManager, + group.getItemStackHandler().getStackInSlot(0), + group, machine); IPanelHandler panelHandler = syncManager.syncedPanel( - "editor_" + groups.indexOf(item.getWidgetValue()), true, + "editor_%d".formatted(index), true, (syncManager1, panelHandler1) -> this.createGroupEditorPanel( - syncManager1, groupSync, - machine, item.getWidgetValue(), - groups, helpPanel)); - return item.child(Flow.row() + syncManager1, groupSync, index, machine, moduleEditor)); + return Flow.row() + .background(new BorderDrawable(0xFF888888, 1)) .height(20) - .child(new TextWidget<>(Text.dynamic(() -> Component.literal(item.getWidgetValue().getName()))) + .child(new TextWidget<>(Text.dynamic(() -> Component.literal(group.getName()))) .paddingLeft(5) - .widthRelOffset(1, -38)) + .widthRelOffset(1, -18 * 3)) + .child(new ItemSlot() + .syncHandler(syncManager.getOrCreateSyncHandler( + "module_slot", index, + ItemSlotSyncHandler.class, + () -> new ItemSlotSyncHandler(new ModularSlot(group.getItemStackHandler(), 0) + .changeListener((newItem, onlyAmountChanged, client, init) -> { + if (!init) { + groups.set(index, group); + groupSync.setValue(groups, true, false); + } + }))))) .child(new ButtonWidget<>() - .background(GuiTextures.EDIT) - .hoverBackground(GuiTextures.EDIT, new BorderDrawable()) + .overlay(GuiTextures.EDIT) .onMousePressed((context, button) -> { panelHandler.openPanel(); return true; })) .child(new ButtonWidget<>() - .background(GuiTextures.CLOSE) - .hoverBackground(GuiTextures.CLOSE, new BorderDrawable()) - .onMousePressed((context, button) -> { - groups.remove(item.getWidgetValue()); - groupSync.setValue(groups); - item.removeSelfFromList(); + .overlay(GuiTextures.REMOVE) + .syncHandler(syncManager.getOrCreateSyncHandler("delete_group", index, + InteractionSyncHandler.class, () -> new InteractionSyncHandler() + .setOnMousePressed(mouseData -> { + groups.remove(index); + groupSync.setValue(groups, true, false); + })))) + .childIf(moduleEditor != null, () -> new ButtonWidget<>() + .right(36) + .bottom(1) + .background() + .hoverBackground() + .overlay(GuiTextures.MC_BUTTON, GuiTextures.EDIT) + .hoverOverlay(GuiTextures.MC_BUTTON_HOVERED, GuiTextures.EDIT) + .size(8) + .onMousePressed((ctx, button) -> { + assert moduleEditor != null; + moduleEditor.openPanel(); return true; - }))); + })); }; - DynamicSyncHandler listHandler = new DynamicSyncHandler() - .widgetProvider((psm, buf) -> new SortableListWidget() - .children(groups.stream() - .map(SortableListWidget.Item::new) + DynamicLinkedSyncHandler> listHandler = new DynamicLinkedSyncHandler<>( + groupSync) + .widgetProvider((psm, list) -> new ListWidget<>() + .children(list.getValue().stream() .map(processGroupItem) .toList()) - .onChange(groupSync::setValue) - .widthRel(1)); - listHandler.notifyUpdate(buf -> {}); + .widthRel(1) + .fullHeight() + .horizontalCenter()); return new Dialog<>("main") .draggable(true) .padding(5) @@ -111,61 +138,78 @@ public ModularPanel buildUIFunction(PosGuiData data, PanelSyncManager syncMan .heightRel(1) .widthRel(1) .padding(2) - .child(new Flow(GuiAxis.X) + .child(Flow.row() .child(new TextWidget<>(Text.lang("gtceu.central_monitor.gui.monitor_groups")) - .leftRel(0)) + .verticalCenter()) .child(new ButtonWidget<>() - .leftRel(1) - .background(GuiTextures.MC_BUTTON, GuiTextures.ADD) - .hoverBackground(GuiTextures.MC_BUTTON_HOVERED, GuiTextures.ADD) + .overlay(GuiTextures.HELP) + .right(0) + .onMousePressed((ctx, button) -> { + helpPanel.openPanel(); + return true; + })) + .child(new ButtonWidget<>() + .overlay(GuiTextures.SERVER) + .right(18) + .onMousePressed((ctx, button) -> { + inventoryPanel.openPanel(); + return true; + })) + .child(new ButtonWidget<>() + .overlay(GuiTextures.ADD) + .right(36) .syncHandler(new InteractionSyncHandler() .setOnMousePressed(mouseData -> { MonitorGroup group = new MonitorGroup(getNewGroupName(groupSync)); groups.add(group); - GTCEu.LOGGER.info("adding group: {} isClient = {}", groups, - syncManager.isClient()); groupSync.setValue(groups, true, false); - listHandler.notifyUpdate(buf -> {}); }))) .widthRel(1).height(20)) .child(new DynamicSyncedWidget<>() + .overlay(new BorderDrawable(0xFF555555, 4)) .syncHandler(listHandler) + .padding(4) .widthRel(1) - .heightRelOffset(() -> 1, -96)) - .child(SlotGroupWidget.playerInventory(false))); + .horizontalCenter() + .heightRelOffset(1, -24))); + } + + private ModularPanel createInventoryPanel(PanelSyncManager psm, IPanelHandler panelHandler) { + return new ModularPanel<>("inventory") + .bindPlayerInventory() + .left(30) + .height(88); } private ModularPanel createGroupEditorPanel(PanelSyncManager syncManager, GenericListSyncHandler groupSync, - CentralMonitorMachine machine, MonitorGroup group, - List groups, - IPanelHandler helpPanel) { + int groupIndex, + CentralMonitorMachine machine, + IPanelHandler moduleEditor) { List> matrix = new ArrayList<>(); int matrixWidth = 0; + List groups = List.copyOf(groupSync.getValue()); + MonitorGroup group = groups.get(groupIndex); for (int row = 0; row <= machine.getDownDist() + machine.getUpDist(); row++) { List curRow = new ArrayList<>(); matrix.add(curRow); for (int col = 0; col <= machine.getLeftDist() + machine.getRightDist(); col++) { IMonitorComponent component = machine.getComponent(row, col); IDrawable texture = component == null ? GuiTextures.CROSS : component.getIcon(); - int finalCol = col; - int finalRow = row; + String id = "%d_%d_%d".formatted(col, row, groupIndex); IPanelHandler slotDialogHandler = component == null || component.getDataItems() == null ? null : syncManager.syncedPanel( - "slot_dialog_" + finalCol + "_" + finalRow + "_" + groups.indexOf(group), + "slot_dialog_" + id, true, (syncManager1, panelHandler1) -> new SimpleDialog<>( - "slot_number_dialog_" + finalCol + "_" + finalRow + "_" + groups.indexOf(group), - slot -> { - group.setTarget(component.getBlockPos()); - group.setDataSlot(slot - 1); - groupSync.setValue(groups); - }, + "slot_number_dialog_" + id, new TextFieldWidget().setNumbers(1, component.getDataItems().getSlots()), w -> Integer.parseInt(w.getText()), - Text.lang("gtceu.central_monitor.gui.data_slot")).draggable(true) - .size(160, 80)); + Text.lang("gtceu.central_monitor.gui.data_slot")).resultConsumer(slot -> { + group.setDataSlot(slot - 1); + groupSync.setValue(groups, true, false); + }).draggable(true).size(160, 80)); IntSupplier colorSupplier = () -> { if (component == null) return 0; boolean inGroup = group.contains(component.getBlockPos()); @@ -186,33 +230,32 @@ private ModularPanel createGroupEditorPanel(PanelSyncManager syncManager, else return Component.empty(); })) .hoverBackground(texture, new BorderDrawable(() -> colorSupplier.getAsInt() | 0x222222, 1)) - .onMousePressed((context, button) -> { - if (component == null) return true; - if (button == InputConstants.MOUSE_BUTTON_LEFT) { - if (!component.isMonitor()) return true; - if (group.contains(component.getBlockPos())) { - group.remove(component.getBlockPos()); - } else { - group.add(component.getBlockPos()); - } - } else if (button == InputConstants.MOUSE_BUTTON_RIGHT) { - if (slotDialogHandler != null) { - slotDialogHandler.openPanel(); - } else group.setTarget(component.getBlockPos()); - } - groupSync.setValue(groups); - return true; - })); + .syncHandler(new InteractionSyncHandler() + .setOnMousePressed(mouseData -> { + if (component == null) return; + int button = mouseData.mouseButton(); + if (button == InputConstants.MOUSE_BUTTON_LEFT) { + if (!component.isMonitor()) return; + if (group.contains(component.getBlockPos())) { + group.remove(component.getBlockPos()); + } else { + group.add(component.getBlockPos()); + } + } else if (button == InputConstants.MOUSE_BUTTON_RIGHT) { + group.setTarget(component.getBlockPos()); + groupSync.setValue(groups, true, false); + if (slotDialogHandler != null) { + slotDialogHandler.openPanel(); + } + } + groupSync.setValue(groups, true, false); + }))); } matrixWidth = Math.max(matrixWidth, curRow.size() * 20); } int matrixHeight = matrix.size() * 20; - IPanelHandler moduleEditor = createModulePanelHandler( - syncManager, - group.getItemStackHandler().getStackInSlot(0), - group, machine); BoolValue moduleChanged = new BoolValue(false); - return new ModularPanel<>("editor_" + groups.indexOf(group) + "_panel") + return new ModularPanel<>("editor_%d_panel".formatted(groupIndex)) .width(Math.max(matrixWidth, 150)) .height(matrixHeight + 60) .excludeAreaInRecipeViewer() @@ -224,46 +267,27 @@ private ModularPanel createGroupEditorPanel(PanelSyncManager syncManager, .child(new TextWidget<>(Text.lang("gtceu.central_monitor.gui.group_name")) .paddingRight(4)) .child(new TextFieldWidget() - .value(SyncHandlers.string(group::getName, group::setName))) + .value(SyncHandlers.string(group::getName, s -> { + group.setName(s); + groupSync.setValue(groups, true, false); + }).allowC2S())) .child(new ItemSlot() .slot(group.getItemStackHandler(), 0) .name("module_slot") .slot(new ModularSlot(group.getItemStackHandler(), 0) .changeListener((item, amount, client, init) -> { - if (!amount && !init) - moduleChanged.setValue(true); + groupSync.setValue(groups, true, false); }))) .child(new ButtonWidget<>() - .background( - new DynamicDrawable(() -> moduleChanged.getValue() ? - GuiTextures.MC_BUTTON_DISABLED : - GuiTextures.MC_BUTTON), - GuiTextures.EDIT) - .hoverBackground( - new DynamicDrawable(() -> moduleChanged.getValue() ? - GuiTextures.MC_BUTTON_DISABLED : - GuiTextures.MC_BUTTON_HOVERED), - GuiTextures.EDIT) + .overlay(GuiTextures.EDIT) .setEnabledIf(w -> !group.getItemStackHandler().getStackInSlot(0).isEmpty()) - .addTooltipLine(Text.dynamic(() -> moduleChanged.getValue() ? - Component.translatable( - "gtceu.gui.central_monitor.module_editor_disabled") : - Component.translatable( - "gtceu.gui.central_monitor.module_editor_button"))) + .addTooltipLine(Text.lang("gtceu.gui.central_monitor.module_editor_button")) .onMousePressed((context, button) -> { if (moduleEditor != null && !moduleChanged.getValue()) moduleEditor.openPanel(); return true; }))) - .child(new Grid().grid(matrix).leftRel(0.5f).size(matrixWidth, matrixHeight))) - .child(new ButtonWidget<>() - .posRel(Alignment.TopRight) - .background(GuiTextures.HELP) - .hoverBackground(GuiTextures.HELP, new BorderDrawable()) - .onMousePressed((context, button) -> { - helpPanel.openPanel(); - return true; - })); + .child(new Grid().grid(matrix).leftRel(0.5f).size(matrixWidth, matrixHeight))); } private ModularPanel createHelpPanel() { diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/SimpleDialog.java b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/SimpleDialog.java index 23ee98be8df..22ab437ad2e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/SimpleDialog.java +++ b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/SimpleDialog.java @@ -3,17 +3,17 @@ import brachy.modularui.api.drawable.Text; import brachy.modularui.drawable.GuiTextures; import brachy.modularui.utils.Alignment; +import brachy.modularui.value.sync.InteractionSyncHandler; import brachy.modularui.widget.Widget; import brachy.modularui.widgets.ButtonWidget; import brachy.modularui.widgets.Dialog; import brachy.modularui.widgets.TextWidget; -import java.util.function.Consumer; import java.util.function.Function; public class SimpleDialog> extends Dialog> { - public SimpleDialog(String name, Consumer valueConsumer, W widget, Function valueGetter, Text title) { + public SimpleDialog(String name, W widget, Function valueGetter, Text title) { super(name); child(new TextWidget<>(title.get()).leftRel(0.5f).marginTop(4)); child(widget.center()); @@ -29,9 +29,15 @@ public SimpleDialog(String name, Consumer valueConsumer, W widget, Function { - closeWith(valueGetter.apply(widget)); - return true; - })); + .syncHandler(new InteractionSyncHandler() + .setOnMousePressed(mouseData -> { + try { + T value = valueGetter.apply(widget); + closeWith(value); + // since valueGetter is most likely a parser, and those + // throw a subclass of IllegalArgumentException if the input is invalid + // we can just catch it here + } catch (IllegalArgumentException ignored) {} + }))); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/textfield/CodeEditorWidget.java b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/textfield/CodeEditorWidget.java index 614807f3847..7cfb8a2e9ac 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/textfield/CodeEditorWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/common/mui/widgets/textfield/CodeEditorWidget.java @@ -9,10 +9,11 @@ import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; +import brachy.modularui.api.value.IStringValue; import brachy.modularui.api.value.ISyncOrValue; import brachy.modularui.screen.viewport.ModularGuiContext; +import brachy.modularui.theme.TextFieldTheme; import brachy.modularui.value.sync.GenericListSyncHandler; -import brachy.modularui.value.sync.StringSyncValue; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; @@ -51,15 +52,15 @@ public CodeEditorWidget() {} public CodeEditorWidget(@Nullable LanguageDefinition language) { this.language = language; GenericListSyncHandler formattedTextSync = new GenericListSyncHandler<>( - this::getTextAsComponents, this::formattedText, GTByteBufAdapters.COMPONENT::deserialize, - GTByteBufAdapters.COMPONENT::serialize, GTByteBufAdapters.COMPONENT::areEqual, Component::copy); + this::getTextAsComponents, this::formattedText, GTByteBufAdapters.COMPONENT, + GTByteBufAdapters.COMPONENT, GTByteBufAdapters.COMPONENT, Component::copy); setSyncOrValue(formattedTextSync); } @Override public boolean isValidSyncOrValue(@NotNull ISyncOrValue syncOrValue) { return syncOrValue.isTypeOrEmpty(GenericListSyncHandler.class) || - syncOrValue.isTypeOrEmpty(StringSyncValue.class); + syncOrValue.isTypeOrEmpty(IStringValue.class); } public List getTextAsComponents() { @@ -99,6 +100,15 @@ public void onUpdate() { } } + @Override + protected void drawText(ModularGuiContext context, TextFieldTheme widgetTheme) { + context.graphicsPose().pushPose(); + context.graphicsPose().translate(-1, 3, 0); + this.renderer.draw(context.getGraphics(), getTextAsComponents()); + context.graphicsPose().popPose(); + getScrollArea().getScrollX().setScrollSize(Math.max(0, (int) (this.renderer.getLastWidth() + 0.5f))); + } + public boolean notEditedForSomeTime() { return Util.getEpochMillis() - 3000 > lastEdited; } diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java index 1bf77349ca5..a634e4282ee 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/LangHandler.java @@ -1833,7 +1833,7 @@ When you insert it, a button will appear to configure the module (for example ju provider.add("gtceu.placeholder_editor.extra_closing_bracket", "Extra closing bracket"); provider.add("gtceu.placeholder_editor.no_placeholder", "Placeholder with name '%s' does not exist"); provider.add("gtceu.placeholder_editor.constant_value", - "This expression always evaluates to the same result.\nConsider replacing it with a constant."); + "This expression always evaluates to '%s'.\nConsider replacing it with a constant."); provider.add("gtceu.placeholder_editor.write_in_if", """ Placeholders inside {if} are executed regardless of the condition. This means that, for example, "{if 0 {redstone set 15}}" will produce redstone output.