diff options
| author | shedaniel <daniel@shedaniel.me> | 2020-04-01 20:01:34 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2020-04-01 20:01:34 +0800 |
| commit | 66abc317e5fc36a397ca1cc919e388fbe143956b (patch) | |
| tree | 915cc4799d89297b8d4bd2dbe1046c177f4d1627 /src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java | |
| parent | 3919ec1e15d6eb9a8aa4564bb2d4e4dfdbeb54e3 (diff) | |
| download | RoughlyEnoughItems-66abc317e5fc36a397ca1cc919e388fbe143956b.tar.gz RoughlyEnoughItems-66abc317e5fc36a397ca1cc919e388fbe143956b.tar.bz2 RoughlyEnoughItems-66abc317e5fc36a397ca1cc919e388fbe143956b.zip | |
ScrollingContainer & SubsetsMenu && 20w18b
Signed-off-by: shedaniel <daniel@shedaniel.me>
Diffstat (limited to 'src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java')
| -rw-r--r-- | src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java b/src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java new file mode 100644 index 000000000..0cf2763a1 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/gui/widget/ScrollingContainer.java @@ -0,0 +1,180 @@ +package me.shedaniel.rei.gui.widget; + +import com.mojang.blaze3d.systems.RenderSystem; +import me.shedaniel.clothconfig2.ClothConfigInitializer; +import me.shedaniel.math.Rectangle; +import me.shedaniel.math.impl.PointHelper; +import me.shedaniel.rei.api.ConfigObject; +import me.shedaniel.rei.api.REIHelper; +import net.minecraft.client.render.BufferBuilder; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexFormats; +import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.ApiStatus; + +import static me.shedaniel.rei.gui.widget.EntryListWidget.entrySize; + +@ApiStatus.Internal +public abstract class ScrollingContainer { + public double scrollAmount; + public double scrollTarget; + public long start; + public long duration; + public boolean draggingScrollBar = false; + + public abstract Rectangle getBounds(); + + public Rectangle getScissorBounds() { + Rectangle bounds = getBounds(); + if (hasScrollBar()) { + return new Rectangle(bounds.x, bounds.y, bounds.width - 6, bounds.height); + } + return bounds; + } + + public int getScrollBarX() { + return hasScrollBar() ? getBounds().getMaxX() - 6 : getBounds().getMaxX(); + } + + public boolean hasScrollBar() { + return getMaxScrollHeight() > getBounds().height; + } + + public abstract int getMaxScrollHeight(); + + public final int getMaxScroll() { + return Math.max(0, getMaxScrollHeight() - getBounds().height); + } + + public final double clamp(double v) { + return this.clamp(v, 200.0D); + } + + public final double clamp(double v, double clampExtension) { + return MathHelper.clamp(v, -clampExtension, (double) this.getMaxScroll() + clampExtension); + } + + public final void offset(double value, boolean animated) { + scrollTo(scrollTarget + value, animated); + } + + public final void scrollTo(double value, boolean animated) { + scrollTo(value, animated, ClothConfigInitializer.getScrollDuration()); + } + + public final void scrollTo(double value, boolean animated, long duration) { + scrollTarget = clamp(value); + + if (animated) { + start = System.currentTimeMillis(); + this.duration = duration; + } else + scrollAmount = scrollTarget; + } + + public void updatePosition(float delta) { + double[] target = new double[]{this.scrollTarget}; + this.scrollAmount = ClothConfigInitializer.handleScrollingPosition(target, this.scrollAmount, this.getMaxScroll(), delta, this.start, this.duration); + this.scrollTarget = target[0]; + } + + public void renderScrollBar() { + renderScrollBar(0, 1); + } + + public void renderScrollBar(int background, float alpha) { + if (hasScrollBar()) { + Rectangle bounds = getBounds(); + int maxScroll = getMaxScroll(); + int height = bounds.height * bounds.height / getMaxScrollHeight(); + height = MathHelper.clamp(height, 32, bounds.height); + height -= Math.min((scrollAmount < 0 ? (int) -scrollAmount : scrollAmount > maxScroll ? (int) scrollAmount - maxScroll : 0), height * .95); + height = Math.max(10, height); + int minY = Math.min(Math.max((int) scrollAmount * (bounds.height - height) / maxScroll + bounds.y, bounds.y), bounds.getMaxY() - height); + + int scrollbarPositionMinX = getScrollBarX(); + int scrollbarPositionMaxX = scrollbarPositionMinX + 6; + boolean hovered = (new Rectangle(scrollbarPositionMinX, minY, scrollbarPositionMaxX - scrollbarPositionMinX, height)).contains(PointHelper.ofMouse()); + float bottomC = (hovered ? .67f : .5f) * (REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); + float topC = (hovered ? .87f : .67f) * (REIHelper.getInstance().isDarkThemeEnabled() ? 0.8f : 1f); + + RenderSystem.disableTexture(); + RenderSystem.enableBlend(); + RenderSystem.disableAlphaTest(); + RenderSystem.blendFuncSeparate(770, 771, 1, 0); + RenderSystem.shadeModel(7425); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder buffer = tessellator.getBuffer(); + { + float a = (background >> 24 & 255) / 255.0F; + float r = (background >> 16 & 255) / 255.0F; + float g = (background >> 8 & 255) / 255.0F; + float b = (background & 255) / 255.0F; + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(scrollbarPositionMinX, bounds.getMaxY(), 0.0D).color(r, g, b, a).next(); + buffer.vertex(scrollbarPositionMaxX, bounds.getMaxY(), 0.0D).color(r, g, b, a).next(); + buffer.vertex(scrollbarPositionMaxX, bounds.y, 0.0D).color(r, g, b, a).next(); + buffer.vertex(scrollbarPositionMinX, bounds.y, 0.0D).color(r, g, b, a).next(); + } + tessellator.draw(); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(scrollbarPositionMinX, minY + height, 0.0D).color(bottomC, bottomC, bottomC, alpha).next(); + buffer.vertex(scrollbarPositionMaxX, minY + height, 0.0D).color(bottomC, bottomC, bottomC, alpha).next(); + buffer.vertex(scrollbarPositionMaxX, minY, 0.0D).color(bottomC, bottomC, bottomC, alpha).next(); + buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(bottomC, bottomC, bottomC, alpha).next(); + tessellator.draw(); + buffer.begin(7, VertexFormats.POSITION_COLOR); + buffer.vertex(scrollbarPositionMinX, (minY + height - 1), 0.0D).color(topC, topC, topC, alpha).next(); + buffer.vertex((scrollbarPositionMaxX - 1), (minY + height - 1), 0.0D).color(topC, topC, topC, alpha).next(); + buffer.vertex((scrollbarPositionMaxX - 1), minY, 0.0D).color(topC, topC, topC, alpha).next(); + buffer.vertex(scrollbarPositionMinX, minY, 0.0D).color(topC, topC, topC, alpha).next(); + tessellator.draw(); + RenderSystem.shadeModel(7424); + RenderSystem.disableBlend(); + RenderSystem.enableAlphaTest(); + RenderSystem.enableTexture(); + } + } + + public boolean mouseDragged(double mouseX, double mouseY, int button, double dx, double dy) { + return mouseDragged(mouseX, mouseY, button, dx, dy, false); + } + + public boolean mouseDragged(double mouseX, double mouseY, int button, double dx, double dy, boolean careSnapping) { + if (button == 0 && draggingScrollBar) { + float height = getMaxScrollHeight(); + Rectangle bounds = getBounds(); + int actualHeight = bounds.height; + if (mouseY >= bounds.y && mouseY <= bounds.getMaxY()) { + double maxScroll = Math.max(1, getMaxScroll()); + double int_3 = MathHelper.clamp(((double) (actualHeight * actualHeight) / (double) height), 32, actualHeight - 8); + double double_6 = Math.max(1.0D, maxScroll / (actualHeight - int_3)); + float to = MathHelper.clamp((float) (scrollAmount + dy * double_6), 0, getMaxScroll()); + if (careSnapping && ConfigObject.getInstance().doesSnapToRows()) { + double nearestRow = Math.round(to / (double) entrySize()) * (double) entrySize(); + scrollTo(nearestRow, false); + } else + scrollTo(to, false); + } + return true; + } + return false; + } + + public boolean updateDraggingState(double mouseX, double mouseY, int button) { + if (!hasScrollBar()) + return false; + double height = getMaxScroll(); + Rectangle bounds = getBounds(); + int actualHeight = bounds.height; + if (height > actualHeight && mouseY >= bounds.y && mouseY <= bounds.getMaxY()) { + double scrollbarPositionMinX = getScrollBarX(); + if (mouseX >= scrollbarPositionMinX - 1 & mouseX <= scrollbarPositionMinX + 8) { + this.draggingScrollBar = true; + return true; + } + } + this.draggingScrollBar = false; + return false; + } +} |
