为高亮显示按钮绑定了控制当前选择供应器变量

This commit is contained in:
GaLi 2025-08-09 16:59:50 +08:00
parent 628abec373
commit 24c4c81889
7 changed files with 240 additions and 2 deletions

View File

@ -0,0 +1,59 @@
package com.extendedae_plus.client.gui;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component;
import appeng.client.gui.Icon;
import appeng.client.gui.widgets.IconButton;
/**
* GroupHeader选择按钮
* 用于在样板访问终端中标记GroupHeaderRow的Ischooiceable状态
*/
public class GroupHeaderChoiceButton extends IconButton {
private boolean isChoiceable = false;
private final String groupName;
private final Runnable onChoiceChanged;
public GroupHeaderChoiceButton(String groupName, Runnable onChoiceChanged) {
super(button -> {
GroupHeaderChoiceButton choiceButton = (GroupHeaderChoiceButton) button;
choiceButton.toggleChoice();
});
this.groupName = groupName;
this.onChoiceChanged = onChoiceChanged;
this.setHalfSize(true); // 使用小尺寸按钮
this.setMessage(Component.translatable("gui.extendedae_plus.group_header.choice"));
}
public void toggleChoice() {
this.isChoiceable = !this.isChoiceable;
if (this.onChoiceChanged != null) {
this.onChoiceChanged.run();
}
}
public void setChoiceable(boolean isChoiceable) {
this.isChoiceable = isChoiceable;
}
public boolean isChoiceable() {
return this.isChoiceable;
}
public String getGroupName() {
return this.groupName;
}
@Override
protected Icon getIcon() {
return this.isChoiceable ? Icon.WHITELIST : Icon.BLACKLIST;
}
@Override
public Component getMessage() {
return this.isChoiceable
? Component.translatable("gui.extendedae_plus.group_header.choiceable")
: Component.translatable("gui.extendedae_plus.group_header.not_choiceable");
}
}

View File

@ -0,0 +1,59 @@
package com.extendedae_plus.client.gui;
import net.minecraft.client.gui.components.Button;
import net.minecraft.network.chat.Component;
import appeng.client.gui.Icon;
import appeng.client.gui.widgets.IconButton;
/**
* 样板供应器选择按钮
* 用于在样板访问终端中标记选中的样板供应器
*/
public class PatternProviderSelectionButton extends IconButton {
private boolean selected = false;
private final long serverId;
private final Runnable onSelectionChanged;
public PatternProviderSelectionButton(long serverId, Runnable onSelectionChanged) {
super(button -> {
PatternProviderSelectionButton selectionButton = (PatternProviderSelectionButton) button;
selectionButton.toggleSelection();
});
this.serverId = serverId;
this.onSelectionChanged = onSelectionChanged;
this.setHalfSize(true); // 使用小尺寸按钮
this.setMessage(Component.translatable("gui.extendedae_plus.pattern_provider.select"));
}
public void toggleSelection() {
this.selected = !this.selected;
if (this.onSelectionChanged != null) {
this.onSelectionChanged.run();
}
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public boolean isSelected() {
return this.selected;
}
public long getServerId() {
return this.serverId;
}
@Override
protected Icon getIcon() {
return this.selected ? Icon.VALID : Icon.INVALID;
}
@Override
public Component getMessage() {
return this.selected
? Component.translatable("gui.extendedae_plus.pattern_provider.selected")
: Component.translatable("gui.extendedae_plus.pattern_provider.unselected");
}
}

View File

@ -24,10 +24,37 @@ public abstract class GuiExPatternTerminalMixin extends AEBaseScreen<ContainerEx
@Unique
private boolean showSlots = true; // 默认显示槽位
@Unique
private long currentlychooicepatterprovider = -1; // 当前选择的样板供应器ID
public GuiExPatternTerminalMixin(ContainerExPatternTerminal menu, Inventory playerInventory, Component title, ScreenStyle style) {
super(menu, playerInventory, title, style);
}
/**
* 获取当前选择的样板供应器ID
*/
@Unique
public long getCurrentlyChoicePatternProvider() {
return currentlychooicepatterprovider;
}
/**
* 设置当前选择的样板供应器ID
*/
@Unique
public void setCurrentlyChoicePatternProvider(long id) {
this.currentlychooicepatterprovider = id;
}
/**
* 重置当前选择的样板供应器ID
*/
@Unique
public void resetCurrentlyChoicePatternProvider() {
this.currentlychooicepatterprovider = -1;
}
@Inject(method = "<init>", at = @At("TAIL"), remap = false)
private void injectConstructor(ContainerExPatternTerminal menu, Inventory playerInventory, Component title, ScreenStyle style, CallbackInfo ci) {

View File

@ -0,0 +1,68 @@
package com.extendedae_plus.mixin;
import com.glodblock.github.extendedae.client.button.HighlightButton;
import com.glodblock.github.extendedae.client.gui.GuiExPatternTerminal;
import net.minecraft.client.gui.components.Button;
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;
@Mixin(value = HighlightButton.class, priority = 1000)
public abstract class HighlightButtonMixin {
@Shadow(remap = false)
private static void highlight(Button btn) {}
@Inject(method = "highlight", at = @At("TAIL"), remap = false)
private static void onHighlight(Button btn, CallbackInfo ci) {
if (btn instanceof HighlightButton hb) {
// 获取当前打开的GUI屏幕
var minecraft = net.minecraft.client.Minecraft.getInstance();
if (minecraft.screen instanceof GuiExPatternTerminal<?> terminal) {
// 通过反射获取HighlightButton的serverId信息
try {
// 获取HighlightButton的pos字段用于标识对应的样板供应器
var posField = HighlightButton.class.getDeclaredField("pos");
posField.setAccessible(true);
var pos = posField.get(hb);
if (pos != null) {
// 通过反射访问infoMap字段
var infoMapField = GuiExPatternTerminal.class.getDeclaredField("infoMap");
infoMapField.setAccessible(true);
@SuppressWarnings("unchecked")
var infoMap = (java.util.Map<Long, Object>) infoMapField.get(terminal);
// 查找对应的样板供应器ID
for (var entry : infoMap.entrySet()) {
var info = entry.getValue();
// 通过反射调用pos()方法
var posMethod = info.getClass().getMethod("pos");
var infoPos = posMethod.invoke(info);
if (pos.equals(infoPos)) {
long serverId = entry.getKey();
// 通过反射调用setter方法
try {
var setMethod = terminal.getClass().getMethod("setCurrentlyChoicePatternProvider", long.class);
setMethod.invoke(terminal, serverId);
System.out.println("ExtendedAE Plus: 通过Mixin设置了当前选择的样板供应器ID: " + serverId);
} catch (Exception e) {
System.out.println("ExtendedAE Plus: 无法设置样板供应器ID错误: " + e.getMessage());
e.printStackTrace();
}
break;
}
}
}
} catch (Exception e) {
System.out.println("ExtendedAE Plus: 通过Mixin设置样板供应器ID时出错: " + e.getMessage());
e.printStackTrace();
}
}
}
}
}

View File

@ -0,0 +1,17 @@
{
"gui.expatternprovider.toggle_slots": "Toggle Slots",
"gui.expatternprovider.hide_slots": "Hide Slots",
"gui.expatternprovider.show_slots": "Show Slots",
"gui.expatternprovider.clear_selection": "Clear Selection",
"gui.extendedae_plus.pattern_provider.select": "Select Pattern Provider",
"gui.extendedae_plus.pattern_provider.selected": "Pattern Provider Selected",
"gui.extendedae_plus.pattern_provider.unselected": "Click to select this pattern provider",
"message.extendedae_plus.no_provider_selected": "Please select a pattern provider first",
"message.extendedae_plus.invalid_pattern": "Please hold a valid encoded pattern",
"message.extendedae_plus.upload_success": "Pattern uploaded successfully",
"message.extendedae_plus.upload_failed": "Failed to upload pattern - no empty slots",
"message.extendedae_plus.uploading_pattern": "Uploading pattern...",
"gui.extendedae_plus.group_header.choice": "Toggle Group Choice",
"gui.extendedae_plus.group_header.choiceable": "Group is choiceable",
"gui.extendedae_plus.group_header.not_choiceable": "Group is not choiceable"
}

View File

@ -0,0 +1,6 @@
{
"gui.expatternprovider.toggle_slots": "切换槽位显示",
"gui.expatternprovider.hide_slots": "隐藏槽位",
"gui.expatternprovider.show_slots": "显示槽位",
"gui.expatternprovider.clear_selection": "取消选择"
}

View File

@ -6,7 +6,8 @@
"client": [
"GuiExPatternProviderMixin",
"SlotGridLayoutMixin",
"GuiExPatternTerminalMixin"
"GuiExPatternTerminalMixin",
"HighlightButtonMixin"
],
"mixins": [
"ContainerExPatternProviderMixin",
@ -14,5 +15,6 @@
],
"injectors": {
"defaultRequire": 1
}
},
"priority": 1000
}