ClothConfigScreen.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. package me.shedaniel.clothconfig2.gui;
  2. import com.google.common.collect.Lists;
  3. import com.google.common.collect.Maps;
  4. import com.mojang.blaze3d.systems.RenderSystem;
  5. import me.shedaniel.clothconfig2.api.*;
  6. import me.shedaniel.clothconfig2.gui.widget.DynamicElementListWidget;
  7. import me.shedaniel.clothconfig2.impl.EasingMethod;
  8. import me.shedaniel.math.Point;
  9. import me.shedaniel.math.Rectangle;
  10. import net.fabricmc.api.EnvType;
  11. import net.fabricmc.api.Environment;
  12. import net.minecraft.client.MinecraftClient;
  13. import net.minecraft.client.gui.screen.Screen;
  14. import net.minecraft.client.gui.widget.AbstractButtonWidget;
  15. import net.minecraft.client.gui.widget.ButtonWidget;
  16. import net.minecraft.client.render.BufferBuilder;
  17. import net.minecraft.client.render.Tessellator;
  18. import net.minecraft.client.render.VertexFormats;
  19. import net.minecraft.client.resource.language.I18n;
  20. import net.minecraft.client.util.NarratorManager;
  21. import net.minecraft.client.util.math.MatrixStack;
  22. import net.minecraft.text.Text;
  23. import net.minecraft.text.TranslatableText;
  24. import net.minecraft.util.Identifier;
  25. import net.minecraft.util.Pair;
  26. import net.minecraft.util.math.Matrix4f;
  27. import org.jetbrains.annotations.ApiStatus;
  28. import java.util.LinkedHashMap;
  29. import java.util.List;
  30. import java.util.Map;
  31. import java.util.Optional;
  32. import java.util.stream.Collectors;
  33. @SuppressWarnings({"deprecation", "rawtypes", "DuplicatedCode"})
  34. @Environment(EnvType.CLIENT)
  35. public class ClothConfigScreen extends AbstractTabbedConfigScreen {
  36. private ScrollingContainer tabsScroller = new ScrollingContainer() {
  37. @Override
  38. public Rectangle getBounds() {
  39. return new Rectangle(0, 0, 1, ClothConfigScreen.this.width - 40); // We don't need to handle dragging
  40. }
  41. @Override
  42. public int getMaxScrollHeight() {
  43. return (int) ClothConfigScreen.this.getTabsMaximumScrolled();
  44. }
  45. @Override
  46. public void updatePosition(float delta) {
  47. super.updatePosition(delta);
  48. scrollAmount = clamp(scrollAmount, 0);
  49. }
  50. };
  51. public ListWidget<AbstractConfigEntry<AbstractConfigEntry<?>>> listWidget;
  52. private final LinkedHashMap<Text, List<AbstractConfigEntry<?>>> categorizedEntries = Maps.newLinkedHashMap();
  53. private final List<Pair<Text, Integer>> tabs;
  54. private AbstractButtonWidget quitButton, saveButton, buttonLeftTab, buttonRightTab;
  55. private Rectangle tabsBounds, tabsLeftBounds, tabsRightBounds;
  56. private double tabsMaximumScrolled = -1d;
  57. private final List<ClothConfigTabButton> tabButtons = Lists.newArrayList();
  58. @ApiStatus.Internal
  59. public ClothConfigScreen(Screen parent, Text title, Map<Text, List<Object>> entriesMap, Identifier backgroundLocation) {
  60. super(parent, title, backgroundLocation);
  61. entriesMap.forEach((categoryName, list) -> {
  62. List<AbstractConfigEntry<?>> entries = Lists.newArrayList();
  63. for (Object object : list) {
  64. AbstractConfigListEntry<?> entry;
  65. if (object instanceof Pair<?, ?>) {
  66. entry = (AbstractConfigListEntry<?>) ((Pair<?, ?>) object).getRight();
  67. } else {
  68. entry = (AbstractConfigListEntry<?>) object;
  69. }
  70. entry.setScreen(this);
  71. entries.add(entry);
  72. }
  73. categorizedEntries.put(categoryName, entries);
  74. });
  75. this.tabs = categorizedEntries.keySet().stream().map(s -> new Pair<>(s, MinecraftClient.getInstance().textRenderer.getWidth(s) + 8)).collect(Collectors.toList());
  76. }
  77. @Override
  78. public Text getSelectedCategory() {
  79. return tabs.get(selectedCategoryIndex).getLeft();
  80. }
  81. @Override
  82. public Map<Text, List<AbstractConfigEntry<?>>> getCategorizedEntries() {
  83. return categorizedEntries;
  84. }
  85. @Override
  86. public boolean isEdited() {
  87. return super.isEdited();
  88. }
  89. /**
  90. * Override #isEdited please
  91. */
  92. @Deprecated
  93. public void setEdited(boolean edited) {
  94. super.setEdited(edited);
  95. }
  96. /**
  97. * Override #isEdited please
  98. */
  99. @Override
  100. @Deprecated
  101. public void setEdited(boolean edited, boolean requiresRestart) {
  102. super.setEdited(edited, requiresRestart);
  103. }
  104. @Override
  105. public void saveAll(boolean openOtherScreens) {
  106. super.saveAll(openOtherScreens);
  107. }
  108. @Override
  109. protected void init() {
  110. super.init();
  111. this.tabButtons.clear();
  112. children.add(listWidget = new ListWidget(this, client, width, height, isShowingTabs() ? 70 : 30, height - 32, getBackgroundLocation()));
  113. if (categorizedEntries.size() > selectedCategoryIndex) {
  114. listWidget.children().addAll((List) Lists.newArrayList(categorizedEntries.values()).get(selectedCategoryIndex));
  115. }
  116. int buttonWidths = Math.min(200, (width - 50 - 12) / 3);
  117. addButton(quitButton = new ButtonWidget(width / 2 - buttonWidths - 3, height - 26, buttonWidths, 20, isEdited() ? new TranslatableText("text.cloth-config.cancel_discard") : new TranslatableText("gui.cancel"), widget -> quit()));
  118. addButton(saveButton = new ButtonWidget(width / 2 + 3, height - 26, buttonWidths, 20, NarratorManager.EMPTY, button -> saveAll(true)) {
  119. @Override
  120. public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  121. boolean hasErrors = false;
  122. for (List<AbstractConfigEntry<?>> entries : Lists.newArrayList(categorizedEntries.values())) {
  123. for (AbstractConfigEntry<?> entry : entries)
  124. if (entry.getConfigError().isPresent()) {
  125. hasErrors = true;
  126. break;
  127. }
  128. if (hasErrors)
  129. break;
  130. }
  131. active = isEdited() && !hasErrors;
  132. setMessage(hasErrors ? new TranslatableText("text.cloth-config.error_cannot_save") : new TranslatableText("text.cloth-config.save_and_done"));
  133. super.render(matrices, mouseX, mouseY, delta);
  134. }
  135. });
  136. saveButton.active = isEdited();
  137. if (isShowingTabs()) {
  138. tabsBounds = new Rectangle(0, 41, width, 24);
  139. tabsLeftBounds = new Rectangle(0, 41, 18, 24);
  140. tabsRightBounds = new Rectangle(width - 18, 41, 18, 24);
  141. children.add(buttonLeftTab = new ButtonWidget(4, 44, 12, 18, NarratorManager.EMPTY, button -> tabsScroller.scrollTo(0, true)) {
  142. @Override
  143. public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  144. client.getTextureManager().bindTexture(CONFIG_TEX);
  145. RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
  146. int int_3 = this.getYImage(this.isHovered());
  147. RenderSystem.enableBlend();
  148. RenderSystem.blendFuncSeparate(770, 771, 0, 1);
  149. RenderSystem.blendFunc(770, 771);
  150. this.drawTexture(matrices, x, y, 12, 18 * int_3, width, height);
  151. }
  152. });
  153. int j = 0;
  154. for (Pair<Text, Integer> tab : tabs) {
  155. tabButtons.add(new ClothConfigTabButton(this, j, -100, 43, tab.getRight(), 20, tab.getLeft()));
  156. j++;
  157. }
  158. children.addAll(tabButtons);
  159. children.add(buttonRightTab = new ButtonWidget(width - 16, 44, 12, 18, NarratorManager.EMPTY, button -> tabsScroller.scrollTo(tabsScroller.getMaxScroll(), true)) {
  160. @Override
  161. public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  162. client.getTextureManager().bindTexture(CONFIG_TEX);
  163. RenderSystem.color4f(1.0F, 1.0F, 1.0F, this.alpha);
  164. int int_3 = this.getYImage(this.isHovered());
  165. RenderSystem.enableBlend();
  166. RenderSystem.blendFuncSeparate(770, 771, 0, 1);
  167. RenderSystem.blendFunc(770, 771);
  168. this.drawTexture(matrices, x, y, 0, 18 * int_3, width, height);
  169. }
  170. });
  171. } else {
  172. tabsBounds = tabsLeftBounds = tabsRightBounds = new Rectangle();
  173. }
  174. Optional.ofNullable(this.afterInitConsumer).ifPresent(consumer -> consumer.accept(this));
  175. }
  176. @Override
  177. public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
  178. if (tabsBounds.contains(mouseX, mouseY) && !tabsLeftBounds.contains(mouseX, mouseY) && !tabsRightBounds.contains(mouseX, mouseY) && amount != 0d) {
  179. tabsScroller.offset(-amount * 16, true);
  180. return true;
  181. }
  182. return super.mouseScrolled(mouseX, mouseY, amount);
  183. }
  184. public double getTabsMaximumScrolled() {
  185. if (tabsMaximumScrolled == -1d) {
  186. int[] i = {0};
  187. for (Pair<Text, Integer> pair : tabs) i[0] += pair.getRight() + 2;
  188. tabsMaximumScrolled = i[0];
  189. }
  190. return tabsMaximumScrolled + 6;
  191. }
  192. public void resetTabsMaximumScrolled() {
  193. tabsMaximumScrolled = -1d;
  194. }
  195. @Override
  196. public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
  197. if (isShowingTabs()) {
  198. tabsScroller.updatePosition(delta * 3);
  199. int xx = 24 - (int) tabsScroller.scrollAmount;
  200. for (ClothConfigTabButton tabButton : tabButtons) {
  201. tabButton.x = xx;
  202. xx += tabButton.getWidth() + 2;
  203. }
  204. buttonLeftTab.active = tabsScroller.scrollAmount > 0d;
  205. buttonRightTab.active = tabsScroller.scrollAmount < getTabsMaximumScrolled() - width + 40;
  206. }
  207. if (isTransparentBackground()) {
  208. fillGradient(matrices, 0, 0, this.width, this.height, -1072689136, -804253680);
  209. } else {
  210. renderBackgroundTexture(0);
  211. }
  212. listWidget.render(matrices, mouseX, mouseY, delta);
  213. ScissorsHandler.INSTANCE.scissor(new Rectangle(listWidget.left, listWidget.top, listWidget.width, listWidget.bottom - listWidget.top));
  214. for (AbstractConfigEntry child : listWidget.children())
  215. child.lateRender(matrices, mouseX, mouseY, delta);
  216. ScissorsHandler.INSTANCE.removeLastScissor();
  217. if (isShowingTabs()) {
  218. drawCenteredText(matrices, client.textRenderer, title, width / 2, 18, -1);
  219. Rectangle onlyInnerTabBounds = new Rectangle(tabsBounds.x + 20, tabsBounds.y, tabsBounds.width - 40, tabsBounds.height);
  220. ScissorsHandler.INSTANCE.scissor(onlyInnerTabBounds);
  221. if (isTransparentBackground())
  222. fillGradient(matrices, onlyInnerTabBounds.x, onlyInnerTabBounds.y, onlyInnerTabBounds.getMaxX(), onlyInnerTabBounds.getMaxY(), 0x68000000, 0x68000000);
  223. else
  224. overlayBackground(matrices, onlyInnerTabBounds, 32, 32, 32, 255, 255);
  225. tabButtons.forEach(widget -> widget.render(matrices, mouseX, mouseY, delta));
  226. drawTabsShades(matrices, 0, isTransparentBackground() ? 120 : 255);
  227. ScissorsHandler.INSTANCE.removeLastScissor();
  228. buttonLeftTab.render(matrices, mouseX, mouseY, delta);
  229. buttonRightTab.render(matrices, mouseX, mouseY, delta);
  230. } else
  231. drawCenteredText(matrices, client.textRenderer, title, width / 2, 12, -1);
  232. if (isEditable()) {
  233. List<Text> errors = Lists.newArrayList();
  234. for (List<AbstractConfigEntry<?>> entries : Lists.newArrayList(categorizedEntries.values()))
  235. for (AbstractConfigEntry<?> entry : entries)
  236. if (entry.getConfigError().isPresent())
  237. errors.add(entry.getConfigError().get());
  238. if (errors.size() > 0) {
  239. client.getTextureManager().bindTexture(CONFIG_TEX);
  240. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  241. String text = "§c" + (errors.size() == 1 ? errors.get(0).copy().getString() : I18n.translate("text.cloth-config.multi_error"));
  242. if (isTransparentBackground()) {
  243. int stringWidth = client.textRenderer.getStringWidth(text);
  244. fillGradient(matrices, 8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
  245. }
  246. drawTexture(matrices, 10, 10, 0, 54, 3, 11);
  247. drawStringWithShadow(matrices, client.textRenderer, text, 18, 12, -1);
  248. if (errors.size() > 1) {
  249. int stringWidth = client.textRenderer.getStringWidth(text);
  250. if (mouseX >= 10 && mouseY >= 10 && mouseX <= 18 + stringWidth && mouseY <= 14 + client.textRenderer.fontHeight)
  251. addTooltip(Tooltip.of(new Point(mouseX, mouseY), errors.toArray(new Text[0])));
  252. }
  253. }
  254. } else if (!isEditable()) {
  255. client.getTextureManager().bindTexture(CONFIG_TEX);
  256. RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
  257. String text = "§c" + I18n.translate("text.cloth-config.not_editable");
  258. if (isTransparentBackground()) {
  259. int stringWidth = client.textRenderer.getStringWidth(text);
  260. fillGradient(matrices, 8, 9, 20 + stringWidth, 14 + client.textRenderer.fontHeight, 0x68000000, 0x68000000);
  261. }
  262. drawTexture(matrices, 10, 10, 0, 54, 3, 11);
  263. drawStringWithShadow(matrices, client.textRenderer, text, 18, 12, -1);
  264. }
  265. super.render(matrices, mouseX, mouseY, delta);
  266. }
  267. @ApiStatus.ScheduledForRemoval
  268. @Deprecated
  269. public void queueTooltip(QueuedTooltip queuedTooltip) {
  270. super.addTooltip(queuedTooltip);
  271. }
  272. private void drawTabsShades(MatrixStack matrices, int lightColor, int darkColor) {
  273. drawTabsShades(matrices.peek().getModel(), lightColor, darkColor);
  274. }
  275. private void drawTabsShades(Matrix4f matrix, int lightColor, int darkColor) {
  276. RenderSystem.enableBlend();
  277. RenderSystem.blendFuncSeparate(770, 771, 0, 1);
  278. RenderSystem.disableAlphaTest();
  279. RenderSystem.shadeModel(7425);
  280. RenderSystem.disableTexture();
  281. Tessellator tessellator = Tessellator.getInstance();
  282. BufferBuilder buffer = tessellator.getBuffer();
  283. buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
  284. buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMinY() + 4, 0.0F).texture(0, 1f).color(0, 0, 0, lightColor).next();
  285. buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMinY() + 4, 0.0F).texture(1f, 1f).color(0, 0, 0, lightColor).next();
  286. buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMinY(), 0.0F).texture(1f, 0).color(0, 0, 0, darkColor).next();
  287. buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMinY(), 0.0F).texture(0, 0).color(0, 0, 0, darkColor).next();
  288. tessellator.draw();
  289. buffer.begin(7, VertexFormats.POSITION_TEXTURE_COLOR);
  290. buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMaxY(), 0.0F).texture(0, 1f).color(0, 0, 0, darkColor).next();
  291. buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMaxY(), 0.0F).texture(1f, 1f).color(0, 0, 0, darkColor).next();
  292. buffer.vertex(matrix, tabsBounds.getMaxX() - 20, tabsBounds.getMaxY() - 4, 0.0F).texture(1f, 0).color(0, 0, 0, lightColor).next();
  293. buffer.vertex(matrix, tabsBounds.getMinX() + 20, tabsBounds.getMaxY() - 4, 0.0F).texture(0, 0).color(0, 0, 0, lightColor).next();
  294. tessellator.draw();
  295. RenderSystem.enableTexture();
  296. RenderSystem.shadeModel(7424);
  297. RenderSystem.enableAlphaTest();
  298. RenderSystem.disableBlend();
  299. }
  300. @Override
  301. public void save() {
  302. super.save();
  303. }
  304. @Override
  305. public boolean isEditable() {
  306. return super.isEditable();
  307. }
  308. public static class ListWidget<R extends DynamicElementListWidget.ElementEntry<R>> extends DynamicElementListWidget<R> {
  309. private AbstractConfigScreen screen;
  310. private boolean hasCurrent;
  311. private double currentX;
  312. private double currentY;
  313. private double currentWidth;
  314. private double currentHeight;
  315. public Rectangle target;
  316. public Rectangle thisTimeTarget;
  317. public long start;
  318. public long duration;
  319. public ListWidget(AbstractConfigScreen screen, MinecraftClient client, int width, int height, int top, int bottom, Identifier backgroundLocation) {
  320. super(client, width, height, top, bottom, backgroundLocation);
  321. setRenderSelection(false);
  322. this.screen = screen;
  323. }
  324. @Override
  325. public int getItemWidth() {
  326. return width - 80;
  327. }
  328. @Override
  329. protected int getScrollbarPosition() {
  330. return left + width - 36;
  331. }
  332. @Override
  333. protected void renderItem(MatrixStack matrices, R item, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean isSelected, float delta) {
  334. if (item instanceof AbstractConfigEntry)
  335. ((AbstractConfigEntry) item).updateSelected(getFocused() == item);
  336. super.renderItem(matrices, item, index, y, x, entryWidth, entryHeight, mouseX, mouseY, isSelected, delta);
  337. }
  338. @Override
  339. protected void renderList(MatrixStack matrices, int startX, int startY, int int_3, int int_4, float delta) {
  340. thisTimeTarget = null;
  341. if (hasCurrent) {
  342. fillGradient(matrices, currentX, currentY, currentX + currentWidth, currentY + currentHeight, 0x24FFFFFF, 0x24FFFFFF);
  343. }
  344. super.renderList(matrices, startX, startY, int_3, int_4, delta);
  345. if (thisTimeTarget != null && !thisTimeTarget.equals(target)) {
  346. if (!hasCurrent) {
  347. currentX = thisTimeTarget.x;
  348. currentY = thisTimeTarget.y;
  349. currentWidth = thisTimeTarget.width;
  350. currentHeight = thisTimeTarget.height;
  351. hasCurrent = true;
  352. }
  353. target = thisTimeTarget.clone();
  354. start = System.currentTimeMillis();
  355. this.duration = 40;
  356. } else if (hasCurrent && target != null) {
  357. currentX = (int) ScrollingContainer.ease(currentX, target.x, Math.min((System.currentTimeMillis() - start) / (double) duration * delta * 3, 1), EasingMethod.EasingMethodImpl.LINEAR);
  358. currentY = (int) ScrollingContainer.ease(currentY, target.y, Math.min((System.currentTimeMillis() - start) / (double) duration * delta * 3, 1), EasingMethod.EasingMethodImpl.LINEAR);
  359. currentWidth = (int) ScrollingContainer.ease(currentWidth, target.width, Math.min((System.currentTimeMillis() - start) / (double) duration * delta * 3, 1), EasingMethod.EasingMethodImpl.LINEAR);
  360. currentHeight = (int) ScrollingContainer.ease(currentHeight, target.height, Math.min((System.currentTimeMillis() - start) / (double) duration * delta * 3, 1), EasingMethod.EasingMethodImpl.LINEAR);
  361. }
  362. }
  363. protected void fillGradient(MatrixStack matrices, double xStart, double yStart, double xEnd, double yEnd, int colorStart, int colorEnd) {
  364. RenderSystem.disableTexture();
  365. RenderSystem.enableBlend();
  366. RenderSystem.disableAlphaTest();
  367. RenderSystem.defaultBlendFunc();
  368. RenderSystem.shadeModel(7425);
  369. Tessellator tessellator = Tessellator.getInstance();
  370. BufferBuilder bufferBuilder = tessellator.getBuffer();
  371. bufferBuilder.begin(7, VertexFormats.POSITION_COLOR);
  372. fillGradient(matrices.peek().getModel(), bufferBuilder, xStart, yStart, xEnd, yEnd, this.getZOffset(), colorStart, colorEnd);
  373. tessellator.draw();
  374. RenderSystem.shadeModel(7424);
  375. RenderSystem.disableBlend();
  376. RenderSystem.enableAlphaTest();
  377. RenderSystem.enableTexture();
  378. }
  379. protected static void fillGradient(Matrix4f matrix4f, BufferBuilder bufferBuilder, double xStart, double yStart, double xEnd, double yEnd, int i, int j, int k) {
  380. float f = (float) (j >> 24 & 255) / 255.0F;
  381. float g = (float) (j >> 16 & 255) / 255.0F;
  382. float h = (float) (j >> 8 & 255) / 255.0F;
  383. float l = (float) (j & 255) / 255.0F;
  384. float m = (float) (k >> 24 & 255) / 255.0F;
  385. float n = (float) (k >> 16 & 255) / 255.0F;
  386. float o = (float) (k >> 8 & 255) / 255.0F;
  387. float p = (float) (k & 255) / 255.0F;
  388. bufferBuilder.vertex(matrix4f, (float) xEnd, (float) yStart, (float) i).color(g, h, l, f).next();
  389. bufferBuilder.vertex(matrix4f, (float) xStart, (float) yStart, (float) i).color(g, h, l, f).next();
  390. bufferBuilder.vertex(matrix4f, (float) xStart, (float) yEnd, (float) i).color(n, o, p, m).next();
  391. bufferBuilder.vertex(matrix4f, (float) xEnd, (float) yEnd, (float) i).color(n, o, p, m).next();
  392. }
  393. @Override
  394. public boolean mouseClicked(double mouseX, double mouseY, int button) {
  395. this.updateScrollingState(mouseX, mouseY, button);
  396. if (!this.isMouseOver(mouseX, mouseY)) {
  397. return false;
  398. } else {
  399. for (R entry : children()) {
  400. if (entry.mouseClicked(mouseX, mouseY, button)) {
  401. this.setFocused(entry);
  402. this.setDragging(true);
  403. return true;
  404. }
  405. }
  406. if (button == 0) {
  407. this.clickedHeader((int) (mouseX - (double) (this.left + this.width / 2 - this.getItemWidth() / 2)), (int) (mouseY - (double) this.top) + (int) this.getScroll() - 4);
  408. return true;
  409. }
  410. return this.scrolling;
  411. }
  412. }
  413. @Override
  414. protected void renderBackBackground(MatrixStack matrices, BufferBuilder buffer, Tessellator tessellator) {
  415. if (!screen.isTransparentBackground())
  416. super.renderBackBackground(matrices, buffer, tessellator);
  417. else {
  418. fillGradient(matrices, left, top, right, bottom, 0x68000000, 0x68000000);
  419. }
  420. }
  421. @Override
  422. protected void renderHoleBackground(MatrixStack matrices, int y1, int y2, int alpha1, int alpha2) {
  423. if (!screen.isTransparentBackground())
  424. super.renderHoleBackground(matrices, y1, y2, alpha1, alpha2);
  425. }
  426. }
  427. }