|
| 1 | +package com.mitchej123.hodgepodge.mixins.early.minecraft; |
| 2 | + |
| 3 | +import java.util.Iterator; |
| 4 | +import java.util.List; |
| 5 | + |
| 6 | +import net.minecraft.client.gui.GuiButton; |
| 7 | +import net.minecraft.client.gui.GuiDisconnected; |
| 8 | +import net.minecraft.client.gui.GuiScreen; |
| 9 | + |
| 10 | +import org.spongepowered.asm.mixin.Mixin; |
| 11 | +import org.spongepowered.asm.mixin.Shadow; |
| 12 | +import org.spongepowered.asm.mixin.Unique; |
| 13 | +import org.spongepowered.asm.mixin.injection.At; |
| 14 | +import org.spongepowered.asm.mixin.injection.Inject; |
| 15 | +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; |
| 16 | + |
| 17 | +/** |
| 18 | + * Vertically centers the disconnect screen as a group so the button doesn't overlap long kick messages. |
| 19 | + * |
| 20 | + * <pre> |
| 21 | + * Layout (top to bottom, group centered on the screen): |
| 22 | + * Title (FONT_HEIGHT = 9px) |
| 23 | + * 20px gap (padding: 10 below title + 10 above text) |
| 24 | + * Wrapped reason text (n * FONT_HEIGHT) |
| 25 | + * 12px gap (padding: 10 below text + 2 above button) |
| 26 | + * Button (20px tall) |
| 27 | + * </pre> |
| 28 | + */ |
| 29 | +@Mixin(GuiDisconnected.class) |
| 30 | +public class MixinGuiDisconnected_FixLayout extends GuiScreen { |
| 31 | + |
| 32 | + @Shadow |
| 33 | + private String field_146306_a; // title string |
| 34 | + |
| 35 | + @Shadow |
| 36 | + private List field_146305_g; // wrapped text lines |
| 37 | + |
| 38 | + @Unique |
| 39 | + private int hodgepodge$titleY; |
| 40 | + |
| 41 | + @Unique |
| 42 | + private int hodgepodge$textStartY; |
| 43 | + |
| 44 | + @Inject(method = "initGui", at = @At("TAIL")) |
| 45 | + private void hodgepodge$centerLayout(CallbackInfo ci) { |
| 46 | + int lineHeight = this.fontRendererObj.FONT_HEIGHT; |
| 47 | + int textLines = field_146305_g != null ? field_146305_g.size() : 0; |
| 48 | + |
| 49 | + // Inter-element gap = bottom padding of previous + top padding of next. |
| 50 | + // title→text = 10+10 = 20, text→button = 10+2 = 12. |
| 51 | + int totalHeight = lineHeight + 20 + (textLines * lineHeight) + 12 + 20; |
| 52 | + |
| 53 | + int topY = Math.max(5, (this.height - totalHeight) / 2); |
| 54 | + |
| 55 | + hodgepodge$titleY = topY; |
| 56 | + hodgepodge$textStartY = topY + lineHeight + 20; |
| 57 | + int buttonY = hodgepodge$textStartY + (textLines * lineHeight) + 12; |
| 58 | + |
| 59 | + // Clamp so button stays on screen (button is 20px tall) |
| 60 | + if (buttonY + 20 > this.height - 5) { |
| 61 | + buttonY = this.height - 25; |
| 62 | + } |
| 63 | + |
| 64 | + for (Object obj : this.buttonList) { |
| 65 | + GuiButton button = (GuiButton) obj; |
| 66 | + if (button.id == 0) { |
| 67 | + button.yPosition = buttonY; |
| 68 | + break; |
| 69 | + } |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + /** |
| 74 | + * Vanilla hardcodes title at height/2-50 and text at height/2-30. We cancel and redraw at the centered positions, |
| 75 | + * then let super render the buttons from buttonList. |
| 76 | + */ |
| 77 | + @Inject(method = "drawScreen", at = @At("HEAD"), cancellable = true) |
| 78 | + private void hodgepodge$drawScreen(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { |
| 79 | + ci.cancel(); |
| 80 | + |
| 81 | + this.drawDefaultBackground(); |
| 82 | + |
| 83 | + this.drawCenteredString(this.fontRendererObj, this.field_146306_a, this.width / 2, hodgepodge$titleY, 0xAAAAAA); |
| 84 | + |
| 85 | + if (this.field_146305_g != null) { |
| 86 | + int y = hodgepodge$textStartY; |
| 87 | + for (Iterator<?> iterator = this.field_146305_g.iterator(); iterator |
| 88 | + .hasNext(); y += this.fontRendererObj.FONT_HEIGHT) { |
| 89 | + String s = (String) iterator.next(); |
| 90 | + this.drawCenteredString(this.fontRendererObj, s, this.width / 2, y, 0xFFFFFF); |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + super.drawScreen(mouseX, mouseY, partialTicks); |
| 95 | + } |
| 96 | +} |
0 commit comments