ContainerScreenOverlay.java 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. /*
  2. * Roughly Enough Items by Danielshe.
  3. * Licensed under the MIT License.
  4. */
  5. package me.shedaniel.rei.gui;
  6. import com.google.common.collect.Lists;
  7. import com.mojang.blaze3d.systems.RenderSystem;
  8. import me.shedaniel.math.api.Point;
  9. import me.shedaniel.math.api.Rectangle;
  10. import me.shedaniel.math.impl.PointHelper;
  11. import me.shedaniel.rei.RoughlyEnoughItemsCore;
  12. import me.shedaniel.rei.api.ClientHelper;
  13. import me.shedaniel.rei.api.DisplayHelper;
  14. import me.shedaniel.rei.api.EntryStack;
  15. import me.shedaniel.rei.api.RecipeHelper;
  16. import me.shedaniel.rei.gui.config.SearchFieldLocation;
  17. import me.shedaniel.rei.gui.widget.*;
  18. import me.shedaniel.rei.impl.RecipeHelperImpl;
  19. import me.shedaniel.rei.impl.ScreenHelper;
  20. import me.shedaniel.rei.impl.Weather;
  21. import me.shedaniel.rei.listeners.ContainerScreenHooks;
  22. import me.shedaniel.rei.utils.CollectionUtils;
  23. import net.minecraft.client.MinecraftClient;
  24. import net.minecraft.client.gui.Element;
  25. import net.minecraft.client.gui.screen.Screen;
  26. import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen;
  27. import net.minecraft.client.render.GuiLighting;
  28. import net.minecraft.client.render.LayeredVertexConsumerStorage;
  29. import net.minecraft.client.render.Tessellator;
  30. import net.minecraft.client.resource.language.I18n;
  31. import net.minecraft.client.sound.PositionedSoundInstance;
  32. import net.minecraft.client.util.Window;
  33. import net.minecraft.client.util.math.Matrix4f;
  34. import net.minecraft.client.util.math.MatrixStack;
  35. import net.minecraft.client.world.ClientWorld;
  36. import net.minecraft.container.Slot;
  37. import net.minecraft.item.ItemStack;
  38. import net.minecraft.sound.SoundEvents;
  39. import net.minecraft.text.TranslatableText;
  40. import net.minecraft.util.ActionResult;
  41. import net.minecraft.util.Identifier;
  42. import net.minecraft.util.math.MathHelper;
  43. import net.minecraft.world.GameMode;
  44. import org.apache.logging.log4j.util.TriConsumer;
  45. import javax.annotation.Nullable;
  46. import java.util.*;
  47. public class ContainerScreenOverlay extends Widget {
  48. private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
  49. private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
  50. public static String searchTerm = "";
  51. private static int page = 0;
  52. private static EntryListWidget entryListWidget;
  53. private final List<Widget> widgets = Lists.newLinkedList();
  54. public boolean shouldReInit = false;
  55. private int tooltipWidth;
  56. private int tooltipHeight;
  57. private List<String> tooltipLines;
  58. public final TriConsumer<Integer, Integer, Float> renderTooltipCallback = (x, y, aFloat) -> {
  59. RenderSystem.disableRescaleNormal();
  60. RenderSystem.disableDepthTest();
  61. setBlitOffset(1000);
  62. this.fillGradient(x - 3, y - 4, x + tooltipWidth + 3, y - 3, -267386864, -267386864);
  63. this.fillGradient(x - 3, y + tooltipHeight + 3, x + tooltipWidth + 3, y + tooltipHeight + 4, -267386864, -267386864);
  64. this.fillGradient(x - 3, y - 3, x + tooltipWidth + 3, y + tooltipHeight + 3, -267386864, -267386864);
  65. this.fillGradient(x - 4, y - 3, x - 3, y + tooltipHeight + 3, -267386864, -267386864);
  66. this.fillGradient(x + tooltipWidth + 3, y - 3, x + tooltipWidth + 4, y + tooltipHeight + 3, -267386864, -267386864);
  67. this.fillGradient(x - 3, y - 3 + 1, x - 3 + 1, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
  68. this.fillGradient(x + tooltipWidth + 2, y - 3 + 1, x + tooltipWidth + 3, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
  69. this.fillGradient(x - 3, y - 3, x + tooltipWidth + 3, y - 3 + 1, 1347420415, 1347420415);
  70. this.fillGradient(x - 3, y + tooltipHeight + 2, x + tooltipWidth + 3, y + tooltipHeight + 3, 1344798847, 1344798847);
  71. int currentY = y;
  72. MatrixStack matrixStack_1 = new MatrixStack();
  73. LayeredVertexConsumerStorage.Drawer drawer = LayeredVertexConsumerStorage.makeDrawer(Tessellator.getInstance().getBufferBuilder());
  74. matrixStack_1.translate(0.0D, 0.0D, getBlitOffset());
  75. Matrix4f matrix4f_1 = matrixStack_1.peek();
  76. for (int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) {
  77. font.method_22942(tooltipLines.get(lineIndex), (float) x, (float) currentY, -1, true, matrix4f_1, drawer, false, 0, 15728880);
  78. currentY += lineIndex == 0 ? 12 : 10;
  79. }
  80. drawer.draw();
  81. setBlitOffset(0);
  82. RenderSystem.enableDepthTest();
  83. RenderSystem.enableRescaleNormal();
  84. };
  85. private Rectangle rectangle;
  86. private Window window;
  87. private CraftableToggleButtonWidget toggleButtonWidget;
  88. private ButtonWidget buttonLeft, buttonRight;
  89. public static EntryListWidget getEntryListWidget() {
  90. return entryListWidget;
  91. }
  92. public static void setPage(int page) {
  93. ContainerScreenOverlay.page = page;
  94. }
  95. public void init() {
  96. init(false);
  97. }
  98. public void init(boolean setPage) {
  99. this.shouldReInit = false;
  100. //Update Variables
  101. this.children().clear();
  102. this.window = MinecraftClient.getInstance().getWindow();
  103. DisplayHelper.DisplayBoundsHandler boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
  104. this.rectangle = RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? boundsHandler.getLeftBounds(MinecraftClient.getInstance().currentScreen) : boundsHandler.getRightBounds(MinecraftClient.getInstance().currentScreen);
  105. widgets.add(entryListWidget = new EntryListWidget(page));
  106. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
  107. if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
  108. widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + (RoughlyEnoughItemsCore.getConfigManager().getConfig().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16, new TranslatableText("text.rei.left_arrow")) {
  109. @Override
  110. public void onPressed() {
  111. page--;
  112. if (page < 0)
  113. page = getTotalPage();
  114. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
  115. }
  116. @Override
  117. public Optional<String> getTooltips() {
  118. return Optional.ofNullable(I18n.translate("text.rei.previous_page"));
  119. }
  120. @Override
  121. public boolean changeFocus(boolean boolean_1) {
  122. return false;
  123. }
  124. @Override
  125. public boolean containsMouse(double mouseX, double mouseY) {
  126. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  127. }
  128. });
  129. widgets.add(buttonRight = new ButtonWidget(rectangle.x + rectangle.width - 18, rectangle.y + (RoughlyEnoughItemsCore.getConfigManager().getConfig().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16, new TranslatableText("text.rei.right_arrow")) {
  130. @Override
  131. public void onPressed() {
  132. page++;
  133. if (page > getTotalPage())
  134. page = 0;
  135. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
  136. }
  137. @Override
  138. public Optional<String> getTooltips() {
  139. return Optional.ofNullable(I18n.translate("text.rei.next_page"));
  140. }
  141. @Override
  142. public boolean changeFocus(boolean boolean_1) {
  143. return false;
  144. }
  145. @Override
  146. public boolean containsMouse(double mouseX, double mouseY) {
  147. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  148. }
  149. });
  150. }
  151. if (setPage)
  152. page = MathHelper.clamp(page, 0, getTotalPage());
  153. widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20, "") {
  154. @Override
  155. public void onPressed() {
  156. if (Screen.hasShiftDown()) {
  157. ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating());
  158. return;
  159. }
  160. RoughlyEnoughItemsCore.getConfigManager().openConfigScreen(ScreenHelper.getLastContainerScreen());
  161. }
  162. @Override
  163. public void render(int mouseX, int mouseY, float delta) {
  164. super.render(mouseX, mouseY, delta);
  165. GuiLighting.disable();
  166. if (ClientHelper.getInstance().isCheating() && RoughlyEnoughItemsCore.hasOperatorPermission()) {
  167. if (RoughlyEnoughItemsCore.hasPermissionToUsePackets())
  168. fill(getBounds().x, getBounds().y, getBounds().x + 20, getBounds().y + 20, 721354752);
  169. else
  170. fill(getBounds().x, getBounds().y, getBounds().x + 20, getBounds().y + 20, 1476440063);
  171. }
  172. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  173. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  174. blit(getBounds().x + 3, getBounds().y + 3, 0, 0, 14, 14);
  175. }
  176. @Override
  177. public Optional<String> getTooltips() {
  178. String tooltips = I18n.translate("text.rei.config_tooltip");
  179. tooltips += "\n ";
  180. if (!ClientHelper.getInstance().isCheating())
  181. tooltips += "\n" + I18n.translate("text.rei.cheating_disabled");
  182. else if (!RoughlyEnoughItemsCore.hasOperatorPermission())
  183. tooltips += "\n" + I18n.translate("text.rei.cheating_enabled_no_perms");
  184. else if (RoughlyEnoughItemsCore.hasPermissionToUsePackets())
  185. tooltips += "\n" + I18n.translate("text.rei.cheating_enabled");
  186. else
  187. tooltips += "\n" + I18n.translate("text.rei.cheating_limited_enabled");
  188. return Optional.ofNullable(tooltips);
  189. }
  190. @Override
  191. public boolean changeFocus(boolean boolean_1) {
  192. return false;
  193. }
  194. @Override
  195. public boolean containsMouse(double mouseX, double mouseY) {
  196. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  197. }
  198. });
  199. if (RoughlyEnoughItemsCore.getConfigManager().getConfig().doesShowUtilsButtons()) {
  200. widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? window.getScaledWidth() - 55 : 35, 10, 20, 20, "") {
  201. @Override
  202. public void onPressed() {
  203. MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().getGamemodeCommand().replaceAll("\\{gamemode}", getNextGameMode(Screen.hasShiftDown()).getName()));
  204. }
  205. @Override
  206. public void render(int mouseX, int mouseY, float delta) {
  207. text = getGameModeShortText(getCurrentGameMode());
  208. super.render(mouseX, mouseY, delta);
  209. }
  210. @Override
  211. public Optional<String> getTooltips() {
  212. return Optional.ofNullable(I18n.translate("text.rei.gamemode_button.tooltip", getGameModeText(getNextGameMode(Screen.hasShiftDown()))));
  213. }
  214. @Override
  215. public boolean changeFocus(boolean boolean_1) {
  216. return false;
  217. }
  218. @Override
  219. public boolean containsMouse(double mouseX, double mouseY) {
  220. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  221. }
  222. });
  223. int xxx = RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10;
  224. for (Weather weather : Weather.values()) {
  225. widgets.add(new ButtonWidget(xxx, 35, 20, 20, "") {
  226. @Override
  227. public void onPressed() {
  228. MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().getWeatherCommand().replaceAll("\\{weather}", weather.name().toLowerCase(Locale.ROOT)));
  229. }
  230. @Override
  231. public void render(int mouseX, int mouseY, float delta) {
  232. super.render(mouseX, mouseY, delta);
  233. GuiLighting.disable();
  234. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  235. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  236. blit(getBounds().x + 3, getBounds().y + 3, weather.getId() * 14, 14, 14, 14);
  237. }
  238. @Override
  239. public Optional<String> getTooltips() {
  240. return Optional.ofNullable(I18n.translate("text.rei.weather_button.tooltip", I18n.translate(weather.getTranslateKey())));
  241. }
  242. @Override
  243. public boolean changeFocus(boolean boolean_1) {
  244. return false;
  245. }
  246. @Override
  247. public boolean containsMouse(double mouseX, double mouseY) {
  248. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  249. }
  250. });
  251. xxx += RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel() ? -25 : 25;
  252. }
  253. }
  254. if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
  255. widgets.add(new ClickableLabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + (RoughlyEnoughItemsCore.getConfigManager().getConfig().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10, "", getTotalPage() > 0) {
  256. @Override
  257. public void render(int mouseX, int mouseY, float delta) {
  258. page = MathHelper.clamp(page, 0, getTotalPage());
  259. this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
  260. super.render(mouseX, mouseY, delta);
  261. }
  262. @Override
  263. public Optional<String> getTooltips() {
  264. return Optional.ofNullable(I18n.translate("text.rei.go_back_first_page"));
  265. }
  266. @Override
  267. public void onLabelClicked() {
  268. MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
  269. page = 0;
  270. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
  271. }
  272. @Override
  273. public boolean changeFocus(boolean boolean_1) {
  274. return false;
  275. }
  276. });
  277. buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
  278. }
  279. if (ScreenHelper.searchField == null)
  280. ScreenHelper.setSearchField(new OverlaySearchField(0, 0, 0, 0));
  281. ScreenHelper.searchField.getBounds().setBounds(getTextFieldArea());
  282. this.widgets.add(ScreenHelper.searchField);
  283. ScreenHelper.searchField.setText(searchTerm);
  284. ScreenHelper.searchField.setChangedListener(s -> {
  285. searchTerm = s;
  286. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
  287. });
  288. if (RoughlyEnoughItemsCore.getConfigManager().getConfig().isCraftableFilterEnabled())
  289. this.widgets.add(toggleButtonWidget = new CraftableToggleButtonWidget(getCraftableToggleArea()) {
  290. @Override
  291. public void onPressed() {
  292. RoughlyEnoughItemsCore.getConfigManager().toggleCraftableOnly();
  293. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
  294. }
  295. @Override
  296. public void lateRender(int mouseX, int mouseY, float delta) {
  297. setBlitOffset(300);
  298. super.lateRender(mouseX, mouseY, delta);
  299. }
  300. @Override
  301. public boolean containsMouse(double mouseX, double mouseY) {
  302. return isNotInExclusionZones(mouseX, mouseY) && super.containsMouse(mouseX, mouseY);
  303. }
  304. });
  305. else
  306. toggleButtonWidget = null;
  307. this.entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, false);
  308. }
  309. private Weather getNextWeather() {
  310. try {
  311. Weather current = getCurrentWeather();
  312. int next = current.getId() + 1;
  313. if (next >= 3)
  314. next = 0;
  315. return Weather.byId(next);
  316. } catch (Exception e) {
  317. return Weather.CLEAR;
  318. }
  319. }
  320. private Weather getCurrentWeather() {
  321. ClientWorld world = MinecraftClient.getInstance().world;
  322. if (world.isThundering())
  323. return Weather.THUNDER;
  324. if (world.getLevelProperties().isRaining())
  325. return Weather.RAIN;
  326. return Weather.CLEAR;
  327. }
  328. private String getGameModeShortText(GameMode gameMode) {
  329. return I18n.translate("text.rei.short_gamemode." + gameMode.getName());
  330. }
  331. private String getGameModeText(GameMode gameMode) {
  332. return I18n.translate("selectWorld.gameMode." + gameMode.getName());
  333. }
  334. private GameMode getNextGameMode(boolean reverse) {
  335. try {
  336. GameMode current = getCurrentGameMode();
  337. int next = current.getId() + 1;
  338. if (reverse)
  339. next -= 2;
  340. if (next > 3)
  341. next = 0;
  342. if (next < 0)
  343. next = 3;
  344. return GameMode.byId(next);
  345. } catch (Exception e) {
  346. return GameMode.NOT_SET;
  347. }
  348. }
  349. private GameMode getCurrentGameMode() {
  350. return MinecraftClient.getInstance().getNetworkHandler().getPlayerListEntry(MinecraftClient.getInstance().player.getGameProfile().getId()).getGameMode();
  351. }
  352. private Rectangle getTextFieldArea() {
  353. int widthRemoved = RoughlyEnoughItemsCore.getConfigManager().getConfig().isCraftableFilterEnabled() ? 22 : 2;
  354. SearchFieldLocation searchFieldLocation = RoughlyEnoughItemsCore.getConfigManager().getConfig().getSearchFieldLocation();
  355. if (searchFieldLocation == SearchFieldLocation.BOTTOM_SIDE)
  356. return new Rectangle(rectangle.x + 2, window.getScaledHeight() - 22, rectangle.width - 6 - widthRemoved, 18);
  357. if (searchFieldLocation == SearchFieldLocation.TOP_SIDE)
  358. return new Rectangle(rectangle.x + 2, 4, rectangle.width - 6 - widthRemoved, 18);
  359. if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
  360. RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  361. return new Rectangle(widget.getBounds().x, window.getScaledHeight() - 22, widget.getBounds().width - widthRemoved, 18);
  362. }
  363. if (MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen) {
  364. VillagerRecipeViewingScreen widget = (VillagerRecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  365. return new Rectangle(widget.bounds.x, window.getScaledHeight() - 22, widget.bounds.width - widthRemoved, 18);
  366. }
  367. return new Rectangle(ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft(), window.getScaledHeight() - 22, ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth() - widthRemoved, 18);
  368. }
  369. private Rectangle getCraftableToggleArea() {
  370. Rectangle searchBoxArea = getTextFieldArea();
  371. searchBoxArea.setLocation(searchBoxArea.x + searchBoxArea.width + 4, searchBoxArea.y - 1);
  372. searchBoxArea.setSize(20, 20);
  373. return searchBoxArea;
  374. }
  375. private String getCheatModeText() {
  376. return I18n.translate(String.format("%s%s", "text.rei.", ClientHelper.getInstance().isCheating() ? "cheat" : "nocheat"));
  377. }
  378. public Rectangle getRectangle() {
  379. return rectangle;
  380. }
  381. @Override
  382. public void render(int mouseX, int mouseY, float delta) {
  383. List<ItemStack> currentStacks = ClientHelper.getInstance().getInventoryItemsTypes();
  384. if (RoughlyEnoughItemsCore.getDisplayHelper().getBaseBoundsHandler() != null && RoughlyEnoughItemsCore.getDisplayHelper().getBaseBoundsHandler().shouldRecalculateArea(!RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel(), rectangle))
  385. shouldReInit = true;
  386. if (shouldReInit)
  387. init(true);
  388. else if (RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() && ((currentStacks.size() != ScreenHelper.inventoryStacks.size()) || !hasSameListContent(new LinkedList<>(ScreenHelper.inventoryStacks), currentStacks))) {
  389. ScreenHelper.inventoryStacks = currentStacks;
  390. DisplayHelper.DisplayBoundsHandler<?> boundsHandler = RoughlyEnoughItemsCore.getDisplayHelper().getResponsibleBoundsHandler(MinecraftClient.getInstance().currentScreen.getClass());
  391. entryListWidget.updateList(boundsHandler, boundsHandler.getItemListArea(rectangle), page, searchTerm, true);
  392. }
  393. if (OverlaySearchField.isSearching) {
  394. GuiLighting.disable();
  395. setBlitOffset(200);
  396. if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen) {
  397. ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
  398. int left = hooks.rei_getContainerLeft(), top = hooks.rei_getContainerTop();
  399. for (Slot slot : ((AbstractContainerScreen<?>) MinecraftClient.getInstance().currentScreen).getContainer().slotList)
  400. if (!slot.hasStack() || !entryListWidget.filterEntry(EntryStack.create(slot.getStack()), entryListWidget.getLastSearchArgument()))
  401. fillGradient(left + slot.xPosition, top + slot.yPosition, left + slot.xPosition + 16, top + slot.yPosition + 16, -601874400, -601874400);
  402. }
  403. setBlitOffset(0);
  404. }
  405. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  406. GuiLighting.disable();
  407. this.renderWidgets(mouseX, mouseY, delta);
  408. if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen && RoughlyEnoughItemsCore.getConfigManager().getConfig().areClickableRecipeArrowsEnabled()) {
  409. ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
  410. for (RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
  411. if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
  412. if (area.getRectangle().contains(mouseX - hooks.rei_getContainerLeft(), mouseY - hooks.rei_getContainerTop())) {
  413. String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
  414. QUEUED_TOOLTIPS.add(QueuedTooltip.create(I18n.translate("text.rei.view_recipes_for", collect)));
  415. break;
  416. }
  417. }
  418. }
  419. public void lateRender(int mouseX, int mouseY, float delta) {
  420. if (ScreenHelper.isOverlayVisible()) {
  421. ScreenHelper.searchField.laterRender(mouseX, mouseY, delta);
  422. if (toggleButtonWidget != null)
  423. toggleButtonWidget.lateRender(mouseX, mouseY, delta);
  424. Screen currentScreen = MinecraftClient.getInstance().currentScreen;
  425. if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
  426. for (QueuedTooltip queuedTooltip : QUEUED_TOOLTIPS) {
  427. if (queuedTooltip != null)
  428. renderTooltip(queuedTooltip);
  429. }
  430. }
  431. QUEUED_TOOLTIPS.clear();
  432. }
  433. @SuppressWarnings("deprecation")
  434. public void renderTooltip(QueuedTooltip tooltip) {
  435. if (tooltip.getConsumer() == null)
  436. renderTooltip(tooltip.getText(), tooltip.getX(), tooltip.getY());
  437. else
  438. tooltip.getConsumer().accept(tooltip);
  439. }
  440. public void renderTooltip(List<String> lines, int mouseX, int mouseY) {
  441. if (lines.isEmpty())
  442. return;
  443. tooltipWidth = lines.stream().map(font::getStringWidth).max(Integer::compareTo).get();
  444. tooltipHeight = lines.size() <= 1 ? 8 : lines.size() * 10;
  445. tooltipLines = lines;
  446. ScreenHelper.drawHoveringWidget(mouseX, mouseY, renderTooltipCallback, tooltipWidth, tooltipHeight, 0);
  447. }
  448. private boolean hasSameListContent(List<ItemStack> list1, List<ItemStack> list2) {
  449. list1.sort(Comparator.comparing(Object::toString));
  450. list2.sort(Comparator.comparing(Object::toString));
  451. return CollectionUtils.mapAndJoinToString(list1, Object::toString, "").equals(CollectionUtils.mapAndJoinToString(list2, Object::toString, ""));
  452. }
  453. public void addTooltip(@Nullable QueuedTooltip queuedTooltip) {
  454. if (queuedTooltip != null)
  455. QUEUED_TOOLTIPS.add(queuedTooltip);
  456. }
  457. public void renderWidgets(int int_1, int int_2, float float_1) {
  458. if (!ScreenHelper.isOverlayVisible())
  459. return;
  460. if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled())
  461. buttonLeft.enabled = buttonRight.enabled = getTotalPage() > 0;
  462. widgets.forEach(widget -> {
  463. GuiLighting.disable();
  464. widget.render(int_1, int_2, float_1);
  465. });
  466. GuiLighting.disable();
  467. }
  468. private int getTotalPage() {
  469. return entryListWidget.getTotalPage();
  470. }
  471. @Override
  472. public boolean mouseScrolled(double i, double j, double amount) {
  473. if (!ScreenHelper.isOverlayVisible())
  474. return false;
  475. if (isInside(PointHelper.fromMouse())) {
  476. if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().isEntryListWidgetScrolled()) {
  477. if (amount > 0 && buttonLeft.enabled)
  478. buttonLeft.onPressed();
  479. else if (amount < 0 && buttonRight.enabled)
  480. buttonRight.onPressed();
  481. else
  482. return false;
  483. return true;
  484. } else {
  485. return entryListWidget.mouseScrolled(i, j, amount);
  486. }
  487. }
  488. for (Widget widget : widgets)
  489. if (widget.mouseScrolled(i, j, amount))
  490. return true;
  491. return false;
  492. }
  493. @Override
  494. public boolean keyPressed(int int_1, int int_2, int int_3) {
  495. if (ScreenHelper.isOverlayVisible())
  496. for (Element listener : widgets)
  497. if (listener.keyPressed(int_1, int_2, int_3))
  498. return true;
  499. if (ClientHelper.getInstance().getHideKeyBinding().matchesKey(int_1, int_2)) {
  500. ScreenHelper.toggleOverlayVisible();
  501. return true;
  502. }
  503. ItemStack itemStack = null;
  504. if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen)
  505. if (ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot() != null && !ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot().getStack().isEmpty())
  506. itemStack = ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot().getStack();
  507. if (itemStack != null && !itemStack.isEmpty()) {
  508. if (ClientHelper.getInstance().getRecipeKeyBinding().matchesKey(int_1, int_2))
  509. return ClientHelper.getInstance().executeRecipeKeyBind(itemStack);
  510. else if (ClientHelper.getInstance().getUsageKeyBinding().matchesKey(int_1, int_2))
  511. return ClientHelper.getInstance().executeUsageKeyBind(itemStack);
  512. }
  513. if (!ScreenHelper.isOverlayVisible())
  514. return false;
  515. if (ClientHelper.getInstance().getFocusSearchFieldKeyBinding().matchesKey(int_1, int_2)) {
  516. ScreenHelper.searchField.setFocused(true);
  517. setFocused(ScreenHelper.searchField);
  518. ScreenHelper.searchField.keybindFocusTime = System.currentTimeMillis();
  519. ScreenHelper.searchField.keybindFocusKey = int_1;
  520. return true;
  521. }
  522. return false;
  523. }
  524. @Override
  525. public boolean charTyped(char char_1, int int_1) {
  526. if (!ScreenHelper.isOverlayVisible())
  527. return false;
  528. for (Element listener : widgets)
  529. if (listener.charTyped(char_1, int_1))
  530. return true;
  531. return false;
  532. }
  533. @Override
  534. public List<? extends Element> children() {
  535. return widgets;
  536. }
  537. @Override
  538. public boolean mouseClicked(double double_1, double double_2, int int_1) {
  539. if (!ScreenHelper.isOverlayVisible())
  540. return false;
  541. if (MinecraftClient.getInstance().currentScreen instanceof AbstractContainerScreen && RoughlyEnoughItemsCore.getConfigManager().getConfig().areClickableRecipeArrowsEnabled()) {
  542. ContainerScreenHooks hooks = (ContainerScreenHooks) MinecraftClient.getInstance().currentScreen;
  543. for (RecipeHelperImpl.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
  544. if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
  545. if (area.getRectangle().contains(double_1 - hooks.rei_getContainerLeft(), double_2 - hooks.rei_getContainerTop())) {
  546. ClientHelper.getInstance().executeViewAllRecipesFromCategories(Arrays.asList(area.getCategories()));
  547. MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
  548. return true;
  549. }
  550. }
  551. for (Element element : widgets)
  552. if (element.mouseClicked(double_1, double_2, int_1)) {
  553. this.setFocused(element);
  554. if (int_1 == 0)
  555. this.setDragging(true);
  556. return true;
  557. }
  558. return false;
  559. }
  560. @Override
  561. public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
  562. if (!ScreenHelper.isOverlayVisible())
  563. return false;
  564. return this.getFocused() != null && this.isDragging() && int_1 == 0 ? this.getFocused().mouseDragged(double_1, double_2, int_1, double_3, double_4) : false;
  565. }
  566. public boolean isInside(double mouseX, double mouseY) {
  567. if (!rectangle.contains(mouseX, mouseY))
  568. return false;
  569. for (DisplayHelper.DisplayBoundsHandler<?> handler : RoughlyEnoughItemsCore.getDisplayHelper().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
  570. ActionResult in = handler.isInZone(!RoughlyEnoughItemsCore.getConfigManager().getConfig().isLeftHandSidePanel(), mouseX, mouseY);
  571. if (in != ActionResult.PASS)
  572. return in == ActionResult.SUCCESS;
  573. }
  574. return true;
  575. }
  576. public boolean isNotInExclusionZones(double mouseX, double mouseY) {
  577. for (DisplayHelper.DisplayBoundsHandler<?> handler : RoughlyEnoughItemsCore.getDisplayHelper().getSortedBoundsHandlers(MinecraftClient.getInstance().currentScreen.getClass())) {
  578. ActionResult in = handler.isInZone(true, mouseX, mouseY);
  579. if (in != ActionResult.PASS)
  580. return in == ActionResult.SUCCESS;
  581. in = handler.isInZone(false, mouseX, mouseY);
  582. if (in != ActionResult.PASS)
  583. return in == ActionResult.SUCCESS;
  584. }
  585. return true;
  586. }
  587. public boolean isInside(Point point) {
  588. return isInside(point.getX(), point.getY());
  589. }
  590. }