Create/src/main/java/com/simibubi/create/foundation/ponder/PonderProgressBar.java
2021-05-03 18:25:57 +02:00

182 lines
5.6 KiB
Java

package com.simibubi.create.foundation.ponder;
import javax.annotation.Nonnull;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.gui.BoxElement;
import com.simibubi.create.foundation.gui.Theme;
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.FontRenderer;
import net.minecraftforge.fml.client.gui.GuiUtils;
public class PonderProgressBar extends AbstractSimiWidget {
LerpedFloat progress;
PonderUI ponder;
public PonderProgressBar(PonderUI ponder, int xIn, int yIn, int widthIn, int heightIn) {
super(xIn, yIn, widthIn, heightIn);
this.ponder = ponder;
progress = LerpedFloat.linear()
.startWithValue(0);
}
public void tick() {
progress.chase(ponder.getActiveScene()
.getSceneProgress(), .5f, LerpedFloat.Chaser.EXP);
progress.tickChaser();
}
@Override
protected boolean clicked(double mouseX, double mouseY) {
return this.active && this.visible && !ponder.getActiveScene().keyframeTimes.isEmpty()
&& mouseX >= (double) this.x && mouseX < (double) (this.x + this.width + 4) && mouseY >= (double) this.y - 3
&& mouseY < (double) (this.y + this.height + 20);
}
@Override
public void onClick(double mouseX, double mouseY) {
PonderScene activeScene = ponder.getActiveScene();
IntList keyframeTimes = activeScene.keyframeTimes;
int keyframeIndex = getHoveredKeyframeIndex(activeScene, mouseX);
if (keyframeIndex == -1)
ponder.seekToTime(0);
else if (keyframeIndex == keyframeTimes.size())
ponder.seekToTime(activeScene.totalTime);
else
ponder.seekToTime(keyframeTimes.getInt(keyframeIndex));
}
public int getHoveredKeyframeIndex(PonderScene activeScene, double mouseX) {
IntList keyframeTimes = activeScene.keyframeTimes;
int totalTime = activeScene.totalTime;
int clickedAtTime = (int) ((mouseX - x) / ((double) width + 4) * totalTime);
{
int lastKeyframeTime = keyframeTimes.getInt(keyframeTimes.size() - 1);
int diffToEnd = totalTime - clickedAtTime;
int diffToLast = clickedAtTime - lastKeyframeTime;
if (diffToEnd > 0 && diffToEnd < diffToLast / 2) {
return keyframeTimes.size();
}
}
int index = -1;
for (int i = 0; i < keyframeTimes.size(); i++) {
int keyframeTime = keyframeTimes.getInt(i);
if (keyframeTime > clickedAtTime)
break;
index = i;
}
return index;
}
@Override
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
hovered = clicked(mouseX, mouseY);
new BoxElement()
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
.at(x, y, 250)
.withBounds(width, height)
.render(ms);
ms.push();
ms.translate(x - 2, y - 2, 150);
ms.push();
ms.scale((width + 4) * progress.getValue(partialTicks), 1, 1);
int c1 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, true);
int c2 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, false);
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 3, 1, 4, c1, c1);
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 4, 1, 5, c2, c2);
ms.pop();
renderKeyframes(ms, mouseX, partialTicks);
ms.pop();
}
private void renderKeyframes(MatrixStack ms, int mouseX, float partialTicks) {
PonderScene activeScene = ponder.getActiveScene();
int hoverStartColor = Theme.i(Theme.Key.PONDER_HOVER, true) | 0xa0_000000;
int hoverEndColor = Theme.i(Theme.Key.PONDER_HOVER, false) | 0xa0_000000;
int idleStartColor = Theme.i(Theme.Key.PONDER_IDLE, true) | 0x40_000000;
int idleEndColor = Theme.i(Theme.Key.PONDER_IDLE, false) | 0x40_000000;
int hoverIndex;
if (hovered) {
hoverIndex = getHoveredKeyframeIndex(activeScene, mouseX);
} else {
hoverIndex = -2;
}
IntList keyframeTimes = activeScene.keyframeTimes;
if (hoverIndex == -1)
drawKeyframe(ms, activeScene, true, 0, 0, hoverStartColor, hoverEndColor, 8);
else if (hoverIndex == keyframeTimes.size())
drawKeyframe(ms, activeScene, true, activeScene.totalTime, width + 4, hoverStartColor, hoverEndColor, 8);
for (int i = 0; i < keyframeTimes.size(); i++) {
int keyframeTime = keyframeTimes.getInt(i);
int keyframePos = (int) (((float) keyframeTime) / ((float) activeScene.totalTime) * (width + 4));
boolean selected = i == hoverIndex;
int startColor = selected ? hoverStartColor : idleStartColor;
int endColor = selected ? hoverEndColor : idleEndColor;
int height = selected ? 8 : 4;
drawKeyframe(ms, activeScene, selected, keyframeTime, keyframePos, startColor, endColor, height);
}
}
private void drawKeyframe(MatrixStack ms, PonderScene activeScene, boolean selected, int keyframeTime, int keyframePos, int startColor, int endColor, int height) {
if (selected) {
FontRenderer font = Minecraft.getInstance().fontRenderer;
GuiUtils.drawGradientRect(ms.peek()
.getModel(), 100, keyframePos, 10, keyframePos + 1, 10 + height, endColor, startColor);
ms.push();
ms.translate(0, 0, 100);
String text;
int offset;
if (activeScene.currentTime < keyframeTime) {
text = ">";
offset = -1 - font.getStringWidth(text);
} else {
text = "<";
offset = 3;
}
font.draw(ms, text, keyframePos + offset, 10, endColor);
ms.pop();
}
GuiUtils.drawGradientRect(ms.peek()
.getModel(), 500, keyframePos, -1, keyframePos + 1, 2 + height, startColor, endColor);
}
@Override
public void playDownSound(SoundHandler handler) {
}
}