调整上传样板按钮布局
This commit is contained in:
parent
e7f93b70c2
commit
6a536b90d0
|
|
@ -1,63 +1,142 @@
|
|||
package com.extendedae_plus.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.client.gui.components.Tooltip;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.renderer.Rect2i;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
|
||||
import appeng.client.gui.Icon;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.me.items.PatternEncodingTermScreen;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.client.gui.style.WidgetStyle;
|
||||
import appeng.client.gui.widgets.IconButton;
|
||||
import appeng.menu.me.items.PatternEncodingTermMenu;
|
||||
import appeng.menu.AEBaseMenu;
|
||||
|
||||
import com.extendedae_plus.network.ModNetwork;
|
||||
import com.extendedae_plus.network.UploadEncodedPatternToProviderC2SPacket;
|
||||
import com.extendedae_plus.mixin.accessor.AEBaseScreenAccessor;
|
||||
import com.extendedae_plus.mixin.accessor.AbstractContainerScreenAccessor;
|
||||
import com.extendedae_plus.mixin.accessor.ScreenAccessor;
|
||||
|
||||
/**
|
||||
* 在图样编码终端右侧工具栏加入一个上传按钮:
|
||||
* 在图样编码终端界面加入一个上传按钮:
|
||||
* 点击后把当前“已编码样板”上传到任意可用的样板供应器(服务端自动选择)。
|
||||
* 通过解析 AE2 样式中 encodePattern 的坐标,将按钮放在其左侧紧挨位置。
|
||||
*/
|
||||
@Mixin(AEBaseScreen.class)
|
||||
public abstract class PatternEncodingTermScreenMixin<T extends AEBaseMenu> {
|
||||
|
||||
// 使用 @Shadow 访问 AEBaseScreen 的受保护方法
|
||||
@Shadow
|
||||
protected abstract <B extends Button> B addToLeftToolbar(B button);
|
||||
|
||||
@Unique
|
||||
private boolean extendedae_plus$uploadBtnAdded = false;
|
||||
private IconButton extendedae_plus$uploadBtn;
|
||||
|
||||
@Inject(method = "init", at = @At("HEAD"))
|
||||
@Inject(method = "init", at = @At("TAIL"))
|
||||
private void extendedae_plus$addUploadButton(CallbackInfo ci) {
|
||||
// 仅在图样编码终端界面中添加按钮
|
||||
if (!(((Object) this) instanceof PatternEncodingTermScreen)) {
|
||||
return;
|
||||
}
|
||||
// 幂等:避免每次 init() 都重复添加按钮
|
||||
if (extendedae_plus$uploadBtnAdded) {
|
||||
return;
|
||||
}
|
||||
var uploadBtn = new IconButton(btn -> ModNetwork.CHANNEL
|
||||
.sendToServer(new com.extendedae_plus.network.RequestProvidersListC2SPacket())) {
|
||||
// 复用已存在的按钮实例,避免重复创建
|
||||
if (extendedae_plus$uploadBtn == null) {
|
||||
extendedae_plus$uploadBtn = new IconButton(btn -> ModNetwork.CHANNEL
|
||||
.sendToServer(new com.extendedae_plus.network.RequestProvidersListC2SPacket())) {
|
||||
@Override
|
||||
protected Icon getIcon() {
|
||||
return Icon.ARROW_UP;
|
||||
}
|
||||
};
|
||||
uploadBtn.setTooltip(Tooltip.create(Component.translatable("extendedae_plus.button.choose_provider")));
|
||||
};
|
||||
extendedae_plus$uploadBtn.setTooltip(Tooltip.create(Component.translatable("extendedae_plus.button.choose_provider")));
|
||||
}
|
||||
|
||||
// 直接调用 @Shadow 方法,避免跨包 protected 访问问题
|
||||
this.addToLeftToolbar(uploadBtn);
|
||||
extendedae_plus$uploadBtnAdded = true;
|
||||
// 解析 encodePattern 的样式位置
|
||||
try {
|
||||
ScreenStyle style = ((AEBaseScreenAccessor<?>) (Object) this).extendedae_plus$getStyle();
|
||||
WidgetStyle ws = style.getWidget("encodePattern");
|
||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getLeftPos();
|
||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getTopPos();
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageWidth();
|
||||
int imageHeight = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageHeight();
|
||||
Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight);
|
||||
var pos = ws.resolve(bounds);
|
||||
int targetW = ws.getWidth() > 0 ? ws.getWidth() : 18;
|
||||
int targetH = ws.getHeight() > 0 ? ws.getHeight() : 18;
|
||||
// 尺寸与 encodePattern 一致
|
||||
extendedae_plus$uploadBtn.setWidth(targetW);
|
||||
extendedae_plus$uploadBtn.setHeight(targetH);
|
||||
// 放在其左侧紧挨(预留 2px 间距)
|
||||
extendedae_plus$uploadBtn.setX(pos.getX() - targetW - 2);
|
||||
extendedae_plus$uploadBtn.setY(pos.getY());
|
||||
} catch (Throwable t) {
|
||||
// 回退:放在界面右侧大致位置,避免不可见
|
||||
extendedae_plus$uploadBtn.setWidth(18);
|
||||
extendedae_plus$uploadBtn.setHeight(18);
|
||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getLeftPos();
|
||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getTopPos();
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageWidth();
|
||||
extendedae_plus$uploadBtn.setX(leftPos + imageWidth - 18 - 8);
|
||||
extendedae_plus$uploadBtn.setY(topPos + 88);
|
||||
}
|
||||
|
||||
// 直接向 renderables / children 列表添加,避免依赖受保护方法
|
||||
var accessor = (ScreenAccessor) (Object) this;
|
||||
var renderables = accessor.extendedae_plus$getRenderables();
|
||||
var children = accessor.extendedae_plus$getChildren();
|
||||
if (!renderables.contains(extendedae_plus$uploadBtn)) {
|
||||
renderables.add(extendedae_plus$uploadBtn);
|
||||
}
|
||||
if (!children.contains(extendedae_plus$uploadBtn)) {
|
||||
children.add(extendedae_plus$uploadBtn);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "containerTick", at = @At("TAIL"))
|
||||
private void extendedae_plus$ensureUploadButton(CallbackInfo ci) {
|
||||
if (!(((Object) this) instanceof PatternEncodingTermScreen)) {
|
||||
return;
|
||||
}
|
||||
if (extendedae_plus$uploadBtn == null) {
|
||||
return;
|
||||
}
|
||||
var renderables2 = ((ScreenAccessor) (Object) this).extendedae_plus$getRenderables();
|
||||
if (!renderables2.contains(extendedae_plus$uploadBtn)) {
|
||||
// 被其它模组清空/替换后,重新计算一次位置并补回
|
||||
try {
|
||||
ScreenStyle style = ((AEBaseScreenAccessor<?>) (Object) this).extendedae_plus$getStyle();
|
||||
WidgetStyle ws = style.getWidget("encodePattern");
|
||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getLeftPos();
|
||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getTopPos();
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageWidth();
|
||||
int imageHeight = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageHeight();
|
||||
Rect2i bounds = new Rect2i(leftPos, topPos, imageWidth, imageHeight);
|
||||
var pos = ws.resolve(bounds);
|
||||
int targetW = ws.getWidth() > 0 ? ws.getWidth() : 18;
|
||||
int targetH = ws.getHeight() > 0 ? ws.getHeight() : 18;
|
||||
extendedae_plus$uploadBtn.setWidth(targetW);
|
||||
extendedae_plus$uploadBtn.setHeight(targetH);
|
||||
extendedae_plus$uploadBtn.setX(pos.getX() - targetW - 2);
|
||||
extendedae_plus$uploadBtn.setY(pos.getY());
|
||||
} catch (Throwable t) {
|
||||
int leftPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getLeftPos();
|
||||
int topPos = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getTopPos();
|
||||
int imageWidth = ((AbstractContainerScreenAccessor<?>) (Object) this).extendedae_plus$getImageWidth();
|
||||
extendedae_plus$uploadBtn.setWidth(18);
|
||||
extendedae_plus$uploadBtn.setHeight(18);
|
||||
extendedae_plus$uploadBtn.setX(leftPos + imageWidth - 18 - 8);
|
||||
extendedae_plus$uploadBtn.setY(topPos + 88);
|
||||
}
|
||||
var accessor2 = (ScreenAccessor) (Object) this;
|
||||
var r = accessor2.extendedae_plus$getRenderables();
|
||||
var c = accessor2.extendedae_plus$getChildren();
|
||||
if (!r.contains(extendedae_plus$uploadBtn)) {
|
||||
r.add(extendedae_plus$uploadBtn);
|
||||
}
|
||||
if (!c.contains(extendedae_plus$uploadBtn)) {
|
||||
c.add(extendedae_plus$uploadBtn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
package com.extendedae_plus.mixin.accessor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.style.ScreenStyle;
|
||||
import appeng.menu.AEBaseMenu;
|
||||
|
||||
@Mixin(value = AEBaseScreen.class, remap = false)
|
||||
public interface AEBaseScreenAccessor<T extends AEBaseMenu> {
|
||||
@Accessor(value = "style", remap = false)
|
||||
ScreenStyle extendedae_plus$getStyle();
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.extendedae_plus.mixin.accessor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.menu.AEBaseMenu;
|
||||
|
||||
@Mixin(AEBaseScreen.class)
|
||||
public interface AEBaseScreenInvoker<T extends AEBaseMenu> {
|
||||
// 空接口:避免在 AEBaseScreen 上声明不存在方法的 Invoker 导致编译错误
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.extendedae_plus.mixin.accessor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
|
||||
@Mixin(AbstractContainerScreen.class)
|
||||
public interface AbstractContainerScreenAccessor<T extends AbstractContainerMenu> {
|
||||
@Accessor("leftPos") int extendedae_plus$getLeftPos();
|
||||
@Accessor("topPos") int extendedae_plus$getTopPos();
|
||||
@Accessor("imageWidth") int extendedae_plus$getImageWidth();
|
||||
@Accessor("imageHeight") int extendedae_plus$getImageHeight();
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.extendedae_plus.mixin.accessor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.client.gui.components.Renderable;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public interface ScreenAccessor {
|
||||
@Accessor("renderables")
|
||||
List<Renderable> extendedae_plus$getRenderables();
|
||||
|
||||
@Accessor("children")
|
||||
List<GuiEventListener> extendedae_plus$getChildren();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.extendedae_plus.mixin.accessor;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
import net.minecraft.client.gui.components.Renderable;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
|
||||
@Mixin(Screen.class)
|
||||
public interface ScreenInvoker {
|
||||
@Invoker("addRenderableWidget")
|
||||
<W extends GuiEventListener & Renderable> W extendedae_plus$invokeAddRenderableWidget(W widget);
|
||||
}
|
||||
|
|
@ -10,7 +10,10 @@
|
|||
"HighlightButtonMixin",
|
||||
"PickFromWirelessMixin",
|
||||
"PatternEncodingTermScreenMixin",
|
||||
"jei.EncodePatternTransferHandlerMixin"
|
||||
"jei.EncodePatternTransferHandlerMixin",
|
||||
"accessor.AEBaseScreenAccessor",
|
||||
"accessor.AbstractContainerScreenAccessor",
|
||||
"accessor.ScreenAccessor"
|
||||
],
|
||||
"mixins": [
|
||||
"ContainerExPatternProviderMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user