RecipeViewingWidget.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package me.shedaniel.rei.gui.widget;
  2. import com.google.common.collect.Lists;
  3. import com.mojang.blaze3d.platform.GlStateManager;
  4. import me.shedaniel.rei.api.IRecipeCategory;
  5. import me.shedaniel.rei.api.IRecipeDisplay;
  6. import me.shedaniel.rei.client.ClientHelper;
  7. import me.shedaniel.rei.client.GuiHelper;
  8. import me.shedaniel.rei.listeners.IMixinContainerGui;
  9. import net.minecraft.client.MinecraftClient;
  10. import net.minecraft.client.audio.PositionedSoundInstance;
  11. import net.minecraft.client.gui.Gui;
  12. import net.minecraft.client.gui.GuiEventListener;
  13. import net.minecraft.client.render.GuiLighting;
  14. import net.minecraft.client.util.Window;
  15. import net.minecraft.sound.SoundEvents;
  16. import net.minecraft.util.Identifier;
  17. import net.minecraft.util.math.MathHelper;
  18. import java.awt.*;
  19. import java.util.*;
  20. import java.util.List;
  21. public class RecipeViewingWidget extends Gui {
  22. private static final Identifier CREATIVE_INVENTORY_TABS = new Identifier("textures/gui/container/creative_inventory/tabs.png");
  23. private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
  24. public final int guiWidth = 176;
  25. public final int guiHeight = 186;
  26. private List<IWidget> widgets;
  27. private List<TabWidget> tabs;
  28. private Window window;
  29. private Rectangle bounds;
  30. private Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap;
  31. private List<IRecipeCategory> categories;
  32. private IRecipeCategory selectedCategory;
  33. private IMixinContainerGui parent;
  34. private int page, categoryPages;
  35. private ButtonWidget recipeBack, recipeNext, categoryBack, categoryNext;
  36. public RecipeViewingWidget(Window window, IMixinContainerGui parent, Map<IRecipeCategory, List<IRecipeDisplay>> categoriesMap) {
  37. this.categoryPages = 0;
  38. this.parent = parent;
  39. this.window = window;
  40. this.widgets = Lists.newArrayList();
  41. this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, guiWidth, guiHeight);
  42. this.categoriesMap = categoriesMap;
  43. this.categories = new LinkedList<>(categoriesMap.keySet());
  44. Collections.reverse(categories);
  45. this.selectedCategory = categories.get(0);
  46. this.tabs = new ArrayList<>();
  47. }
  48. public IMixinContainerGui getParent() {
  49. return parent;
  50. }
  51. @Override
  52. public boolean keyPressed(int int_1, int int_2, int int_3) {
  53. if (int_1 == 256 && this.doesEscapeKeyClose()) {
  54. MinecraftClient.getInstance().openGui(parent.getContainerGui());
  55. return true;
  56. }
  57. for(GuiEventListener listener : listeners)
  58. if (listener.keyPressed(int_1, int_2, int_3))
  59. return true;
  60. return super.keyPressed(int_1, int_2, int_3);
  61. }
  62. @Override
  63. public void onClosed() {
  64. GuiHelper.resetOverlay();
  65. }
  66. @Override
  67. protected void onInitialized() {
  68. super.onInitialized();
  69. this.tabs.clear();
  70. this.widgets.clear();
  71. this.bounds = new Rectangle(window.getScaledWidth() / 2 - guiWidth / 2, window.getScaledHeight() / 2 - guiHeight / 2, guiWidth, guiHeight);
  72. widgets.add(categoryBack = new ButtonWidget((int) bounds.getX() + 5, (int) bounds.getY() + 5, 12, 12, "<") {
  73. @Override
  74. public void onPressed(int button, double mouseX, double mouseY) {
  75. int currentCategoryIndex = categories.indexOf(selectedCategory);
  76. currentCategoryIndex--;
  77. if (currentCategoryIndex < 0)
  78. currentCategoryIndex = categories.size() - 1;
  79. selectedCategory = categories.get(currentCategoryIndex);
  80. categoryPages = MathHelper.floor(currentCategoryIndex / 6d);
  81. RecipeViewingWidget.this.onInitialized();
  82. }
  83. });
  84. widgets.add(categoryNext = new ButtonWidget((int) bounds.getX() + 159, (int) bounds.getY() + 5, 12, 12, ">") {
  85. @Override
  86. public void onPressed(int button, double mouseX, double mouseY) {
  87. int currentCategoryIndex = categories.indexOf(selectedCategory);
  88. currentCategoryIndex++;
  89. if (currentCategoryIndex >= categories.size())
  90. currentCategoryIndex = 0;
  91. selectedCategory = categories.get(currentCategoryIndex);
  92. categoryPages = MathHelper.floor(currentCategoryIndex / 6d);
  93. RecipeViewingWidget.this.onInitialized();
  94. }
  95. });
  96. categoryBack.enabled = categories.size() > 1;
  97. categoryNext.enabled = categories.size() > 1;
  98. widgets.add(recipeBack = new ButtonWidget((int) bounds.getX() + 5, (int) bounds.getY() + 21, 12, 12, "<") {
  99. @Override
  100. public void onPressed(int button, double mouseX, double mouseY) {
  101. page--;
  102. if (page < 0)
  103. page = getTotalPages(selectedCategory) - 1;
  104. RecipeViewingWidget.this.onInitialized();
  105. }
  106. });
  107. widgets.add(recipeNext = new ButtonWidget((int) bounds.getX() + 159, (int) bounds.getY() + 21, 12, 12, ">") {
  108. @Override
  109. public void onPressed(int button, double mouseX, double mouseY) {
  110. page++;
  111. if (page >= getTotalPages(selectedCategory))
  112. page = 0;
  113. RecipeViewingWidget.this.onInitialized();
  114. }
  115. });
  116. recipeBack.enabled = categoriesMap.get(selectedCategory).size() > getRecipesPerPage();
  117. recipeNext.enabled = categoriesMap.get(selectedCategory).size() > getRecipesPerPage();
  118. widgets.add(new LabelWidget((int) bounds.getCenterX(), (int) bounds.getY() + 7, "") {
  119. @Override
  120. public void draw(int mouseX, int mouseY, float partialTicks) {
  121. this.text = selectedCategory.getCategoryName();
  122. super.draw(mouseX, mouseY, partialTicks);
  123. }
  124. });
  125. widgets.add(new LabelWidget((int) bounds.getCenterX(), (int) bounds.getY() + 23, "") {
  126. @Override
  127. public void draw(int mouseX, int mouseY, float partialTicks) {
  128. this.text = String.format("%d/%d", page + 1, getTotalPages(selectedCategory));
  129. super.draw(mouseX, mouseY, partialTicks);
  130. }
  131. });
  132. for(int i = 0; i < 6; i++) {
  133. int j = i + categoryPages * 6;
  134. if (categories.size() > j) {
  135. TabWidget tab;
  136. tabs.add(tab = new TabWidget(i, this, new Rectangle(bounds.x + 4 + 28 * i, bounds.y - 28, 28, 28)) {
  137. @Override
  138. public boolean onMouseClick(int button, double mouseX, double mouseY) {
  139. if (getBounds().contains(mouseX, mouseY)) {
  140. MinecraftClient.getInstance().getSoundLoader().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
  141. if (getId() + categoryPages * 6 == categories.indexOf(selectedCategory))
  142. return false;
  143. selectedCategory = categories.get(getId() + categoryPages * 6);
  144. page = 0;
  145. RecipeViewingWidget.this.onInitialized();
  146. return true;
  147. }
  148. return false;
  149. }
  150. });
  151. tab.setItem(categories.get(j).getCategoryIcon(), categories.get(j).getCategoryName(), tab.getId() + categoryPages * 6 == categories.indexOf(selectedCategory));
  152. }
  153. }
  154. if (page * getRecipesPerPage() < categoriesMap.get(selectedCategory).size()) {
  155. IRecipeDisplay topDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage());
  156. widgets.addAll(selectedCategory.setupDisplay(getParent(), topDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 40, 150, selectedCategory.usesFullPage() ? 118 : 66)));
  157. if (!selectedCategory.usesFullPage() && page * getRecipesPerPage() + 1 < categoriesMap.get(selectedCategory).size()) {
  158. IRecipeDisplay middleDisplay = categoriesMap.get(selectedCategory).get(page * getRecipesPerPage() + 1);
  159. widgets.addAll(selectedCategory.setupDisplay(getParent(), middleDisplay, new Rectangle((int) getBounds().getCenterX() - 75, getBounds().y + 108, 150, 66)));
  160. }
  161. }
  162. GuiHelper.getOverlay(parent.getContainerGui()).onInitialized();
  163. listeners.addAll(tabs);
  164. listeners.add(GuiHelper.getOverlay(parent.getContainerGui()));
  165. listeners.addAll(widgets);
  166. }
  167. private int getRecipesPerPage() {
  168. if (selectedCategory.usesFullPage())
  169. return 1;
  170. return 2;
  171. }
  172. @Override
  173. public void draw(int mouseX, int mouseY, float partialTicks) {
  174. drawBackground();
  175. tabs.stream().filter(tabWidget -> {
  176. return !tabWidget.isSelected();
  177. }).forEach(tabWidget -> tabWidget.draw(mouseX, mouseY, partialTicks));
  178. GuiLighting.disable();
  179. super.draw(mouseX, mouseY, partialTicks);
  180. widgets.forEach(widget -> {
  181. GuiLighting.disable();
  182. widget.draw(mouseX, mouseY, partialTicks);
  183. });
  184. GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  185. GuiLighting.disable();
  186. tabs.stream().filter(TabWidget::isSelected).forEach(tabWidget -> tabWidget.draw(mouseX, mouseY, partialTicks));
  187. GuiHelper.getOverlay(parent.getContainerGui()).render(mouseX, mouseY, partialTicks);
  188. }
  189. @Override
  190. public void drawBackground() {
  191. drawBackground(0);
  192. GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  193. GuiLighting.disable();
  194. this.client.getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  195. this.drawTexturedRect((int) bounds.getX(), (int) bounds.getY(), 0, 0, (int) bounds.getWidth(), (int) bounds.getHeight());
  196. }
  197. public int getTotalPages(IRecipeCategory category) {
  198. return MathHelper.ceil(categoriesMap.get(category).size() / (double) getRecipesPerPage());
  199. }
  200. public Rectangle getBounds() {
  201. return bounds;
  202. }
  203. @Override
  204. public boolean charTyped(char char_1, int int_1) {
  205. for(GuiEventListener listener : listeners)
  206. if (listener.charTyped(char_1, int_1))
  207. return true;
  208. return super.charTyped(char_1, int_1);
  209. }
  210. @Override
  211. public boolean mouseScrolled(double amount) {
  212. for(GuiEventListener listener : listeners)
  213. if (listener.mouseScrolled(amount))
  214. return true;
  215. if (getBounds().contains(ClientHelper.getMouseLocation())) {
  216. if (amount > 0 && recipeBack.enabled)
  217. recipeBack.onPressed(0, 0, 0);
  218. else if (amount < 0 && recipeNext.enabled)
  219. recipeNext.onPressed(0, 0, 0);
  220. }
  221. if ((new Rectangle(bounds.x, bounds.y - 28, bounds.width, 28)).contains(ClientHelper.getMouseLocation())) {
  222. if (amount > 0 && categoryBack.enabled)
  223. categoryBack.onPressed(0, 0, 0);
  224. else if (amount < 0 && categoryNext.enabled)
  225. categoryNext.onPressed(0, 0, 0);
  226. }
  227. return super.mouseScrolled(amount);
  228. }
  229. @Override
  230. public boolean mouseClicked(double double_1, double double_2, int int_1) {
  231. for(GuiEventListener entry : getEntries())
  232. if (entry.mouseClicked(double_1, double_2, int_1)) {
  233. focusOn(entry);
  234. if (int_1 == 0)
  235. setActive(true);
  236. return true;
  237. }
  238. return false;
  239. }
  240. }