ContainerScreenOverlay.java 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. /*
  2. * This file is licensed under the MIT License, part of Roughly Enough Items.
  3. * Copyright (c) 2018, 2019, 2020 shedaniel
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in all
  13. * copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. */
  23. package me.shedaniel.rei.gui;
  24. import com.google.common.collect.Lists;
  25. import com.mojang.blaze3d.systems.RenderSystem;
  26. import me.shedaniel.math.Point;
  27. import me.shedaniel.math.Rectangle;
  28. import me.shedaniel.math.impl.PointHelper;
  29. import me.shedaniel.rei.RoughlyEnoughItemsCore;
  30. import me.shedaniel.rei.api.*;
  31. import me.shedaniel.rei.api.widgets.Button;
  32. import me.shedaniel.rei.api.widgets.Tooltip;
  33. import me.shedaniel.rei.api.widgets.Widgets;
  34. import me.shedaniel.rei.gui.config.SearchFieldLocation;
  35. import me.shedaniel.rei.gui.modules.Menu;
  36. import me.shedaniel.rei.gui.modules.entries.GameModeMenuEntry;
  37. import me.shedaniel.rei.gui.modules.entries.WeatherMenuEntry;
  38. import me.shedaniel.rei.gui.widget.*;
  39. import me.shedaniel.rei.impl.ClientHelperImpl;
  40. import me.shedaniel.rei.impl.InternalWidgets;
  41. import me.shedaniel.rei.impl.ScreenHelper;
  42. import me.shedaniel.rei.impl.Weather;
  43. import me.shedaniel.rei.utils.CollectionUtils;
  44. import net.minecraft.block.Blocks;
  45. import net.minecraft.client.MinecraftClient;
  46. import net.minecraft.client.gui.Element;
  47. import net.minecraft.client.gui.screen.Screen;
  48. import net.minecraft.client.gui.screen.ingame.ContainerScreen;
  49. import net.minecraft.client.render.Tessellator;
  50. import net.minecraft.client.render.VertexConsumerProvider;
  51. import net.minecraft.client.render.item.ItemRenderer;
  52. import net.minecraft.client.resource.language.I18n;
  53. import net.minecraft.client.sound.PositionedSoundInstance;
  54. import net.minecraft.client.util.NarratorManager;
  55. import net.minecraft.client.util.Window;
  56. import net.minecraft.client.util.math.MatrixStack;
  57. import net.minecraft.client.util.math.Vector4f;
  58. import net.minecraft.client.world.ClientWorld;
  59. import net.minecraft.item.ItemStack;
  60. import net.minecraft.screen.slot.Slot;
  61. import net.minecraft.sound.SoundEvents;
  62. import net.minecraft.text.LiteralText;
  63. import net.minecraft.text.OrderedText;
  64. import net.minecraft.text.Text;
  65. import net.minecraft.text.TranslatableText;
  66. import net.minecraft.util.ActionResult;
  67. import net.minecraft.util.Identifier;
  68. import net.minecraft.util.math.Matrix4f;
  69. import net.minecraft.world.GameMode;
  70. import org.apache.logging.log4j.util.TriConsumer;
  71. import org.jetbrains.annotations.ApiStatus;
  72. import org.jetbrains.annotations.NotNull;
  73. import org.jetbrains.annotations.Nullable;
  74. import java.util.Arrays;
  75. import java.util.Comparator;
  76. import java.util.LinkedList;
  77. import java.util.List;
  78. @ApiStatus.Internal
  79. public class ContainerScreenOverlay extends WidgetWithBounds implements REIOverlay {
  80. private static final Identifier CHEST_GUI_TEXTURE = new Identifier("roughlyenoughitems", "textures/gui/recipecontainer.png");
  81. private static final List<Tooltip> TOOLTIPS = Lists.newArrayList();
  82. private static final List<Runnable> AFTER_RENDER = Lists.newArrayList();
  83. private static final EntryListWidget ENTRY_LIST_WIDGET = new EntryListWidget();
  84. private static FavoritesListWidget favoritesListWidget = null;
  85. private final List<Widget> widgets = Lists.newLinkedList();
  86. public boolean shouldReInit = false;
  87. private int tooltipWidth;
  88. private int tooltipHeight;
  89. private List<OrderedText> tooltipLines;
  90. public final TriConsumer<MatrixStack, Point, Float> renderTooltipCallback = (matrices, mouse, aFloat) -> {
  91. RenderSystem.disableRescaleNormal();
  92. RenderSystem.disableDepthTest();
  93. matrices.push();
  94. matrices.translate(0, 0, 999);
  95. int x = mouse.x;
  96. int y = mouse.y;
  97. this.fillGradient(matrices, x - 3, y - 4, x + tooltipWidth + 3, y - 3, -267386864, -267386864);
  98. this.fillGradient(matrices, x - 3, y + tooltipHeight + 3, x + tooltipWidth + 3, y + tooltipHeight + 4, -267386864, -267386864);
  99. this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y + tooltipHeight + 3, -267386864, -267386864);
  100. this.fillGradient(matrices, x - 4, y - 3, x - 3, y + tooltipHeight + 3, -267386864, -267386864);
  101. this.fillGradient(matrices, x + tooltipWidth + 3, y - 3, x + tooltipWidth + 4, y + tooltipHeight + 3, -267386864, -267386864);
  102. this.fillGradient(matrices, x - 3, y - 3 + 1, x - 3 + 1, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
  103. this.fillGradient(matrices, x + tooltipWidth + 2, y - 3 + 1, x + tooltipWidth + 3, y + tooltipHeight + 3 - 1, 1347420415, 1344798847);
  104. this.fillGradient(matrices, x - 3, y - 3, x + tooltipWidth + 3, y - 3 + 1, 1347420415, 1347420415);
  105. this.fillGradient(matrices, x - 3, y + tooltipHeight + 2, x + tooltipWidth + 3, y + tooltipHeight + 3, 1344798847, 1344798847);
  106. int currentY = y;
  107. VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
  108. Matrix4f matrix = matrices.peek().getModel();
  109. for (int lineIndex = 0; lineIndex < tooltipLines.size(); lineIndex++) {
  110. font.draw(tooltipLines.get(lineIndex), x, currentY, -1, true, matrix, immediate, false, 0, 15728880);
  111. currentY += lineIndex == 0 ? 12 : 10;
  112. }
  113. immediate.draw();
  114. matrices.pop();
  115. RenderSystem.enableDepthTest();
  116. RenderSystem.enableRescaleNormal();
  117. };
  118. private Rectangle bounds;
  119. private Window window;
  120. private Button leftButton, rightButton;
  121. @ApiStatus.Experimental
  122. private Rectangle subsetsButtonBounds;
  123. @ApiStatus.Experimental
  124. @Nullable
  125. private Menu subsetsMenu = null;
  126. private Widget wrappedSubsetsMenu = null;
  127. @Nullable
  128. private Menu weatherMenu = null;
  129. private Widget wrappedWeatherMenu = null;
  130. private boolean renderWeatherMenu = false;
  131. private Button weatherButton = null;
  132. @Nullable
  133. private Menu gameModeMenu = null;
  134. private Widget wrappedGameModeMenu = null;
  135. private boolean renderGameModeMenu = false;
  136. private Button gameModeButton = null;
  137. public static EntryListWidget getEntryListWidget() {
  138. return ENTRY_LIST_WIDGET;
  139. }
  140. @Nullable
  141. public static FavoritesListWidget getFavoritesListWidget() {
  142. return favoritesListWidget;
  143. }
  144. @ApiStatus.Experimental
  145. @Nullable
  146. public Menu getSubsetsMenu() {
  147. return subsetsMenu;
  148. }
  149. public void removeWeatherMenu() {
  150. this.renderWeatherMenu = false;
  151. Widget tmpWeatherMenu = wrappedWeatherMenu;
  152. AFTER_RENDER.add(() -> this.widgets.remove(tmpWeatherMenu));
  153. this.weatherMenu = null;
  154. this.wrappedWeatherMenu = null;
  155. }
  156. public void removeGameModeMenu() {
  157. this.renderGameModeMenu = false;
  158. Widget tmpGameModeMenu = wrappedGameModeMenu;
  159. AFTER_RENDER.add(() -> this.widgets.remove(tmpGameModeMenu));
  160. this.gameModeMenu = null;
  161. this.wrappedGameModeMenu = null;
  162. }
  163. @Override
  164. public void queueReloadOverlay() {
  165. shouldReInit = true;
  166. }
  167. public void init(boolean useless) {
  168. init();
  169. }
  170. public void init() {
  171. this.shouldReInit = false;
  172. //Update Variables
  173. this.children().clear();
  174. this.wrappedSubsetsMenu = null;
  175. this.subsetsMenu = null;
  176. this.weatherMenu = null;
  177. this.renderWeatherMenu = false;
  178. this.weatherButton = null;
  179. this.window = MinecraftClient.getInstance().getWindow();
  180. this.bounds = DisplayHelper.getInstance().getOverlayBounds(ConfigObject.getInstance().getDisplayPanelLocation(), MinecraftClient.getInstance().currentScreen);
  181. widgets.add(ENTRY_LIST_WIDGET);
  182. if (ConfigObject.getInstance().isFavoritesEnabled()) {
  183. if (favoritesListWidget == null)
  184. favoritesListWidget = new FavoritesListWidget();
  185. widgets.add(favoritesListWidget);
  186. }
  187. ENTRY_LIST_WIDGET.updateArea(ScreenHelper.getSearchField() == null ? "" : null);
  188. if (ScreenHelper.getSearchField() == null) {
  189. ScreenHelper.setSearchField(new OverlaySearchField(0, 0, 0, 0));
  190. }
  191. ScreenHelper.getSearchField().getBounds().setBounds(getSearchFieldArea());
  192. this.widgets.add(ScreenHelper.getSearchField());
  193. ScreenHelper.getSearchField().setChangedListener(s -> ENTRY_LIST_WIDGET.updateSearch(s, false));
  194. if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
  195. widgets.add(leftButton = Widgets.createButton(new Rectangle(bounds.x, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), new TranslatableText("text.rei.left_arrow"))
  196. .onClick(button -> {
  197. ENTRY_LIST_WIDGET.previousPage();
  198. if (ENTRY_LIST_WIDGET.getPage() < 0)
  199. ENTRY_LIST_WIDGET.setPage(ENTRY_LIST_WIDGET.getTotalPages() - 1);
  200. ENTRY_LIST_WIDGET.updateEntriesPosition();
  201. })
  202. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y))
  203. .tooltipLine(I18n.translate("text.rei.previous_page"))
  204. .focusable(false));
  205. widgets.add(rightButton = Widgets.createButton(new Rectangle(bounds.x + bounds.width - 18, bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 5, 16, 16), new TranslatableText("text.rei.right_arrow"))
  206. .onClick(button -> {
  207. ENTRY_LIST_WIDGET.nextPage();
  208. if (ENTRY_LIST_WIDGET.getPage() >= ENTRY_LIST_WIDGET.getTotalPages())
  209. ENTRY_LIST_WIDGET.setPage(0);
  210. ENTRY_LIST_WIDGET.updateEntriesPosition();
  211. })
  212. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y))
  213. .tooltipLine(I18n.translate("text.rei.next_page"))
  214. .focusable(false));
  215. }
  216. final Rectangle configButtonArea = getConfigButtonArea();
  217. Widget tmp;
  218. widgets.add(tmp = InternalWidgets.wrapLateRenderable(InternalWidgets.mergeWidgets(
  219. Widgets.createButton(configButtonArea, NarratorManager.EMPTY)
  220. .onClick(button -> {
  221. if (Screen.hasShiftDown()) {
  222. ClientHelper.getInstance().setCheating(!ClientHelper.getInstance().isCheating());
  223. return;
  224. }
  225. ConfigManager.getInstance().openConfigScreen(REIHelper.getInstance().getPreviousContainerScreen());
  226. })
  227. .onRender((matrices, button) -> {
  228. if (ClientHelper.getInstance().isCheating() && RoughlyEnoughItemsCore.hasOperatorPermission()) {
  229. button.setTint(RoughlyEnoughItemsCore.hasPermissionToUsePackets() ? 721354752 : 1476440063);
  230. } else {
  231. button.removeTint();
  232. }
  233. })
  234. .focusable(false)
  235. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y))
  236. .tooltipSupplier(button -> {
  237. String tooltips = I18n.translate("text.rei.config_tooltip");
  238. tooltips += "\n ";
  239. if (!ClientHelper.getInstance().isCheating())
  240. tooltips += "\n" + I18n.translate("text.rei.cheating_disabled");
  241. else if (!RoughlyEnoughItemsCore.hasOperatorPermission()) {
  242. if (minecraft.interactionManager.hasCreativeInventory())
  243. tooltips += "\n" + I18n.translate("text.rei.cheating_limited_creative_enabled");
  244. else tooltips += "\n" + I18n.translate("text.rei.cheating_enabled_no_perms");
  245. } else if (RoughlyEnoughItemsCore.hasPermissionToUsePackets())
  246. tooltips += "\n" + I18n.translate("text.rei.cheating_enabled");
  247. else
  248. tooltips += "\n" + I18n.translate("text.rei.cheating_limited_enabled");
  249. return tooltips;
  250. }),
  251. Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
  252. helper.setZOffset(helper.getZOffset() + 1);
  253. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  254. helper.drawTexture(matrices, configButtonArea.x + 3, configButtonArea.y + 3, 0, 0, 14, 14);
  255. })
  256. )
  257. ));
  258. tmp.setZ(600);
  259. if (ConfigObject.getInstance().doesShowUtilsButtons()) {
  260. widgets.add(gameModeButton = Widgets.createButton(ConfigObject.getInstance().isLowerConfigButton() ? new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20) : new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 55 : 35, 10, 20, 20), NarratorManager.EMPTY)
  261. .onRender((matrices, button) -> {
  262. boolean tmpRender = renderGameModeMenu;
  263. renderGameModeMenu = !renderWeatherMenu && (button.isFocused() || button.containsMouse(PointHelper.ofMouse()) || (wrappedGameModeMenu != null && wrappedGameModeMenu.containsMouse(PointHelper.ofMouse())));
  264. if (tmpRender != renderGameModeMenu) {
  265. if (renderGameModeMenu) {
  266. this.gameModeMenu = new Menu(new Point(button.getBounds().x, button.getBounds().getMaxY()),
  267. CollectionUtils.filterAndMap(Arrays.asList(GameMode.values()), mode -> mode != GameMode.NOT_SET, GameModeMenuEntry::new));
  268. if (ConfigObject.getInstance().isLeftHandSidePanel())
  269. this.gameModeMenu.menuStartPoint.x -= this.gameModeMenu.getBounds().width - this.gameModeButton.getBounds().width;
  270. this.wrappedGameModeMenu = InternalWidgets.wrapTranslate(InternalWidgets.wrapLateRenderable(gameModeMenu), 0, 0, 600);
  271. AFTER_RENDER.add(() -> this.widgets.add(wrappedGameModeMenu));
  272. } else {
  273. removeGameModeMenu();
  274. }
  275. }
  276. button.setText(new LiteralText(getGameModeShortText(getCurrentGameMode())));
  277. })
  278. .focusable(false)
  279. .tooltipLine(I18n.translate("text.rei.gamemode_button.tooltip.all"))
  280. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)));
  281. widgets.add(weatherButton = Widgets.createButton(new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 35, 20, 20), NarratorManager.EMPTY)
  282. .onRender((matrices, button) -> {
  283. boolean tmpRender = renderWeatherMenu;
  284. renderWeatherMenu = !renderGameModeMenu && (button.isFocused() || button.containsMouse(PointHelper.ofMouse()) || (wrappedWeatherMenu != null && wrappedWeatherMenu.containsMouse(PointHelper.ofMouse())));
  285. if (tmpRender != renderWeatherMenu) {
  286. if (renderWeatherMenu) {
  287. this.weatherMenu = new Menu(new Point(button.getBounds().x, button.getBounds().getMaxY()),
  288. CollectionUtils.map(Weather.values(), WeatherMenuEntry::new));
  289. if (ConfigObject.getInstance().isLeftHandSidePanel())
  290. this.weatherMenu.menuStartPoint.x -= this.weatherMenu.getBounds().width - this.weatherButton.getBounds().width;
  291. this.wrappedWeatherMenu = InternalWidgets.wrapTranslate(InternalWidgets.wrapLateRenderable(weatherMenu), 0, 0, 400);
  292. AFTER_RENDER.add(() -> this.widgets.add(wrappedWeatherMenu));
  293. } else {
  294. removeWeatherMenu();
  295. }
  296. }
  297. })
  298. .tooltipLine(I18n.translate("text.rei.weather_button.tooltip.all"))
  299. .focusable(false)
  300. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y)));
  301. widgets.add(Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
  302. MinecraftClient.getInstance().getTextureManager().bindTexture(CHEST_GUI_TEXTURE);
  303. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  304. helper.drawTexture(matrices, weatherButton.getBounds().x + 3, weatherButton.getBounds().y + 3, getCurrentWeather().getId() * 14, 14, 14, 14);
  305. }));
  306. }
  307. subsetsButtonBounds = getSubsetsButtonBounds();
  308. if (ConfigObject.getInstance().isSubsetsEnabled()) {
  309. widgets.add(InternalWidgets.wrapLateRenderable(InternalWidgets.wrapTranslate(Widgets.createButton(subsetsButtonBounds, ((ClientHelperImpl) ClientHelper.getInstance()).isAprilFools.get() ? new TranslatableText("text.rei.tiny_potato") : new TranslatableText("text.rei.subsets"))
  310. .onClick(button -> {
  311. if (subsetsMenu == null) {
  312. wrappedSubsetsMenu = InternalWidgets.wrapTranslate(InternalWidgets.wrapLateRenderable(this.subsetsMenu = Menu.createSubsetsMenuFromRegistry(new Point(this.subsetsButtonBounds.x, this.subsetsButtonBounds.getMaxY()))), 0, 0, 400);
  313. this.widgets.add(this.wrappedSubsetsMenu);
  314. } else {
  315. this.widgets.remove(this.wrappedSubsetsMenu);
  316. this.subsetsMenu = null;
  317. this.wrappedSubsetsMenu = null;
  318. }
  319. }), 0, 0, 600)));
  320. }
  321. if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
  322. widgets.add(Widgets.createClickableLabel(new Point(bounds.x + (bounds.width / 2), bounds.y + (ConfigObject.getInstance().getSearchFieldLocation() == SearchFieldLocation.TOP_SIDE ? 24 : 0) + 10), NarratorManager.EMPTY, label -> {
  323. ENTRY_LIST_WIDGET.setPage(0);
  324. ENTRY_LIST_WIDGET.updateEntriesPosition();
  325. }).tooltipLine(I18n.translate("text.rei.go_back_first_page")).focusable(false).onRender((matrices, label) -> {
  326. label.setClickable(ENTRY_LIST_WIDGET.getTotalPages() > 1);
  327. label.setText(new LiteralText(String.format("%s/%s", ENTRY_LIST_WIDGET.getPage() + 1, Math.max(ENTRY_LIST_WIDGET.getTotalPages(), 1))));
  328. }));
  329. }
  330. if (ConfigObject.getInstance().isCraftableFilterEnabled()) {
  331. Rectangle area = getCraftableToggleArea();
  332. ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
  333. ItemStack icon = new ItemStack(Blocks.CRAFTING_TABLE);
  334. this.widgets.add(tmp = InternalWidgets.wrapLateRenderable(InternalWidgets.mergeWidgets(
  335. Widgets.createButton(area, NarratorManager.EMPTY)
  336. .focusable(false)
  337. .onClick(button -> {
  338. ConfigManager.getInstance().toggleCraftableOnly();
  339. ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
  340. })
  341. .onRender((matrices, button) -> button.setTint(ConfigManager.getInstance().isCraftableOnlyEnabled() ? 939579655 : 956235776))
  342. .containsMousePredicate((button, point) -> button.getBounds().contains(point) && isNotInExclusionZones(point.x, point.y))
  343. .tooltipSupplier(button -> I18n.translate(ConfigManager.getInstance().isCraftableOnlyEnabled() ? "text.rei.showing_craftable" : "text.rei.showing_all")),
  344. Widgets.createDrawableWidget((helper, matrices, mouseX, mouseY, delta) -> {
  345. Vector4f vector = new Vector4f(area.x + 2, area.y + 2, helper.getZOffset() - 10, 1.0F);
  346. vector.transform(matrices.peek().getModel());
  347. itemRenderer.zOffset = vector.getZ();
  348. itemRenderer.renderGuiItemIcon(icon, (int) vector.getX(), (int) vector.getY());
  349. itemRenderer.zOffset = 0.0F;
  350. }))
  351. ));
  352. tmp.setZ(600);
  353. }
  354. }
  355. @ApiStatus.Experimental
  356. private Rectangle getSubsetsButtonBounds() {
  357. if (ConfigObject.getInstance().isSubsetsEnabled()) {
  358. if (MinecraftClient.getInstance().currentScreen instanceof RecipeViewingScreen) {
  359. RecipeViewingScreen widget = (RecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  360. return new Rectangle(widget.getBounds().x, 3, widget.getBounds().width, 18);
  361. }
  362. if (MinecraftClient.getInstance().currentScreen instanceof VillagerRecipeViewingScreen) {
  363. VillagerRecipeViewingScreen widget = (VillagerRecipeViewingScreen) MinecraftClient.getInstance().currentScreen;
  364. return new Rectangle(widget.bounds.x, 3, widget.bounds.width, 18);
  365. }
  366. return new Rectangle(REIHelper.getInstance().getPreviousContainerScreen().x, 3, REIHelper.getInstance().getPreviousContainerScreen().containerWidth, 18);
  367. }
  368. return null;
  369. }
  370. private Weather getNextWeather() {
  371. try {
  372. Weather current = getCurrentWeather();
  373. int next = current.getId() + 1;
  374. if (next >= 3)
  375. next = 0;
  376. return Weather.byId(next);
  377. } catch (Exception e) {
  378. return Weather.CLEAR;
  379. }
  380. }
  381. private Weather getCurrentWeather() {
  382. ClientWorld world = MinecraftClient.getInstance().world;
  383. if (world.isThundering())
  384. return Weather.THUNDER;
  385. if (world.getLevelProperties().isRaining())
  386. return Weather.RAIN;
  387. return Weather.CLEAR;
  388. }
  389. private String getGameModeShortText(GameMode gameMode) {
  390. return I18n.translate("text.rei.short_gamemode." + gameMode.getName());
  391. }
  392. private String getGameModeText(GameMode gameMode) {
  393. return I18n.translate("selectWorld.gameMode." + gameMode.getName());
  394. }
  395. private GameMode getNextGameMode(boolean reverse) {
  396. try {
  397. GameMode current = getCurrentGameMode();
  398. int next = current.getId() + 1;
  399. if (reverse)
  400. next -= 2;
  401. if (next > 3)
  402. next = 0;
  403. if (next < 0)
  404. next = 3;
  405. return GameMode.byId(next);
  406. } catch (Exception e) {
  407. return GameMode.NOT_SET;
  408. }
  409. }
  410. private GameMode getCurrentGameMode() {
  411. return MinecraftClient.getInstance().getNetworkHandler().getPlayerListEntry(MinecraftClient.getInstance().player.getGameProfile().getId()).getGameMode();
  412. }
  413. private Rectangle getSearchFieldArea() {
  414. int widthRemoved = 1 + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 22 : 0) + (ConfigObject.getInstance().isLowerConfigButton() ? 22 : 0);
  415. SearchFieldLocation searchFieldLocation = ConfigObject.getInstance().getSearchFieldLocation();
  416. if (searchFieldLocation == SearchFieldLocation.BOTTOM_SIDE)
  417. return new Rectangle(bounds.x + 2, window.getScaledHeight() - 22, bounds.width - 6 - widthRemoved, 18);
  418. if (searchFieldLocation == SearchFieldLocation.TOP_SIDE)
  419. return new Rectangle(bounds.x + 2, 4, bounds.width - 6 - widthRemoved, 18);
  420. for (OverlayDecider decider : DisplayHelper.getInstance().getSortedOverlayDeciders(MinecraftClient.getInstance().currentScreen.getClass())) {
  421. if (decider instanceof DisplayHelper.DisplayBoundsProvider) {
  422. Rectangle containerBounds = ((DisplayHelper.DisplayBoundsProvider<Screen>) decider).getScreenBounds(MinecraftClient.getInstance().currentScreen);
  423. return new Rectangle(containerBounds.x, window.getScaledHeight() - 22, containerBounds.width - widthRemoved, 18);
  424. }
  425. }
  426. return new Rectangle();
  427. }
  428. private Rectangle getCraftableToggleArea() {
  429. Rectangle area = getSearchFieldArea();
  430. area.setLocation(area.x + area.width + 4, area.y - 1);
  431. area.setSize(20, 20);
  432. return area;
  433. }
  434. private Rectangle getConfigButtonArea() {
  435. if (ConfigObject.getInstance().isLowerConfigButton()) {
  436. Rectangle area = getSearchFieldArea();
  437. area.setLocation(area.x + area.width + (ConfigObject.getInstance().isCraftableFilterEnabled() ? 26 : 4), area.y - 1);
  438. area.setSize(20, 20);
  439. return area;
  440. }
  441. return new Rectangle(ConfigObject.getInstance().isLeftHandSidePanel() ? window.getScaledWidth() - 30 : 10, 10, 20, 20);
  442. }
  443. private String getCheatModeText() {
  444. return I18n.translate(String.format("%s%s", "text.rei.", ClientHelper.getInstance().isCheating() ? "cheat" : "nocheat"));
  445. }
  446. @NotNull
  447. @Override
  448. public Rectangle getBounds() {
  449. return bounds;
  450. }
  451. @Override
  452. public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  453. List<ItemStack> currentStacks = ClientHelper.getInstance().getInventoryItemsTypes();
  454. if (shouldReInit) {
  455. ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
  456. init();
  457. } else {
  458. for (OverlayDecider decider : DisplayHelper.getInstance().getSortedOverlayDeciders(minecraft.currentScreen.getClass())) {
  459. if (decider != null && decider.shouldRecalculateArea(ConfigObject.getInstance().getDisplayPanelLocation(), bounds)) {
  460. init();
  461. break;
  462. }
  463. }
  464. }
  465. if (ConfigManager.getInstance().isCraftableOnlyEnabled() && ((currentStacks.size() != ScreenHelper.inventoryStacks.size()) || !hasSameListContent(new LinkedList<>(ScreenHelper.inventoryStacks), currentStacks))) {
  466. ScreenHelper.inventoryStacks = currentStacks;
  467. ENTRY_LIST_WIDGET.updateSearch(ScreenHelper.getSearchField().getText(), true);
  468. }
  469. if (OverlaySearchField.isSearching) {
  470. matrices.push();
  471. matrices.translate(0, 0, 200f);
  472. if (MinecraftClient.getInstance().currentScreen instanceof ContainerScreen) {
  473. ContainerScreen<?> containerScreen = (ContainerScreen<?>) MinecraftClient.getInstance().currentScreen;
  474. int x = containerScreen.x, y = containerScreen.y;
  475. for (Slot slot : containerScreen.getContainer().slots)
  476. if (!slot.hasStack() || !ENTRY_LIST_WIDGET.canLastSearchTermsBeAppliedTo(EntryStack.create(slot.getStack())))
  477. fillGradient(matrices, x + slot.xPosition, y + slot.yPosition, x + slot.xPosition + 16, y + slot.yPosition + 16, -601874400, -601874400);
  478. }
  479. matrices.pop();
  480. }
  481. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  482. this.renderWidgets(matrices, mouseX, mouseY, delta);
  483. if (MinecraftClient.getInstance().currentScreen instanceof ContainerScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
  484. ContainerScreen<?> containerScreen = (ContainerScreen<?>) MinecraftClient.getInstance().currentScreen;
  485. for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
  486. if (area.getScreenClass().equals(MinecraftClient.getInstance().currentScreen.getClass()))
  487. if (area.getRectangle().contains(mouseX - containerScreen.x, mouseY - containerScreen.y)) {
  488. String collect = CollectionUtils.mapAndJoinToString(area.getCategories(), identifier -> RecipeHelper.getInstance().getCategory(identifier).getCategoryName(), ", ");
  489. TOOLTIPS.add(Tooltip.create(new TranslatableText("text.rei.view_recipes_for", collect)));
  490. break;
  491. }
  492. }
  493. }
  494. public void lateRender(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  495. if (ScreenHelper.isOverlayVisible()) {
  496. ScreenHelper.getSearchField().laterRender(matrices, mouseX, mouseY, delta);
  497. for (Widget widget : widgets) {
  498. if (widget instanceof LateRenderable && wrappedSubsetsMenu != widget && wrappedWeatherMenu != widget && wrappedGameModeMenu != widget)
  499. widget.render(matrices, mouseX, mouseY, delta);
  500. }
  501. }
  502. if (wrappedWeatherMenu != null) {
  503. if (wrappedWeatherMenu.containsMouse(mouseX, mouseY)) {
  504. TOOLTIPS.clear();
  505. }
  506. wrappedWeatherMenu.render(matrices, mouseX, mouseY, delta);
  507. } else if (wrappedGameModeMenu != null) {
  508. if (wrappedGameModeMenu.containsMouse(mouseX, mouseY)) {
  509. TOOLTIPS.clear();
  510. }
  511. wrappedGameModeMenu.render(matrices, mouseX, mouseY, delta);
  512. }
  513. if (wrappedSubsetsMenu != null) {
  514. TOOLTIPS.clear();
  515. wrappedSubsetsMenu.render(matrices, mouseX, mouseY, delta);
  516. }
  517. Screen currentScreen = MinecraftClient.getInstance().currentScreen;
  518. if (!(currentScreen instanceof RecipeViewingScreen) || !((RecipeViewingScreen) currentScreen).choosePageActivated)
  519. for (Tooltip tooltip : TOOLTIPS) {
  520. if (tooltip != null)
  521. renderTooltip(matrices, tooltip);
  522. }
  523. for (Runnable runnable : AFTER_RENDER) {
  524. runnable.run();
  525. }
  526. TOOLTIPS.clear();
  527. AFTER_RENDER.clear();
  528. }
  529. public void renderTooltip(MatrixStack matrices, Tooltip tooltip) {
  530. renderTooltip(matrices, tooltip.getText(), tooltip.getX(), tooltip.getY());
  531. }
  532. public void renderTooltip(MatrixStack matrices, List<Text> lines, int mouseX, int mouseY) {
  533. if (lines.isEmpty())
  534. return;
  535. List<OrderedText> orderedTexts = CollectionUtils.map(lines, Text::asOrderedText);
  536. renderTooltipInner(matrices, orderedTexts, mouseX, mouseY);
  537. }
  538. public void renderTooltipInner(MatrixStack matrices, List<OrderedText> lines, int mouseX, int mouseY) {
  539. if (lines.isEmpty())
  540. return;
  541. tooltipWidth = lines.stream().map(font::getWidth).max(Integer::compareTo).get();
  542. tooltipHeight = lines.size() <= 1 ? 8 : lines.size() * 10;
  543. tooltipLines = lines;
  544. ScreenHelper.drawHoveringWidget(matrices, mouseX, mouseY, renderTooltipCallback, tooltipWidth, tooltipHeight, 0);
  545. }
  546. private boolean hasSameListContent(List<ItemStack> list1, List<ItemStack> list2) {
  547. list1.sort(Comparator.comparing(Object::toString));
  548. list2.sort(Comparator.comparing(Object::toString));
  549. return CollectionUtils.mapAndJoinToString(list1, Object::toString, "").equals(CollectionUtils.mapAndJoinToString(list2, Object::toString, ""));
  550. }
  551. public void addTooltip(@Nullable Tooltip tooltip) {
  552. if (tooltip != null)
  553. TOOLTIPS.add(tooltip);
  554. }
  555. public void renderWidgets(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  556. if (!ScreenHelper.isOverlayVisible())
  557. return;
  558. if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
  559. leftButton.setEnabled(ENTRY_LIST_WIDGET.getTotalPages() > 1);
  560. rightButton.setEnabled(ENTRY_LIST_WIDGET.getTotalPages() > 1);
  561. }
  562. for (Widget widget : widgets) {
  563. if (!(widget instanceof LateRenderable))
  564. widget.render(matrices, mouseX, mouseY, delta);
  565. }
  566. }
  567. @Override
  568. public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
  569. if (!ScreenHelper.isOverlayVisible())
  570. return false;
  571. if (wrappedSubsetsMenu != null && wrappedSubsetsMenu.mouseScrolled(mouseX, mouseY, amount))
  572. return true;
  573. if (wrappedWeatherMenu != null && wrappedWeatherMenu.mouseScrolled(mouseX, mouseY, amount))
  574. return true;
  575. if (wrappedGameModeMenu != null && wrappedGameModeMenu.mouseScrolled(mouseX, mouseY, amount))
  576. return true;
  577. if (isInside(PointHelper.ofMouse())) {
  578. if (!ConfigObject.getInstance().isEntryListWidgetScrolled()) {
  579. if (amount > 0 && leftButton.isEnabled())
  580. leftButton.onClick();
  581. else if (amount < 0 && rightButton.isEnabled())
  582. rightButton.onClick();
  583. else
  584. return false;
  585. return true;
  586. } else if (ENTRY_LIST_WIDGET.mouseScrolled(mouseX, mouseY, amount))
  587. return true;
  588. }
  589. if (isNotInExclusionZones(PointHelper.getMouseX(), PointHelper.getMouseY())) {
  590. if (favoritesListWidget != null && favoritesListWidget.mouseScrolled(mouseX, mouseY, amount))
  591. return true;
  592. }
  593. for (Widget widget : widgets)
  594. if (widget != ENTRY_LIST_WIDGET && (favoritesListWidget == null || widget != favoritesListWidget)
  595. && (wrappedSubsetsMenu == null || widget != wrappedSubsetsMenu)
  596. && (wrappedWeatherMenu == null || widget != wrappedWeatherMenu)
  597. && (wrappedGameModeMenu == null || widget != wrappedGameModeMenu)
  598. && widget.mouseScrolled(mouseX, mouseY, amount))
  599. return true;
  600. return false;
  601. }
  602. @Override
  603. public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
  604. if (ScreenHelper.isOverlayVisible()) {
  605. if (ScreenHelper.getSearchField().keyPressed(keyCode, scanCode, modifiers))
  606. return true;
  607. for (Element listener : widgets)
  608. if (listener != ScreenHelper.getSearchField() && listener.keyPressed(keyCode, scanCode, modifiers))
  609. return true;
  610. }
  611. if (ConfigObject.getInstance().getHideKeybind().matchesKey(keyCode, scanCode)) {
  612. ScreenHelper.toggleOverlayVisible();
  613. return true;
  614. }
  615. EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(MinecraftClient.getInstance().currentScreen);
  616. if (stack != null && !stack.isEmpty()) {
  617. stack = stack.copy();
  618. if (ConfigObject.getInstance().getRecipeKeybind().matchesKey(keyCode, scanCode)) {
  619. return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
  620. } else if (ConfigObject.getInstance().getUsageKeybind().matchesKey(keyCode, scanCode)) {
  621. return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addUsagesFor(stack).setInputNotice(stack).fillPreferredOpenedCategory());
  622. } else if (ConfigObject.getInstance().getFavoriteKeyCode().matchesKey(keyCode, scanCode)) {
  623. stack.setAmount(127);
  624. if (!CollectionUtils.anyMatchEqualsEntryIgnoreAmount(ConfigObject.getInstance().getFavorites(), stack))
  625. ConfigObject.getInstance().getFavorites().add(stack);
  626. ConfigManager.getInstance().saveConfig();
  627. FavoritesListWidget favoritesListWidget = ContainerScreenOverlay.getFavoritesListWidget();
  628. if (favoritesListWidget != null)
  629. favoritesListWidget.updateSearch(ContainerScreenOverlay.getEntryListWidget(), ScreenHelper.getSearchField().getText());
  630. return true;
  631. }
  632. }
  633. if (!ScreenHelper.isOverlayVisible())
  634. return false;
  635. if (ConfigObject.getInstance().getFocusSearchFieldKeybind().matchesKey(keyCode, scanCode)) {
  636. ScreenHelper.getSearchField().setFocused(true);
  637. setFocused(ScreenHelper.getSearchField());
  638. ScreenHelper.getSearchField().keybindFocusTime = System.currentTimeMillis();
  639. ScreenHelper.getSearchField().keybindFocusKey = keyCode;
  640. return true;
  641. }
  642. return false;
  643. }
  644. @Override
  645. public boolean charTyped(char char_1, int int_1) {
  646. if (!ScreenHelper.isOverlayVisible())
  647. return false;
  648. if (ScreenHelper.getSearchField().charTyped(char_1, int_1))
  649. return true;
  650. for (Element listener : widgets)
  651. if (listener != ScreenHelper.getSearchField() && listener.charTyped(char_1, int_1))
  652. return true;
  653. return false;
  654. }
  655. @Override
  656. public List<Widget> children() {
  657. return widgets;
  658. }
  659. @Override
  660. public boolean mouseClicked(double mouseX, double mouseY, int button) {
  661. if (ConfigObject.getInstance().getHideKeybind().matchesMouse(button)) {
  662. ScreenHelper.toggleOverlayVisible();
  663. return true;
  664. }
  665. EntryStack stack = RecipeHelper.getInstance().getScreenFocusedStack(MinecraftClient.getInstance().currentScreen);
  666. if (stack != null && !stack.isEmpty()) {
  667. stack = stack.copy();
  668. if (ConfigObject.getInstance().getRecipeKeybind().matchesMouse(button)) {
  669. return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addRecipesFor(stack).setOutputNotice(stack).fillPreferredOpenedCategory());
  670. } else if (ConfigObject.getInstance().getUsageKeybind().matchesMouse(button)) {
  671. return ClientHelper.getInstance().openView(ClientHelper.ViewSearchBuilder.builder().addUsagesFor(stack).setInputNotice(stack).fillPreferredOpenedCategory());
  672. } else if (ConfigObject.getInstance().getFavoriteKeyCode().matchesMouse(button)) {
  673. stack.setAmount(127);
  674. if (!CollectionUtils.anyMatchEqualsEntryIgnoreAmount(ConfigObject.getInstance().getFavorites(), stack))
  675. ConfigObject.getInstance().getFavorites().add(stack);
  676. ConfigManager.getInstance().saveConfig();
  677. FavoritesListWidget favoritesListWidget = ContainerScreenOverlay.getFavoritesListWidget();
  678. if (favoritesListWidget != null)
  679. favoritesListWidget.updateSearch(ContainerScreenOverlay.getEntryListWidget(), ScreenHelper.getSearchField().getText());
  680. return true;
  681. }
  682. }
  683. if (!ScreenHelper.isOverlayVisible())
  684. return false;
  685. if (wrappedSubsetsMenu != null && wrappedSubsetsMenu.mouseClicked(mouseX, mouseY, button)) {
  686. this.setFocused(wrappedSubsetsMenu);
  687. if (button == 0)
  688. this.setDragging(true);
  689. ScreenHelper.getSearchField().setFocused(false);
  690. return true;
  691. }
  692. if (wrappedWeatherMenu != null) {
  693. if (wrappedWeatherMenu.mouseClicked(mouseX, mouseY, button)) {
  694. this.setFocused(wrappedWeatherMenu);
  695. if (button == 0)
  696. this.setDragging(true);
  697. ScreenHelper.getSearchField().setFocused(false);
  698. return true;
  699. } else if (!wrappedWeatherMenu.containsMouse(mouseX, mouseY) && !weatherButton.containsMouse(mouseX, mouseY)) {
  700. removeWeatherMenu();
  701. }
  702. }
  703. if (wrappedGameModeMenu != null) {
  704. if (wrappedGameModeMenu.mouseClicked(mouseX, mouseY, button)) {
  705. this.setFocused(wrappedGameModeMenu);
  706. if (button == 0)
  707. this.setDragging(true);
  708. ScreenHelper.getSearchField().setFocused(false);
  709. return true;
  710. } else if (!wrappedGameModeMenu.containsMouse(mouseX, mouseY) && !gameModeButton.containsMouse(mouseX, mouseY)) {
  711. removeGameModeMenu();
  712. }
  713. }
  714. if (MinecraftClient.getInstance().currentScreen instanceof ContainerScreen && ConfigObject.getInstance().areClickableRecipeArrowsEnabled()) {
  715. ContainerScreen<?> containerScreen = (ContainerScreen<?>) MinecraftClient.getInstance().currentScreen;
  716. for (RecipeHelper.ScreenClickArea area : RecipeHelper.getInstance().getScreenClickAreas())
  717. if (area.getScreenClass().equals(containerScreen.getClass()))
  718. if (area.getRectangle().contains(mouseX - containerScreen.x, mouseY - containerScreen.y)) {
  719. ClientHelper.getInstance().executeViewAllRecipesFromCategories(Arrays.asList(area.getCategories()));
  720. MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(SoundEvents.UI_BUTTON_CLICK, 1.0F));
  721. return true;
  722. }
  723. }
  724. for (Element element : widgets)
  725. if (element != wrappedSubsetsMenu && element != wrappedWeatherMenu && element != wrappedGameModeMenu && element.mouseClicked(mouseX, mouseY, button)) {
  726. this.setFocused(element);
  727. if (button == 0)
  728. this.setDragging(true);
  729. if (!(element instanceof OverlaySearchField))
  730. ScreenHelper.getSearchField().setFocused(false);
  731. return true;
  732. }
  733. if (ConfigObject.getInstance().getFocusSearchFieldKeybind().matchesMouse(button)) {
  734. ScreenHelper.getSearchField().setFocused(true);
  735. setFocused(ScreenHelper.getSearchField());
  736. ScreenHelper.getSearchField().keybindFocusTime = -1;
  737. ScreenHelper.getSearchField().keybindFocusKey = -1;
  738. return true;
  739. }
  740. return false;
  741. }
  742. @Override
  743. public boolean mouseDragged(double double_1, double double_2, int int_1, double double_3, double double_4) {
  744. if (!ScreenHelper.isOverlayVisible())
  745. return false;
  746. return (this.getFocused() != null && this.isDragging() && int_1 == 0) && this.getFocused().mouseDragged(double_1, double_2, int_1, double_3, double_4);
  747. }
  748. public boolean isInside(double mouseX, double mouseY) {
  749. return bounds.contains(mouseX, mouseY) && isNotInExclusionZones(mouseX, mouseY);
  750. }
  751. public boolean isNotInExclusionZones(double mouseX, double mouseY) {
  752. for (OverlayDecider decider : DisplayHelper.getInstance().getSortedOverlayDeciders(MinecraftClient.getInstance().currentScreen.getClass())) {
  753. ActionResult in = decider.isInZone(mouseX, mouseY);
  754. if (in != ActionResult.PASS)
  755. return in == ActionResult.SUCCESS;
  756. }
  757. return true;
  758. }
  759. public boolean isInside(Point point) {
  760. return isInside(point.getX(), point.getY());
  761. }
  762. }