55import com .gregtechceu .gtceu .api .capability .GTCapabilityHelper ;
66import com .gregtechceu .gtceu .api .capability .IElectricItem ;
77import com .gregtechceu .gtceu .api .cover .filter .ItemFilter ;
8- import com .gregtechceu .gtceu .api .gui . GuiTextures ;
9- import com .gregtechceu .gtceu .api .gui . UITemplate ;
8+ import com .gregtechceu .gtceu .api .cover . filter . SimpleItemFilter ;
9+ import com .gregtechceu .gtceu .api .cover . filter . TagItemFilter ;
1010import com .gregtechceu .gtceu .api .gui .widget .EnumSelectorWidget ;
1111import com .gregtechceu .gtceu .api .item .ComponentItem ;
1212import com .gregtechceu .gtceu .api .item .IComponentItem ;
1313import com .gregtechceu .gtceu .api .item .component .IAddInformation ;
1414import com .gregtechceu .gtceu .api .item .component .IInteractionItem ;
1515import com .gregtechceu .gtceu .api .item .component .IItemLifeCycle ;
16- import com .gregtechceu .gtceu .api .item . component . IItemUIFactory ;
16+ import com .gregtechceu .gtceu .api .mui . IItemUIHolder ;
1717import com .gregtechceu .gtceu .common .data .GTItems ;
18+ import com .gregtechceu .gtceu .common .mui .GTGuiTextures ;
1819
19- import com .lowdragmc .lowdraglib .gui .factory .HeldItemUIFactory ;
20- import com .lowdragmc .lowdraglib .gui .modular .ModularUI ;
2120import com .lowdragmc .lowdraglib .gui .texture .IGuiTexture ;
2221import com .lowdragmc .lowdraglib .gui .texture .ResourceTexture ;
23- import com .lowdragmc .lowdraglib .gui .widget .LabelWidget ;
24- import com .lowdragmc .lowdraglib .gui .widget .Widget ;
2522
2623import net .minecraft .nbt .CompoundTag ;
2724import net .minecraft .network .chat .Component ;
4441import net .minecraftforge .event .entity .player .PlayerXpEvent ;
4542import net .minecraftforge .eventbus .api .SubscribeEvent ;
4643
44+ import brachy .modularui .api .drawable .IKey ;
45+ import brachy .modularui .drawable .ItemDrawable ;
46+ import brachy .modularui .factory .PlayerInventoryGuiData ;
47+ import brachy .modularui .factory .UIFactories ;
48+ import brachy .modularui .screen .ModularPanel ;
49+ import brachy .modularui .screen .RichTooltip ;
50+ import brachy .modularui .screen .UISettings ;
51+ import brachy .modularui .value .sync .*;
52+ import brachy .modularui .widget .ParentWidget ;
53+ import brachy .modularui .widgets .CycleButtonWidget ;
54+ import brachy .modularui .widgets .PagedWidget ;
55+ import brachy .modularui .widgets .SlotGroupWidget ;
56+ import brachy .modularui .widgets .ToggleButton ;
57+ import brachy .modularui .widgets .layout .Flow ;
58+ import brachy .modularui .widgets .layout .Grid ;
59+ import brachy .modularui .widgets .slot .ModularSlot ;
60+ import brachy .modularui .widgets .slot .PhantomItemSlot ;
61+ import brachy .modularui .widgets .textfield .TextFieldWidget ;
4762import com .tterrag .registrate .util .entry .ItemEntry ;
4863import org .jetbrains .annotations .NotNull ;
4964import org .jetbrains .annotations .Nullable ;
50- import oshi .util .tuples .Triplet ;
5165import top .theillusivec4 .curios .api .CuriosApi ;
5266
53- import java .util .*;
67+ import java .util .EnumMap ;
68+ import java .util .List ;
69+ import java .util .Map ;
5470
55- public class ItemMagnetBehavior implements IInteractionItem , IItemLifeCycle , IAddInformation , IItemUIFactory {
71+ public class ItemMagnetBehavior implements IInteractionItem , IItemLifeCycle , IAddInformation , IItemUIHolder {
5672
5773 public static final String FILTER_TAG = "MagnetFilter" ;
5874 public static final String FILTER_ORDINAL_TAG = "FilterOrdinal" ;
@@ -67,56 +83,119 @@ public ItemMagnetBehavior(int range) {
6783 }
6884
6985 @ Override
70- public ModularUI createUI (HeldItemUIFactory .HeldItemHolder holder , Player entityPlayer ) {
71- var held = holder .getHeld ();
72- var tag = held .getOrCreateTag ();
73- var selected = Filter .get (tag .getInt (FILTER_ORDINAL_TAG ));
74- var widgets = new HashSet <Triplet <Filter , Widget , Widget >>();
75- var stacks = new HashMap <Filter , ItemStack >();
76- var ui = new ModularUI (176 , 157 , holder , entityPlayer )
77- .background (GuiTextures .BACKGROUND )
78- .widget (new EnumSelectorWidget <>(146 , 5 , 20 , 20 ,
79- Filter .values (), selected , (val ) -> updateSelection (tag , val , widgets )))
80- .widget (UITemplate .bindPlayerInventory (entityPlayer .getInventory (), GuiTextures .SLOT , 7 , 75 , true ));
81- for (var f : Filter .values ()) {
82- var stack = f .getFilter (held );
83- stack .setTag (tag .getCompound (FILTER_TAG ).copy ());
84- stacks .put (f , stack );
85- var description = new LabelWidget (5 , 5 , stack .getDescriptionId ());
86- var config = ItemFilter
87- .loadFilter (stack )
88- .openConfigurator ((176 - 80 ) / 2 , (60 - 55 ) / 2 + 15 );
89- var visible = f == selected ;
90- description .setVisible (visible );
91- config .setVisible (visible );
92- widgets .add (new Triplet <>(f , description , config ));
93- ui .widget (description );
94- ui .widget (config );
86+ public ModularPanel <?> buildUI (PlayerInventoryGuiData <?> data , PanelSyncManager syncManager , UISettings settings ) {
87+ ItemStack held = data .getUsedItemStack ();
88+ CompoundTag heldTag = held .getOrCreateTag ();
89+
90+ Filter selectedFilter = Filter .get (heldTag .getInt (FILTER_ORDINAL_TAG ));
91+ Map <Filter , ItemStack > stacks = new EnumMap <>(Filter .class );
92+ CompoundTag startFilterTag = heldTag .getCompound (FILTER_TAG ).copy ();
93+ for (Filter filter : Filter .values ()) {
94+ ItemStack stack = filter .getFilter (held );
95+ stack .setTag (startFilterTag .copy ());
96+ stacks .put (filter , stack );
9597 }
96- ui .registerCloseListener (() -> {
97- var selection = Filter .get (tag .getInt (FILTER_ORDINAL_TAG ));
98- tag .put (FILTER_TAG , stacks .get (selection ).getOrCreateTag ());
98+
99+ EnumSyncValue <Filter > filterSync = new EnumSyncValue <>(Filter .class ,
100+ () -> Filter .get (data .getUsedItemStack ().getOrCreateTag ().getInt (FILTER_ORDINAL_TAG )),
101+ filter -> data .getUsedItemStack ().getOrCreateTag ().putInt (FILTER_ORDINAL_TAG , filter .ordinal ()));
102+
103+ PagedWidget <?> pages = new PagedWidget <>()
104+ .left ((176 - 80 ) / 2 )
105+ .top ((60 - 55 ) / 2 + 15 )
106+ .size (80 , 55 )
107+ .initialPage (selectedFilter .ordinal ())
108+ .addPage (createSimpleFilterPage ((SimpleItemFilter ) ItemFilter .loadFilter (stacks .get (Filter .SIMPLE ))))
109+ .addPage (createTagFilterPage ((TagItemFilter ) ItemFilter .loadFilter (stacks .get (Filter .TAG ))));
110+ pages .onUpdateListener (widget -> {
111+ int selected = filterSync .getIntValue ();
112+ if (selected != widget .getCurrentPageIndex ()) {
113+ widget .setPage (selected );
114+ }
99115 });
100- return ui ;
101- }
102116
103- private void updateSelection (CompoundTag tag , Filter filter , Collection <Triplet <Filter , Widget , Widget >> widgets ) {
104- tag .putInt (FILTER_ORDINAL_TAG , filter .ordinal ());
105- widgets .forEach (tri -> {
106- var visible = tri .getA () == filter ;
107- tri .getB ().setVisible (visible );
108- tri .getC ().setVisible (visible );
117+ syncManager .addCloseListener (player -> {
118+ ItemStack stack = data .getUsedItemStack ();
119+ CompoundTag tag = stack .getOrCreateTag ();
120+ Filter selected = Filter .get (tag .getInt (FILTER_ORDINAL_TAG ));
121+ tag .put (FILTER_TAG , stacks .get (selected ).getOrCreateTag ().copy ());
109122 });
123+
124+ return new ModularPanel <>("item_magnet" )
125+ .size (176 , 157 )
126+ .background (GTGuiTextures .BACKGROUND )
127+ .child (IKey .dynamic (() -> Component .translatable (filterSync .getValue ().getTooltip ()))
128+ .asWidget ()
129+ .left (5 )
130+ .top (5 ))
131+ .child (new CycleButtonWidget ()
132+ .left (146 )
133+ .top (5 )
134+ .size (20 )
135+ .value (filterSync )
136+ .stateCount (Filter .values ().length )
137+ .stateOverlay (Filter .SIMPLE , new ItemDrawable (GTItems .ITEM_FILTER .asItem ()))
138+ .stateOverlay (Filter .TAG , new ItemDrawable (GTItems .TAG_FILTER .asItem ()))
139+ .tooltipBuilder (r -> r .addLine (IKey .dynamic (
140+ () -> Component .translatable (filterSync .getValue ().getTooltip ())))))
141+ .child (pages )
142+ .child (SlotGroupWidget .playerInventory (false ).left (7 ).top (75 ).disableSortButtons ());
143+ }
144+
145+ private ParentWidget <?> createSimpleFilterPage (SimpleItemFilter filter ) {
146+ SimpleItemFilter .FilterItemStackHandler handler = new SimpleItemFilter .FilterItemStackHandler (filter );
147+
148+ Grid filterGrid = new Grid ()
149+ .coverChildren ()
150+ .mapTo (3 , 9 , i -> new PhantomItemSlot ()
151+ .size (16 )
152+ .syncHandler (new PhantomItemSlotSyncHandler (new ModularSlot (handler , i )
153+ .changeListener ((stack , amount , client , init ) -> handler .setStackInSlot (i , stack ))
154+ .ignoreMaxStackSize (true ).accessibility (true , false ))));
155+
156+ BooleanSyncValue blacklist = new BooleanSyncValue (filter ::isBlackList , filter ::setBlackList );
157+
158+ BooleanSyncValue ignoreNBT = new BooleanSyncValue (filter ::isIgnoreNbt , filter ::setIgnoreNbt );
159+
160+ Flow filterButtons = Flow .col ()
161+ .coverChildren ()
162+ .child (new ToggleButton ().stateBackground (GTGuiTextures .BUTTON_BLACKLIST ).value (blacklist ))
163+ .child (new ToggleButton ().stateBackground (GTGuiTextures .BUTTON_IGNORE_NBT ).value (ignoreNBT ));
164+
165+ return new ParentWidget <>()
166+ .size (80 , 55 )
167+ .child (filterGrid .left (0 ).top (0 ))
168+ .child (filterButtons .left (58 ).top (0 ));
169+ }
170+
171+ private ParentWidget <?> createTagFilterPage (TagItemFilter filter ) {
172+ StringSyncValue filterString = new StringSyncValue (filter ::getFilterString , filter ::setFilterString );
173+ RichTooltip infoTooltip = new RichTooltip ().add ("cover.tag_filter.info" );
174+
175+ return new ParentWidget <>()
176+ .size (80 , 55 )
177+ .child (Flow .row ()
178+ .coverChildren ()
179+ .left (0 )
180+ .top (18 )
181+ .child (new TextFieldWidget ()
182+ .width (62 )
183+ .value (filterString ))
184+ .child (GTGuiTextures .INFO .asWidget ()
185+ .size (16 )
186+ .tooltip (infoTooltip )));
110187 }
111188
112189 @ Override
113190 public InteractionResultHolder <ItemStack > use (Item item , Level world , @ NotNull Player player ,
114191 InteractionHand hand ) {
115- if (!player .level ().isClientSide && player .isShiftKeyDown ()) {
116- player .displayClientMessage (Component .translatable (toggleActive (player .getItemInHand (hand )) ?
117- "behavior.item_magnet.enabled" : "behavior.item_magnet.disabled" ), true );
118- } else {
119- IItemUIFactory .super .use (item , world , player , hand );
192+ if (!player .level ().isClientSide ) {
193+ if (player .isShiftKeyDown ()) {
194+ player .displayClientMessage (Component .translatable (toggleActive (player .getItemInHand (hand )) ?
195+ "behavior.item_magnet.enabled" : "behavior.item_magnet.disabled" ), true );
196+ } else {
197+ UIFactories .playerInventory ().openFromHand (player , hand );
198+ }
120199 }
121200 return InteractionResultHolder .pass (player .getItemInHand (hand ));
122201 }
0 commit comments