🌎 Global Actions & Bulk Toggles
| Parameter | Specification |
|---|---|
| Component Class | net.instantgratification.collapsiblegamerules.ui.GlobalActionsRuleEntry |
| List Position | Index 0 (Always pinned at the top of RuleList) |
| Left Action Button | [ Expand All ] (gui.collapsible-game-rules.expand_all) |
| Right Action Button | [ Collapse All ] (gui.collapsible-game-rules.collapse_all) |
| Left Center Position | this.getX() + this.getWidth() / 4 |
| Right Center Position | this.getX() + 3 * this.getWidth() / 4 |
| Hover Feedback Color | 0x22FFFFFF (Applied to hovered half) |
| Bottom Separator Line | 0x44AAAAAA |
| Click Audio Feedback | SoundEvents.UI_BUTTON_CLICK (1.0F) |
📖 Overview
When managing modpacks with hundreds of game rules, expanding or collapsing categories one by one can become repetitive.
Global Actions introduces a dual-button header permanently anchored at Index 0 of the Game Rules screen, providing instant, one-click bulk expansion and collapse across every registered category.
🎨 Visual Layout & Split-Button Design
The header divides the screen width into two distinct interactive zones:
┌─────────────────────────────────────────────────────────────────────────────┐
│ ◄──────────────── Left Half ───────────────►◄────────────── Right Half ───► │
│ [ Expand All ] [ Collapse All ] │
│ ─────────────────────────────────────────────────────────────────────────── │
└─────────────────────────────────────────────────────────────────────────────┘- Left Zone (
mouseX < getX() + getWidth() / 2): TriggersexpandAll. - Right Zone (
mouseX >= getX() + getWidth() / 2): TriggerscollapseAll. - Hover State: Highlights only the hovered half with a
0x22FFFFFFbackground tint and alters the text color to0xFFFFFFAA.
⚙️ Technical Mechanics
1. Pinned Insertion at Index 0
During updateVisibleEntries() in AbstractGameRulesScreenRuleListMixin, the global actions header is injected before any category or rule entries:
if (!this.collapsible_game_rules$allEntries.isEmpty()) {
this.addEntry(new GlobalActionsRuleEntry(
() -> {
List<String> allKeys = this.collapsible_game_rules$allEntries.stream()
.filter(e -> e instanceof AbstractGameRulesScreen.CategoryRuleEntry)
.map(e -> {
Component lbl = ((CategoryRuleEntryAccessor) e).collapsible_game_rules$getLabel();
if (lbl.getContents() instanceof TranslatableContents translatable) {
return translatable.getKey();
}
return lbl.getString();
})
.toList();
GameRuleStateConfig.expandAll(allKeys);
this.collapsible_game_rules$updateVisibleEntries();
},
() -> {
GameRuleStateConfig.collapseAll();
this.collapsible_game_rules$updateVisibleEntries();
}
));
}2. Category Key Extraction
To expand all categories, the stream pipeline extracts every category's unique identifier:
- Filters entries to find
CategoryRuleEntryinstances. - Accesses the category label via
CategoryRuleEntryAccessor. - If the label contains
TranslatableContents, extracts the localization key (e.g.gamerule.category.spawning). - Falls back to raw literal strings if unlocalized.
- Collects keys into an immutable Java 25 list (
.toList()) and passes them toGameRuleStateConfig.expandAll(allKeys).
3. Click Dispatching Logic
In GlobalActionsRuleEntry.mouseClicked(MouseButtonEvent event, boolean doubleClick):
if (event.button() == 0 || event.button() == 1) {
double mouseX = event.x();
if (mouseX < this.getX() + this.getWidth() / 2.0) {
this.expandAll.run();
} else {
this.collapseAll.run();
}
Minecraft.getInstance().getSoundManager().play(
SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)
);
return true;
}🌐 Localization Keys
The action titles are fully localized via src/main/resources/assets/collapsiblegamerules/lang/en_us.json:
{
"gui.collapsible-game-rules.expand_all": "Expand All",
"gui.collapsible-game-rules.collapse_all": "Collapse All"
}