aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/common/gui
diff options
context:
space:
mode:
authorBlueWeabo <ilia.iliev2005@gmail.com>2024-01-06 00:41:00 +0200
committerGitHub <noreply@github.com>2024-01-05 23:41:00 +0100
commit02bedd5c0a96a654c6692edd1b7f2765fd9c46b4 (patch)
tree57dd675f658dda3caba629f15d4708247e702f88 /src/main/java/gregtech/common/gui
parentfc63cee4c0284635c601889ce49a892cf73082ff (diff)
downloadGT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.tar.gz
GT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.tar.bz2
GT5-Unofficial-02bedd5c0a96a654c6692edd1b7f2765fd9c46b4.zip
Merge MuTEMaster into Master (#2431)
* Fix MuTE structure check and power intake (#1975) * Fixed casing lists being cleared for every checked structure piece * Fixed power being taken from any side BUT the right one * ACP Structure - Rebased (#1978) * Added 2nd structure tier to ACR and make complex parallels depend on it * Added tier 3 to 8 structure pieces to ACR * Added disclaimer * Renamed ACR to ACP because MV CR already is named ACR * Add autopush functionality to MuTE (#1976) - fix conflict * Working auto push * Revert wildcard import * Addresssed reviews * Fix reference issue * Minor MuTE fixes - Rebased (#1983) * Fixed ACP recipe map * Fixed controller side being used instead of part side when accessing tanks * Fix Structure not forming (#1984) * fix cables not connecting * fix structure and don't store controller * Add missing tooltips (#1981) * Add missing tooltips * Address blue's change * Distillation MuTE (#1989) * Started work on DT MuTE * Renamed methods so they also make sense when used horizontally * MuTE Upgrade Casings - Rebased (#1988) - fix conflict * Added cleanroom upgrade casing * Added inventory and tank upgrades * Added tooltips to mute casings * Added power upgrades * Set player UUID when placing MuTE * MuTE fixes (#1991) * Fixed pipes not connectable to MuTE casings * Fixed not all things being renamed to ACP * Fix running in obf * fix for real yo * Add a Generic Processing Logic and extract methods - Rebased (#1992) * add a generic processing logic * calculate tier in another method * calculate power logic in another method * Add Layered Coke Foundry (#1995) * Add the Foundry class and call it * Foundry name correction * Buildable stackable structure * Fixed min stacks and added motor casings * checkMachine override for custom checking * Working checkMachine for all stacks, and recipes * Fix getOutputFluids * Change recipe processing to GenericProcessingLogic * Change inventoryName to protected for override * Override checkRecipe for multis that consume EU * Rename class and add inner walls to multi * Structure update and other fixes * Fix processing logic being static * MuTE inventory upgrade logic (#2082) * Catch potential NPE * Don't load name when it doesn't exist * Potentially cause weird non-replicatable issue where registry ends up with different key * Use proper block removal method * Validate index before using it * Don't open controller GUI from inventory upgrade * semi-working concept * sync the ID of the inventory upgrade to correctly remove it later * remove unneeded boolean --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * fixed layeredCokeBattery checkMachine to prevent 'already in building state' (#2099) * MuTE casing structure element (#2105) - fix conflict * Added class containing MuTE relevant structure elements * Migrate MuTE to new structure element * Formatting fix * Use int array instead of int hashmap, since its expected these arrays will never get long enough to be faster as hashmap * Delete old code * Cache MuTEs for non-instance specific actions (#2109) * Introduce map of cached TEs, which are used to perform actions that don't require a specific instance of the TE. This prevents constant creation of new TEs * Remove static modifier from map of cached TEs * First Modular Upgrade Casings Implementation (#2142) * Base support for Heater MUCs - Define Heater upgrade casings; - Create the 5 tiers of Heaters; - Add method to increase and decrease count. * Refactor the cache of MUCs in structure - Change the way that each MUC is counted: since there will be several types, the integer that counted heaters is now a hashmap that divides all MUCs based on their type and tier, to be counted separately from each other. * Add Insulator MUC - Add second MUC type (insulator) to test alongside heaters on the Layered Coke Battery. * Fix MUC count reset * Refactor MUC implementation into subclass - Move the new methods and hashmap away from the base classes, and onto a s specific one that won't be used by unrelated multiblocks. * Remove empty lines * Refactor MUC implementations into subclasses * Requested fixes in StackableModularController * Change hashmap keys to an enum * Hashmap getter for load order purposes - Added a getter that generates the default value for the hashmap if it is null, due to problems with load order; * Apply spotless * NotNull annotations * More Additions to MUCs and the LCB (#2215) * Fix old LCB multi name in some locations * Refactor mucMap and override checkRecipe - Refactor mucMap to an array of primitive integers instead of the wrapper type, for ease of use with other methods such as stream; - Override checkRecipe for custom recipe behavior on MUC multis, to be implemented in a future commit; * First implementation of bonuses and MUC requirements - Change EU/t and recipe duration of this multi based on the count of different MUCs in the multi; - Fail the structure check based on the count of each of the allowed MUCs. * Parallel count implementation - Calculate parallels based on the count of base MUCs, the cheapest option amongst the possibilities, in this case heaters; - Added more abstract methods to require specific values from the multi classes. * Fix parallel count and processing - Fixed the handling of parallels by pointing to the corrent maxParallel variable in ProcessingLogic. * Test of parallels with additional amp input * Structure fix for the intended LCB - Changed MUC placements to match what I intended at the beginning, to better test the multi. * One more comment * Remove checkRecipe override * Refactor Item and Fluid to be in separate logic classes (#2178) - fix conflict * basics of inventory logic * mostly working item logic * working nbt saving/loading * fluid handler * FluidSlotHandler WIP * fluid handler mostly working * remove fluid handler from gt5u * prepare for conversion * use correct imports * spotless * more controller logic * spotless * final refactor. migration next * spotless * add more methods to logic classes * convert almost everything to use new Logic * spotless * make mute casing mode an int * allow pump cover to work with FluidInventoryLogic * pumps work * spotless * make item inventory logic work with every item input thing * rework Fluid Inventory Logic to work with all fluid inputs * spotless * address annotation reviews * finish off todos * missed to dos * cleanup Coke oven will get a new GUI when i get to it * address review * prevent npes from ControllerXXXLogic * null checks * remove accidentally added methods * fix missed return * fixes after rebase - fix conflict * Laser Engraver Multi. (#2223) - fix conflict * saving............. * clean up * savin * Small fixes + Adding back stuff, Crashes you and spams logs. * fix stack overflow * Fixes * Fixes --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Add TickableTask (#2216) * Add autopush functionality to MuTE (#1976) * Working auto push * Revert wildcard import * Addresssed reviews * Fix reference issue * MuTE Upgrade Casings (#1988) * Added cleanroom upgrade casing * Added inventory and tank upgrades * Added tooltips to mute casings * Added power upgrades * Set player UUID when placing MuTE * Add a Generic Processing Logic and extract methods (#1992) * add a generic processing logic * calculate tier in another method * calculate power logic in another method * MuTE inventory upgrade logic (#2082) * Catch potential NPE * Don't load name when it doesn't exist * Potentially cause weird non-replicatable issue where registry ends up with different key * Use proper block removal method * Validate index before using it * Don't open controller GUI from inventory upgrade * semi-working concept * sync the ID of the inventory upgrade to correctly remove it later * remove unneeded boolean --------- Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * MuTE casing structure element (#2105) * Added class containing MuTE relevant structure elements * Migrate MuTE to new structure element * Formatting fix * Use int array instead of int hashmap, since its expected these arrays will never get long enough to be faster as hashmap * Delete old code * Refactor Item and Fluid to be in separate logic classes (#2178) * basics of inventory logic * mostly working item logic * working nbt saving/loading * fluid handler * FluidSlotHandler WIP * fluid handler mostly working * remove fluid handler from gt5u * prepare for conversion * use correct imports * spotless * more controller logic * spotless * final refactor. migration next * spotless * add more methods to logic classes * convert almost everything to use new Logic * spotless * make mute casing mode an int * allow pump cover to work with FluidInventoryLogic * pumps work * spotless * make item inventory logic work with every item input thing * rework Fluid Inventory Logic to work with all fluid inputs * spotless * address annotation reviews * finish off todos * missed to dos * cleanup Coke oven will get a new GUI when i get to it * address review * prevent npes from ControllerXXXLogic * null checks * Base work * PollutionTask * move package * Fix generics * Internal -> OverrideOnly * rebase fix * Ducttape addPollution --------- Co-authored-by: Maxim <maxim235@gmx.de> Co-authored-by: BlueWeabo <ilia.iliev2005@gmail.com> Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Rework a bit of ProcessingLogic to fit MuTEs (#2283) - fix conflicts * Add a way to enable or disable the crafting buffer on GPL multiblocks (#2218) * add a way to enable or disable the crafting buffer on GPL multiblocks * don't register the hatch either * fix Refractory Capsule (#2219) * Fix PAs overclocking ulv recipes too much (#2220) * fix PAs overclocking ulv recipes too much * make sure we save the returned value * Fix Digital Tank capacity for Fluid Storage Monitor (#2217) * Fix Digital Tank capacity for Fluid Storage Monitor * Annotations * Blacklist AE2FC drop and packet, and Chisel stones from Recycler (#2222) * Fix recycler blacklist being sensitive to NBT * Blacklist AE2FC drop and packet, and Chisel stones * fix class loader issue * Add detailed logging for ME hatches (#2224) * Fix overclock calculator calculating eu/t use for ulv recipe wrong on certain parallel (#2225) * fix overclock calculator calculating eu/t use for ulv recipe wrong on certain parallel * make formula into its own method * Fix drilling rigs, plants and concrete backfiller to fail with multiple energy hatches (#2227) * max-1-energy-hatch-in-drilling-rigs.-plants-and-concrete-backfiller * spotlessApply (#2228) Co-authored-by: GitHub GTNH Actions <> * revert --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * clear stale crafting input bus list (#2233) * add ability to remove item data and use it for clay (#2229) * Update buildscript (#2232) * Fix server crash with RecipeFilter (#2231) * Fix server crash with RecipeFilter * Make client send filtered machines to server * Use mUniqueIdentifier * Fix a NPE w/ injecting into super/quantum chests (#2234) When simulating an injection, if the stackSize > chest's capacity, it causes a NPE when the internal chest is empty. Also fixes a potential bug when void overflow is set; the chest should return null in such a scenario regardless of simulation/modulation. * Fix lag caused by getRecipeMap for PA (#2236) * Experimental fix to prevent infinite loop in Grid destruction (#2235) Co-authored-by: Firenoo <49818773+firenoo@users.noreply.github.com> * Fix ME Output Bus and Crafting Input Bus overflow when save/load (#2238) * Remove fire display from singleblock generator (#2240) * Fix some output slots allowing insertion (#2230) * fix overlay zfighting by disable depth test (#2226) * Crafting input - Optimize isEmpty check to reduce lag (#2239) * Optimize isEmpty check * rearrage * remove broken hsla recipe (#2241) * Correct PCB Factory Energy Hatch description (#2237) * Correct PCB Factory Energy Hatch description Changes the PCB factory description (the one seen when holding shift) which currently says "Energy Hatches: 1+" I believe this is incorrect and that the correct description is 1-2 energy hatches or 1 TT energy hatch. I believe the PCB factory uses this, which checks for 1-2 or 1 TT: public boolean checkExoticAndNormalEnergyHatches() { if (mExoticEnergyHatches.isEmpty() && mEnergyHatches.isEmpty()) { return false; } if (!mExoticEnergyHatches.isEmpty()) { if (!mEnergyHatches.isEmpty()) { return false; } if (mExoticEnergyHatches.size() != 1) { return false; } } return mEnergyHatches.size() <= 2; } * gradlew spotlessApply * Correct file name on resource pack guide (#2242) * Fix GT_RecipeConstants.Fuel (#2243) * Update text (#2246) * Fix startup tier for fusion NEI (#2249) * Update the conditionals buttons and tooltips on covers to reflect their actual effects (#2244) * Update redstone buttons and tooltips to better reflect actual use * Spotless Apply * Update GT_Cover_FluidRegulator.java * Update GT_Cover_FluidRegulator.java * Typo fix, Icon Improved and interactive blocking ui - Fixed a typo in the world machine - Fixed double button situation for conveyor belts. - There was never any issue, the testing methodology gave me invalid results. - Conveyor behaviour is in line with all the other covers affected by this PR/Branch. - Updated icon for the machine state to be a miniature machine controller cover. - Made the block/allow input section more interactive in order to better reflect the actual effect of these buttons. - In import mode, it actually blocks the machine from outputting from that side. * typos I can't write to save myself sometimes * Better text alignment - Better text alignment * fix typos I swear I can't write to save myself. --------- Co-authored-by: Martin Robertz <dream-master@gmx.net> * Fix Orichalcum and Shadowiron smelting (#2251) * fix orichalcum and shadowiron smelting * add Alduorite and Chrysotile * Fix tier display for Fusion NEI header (#2250) * fix ulv recipes being broken again when under 1 tick calculation is taken (#2254) * change way to fix zfighting (#2253) * Crafting input hatches QoLs (#2200) * Fixes + Detect Inventory Slot Changes * support rename + check for updates * add back onChangeListener + fix npe * ICustomNameObject TileEntity * Fix NPEs * Use IInterfaceTerminalSupport * fix * register * dep * spotless * General Crafting Input Hatch QoL fixes (#2212) * feat: refactor naming && include circuit and catalyst in default name * feat: add 4 more slot to solve my ocd * fix: formatting * feat: migrate from 4x8 to 4x9 * spotlessApply (#2213) Co-authored-by: GitHub GTNH Actions <> * QoLs * 9 manual items * spotless * feat: open master GUI when used, without holding a data-stick (#2221) * fix destpos * optimize empty check * Fix error when fluidInventory.size() == 0 If the fluidInventory size is 0, there is no element to get. Add a check for it. * name in waila + fix int overflow * unnecssary super * update deps --------- Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> * Use real stack limit (#2256) * Fix incorrect data stick behaviors for hatches (#2257) * Fix pcb factory not applying its roughness multiplier when it doesn't OC (#2258) * fix PCB Factory not applying its roughness multiplier when it doesn't do any overclocks * spotless * Remove duplicate obsidian long rod (#2259) * disable gt obsidian long rod * cleaner code * Add hazmat to ThaumicBoots (#2260) * Add hazmat to ThaumicBoots does what it says * fixed * fix item names (#2263) * Fix renaming recipe check might ignore NBT equality (#2261) * Fix GPL ignoring if the recipe is allowed to be cached (#2262) * Added bricked blast furnace recipe progress to waila. (#2265) * Added bricked blast furnace recipe progress to waila. * fixed formatting issues. * Fix cutter recipes not being added (#2271) * add processing task * clean up item logic host * temporary fix for GT_StructrureMuTE * use j9+ feature on pollution task * prepare complex parallel logic for transition * feature to ProcessingLogicHost * fix up multiblock bases * add processing logic for each multi to prepare for transition * spotless * removed debug text from wailaBody of GT_MetaTileEntity_Hatch_CraftingInput_ME (#2272) * Proper recipe selection for output overflow in LCR and other multiblocks (#2247) * Implement Stream<FindRecipeResult> findRecipesWithResult for GT_RecipeMap * Change ProcessingLogic.process to actually use new findRecipesWithResult * Change ProcessingLogic.process to start finding something only for OUTPUT_FULL result * Refactor ProcessingLogic.process to make logic more readable * Replace while with for loop, remove NOT_FOUND return in end of findRecipesWithResult * Apply spotless * Make findRecipe use findRecipes, add annotation to GT_Recipe and FindRecipeResult for processRecipe and make method protected, replace wildcard imports * Remake isRecipeWithOutputFullFound * Add @Nonnull to methods * Apply spotless * Remove Stream version of findRecipeWithResult, replace with predicate one. Add GT_Predicated_Recipe_Map class for utilizing this method. Changes some existent recipe maps to inherit from base class. * Remove GT_Predicated_Recipe_Map, add Predicate directly to GT_Recipe_Map#findRecipeWithResult. Add AdvancedRecipeValidatorPredicate and FindRecipeWithAdvancedValidatorResult to allow store validation calculations for further use and proper errors displaying. * Fix InsufficientVoltage errors * Changes according to review comments. Integrate FindRecipeWithAdvancedValidatorResult to FindRecipeResult, rename AdvancedRecipeValidatorPredicate, encapsulate AdvancedRecipeValidatorPredicate fields, fixes some typos, etc * Moves InsufficientVoltage check to GT_ParallelHelper. Removes FindRecipeResult#State#INSUFFICIENT_VOLTAGE * Return an old findRecipeWithResult * Renames things, call old methods for singleblocks * Renames things, makes FindRecipeResult ctor private * Apply spotless * Move RecipeValidator, fix comments typos * update deps * fix up complex processing logic * add a getter for voiding mode * fix getAccessibleSlotsFromSide being wrong sometimes * allow for subtraction of a specific item * use long for amount * add a setter for machine host * initial work on finding recipes and input consumption * Deprecate PA by removing its controller recipe (#2273) * Restore PA controller recipe (#2276) * Restore PA controller recipe * Remove duplicated recipe * Add optional description to input hatch constructors (#2278) * mini fix (#2204) * [chore] Bump fallback version to 44 (#2274) * find recipe in theory working * add some helper methods to inventory logics * update deps * use collect not toList * fix loading crash * fix complex processing logic using wrong find recipe * fix up everything and get recipe finding working * annotate and clean up methods * spotless * save things to nbt * input separation for mutes and fully working processing * apply mute mode on processing logic * clean up overrides --------- Co-authored-by: chochem <40274384+chochem@users.noreply.github.com> Co-authored-by: miozune <miozune@gmail.com> Co-authored-by: Pxx500 <81298696+Pxx500@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Glease <4586901+Glease@users.noreply.github.com> Co-authored-by: firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: Harry <harryyunull@gmail.com> Co-authored-by: Eraldoe <Eraldoe@users.noreply.github.com> Co-authored-by: Jakub <53441451+kuba6000@users.noreply.github.com> Co-authored-by: Connor-Colenso <52056774+Connor-Colenso@users.noreply.github.com> Co-authored-by: Guillaume Mercier <C0bra5@users.noreply.github.com> Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: Alastors <78517796+Alastors@users.noreply.github.com> Co-authored-by: Kyium <43573052+Kyium@users.noreply.github.com> Co-authored-by: SKProCH <29896317+SKProCH@users.noreply.github.com> Co-authored-by: Sampsa <69092953+S4mpsa@users.noreply.github.com> Co-authored-by: Jaiden Baker <jaidencolebaker@gmail.com> * address minecraft's reviews from #2283 * Refactor MuTE processing logic (#2301) -fix conflicts * Fix void protection for mutes (#2298) - fix conflicts * initial variables * implement working void protection on items and fluids * Adds a Simple PowerOutput task and cleans up some of the code. (#2303) * create a power output task which can be used for dynamos * refactor the controllers and clean up * add some documentation to power logic * make a wireless network manager class instead of using an interface * clean up and add documentation. * setAmperage to setMaxAmperage * fix comment * remove IGlobalWirelessEnergy usage * getAmperage -> getMaxAmperage * add todo for future * Cleanup MuTEMaster code (#2282) * exit early * spotless * better side checking * make if blocks mutually exclusive * more exit early * convert nested ternary operators into if blocks * remove dead code * collapse nested if blocks * add todo to break verylong condition into much smaller ones * spotless apply * collapsing nested if blocks and more exit early * spotless apply * extract try/catch block to its own utility method * break down this unreadable condition * boolean magic (1/5) * boolean magic (2/5) Also corrected some logic on the player null check, we want it to be non null * boolean magic (3/5) * boolean magic (4/5) * boolean magic (5/5) * remove todo * Fix logic --------- Co-authored-by: Jason Mitchell <jason@puzzle.io> Co-authored-by: BlueWeabo <76872108+BlueWeabo@users.noreply.github.com> * Clean up a lil bit and fix some issues with MuTEs (#2316) * clean up fixes * actual fix and remove useless if * Rework MuTEGUI structure (#2429) - fix conflicts` Merged to rebase MuTEMaster and fix any non-compile errors and game not launching in there * some docs on a few methods * innitial GUI class * try to implement guis * almost working - fix comflict * add UIBuildContext to getGUI method * make it compile * sketch gui - fix conflict * compile and spotless * add config option to enabling MuTEs * Spotless apply for branch feature/MuTEMaster for #2431 (#2432) spotlessApply Co-authored-by: GitHub GTNH Actions <> * address reviews on broken processing logic * spotless * fix doc and review --------- Co-authored-by: Maxim <maxim235@gmx.de> Co-authored-by: RIONDY 'POPlol333' Adam <76914762+POPlol333@users.noreply.github.com> Co-authored-by: Jason Mitchell <mitchej@gmail.com> Co-authored-by: Daniel Mendes <70096037+Steelux8@users.noreply.github.com> Co-authored-by: kstvr32 <109012629+kstvr32@users.noreply.github.com> Co-authored-by: TheEpicGamer274 <102255081+TheEpicGamer274@users.noreply.github.com> Co-authored-by: miozune <miozune@gmail.com> Co-authored-by: chochem <40274384+chochem@users.noreply.github.com> Co-authored-by: Pxx500 <81298696+Pxx500@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Glease <4586901+Glease@users.noreply.github.com> Co-authored-by: firenoo <49818773+firenoo@users.noreply.github.com> Co-authored-by: Martin Robertz <dream-master@gmx.net> Co-authored-by: Harry <harryyunull@gmail.com> Co-authored-by: Eraldoe <Eraldoe@users.noreply.github.com> Co-authored-by: Jakub <53441451+kuba6000@users.noreply.github.com> Co-authored-by: Connor-Colenso <52056774+Connor-Colenso@users.noreply.github.com> Co-authored-by: Guillaume Mercier <C0bra5@users.noreply.github.com> Co-authored-by: Fox_white <39846845+foxwhite25@users.noreply.github.com> Co-authored-by: Alastors <78517796+Alastors@users.noreply.github.com> Co-authored-by: Kyium <43573052+Kyium@users.noreply.github.com> Co-authored-by: SKProCH <29896317+SKProCH@users.noreply.github.com> Co-authored-by: Sampsa <69092953+S4mpsa@users.noreply.github.com> Co-authored-by: Jaiden Baker <jaidencolebaker@gmail.com> Co-authored-by: boubou19 <miisterunknown@gmail.com> Co-authored-by: Jason Mitchell <jason@puzzle.io>
Diffstat (limited to 'src/main/java/gregtech/common/gui')
-rw-r--r--src/main/java/gregtech/common/gui/ComplexParallelMachineGUIProvider.java32
-rw-r--r--src/main/java/gregtech/common/gui/MachineGUIProvider.java498
-rw-r--r--src/main/java/gregtech/common/gui/PartGUIProvider.java33
3 files changed, 563 insertions, 0 deletions
diff --git a/src/main/java/gregtech/common/gui/ComplexParallelMachineGUIProvider.java b/src/main/java/gregtech/common/gui/ComplexParallelMachineGUIProvider.java
new file mode 100644
index 0000000000..89b42c8500
--- /dev/null
+++ b/src/main/java/gregtech/common/gui/ComplexParallelMachineGUIProvider.java
@@ -0,0 +1,32 @@
+package gregtech.common.gui;
+
+import javax.annotation.Nonnull;
+
+import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+
+import gregtech.api.gui.GUIHost;
+import gregtech.api.logic.ComplexParallelProcessingLogic;
+import gregtech.api.logic.interfaces.PowerLogicHost;
+import gregtech.api.logic.interfaces.ProcessingLogicHost;
+
+/**
+ * Default GUI class for machines with complex parallel
+ */
+public class ComplexParallelMachineGUIProvider<T extends GUIHost & ProcessingLogicHost<? extends ComplexParallelProcessingLogic<?>> & PowerLogicHost>
+ extends MachineGUIProvider<T> {
+
+ public ComplexParallelMachineGUIProvider(@Nonnull T host) {
+ super(host);
+ }
+
+ @Override
+ protected void attachSynchHandlers(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+
+ }
+
+ @Override
+ protected void addWidgets(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+
+ }
+}
diff --git a/src/main/java/gregtech/common/gui/MachineGUIProvider.java b/src/main/java/gregtech/common/gui/MachineGUIProvider.java
new file mode 100644
index 0000000000..91d14c209a
--- /dev/null
+++ b/src/main/java/gregtech/common/gui/MachineGUIProvider.java
@@ -0,0 +1,498 @@
+package gregtech.common.gui;
+
+import static gregtech.api.metatileentity.BaseTileEntity.BUTTON_FORBIDDEN_TOOLTIP;
+import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+
+import net.minecraft.util.StatCollector;
+
+import com.gtnewhorizons.modularui.api.ModularUITextures;
+import com.gtnewhorizons.modularui.api.drawable.IDrawable;
+import com.gtnewhorizons.modularui.api.drawable.ItemDrawable;
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+import com.gtnewhorizons.modularui.api.math.Pos2d;
+import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.DrawableWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+import com.gtnewhorizons.modularui.common.widget.MultiChildWidget;
+import com.gtnewhorizons.modularui.common.widget.TabButton;
+import com.gtnewhorizons.modularui.common.widget.TabContainer;
+import com.gtnewhorizons.modularui.common.widget.TextWidget;
+
+import gregtech.api.enums.InventoryType;
+import gregtech.api.enums.SoundResource;
+import gregtech.api.enums.VoidingMode;
+import gregtech.api.gui.GUIHost;
+import gregtech.api.gui.GUIProvider;
+import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.api.gui.modularui.GUITextureSet;
+import gregtech.api.logic.MuTEProcessingLogic;
+import gregtech.api.logic.PowerLogic;
+import gregtech.api.logic.interfaces.PowerLogicHost;
+import gregtech.api.logic.interfaces.ProcessingLogicHost;
+
+/**
+ * Default GUI a machine will use to show its information
+ */
+public class MachineGUIProvider<T extends GUIHost & ProcessingLogicHost<? extends MuTEProcessingLogic<?>> & PowerLogicHost>
+ extends GUIProvider<T> {
+
+ private static final int LOGO_SIZE = 17;
+ @Nonnull
+ protected static final Pos2d POWER_SWITCH_BUTTON_DEFAULT_POS = new Pos2d(144, 0);
+ @Nonnull
+ protected static final Pos2d VOIDING_MODE_BUTTON_DEFAULT_POS = new Pos2d(54, 0);
+ @Nonnull
+ protected static final Pos2d INPUT_SEPARATION_BUTTON_DEFAULT_POS = new Pos2d(36, 0);
+ @Nonnull
+ protected static final Pos2d BATCH_MODE_BUTTON_DEFAULT_POS = new Pos2d(18, 0);
+ @Nonnull
+ protected static final Pos2d RECIPE_LOCKING_BUTTON_DEFAULT_POS = new Pos2d(0, 0);
+
+ public MachineGUIProvider(@Nonnull T host) {
+ super(host);
+ }
+
+ @Override
+ protected void attachSynchHandlers(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+
+ }
+
+ @Override
+ protected void addWidgets(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+ int page = 0;
+ builder.setBackground(GT_UITextures.BACKGROUND_SINGLEBLOCK_DEFAULT);
+ MultiChildWidget mainTab = new MultiChildWidget();
+ mainTab.setSize(host.getWidth(), host.getHeight());
+ createMainTab(mainTab, builder, uiContext);
+ TabContainer tabs = new TabContainer().setButtonSize(20, 24);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0, 1f, 0.5f),
+ new ItemDrawable(host.getAsItem()).withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_START.getSubArea(0, 0.5f, 1f, 1f),
+ new ItemDrawable(host.getAsItem()).withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip(host.getMachineName())
+ .setPos(20 * (page - 1), -20))
+ .addPage(mainTab);
+ if (host.hasItemInput()) {
+ MultiChildWidget itemInputTab = new MultiChildWidget();
+ itemInputTab.setSize(host.getWidth(), host.getHeight());
+ createItemInputTab(itemInputTab, builder, uiContext);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
+ GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
+ GT_UITextures.PICTURE_ITEM_IN.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip("Item Input Inventory")
+ .setPos(20 * (page - 1), -20))
+ .addPage(itemInputTab.addChild(getLogo().setPos(147, 86)));
+ }
+
+ if (host.hasItemOutput()) {
+ MultiChildWidget itemOutputTab = new MultiChildWidget();
+ itemOutputTab.setSize(host.getWidth(), host.getHeight());
+ createItemOutputTab(itemOutputTab, builder, uiContext);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
+ GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
+ GT_UITextures.PICTURE_ITEM_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip("Item Output Inventory")
+ .setPos(20 * (page - 1), -20))
+ .addPage(itemOutputTab.addChild(getLogo().setPos(147, 86)));
+ }
+
+ if (host.hasFluidInput()) {
+ MultiChildWidget fluidInputTab = new MultiChildWidget();
+ fluidInputTab.setSize(host.getWidth(), host.getHeight());
+ createFluidInputTab(fluidInputTab, builder, uiContext);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
+ GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
+ GT_UITextures.PICTURE_FLUID_IN.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip("Fluid Input Tanks")
+ .setPos(20 * (page - 1), -20))
+ .addPage(fluidInputTab.addChild(getLogo().setPos(147, 86)));
+ }
+
+ if (host.hasFluidOutput()) {
+ MultiChildWidget fluidOutputTab = new MultiChildWidget();
+ fluidOutputTab.setSize(host.getWidth(), host.getHeight());
+ createFluidOutputTab(fluidOutputTab, builder, uiContext);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
+ GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
+ GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip("Fluid Output Tanks")
+ .setPos(20 * (page - 1), -20))
+ .addPage(fluidOutputTab.addChild(getLogo().setPos(147, 86)));
+ }
+ MultiChildWidget powerInfoTab = new MultiChildWidget();
+ powerInfoTab.setSize(host.getWidth(), host.getHeight());
+ createPowerTab(powerInfoTab, builder, uiContext);
+ tabs.addTabButton(
+ new TabButton(page++)
+ .setBackground(
+ false,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0, 1f, 0.5f),
+ GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .setBackground(
+ true,
+ ModularUITextures.VANILLA_TAB_TOP_MIDDLE.getSubArea(0, 0.5f, 1f, 1f),
+ GT_UITextures.PICTURE_FLUID_OUT.withFixedSize(16, 16)
+ .withOffset(2, 4))
+ .addTooltip("Power Information")
+ .setPos(20 * (page - 1), -20))
+ .addPage(powerInfoTab.addChild(getLogo().setPos(147, 86)));
+ builder.widget(tabs);
+ }
+
+ protected void createMainTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ MultiChildWidget buttons = new MultiChildWidget();
+ buttons.setSize(16, 167)
+ .setPos(7, 86);
+ buttons.addChild(createPowerSwitchButton(builder))
+ .addChild(createVoidExcessButton(builder))
+ .addChild(createInputSeparationButton(builder))
+ .addChild(createBatchModeButton(builder))
+ .addChild(createLockToSingleRecipeButton(builder));
+ tab.addChild(
+ new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK)
+ .setPos(7, 4)
+ .setSize(160, 75))
+ .addChild(buttons);
+ }
+
+ protected void createItemInputTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ tab.addChild(
+ host.getItemLogic(InventoryType.Input, null)
+ .getGuiPart()
+ .setSize(18 * 4 + 9, 5 * 18)
+ .setPos(host.getWidth() / 2 - 2 * 18, 10));
+ }
+
+ protected void createItemOutputTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ tab.addChild(
+ host.getItemLogic(InventoryType.Output, null)
+ .getGuiPart()
+ .setSize(18 * 4 + 9, 5 * 18)
+ .setPos(host.getWidth() / 2 - 2 * 18, 10));
+ }
+
+ protected void createFluidInputTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ tab.addChild(
+ host.getFluidLogic(InventoryType.Input, null)
+ .getGuiPart()
+ .setSize(18 * 4 + 9, 5 * 18)
+ .setPos(host.getWidth() / 2 - 2 * 18, 10));
+ }
+
+ protected void createFluidOutputTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ tab.addChild(
+ host.getFluidLogic(InventoryType.Output, null)
+ .getGuiPart()
+ .setSize(18 * 4 + 9, 5 * 18)
+ .setPos(host.getWidth() / 2 - 2 * 18, 10));
+ }
+
+ protected void createPowerTab(@Nonnull MultiChildWidget tab, @Nonnull Builder builder,
+ @Nonnull UIBuildContext uiBuildContext) {
+ PowerLogic power = host.getPowerLogic();
+ tab.addChild(
+ TextWidget.dynamicString(() -> power.getStoredEnergy() + "/" + power.getCapacity() + " EU")
+ .setPos(10, 30))
+ .addChild(
+ TextWidget.dynamicString(() -> power.getVoltage() + " EU/t" + "(" + power.getMaxAmperage() + " A)")
+ .setPos(10, 60));
+ }
+
+ /**
+ * Should return the logo you want to use that is pasted on each tab. Default is the GT logo.
+ */
+ @Nonnull
+ protected Widget getLogo() {
+ DrawableWidget logo = new DrawableWidget();
+ logo.setDrawable(GUITextureSet.DEFAULT.getGregTechLogo())
+ .setSize(LOGO_SIZE, LOGO_SIZE);
+ return logo;
+ }
+
+ protected Pos2d getPowerSwitchButtonPos() {
+ return POWER_SWITCH_BUTTON_DEFAULT_POS;
+ }
+
+ protected ButtonWidget createPowerSwitchButton(IWidgetBuilder<?> builder) {
+ ButtonWidget button = new ButtonWidget();
+ button.setOnClick((clickData, widget) -> {
+ if (host.isAllowedToWork()) {
+ host.disableWorking();
+ } else {
+ host.enableWorking();
+ }
+ })
+ .setPlayClickSoundResource(
+ () -> host.isAllowedToWork() ? SoundResource.GUI_BUTTON_UP.resourceLocation
+ : SoundResource.GUI_BUTTON_DOWN.resourceLocation)
+ .setBackground(() -> {
+ if (host.isAllowedToWork()) {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD_PRESSED,
+ GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_ON };
+ } else {
+ return new IDrawable[] { GT_UITextures.BUTTON_STANDARD,
+ GT_UITextures.OVERLAY_BUTTON_POWER_SWITCH_OFF };
+ }
+ })
+ .attachSyncer(new FakeSyncWidget.BooleanSyncer(host::isAllowedToWork, host::setAllowedToWork), builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.power_switch"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getPowerSwitchButtonPos())
+ .setSize(16, 16);
+ return button;
+ }
+
+ @Nonnull
+ protected Pos2d getVoidingModeButtonPos() {
+ return VOIDING_MODE_BUTTON_DEFAULT_POS;
+ }
+
+ @Nonnull
+ protected ButtonWidget createVoidExcessButton(IWidgetBuilder<?> builder) {
+ ButtonWidget button = new ButtonWidget();
+ button.setOnClick((clickData, widget) -> {
+ if (host.supportsVoidProtection()) {
+ Set<VoidingMode> allowed = host.getAllowedVoidingModes();
+ switch (clickData.mouseButton) {
+ case 0 -> host.setVoidingMode(
+ host.getVoidingMode()
+ .nextInCollection(allowed));
+ case 1 -> host.setVoidingMode(
+ host.getVoidingMode()
+ .previousInCollection(allowed));
+ }
+ widget.notifyTooltipChange();
+ }
+ })
+ .setPlayClickSound(host.supportsVoidProtection())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ ret.add(host.getVoidingMode().buttonTexture);
+ ret.add(host.getVoidingMode().buttonOverlay);
+ if (!host.supportsVoidProtection()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(
+ new FakeSyncWidget.IntegerSyncer(
+ () -> host.getVoidingMode()
+ .ordinal(),
+ val -> host.setVoidingMode(VoidingMode.fromOrdinal(val))),
+ builder)
+ .dynamicTooltip(
+ () -> Arrays.asList(
+ StatCollector.translateToLocal("GT5U.gui.button.voiding_mode"),
+ StatCollector.translateToLocal(
+ host.getVoidingMode()
+ .getTransKey())))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getVoidingModeButtonPos())
+ .setSize(16, 16);
+ if (!host.supportsVoidProtection()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return button;
+ }
+
+ @Nonnull
+ protected Pos2d getInputSeparationButtonPos() {
+ return INPUT_SEPARATION_BUTTON_DEFAULT_POS;
+ }
+
+ protected ButtonWidget createInputSeparationButton(IWidgetBuilder<?> builder) {
+ ButtonWidget button = new ButtonWidget();
+ button.setOnClick((clickData, widget) -> {
+ if (host.supportsInputSeparation()) {
+ host.setInputSeparation(!host.isInputSeparated());
+ }
+ })
+ .setPlayClickSound(host.supportsInputSeparation())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (host.isInputSeparated()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (host.supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_ON_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (host.supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_INPUT_SEPARATION_OFF_DISABLED);
+ }
+ }
+ if (!host.supportsInputSeparation()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(new FakeSyncWidget.BooleanSyncer(host::isInputSeparated, host::setInputSeparation), builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.input_separation"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getInputSeparationButtonPos())
+ .setSize(16, 16);
+ if (!host.supportsInputSeparation()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return button;
+ }
+
+ @Nonnull
+ protected Pos2d getBatchModeButtonPos() {
+ return BATCH_MODE_BUTTON_DEFAULT_POS;
+ }
+
+ protected ButtonWidget createBatchModeButton(IWidgetBuilder<?> builder) {
+ ButtonWidget button = new ButtonWidget();
+ button.setOnClick((clickData, widget) -> {
+ if (host.supportsBatchMode()) {
+ host.setBatchMode(!host.isBatchModeEnabled());
+ }
+ })
+ .setPlayClickSound(host.supportsBatchMode())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (host.isBatchModeEnabled()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (host.supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_ON_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (host.supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_BATCH_MODE_OFF_DISABLED);
+ }
+ }
+ if (!host.supportsBatchMode()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(new FakeSyncWidget.BooleanSyncer(host::isBatchModeEnabled, host::setBatchMode), builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.batch_mode"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getBatchModeButtonPos())
+ .setSize(16, 16);
+ if (!host.supportsBatchMode()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return button;
+ }
+
+ @Nonnull
+ protected Pos2d getRecipeLockingButtonPos() {
+ return RECIPE_LOCKING_BUTTON_DEFAULT_POS;
+ }
+
+ protected ButtonWidget createLockToSingleRecipeButton(IWidgetBuilder<?> builder) {
+ ButtonWidget button = new ButtonWidget();
+ button.setOnClick((clickData, widget) -> {
+ if (host.supportsSingleRecipeLocking()) {
+ host.setRecipeLocking(!host.isRecipeLockingEnabled());
+ }
+ })
+ .setPlayClickSound(host.supportsSingleRecipeLocking())
+ .setBackground(() -> {
+ List<UITexture> ret = new ArrayList<>();
+ if (host.isRecipeLockingEnabled()) {
+ ret.add(GT_UITextures.BUTTON_STANDARD_PRESSED);
+ if (host.supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_LOCKED_DISABLED);
+ }
+ } else {
+ ret.add(GT_UITextures.BUTTON_STANDARD);
+ if (host.supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED);
+ } else {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_RECIPE_UNLOCKED_DISABLED);
+ }
+ }
+ if (!host.supportsSingleRecipeLocking()) {
+ ret.add(GT_UITextures.OVERLAY_BUTTON_FORBIDDEN);
+ }
+ return ret.toArray(new IDrawable[0]);
+ })
+ .attachSyncer(
+ new FakeSyncWidget.BooleanSyncer(host::isRecipeLockingEnabled, host::setRecipeLocking),
+ builder)
+ .addTooltip(StatCollector.translateToLocal("GT5U.gui.button.lock_recipe"))
+ .setTooltipShowUpDelay(TOOLTIP_DELAY)
+ .setPos(getRecipeLockingButtonPos())
+ .setSize(16, 16);
+ if (!host.supportsSingleRecipeLocking()) {
+ button.addTooltip(StatCollector.translateToLocal(BUTTON_FORBIDDEN_TOOLTIP));
+ }
+ return button;
+ }
+}
diff --git a/src/main/java/gregtech/common/gui/PartGUIProvider.java b/src/main/java/gregtech/common/gui/PartGUIProvider.java
new file mode 100644
index 0000000000..7600444f71
--- /dev/null
+++ b/src/main/java/gregtech/common/gui/PartGUIProvider.java
@@ -0,0 +1,33 @@
+package gregtech.common.gui;
+
+import javax.annotation.Nonnull;
+
+import com.gtnewhorizons.modularui.api.screen.ModularWindow.Builder;
+import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
+
+import gregtech.api.gui.GUIHost;
+import gregtech.api.gui.GUIProvider;
+import gregtech.api.logic.interfaces.FluidInventoryLogicHost;
+import gregtech.api.logic.interfaces.ItemInventoryLogicHost;
+import gregtech.api.logic.interfaces.PowerLogicHost;
+
+public class PartGUIProvider<T extends GUIHost & ItemInventoryLogicHost & PowerLogicHost & FluidInventoryLogicHost>
+ extends GUIProvider<T> {
+
+ public PartGUIProvider(@Nonnull T host) {
+ super(host);
+ }
+
+ @Override
+ protected void attachSynchHandlers(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException("Unimplemented method 'attachSynchHandlers'");
+ }
+
+ @Override
+ protected void addWidgets(@Nonnull Builder builder, @Nonnull UIBuildContext uiContext) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException("Unimplemented method 'addWidgets'");
+ }
+
+}