Skip to content

Commit ea88890

Browse files
authored
Module: ContainerPreview (#176)
Added ContainerPreview for showing shulker box and ender chest contents with locking feature to hover over containing items. Echest needs to be opened at least once in the session to show the contents. <img width="1513" height="979" alt="image" src="https://github.com/user-attachments/assets/1db2b381-e9a9-45c3-b367-5d2ba4188792" />
1 parent 54183e1 commit ea88890

File tree

7 files changed

+506
-0
lines changed

7 files changed

+506
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.items;
19+
20+
import com.lambda.module.modules.render.ContainerPreview;
21+
import net.minecraft.item.BlockItem;
22+
import net.minecraft.item.Item;
23+
import net.minecraft.item.ItemStack;
24+
import net.minecraft.item.tooltip.TooltipData;
25+
import org.spongepowered.asm.mixin.Mixin;
26+
27+
import java.util.Optional;
28+
29+
@Mixin(BlockItem.class)
30+
public class BlockItemMixin extends Item {
31+
public BlockItemMixin(Settings settings) {
32+
super(settings);
33+
}
34+
35+
@Override
36+
public Optional<TooltipData> getTooltipData(ItemStack stack) {
37+
if (ContainerPreview.INSTANCE.isEnabled() && ContainerPreview.isPreviewableContainer(stack)) {
38+
return Optional.of(new ContainerPreview.ContainerComponent(stack));
39+
}
40+
return super.getTooltipData(stack);
41+
}
42+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.render;
19+
20+
import com.lambda.module.modules.render.ContainerPreview;
21+
import net.minecraft.client.font.TextRenderer;
22+
import net.minecraft.client.gui.DrawContext;
23+
import net.minecraft.client.gui.tooltip.TooltipComponent;
24+
import net.minecraft.client.gui.tooltip.TooltipPositioner;
25+
import net.minecraft.item.ItemStack;
26+
import net.minecraft.item.tooltip.TooltipData;
27+
import net.minecraft.text.Text;
28+
import net.minecraft.util.Identifier;
29+
import org.jetbrains.annotations.Nullable;
30+
import org.spongepowered.asm.mixin.Mixin;
31+
import org.spongepowered.asm.mixin.injection.At;
32+
import org.spongepowered.asm.mixin.injection.Inject;
33+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
34+
35+
import java.util.List;
36+
import java.util.Optional;
37+
38+
@Mixin(DrawContext.class)
39+
public class DrawContextMixin {
40+
@Inject(method = "drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;Ljava/util/Optional;IILnet/minecraft/util/Identifier;)V", at = @At("HEAD"), cancellable = true)
41+
private void onDrawTooltip(TextRenderer textRenderer, List<Text> text, Optional<TooltipData> data, int x, int y, @Nullable Identifier texture, CallbackInfo ci) {
42+
if (!ContainerPreview.INSTANCE.isEnabled()) return;
43+
44+
if (ContainerPreview.isRenderingSubTooltip()) return;
45+
46+
if (ContainerPreview.isLocked()) {
47+
ci.cancel();
48+
ContainerPreview.renderLockedTooltip((DrawContext)(Object)this, textRenderer);
49+
return;
50+
}
51+
52+
if (data.isPresent() && data.get() instanceof ContainerPreview.ContainerComponent component) {
53+
ci.cancel();
54+
ContainerPreview.renderShulkerTooltip((DrawContext)(Object)this, textRenderer, component, x, y);
55+
}
56+
}
57+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.render;
19+
20+
import com.lambda.module.modules.render.ContainerPreview;
21+
import net.minecraft.client.gui.screen.ingame.HandledScreen;
22+
import org.spongepowered.asm.mixin.Mixin;
23+
import org.spongepowered.asm.mixin.injection.At;
24+
import org.spongepowered.asm.mixin.injection.Inject;
25+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
26+
27+
@Mixin(HandledScreen.class)
28+
public class HandledScreenMixin {
29+
@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
30+
private void onMouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
31+
if (ContainerPreview.INSTANCE.isEnabled() && ContainerPreview.isLocked()) {
32+
if (ContainerPreview.isMouseOverLockedTooltip((int) mouseX, (int) mouseY)) {
33+
cir.setReturnValue(true);
34+
}
35+
}
36+
}
37+
38+
@Inject(method = "mouseReleased", at = @At("HEAD"), cancellable = true)
39+
private void onMouseReleased(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
40+
if (ContainerPreview.INSTANCE.isEnabled() && ContainerPreview.isLocked()) {
41+
if (ContainerPreview.isMouseOverLockedTooltip((int) mouseX, (int) mouseY)) {
42+
cir.setReturnValue(true);
43+
}
44+
}
45+
}
46+
}

src/main/java/com/lambda/mixin/render/ScreenMixin.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
package com.lambda.mixin.render;
1919

2020
import com.lambda.gui.components.QuickSearch;
21+
import com.lambda.module.modules.render.ContainerPreview;
2122
import com.lambda.module.modules.render.NoRender;
23+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
24+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
25+
import net.minecraft.client.MinecraftClient;
2226
import net.minecraft.client.gui.DrawContext;
2327
import net.minecraft.client.gui.screen.Screen;
2428
import org.lwjgl.glfw.GLFW;
@@ -42,4 +46,13 @@ private void onKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfo
4246
private void injectRenderInGameBackground(DrawContext context, CallbackInfo ci) {
4347
if (NoRender.INSTANCE.isEnabled() && NoRender.getNoGuiShadow()) ci.cancel();
4448
}
49+
50+
@WrapOperation(method = "renderWithTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;render(Lnet/minecraft/client/gui/DrawContext;IIF)V"))
51+
private void wrapRender(Screen instance, DrawContext context, int mouseX, int mouseY, float deltaTicks, Operation<Void> original) {
52+
original.call(instance, context, mouseX, mouseY, deltaTicks);
53+
54+
if (ContainerPreview.INSTANCE.isEnabled() && ContainerPreview.isLocked()) {
55+
ContainerPreview.renderLockedTooltip(context, MinecraftClient.getInstance().textRenderer);
56+
}
57+
}
4558
}

src/main/java/com/lambda/mixin/render/TooltipComponentMixin.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
package com.lambda.mixin.render;
1919

20+
import com.lambda.module.modules.render.ContainerPreview;
2021
import com.lambda.module.modules.render.MapPreview;
2122
import net.minecraft.client.gui.tooltip.BundleTooltipComponent;
2223
import net.minecraft.client.gui.tooltip.ProfilesTooltipComponent;
@@ -32,6 +33,11 @@
3233
public interface TooltipComponentMixin {
3334
@Inject(method = "of(Lnet/minecraft/item/tooltip/TooltipData;)Lnet/minecraft/client/gui/tooltip/TooltipComponent;", at = @At("HEAD"), cancellable = true)
3435
private static void of(TooltipData tooltipData, CallbackInfoReturnable<TooltipComponent> cir) {
36+
if (ContainerPreview.INSTANCE.isEnabled() && tooltipData instanceof ContainerPreview.ContainerComponent containerComponent) {
37+
cir.setReturnValue(containerComponent);
38+
return;
39+
}
40+
3541
if (MapPreview.INSTANCE.isEnabled()) cir.setReturnValue((switch (tooltipData) {
3642
case MapPreview.MapComponent mapComponent -> mapComponent;
3743
case BundleTooltipData bundleTooltipData -> new BundleTooltipComponent(bundleTooltipData.contents());

0 commit comments

Comments
 (0)