ContainerScreenOverlay.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. package me.shedaniel.rei.gui;
  2. import com.google.common.collect.Lists;
  3. import com.mojang.blaze3d.platform.GlStateManager;
  4. import me.shedaniel.cloth.ClothInitializer;
  5. import me.shedaniel.rei.RoughlyEnoughItemsCore;
  6. import me.shedaniel.rei.client.ClientHelper;
  7. import me.shedaniel.rei.client.ScreenHelper;
  8. import me.shedaniel.rei.client.Weather;
  9. import me.shedaniel.rei.gui.widget.*;
  10. import net.minecraft.client.MinecraftClient;
  11. import net.minecraft.client.audio.PositionedSoundInstance;
  12. import net.minecraft.client.gui.ContainerScreen;
  13. import net.minecraft.client.gui.InputListener;
  14. import net.minecraft.client.gui.Screen;
  15. import net.minecraft.client.gui.ScreenComponent;
  16. import net.minecraft.client.render.GuiLighting;
  17. import net.minecraft.client.resource.language.I18n;
  18. import net.minecraft.client.util.Window;
  19. import net.minecraft.client.world.ClientWorld;
  20. import net.minecraft.item.ItemStack;
  21. import net.minecraft.sound.SoundEvents;
  22. import net.minecraft.text.TranslatableTextComponent;
  23. import net.minecraft.util.Identifier;
  24. import net.minecraft.util.math.MathHelper;
  25. import net.minecraft.world.GameMode;
  26. import java.awt.*;
  27. import java.util.Collections;
  28. import java.util.LinkedList;
  29. import java.util.List;
  30. import java.util.Optional;
  31. import java.util.stream.Collectors;
  32. public class ContainerScreenOverlay extends ScreenComponent {
  33. private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
  34. private static final List<QueuedTooltip> QUEUED_TOOLTIPS = Lists.newArrayList();
  35. public static String searchTerm = "";
  36. private static int page = 0;
  37. private static ItemListOverlay itemListOverlay;
  38. private final List<Widget> widgets = Lists.newArrayList();
  39. private Rectangle rectangle;
  40. private Window window;
  41. private ButtonWidget buttonLeft, buttonRight;
  42. private int lastLeft;
  43. public static ItemListOverlay getItemListOverlay() {
  44. return itemListOverlay;
  45. }
  46. public void onInitialized() {
  47. onInitialized(false);
  48. }
  49. public void onInitialized(boolean setPage) {
  50. //Update Variables
  51. this.widgets.clear();
  52. this.window = MinecraftClient.getInstance().window;
  53. this.rectangle = calculateBoundary();
  54. this.lastLeft = getLeft();
  55. widgets.add(this.itemListOverlay = new ItemListOverlay(page));
  56. this.itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  57. widgets.add(buttonLeft = new ButtonWidget(rectangle.x, rectangle.y + 5, 16, 16, new TranslatableTextComponent("text.rei.left_arrow")) {
  58. @Override
  59. public void onPressed() {
  60. page--;
  61. if (page < 0)
  62. page = getTotalPage();
  63. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  64. }
  65. @Override
  66. public Optional<String> getTooltips() {
  67. return Optional.ofNullable(I18n.translate("text.rei.previous_page"));
  68. }
  69. @Override
  70. public void setHasFocus(boolean boolean_1) {
  71. }
  72. });
  73. widgets.add(buttonRight = new ButtonWidget(rectangle.x + rectangle.width - 18, rectangle.y + 5, 16, 16, new TranslatableTextComponent("text.rei.right_arrow")) {
  74. @Override
  75. public void onPressed() {
  76. page++;
  77. if (page > getTotalPage())
  78. page = 0;
  79. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  80. }
  81. @Override
  82. public Optional<String> getTooltips() {
  83. return Optional.ofNullable(I18n.translate("text.rei.next_page"));
  84. }
  85. @Override
  86. public void setHasFocus(boolean boolean_1) {
  87. }
  88. });
  89. if (setPage)
  90. page = MathHelper.clamp(page, 0, getTotalPage());
  91. widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? window.getScaledWidth() - 30 : 10, 10, 20, 20, "") {
  92. @Override
  93. public void onPressed() {
  94. if (Screen.isShiftPressed()) {
  95. ClientHelper.setCheating(!ClientHelper.isCheating());
  96. return;
  97. }
  98. ClientHelper.openConfigWindow(ScreenHelper.getLastContainerScreen());
  99. }
  100. @Override
  101. public void draw(int mouseX, int mouseY, float partialTicks) {
  102. super.draw(mouseX, mouseY, partialTicks);
  103. GuiLighting.disable();
  104. if (ClientHelper.isCheating())
  105. drawRect(getBounds().x, getBounds().y, getBounds().x + 20, getBounds().y + 20, new Color(255, 0, 0, 42).getRGB());
  106. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  107. GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  108. drawTexturedRect(getBounds().x + 3, getBounds().y + 3, 0, 0, 14, 14);
  109. }
  110. @Override
  111. public Optional<String> getTooltips() {
  112. String tooltips = I18n.translate("text.rei.config_tooltip");
  113. tooltips += "\n ";
  114. if (!ClientHelper.isCheating())
  115. tooltips += "\n§c§m" + I18n.translate("text.rei.cheating");
  116. else
  117. tooltips += "\n§a" + I18n.translate("text.rei.cheating");
  118. return Optional.ofNullable(tooltips);
  119. }
  120. @Override
  121. public void setHasFocus(boolean boolean_1) {
  122. }
  123. });
  124. if (RoughlyEnoughItemsCore.getConfigManager().getConfig().showUtilsButtons) {
  125. widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? window.getScaledWidth() - 55 : 35, 10, 20, 20, "") {
  126. @Override
  127. public void onPressed() {
  128. MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().gamemodeCommand.replaceAll("\\{gamemode}", getNextGameMode().getName()));
  129. }
  130. @Override
  131. public void draw(int mouseX, int mouseY, float partialTicks) {
  132. text = getGameModeShortText(getCurrentGameMode());
  133. super.draw(mouseX, mouseY, partialTicks);
  134. }
  135. @Override
  136. public Optional<String> getTooltips() {
  137. return Optional.ofNullable(I18n.translate("text.rei.gamemode_button.tooltip", getGameModeText(getNextGameMode())));
  138. }
  139. @Override
  140. public void setHasFocus(boolean boolean_1) {
  141. }
  142. });
  143. widgets.add(new ButtonWidget(RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel ? window.getScaledWidth() - 80 : 60, 10, 20, 20, "") {
  144. @Override
  145. public void onPressed() {
  146. MinecraftClient.getInstance().player.sendChatMessage(RoughlyEnoughItemsCore.getConfigManager().getConfig().weatherCommand.replaceAll("\\{weather}", getNextWeather().name().toLowerCase()));
  147. }
  148. @Override
  149. public void draw(int mouseX, int mouseY, float partialTicks) {
  150. super.draw(mouseX, mouseY, partialTicks);
  151. GuiLighting.disable();
  152. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  153. GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  154. drawTexturedRect(getBounds().x + 3, getBounds().y + 3, getCurrentWeather().getId() * 14, 14, 14, 14);
  155. }
  156. @Override
  157. public Optional<String> getTooltips() {
  158. return Optional.ofNullable(I18n.translate("text.rei.weather_button.tooltip", I18n.translate(getNextWeather().getTranslateKey())));
  159. }
  160. @Override
  161. public void setHasFocus(boolean boolean_1) {
  162. }
  163. });
  164. }
  165. widgets.add(new ClickableLabelWidget(rectangle.x + (rectangle.width / 2), rectangle.y + 10, "") {
  166. @Override
  167. public void draw(int mouseX, int mouseY, float partialTicks) {
  168. page = MathHelper.clamp(page, 0, getTotalPage());
  169. this.text = String.format("%s/%s", page + 1, getTotalPage() + 1);
  170. super.draw(mouseX, mouseY, partialTicks);
  171. if (isHighlighted(mouseX, mouseY))
  172. addTooltip(QueuedTooltip.create(I18n.translate("text.rei.go_back_first_page").split("\n")));
  173. else if (focused)
  174. ScreenHelper.getLastOverlay().addTooltip(QueuedTooltip.create(new Point(x, y), I18n.translate("text.rei.go_back_first_page").split("\n")));
  175. }
  176. @Override
  177. public void onLabelClicked() {
  178. MinecraftClient.getInstance().getSoundLoader().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
  179. page = 0;
  180. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  181. }
  182. @Override
  183. public void setHasFocus(boolean boolean_1) {
  184. }
  185. });
  186. if (ScreenHelper.searchField == null)
  187. ScreenHelper.searchField = new TextFieldWidget(0, 0, 0, 0) {
  188. @Override
  189. public boolean mouseClicked(double double_1, double double_2, int int_1) {
  190. if (isVisible() && getBounds().contains(double_1, double_2) && int_1 == 1) {
  191. setText("");
  192. return true;
  193. }
  194. return super.mouseClicked(double_1, double_2, int_1);
  195. }
  196. };
  197. ScreenHelper.searchField.setChangedListener(s -> {
  198. searchTerm = s;
  199. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  200. });
  201. ScreenHelper.searchField.getBounds().setBounds(getTextFieldArea());
  202. this.widgets.add(ScreenHelper.searchField);
  203. ScreenHelper.searchField.setText(searchTerm);
  204. if (RoughlyEnoughItemsCore.getConfigManager().getConfig().enableCraftableOnlyButton)
  205. this.widgets.add(new CraftableToggleButtonWidget(getCraftableToggleArea()) {
  206. @Override
  207. public void onPressed() {
  208. RoughlyEnoughItemsCore.getConfigManager().toggleCraftableOnly();
  209. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  210. }
  211. });
  212. this.itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  213. }
  214. private Weather getNextWeather() {
  215. try {
  216. Weather current = getCurrentWeather();
  217. int next = current.getId() + 1;
  218. if (next >= 3)
  219. next = 0;
  220. return Weather.byId(next);
  221. } catch (Exception e) {
  222. return Weather.CLEAR;
  223. }
  224. }
  225. private Weather getCurrentWeather() {
  226. ClientWorld world = MinecraftClient.getInstance().world;
  227. if (world.isThundering())
  228. return Weather.THUNDER;
  229. if (world.getLevelProperties().isRaining())
  230. return Weather.RAIN;
  231. return Weather.CLEAR;
  232. }
  233. private String getGameModeShortText(GameMode gameMode) {
  234. return I18n.translate("text.rei.short_gamemode." + gameMode.getName());
  235. }
  236. private String getGameModeText(GameMode gameMode) {
  237. return I18n.translate("selectWorld.gameMode." + gameMode.getName());
  238. }
  239. private GameMode getNextGameMode() {
  240. try {
  241. GameMode current = getCurrentGameMode();
  242. int next = current.getId() + 1;
  243. if (next > 3)
  244. next = 0;
  245. return GameMode.byId(next);
  246. } catch (Exception e) {
  247. return GameMode.INVALID;
  248. }
  249. }
  250. private GameMode getCurrentGameMode() {
  251. return MinecraftClient.getInstance().getNetworkHandler().method_2871(MinecraftClient.getInstance().player.getGameProfile().getId()).getGameMode();
  252. }
  253. private Rectangle getTextFieldArea() {
  254. int widthRemoved = RoughlyEnoughItemsCore.getConfigManager().getConfig().enableCraftableOnlyButton ? 22 : 2;
  255. if (RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField)
  256. return new Rectangle(rectangle.x + 2, window.getScaledHeight() - 22, rectangle.width - 6 - widthRemoved, 18);
  257. if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
  258. RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  259. return new Rectangle(widget.getBounds().x, window.getScaledHeight() - 22, widget.getBounds().width - widthRemoved, 18);
  260. }
  261. return new Rectangle(ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft(), window.getScaledHeight() - 22, ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth() - widthRemoved, 18);
  262. }
  263. private Rectangle getCraftableToggleArea() {
  264. Rectangle searchBoxArea = getTextFieldArea();
  265. searchBoxArea.setLocation(searchBoxArea.x + searchBoxArea.width + 4, searchBoxArea.y - 1);
  266. searchBoxArea.setSize(20, 20);
  267. return searchBoxArea;
  268. }
  269. private String getCheatModeText() {
  270. return I18n.translate(String.format("%s%s", "text.rei.", ClientHelper.isCheating() ? "cheat" : "nocheat"));
  271. }
  272. private Rectangle getItemListArea() {
  273. return new Rectangle(rectangle.x + 2, rectangle.y + 24, rectangle.width - 4, rectangle.height - (RoughlyEnoughItemsCore.getConfigManager().getConfig().sideSearchField ? 27 + 22 : 27));
  274. }
  275. public Rectangle getRectangle() {
  276. return rectangle;
  277. }
  278. public void drawOverlay(int mouseX, int mouseY, float partialTicks) {
  279. List<ItemStack> currentStacks = ClientHelper.getInventoryItemsTypes();
  280. if (getLeft() != lastLeft)
  281. onInitialized(true);
  282. else if (RoughlyEnoughItemsCore.getConfigManager().isCraftableOnlyEnabled() && (!hasSameListContent(new LinkedList<>(ScreenHelper.inventoryStacks), currentStacks) || (currentStacks.size() != ScreenHelper.inventoryStacks.size()))) {
  283. ScreenHelper.inventoryStacks = ClientHelper.getInventoryItemsTypes();
  284. itemListOverlay.updateList(getItemListArea(), page, searchTerm);
  285. }
  286. GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  287. GuiLighting.disable();
  288. this.draw(mouseX, mouseY, partialTicks);
  289. GuiLighting.disable();
  290. Screen currentScreen = MinecraftClient.getInstance().currentScreen;
  291. if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
  292. QUEUED_TOOLTIPS.stream().filter(queuedTooltip -> queuedTooltip != null).forEach(queuedTooltip -> MinecraftClient.getInstance().currentScreen.drawTooltip(queuedTooltip.getText(), queuedTooltip.getLocation().x, queuedTooltip.getLocation().y));
  293. QUEUED_TOOLTIPS.clear();
  294. GuiLighting.disable();
  295. }
  296. private boolean hasSameListContent(List<ItemStack> list1, List<ItemStack> list2) {
  297. Collections.sort(list1, (itemStack, t1) -> {
  298. return ItemListOverlay.tryGetItemStackName(itemStack).compareToIgnoreCase(ItemListOverlay.tryGetItemStackName(t1));
  299. });
  300. Collections.sort(list2, (itemStack, t1) -> {
  301. return ItemListOverlay.tryGetItemStackName(itemStack).compareToIgnoreCase(ItemListOverlay.tryGetItemStackName(t1));
  302. });
  303. String lastString = String.join("", list1.stream().map(itemStack -> {
  304. return ItemListOverlay.tryGetItemStackName(itemStack);
  305. }).collect(Collectors.toList())), currentString = String.join("", list2.stream().map(itemStack -> {
  306. return ItemListOverlay.tryGetItemStackName(itemStack);
  307. }).collect(Collectors.toList()));
  308. return lastString.equals(currentString);
  309. }
  310. public void addTooltip(QueuedTooltip queuedTooltip) {
  311. QUEUED_TOOLTIPS.add(queuedTooltip);
  312. }
  313. public void draw(int int_1, int int_2, float float_1) {
  314. if (!ScreenHelper.isOverlayVisible())
  315. return;
  316. buttonLeft.enabled = itemListOverlay.getWidgets().size() > 0;
  317. buttonRight.enabled = itemListOverlay.getWidgets().size() > 0;
  318. widgets.forEach(widget -> {
  319. GuiLighting.disable();
  320. widget.draw(int_1, int_2, float_1);
  321. });
  322. GuiLighting.disable();
  323. }
  324. private Rectangle calculateBoundary() {
  325. if (!RoughlyEnoughItemsCore.getConfigManager().getConfig().mirrorItemPanel) {
  326. int startX = ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() + ScreenHelper.getLastContainerScreenHooks().rei_getContainerWidth() + 10;
  327. int width = window.getScaledWidth() - startX;
  328. if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
  329. RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  330. startX = widget.getBounds().x + widget.getBounds().width + 10;
  331. width = window.getScaledWidth() - startX;
  332. }
  333. return new Rectangle(startX, 0, width, window.getScaledHeight());
  334. }
  335. return new Rectangle(4, 0, getLeft() - 6, window.getScaledHeight());
  336. }
  337. private int getLeft() {
  338. if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
  339. RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  340. return widget.getBounds().x;
  341. }
  342. if (MinecraftClient.getInstance().player.getRecipeBook().isGuiOpen())
  343. return ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft() - 147 - 30;
  344. return ScreenHelper.getLastContainerScreenHooks().rei_getContainerLeft();
  345. }
  346. private int getTotalPage() {
  347. return MathHelper.ceil(itemListOverlay.getCurrentDisplayed().size() / itemListOverlay.getTotalSlotsPerPage());
  348. }
  349. @Override
  350. public boolean mouseScrolled(double i, double j, double amount) {
  351. if (!ScreenHelper.isOverlayVisible())
  352. return false;
  353. if (rectangle.contains(ClothInitializer.clientUtils.getMouseLocation())) {
  354. if (amount > 0 && buttonLeft.enabled)
  355. buttonLeft.onPressed();
  356. else if (amount < 0 && buttonRight.enabled)
  357. buttonRight.onPressed();
  358. else
  359. return false;
  360. return true;
  361. }
  362. for(Widget widget : widgets)
  363. if (widget.mouseScrolled(i, j, amount))
  364. return true;
  365. return false;
  366. }
  367. @Override
  368. public boolean keyPressed(int int_1, int int_2, int int_3) {
  369. if (ScreenHelper.isOverlayVisible())
  370. for(InputListener listener : widgets)
  371. if (listener.keyPressed(int_1, int_2, int_3))
  372. return true;
  373. if (ClientHelper.HIDE.matchesKey(int_1, int_2)) {
  374. ScreenHelper.toggleOverlayVisible();
  375. return true;
  376. }
  377. if (!ScreenHelper.isOverlayVisible())
  378. return false;
  379. Point point = ClothInitializer.clientUtils.getMouseLocation();
  380. ItemStack itemStack = null;
  381. if (MinecraftClient.getInstance().currentScreen instanceof ContainerScreen)
  382. if (ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot() != null && !ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot().getStack().isEmpty())
  383. itemStack = ScreenHelper.getLastContainerScreenHooks().rei_getHoveredSlot().getStack();
  384. if (itemStack != null && !itemStack.isEmpty()) {
  385. if (ClientHelper.RECIPE.matchesKey(int_1, int_2))
  386. return ClientHelper.executeRecipeKeyBind(itemStack);
  387. else if (ClientHelper.USAGE.matchesKey(int_1, int_2))
  388. return ClientHelper.executeUsageKeyBind(itemStack);
  389. }
  390. return false;
  391. }
  392. @Override
  393. public boolean charTyped(char char_1, int int_1) {
  394. if (!ScreenHelper.isOverlayVisible())
  395. return false;
  396. for(InputListener listener : getInputListeners())
  397. if (listener.charTyped(char_1, int_1))
  398. return true;
  399. return super.charTyped(char_1, int_1);
  400. }
  401. @Override
  402. public List<? extends InputListener> getInputListeners() {
  403. return widgets;
  404. }
  405. @Override
  406. public boolean mouseClicked(double double_1, double double_2, int int_1) {
  407. if (!ScreenHelper.isOverlayVisible())
  408. return false;
  409. return super.mouseClicked(double_1, double_2, int_1);
  410. }
  411. }