From 4dd834241c88a44061a2ec2af673841062dbe1b0 Mon Sep 17 00:00:00 2001 From: tttsaurus Date: Fri, 10 Jan 2025 22:53:55 -0500 Subject: [PATCH] Added another spotify overlay layout --- .../ingameinfo/common/api/gui/Element.java | 56 ++++++-- .../ingameinfo/common/api/gui/GuiLayout.java | 1 + .../common/api/gui/IgiGuiContainer.java | 3 +- .../common/api/gui/layout/ElementGroup.java | 11 ++ .../common/api/gui/layout/Padding.java | 8 ++ .../common/api/mvvm/binding/VvmBinding.java | 1 + .../appcommunication/spotify/SpotifyView.java | 17 ++- .../spotify/SpotifyViewModel.java | 128 +++++++++++++++++- 8 files changed, 207 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/Element.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/Element.java index ac12675..a6275e2 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/Element.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/Element.java @@ -22,19 +22,50 @@ public abstract class Element private final RenderMask mask = new RenderMask(RenderMask.MaskShape.ROUNDED_RECT); // + + // stores width & height when enabled is false + public float cachedWidth = 0f, cachedHeight = 0f; + + // stores padding when enabled is false + public Padding cachedPadding = new Padding(0f, 0f, 0f, 0f); + // stores the actual render pos (top-left) and size - public Rect rect = new Rect(0, 0, 0, 0); + public Rect rect = new Rect(0f, 0f, 0f, 0f); + // stores the actual render pos before applying the pivot - public float pivotPosX = 0, pivotPosY = 0; + public float pivotPosX = 0f, pivotPosY = 0f; + // stores the rect of the parent group - public Rect contextRect = new Rect(0, 0, 0, 0); + public Rect contextRect = new Rect(0f, 0f, 0f, 0f); + private boolean needReCalc = false; // @StylePropertyCallback public void requestReCalc() { needReCalc = true; } - @StyleProperty + @StylePropertyCallback + public void setEnabledCallbackPre(boolean value, CallbackInfo callbackInfo) + { + if (!enabled && value) + { + rect.width = cachedWidth; + rect.height = cachedHeight; + padding.set(cachedPadding.top, cachedPadding.bottom, cachedPadding.left, cachedPadding.right); + requestReCalc(); + } + if (enabled && !value) + { + cachedWidth = rect.width; + cachedHeight = rect.height; + rect.width = 0f; + rect.height = 0f; + cachedPadding.set(padding.top, padding.bottom, padding.left, padding.right); + padding.set(0f, 0f, 0f, 0f); + requestReCalc(); + } + } + @StyleProperty(setterCallbackPre = "setEnabledCallbackPre") public boolean enabled = true; @StylePropertyCallback @@ -62,12 +93,21 @@ public void pivotValidation(Pivot value, CallbackInfo callbackInfo) public Pivot pivot = Pivot.TOP_LEFT; @StylePropertyCallback - public void paddingValidation(Padding value, CallbackInfo callbackInfo) + public void setPaddingCallbackPre(Padding value, CallbackInfo callbackInfo) { - if (value == null) callbackInfo.cancel = true; + if (value == null) + { + callbackInfo.cancel = true; + return; + } + if (!enabled) + { + cachedPadding.set(value.top, value.bottom, value.left, value.right); + callbackInfo.cancel = true; + } } - @StyleProperty(setterCallbackPost = "requestReCalc", setterCallbackPre = "paddingValidation") - public Padding padding = new Padding(0, 0, 0, 0); + @StyleProperty(setterCallbackPost = "requestReCalc", setterCallbackPre = "setPaddingCallbackPre") + public Padding padding = new Padding(0f, 0f, 0f, 0f); // determines how the background is drawn (optional) @StylePropertyCallback diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/GuiLayout.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/GuiLayout.java index e62d106..540b8b3 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/GuiLayout.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/GuiLayout.java @@ -118,6 +118,7 @@ public GuiLayout addElement(Element element, List styles) return this; } + // todo: add inject priority private void injectStyles(Element element, List styles) { for (ElementStyle style: styles) diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/IgiGuiContainer.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/IgiGuiContainer.java index 70cd947..8ec9fab 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/IgiGuiContainer.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/IgiGuiContainer.java @@ -29,7 +29,7 @@ public class IgiGuiContainer private boolean initFlag = false; private boolean isActive = true; - private IFunc exitCallback; + private IFunc exitCallback = () -> { return true; }; // public boolean getActive() { return isActive; } @@ -66,6 +66,7 @@ public void onScaledResolutionResize() mainGroup.resetRenderInfo(); mainGroup.calcWidthHeight(); mainGroup.calcRenderPos(mainGroup.rect); + mainGroup.finishReCalc(); } public void onFixedUpdate(double deltaTime) { diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/ElementGroup.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/ElementGroup.java index 264a5a5..55fe56b 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/ElementGroup.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/ElementGroup.java @@ -29,7 +29,16 @@ public void resetRenderInfo() public void calcWidthHeight() { for (Element element: elements) + { element.calcWidthHeight(); + if (!element.enabled) + { + element.cachedWidth = element.rect.width; + element.cachedHeight = element.rect.height; + element.rect.width = 0f; + element.rect.height = 0f; + } + } } @Override @@ -60,6 +69,7 @@ public void renderBackground() @Override public boolean getNeedReCalc() { + if (super.getNeedReCalc()) return true; for (Element element: elements) if (element.getNeedReCalc()) return true; return false; @@ -67,6 +77,7 @@ public boolean getNeedReCalc() @Override public void finishReCalc() { + super.finishReCalc(); for (Element element: elements) element.finishReCalc(); } diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/Padding.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/Padding.java index f78922c..623b528 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/Padding.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/gui/layout/Padding.java @@ -18,4 +18,12 @@ public Padding(float top, float bottom, float left, float right) this.left = left; this.right = right; } + + public void set(float top, float bottom, float left, float right) + { + this.top = top; + this.bottom = bottom; + this.left = left; + this.right = right; + } } diff --git a/src/main/java/com/tttsaurus/ingameinfo/common/api/mvvm/binding/VvmBinding.java b/src/main/java/com/tttsaurus/ingameinfo/common/api/mvvm/binding/VvmBinding.java index da19c76..7f1f0d5 100644 --- a/src/main/java/com/tttsaurus/ingameinfo/common/api/mvvm/binding/VvmBinding.java +++ b/src/main/java/com/tttsaurus/ingameinfo/common/api/mvvm/binding/VvmBinding.java @@ -41,6 +41,7 @@ public GuiLayout init(ViewModel viewModel, String mvvmRegistryName) return guiLayout; } + // todo: handle the binding of passiveSync public void bindReactiveObject(Reactive reactive, ReactiveObject reactiveObject) { if (reactive.targetUid().isEmpty()) return; 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 c8b62aa..0a3c233 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,17 +12,22 @@ 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 07025c2..09218b9 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 @@ -6,6 +6,7 @@ import com.tttsaurus.ingameinfo.common.api.appcommunication.spotify.SpotifyUserInfo; import com.tttsaurus.ingameinfo.common.api.appcommunication.spotify.TrackPlaying; import com.tttsaurus.ingameinfo.common.api.gui.delegate.button.IMouseClickButton; +import com.tttsaurus.ingameinfo.common.api.gui.layout.Padding; import com.tttsaurus.ingameinfo.common.api.mvvm.binding.Reactive; import com.tttsaurus.ingameinfo.common.api.mvvm.binding.ReactiveObject; import com.tttsaurus.ingameinfo.common.api.mvvm.viewmodel.ViewModel; @@ -22,24 +23,69 @@ public class SpotifyViewModel extends ViewModel { + // albumImageGroup + @Reactive(targetUid = "albumImageGroup", property = "padding", initiativeSync = true) + public ReactiveObject albumImageGroupPadding = new ReactiveObject<>(){}; + + // albumImage @Reactive(targetUid = "albumImage", property = "url", initiativeSync = true) public ReactiveObject albumImageUrl = new ReactiveObject<>(){}; + @Reactive(targetUid = "albumImage", property = "width", initiativeSync = true) + public ReactiveObject albumImageWidth = new ReactiveObject<>(){}; + + @Reactive(targetUid = "albumImage", property = "height", initiativeSync = true) + public ReactiveObject albumImageHeight = new ReactiveObject<>(){}; + + @Reactive(targetUid = "albumImage", property = "padding", initiativeSync = true) + public ReactiveObject albumImagePadding = new ReactiveObject<>(){}; + + // trackTitleGroup + @Reactive(targetUid = "trackTitleGroup", property = "enabled", initiativeSync = true) + public ReactiveObject trackTitleGroupEnabled = new ReactiveObject<>(){}; + + // trackTitle @Reactive(targetUid = "trackTitle", property = "text", initiativeSync = true) public ReactiveObject trackTitleText = new ReactiveObject<>(){}; @Reactive(targetUid = "trackTitle", property = "xShiftSpeed", initiativeSync = true) public ReactiveObject trackTitleXShiftSpeed = new ReactiveObject<>(){}; + // progressBarGroup + @Reactive(targetUid = "progressBarGroup", property = "padding", initiativeSync = true) + public ReactiveObject progressBarGroupPadding = new ReactiveObject<>(){}; + + // progressBar @Reactive(targetUid = "progressBar", property = "percentage", initiativeSync = true) public ReactiveObject progressBarPercentage = new ReactiveObject<>(){}; + @Reactive(targetUid = "progressBar", property = "width", initiativeSync = true) + public ReactiveObject progressBarWidth = new ReactiveObject<>(){}; + + // anotherTrackTitleGroup + @Reactive(targetUid = "anotherTrackTitleGroup", property = "enabled", initiativeSync = true) + public ReactiveObject anotherTrackTitleGroupEnabled = new ReactiveObject<>(){}; + + @Reactive(targetUid = "anotherTrackTitle", property = "text", initiativeSync = true) + public ReactiveObject anotherTrackTitleText = new ReactiveObject<>(){}; + + @Reactive(targetUid = "anotherTrackTitle", property = "xShiftSpeed", initiativeSync = true) + public ReactiveObject anotherTrackTitleXShiftSpeed = new ReactiveObject<>(){}; + + @Reactive(targetUid = "anotherTrackAuthor", property = "text", initiativeSync = true) + public ReactiveObject anotherTrackAuthorText = new ReactiveObject<>(){}; + + @Reactive(targetUid = "anotherTrackTimer", property = "text", initiativeSync = true) + public ReactiveObject anotherTrackTimerText = new ReactiveObject<>(){}; + + // editButton @Reactive(targetUid = "editButton", property = "enabled", initiativeSync = true) public ReactiveObject editButtonEnabled = new ReactiveObject<>(){}; @Reactive(targetUid = "editButton", property = "addClickListener", initiativeSync = true) public ReactiveObject editButtonAddClickListener = new ReactiveObject<>(){}; + private boolean extendedLayout = false; private float durationMs = 0; private float estimatedProgressMs; private boolean isPlaying = false; @@ -109,12 +155,38 @@ private void refreshTrackInfo() durationMs = trackPlaying.durationMs; estimatedProgressMs = trackPlaying.progressMs; isPlaying = trackPlaying.isPlaying; + + anotherTrackTitleXShiftSpeed.set(8f); + if (!anotherTrackTitleText.get().equals(trackPlaying.trackName)) + anotherTrackTitleText.set(trackPlaying.trackName); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < trackPlaying.artists.size(); i++) + { + builder.append(trackPlaying.artists.get(i)); + if (i != trackPlaying.artists.size() - 1) builder.append(", "); + } + String authors = builder.toString(); + if (!anotherTrackAuthorText.get().equals(authors)) + anotherTrackAuthorText.set(authors); + anotherTrackTimerText.set(calcTimeText(percentage)); } } catch (Exception ignored) { } return null; }); } + private String calcTimeText(float percentage) + { + int totalSeconds = (int)durationMs / 1000; + int minutes = totalSeconds / 60; + int seconds = totalSeconds % 60; + String time = String.format("%d:%02d", minutes, seconds); + totalSeconds = (int)(percentage * totalSeconds); + minutes = totalSeconds / 60; + seconds = totalSeconds % 60; + time = String.format("%d:%02d", minutes, seconds) + " / " + time; + return time; + } @Override public void start() @@ -129,11 +201,42 @@ public void start() albumImageUrl.set(""); progressBarPercentage.set(0f); - editButtonEnabled.set(false); + + trackTitleGroupEnabled.set(true); + albumImageGroupPadding.set(new Padding(10f, 5f, 0f, 0f)); + albumImageWidth.set(40f); + albumImageHeight.set(40f); + albumImagePadding.set(new Padding(0f, 0f, 10f, 10f)); + progressBarGroupPadding.set(new Padding(0f, 10f, 0f, 0f)); + progressBarWidth.set(50f); + anotherTrackTitleGroupEnabled.set(false); + editButtonAddClickListener.set((IMouseClickButton)(() -> { - if (Minecraft.getMinecraft().player != null) - Minecraft.getMinecraft().player.sendChatMessage("test"); + if (extendedLayout) + { + extendedLayout = false; + trackTitleGroupEnabled.set(true); + albumImageGroupPadding.set(new Padding(10f, 5f, 0f, 0f)); + albumImageWidth.set(40f); + albumImageHeight.set(40f); + albumImagePadding.set(new Padding(0f, 0f, 10f, 10f)); + progressBarGroupPadding.set(new Padding(0f, 10f, 0f, 0f)); + progressBarWidth.set(50f); + anotherTrackTitleGroupEnabled.set(false); + } + else + { + extendedLayout = true; + trackTitleGroupEnabled.set(false); + albumImageGroupPadding.set(new Padding(5f, 5f, 0f, 0f)); + albumImageWidth.set(60f); + albumImageHeight.set(60f); + albumImagePadding.set(new Padding(0f, 0f, 5f, 5f)); + progressBarGroupPadding.set(new Padding(0f, 5f, 0f, 0f)); + progressBarWidth.set(115f); + anotherTrackTitleGroupEnabled.set(true); + } })); EventCenter.spotifyOverlayEvent.addListener((flag) -> @@ -155,6 +258,11 @@ public void start() trackTitleXShiftSpeed.set(20f); trackTitleText.set("Please wait... And make sure you play a track on Spotify"); + anotherTrackTitleXShiftSpeed.set(20f); + anotherTrackTitleText.set("Please wait... And make sure you play a track on Spotify"); + anotherTrackAuthorText.set(""); + anotherTrackTimerText.set(""); + refreshTokenIfNeeded(() -> { try @@ -172,6 +280,17 @@ public void start() durationMs = trackPlaying.durationMs; estimatedProgressMs = trackPlaying.progressMs; isPlaying = trackPlaying.isPlaying; + + anotherTrackTitleXShiftSpeed.set(8f); + anotherTrackTitleText.set(trackPlaying.trackName); + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < trackPlaying.artists.size(); i++) + { + builder.append(trackPlaying.artists.get(i)); + if (i != trackPlaying.artists.size() - 1) builder.append(", "); + } + anotherTrackAuthorText.set(builder.toString()); + anotherTrackTimerText.set(calcTimeText(percentage)); } } catch (Exception ignored) { } @@ -271,6 +390,9 @@ public void onFixedUpdate(double deltaTime) } float percentage = estimatedProgressMs / durationMs; progressBarPercentage.set(percentage); + String timeText = calcTimeText(percentage); + if (!anotherTrackTimerText.get().equals(timeText)) + anotherTrackTimerText.set(timeText); } } }