From c7fd91d4ab8603eabe15cb233285f0a3ef68c8b4 Mon Sep 17 00:00:00 2001 From: tttsaurus Date: Tue, 7 Jan 2025 20:56:49 -0500 Subject: [PATCH] Polished spotify support --- .../common/api/render/RenderUtils.java | 52 ++++++++++++++++++- .../appcommunication/spotify/SpotifyView.java | 2 +- .../spotify/SpotifyViewModel.java | 27 ++++++++++ .../common/impl/gui/control/ProgressBar.java | 8 ++- .../common/impl/gui/control/SlidingText.java | 2 +- .../common/impl/gui/control/UrlImage.java | 8 +++ 6 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/render/RenderUtils.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/render/RenderUtils.java index 03f3fc8..79cc367 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/render/RenderUtils.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/render/RenderUtils.java @@ -141,7 +141,7 @@ private static void addArcVertices(BufferBuilder bufferbuilder, float cx, float } } - public static void startStencil(float x, float y, float stencilWidth, float stencilHeight, int stencilValue) + public static void startRoundedRectStencil(float x, float y, float stencilWidth, float stencilHeight, int stencilValue, float radius) { if (!Minecraft.getMinecraft().getFramebuffer().isStencilEnabled()) Minecraft.getMinecraft().getFramebuffer().enableStencil(); @@ -160,12 +160,62 @@ public static void startStencil(float x, float y, float stencilWidth, float sten // mask area GL11.glStencilMask(0xFF); + + int segments = Math.max(3, (int)(radius / 2f)); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL11.GL_POLYGON, DefaultVertexFormats.POSITION); + + addArcVertices(bufferbuilder, x + stencilWidth - radius, y + radius, radius, 0, 90, segments); + bufferbuilder.pos(x + stencilWidth, y + radius, 0).endVertex(); + bufferbuilder.pos(x + stencilWidth, y + stencilHeight - radius, 0).endVertex(); + addArcVertices(bufferbuilder, x + stencilWidth - radius, y + stencilHeight - radius, radius, 90, 180, segments); + bufferbuilder.pos(x + stencilWidth - radius, y + stencilHeight, 0).endVertex(); + bufferbuilder.pos(x + radius, y + stencilHeight, 0).endVertex(); + addArcVertices(bufferbuilder, x + radius, y + stencilHeight - radius, radius, 180, 270, segments); + bufferbuilder.pos(x, y + stencilHeight - radius, 0).endVertex(); + bufferbuilder.pos(x, y + radius, 0).endVertex(); + addArcVertices(bufferbuilder, x + radius, y + radius, radius, 270, 360, segments); + bufferbuilder.pos(x + radius, y, 0).endVertex(); + bufferbuilder.pos(x + stencilWidth - radius, y, 0).endVertex(); + + tessellator.draw(); + + GL11.glStencilMask(0x00); + + GlStateManager.depthMask(true); + GlStateManager.colorMask(true, true, true, true); + GL11.glStencilFunc(GL11.GL_EQUAL, stencilValue, 0xFF); + GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP); + } + + public static void startRectStencil(float x, float y, float stencilWidth, float stencilHeight, int stencilValue) + { + if (!Minecraft.getMinecraft().getFramebuffer().isStencilEnabled()) + Minecraft.getMinecraft().getFramebuffer().enableStencil(); + + GlStateManager.disableTexture2D(); + GlStateManager.disableCull(); + + GL11.glEnable(GL11.GL_STENCIL_TEST); + //GL11.glClearStencil(0); + //GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + + GlStateManager.depthMask(false); + GlStateManager.colorMask(false, false, false, false); + GL11.glStencilFunc(GL11.GL_ALWAYS, stencilValue, 0xFF); + GL11.glStencilOp(GL11.GL_REPLACE, GL11.GL_REPLACE, GL11.GL_REPLACE); + + // mask area + GL11.glStencilMask(0xFF); + GL11.glBegin(GL11.GL_QUADS); GL11.glVertex2f(x, y); GL11.glVertex2f(x + stencilWidth, y); GL11.glVertex2f(x + stencilWidth, y + stencilHeight); GL11.glVertex2f(x, y + stencilHeight); GL11.glEnd(); + GL11.glStencilMask(0x00); GlStateManager.depthMask(true); diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyView.java b/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyView.java index 59604db..3d83c5a 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyView.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyView.java @@ -12,7 +12,7 @@ public String getDefaultIxml() - + diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyViewModel.java b/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyViewModel.java index 858be0e..42f0f37 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyViewModel.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/impl/appcommunication/spotify/SpotifyViewModel.java @@ -25,6 +25,10 @@ public class SpotifyViewModel extends ViewModel @Reactive(targetUid = "progressBar", property = "percentage", initiativeSync = true) public ReactiveObject progressBarPercentage = new ReactiveObject<>(){}; + private float durationMs = 0; + private float estimatedProgressMs; + private boolean isPlaying = false; + private void refreshTokenIfNeeded() { long timeSpan = Duration.between(SpotifyUserInfo.token.start, LocalDateTime.now()).getSeconds(); @@ -86,6 +90,9 @@ private void refreshTrackInfo() if (trackPlaying.durationMs != 0) percentage = ((float)trackPlaying.progressMs) / ((float)trackPlaying.durationMs); progressBarPercentage.set(percentage); + durationMs = trackPlaying.durationMs; + estimatedProgressMs = trackPlaying.progressMs; + isPlaying = trackPlaying.isPlaying; } } catch (Exception ignored) { } @@ -97,6 +104,7 @@ private void refreshTrackInfo() public void start() { activeSetter.invoke(false); + progressBarPercentage.set(0f); EventCenter.spotifyOverlayEvent.addListener((flag) -> { @@ -118,6 +126,9 @@ public void start() if (trackPlaying.durationMs != 0) percentage = ((float)trackPlaying.progressMs) / ((float)trackPlaying.durationMs); progressBarPercentage.set(percentage); + durationMs = trackPlaying.durationMs; + estimatedProgressMs = trackPlaying.progressMs; + isPlaying = trackPlaying.isPlaying; } } catch (Exception ignored) { } @@ -192,5 +203,21 @@ public void onFixedUpdate(double deltaTime) refreshTrackTimer -= 3f; refreshTrackInfo(); } + + if (progressBarPercentage.get() < 1 && isPlaying) + { + int timeMs = (int)(deltaTime * 1000); + estimatedProgressMs += timeMs; + if (durationMs != 0) + { + if (estimatedProgressMs >= durationMs) + { + estimatedProgressMs = durationMs; + refreshTrackTimer = 2f; + } + float percentage = estimatedProgressMs / durationMs; + progressBarPercentage.set(percentage); + } + } } } diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/ProgressBar.java b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/ProgressBar.java index 72db192..6f514e7 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/ProgressBar.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/ProgressBar.java @@ -35,8 +35,12 @@ public void onRenderUpdate(boolean focused) { if (rect.width == 0 || rect.height == 0) return; RenderUtils.renderRoundedRect(rect.x, rect.y, rect.width, rect.height, rect.height / 2f, backgroundColor); - if (rect.width * percentage > rect.height) - RenderUtils.renderRoundedRect(rect.x, rect.y, rect.width * percentage, rect.height, rect.height / 2f, fillerColor); + if (percentage != 0) + { + RenderUtils.startRoundedRectStencil(rect.x, rect.y, rect.width, rect.height, 2, rect.height / 2f); + RenderUtils.renderRect(rect.x, rect.y, rect.width * percentage, rect.height, fillerColor); + RenderUtils.endStencil(); + } RenderUtils.renderRoundedRectOutline(rect.x, rect.y, rect.width, rect.height, rect.height / 2f, 1.0f, outlineColor); } } diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/SlidingText.java b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/SlidingText.java index d056482..1f20a82 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/SlidingText.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/SlidingText.java @@ -121,7 +121,7 @@ public void onRenderUpdate(boolean focused) { if (!onDemandSliding || needSliding) { - RenderUtils.startStencil(rect.x, rect.y, rect.width, rect.height, 1); + RenderUtils.startRectStencil(rect.x, rect.y, rect.width, rect.height, 1); if (forwardSliding) { diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/UrlImage.java b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/UrlImage.java index a1bb5d2..2bc5f92 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/UrlImage.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/impl/gui/control/UrlImage.java @@ -5,6 +5,7 @@ import com.tttsaurus.ingameinfo.common.api.gui.style.CallbackInfo; import com.tttsaurus.ingameinfo.common.api.gui.style.StyleProperty; import com.tttsaurus.ingameinfo.common.api.gui.style.StylePropertyCallback; +import com.tttsaurus.ingameinfo.common.api.render.RenderUtils; import com.tttsaurus.ingameinfo.common.impl.render.renderer.UrlImageRenderer; @RegisterElement @@ -12,6 +13,9 @@ public class UrlImage extends Sized { private final UrlImageRenderer urlImageRenderer = new UrlImageRenderer(); + @StyleProperty + public boolean rounded; + @StylePropertyCallback public void urlValidation(String value, CallbackInfo callbackInfo) { @@ -50,6 +54,10 @@ public void onFixedUpdate(double deltaTime) @Override public void onRenderUpdate(boolean focused) { + if (rounded) + RenderUtils.startRoundedRectStencil(rect.x, rect.y, rect.width, rect.height, 1, 3f); urlImageRenderer.render(); + if (rounded) + RenderUtils.endStencil(); } }