ProviderSelectScreen调整底部按钮位置,添加翻译键,切换语言时重置缓存

This commit is contained in:
C-H716 2025-10-24 00:07:17 +08:00
parent a22b932b0c
commit 98900737e9
3 changed files with 96 additions and 56 deletions

View File

@ -39,19 +39,21 @@ public class ProviderSelectScreen extends Screen {
// 中文名输入框用于添加映射
private EditBox cnInput;
private String query = "";
// 翻页按钮
private Button prevButton;
private Button nextButton;
// 页面
private int page = 0;
private static final int PAGE_SIZE = 6;
// 按钮池
private final List<Button> entryButtons = new ArrayList<>();
private final int[] buttonIndexMap = new int[PAGE_SIZE]; // 映射到 fIds 的索引
// 缓存 Component JSON 解析
private static final Map<String, String> componentCache = new HashMap<>();
private Button prevButton;
private Button nextButton;
private String lastLanguage = ""; // 当前语言版本
public ProviderSelectScreen(Screen parent, List<Long> ids, List<String> names, List<Integer> emptySlots) {
super(Component.translatable("extendedae_plus.screen.choose_provider.title"));
@ -130,39 +132,49 @@ public class ProviderSelectScreen extends Screen {
this.addRenderableWidget(nextButton);
// 映射按钮和输入框
// 统一按钮宽度
int btnWidth2 = 80;
int inputWidth = 120;
int btnGap = 5;
// 总宽度 = 重载按钮 + 输入框 + 添加 + 删除 + 关闭按钮 + 间距
int totalWidth = btnWidth2 + btnGap + inputWidth + btnGap + btnWidth2 * 2 + btnGap + btnWidth2;
int startX = centerX - totalWidth / 2;
// 重载映射按钮
Button reload = Button.builder(Component.translatable("extendedae_plus.screen.reload_mapping"), b -> reloadMapping())
.bounds(centerX - 130, navY + 30, 80, 20)
.bounds(startX, navY + 30, btnWidth2, 20)
.build();
this.addRenderableWidget(reload);
// 中文名输入框用于新增映射的值
if (cnInput == null) {
cnInput = new EditBox(this.font, centerX + 50, navY + 30, 120, 20, Component.translatable("extendedae_plus.screen.cn_name"));
cnInput = new EditBox(this.font, startX + btnWidth2 + btnGap, navY + 30, inputWidth, 20, Component.translatable("extendedae_plus.screen.upload.name"));
} else {
cnInput.setX(centerX + 50);
cnInput.setX(startX + btnWidth2 + btnGap);
cnInput.setY(navY + 30);
cnInput.setWidth(120);
cnInput.setWidth(inputWidth);
}
this.addRenderableWidget(cnInput);
// 增加映射按钮使用当前搜索关键字 -> 中文
// 关闭按钮
Button close = Button.builder(Component.translatable("gui.cancel"), b -> onClose())
.bounds(startX + btnWidth2 + btnGap + inputWidth + btnGap, navY + 30, btnWidth2, 20)
.build();
this.addRenderableWidget(close);
// 添加映射按钮使用当前搜索关键字 -> 中文
Button addMap = Button.builder(Component.translatable("extendedae_plus.screen.add_mapping"), b -> addMappingFromUI())
.bounds(centerX + 175, navY + 30, 80, 20)
.bounds(startX + btnWidth2 + btnGap + inputWidth + btnGap + btnWidth2 + btnGap, navY + 30, btnWidth2, 20)
.build();
this.addRenderableWidget(addMap);
// 删除映射按中文值精确匹配删除按钮
// 删除映射按钮按中文值精确匹配删除按钮
Button delByCn = Button.builder(Component.translatable("extendedae_plus.screen.delete_mapping"), b -> deleteMappingByCnFromUI())
.bounds(centerX + 240, navY + 30, 80, 20)
.bounds(startX + btnWidth2 + btnGap + inputWidth + btnGap + btnWidth2 * 2 + btnGap * 2, navY + 30, btnWidth2, 20)
.build();
this.addRenderableWidget(delByCn);
// 关闭按钮
Button close = Button.builder(Component.translatable("gui.cancel"), b -> onClose())
.bounds(centerX - 40, navY + 30, 80, 20)
.build();
this.addRenderableWidget(close);
refreshButtons(); // 初始化完成后刷新按钮状态
}
@ -234,7 +246,7 @@ public class ProviderSelectScreen extends Screen {
String name = fNames.get(idx);
int totalSlots = fTotalSlots.get(idx);
int count = fCount.get(idx);
// 不显示具体 id显示合并统计名称总空位x数量
return name + " (" + totalSlots + ") x" + count;
}
@ -263,7 +275,7 @@ public class ProviderSelectScreen extends Screen {
String name = names.get(i);
long id = ids.get(i);
int slots = emptySlots.get(i);
// Component JSON 转换为本地化文本用于分组键
String groupKey = deserializeComponentName(name);
map.compute(groupKey, (k, g) -> {
@ -284,31 +296,6 @@ public class ProviderSelectScreen extends Screen {
}
}
private static class Group {
long bestId;
int bestSlots;
int totalSlots;
int count;
Group(long id, int slots) {
this.bestId = id;
this.bestSlots = slots;
this.totalSlots = Math.max(0, slots);
this.count = 1;
}
void merge(long id, int slots) {
count++;
totalSlots += Math.max(0, slots);
// 挑选空位最多的作为代表 id若并列保留先到者
if (slots > bestSlots) {
bestSlots = slots;
bestId = id;
}
}
}
private void applyFilter() {
fIds.clear();
fNames.clear();
@ -417,6 +404,13 @@ public class ProviderSelectScreen extends Screen {
if (cnInput != null) {
cnInput.tick();
}
String currentLang = Minecraft.getInstance().options.languageCode;
if (!currentLang.equals(lastLanguage)) {
lastLanguage = currentLang;
componentCache.clear();
refreshButtons();
}
}
private void addMappingFromUI() {
@ -424,28 +418,32 @@ public class ProviderSelectScreen extends Screen {
String val = cnInput == null ? "" : cnInput.getValue().trim();
var player = Minecraft.getInstance().player;
if (key.isEmpty()) {
if (player != null) player.sendSystemMessage(Component.literal("请输入搜索关键字后再添加映射"));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.enter_search_key"));
return;
}
if (val.isEmpty()) {
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称"));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.enter_cn_name"));
return;
}
boolean ok = ExtendedAEPatternUploadUtil.addOrUpdateAliasMapping(key, val);
if (ok) {
if (player != null) player.sendSystemMessage(Component.literal("已添加/更新映射: " + key + " -> " + val));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.mapping_added",
key, val));
// 将刚添加的中文名写入搜索框作为当前查询
this.query = val;
if (this.searchBox != null) {
this.searchBox.setValue(val);
}
// 更新本地过滤显示若名称包含中文可被搜索
// 更新本地过滤显示
applyFilter();
// 回到第一页以展示最新筛选结果
page = 0;
refreshButtons();
} else {
if (player != null) player.sendSystemMessage(Component.literal("写入映射失败"));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.mapping_failed"));
}
}
@ -454,17 +452,44 @@ public class ProviderSelectScreen extends Screen {
String val = cnInput == null ? "" : cnInput.getValue().trim();
var player = Minecraft.getInstance().player;
if (val.isEmpty()) {
if (player != null) player.sendSystemMessage(Component.literal("请输入中文名称后再删除映射"));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.enter_cn_name_delete"));
return;
}
int removed = ExtendedAEPatternUploadUtil.removeMappingsByCnValue(val);
if (removed > 0) {
if (player != null) player.sendSystemMessage(Component.literal("已删除 " + removed + " 条映射,中文= " + val));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.mapping_deleted", removed, val));
applyFilter();
page = 0;
refreshButtons();
} else {
if (player != null) player.sendSystemMessage(Component.literal("未找到中文为 '" + val + "' 的映射"));
if (player != null)
player.sendSystemMessage(Component.translatable("extendedae_plus.screen.upload.mapping_not_found", val));
}
}
private static class Group {
long bestId;
int bestSlots;
int totalSlots;
int count;
Group(long id, int slots) {
this.bestId = id;
this.bestSlots = slots;
this.totalSlots = Math.max(0, slots);
this.count = 1;
}
void merge(long id, int slots) {
count++;
totalSlots += Math.max(0, slots);
// 挑选空位最多的作为代表 id若并列保留先到者
if (slots > bestSlots) {
bestSlots = slots;
bestId = id;
}
}
}
}

View File

@ -18,6 +18,7 @@
"item.extendedae_plus.1024x_crafting_accelerator": "1024x Crafting Accelerator",
"item.extendedae_plus.network_pattern_controller": "Pattern Supplier State Controller",
"item.extendedae_plus.entity_speed_card": "Entity Acceleration Card",
"item.extendedae_plus.entity_speed_card.x1": "§k§l?#@§r§8Should not be stored in §k§l%§r real §centity §k&0%§r speed §k§l*§r cards§k§l...§r",
"item.extendedae_plus.entity_speed_card.x2": "Entity Acceleration Card (x2)",
"item.extendedae_plus.entity_speed_card.x4": "Entity Acceleration Card (x4)",
"item.extendedae_plus.entity_speed_card.x8": "Entity Acceleration Card (x8)",
@ -53,7 +54,14 @@
"extendedae_plus.screen.reload_mapping_fail": "Overloading mapping failed: %s",
"extendedae_plus.screen.add_mapping": "Add Mapping",
"extendedae_plus.screen.delete_mapping": "Delete Mapping",
"extendedae_plus.screen.cn_name": "Chinese Name",
"extendedae_plus.screen.upload.enter_search_key": "Please enter a search keyword before adding a mapping",
"extendedae_plus.screen.upload.enter_name": "Please enter a name",
"extendedae_plus.screen.upload.mapping_added": "Mapping added/updated: %s -> %s",
"extendedae_plus.screen.upload.mapping_failed": "Failed to write mapping",
"extendedae_plus.screen.upload.enter_name_delete": "Please enter a name before deleting a mapping",
"extendedae_plus.screen.upload.mapping_deleted": "Deleted %d mapping(s), name = %s",
"extendedae_plus.screen.upload.mapping_not_found": "No mapping found for name '%s'",
"extendedae_plus.screen.upload.name": "Mapping Name",
"extendedae_plus.button.choose_provider": "Upload Pattern",
"extendedae_plus.pattern.hovertext.player": "Encoded by %s",

View File

@ -54,7 +54,14 @@
"extendedae_plus.screen.reload_mapping_fail": "重载映射失败: %s",
"extendedae_plus.screen.add_mapping": "增加映射",
"extendedae_plus.screen.delete_mapping": "删除映射",
"extendedae_plus.screen.cn_name": "中文名",
"extendedae_plus.screen.upload.enter_search_key": "请输入搜索关键字后再添加映射",
"extendedae_plus.screen.upload.enter_name": "请输入名称",
"extendedae_plus.screen.upload.mapping_added": "已添加/更新映射: %s -> %s",
"extendedae_plus.screen.upload.mapping_failed": "写入映射失败",
"extendedae_plus.screen.upload.enter_name_delete": "请输入名称后再删除映射",
"extendedae_plus.screen.upload.mapping_deleted": "已删除 %d 条映射,名称 = %s",
"extendedae_plus.screen.upload.mapping_not_found": "未找到名称为 '%s' 的映射",
"extendedae_plus.screen.upload.name": "映射名",
"extendedae_plus.button.choose_provider":"上传样板",
"extendedae_plus.pattern.hovertext.player": "由 %s 编码",