Skip to content

Commit 558eaea

Browse files
committed
make adding bogo sort buttons much easier
1 parent 666744f commit 558eaea

6 files changed

Lines changed: 244 additions & 27 deletions

File tree

src/main/java/com/cleanroommc/modularui/test/TestTile.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import com.cleanroommc.modularui.widgets.ScrollingTextWidget;
5151
import com.cleanroommc.modularui.widgets.SliderWidget;
5252
import com.cleanroommc.modularui.widgets.SlotGroupWidget;
53-
import com.cleanroommc.modularui.widgets.SortButtons;
5453
import com.cleanroommc.modularui.widgets.ToggleButton;
5554
import com.cleanroommc.modularui.widgets.layout.Column;
5655
import com.cleanroommc.modularui.widgets.layout.Flow;
@@ -347,25 +346,25 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager syncManager, UI
347346
.childPadding(2)
348347
//.child(SlotGroupWidget.playerInventory().left(0))
349348
.child(SlotGroupWidget.builder()
350-
.matrix("III", "III", "III")
351-
.key('I', index -> {
352-
// 4 is the middle slot with a negative priority -> shift click prioritises middle slot
353-
if (index == 4) {
354-
return new ItemSlot().slot(SyncHandlers.itemSlot(this.bigInventory, index).singletonSlotGroup(-100));
355-
}
356-
return new ItemSlot().slot(SyncHandlers.itemSlot(this.bigInventory, index).slotGroup("item_inv"));
357-
})
358-
.build().name("9 slot inv")
349+
.matrix("III", "III", "III")
350+
.key('I', index -> {
351+
// 4 is the middle slot with a negative priority -> shift click prioritises middle slot
352+
if (index == 4) {
353+
return new ItemSlot().slot(SyncHandlers.itemSlot(this.bigInventory, index).singletonSlotGroup(-100));
354+
}
355+
return new ItemSlot().slot(SyncHandlers.itemSlot(this.bigInventory, index).slotGroup("item_inv"));
356+
})
357+
.build().name("9 slot inv")
358+
.placeSortButtonsTopRightVertical()
359359
//.marginBottom(2)
360-
.child(new SortButtons()
361-
.slotGroup("item_inv")
362-
.right(0).bottomRelOffset(1f, 1)))
360+
)
363361
.child(SlotGroupWidget.builder()
364362
.row("FII")
365363
.row("FII")
366364
.key('F', index -> new FluidSlot().syncHandler("mixer_fluids", index))
367365
.key('I', index -> ItemSlot.create(index >= 2).slot(new ModularSlot(this.mixerItems, index).slotGroup("mixer_items")))
368-
.build().name("mixer inv"))
366+
.build().name("mixer inv")
367+
.disableSortButtons())
369368
.child(new Row()
370369
.coverChildrenHeight()
371370
.child(new CycleButtonWidget()

src/main/java/com/cleanroommc/modularui/value/sync/ISyncRegistrar.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.cleanroommc.modularui.api.IPanelHandler;
44
import com.cleanroommc.modularui.api.ISyncedAction;
55
import com.cleanroommc.modularui.widgets.slot.ModularSlot;
6+
import com.cleanroommc.modularui.widgets.slot.PlayerSlotGroup;
67
import com.cleanroommc.modularui.widgets.slot.SlotGroup;
78

89
import net.minecraft.entity.player.EntityPlayer;
@@ -82,16 +83,15 @@ default S bindPlayerInventory(EntityPlayer player) {
8283
}
8384

8485
default S bindPlayerInventory(EntityPlayer player, @NotNull PanelSyncManager.SlotFunction slotFunction) {
85-
if (getSlotGroup(ModularSyncManager.PLAYER_INVENTORY) != null) {
86+
if (getSlotGroup(PlayerSlotGroup.NAME) != null) {
8687
throw new IllegalStateException("The player slot group is already registered!");
8788
}
8889
PlayerMainInvWrapper playerInventory = new PlayerMainInvWrapper(player.inventory);
8990
String key = "player";
9091
for (int i = 0; i < 36; i++) {
91-
itemSlot(key, i, slotFunction.apply(playerInventory, i).slotGroup(ModularSyncManager.PLAYER_INVENTORY));
92+
itemSlot(key, i, slotFunction.apply(playerInventory, i).slotGroup(PlayerSlotGroup.NAME));
9293
}
93-
// player inv sorting is handled by bogosorter
94-
registerSlotGroup(new SlotGroup(ModularSyncManager.PLAYER_INVENTORY, 9, SlotGroup.PLAYER_INVENTORY_PRIO, true).setAllowSorting(false));
94+
registerSlotGroup(new PlayerSlotGroup(PlayerSlotGroup.NAME));
9595
return (S) this;
9696
}
9797

src/main/java/com/cleanroommc/modularui/widgets/SlotGroupWidget.java

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.cleanroommc.modularui.api.widget.IWidget;
55
import com.cleanroommc.modularui.widget.ParentWidget;
66
import com.cleanroommc.modularui.widgets.slot.ItemSlot;
7+
import com.cleanroommc.modularui.widgets.slot.SlotGroup;
78

89
import it.unimi.dsi.fastutil.chars.Char2IntMap;
910
import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap;
@@ -13,6 +14,7 @@
1314
import java.util.ArrayList;
1415
import java.util.Collections;
1516
import java.util.List;
17+
import java.util.function.Consumer;
1618
import java.util.function.IntFunction;
1719

1820
public class SlotGroupWidget extends ParentWidget<SlotGroupWidget> {
@@ -57,15 +59,66 @@ public static SlotGroupWidget playerInventory(SlotConsumer slotConsumer) {
5759
return slotGroupWidget;
5860
}
5961

60-
public interface SlotConsumer {
62+
private String slotGroupName;
63+
private SlotGroup slotGroup;
64+
private boolean sortButtonsAdded = false;
65+
private Consumer<SortButtons> sortButtonsEditor;
6166

62-
ItemSlot apply(int index, ItemSlot widgetSlot);
67+
@Override
68+
public void onInit() {
69+
super.onInit();
70+
if (!this.sortButtonsAdded) {
71+
SortButtons sb = new SortButtons();
72+
if (this.sortButtonsEditor == null) placeSortButtonsTopRightHorizontal();
73+
if (getName() != null) {
74+
sb.name(getName() + "_sorter_buttons");
75+
}
76+
child(sb);
77+
}
78+
}
79+
80+
@Override
81+
public void afterInit() {
82+
super.afterInit();
83+
if (this.slotGroup != null) {
84+
for (IWidget widget : getChildren()) {
85+
if (widget instanceof ItemSlot itemSlot) {
86+
itemSlot.getSlot().slotGroup(this.slotGroup);
87+
}
88+
}
89+
} else if (this.slotGroupName != null) {
90+
for (IWidget widget : getChildren()) {
91+
if (widget instanceof ItemSlot itemSlot) {
92+
itemSlot.getSlot().slotGroup(this.slotGroupName);
93+
}
94+
}
95+
}
6396
}
6497

65-
private String slotsKeyName;
98+
@Override
99+
protected void onChildAdd(IWidget child) {
100+
super.onChildAdd(child);
101+
if (child instanceof SortButtons sortButtons) {
102+
this.sortButtonsAdded = true;
103+
if (sortButtons.getSlotGroup() == null && sortButtons.getSlotGroupName() == null) {
104+
if (this.slotGroup != null) {
105+
sortButtons.slotGroup(this.slotGroup);
106+
} else if (this.slotGroupName != null) {
107+
sortButtons.slotGroup(this.slotGroupName);
108+
}
109+
}
110+
if (this.sortButtonsEditor != null) {
111+
this.sortButtonsEditor.accept(sortButtons);
112+
}
113+
}
114+
}
115+
116+
public SlotGroupWidget disableSortButtons() {
117+
this.sortButtonsAdded = true;
118+
return this;
119+
}
66120

67121
public void setSlotsSynced(String name) {
68-
this.slotsKeyName = name;
69122
int i = 0;
70123
for (IWidget widget : getChildren()) {
71124
if (widget instanceof ISynced<?> synced) {
@@ -75,15 +128,59 @@ public void setSlotsSynced(String name) {
75128
}
76129
}
77130

131+
public SlotGroupWidget editSortButtons(Consumer<SortButtons> sortButtonsEditor) {
132+
this.sortButtonsEditor = sortButtonsEditor;
133+
return this;
134+
}
135+
136+
public SlotGroupWidget placeSortButtonsTopRightVertical() {
137+
return placeSortButtonsTopRightVertical(this.sortButtonsEditor);
138+
}
139+
140+
public SlotGroupWidget placeSortButtonsTopRightHorizontal() {
141+
return placeSortButtonsTopRightHorizontal(this.sortButtonsEditor);
142+
}
143+
144+
public SlotGroupWidget placeSortButtonsTopRightVertical(Consumer<SortButtons> additionalEdits) {
145+
return editSortButtons(sb -> {
146+
sb.vertical().leftRelOffset(1f, 1).top(0);
147+
if (additionalEdits != null) additionalEdits.accept(sb);
148+
});
149+
}
150+
151+
public SlotGroupWidget placeSortButtonsTopRightHorizontal(Consumer<SortButtons> additionalEdits) {
152+
return editSortButtons(sb -> {
153+
sb.horizontal().bottomRelOffset(1f, 1).right(0);
154+
if (additionalEdits != null) additionalEdits.accept(sb);
155+
});
156+
}
157+
158+
public SlotGroupWidget slotGroup(String slotGroupName) {
159+
this.slotGroupName = slotGroupName;
160+
return this;
161+
}
162+
163+
public SlotGroupWidget slotGroup(SlotGroup slotGroup) {
164+
this.slotGroup = slotGroup;
165+
return this;
166+
}
167+
78168
public static Builder builder() {
79169
return new Builder();
80170
}
81171

172+
public interface SlotConsumer {
173+
174+
ItemSlot apply(int index, ItemSlot widgetSlot);
175+
}
176+
82177
public static class Builder {
83178

84179
private String syncKey;
85180
private final List<String> matrix = new ArrayList<>();
86181
private final Char2ObjectMap<Object> keys = new Char2ObjectOpenHashMap<>();
182+
private String slotGroupName;
183+
private SlotGroup slotGroup;
87184

88185
private Builder() {
89186
this.keys.put(' ', null);
@@ -115,8 +212,20 @@ public Builder key(char c, IntFunction<IWidget> widget) {
115212
return this;
116213
}
117214

215+
public Builder slotGroup(String slotGroupName) {
216+
this.slotGroupName = slotGroupName;
217+
return this;
218+
}
219+
220+
public Builder slotGroup(SlotGroup slotGroup) {
221+
this.slotGroup = slotGroup;
222+
return this;
223+
}
224+
118225
public SlotGroupWidget build() {
119-
SlotGroupWidget slotGroupWidget = new SlotGroupWidget();
226+
SlotGroupWidget slotGroupWidget = new SlotGroupWidget()
227+
.slotGroup(this.slotGroupName)
228+
.slotGroup(this.slotGroup);
120229
Char2IntMap charCount = new Char2IntOpenHashMap();
121230
int x = 0, y = 0, maxWidth = 0;
122231
int syncId = 0;
@@ -129,6 +238,10 @@ public SlotGroupWidget build() {
129238
IWidget widget;
130239
if (o instanceof IWidget iWidget) {
131240
widget = iWidget;
241+
if (count > 0) {
242+
throw new IllegalArgumentException("A widget can only exist once in the widget tree, but the char '" + c +
243+
"' exists more than once in this slot group widget and it has a static widget supplied.");
244+
}
132245
} else if (o instanceof IntFunction<?> function) {
133246
widget = (IWidget) function.apply(count);
134247
} else {

src/main/java/com/cleanroommc/modularui/widgets/SortButtons.java

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,39 @@
22

33
import com.cleanroommc.modularui.ModularUI;
44
import com.cleanroommc.modularui.api.widget.IWidget;
5+
import com.cleanroommc.modularui.drawable.GuiTextures;
6+
import com.cleanroommc.modularui.drawable.UITexture;
57
import com.cleanroommc.modularui.network.NetworkUtils;
68
import com.cleanroommc.modularui.widget.Widget;
9+
import com.cleanroommc.modularui.widget.WidgetTree;
10+
import com.cleanroommc.modularui.widgets.slot.ItemSlot;
711
import com.cleanroommc.modularui.widgets.slot.SlotGroup;
812
import com.cleanroommc.bogosorter.api.IBogoSortAPI;
913
import com.cleanroommc.bogosorter.common.sort.ButtonHandler;
1014

15+
import net.minecraft.inventory.Slot;
16+
1117
import org.jetbrains.annotations.NotNull;
1218

1319
import java.util.Arrays;
1420
import java.util.List;
1521

1622
public class SortButtons extends Widget<SortButtons> {
1723

24+
public static final UITexture HOVER_SORT_OVERLAY;
25+
public static final UITexture HOVER_SETTINGS_OVERLAY;
26+
27+
static {
28+
if (NetworkUtils.isDedicatedClient() && ModularUI.Mods.BOGOSORTER.isLoaded()) {
29+
HOVER_SORT_OVERLAY = ButtonHandler.BUTTON_SORT.withColorOverride(16777120);
30+
HOVER_SETTINGS_OVERLAY = ButtonHandler.BUTTON_SETTINGS.withColorOverride(16777120);
31+
} else {
32+
// any non null value
33+
HOVER_SORT_OVERLAY = GuiTextures.BLOCK;
34+
HOVER_SETTINGS_OVERLAY = GuiTextures.BLOCK;
35+
}
36+
}
37+
1838
private String slotGroupName;
1939
private SlotGroup slotGroup;
2040

@@ -28,14 +48,16 @@ public SortButtons() {
2848
this.sortButton.size(10).pos(0, 0)
2949
.background(ButtonHandler.BUTTON_BACKGROUND)
3050
.overlay(ButtonHandler.BUTTON_SORT)
51+
.hoverOverlay(HOVER_SORT_OVERLAY)
3152
.disableHoverBackground()
3253
.onMousePressed(mouseButton -> {
33-
IBogoSortAPI.getInstance().sortSlotGroup(this.slotGroup.getSlots().get(0));
54+
sort();
3455
return true;
3556
});
3657
this.settingsButton.size(10)
3758
.background(ButtonHandler.BUTTON_BACKGROUND)
3859
.overlay(ButtonHandler.BUTTON_SETTINGS)
60+
.hoverOverlay(HOVER_SETTINGS_OVERLAY)
3961
.disableHoverBackground()
4062
.onMousePressed(mouseButton -> {
4163
IBogoSortAPI.getInstance().openConfigGui();
@@ -44,12 +66,42 @@ public SortButtons() {
4466
}
4567
}
4668

69+
public void sort() {
70+
SlotGroup slotGroup = findFirstSlotGroup();
71+
if (slotGroup != null) {
72+
Slot slot = slotGroup.getFirstSlotForSorting();
73+
if (slot != null) {
74+
IBogoSortAPI.getInstance().sortSlotGroup(slot);
75+
}
76+
}
77+
}
78+
79+
public SlotGroup findFirstSlotGroup() {
80+
if (!isValid()) return null;
81+
if (this.slotGroup != null) return this.slotGroup;
82+
SlotGroupWidget sgw = findSlotGroupParent();
83+
for (IWidget child : sgw.getChildren()) {
84+
if (child instanceof ItemSlot itemSlot) {
85+
SlotGroup sg = itemSlot.getSlot().getSlotGroup();
86+
if (sg != null && sg.isAllowSorting()) return sg;
87+
}
88+
}
89+
return null;
90+
}
91+
92+
public SlotGroupWidget findSlotGroupParent() {
93+
SlotGroupWidget sgw = WidgetTree.findParent(this, SlotGroupWidget.class);
94+
if (sgw == null) {
95+
throw new IllegalArgumentException("If the sort buttons don't have a SlotGroupWidget above itself in the widget tree, then it needs a slot group or name specified. Both were not found.");
96+
}
97+
return sgw;
98+
}
99+
47100
@Override
48101
public void onInit() {
49102
super.onInit();
50-
this.slotGroup = getScreen().getContainer().validateSlotGroup(getPanel().getName(), this.slotGroupName, this.slotGroup);
51-
if (!this.slotGroup.isAllowSorting()) {
52-
throw new IllegalStateException("Slot group can't be sorted!");
103+
if (this.slotGroup != null || this.slotGroupName != null) {
104+
this.slotGroup = getScreen().getContainer().validateSlotGroup(getPanel().getName(), this.slotGroupName, this.slotGroup);
53105
}
54106
if (this.horizontal) {
55107
size(20, 10);
@@ -60,6 +112,16 @@ public void onInit() {
60112
}
61113
}
62114

115+
@Override
116+
public void beforeResize(boolean onOpen) {
117+
super.beforeResize(onOpen);
118+
// we need to do this after init to make sure the slots are also initialized
119+
if (findFirstSlotGroup() == null) {
120+
// silently hide buttons if no slot group is found
121+
setEnabled(false);
122+
}
123+
}
124+
63125
@NotNull
64126
@Override
65127
public List<IWidget> getChildren() {

0 commit comments

Comments
 (0)