From edeb8811054b7d08fe856817e943991d76b061cb Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 14:30:52 +0300 Subject: [PATCH 01/43] chore: update dependencies --- build.gradle | 2 +- fabric/build.gradle | 2 -- gradle.properties | 11 +++++------ neoforge/build.gradle | 2 -- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index 1e340af..0e1089b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'dev.architectury.loom' version '1.11-SNAPSHOT' apply false + id 'dev.architectury.loom' version '1.13.467' apply false id 'architectury-plugin' version '3.4-SNAPSHOT' id 'com.gradleup.shadow' version '8.3.6' apply false } diff --git a/fabric/build.gradle b/fabric/build.gradle index 06ad8cc..2fea682 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -29,8 +29,6 @@ dependencies { modCompileOnly "com.terraformersmc:modmenu:${rootProject.mod_menu_version}" modLocalRuntime "com.terraformersmc:modmenu:${rootProject.mod_menu_version}" - modLocalRuntime "dev.emi:emi-fabric:${rootProject.emi_version}" - common(project(path: ':common', configuration: 'namedElements')) { transitive = false } shadowBundle project(path: ':common', configuration: 'transformProductionFabric') } diff --git a/gradle.properties b/gradle.properties index 257d044..bbfa650 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.parallel=true org.gradle.configuration-cache=false # Minecraft properties -minecraft_version=1.21.1 +minecraft_version=1.21.11 # Mod Properties mod_version=0.3.0 @@ -15,12 +15,11 @@ archives_name=easegui enabled_platforms=fabric,neoforge # Mappings version. Find versions here: https://parchmentmc.org/docs/getting-started -parchment_version=2024.11.17 +parchment_version=2025.12.20 # Dependencies -neoforge_version=21.1.65 +neoforge_version=21.11.0-beta fabric_loader_version=0.18.4 -fabric_api_version=0.105.0+1.21.1 -mod_menu_version=11.0.4 -emi_version=1.1.12+1.21 +fabric_api_version=0.139.4+1.21.11 +mod_menu_version=17.0.0-alpha.1 junit_version=5.13.4 \ No newline at end of file diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 3430b6b..4f90a20 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -25,8 +25,6 @@ configurations { dependencies { neoForge "net.neoforged:neoforge:$rootProject.neoforge_version" - localRuntime "dev.emi:emi-neoforge:${rootProject.emi_version}" - common(project(path: ':common', configuration: 'namedElements')) { transitive = false } shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') } From 3b62ec382c065d403647695e2633281ded28ffcf Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 14:45:38 +0300 Subject: [PATCH 02/43] ref: imports --- .../client/animator/AdvancementsAnimator.java | 2 +- .../client/animator/BackgroundAnimator.java | 1 - .../client/animator/ContainerAnimator.java | 2 +- .../client/animator/ListItemAnimator.java | 2 +- .../easegui/client/animator/LogoAnimator.java | 34 +++++++++---------- .../client/animator/SplashAnimator.java | 2 +- .../client/animator/WidgetAnimator.java | 2 +- .../client/config/EaseGUIScreenRegistry.java | 2 +- .../client/mixin/gui/AbstractWidgetMixin.java | 2 +- .../mixin/gui/title/TitleScreenMixin.java | 4 +-- .../client/state/ScreenStateTracker.java | 2 +- 11 files changed, 27 insertions(+), 28 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java index c540cfb..46a8187 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java index 5e41d12..9ff5828 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java @@ -22,7 +22,6 @@ public static boolean isLoadingScreen(Screen screen) { return screen instanceof LevelLoadingScreen || screen instanceof ProgressScreen || screen instanceof ConnectScreen - || screen instanceof ReceivingLevelScreen || screen instanceof GenericWaitingScreen || screen instanceof BackupConfirmScreen; } diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index 0fae467..b435511 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java index 093e3e4..c479e9e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.weyne1.easegui.client.animation.AnimationMath; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java index cffb2bd..0c2403f 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java @@ -1,9 +1,9 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.LogoRenderer; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.resources.Identifier; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.animation.AnimationScope; @@ -18,16 +18,16 @@ */ public class LogoAnimator { - private static final ResourceLocation[] LETTER_TEXTURES = new ResourceLocation[] { - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/m.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/i.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/n.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/e.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/t.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/f.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/a.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/r.png"), - ResourceLocation.fromNamespaceAndPath("easegui", "textures/gui/title/letters/c.png") + private static final Identifier[] LETTER_TEXTURES = new Identifier[] { + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/m.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/i.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/n.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/e.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/t.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/f.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/a.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/r.png"), + Identifier.fromNamespaceAndPath("easegui", "textures/gui/title/letters/c.png") }; /** @@ -51,7 +51,7 @@ public static boolean render(GuiGraphics gg, int screenWidth, float transparency float finalAlpha = keepLogoThroughFade ? 1.0f : transparency; int startX = screenWidth / 2 - (LogoRendererAccessor.easeGUI$getLogoWidth() / 2); - ResourceLocation logoTexture = showEasterEgg ? LogoRenderer.EASTER_EGG_LOGO : LogoRenderer.MINECRAFT_LOGO; + Identifier logoTexture = showEasterEgg ? LogoRenderer.EASTER_EGG_LOGO : LogoRenderer.MINECRAFT_LOGO; if (logoConfig.animateWholeText) { renderWholeLogo(gg, logoTexture, logoConfig.logoProfile, startX, height, finalAlpha); } else { @@ -63,7 +63,7 @@ public static boolean render(GuiGraphics gg, int screenWidth, float transparency return true; } - private static void renderWholeLogo(GuiGraphics gg, ResourceLocation texture, AnimationProfile profile, int startX, int height, float finalAlpha) { + private static void renderWholeLogo(GuiGraphics gg, Identifier texture, AnimationProfile profile, int startX, int height, float finalAlpha) { long elapsed = Util.getMillis() - actualStartTime; int logoWidth = LogoRendererAccessor.easeGUI$getLogoWidth(); int logoHeight = LogoRendererAccessor.easeGUI$getLogoHeight(); @@ -91,7 +91,7 @@ private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profi if (now - actualStartTime >= maxLogoDelay + profile.duration) { try (AnimationScope ignored = AnimationSystem.beginAlphaOnly(gg, finalAlpha)) { - for (ResourceLocation texture : LETTER_TEXTURES) { + for (Identifier texture : LETTER_TEXTURES) { drawLogoTexture(gg, texture, startX, height); } gg.flush(); @@ -101,7 +101,7 @@ private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profi for (int i = 0; i < LETTER_TEXTURES.length; i++) { int logicalIndex = LOGICAL_INDICES[i]; - ResourceLocation texture = LETTER_TEXTURES[i]; + Identifier texture = LETTER_TEXTURES[i]; long cascadeDelay = calculateCascadeDelay(profile, logicalIndex); long elapsed = now - actualStartTime - cascadeDelay; @@ -172,7 +172,7 @@ private static void trackSessionTime() { } } - private static void drawLogoTexture(GuiGraphics gg, ResourceLocation texture, int x, int y) { + private static void drawLogoTexture(GuiGraphics gg, Identifier texture, int x, int y) { gg.blit(texture, x, y, 0.0f, 0.0f, LogoRendererAccessor.easeGUI$getLogoWidth(), LogoRendererAccessor.easeGUI$getLogoHeight(), diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java index 94806db..8572793 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationScope; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index 7629c4c..3a2b3df 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java index 2e34667..61f4d8f 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java @@ -71,7 +71,7 @@ public final class EaseGUIScreenRegistry { register("create_flat_world", CreateFlatWorldScreen.class, 1000, ScreenGroup.WORLDS); register("direct_join_server", DirectJoinServerScreen.class, 1000, ScreenGroup.WORLDS); register("edit_world", EditWorldScreen.class, 1000, ScreenGroup.WORLDS); - register("edit_server", EditServerScreen.class, 1000, ScreenGroup.WORLDS); + register("edit_server", ManageServerScreen.class, 1000, ScreenGroup.WORLDS); register("edit_game_rules", EditGameRulesScreen.class, 1000, ScreenGroup.WORLDS); register("experiments", ExperimentsScreen.class, 1000, ScreenGroup.WORLDS); register("connecting", ConnectScreen.class, 1000, ScreenGroup.WORLDS); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index 2e18aa1..9cbc43d 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.mixin.gui; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.*; import net.weyne1.easegui.client.EaseGUIWidget; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java index 15ab170..07bffe9 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java @@ -11,11 +11,11 @@ public class TitleScreenMixin { /** - * Cancels the vanilla TitleScreen fadeWidgets animation if EaseGUI is enabled for this screen. + * Cancels the vanilla TitleScreen setWidgetAlpha animation if EaseGUI is enabled for this screen. * This allows EaseGUI to fully control widget fade-in animation, * while preserving vanilla transitions if the screen animation is disabled. */ - @Inject(method = "fadeWidgets", at = @At("HEAD"), cancellable = true) + @Inject(method = "setWidgetAlpha", at = @At("HEAD"), cancellable = true) private void easeGUI$cancelFade(float alpha, CallbackInfo ci) { var titleSettings = ConfigManager.getConfig().screens.get("title"); diff --git a/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java b/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java index 5e6f310..12af6f2 100644 --- a/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java +++ b/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java @@ -1,6 +1,6 @@ package net.weyne1.easegui.client.state; -import net.minecraft.Util; +import net.minecraft.util.Util; import net.minecraft.client.gui.screens.Screen; import java.lang.ref.WeakReference; From 76065eb9ad86d1bfdd42840e70977e35e91d0f8f Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 15:15:24 +0300 Subject: [PATCH 03/43] ref: animation system --- .../client/animation/AnimationScope.java | 36 +++++++++---------- .../easegui/client/animator/LogoAnimator.java | 11 ++---- .../client/animator/SplashAnimator.java | 2 +- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java index 72ceb7c..78d1158 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java @@ -2,6 +2,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.weyne1.easegui.client.EaseGUIDebug; +import org.joml.Matrix3x2fStack; public final class AnimationScope implements AutoCloseable { private static final float MIN_SCALE = 0.001f; @@ -17,9 +18,8 @@ public final class AnimationScope implements AutoCloseable { public AnimationScope(GuiGraphics guiGraphics, float alpha) { this.guiGraphics = guiGraphics; - this.guiGraphics.flush(); AnimationContext.pushAnimation(alpha); - this.guiGraphics.pose().pushPose(); + this.guiGraphics.pose().pushMatrix(); } public void setTransformParams(float offsetX, float offsetY, float scaleX, float scaleY, float pivotX, float pivotY) { @@ -30,29 +30,30 @@ public void setTransformParams(float offsetX, float offsetY, float scaleX, float this.pivotX = pivotX; this.pivotY = pivotY; + Matrix3x2fStack poseStack = guiGraphics.pose(); + if (this.scaleX != 1.0f || this.scaleY != 1.0f) { - guiGraphics.pose().translate(offsetX + pivotX, offsetY + pivotY, 0.0f); - guiGraphics.pose().scale(this.scaleX, this.scaleY, 1.0f); - guiGraphics.pose().translate(-pivotX, -pivotY, 0.0f); + poseStack.translate(offsetX + pivotX, offsetY + pivotY); + poseStack.scale(this.scaleX, this.scaleY); + poseStack.translate(-pivotX, -pivotY); } else { - guiGraphics.pose().translate(offsetX, offsetY, 0.0f); + poseStack.translate(offsetX, offsetY); } } public void suspend() { if (isClosed || isSuspended) return; - this.guiGraphics.flush(); AnimationContext.suspend(); - - guiGraphics.pose().pushPose(); + Matrix3x2fStack poseStack = guiGraphics.pose(); + poseStack.pushMatrix(); if (scaleX != 1.0f || scaleY != 1.0f) { - guiGraphics.pose().translate(pivotX, pivotY, 0.0f); - guiGraphics.pose().scale(1.0f / scaleX, 1.0f / scaleY, 1.0f); - guiGraphics.pose().translate(-(offsetX + pivotX), -(offsetY + pivotY), 0.0f); + poseStack.translate(pivotX, pivotY); + poseStack.scale(1.0f / scaleX, 1.0f / scaleY); + poseStack.translate(-(offsetX + pivotX), -(offsetY + pivotY)); } else { - guiGraphics.pose().translate(-offsetX, -offsetY, 0.0f); + poseStack.translate(-offsetX, -offsetY); } isSuspended = true; @@ -61,8 +62,7 @@ public void suspend() { public void resume() { if (isClosed || !isSuspended) return; - this.guiGraphics.flush(); - guiGraphics.pose().popPose(); + guiGraphics.pose().popMatrix(); AnimationContext.resume(); isSuspended = false; @@ -73,16 +73,14 @@ public void close() { if (isClosed) return; isClosed = true; - this.guiGraphics.flush(); - if (isSuspended) { - guiGraphics.pose().popPose(); + guiGraphics.pose().popMatrix(); AnimationContext.resume(); isSuspended = false; } try { - guiGraphics.pose().popPose(); + guiGraphics.pose().popMatrix(); } catch (IllegalStateException e) { EaseGUIDebug.reportError("pose_stack_underflow", () -> "PoseStack underflow inside AnimationScope close!"); } diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java index 0c2403f..752c0b2 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java @@ -1,5 +1,6 @@ package net.weyne1.easegui.client.animator; +import net.minecraft.client.renderer.RenderPipelines; import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.LogoRenderer; @@ -71,7 +72,6 @@ private static void renderWholeLogo(GuiGraphics gg, Identifier texture, Animatio if (elapsed >= profile.duration) { try (AnimationScope ignored = AnimationSystem.beginAlphaOnly(gg, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); - gg.flush(); } return; } @@ -79,7 +79,6 @@ private static void renderWholeLogo(GuiGraphics gg, Identifier texture, Animatio float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); try (AnimationScope ignored = AnimationSystem.begin(gg, startX, height, logoWidth, logoHeight, profile, progress, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); - gg.flush(); } } @@ -94,7 +93,6 @@ private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profi for (Identifier texture : LETTER_TEXTURES) { drawLogoTexture(gg, texture, startX, height); } - gg.flush(); } return; } @@ -109,7 +107,6 @@ private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profi try (AnimationScope ignored = AnimationSystem.begin(gg, startX, height, logoWidth, logoHeight, profile, progress, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); - gg.flush(); } } } @@ -137,14 +134,12 @@ private static void renderEditionText(GuiGraphics gg, EaseGUIConfig.LogoSettings float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); try (AnimationScope ignored = AnimationSystem.begin(gg, x, y, editionWidth, editionHeight, profile, progress, finalAlpha)) { drawEditionTexture(gg, x, y); - gg.flush(); } } private static void drawStaticEdition(GuiGraphics gg, int x, int y, float finalAlpha) { try (AnimationScope ignored = AnimationSystem.beginAlphaOnly(gg, finalAlpha)) { drawEditionTexture(gg, x, y); - gg.flush(); } } @@ -173,7 +168,7 @@ private static void trackSessionTime() { } private static void drawLogoTexture(GuiGraphics gg, Identifier texture, int x, int y) { - gg.blit(texture, x, y, 0.0f, 0.0f, + gg.blit(RenderPipelines.GUI_TEXTURED, texture, x, y, 0.0f, 0.0f, LogoRendererAccessor.easeGUI$getLogoWidth(), LogoRendererAccessor.easeGUI$getLogoHeight(), LogoRendererAccessor.easeGUI$getLogoWidth(), @@ -181,7 +176,7 @@ private static void drawLogoTexture(GuiGraphics gg, Identifier texture, int x, i } private static void drawEditionTexture(GuiGraphics gg, int x, int y) { - gg.blit(LogoRenderer.MINECRAFT_EDITION, x, y, 0.0f, 0.0f, + gg.blit(RenderPipelines.GUI_TEXTURED, LogoRenderer.MINECRAFT_EDITION, x, y, 0.0f, 0.0f, LogoRendererAccessor.easeGUI$getEditionWidth(), LogoRendererAccessor.easeGUI$getEditionHeight(), LogoRendererAccessor.easeGUI$getEditionWidth(), diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java index 8572793..9419516 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java @@ -37,7 +37,7 @@ public static AnimationScope beginRender(GuiGraphics gg, int color) { float finalAlpha = baseAlpha * progress; AnimationScope scope = AnimationSystem.beginAlphaOnly(gg, finalAlpha); - gg.pose().scale(progress, progress, 1.0f); + gg.pose().scale(progress, progress); return scope; } From f53b5a19c612e35efa070f703a0dbc82c3718805 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 15:30:59 +0300 Subject: [PATCH 04/43] ref: EaseGUI screens --- .../easegui/client/gui/FieldValidator.java | 4 +- .../gui/components/SettingsScrollList.java | 62 +++++++------------ .../screens/EaseGUIAbstractSplitScreen.java | 22 ++++--- .../client/gui/screens/MainConfigScreen.java | 1 - .../gui/screens/ProfileEditorScreen.java | 5 +- .../screens/ScreenSpecificConfigScreen.java | 5 +- 6 files changed, 42 insertions(+), 57 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java b/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java index de2f9be..0a546f9 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java @@ -9,8 +9,8 @@ public class FieldValidator { public static final String REGEX_INT = "\\d*"; public static final String REGEX_FLOAT = "-?\\d*\\.?\\d*"; - private static final int COLOR_VALID = 0xE0E0E0; - private static final int COLOR_INVALID = 0xFF5555; + private static final int COLOR_VALID = 0xFFE0E0E0; + private static final int COLOR_INVALID = 0xFFFF5555; public static void registerLongValidator(EditBox editBox, long min, long max, Consumer onSuccess) { editBox.setFilter(s -> s.matches(REGEX_INT)); diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/components/SettingsScrollList.java b/common/src/main/java/net/weyne1/easegui/client/gui/components/SettingsScrollList.java index 817fe16..7d336a5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/components/SettingsScrollList.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/components/SettingsScrollList.java @@ -1,6 +1,5 @@ package net.weyne1.easegui.client.gui.components; -import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -11,6 +10,7 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.network.chat.Component; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; import java.util.List; @@ -32,21 +32,13 @@ public int getRowWidth() { return Math.min(this.width - 40, MAX_ROW_WIDTH); } - @Override - protected int getScrollbarPosition() { - return this.getX() + this.width - 6; - } - public void addHeader(String text) { this.addEntry(new HeaderEntry(text)); } - - public void addButton(Button btn) { this.addEntry(new ButtonEntry(btn)); } - public void addTwoButtons(Button btn1, Button btn2) {this.addTwoButtons(btn1, btn2, 0.60f); } + public void addButton(Button btn) { this.addEntry(new ButtonEntry(this.getRowWidth(), btn)); } + public void addTwoButtons(Button btn1, Button btn2) { this.addTwoButtons(btn1, btn2, 0.60f); } public void addTwoButtons(Button btn1, Button btn2, float firstButtonRatio) { this.addEntry(new TwoButtonsEntry(this.getRowWidth(), btn1, btn2, firstButtonRatio)); } - public void addField(String label, EditBox box) { this.addEntry(new FieldEntry(this.getRowWidth(), label, box)); } public void addTwoFields(String label, EditBox box1, EditBox box2) { this.addEntry(new TwoFieldsEntry(this.getRowWidth(), label, box1, box2)); } - public abstract static class Entry extends ContainerObjectSelectionList.Entry { } public static class HeaderEntry extends Entry { @@ -57,10 +49,9 @@ public HeaderEntry(String text) { } @Override - public void render(GuiGraphics gg, int index, int top, int left, int width, int height, - int mouseX, int mouseY, boolean isHovered, float partialTick) { + public void renderContent(GuiGraphics gg, int mouseX, int mouseY, boolean isHovered, float partialTick) { Font font = Minecraft.getInstance().font; - gg.drawCenteredString(font, this.text, left + width / 2, top + (height - 9) / 2, COLOR_HEADER); + gg.drawCenteredString(font, this.text, this.getContentXMiddle(), this.getContentYMiddle() - 4, COLOR_HEADER); } @Override @@ -72,16 +63,16 @@ public void render(GuiGraphics gg, int index, int top, int left, int width, int public static class ButtonEntry extends Entry { private final Button button; - public ButtonEntry(Button button) { + public ButtonEntry(int listWidth, Button button) { this.button = button; + this.button.setWidth(listWidth - SCROLLBAR_WIDTH_GAP); + this.button.setHeight(WIDGET_HEIGHT); } @Override - public void render(GuiGraphics gg, int index, int top, int left, int width, int height, - int mouseX, int mouseY, boolean isHovered, float partialTick) { - button.setWidth(width - SCROLLBAR_WIDTH_GAP); - button.setX(left + (SCROLLBAR_WIDTH_GAP / 2)); - button.setY(top); + public void renderContent(@NonNull GuiGraphics gg, int mouseX, int mouseY, boolean isHovered, float partialTick) { + button.setX(this.getContentX() + SCROLLBAR_WIDTH_GAP / 2); + button.setY(this.getContentY()); button.render(gg, mouseX, mouseY, partialTick); } @@ -112,13 +103,12 @@ public TwoButtonsEntry(int listWidth, Button button1, Button button2, float rati } @Override - public void render(GuiGraphics gg, int index, int top, int left, int width, int height, - int mouseX, int mouseY, boolean isHovered, float partialTick) { - button1.setX(left + (SCROLLBAR_WIDTH_GAP / 2)); - button1.setY(top); + public void renderContent(@NonNull GuiGraphics gg, int mouseX, int mouseY, boolean isHovered, float partialTick) { + button1.setX(this.getContentX() + SCROLLBAR_WIDTH_GAP / 2); + button1.setY(this.getContentY()); button2.setX(button1.getX() + button1.getWidth() + ELEMENT_SPACING); - button2.setY(top); + button2.setY(this.getContentY()); button1.render(gg, mouseX, mouseY, partialTick); button2.render(gg, mouseX, mouseY, partialTick); @@ -151,15 +141,13 @@ public FieldEntry(int listWidth, String labelText, EditBox field) { } @Override - public void render(GuiGraphics gg, int index, int top, int left, int width, int height, - int mouseX, int mouseY, boolean isHovered, float partialTick) { - label.setX(left + (SCROLLBAR_WIDTH_GAP / 2)); - label.setY(top); + public void renderContent(@NonNull GuiGraphics gg, int mouseX, int mouseY, boolean isHovered, float partialTick) { + label.setX(this.getContentX() + SCROLLBAR_WIDTH_GAP / 2); + label.setY(this.getContentY()); field.setX(label.getX() + label.getWidth() + ELEMENT_SPACING); - field.setY(top); + field.setY(this.getContentY()); label.render(gg, mouseX, mouseY, partialTick); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); field.render(gg, mouseX, mouseY, partialTick); } @@ -197,19 +185,17 @@ public TwoFieldsEntry(int listWidth, String labelText, EditBox field1, EditBox f } @Override - public void render(GuiGraphics gg, int index, int top, int left, int width, int height, - int mouseX, int mouseY, boolean isHovered, float partialTick) { - label.setX(left + (SCROLLBAR_WIDTH_GAP / 2)); - label.setY(top); + public void renderContent(@NonNull GuiGraphics gg, int mouseX, int mouseY, boolean isHovered, float partialTick) { + label.setX(this.getContentX() + SCROLLBAR_WIDTH_GAP / 2); + label.setY(this.getContentY()); field1.setX(label.getX() + label.getWidth() + ELEMENT_SPACING); - field1.setY(top); + field1.setY(this.getContentY()); field2.setX(field1.getX() + field1.getWidth() + ELEMENT_SPACING); - field2.setY(top); + field2.setY(this.getContentY()); label.render(gg, mouseX, mouseY, partialTick); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); field1.render(gg, mouseX, mouseY, partialTick); field2.render(gg, mouseX, mouseY, partialTick); } diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/EaseGUIAbstractSplitScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/EaseGUIAbstractSplitScreen.java index 0cc43bb..464b457 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/EaseGUIAbstractSplitScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/EaseGUIAbstractSplitScreen.java @@ -1,10 +1,12 @@ package net.weyne1.easegui.client.gui.screens; +import net.minecraft.ChatFormatting; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.StringWidget; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import org.jspecify.annotations.NonNull; public abstract class EaseGUIAbstractSplitScreen extends Screen { protected final Screen parent; @@ -13,7 +15,6 @@ public abstract class EaseGUIAbstractSplitScreen extends Screen { protected int listHeight; protected int leftX; protected int rightX; - protected int stringColor; private static final int LINE_COLOR = 0x33FFFFFF; @@ -32,34 +33,35 @@ protected void init() { this.leftX = 0; this.rightX = halfWidth; - this.stringColor = 0xAAAAAA; - initScreen(); // Главный заголовок экрана (в самом верху по центру) - StringWidget titleWidget = new StringWidget(this.title, this.font); + Component titleColored = this.title.copy().withStyle(ChatFormatting.WHITE); + StringWidget titleWidget = new StringWidget(titleColored, this.font); + titleWidget.setX(this.halfWidth - titleWidget.getWidth() / 2); titleWidget.setY(15); - titleWidget.setColor(0xFFFFFF); this.addRenderableWidget(titleWidget); // Левый подзаголовок Component leftSub = getLeftSubtitle(); if (leftSub != null) { - StringWidget leftSubWidget = new StringWidget(leftSub, this.font); + Component leftSubColored = leftSub.copy().withStyle(ChatFormatting.GRAY); + StringWidget leftSubWidget = new StringWidget(leftSubColored, this.font); + leftSubWidget.setX((this.halfWidth / 2) - (leftSubWidget.getWidth() / 2)); leftSubWidget.setY(35); - leftSubWidget.setColor(this.stringColor); this.addRenderableWidget(leftSubWidget); } // Правый подзаголовок Component rightSub = getRightSubtitle(); if (rightSub != null) { - StringWidget rightSubWidget = new StringWidget(rightSub, this.font); + Component rightSubColored = rightSub.copy().withStyle(ChatFormatting.GRAY); + StringWidget rightSubWidget = new StringWidget(rightSubColored, this.font); + rightSubWidget.setX((this.halfWidth + (this.halfWidth / 2)) - (rightSubWidget.getWidth() / 2)); rightSubWidget.setY(35); - rightSubWidget.setColor(this.stringColor); this.addRenderableWidget(rightSubWidget); } } @@ -73,7 +75,7 @@ protected void init() { protected void renderOverlay(GuiGraphics gg, int mouseX, int mouseY, float partialTick) {} @Override - public void render(GuiGraphics gg, int mouseX, int mouseY, float partialTick) { + public void render(@NonNull GuiGraphics gg, int mouseX, int mouseY, float partialTick) { super.render(gg, mouseX, mouseY, partialTick); // Вертикальный разделитель по центру экрана diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java index 7ae6bf3..4002df0 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java @@ -145,7 +145,6 @@ private void addGlobalProfileButton(SettingsScrollList list, EaseGUIConfig confi } private EditBox createTextField(String value) { - assert this.minecraft != null; EditBox editBox = new EditBox(this.minecraft.font, 0, 0, 60, 16, Component.empty()); editBox.setValue(value); return editBox; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java index a4129ac..d9c3a41 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java @@ -56,9 +56,7 @@ protected void initScreen() { Component.translatable("easegui.generic.reset"), button -> { applyProfileValues(this.workingCopy, this.defaultProfile); - if (this.minecraft != null) { - this.init(this.minecraft, this.width, this.height); - } + this.init(this.width, this.height); } ).build(); @@ -146,7 +144,6 @@ protected void initScreen() { } private EditBox createTextField(String value) { - assert this.minecraft != null; EditBox editBox = new EditBox(this.minecraft.font, 0, 0, 60, 16, Component.empty()); editBox.setValue(value); return editBox; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java index 49b8be5..778aa81 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java @@ -63,11 +63,12 @@ protected void initScreen() { this.addRenderableWidget(warningWidget); } else { - StringWidget noOptionsWidget = new StringWidget(Component.translatable("easegui.gui.no_unique_options"), this.font); + Component noOptionsText = Component.translatable("easegui.gui.no_unique_options") + .withStyle(style -> style.withColor(0x55FFFFFF)); + StringWidget noOptionsWidget = new StringWidget(noOptionsText, this.font); int leftBlockCenterX = leftX + (listWidth / 2); noOptionsWidget.setX(leftBlockCenterX - (noOptionsWidget.getWidth() / 2)); noOptionsWidget.setY(this.height / 2 - 4); - noOptionsWidget.setColor(0x55FFFFFF); this.addRenderableWidget(noOptionsWidget); } } From 2b6af36e825bccfdc6c8cabcbf9c63b48205662a Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 15:44:35 +0300 Subject: [PATCH 05/43] ref: recipe book --- .../client/accessor/RecipeBookAccessor.java | 8 ------ .../accessor/RecipeBookComponentAccessor.java | 7 +++++ .../accessor/RecipeBookScreenAccessor.java | 7 +++++ .../client/animator/ContainerAnimator.java | 21 +++++++-------- .../container/AbstractRecipeBookScreen.java | 19 +++++++++++++ .../container/RecipeBookComponentMixin.java | 27 +++++++------------ common/src/main/resources/easegui.mixins.json | 1 + 7 files changed, 53 insertions(+), 37 deletions(-) delete mode 100644 common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookAccessor.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookAccessor.java b/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookAccessor.java deleted file mode 100644 index 36939bd..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookAccessor.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.weyne1.easegui.client.accessor; - -public interface RecipeBookAccessor { - boolean easeGUI$isVisible(); - int easeGUI$getXOffset(); - int easeGUI$getBookWidth(); - int easeGUI$getBookHeight(); -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java b/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java new file mode 100644 index 0000000..9fb362b --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java @@ -0,0 +1,7 @@ +package net.weyne1.easegui.client.accessor; + +public interface RecipeBookComponentAccessor { + boolean easeGUI$isVisible(); + int easeGUI$getXOrigin(); + int easeGUI$getYOrigin(); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java b/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java new file mode 100644 index 0000000..5aa2f85 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java @@ -0,0 +1,7 @@ +package net.weyne1.easegui.client.accessor; + +import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; + +public interface RecipeBookScreenAccessor { + RecipeBookComponent easeGUI$getRecipeBookComponent(); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index b435511..c832cd5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -4,9 +4,9 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.minecraft.client.gui.screens.recipebook.RecipeUpdateListener; import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; -import net.weyne1.easegui.client.accessor.RecipeBookAccessor; +import net.weyne1.easegui.client.accessor.RecipeBookComponentAccessor; +import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationScope; @@ -32,17 +32,16 @@ public static AnimationScope beginScreenAnimation(Screen screen, GuiGraphics gg) int maxX = minX + container.easeGUI$getImageWidth(); int maxY = minY + container.easeGUI$getImageHeight(); - if (screen instanceof RecipeUpdateListener listener) { - RecipeBookComponent book = listener.getRecipeBookComponent(); + if (screen instanceof RecipeBookScreenAccessor recipeScreen) { + RecipeBookComponent book = recipeScreen.easeGUI$getRecipeBookComponent(); + if (book != null && ((RecipeBookComponentAccessor) book).easeGUI$isVisible()) { + RecipeBookComponentAccessor accessor = (RecipeBookComponentAccessor) book; - if (((RecipeBookAccessor) book).easeGUI$isVisible()) { - RecipeBookAccessor accessor = (RecipeBookAccessor) book; + int bookX = accessor.easeGUI$getXOrigin(); + int bookY = accessor.easeGUI$getYOrigin(); - int bookWidth = accessor.easeGUI$getBookWidth(); - int bookHeight = accessor.easeGUI$getBookHeight(); - - int bookX = (screen.width - bookWidth) / 2 - accessor.easeGUI$getXOffset(); - int bookY = (screen.height - bookHeight) / 2; + int bookWidth = RecipeBookComponent.IMAGE_WIDTH; + int bookHeight = RecipeBookComponent.IMAGE_HEIGHT; minX = Math.min(minX, bookX); minY = Math.min(minY, bookY); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java new file mode 100644 index 0000000..9315bb8 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java @@ -0,0 +1,19 @@ +package net.weyne1.easegui.client.mixin.gui.container; + +import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; +import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(AbstractRecipeBookScreen.class) +public abstract class AbstractRecipeBookScreen implements RecipeBookScreenAccessor { + + @Final + @Shadow private RecipeBookComponent recipeBookComponent; + + @Override + public RecipeBookComponent easeGUI$getRecipeBookComponent() { + return this.recipeBookComponent; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java index 66fe930..cb909e8 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java @@ -1,29 +1,20 @@ package net.weyne1.easegui.client.mixin.gui.container; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.weyne1.easegui.client.accessor.RecipeBookAccessor; +import net.weyne1.easegui.client.accessor.RecipeBookComponentAccessor; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(RecipeBookComponent.class) -public abstract class RecipeBookComponentMixin implements RecipeBookAccessor { - @Shadow private boolean visible; - @Shadow private int xOffset; +public interface RecipeBookComponentMixin extends RecipeBookComponentAccessor { - @Accessor("IMAGE_WIDTH") - public static int easeGUI$getVanillaWidth() { - throw new AssertionError(); - } + @Accessor("visible") + boolean easeGUI$isVisible(); - @Accessor("IMAGE_HEIGHT") - public static int easeGUI$getVanillaHeight() { - throw new AssertionError(); - } + @Invoker("getXOrigin") + int easeGUI$getXOrigin(); - @Override public boolean easeGUI$isVisible() { return this.visible; } - @Override public int easeGUI$getXOffset() { return this.xOffset; } - - @Override public int easeGUI$getBookWidth() { return easeGUI$getVanillaWidth(); } - @Override public int easeGUI$getBookHeight() { return easeGUI$getVanillaHeight(); } + @Invoker("getYOrigin") + int easeGUI$getYOrigin(); } \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index c0c4949..24ed914 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -17,6 +17,7 @@ "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", "gui.container.RecipeBookComponentMixin", + "gui.container.AbstractRecipeBookScreen", "gui.title.LogoRendererMixin", "gui.title.SplashRendererMixin", "gui.title.TitleScreenMixin" From 708e794430451bcedc88bc445ae511a367291700 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 16:33:43 +0300 Subject: [PATCH 06/43] ref: Screen mixins --- .../client/mixin/gui/ScreenLifecycleMixin.java | 7 +++---- .../easegui/client/mixin/gui/ScreenMixin.java | 18 ++++++++---------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenLifecycleMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenLifecycleMixin.java index d86f766..59b7dbf 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenLifecycleMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenLifecycleMixin.java @@ -1,6 +1,5 @@ package net.weyne1.easegui.client.mixin.gui; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.weyne1.easegui.client.state.ScreenStateTracker; import org.spongepowered.asm.mixin.Mixin; @@ -9,10 +8,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(Screen.class) - public class ScreenLifecycleMixin { - @Inject(method = "init(Lnet/minecraft/client/Minecraft;II)V", at = @At("HEAD")) - private void easeGUI$onScreenInit(Minecraft minecraft, int width, int height, CallbackInfo ci) { + + @Inject(method = "added()V", at = @At("HEAD")) + private void easeGUI$onScreenAdded(CallbackInfo ci) { Screen currentScreen = (Screen) (Object) this; if (ScreenStateTracker.checkAndTrackNewScreen(currentScreen)) { ScreenStateTracker.markScreenOpened(); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java index d287e0a..093994c 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java @@ -10,8 +10,7 @@ import net.weyne1.easegui.client.animator.BackgroundAnimator; import net.weyne1.easegui.client.animator.ContainerAnimator; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIConfig; -import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -30,8 +29,8 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { @Unique private AnimationScope easeGUI$containerScreenScope = null; @Unique private AnimationScope easeGUI$menuBackgroundScope = null; - @Shadow @Nullable protected Minecraft minecraft; - @Shadow protected abstract void renderBlurredBackground(float partialTick); + @Final @Shadow protected Minecraft minecraft; + @Shadow protected abstract void renderBlurredBackground(GuiGraphics guiGraphics); @Override @Unique @@ -50,8 +49,8 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { * Initializes the container animation scope at the absolute beginning of the screen * rendering pipeline, ensuring both widgets and late-rendered tooltips are captured. */ - @Inject(method = "renderWithTooltip", at = @At("HEAD")) - private void easeGUI$beforeScreenRenderWithTooltip(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { + @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("HEAD")) + private void easeGUI$beforeScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (RenderSystem.isOnRenderThread() && this instanceof ContainerScreenAccessor) { if (this.easeGUI$containerScreenScope != null) { ContainerAnimator.closeScope(this.easeGUI$containerScreenScope); @@ -65,8 +64,8 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { * Safely collapses and closes the container animation scope at the end of the rendering * pipeline to prevent matrix stack underflows. */ - @Inject(method = "renderWithTooltip", at = @At("RETURN")) - private void easeGUI$afterScreenRenderWithTooltip(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { + @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("RETURN")) + private void easeGUI$afterScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (RenderSystem.isOnRenderThread() && this.easeGUI$containerScreenScope != null) { ContainerAnimator.closeScope(this.easeGUI$containerScreenScope); this.easeGUI$containerScreenScope = null; @@ -88,8 +87,7 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { boolean blurContainers = ConfigManager.getConfig().global.blurContainers; if (this.minecraft != null && this.minecraft.level != null && blurContainers) { - float partialTick = this.minecraft.getTimer().getGameTimeDeltaTicks(); - this.renderBlurredBackground(partialTick); + this.renderBlurredBackground(guiGraphics); } } From 02db85d9137a5b7b2d4f630bc861df2435618fb4 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 16:41:55 +0300 Subject: [PATCH 07/43] ref: adapt blur animation to new shader system --- .../client/mixin/GameRendererMixin.java | 19 ------------- .../easegui/client/mixin/OptionsMixin.java | 28 +++++++++++++++++++ common/src/main/resources/easegui.mixins.json | 3 +- 3 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/OptionsMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/GameRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/GameRendererMixin.java index bee4a7d..672f0d5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/GameRendererMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/GameRendererMixin.java @@ -3,34 +3,15 @@ import net.minecraft.client.DeltaTracker; import net.minecraft.client.renderer.GameRenderer; import net.weyne1.easegui.client.animation.AnimationContext; -import net.weyne1.easegui.client.animator.BackgroundAnimator; -import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.state.ScreenAnimationTracker; import net.weyne1.easegui.client.state.ScreenStateTracker; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GameRenderer.class) public class GameRendererMixin { - @ModifyArg( - method = "processBlurEffect", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;setUniform(Ljava/lang/String;F)V"), - index = 1 - ) - private float easeGUI$animateBlurRadiusArg(float originalRadius) { - boolean enableSmoothBlur = ConfigManager.getConfig().global.enableSmoothBlur; - - if (!enableSmoothBlur || BackgroundAnimator.skipBackgroundFade) { - return originalRadius; - } - - return originalRadius * ScreenAnimationTracker.getProgress(); - } - @Inject(method = "render", at = @At("HEAD")) private void easeGUI$onFrameStart(DeltaTracker deltaTracker, boolean renderLevel, CallbackInfo ci) { ScreenStateTracker.incrementFrame(); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/OptionsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/OptionsMixin.java new file mode 100644 index 0000000..0dd3c6e --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/OptionsMixin.java @@ -0,0 +1,28 @@ +package net.weyne1.easegui.client.mixin; + +import net.minecraft.client.Options; +import net.weyne1.easegui.client.animator.BackgroundAnimator; +import net.weyne1.easegui.client.config.ConfigManager; +import net.weyne1.easegui.client.state.ScreenAnimationTracker; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Options.class) +public class OptionsMixin { + + @Inject(method = "getMenuBackgroundBlurriness", at = @At("RETURN"), cancellable = true) + private void easeGUI$animateMenuBlurriness(CallbackInfoReturnable cir) { + boolean enableSmoothBlur = ConfigManager.getConfig().global.enableSmoothBlur; + + if (!enableSmoothBlur || BackgroundAnimator.skipBackgroundFade) { + return; + } + + int originalValue = cir.getReturnValue(); + int animatedValue = Math.round(originalValue * ScreenAnimationTracker.getProgress()); + + cir.setReturnValue(animatedValue); + } +} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 24ed914..97fa0cc 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -13,11 +13,12 @@ "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", "gui.GuiGraphicsMixin", + "OptionsMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", - "gui.container.RecipeBookComponentMixin", "gui.container.AbstractRecipeBookScreen", + "gui.container.RecipeBookComponentMixin", "gui.title.LogoRendererMixin", "gui.title.SplashRendererMixin", "gui.title.TitleScreenMixin" From ec9bb83d18bf63e304b162866bc4c0d42cdfd1dd Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 16:49:18 +0300 Subject: [PATCH 08/43] ref: AdvancementsScreenMixin --- .../client/mixin/gui/AdvancementsScreenMixin.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java index 3020069..5197355 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java @@ -23,7 +23,7 @@ public class AdvancementsScreenMixin { // === АНИМАЦИЯ ГЛАВНОГО ОКНА === @Inject( method = "render", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementsScreen;renderInside(Lnet/minecraft/client/gui/GuiGraphics;IIII)V") + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementsScreen;renderInside(Lnet/minecraft/client/gui/GuiGraphics;II)V") ) private void easeGUI$preRenderWindow(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (this.easeGUI$windowScope != null) { @@ -44,19 +44,19 @@ public class AdvancementsScreenMixin { // === АНИМАЦИЯ ВКЛАДОК (ФОН) === @WrapOperation( method = "renderWindow", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementTab;drawTab(Lnet/minecraft/client/gui/GuiGraphics;IIZ)V") + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementTab;drawTab(Lnet/minecraft/client/gui/GuiGraphics;IIIIZ)V") ) - private void easeGUI$wrapDrawTab(AdvancementTab tab, GuiGraphics guiGraphics, int offsetX, int offsetY, boolean isSelected, Operation original) { + private void easeGUI$wrapDrawTab(AdvancementTab tab, GuiGraphics guiGraphics, int x, int y, int mouseX, int mouseY, boolean selected, Operation original) { AdvancementsScreen screen = (AdvancementsScreen) (Object) this; int index = ((AdvancementTabAccessor) tab).easeGUI$getIndex(); AnimationScope scope = AdvancementsAnimator.beginRenderTab(screen, guiGraphics, index); if (scope != null) { try (scope) { - original.call(tab, guiGraphics, offsetX, offsetY, isSelected); + original.call(tab, guiGraphics, x, y, mouseX, mouseY, selected); } } else { - original.call(tab, guiGraphics, offsetX, offsetY, isSelected); + original.call(tab, guiGraphics, x, y, mouseX, mouseY, selected); } } From 94c14eae9038e6bcf06095c8afa6b6c5fd2d2cb4 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 16:59:12 +0300 Subject: [PATCH 09/43] ref: AbstractSelectionListMixin --- .../mixin/gui/AbstractSelectionListMixin.java | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java index b54c174..dbbe0d7 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java @@ -1,40 +1,48 @@ package net.weyne1.easegui.client.mixin.gui; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractSelectionList; +import net.minecraft.client.gui.layouts.LayoutElement; import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.ListItemAnimator; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.Coerce; @Mixin(AbstractSelectionList.class) -public class AbstractSelectionListMixin { - - @Unique - private AnimationScope easeGUI$itemScope = null; - - @Inject(method = "renderItem", at = @At("HEAD")) - private void easeGUI$onPreRenderItem(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, - int index, int left, int top, int width, int height, CallbackInfo ci) { +public abstract class AbstractSelectionListMixin { + + @Shadow public abstract int getRowLeft(); + @Shadow public abstract int getRowWidth(); + + @WrapOperation( + method = "renderListItems", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/AbstractSelectionList;renderItem(Lnet/minecraft/client/gui/GuiGraphics;IIFLnet/minecraft/client/gui/components/AbstractSelectionList$Entry;)V" + ) + ) + private void easeGUI$wrapRenderItem(AbstractSelectionList instance, GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, @Coerce Object item, Operation original) { AnimationContext.pushParentAnimation(); - if (this.easeGUI$itemScope != null) { - this.easeGUI$itemScope.close(); - } + LayoutElement element = (LayoutElement) item; + int left = this.getRowLeft(); + int width = this.getRowWidth(); + int top = element.getY(); + int height = element.getHeight(); - this.easeGUI$itemScope = ListItemAnimator.beginRender(guiGraphics, top, left, width, height); - } + AnimationScope scope = ListItemAnimator.beginRender(guiGraphics, top, left, width, height); - @Inject(method = "renderItem", at = @At("RETURN")) - private void easeGUI$onPostRenderItem(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, - int index, int left, int top, int width, int height, CallbackInfo ci) { - if (this.easeGUI$itemScope != null) { - this.easeGUI$itemScope.close(); - this.easeGUI$itemScope = null; + if (scope != null) { + try (scope) { + original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); + } + } else { + original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); } AnimationContext.popParentAnimation(); From cf103685d2c7c961397466a9af0381a3394f581c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 17:09:13 +0300 Subject: [PATCH 10/43] ref: TitleScreenMixin --- .../mixin/gui/title/TitleScreenMixin.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java index 07bffe9..83568ca 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java @@ -1,28 +1,34 @@ package net.weyne1.easegui.client.mixin.gui.title; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.client.gui.screens.TitleScreen; import net.weyne1.easegui.client.config.ConfigManager; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(TitleScreen.class) public class TitleScreenMixin { /** - * Cancels the vanilla TitleScreen setWidgetAlpha animation if EaseGUI is enabled for this screen. + * Cancels the vanilla TitleScreen fadeWidgets animation if EaseGUI is enabled for this screen. * This allows EaseGUI to fully control widget fade-in animation, * while preserving vanilla transitions if the screen animation is disabled. */ - @Inject(method = "setWidgetAlpha", at = @At("HEAD"), cancellable = true) - private void easeGUI$cancelFade(float alpha, CallbackInfo ci) { + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/screens/TitleScreen;fadeWidgets(F)V" + ) + ) + private void easeGUI$conditionallyFadeWidgets(TitleScreen instance, float v, Operation original) { var titleSettings = ConfigManager.getConfig().screens.get("title"); - if (titleSettings == null || !titleSettings.enabled) { + if (titleSettings != null && titleSettings.enabled) { return; } - ci.cancel(); + original.call(instance, v); } } \ No newline at end of file From 2e4cdfa1b36a5994c65628e220ac6b1fdb02084c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 17:20:59 +0300 Subject: [PATCH 11/43] ref: move splash interception logic to TitleScreenMixin --- .../accessor/SplashRendererAccessor.java | 13 +++++++ .../mixin/gui/title/SplashRendererMixin.java | 31 ----------------- .../mixin/gui/title/TitleScreenMixin.java | 34 +++++++++++++++++++ common/src/main/resources/easegui.mixins.json | 4 +-- 4 files changed, 49 insertions(+), 33 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java delete mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java b/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java new file mode 100644 index 0000000..e359edb --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java @@ -0,0 +1,13 @@ +package net.weyne1.easegui.client.mixin.accessor; + +import net.minecraft.client.gui.components.SplashRenderer; +import net.minecraft.network.chat.Component; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(SplashRenderer.class) +public interface SplashRendererAccessor { + + @Accessor("splash") + Component easeGUI$getSplash(); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java deleted file mode 100644 index 935cc09..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.weyne1.easegui.client.mixin.gui.title; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.SplashRenderer; -import net.weyne1.easegui.client.animation.AnimationScope; -import net.weyne1.easegui.client.animator.SplashAnimator; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(SplashRenderer.class) -public class SplashRendererMixin { - - @WrapOperation( - method = "render", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;drawCenteredString(Lnet/minecraft/client/gui/Font;Ljava/lang/String;III)V") - ) - private void easeGUI$wrapSplash(GuiGraphics gg, Font font, String text, int x, int y, int color, Operation original) { - AnimationScope scope = SplashAnimator.beginRender(gg, color); - - if (scope != null) { - try (scope) { - original.call(gg, font, text, x, y, color); - } - } else { - original.call(gg, font, text, x, y, color); - } - } -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java index 83568ca..6198f45 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java @@ -2,8 +2,16 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.SplashRenderer; import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.network.chat.Style; +import net.minecraft.network.chat.TextColor; +import net.weyne1.easegui.client.animation.AnimationScope; +import net.weyne1.easegui.client.animator.SplashAnimator; import net.weyne1.easegui.client.config.ConfigManager; +import net.weyne1.easegui.client.mixin.accessor.SplashRendererAccessor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -31,4 +39,30 @@ public class TitleScreenMixin { original.call(instance, v); } + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/SplashRenderer;render(Lnet/minecraft/client/gui/GuiGraphics;ILnet/minecraft/client/gui/Font;F)V" + ) + ) + private void easeGUI$wrapSplashRender(SplashRenderer splashRenderer, GuiGraphics guiGraphics, int width, Font font, float fade, Operation original) { + var component = ((SplashRendererAccessor) splashRenderer).easeGUI$getSplash(); + + int color = 0xFFFF55; + if (component != null && component.getStyle().getColor() != null) { + color = component.getStyle().getColor().getValue(); + } + + AnimationScope scope = SplashAnimator.beginRender(guiGraphics, color); + + if (scope != null) { + try (scope) { + original.call(splashRenderer, guiGraphics, width, font, fade); + } + } else { + original.call(splashRenderer, guiGraphics, width, font, fade); + } + } } \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 97fa0cc..cdbbdd6 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -6,21 +6,21 @@ "client": [ "GameRendererMixin", "MinecraftMixin", + "OptionsMixin", "accessor.AdvancementTabAccessor", "accessor.LogoRendererAccessor", + "accessor.SplashRendererAccessor", "blaze3d.VertexBufferMixin", "gui.AbstractSelectionListMixin", "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", "gui.GuiGraphicsMixin", - "OptionsMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", "gui.container.AbstractRecipeBookScreen", "gui.container.RecipeBookComponentMixin", "gui.title.LogoRendererMixin", - "gui.title.SplashRendererMixin", "gui.title.TitleScreenMixin" ], "injectors": { From a14471a07bf79b3482a95e2c7063a22e1a6989fd Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 17:25:06 +0300 Subject: [PATCH 12/43] chore: add @Dynamic to EmiCompatMixin --- .../net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java index 36e3039..b0c9ed5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java @@ -4,6 +4,7 @@ import net.minecraft.client.gui.screens.Screen; import net.weyne1.easegui.client.accessor.ScreenAnimationAccessor; import net.weyne1.easegui.client.animation.AnimationScope; +import org.spongepowered.asm.mixin.Dynamic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.Unique; @@ -28,6 +29,7 @@ public class EmiCompatMixin { return null; } + @Dynamic @Inject(method = {"render", "drawBackground", "drawForeground"}, at = @At("HEAD"), require = 0) private static void easeGUI$onEmiRenderStart(CallbackInfo ci) { AnimationScope scope = easeGUI$getCurrentScope(); @@ -36,6 +38,7 @@ public class EmiCompatMixin { } } + @Dynamic @Inject(method = {"render", "drawBackground", "drawForeground"}, at = @At("TAIL"), require = 0) private static void easeGUI$onEmiRenderEnd(CallbackInfo ci) { AnimationScope scope = easeGUI$getCurrentScope(); From 0017750e2eb58f7aa55e17bc861a2c31839b2b3c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sun, 5 Jul 2026 21:40:50 +0300 Subject: [PATCH 13/43] ref: remove redundant GuiGraphicsMixin --- .../client/mixin/gui/GuiGraphicsMixin.java | 53 ------------------- common/src/main/resources/easegui.mixins.json | 1 - 2 files changed, 54 deletions(-) delete mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java deleted file mode 100644 index e579264..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.weyne1.easegui.client.mixin.gui; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.gui.GuiGraphics; -import net.weyne1.easegui.client.animation.AnimationContext; -import org.joml.Matrix4f; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - -@Mixin(GuiGraphics.class) -public abstract class GuiGraphicsMixin { - - @Shadow public abstract PoseStack pose(); - - @ModifyArgs( - method = "enableScissor", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/navigation/ScreenRectangle;(IIII)V") - ) - private void easeGUI$transformScissorBounds(Args args) { - if (!AnimationContext.isAnimating()) { - return; - } - - int minX = args.get(0); - int minY = args.get(1); - int width = args.get(2); - int height = args.get(3); - int maxX = minX + width; - int maxY = minY + height; - - Matrix4f matrix = this.pose().last().pose(); - float sx = matrix.m00(); - float sy = matrix.m11(); - float tx = matrix.m30(); - float ty = matrix.m31(); - - int newMinX = Math.round(minX * sx + tx); - int newMinY = Math.round(minY * sy + ty); - int newMaxX = Math.round(maxX * sx + tx); - int newMaxY = Math.round(maxY * sy + ty); - - int newWidth = newMaxX - newMinX; - int newHeight = newMaxY - newMinY; - - args.set(0, newMinX); - args.set(1, newMinY); - args.set(2, Math.max(0, newWidth)); - args.set(3, Math.max(0, newHeight)); - } -} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index cdbbdd6..fe77f10 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -14,7 +14,6 @@ "gui.AbstractSelectionListMixin", "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", - "gui.GuiGraphicsMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", From 33b66603f89e30806efe1aab64184f10369e2325 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 6 Jul 2026 20:20:08 +0300 Subject: [PATCH 14/43] feat: remove redundant VertexBufferMixin --- .../mixin/blaze3d/VertexBufferMixin.java | 61 ------------------- common/src/main/resources/easegui.mixins.json | 1 - 2 files changed, 62 deletions(-) delete mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/blaze3d/VertexBufferMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/blaze3d/VertexBufferMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/blaze3d/VertexBufferMixin.java deleted file mode 100644 index b415748..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/blaze3d/VertexBufferMixin.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.weyne1.easegui.client.mixin.blaze3d; - -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.VertexBuffer; -import net.minecraft.client.renderer.ShaderInstance; -import net.weyne1.easegui.client.animation.AnimationContext; -import org.joml.Matrix4f; -import org.lwjgl.opengl.GL11; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(VertexBuffer.class) -public class VertexBufferMixin { - @Unique private float easeGUI$savedR; - @Unique private float easeGUI$savedG; - @Unique private float easeGUI$savedB; - @Unique private float easeGUI$savedA; - @Unique private boolean easeGUI$hasSavedColor = false; - @Unique private boolean easeGUI$wasBlendEnabled; - - @Inject(method = "_drawWithShader", at = @At("HEAD")) - private void easeGUI$injectAlphaBeforeShader(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, ShaderInstance shader, CallbackInfo ci) { - if (AnimationContext.isAnimating()) { - float[] currentColor = RenderSystem.getShaderColor(); - - this.easeGUI$savedR = currentColor[0]; - this.easeGUI$savedG = currentColor[1]; - this.easeGUI$savedB = currentColor[2]; - this.easeGUI$savedA = currentColor[3]; - this.easeGUI$hasSavedColor = true; - - this.easeGUI$wasBlendEnabled = GL11.glIsEnabled(GL11.GL_BLEND); - - float animationAlpha = AnimationContext.getCurrentAlpha(); - float finalAlpha = this.easeGUI$savedA * animationAlpha; - - if (!this.easeGUI$wasBlendEnabled && finalAlpha < 1.0f) { - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - } - - RenderSystem.setShaderColor(this.easeGUI$savedR, this.easeGUI$savedG, this.easeGUI$savedB, finalAlpha); - } - } - - @Inject(method = "_drawWithShader", at = @At("TAIL")) - private void easeGUI$restoreAlphaAfterShader(Matrix4f modelViewMatrix, Matrix4f projectionMatrix, ShaderInstance shader, CallbackInfo ci) { - if (this.easeGUI$hasSavedColor) { - RenderSystem.setShaderColor(this.easeGUI$savedR, this.easeGUI$savedG, this.easeGUI$savedB, this.easeGUI$savedA); - - if (!this.easeGUI$wasBlendEnabled) { - RenderSystem.disableBlend(); - } - - this.easeGUI$hasSavedColor = false; - } - } -} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index fe77f10..311dcf5 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -10,7 +10,6 @@ "accessor.AdvancementTabAccessor", "accessor.LogoRendererAccessor", "accessor.SplashRendererAccessor", - "blaze3d.VertexBufferMixin", "gui.AbstractSelectionListMixin", "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", From a4f40028aedabff02c526abdfa4dd86ddbb3dd8b Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 6 Jul 2026 20:33:43 +0300 Subject: [PATCH 15/43] fix: AbstractRecipeBookScreenMixin naming --- ...ecipeBookScreen.java => AbstractRecipeBookScreenMixin.java} | 3 ++- common/src/main/resources/easegui.mixins.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/{AbstractRecipeBookScreen.java => AbstractRecipeBookScreenMixin.java} (77%) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java similarity index 77% rename from common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java rename to common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java index 9315bb8..846478a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java @@ -1,5 +1,6 @@ package net.weyne1.easegui.client.mixin.gui.container; +import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; import org.spongepowered.asm.mixin.Final; @@ -7,7 +8,7 @@ import org.spongepowered.asm.mixin.Shadow; @Mixin(AbstractRecipeBookScreen.class) -public abstract class AbstractRecipeBookScreen implements RecipeBookScreenAccessor { +public abstract class AbstractRecipeBookScreenMixin implements RecipeBookScreenAccessor { @Final @Shadow private RecipeBookComponent recipeBookComponent; diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 311dcf5..517d801 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -16,7 +16,7 @@ "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", - "gui.container.AbstractRecipeBookScreen", + "gui.container.AbstractRecipeBookScreenMixin", "gui.container.RecipeBookComponentMixin", "gui.title.LogoRendererMixin", "gui.title.TitleScreenMixin" From 5b0f100f9535ca7bd3476d275b20f623eb703205 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 6 Jul 2026 21:30:11 +0300 Subject: [PATCH 16/43] feat: add GuiGraphicsMixin to control GUI alpha --- .../client/mixin/gui/GuiGraphicsMixin.java | 51 +++++++++++++++++++ common/src/main/resources/easegui.mixins.json | 1 + 2 files changed, 52 insertions(+) create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java new file mode 100644 index 0000000..7944c41 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java @@ -0,0 +1,51 @@ +package net.weyne1.easegui.client.mixin.gui; + +import net.minecraft.client.gui.GuiGraphics; +import net.weyne1.easegui.client.animation.AnimationContext; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@SuppressWarnings("ModifyVariableMayUseName") +@Mixin(GuiGraphics.class) +public class GuiGraphicsMixin { + + @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 4) + private int easeGUI$modifyColorFrom(int colorFrom) { + if (!AnimationContext.isAnimating()) return colorFrom; + return easegui$getNewColor(colorFrom); + } + + @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 0) + private Integer easeGUI$modifyColorTo(Integer colorTo) { + if (!AnimationContext.isAnimating() || colorTo == null) return colorTo; + return easegui$getNewColor(colorTo); + } + + @ModifyVariable(method = "submitBlit", at = @At("HEAD"), argsOnly = true, ordinal = 4) + private int easeGUI$modifyBlitColor(int color) { + if (!AnimationContext.isAnimating()) return color; + return easegui$getNewColor(color); + } + + @ModifyVariable(method = "submitTiledBlit", at = @At("HEAD"), argsOnly = true, ordinal = 6) + private int easeGUI$modifyTiledBlitColor(int color) { + if (!AnimationContext.isAnimating()) return color; + return easegui$getNewColor(color); + } + + @Unique + private static int easegui$getNewColor(int originalColor) { + int originalAlpha = (originalColor >> 24) & 0xFF; + + if (originalAlpha == 0 && (originalColor & 0x00FFFFFF) != 0) { + originalAlpha = 255; + } + + float animationAlpha = AnimationContext.getCurrentAlpha(); + int finalAlpha = Math.round(originalAlpha * animationAlpha); + + return (originalColor & 0x00FFFFFF) | (finalAlpha << 24); + } +} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 517d801..0c33cae 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -13,6 +13,7 @@ "gui.AbstractSelectionListMixin", "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", + "gui.GuiGraphicsMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", From f9c18f058d6fcd55d0cf018239ab7c0b3f7c5803 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 7 Jul 2026 02:39:35 +0300 Subject: [PATCH 17/43] feat: add GuiTextRenderStateMixin to control text alpha --- .../mixin/gui/GuiTextRenderStateMixin.java | 30 +++++++++++++++++++ common/src/main/resources/easegui.mixins.json | 1 + 2 files changed, 31 insertions(+) create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java new file mode 100644 index 0000000..d7c9c87 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java @@ -0,0 +1,30 @@ +package net.weyne1.easegui.client.mixin.gui; + +import net.minecraft.client.gui.render.state.GuiTextRenderState; +import net.weyne1.easegui.client.animation.AnimationContext; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@SuppressWarnings("ModifyVariableMayUseName") +@Mixin(GuiTextRenderState.class) +public class GuiTextRenderStateMixin { + + @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true, ordinal = 2) + private static int easeGUI$modifyTextStateColor(int color) { + if (!AnimationContext.isAnimating()) { + return color; + } + + int originalAlpha = (color >> 24) & 0xFF; + + if (originalAlpha == 0 && (color & 0x00FFFFFF) != 0) { + originalAlpha = 255; + } + + float animationAlpha = AnimationContext.getCurrentAlpha(); + int finalAlpha = Math.round(originalAlpha * animationAlpha); + + return (color & 0x00FFFFFF) | (finalAlpha << 24); + } +} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 0c33cae..737e23c 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -14,6 +14,7 @@ "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", "gui.GuiGraphicsMixin", + "gui.GuiTextRenderStateMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", "gui.container.AbstractContainerScreenMixin", From c5c93caf5fc3b5420a53cd7930b9831694aa2347 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 7 Jul 2026 02:42:32 +0300 Subject: [PATCH 18/43] ref: add ColorUtils --- .../configurator/TitleScreenConfigurator.java | 2 +- .../gui/screens/ProfileEditorScreen.java | 2 +- .../client/mixin/gui/GuiGraphicsMixin.java | 24 ++++--------------- .../mixin/gui/GuiTextRenderStateMixin.java | 16 ++----------- .../easegui/client/util/ColorUtils.java | 21 ++++++++++++++++ .../client/{ => util}/StringUtils.java | 2 +- 6 files changed, 31 insertions(+), 36 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/util/ColorUtils.java rename common/src/main/java/net/weyne1/easegui/client/{ => util}/StringUtils.java (94%) diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java index 433304b..89c4cd3 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.StringUtils; +import net.weyne1.easegui.client.util.StringUtils; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.config.EaseGUIConfig; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java index d9c3a41..5c3f71a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.StringUtils; +import net.weyne1.easegui.client.util.StringUtils; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.ProfileFeature; import net.weyne1.easegui.client.gui.FieldValidator; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java index 7944c41..9813f61 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java @@ -2,8 +2,8 @@ import net.minecraft.client.gui.GuiGraphics; import net.weyne1.easegui.client.animation.AnimationContext; +import net.weyne1.easegui.client.util.ColorUtils; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; @@ -14,38 +14,24 @@ public class GuiGraphicsMixin { @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 4) private int easeGUI$modifyColorFrom(int colorFrom) { if (!AnimationContext.isAnimating()) return colorFrom; - return easegui$getNewColor(colorFrom); + return ColorUtils.getAnimatedColor(colorFrom); } @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 0) private Integer easeGUI$modifyColorTo(Integer colorTo) { if (!AnimationContext.isAnimating() || colorTo == null) return colorTo; - return easegui$getNewColor(colorTo); + return ColorUtils.getAnimatedColor(colorTo); } @ModifyVariable(method = "submitBlit", at = @At("HEAD"), argsOnly = true, ordinal = 4) private int easeGUI$modifyBlitColor(int color) { if (!AnimationContext.isAnimating()) return color; - return easegui$getNewColor(color); + return ColorUtils.getAnimatedColor(color); } @ModifyVariable(method = "submitTiledBlit", at = @At("HEAD"), argsOnly = true, ordinal = 6) private int easeGUI$modifyTiledBlitColor(int color) { if (!AnimationContext.isAnimating()) return color; - return easegui$getNewColor(color); - } - - @Unique - private static int easegui$getNewColor(int originalColor) { - int originalAlpha = (originalColor >> 24) & 0xFF; - - if (originalAlpha == 0 && (originalColor & 0x00FFFFFF) != 0) { - originalAlpha = 255; - } - - float animationAlpha = AnimationContext.getCurrentAlpha(); - int finalAlpha = Math.round(originalAlpha * animationAlpha); - - return (originalColor & 0x00FFFFFF) | (finalAlpha << 24); + return ColorUtils.getAnimatedColor(color); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java index d7c9c87..9fc1b73 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java @@ -12,19 +12,7 @@ public class GuiTextRenderStateMixin { @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true, ordinal = 2) private static int easeGUI$modifyTextStateColor(int color) { - if (!AnimationContext.isAnimating()) { - return color; - } - - int originalAlpha = (color >> 24) & 0xFF; - - if (originalAlpha == 0 && (color & 0x00FFFFFF) != 0) { - originalAlpha = 255; - } - - float animationAlpha = AnimationContext.getCurrentAlpha(); - int finalAlpha = Math.round(originalAlpha * animationAlpha); - - return (color & 0x00FFFFFF) | (finalAlpha << 24); + if (!AnimationContext.isAnimating()) return color; + return net.weyne1.easegui.client.util.ColorUtils.getAnimatedColor(color); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/util/ColorUtils.java b/common/src/main/java/net/weyne1/easegui/client/util/ColorUtils.java new file mode 100644 index 0000000..7ebd546 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/util/ColorUtils.java @@ -0,0 +1,21 @@ +package net.weyne1.easegui.client.util; + +import net.weyne1.easegui.client.animation.AnimationContext; + +public final class ColorUtils { + + private ColorUtils() {} + + public static int getAnimatedColor(int originalColor) { + int originalAlpha = (originalColor >> 24) & 0xFF; + + if (originalAlpha == 0 && (originalColor & 0x00FFFFFF) != 0) { + originalAlpha = 255; + } + + float animationAlpha = AnimationContext.getCurrentAlpha(); + int finalAlpha = Math.round(originalAlpha * animationAlpha); + + return (originalColor & 0x00FFFFFF) | (finalAlpha << 24); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/StringUtils.java b/common/src/main/java/net/weyne1/easegui/client/util/StringUtils.java similarity index 94% rename from common/src/main/java/net/weyne1/easegui/client/StringUtils.java rename to common/src/main/java/net/weyne1/easegui/client/util/StringUtils.java index 56d4c2b..70c46ef 100644 --- a/common/src/main/java/net/weyne1/easegui/client/StringUtils.java +++ b/common/src/main/java/net/weyne1/easegui/client/util/StringUtils.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client; +package net.weyne1.easegui.client.util; public class StringUtils { public static String toTitleCase(Enum e) { From b70779efb1c977b3d6edbba2f09013f41e22cf00 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 7 Jul 2026 02:52:14 +0300 Subject: [PATCH 19/43] fix: disable the default logo fade-in effect --- .../mixin/gui/title/TitleScreenMixin.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java index 6198f45..3913151 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java @@ -4,10 +4,9 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.LogoRenderer; import net.minecraft.client.gui.components.SplashRenderer; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.network.chat.Style; -import net.minecraft.network.chat.TextColor; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.SplashAnimator; import net.weyne1.easegui.client.config.ConfigManager; @@ -40,6 +39,24 @@ public class TitleScreenMixin { original.call(instance, v); } + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/components/LogoRenderer;renderLogo(Lnet/minecraft/client/gui/GuiGraphics;IF)V" + ) + ) + private void easeGUI$conditionallyFadeLogo(LogoRenderer instance, GuiGraphics guiGraphics, int screenWidth, float transparency, Operation original) { + var titleSettings = ConfigManager.getConfig().screens.get("title"); + + if (titleSettings != null && titleSettings.enabled) { + original.call(instance, guiGraphics, screenWidth, 1.0F); + return; + } + + original.call(instance, guiGraphics, screenWidth, transparency); + } + @WrapOperation( method = "render", at = @At( From 753d741424214d6b01d9677736f33638cd972c2c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 14:56:16 +0300 Subject: [PATCH 20/43] fix: correct splash animation --- .../client/animator/SplashAnimator.java | 58 ++++++++++++------- .../mixin/gui/title/SplashRendererMixin.java | 34 +++++++++++ .../mixin/gui/title/TitleScreenMixin.java | 31 ---------- common/src/main/resources/easegui.mixins.json | 1 + 4 files changed, 72 insertions(+), 52 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java index 9419516..9a0f719 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java @@ -1,44 +1,60 @@ package net.weyne1.easegui.client.animator; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import net.minecraft.client.gui.ActiveTextCollector; +import net.minecraft.client.gui.TextAlignment; +import net.minecraft.network.chat.Component; import net.minecraft.util.Util; -import net.minecraft.client.gui.GuiGraphics; import net.weyne1.easegui.client.animation.AnimationMath; -import net.weyne1.easegui.client.animation.AnimationScope; -import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.state.ScreenStateTracker; -/** - * Animates the title screen splash text. - */ public class SplashAnimator { - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ - public static AnimationScope beginRender(GuiGraphics gg, int color) { + private static long lastTrackedSessionTime = -1L; + private static long actualStartTime = -1L; + + public static void animate( + ActiveTextCollector collector, + TextAlignment textAlignment, + int x, + int y, + ActiveTextCollector.Parameters parameters, + Component text, + Operation original + ) { + trackSessionTime(); + var screenConfig = ConfigManager.getConfig().screens.get("title"); + if (screenConfig == null || !screenConfig.enabled || screenConfig.splash == null || !screenConfig.splash.enabled) { - return null; + original.call(collector, textAlignment, x, y, parameters, text); + return; } var splashConfig = screenConfig.splash; - long startTime = ScreenStateTracker.getScreenOpenTime(); - long elapsed = Util.getMillis() - startTime - splashConfig.splashDelay; + long elapsed = Util.getMillis() - actualStartTime - splashConfig.splashDelay; + + if (elapsed <= 0) { + return; + } if (elapsed >= splashConfig.splashDuration) { - return null; + original.call(collector, textAlignment, x, y, parameters.withOpacity(1.0f), text); + return; } float progress = AnimationMath.calculateProgress(elapsed, splashConfig.splashDuration, splashConfig.splashEasing); - float baseAlpha = ((color >> 24) & 255) / 255.0f; - float finalAlpha = baseAlpha * progress; - AnimationScope scope = AnimationSystem.beginAlphaOnly(gg, finalAlpha); + ActiveTextCollector.Parameters animatedParams = parameters.withOpacity(AnimationMath.clamp(progress, 0f, 1f)).withScale(progress); - gg.pose().scale(progress, progress); + original.call(collector, textAlignment, x, y, animatedParams, text); + } - return scope; + private static void trackSessionTime() { + long currentSessionTime = ScreenStateTracker.getScreenOpenTime(); + if (lastTrackedSessionTime != currentSessionTime) { + lastTrackedSessionTime = currentSessionTime; + actualStartTime = Util.getMillis(); + } } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java new file mode 100644 index 0000000..f4615f5 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java @@ -0,0 +1,34 @@ +package net.weyne1.easegui.client.mixin.gui.title; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.client.gui.ActiveTextCollector; +import net.minecraft.client.gui.TextAlignment; +import net.minecraft.client.gui.components.SplashRenderer; +import net.minecraft.network.chat.Component; +import net.weyne1.easegui.client.animator.SplashAnimator; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(SplashRenderer.class) +public class SplashRendererMixin { + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/ActiveTextCollector;accept(Lnet/minecraft/client/gui/TextAlignment;IILnet/minecraft/client/gui/ActiveTextCollector$Parameters;Lnet/minecraft/network/chat/Component;)V" + ) + ) + private void easeGUI$animateSplash( + ActiveTextCollector collector, + TextAlignment textAlignment, + int x, + int y, + ActiveTextCollector.Parameters parameters, + Component text, + Operation original + ) { + SplashAnimator.animate(collector, textAlignment, x, y, parameters, text, original); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java index 3913151..0e88ea2 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/TitleScreenMixin.java @@ -2,15 +2,10 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.LogoRenderer; -import net.minecraft.client.gui.components.SplashRenderer; import net.minecraft.client.gui.screens.TitleScreen; -import net.weyne1.easegui.client.animation.AnimationScope; -import net.weyne1.easegui.client.animator.SplashAnimator; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.mixin.accessor.SplashRendererAccessor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -56,30 +51,4 @@ public class TitleScreenMixin { original.call(instance, guiGraphics, screenWidth, transparency); } - - @WrapOperation( - method = "render", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/components/SplashRenderer;render(Lnet/minecraft/client/gui/GuiGraphics;ILnet/minecraft/client/gui/Font;F)V" - ) - ) - private void easeGUI$wrapSplashRender(SplashRenderer splashRenderer, GuiGraphics guiGraphics, int width, Font font, float fade, Operation original) { - var component = ((SplashRendererAccessor) splashRenderer).easeGUI$getSplash(); - - int color = 0xFFFF55; - if (component != null && component.getStyle().getColor() != null) { - color = component.getStyle().getColor().getValue(); - } - - AnimationScope scope = SplashAnimator.beginRender(guiGraphics, color); - - if (scope != null) { - try (scope) { - original.call(splashRenderer, guiGraphics, width, font, fade); - } - } else { - original.call(splashRenderer, guiGraphics, width, font, fade); - } - } } \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 737e23c..3962648 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -21,6 +21,7 @@ "gui.container.AbstractRecipeBookScreenMixin", "gui.container.RecipeBookComponentMixin", "gui.title.LogoRendererMixin", + "gui.title.SplashRendererMixin", "gui.title.TitleScreenMixin" ], "injectors": { From be43362dbb414a07761c0fe2da46bb2826e576e4 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 15:12:21 +0300 Subject: [PATCH 21/43] ref: ScreenMixin lifecycle --- .../client/animator/BackgroundAnimator.java | 32 ++---- .../client/animator/ContainerAnimator.java | 58 ++--------- .../easegui/client/mixin/MinecraftMixin.java | 4 +- .../easegui/client/mixin/gui/ScreenMixin.java | 99 ++++++------------- 4 files changed, 48 insertions(+), 145 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java index 9ff5828..3d472be 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java @@ -1,6 +1,5 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.*; import net.weyne1.easegui.client.animation.AnimationScope; @@ -12,9 +11,6 @@ import net.weyne1.easegui.client.state.ScreenAnimationTracker; import net.weyne1.easegui.client.state.ScreenStateTracker; -/** - * Handles background fade animations. - */ public class BackgroundAnimator { public static boolean skipBackgroundFade = false; @@ -26,10 +22,8 @@ public static boolean isLoadingScreen(Screen screen) { || screen instanceof BackupConfirmScreen; } - public static boolean isScreenBlurred(Screen screen) { - if (screen == null - || screen instanceof TitleScreen - || isLoadingScreen(screen)) { + public static boolean shouldAnimateBackground(Screen screen) { + if (screen == null || screen instanceof TitleScreen || isLoadingScreen(screen)) { return false; } @@ -47,15 +41,8 @@ public static boolean isScreenBlurred(Screen screen) { } } - public static boolean shouldAnimate() { - return isScreenBlurred(Minecraft.getInstance().screen); - } - - /** - * Returns whether background animations are enabled. - */ - public static int getAnimatedColor(int originalColor) { - if (!shouldAnimate() || skipBackgroundFade) { + public static int getAnimatedColor(Screen screen, int originalColor) { + if (!shouldAnimateBackground(screen) || skipBackgroundFade) { return originalColor; } @@ -72,13 +59,10 @@ public static int getAnimatedColor(int originalColor) { return (originalColor & 0x00FFFFFF) | (finalAlpha << 24); } - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ - public static AnimationScope beginRenderMenu(GuiGraphics gg) { - if (!shouldAnimate() || skipBackgroundFade) return null; + public static AnimationScope beginRenderMenu(Screen screen, GuiGraphics gg) { + if (isLoadingScreen(screen) || !shouldAnimateBackground(screen) || skipBackgroundFade) { + return null; + } long elapsed = ScreenStateTracker.getScreenElapsed(); long duration = ConfigManager.getConfig().global.blurDuration; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index c832cd5..522751a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -7,7 +7,6 @@ import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; import net.weyne1.easegui.client.accessor.RecipeBookComponentAccessor; import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; -import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; @@ -17,12 +16,11 @@ public class ContainerAnimator { /** - * Evaluates container bounds (integrating the Recipe Book if open) and instantiates - * a localized context-aware AnimationScope. + * Starts the animation. * - * @return a new {@link AnimationScope} mapped to the screen matrix, or {@code null} if transitions are disabled + * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed */ - public static AnimationScope beginScreenAnimation(Screen screen, GuiGraphics gg) { + public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { if (!(screen instanceof ContainerScreenAccessor container)) { return null; } @@ -36,62 +34,22 @@ public static AnimationScope beginScreenAnimation(Screen screen, GuiGraphics gg) RecipeBookComponent book = recipeScreen.easeGUI$getRecipeBookComponent(); if (book != null && ((RecipeBookComponentAccessor) book).easeGUI$isVisible()) { RecipeBookComponentAccessor accessor = (RecipeBookComponentAccessor) book; - - int bookX = accessor.easeGUI$getXOrigin(); - int bookY = accessor.easeGUI$getYOrigin(); - - int bookWidth = RecipeBookComponent.IMAGE_WIDTH; - int bookHeight = RecipeBookComponent.IMAGE_HEIGHT; - - minX = Math.min(minX, bookX); - minY = Math.min(minY, bookY); - maxX = Math.max(maxX, bookX + bookWidth); - maxY = Math.max(maxY, bookY + bookHeight); + minX = Math.min(minX, accessor.easeGUI$getXOrigin()); + minY = Math.min(minY, accessor.easeGUI$getYOrigin()); + maxX = Math.max(maxX, accessor.easeGUI$getXOrigin() + RecipeBookComponent.IMAGE_WIDTH); + maxY = Math.max(maxY, accessor.easeGUI$getYOrigin() + RecipeBookComponent.IMAGE_HEIGHT); } } - AnimationScope scope = beginAnimation(gg, minX, minY, maxX - minX, maxY - minY); - if (scope != null) { - AnimationContext.pushParentAnimation(); - } - return scope; - } - - /** - * Safely closes the provided animation scope and cleanly balances the global animation context depth. - * - * @param scope Target scope to dissolve - */ - public static void closeScope(AnimationScope scope) { - if (scope != null) { - try { - if (!scope.isClosed()) { - scope.close(); - } - } finally { - if (AnimationContext.hasParentAnimation()) { - AnimationContext.popParentAnimation(); - } - } - } - } - - /** - * Looks up user configurations and computes tween progress mapping to generate the core AnimationScope. - * - * @return an active {@link AnimationScope} or {@code null} if config conditions are unmet or duration expired - */ - public static AnimationScope beginAnimation(GuiGraphics gg, int x, int y, int width, int height) { var profile = ConfigManager.getProfileForCurrentContext(UIElementCategory.CONTAINERS); if (profile == null || !profile.enabled) return null; long startTime = ScreenStateTracker.getScreenOpenTime(); long elapsed = Util.getMillis() - startTime; - if (elapsed >= profile.duration) return null; float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); - return AnimationSystem.begin(gg, x, y, width, height, profile, progress, 1.0f); + return AnimationSystem.begin(gg, minX, minY, maxX - minX, maxY - minY, profile, progress, 1.0f); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java index 75b5968..0926c98 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java @@ -23,8 +23,8 @@ public class MinecraftMixin { return; } - boolean wasBlurred = BackgroundAnimator.isScreenBlurred(oldScreen); - boolean willBeBlurred = BackgroundAnimator.isScreenBlurred(guiScreen); + boolean wasBlurred = BackgroundAnimator.shouldAnimateBackground(oldScreen); + boolean willBeBlurred = BackgroundAnimator.shouldAnimateBackground(guiScreen); BackgroundAnimator.skipBackgroundFade = wasBlurred && willBeBlurred; } diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java index 093994c..54ffa54 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java @@ -6,6 +6,7 @@ import net.minecraft.client.gui.screens.Screen; import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; import net.weyne1.easegui.client.accessor.ScreenAnimationAccessor; +import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.BackgroundAnimator; import net.weyne1.easegui.client.animator.ContainerAnimator; @@ -16,13 +17,10 @@ import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.ModifyArgs; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; -/** - * Injects custom animation behavior into the global Screen rendering pipeline. - * Manages container transition lifecycles, menu textures, and background dimming. - */ @Mixin(Screen.class) public abstract class ScreenMixin implements ScreenAnimationAccessor { @@ -38,63 +36,50 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { return this.easeGUI$containerScreenScope; } - @Unique - private boolean easeGUI$isWorldLoadingScreen() { - return BackgroundAnimator.isLoadingScreen((Screen) (Object) this); - } + // Container lifecycle - // CONTAINER SCREEN ANIMATION LIFECYCLE - - /** - * Initializes the container animation scope at the absolute beginning of the screen - * rendering pipeline, ensuring both widgets and late-rendered tooltips are captured. - */ @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("HEAD")) private void easeGUI$beforeScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (RenderSystem.isOnRenderThread() && this instanceof ContainerScreenAccessor) { if (this.easeGUI$containerScreenScope != null) { - ContainerAnimator.closeScope(this.easeGUI$containerScreenScope); + this.easeGUI$containerScreenScope.close(); + this.easeGUI$containerScreenScope = null; } + this.easeGUI$containerScreenScope = ContainerAnimator.beginAnimation((Screen) (Object) this, guiGraphics); - this.easeGUI$containerScreenScope = ContainerAnimator.beginScreenAnimation((Screen) (Object) this, guiGraphics); + if (this.easeGUI$containerScreenScope != null) { + AnimationContext.pushParentAnimation(); + } } } - /** - * Safely collapses and closes the container animation scope at the end of the rendering - * pipeline to prevent matrix stack underflows. - */ @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("RETURN")) private void easeGUI$afterScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (RenderSystem.isOnRenderThread() && this.easeGUI$containerScreenScope != null) { - ContainerAnimator.closeScope(this.easeGUI$containerScreenScope); + this.easeGUI$containerScreenScope.close(); this.easeGUI$containerScreenScope = null; + + if (AnimationContext.hasParentAnimation()) { + AnimationContext.popParentAnimation(); + } } } - // BACKGROUND RENDERING ISOLATION (SUSPEND / RESUME) + // Transparent background (blur / dim) - /** - * Suspends active container scaling/translation right before the transparent background - * gradient is drawn, keeping the background tint absolute and static. - */ @Inject(method = "renderTransparentBackground", at = @At("HEAD")) private void easeGUI$suspendBeforeTransparentBackground(GuiGraphics guiGraphics, CallbackInfo ci) { if (this.easeGUI$containerScreenScope != null) { this.easeGUI$containerScreenScope.suspend(); } + Screen currentScreen = (Screen) (Object) this; boolean blurContainers = ConfigManager.getConfig().global.blurContainers; - - if (this.minecraft != null && this.minecraft.level != null && blurContainers) { + if (this.minecraft != null && this.minecraft.level != null && blurContainers && BackgroundAnimator.shouldAnimateBackground(currentScreen)) { this.renderBlurredBackground(guiGraphics); } } - /** - * Resumes the container animation transformations immediately after the transparent - * background gradient has finished rendering. - */ @Inject(method = "renderTransparentBackground", at = @At("RETURN")) private void easeGUI$resumeAfterTransparentBackground(GuiGraphics guiGraphics, CallbackInfo ci) { if (this.easeGUI$containerScreenScope != null) { @@ -102,10 +87,8 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { } } - /** - * Isolates the main menu background rendering from container transformations and - * handles standalone main-menu background animations. - */ + // Menu background + @Inject(method = "renderMenuBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", at = @At("HEAD")) private void easeGUI$preRenderMenuBackground(GuiGraphics guiGraphics, CallbackInfo ci) { if (this.easeGUI$containerScreenScope != null) { @@ -116,15 +99,9 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { this.easeGUI$menuBackgroundScope.close(); } - if (!easeGUI$isWorldLoadingScreen() && BackgroundAnimator.shouldAnimate()) { - this.easeGUI$menuBackgroundScope = BackgroundAnimator.beginRenderMenu(guiGraphics); - } + this.easeGUI$menuBackgroundScope = BackgroundAnimator.beginRenderMenu((Screen) (Object) this, guiGraphics); } - /** - * Cleans up menu background scope and restores the container animation transforms - * for subsequent interface elements. - */ @Inject(method = "renderMenuBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", at = @At("RETURN")) private void easeGUI$postRenderMenuBackground(GuiGraphics guiGraphics, CallbackInfo ci) { if (this.easeGUI$menuBackgroundScope != null) { @@ -137,35 +114,19 @@ public abstract class ScreenMixin implements ScreenAnimationAccessor { } } - // BACKGROUND GRADIENT COLOR MODIFICATIONS + // Gradient color - /** - * Applies animated alpha to the top color of the Screen background gradient. - */ - @ModifyArg( + @ModifyArgs( method = "renderTransparentBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;fillGradient(IIIIII)V"), - index = 4 + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;fillGradient(IIIIII)V") ) - private int easeGUI$modifyTransparentBgTopColor(int originalColor) { - if (easeGUI$isWorldLoadingScreen()) { - return originalColor; + private void easeGUI$modifyTransparentBgColors(Args args) { + Screen currentScreen = (Screen) (Object) this; + if (BackgroundAnimator.isLoadingScreen(currentScreen)) { + return; } - return BackgroundAnimator.getAnimatedColor(originalColor); - } - /** - * Applies animated alpha to the bottom color of the Screen background gradient. - */ - @ModifyArg( - method = "renderTransparentBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiGraphics;fillGradient(IIIIII)V"), - index = 5 - ) - private int easeGUI$modifyTransparentBgBottomColor(int originalColor) { - if (easeGUI$isWorldLoadingScreen()) { - return originalColor; - } - return BackgroundAnimator.getAnimatedColor(originalColor); + args.set(4, BackgroundAnimator.getAnimatedColor(currentScreen, args.get(4))); + args.set(5, BackgroundAnimator.getAnimatedColor(currentScreen, args.get(5))); } } \ No newline at end of file From f8c08496d10b07513c13e961163d8a1f3afcce07 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 16:44:28 +0300 Subject: [PATCH 22/43] fix(AbstractSelectionListMixin): safe push/pop for parent animation --- .../client/mixin/gui/AbstractSelectionListMixin.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java index dbbe0d7..e5616a6 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java @@ -39,12 +39,17 @@ public abstract class AbstractSelectionListMixin { if (scope != null) { try (scope) { - original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); + AnimationContext.pushParentAnimation(); + try { + original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); + } finally { + if (AnimationContext.hasParentAnimation()) { + AnimationContext.popParentAnimation(); + } + } } } else { original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); } - - AnimationContext.popParentAnimation(); } } \ No newline at end of file From 82888fd4464a86d1c87a9c220188de0997554748 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 16:49:44 +0300 Subject: [PATCH 23/43] ref: improve text widget category detection --- .../weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index 9cbc43d..51f11de 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -41,7 +41,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { else if (AbstractSelectionList.class.isAssignableFrom(clazz)) { this.easeGUI$cachedCategory = UIElementCategory.SCROLLABLE; } - else if (StringWidget.class.isAssignableFrom(clazz) || MultiLineTextWidget.class.isAssignableFrom(clazz)) { + else if (AbstractStringWidget.class.isAssignableFrom(clazz)) { this.easeGUI$cachedCategory = UIElementCategory.TEXT; } else { From 9027e68d364d2dd86d6e6542a29e945b5eb943b9 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 17:11:51 +0300 Subject: [PATCH 24/43] ref: delegate widget category resolution to UIElementCategory --- .../client/config/UIElementCategory.java | 20 +++++++++++++++++++ .../client/mixin/gui/AbstractWidgetMixin.java | 14 +------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java b/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java index 996dc55..cf00245 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java @@ -1,5 +1,9 @@ package net.weyne1.easegui.client.config; +import net.minecraft.client.gui.components.*; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import org.jetbrains.annotations.NotNull; + import java.util.EnumSet; public enum UIElementCategory { @@ -19,4 +23,20 @@ public enum UIElementCategory { public EnumSet getAllowedFeatures() { return EnumSet.copyOf(this.allowedFeatures); } + + @NotNull public static UIElementCategory fromClass(Class clazz) { + if (AbstractButton.class.isAssignableFrom(clazz) || AbstractSliderButton.class.isAssignableFrom(clazz) || EditBox.class.isAssignableFrom(clazz)) { + return BUTTON_LIKE; + } + if (AbstractStringWidget.class.isAssignableFrom(clazz)) { + return TEXT; + } + if (AbstractSelectionList.class.isAssignableFrom(clazz)) { + return SCROLLABLE; + } + if (AbstractContainerScreen.class.isAssignableFrom(clazz)) { + return CONTAINERS; + } + return UNKNOWN; + } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index 51f11de..0d1badd 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -34,19 +34,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { @Override public UIElementCategory easeGUI$getCategory() { if (this.easeGUI$cachedCategory == null) { - Class clazz = this.getClass(); - if (AbstractButton.class.isAssignableFrom(clazz) || AbstractSliderButton.class.isAssignableFrom(clazz) || EditBox.class.isAssignableFrom(clazz)) { - this.easeGUI$cachedCategory = UIElementCategory.BUTTON_LIKE; - } - else if (AbstractSelectionList.class.isAssignableFrom(clazz)) { - this.easeGUI$cachedCategory = UIElementCategory.SCROLLABLE; - } - else if (AbstractStringWidget.class.isAssignableFrom(clazz)) { - this.easeGUI$cachedCategory = UIElementCategory.TEXT; - } - else { - this.easeGUI$cachedCategory = UIElementCategory.UNKNOWN; - } + this.easeGUI$cachedCategory = UIElementCategory.fromClass(this.getClass()); } return this.easeGUI$cachedCategory; } From 9ca3766a55617539b9af84fc3679f2133302e809 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Wed, 8 Jul 2026 17:37:39 +0300 Subject: [PATCH 25/43] ref: extract AnimationState into a top-level class --- .../easegui/client/animation/AnimationState.java | 13 +++++-------- .../easegui/client/animator/WidgetAnimator.java | 8 ++++---- .../client/mixin/gui/AbstractWidgetMixin.java | 8 ++++---- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationState.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationState.java index 378b817..4be2f5a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationState.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationState.java @@ -1,11 +1,8 @@ package net.weyne1.easegui.client.animation; -public class AnimationState { - - public static final class AnimationData { - public long startTime = -1; - public long delay = 0; - public boolean init = false; - public int lastRenderFrame = -1; - } +public final class AnimationState { + public long startTime = -1; + public long delay = 0; + public boolean init = false; + public int lastRenderFrame = -1; } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index 3a2b3df..37da95d 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -21,7 +21,7 @@ public class WidgetAnimator { * * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed */ - public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, UIElementCategory category, AnimationState.AnimationData state) { + public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, UIElementCategory category, AnimationState state) { if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { return null; } @@ -63,7 +63,7 @@ public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, * Initializes animation state when a widget appears and * recalculates cascade timing if needed. */ - private static void updateAnimationState(AbstractWidget widget, AnimationState.AnimationData state, long now, AnimationProfile profile) { + private static void updateAnimationState(AbstractWidget widget, AnimationState state, long now, AnimationProfile profile) { int currentFrame = ScreenStateTracker.getCurrentFrameId(); if (state.init && currentFrame > state.lastRenderFrame + 1) { @@ -84,8 +84,8 @@ private static void updateAnimationState(AbstractWidget widget, AnimationState.A } /** - * Вычисляет расстояние до виджета в виртуальной шкале координат, - * делая скорость каскада независимой от GUI Scale и разрешения монитора. + * Calculates the distance to the widget in a virtual coordinate scale, + * making the cascade speed independent of the GUI scale and monitor resolution. */ private static float getDistance(AbstractWidget widget, AnimationProfile profile) { var window = Minecraft.getInstance().getWindow(); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index 0d1badd..dca3fa0 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -22,7 +22,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { @Shadow protected float alpha; @Shadow protected boolean isHovered; - @Unique private final AnimationState.AnimationData easeGUI$animationData = new AnimationState.AnimationData(); + @Unique private final AnimationState easeGUI$animationState = new AnimationState(); @Unique private UIElementCategory easeGUI$cachedCategory = null; @Unique private AnimationScope easeGUI$widgetScope = null; @@ -55,11 +55,11 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { var category = this.easeGUI$getCategory(); if (category == null || category == UIElementCategory.UNKNOWN) return; - this.easeGUI$widgetScope = WidgetAnimator.beginRender(widget, guiGraphics, category, this.easeGUI$animationData); + this.easeGUI$widgetScope = WidgetAnimator.beginRender(widget, guiGraphics, category, this.easeGUI$animationState); var profile = ConfigManager.getProfileForCurrentContext(category); - if (profile != null && profile.enabled && this.easeGUI$animationData.init) { - long elapsed = Util.getMillis() - this.easeGUI$animationData.startTime - this.easeGUI$animationData.delay; + if (profile != null && profile.enabled && this.easeGUI$animationState.init) { + long elapsed = Util.getMillis() - this.easeGUI$animationState.startTime - this.easeGUI$animationState.delay; if (elapsed < profile.duration) { this.isHovered = false; } From 57a313b18ed11e0f00fdf36ace0f5f51aae5ca3e Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 21:25:44 +0300 Subject: [PATCH 26/43] ref(anim): migrate AnimationContext to object scope tracking --- .../client/animation/AnimationContext.java | 54 ++++++++++++------- .../client/animation/AnimationScope.java | 18 +++++-- .../client/mixin/gui/GuiGraphicsMixin.java | 8 +-- .../mixin/gui/GuiTextRenderStateMixin.java | 2 +- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationContext.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationContext.java index a3809f8..1018ce1 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationContext.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationContext.java @@ -6,39 +6,54 @@ import java.util.Deque; public final class AnimationContext { - private static final Deque ALPHA_STACK = new ArrayDeque<>(); - private static int suspensionDepth = 0; + private static final Deque SCOPE_STACK = new ArrayDeque<>(); private static int parentAnimationDepth = 0; - public static void pushAnimation(float alpha) { - ALPHA_STACK.push(alpha); + public static void pushScope(AnimationScope scope) { + SCOPE_STACK.push(scope); } - public static void popAnimation() { - if (!ALPHA_STACK.isEmpty()) { - ALPHA_STACK.pop(); + public static void popScope(AnimationScope scope) { + if (SCOPE_STACK.isEmpty()) { + EaseGUIDebug.reportError("scope_underflow", () -> "Attempt to close a scope when the stack is empty!"); + return; } - } - public static void suspend() { - suspensionDepth++; + if (SCOPE_STACK.peek() == scope) { + SCOPE_STACK.pop(); + } else { + EaseGUIDebug.reportError("scope_mismatch", () -> "Animation closing order violated! Attempted to close the wrong scope."); + } } - public static void resume() { - if (suspensionDepth > 0) { - suspensionDepth--; - } + public static AnimationScope getCurrentScope() { + return SCOPE_STACK.peek(); } - public static boolean isAnimating() { - return suspensionDepth == 0 && !ALPHA_STACK.isEmpty(); + public static boolean isActive() { + if (SCOPE_STACK.isEmpty()) return false; + for (AnimationScope scope : SCOPE_STACK) { + if (!scope.isSuspended()) return true; + } + return false; } public static float getCurrentAlpha() { - if (suspensionDepth > 0 || ALPHA_STACK.isEmpty()) { + if (SCOPE_STACK.isEmpty()) { return 1.0f; } - return ALPHA_STACK.peek(); + + float totalAlpha = 1.0f; + boolean hasActiveScope = false; + + for (AnimationScope scope : SCOPE_STACK) { + if (!scope.isSuspended()) { + totalAlpha *= scope.getAlpha(); + hasActiveScope = true; + } + } + + return hasActiveScope ? totalAlpha : 1.0f; } public static void pushParentAnimation() { @@ -59,8 +74,7 @@ public static boolean hasParentAnimation() { } public static void resetFrameState() { - ALPHA_STACK.clear(); - suspensionDepth = 0; + SCOPE_STACK.clear(); parentAnimationDepth = 0; } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java index 78d1158..6595bc5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java @@ -8,6 +8,7 @@ public final class AnimationScope implements AutoCloseable { private static final float MIN_SCALE = 0.001f; private final GuiGraphics guiGraphics; + private final float alpha; private boolean isClosed = false; private boolean isSuspended = false; @@ -18,7 +19,9 @@ public final class AnimationScope implements AutoCloseable { public AnimationScope(GuiGraphics guiGraphics, float alpha) { this.guiGraphics = guiGraphics; - AnimationContext.pushAnimation(alpha); + this.alpha = alpha; + + AnimationContext.pushScope(this); this.guiGraphics.pose().pushMatrix(); } @@ -44,7 +47,6 @@ public void setTransformParams(float offsetX, float offsetY, float scaleX, float public void suspend() { if (isClosed || isSuspended) return; - AnimationContext.suspend(); Matrix3x2fStack poseStack = guiGraphics.pose(); poseStack.pushMatrix(); @@ -63,7 +65,6 @@ public void resume() { if (isClosed || !isSuspended) return; guiGraphics.pose().popMatrix(); - AnimationContext.resume(); isSuspended = false; } @@ -75,7 +76,6 @@ public void close() { if (isSuspended) { guiGraphics.pose().popMatrix(); - AnimationContext.resume(); isSuspended = false; } @@ -85,13 +85,21 @@ public void close() { EaseGUIDebug.reportError("pose_stack_underflow", () -> "PoseStack underflow inside AnimationScope close!"); } - AnimationContext.popAnimation(); + AnimationContext.popScope(this); } public boolean isClosed() { return isClosed; } + public boolean isSuspended() { + return isSuspended; + } + + public float getAlpha() { + return alpha; + } + private static float clampScale(float scale) { if (Math.abs(scale) < MIN_SCALE) { return Math.copySign(MIN_SCALE, scale == 0.0f ? 1.0f : scale); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java index 9813f61..f8d016f 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java @@ -13,25 +13,25 @@ public class GuiGraphicsMixin { @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 4) private int easeGUI$modifyColorFrom(int colorFrom) { - if (!AnimationContext.isAnimating()) return colorFrom; + if (!AnimationContext.isActive()) return colorFrom; return ColorUtils.getAnimatedColor(colorFrom); } @ModifyVariable(method = "submitColoredRectangle", at = @At("HEAD"), argsOnly = true, ordinal = 0) private Integer easeGUI$modifyColorTo(Integer colorTo) { - if (!AnimationContext.isAnimating() || colorTo == null) return colorTo; + if (!AnimationContext.isActive() || colorTo == null) return colorTo; return ColorUtils.getAnimatedColor(colorTo); } @ModifyVariable(method = "submitBlit", at = @At("HEAD"), argsOnly = true, ordinal = 4) private int easeGUI$modifyBlitColor(int color) { - if (!AnimationContext.isAnimating()) return color; + if (!AnimationContext.isActive()) return color; return ColorUtils.getAnimatedColor(color); } @ModifyVariable(method = "submitTiledBlit", at = @At("HEAD"), argsOnly = true, ordinal = 6) private int easeGUI$modifyTiledBlitColor(int color) { - if (!AnimationContext.isAnimating()) return color; + if (!AnimationContext.isActive()) return color; return ColorUtils.getAnimatedColor(color); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java index 9fc1b73..b003d28 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java @@ -12,7 +12,7 @@ public class GuiTextRenderStateMixin { @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true, ordinal = 2) private static int easeGUI$modifyTextStateColor(int color) { - if (!AnimationContext.isAnimating()) return color; + if (!AnimationContext.isActive()) return color; return net.weyne1.easegui.client.util.ColorUtils.getAnimatedColor(color); } } \ No newline at end of file From aa33280152daf0abd93acea1bf02515233864d31 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 21:38:28 +0300 Subject: [PATCH 27/43] ref(anim): migrate ScreenMixin to updated AnimationContext --- .../accessor/ScreenAnimationAccessor.java | 7 -- .../client/animator/ContainerAnimator.java | 6 +- .../accessor/SplashRendererAccessor.java | 13 --- .../client/mixin/compat/EmiCompatMixin.java | 22 +--- .../easegui/client/mixin/gui/ScreenMixin.java | 100 ++++++------------ common/src/main/resources/easegui.mixins.json | 1 - 6 files changed, 38 insertions(+), 111 deletions(-) delete mode 100644 common/src/main/java/net/weyne1/easegui/client/accessor/ScreenAnimationAccessor.java delete mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/ScreenAnimationAccessor.java b/common/src/main/java/net/weyne1/easegui/client/accessor/ScreenAnimationAccessor.java deleted file mode 100644 index e469b26..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/accessor/ScreenAnimationAccessor.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.weyne1.easegui.client.accessor; - -import net.weyne1.easegui.client.animation.AnimationScope; - -public interface ScreenAnimationAccessor { - AnimationScope easeGUI$getContainerScope(); -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index 522751a..4bbaa08 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -15,11 +15,7 @@ import net.weyne1.easegui.client.state.ScreenStateTracker; public class ContainerAnimator { - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ + public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { if (!(screen instanceof ContainerScreenAccessor container)) { return null; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java b/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java deleted file mode 100644 index e359edb..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/accessor/SplashRendererAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.weyne1.easegui.client.mixin.accessor; - -import net.minecraft.client.gui.components.SplashRenderer; -import net.minecraft.network.chat.Component; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(SplashRenderer.class) -public interface SplashRendererAccessor { - - @Accessor("splash") - Component easeGUI$getSplash(); -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java index b0c9ed5..974b73d 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/compat/EmiCompatMixin.java @@ -1,13 +1,10 @@ package net.weyne1.easegui.client.mixin.compat; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.screens.Screen; -import net.weyne1.easegui.client.accessor.ScreenAnimationAccessor; +import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import org.spongepowered.asm.mixin.Dynamic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -20,28 +17,17 @@ @Mixin(targets = "dev.emi.emi.screen.EmiScreenManager", remap = false) public class EmiCompatMixin { - @Unique - private static AnimationScope easeGUI$getCurrentScope() { - Screen currentScreen = Minecraft.getInstance().screen; - if (currentScreen instanceof ScreenAnimationAccessor accessor) { - return accessor.easeGUI$getContainerScope(); - } - return null; - } - @Dynamic @Inject(method = {"render", "drawBackground", "drawForeground"}, at = @At("HEAD"), require = 0) private static void easeGUI$onEmiRenderStart(CallbackInfo ci) { - AnimationScope scope = easeGUI$getCurrentScope(); - if (scope != null) { - scope.suspend(); - } + AnimationScope scope = AnimationContext.getCurrentScope(); + if (scope != null) scope.suspend(); } @Dynamic @Inject(method = {"render", "drawBackground", "drawForeground"}, at = @At("TAIL"), require = 0) private static void easeGUI$onEmiRenderEnd(CallbackInfo ci) { - AnimationScope scope = easeGUI$getCurrentScope(); + AnimationScope scope = AnimationContext.getCurrentScope(); if (scope != null) scope.resume(); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java index 54ffa54..da78145 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java @@ -1,11 +1,12 @@ package net.weyne1.easegui.client.mixin.gui; +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; -import net.weyne1.easegui.client.accessor.ScreenAnimationAccessor; import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.BackgroundAnimator; @@ -14,103 +15,68 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; @Mixin(Screen.class) -public abstract class ScreenMixin implements ScreenAnimationAccessor { - - @Unique private AnimationScope easeGUI$containerScreenScope = null; - @Unique private AnimationScope easeGUI$menuBackgroundScope = null; +@SuppressWarnings("ConstantConditions") +public abstract class ScreenMixin { @Final @Shadow protected Minecraft minecraft; @Shadow protected abstract void renderBlurredBackground(GuiGraphics guiGraphics); - @Override - @Unique - public AnimationScope easeGUI$getContainerScope() { - return this.easeGUI$containerScreenScope; - } - // Container lifecycle - @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("HEAD")) - private void easeGUI$beforeScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { + @WrapMethod(method = "renderWithTooltipAndSubtitles") + private void easeGUI$wrapScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, Operation original) { if (RenderSystem.isOnRenderThread() && this instanceof ContainerScreenAccessor) { - if (this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.close(); - this.easeGUI$containerScreenScope = null; - } - this.easeGUI$containerScreenScope = ContainerAnimator.beginAnimation((Screen) (Object) this, guiGraphics); - if (this.easeGUI$containerScreenScope != null) { + try (AnimationScope ignored = ContainerAnimator.beginAnimation((Screen) (Object) this, guiGraphics)) { AnimationContext.pushParentAnimation(); - } - } - } - @Inject(method = "render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At("RETURN")) - private void easeGUI$afterScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { - if (RenderSystem.isOnRenderThread() && this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.close(); - this.easeGUI$containerScreenScope = null; + original.call(guiGraphics, mouseX, mouseY, partialTick); - if (AnimationContext.hasParentAnimation()) { AnimationContext.popParentAnimation(); } + + } else { + original.call(guiGraphics, mouseX, mouseY, partialTick); } } // Transparent background (blur / dim) - @Inject(method = "renderTransparentBackground", at = @At("HEAD")) - private void easeGUI$suspendBeforeTransparentBackground(GuiGraphics guiGraphics, CallbackInfo ci) { - if (this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.suspend(); - } + @WrapMethod(method = "renderTransparentBackground") + private void easeGUI$wrapTransparentBackground(GuiGraphics guiGraphics, Operation original) { + AnimationScope currentScope = AnimationContext.getCurrentScope(); + if (currentScope != null) currentScope.suspend(); - Screen currentScreen = (Screen) (Object) this; - boolean blurContainers = ConfigManager.getConfig().global.blurContainers; - if (this.minecraft != null && this.minecraft.level != null && blurContainers && BackgroundAnimator.shouldAnimateBackground(currentScreen)) { - this.renderBlurredBackground(guiGraphics); - } - } + try { + Screen currentScreen = (Screen) (Object) this; + boolean blurContainers = ConfigManager.getConfig().global.blurContainers; + + if (this.minecraft != null && this.minecraft.level != null && blurContainers && BackgroundAnimator.shouldAnimateBackground(currentScreen)) { + this.renderBlurredBackground(guiGraphics); + } - @Inject(method = "renderTransparentBackground", at = @At("RETURN")) - private void easeGUI$resumeAfterTransparentBackground(GuiGraphics guiGraphics, CallbackInfo ci) { - if (this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.resume(); + original.call(guiGraphics); + } finally { + if (currentScope != null) currentScope.resume(); } } // Menu background - @Inject(method = "renderMenuBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", at = @At("HEAD")) - private void easeGUI$preRenderMenuBackground(GuiGraphics guiGraphics, CallbackInfo ci) { - if (this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.suspend(); - } - - if (this.easeGUI$menuBackgroundScope != null) { - this.easeGUI$menuBackgroundScope.close(); - } - - this.easeGUI$menuBackgroundScope = BackgroundAnimator.beginRenderMenu((Screen) (Object) this, guiGraphics); - } - - @Inject(method = "renderMenuBackground(Lnet/minecraft/client/gui/GuiGraphics;)V", at = @At("RETURN")) - private void easeGUI$postRenderMenuBackground(GuiGraphics guiGraphics, CallbackInfo ci) { - if (this.easeGUI$menuBackgroundScope != null) { - this.easeGUI$menuBackgroundScope.close(); - this.easeGUI$menuBackgroundScope = null; - } + @WrapMethod(method = "renderMenuBackground(Lnet/minecraft/client/gui/GuiGraphics;)V") + private void easeGUI$wrapMenuBackground(GuiGraphics guiGraphics, Operation original) { + AnimationScope currentScope = AnimationContext.getCurrentScope(); + if (currentScope != null) currentScope.suspend(); - if (this.easeGUI$containerScreenScope != null) { - this.easeGUI$containerScreenScope.resume(); + try (AnimationScope ignored = BackgroundAnimator.beginRenderMenu((Screen) (Object) this, guiGraphics)) { + original.call(guiGraphics); + } finally { + if (currentScope != null) currentScope.resume(); } } diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index 3962648..ba771ff 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -9,7 +9,6 @@ "OptionsMixin", "accessor.AdvancementTabAccessor", "accessor.LogoRendererAccessor", - "accessor.SplashRendererAccessor", "gui.AbstractSelectionListMixin", "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", From ffa59372f55464fb9071b1e097b1e3c70046615a Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 21:46:00 +0300 Subject: [PATCH 28/43] ref(anim): migrate AbstractWidgetMixin to updated AnimationContext --- .../client/animator/WidgetAnimator.java | 5 -- .../client/mixin/gui/AbstractWidgetMixin.java | 53 ++++++++++--------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index 37da95d..ba0f693 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -16,11 +16,6 @@ */ public class WidgetAnimator { - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, UIElementCategory category, AnimationState state) { if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { return null; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index dca3fa0..d2cc835 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -1,5 +1,7 @@ package net.weyne1.easegui.client.mixin.gui; +import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.*; @@ -12,9 +14,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(AbstractWidget.class) public abstract class AbstractWidgetMixin implements EaseGUIWidget { @@ -24,7 +23,6 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { @Unique private final AnimationState easeGUI$animationState = new AnimationState(); @Unique private UIElementCategory easeGUI$cachedCategory = null; - @Unique private AnimationScope easeGUI$widgetScope = null; @Override public float easeGUI$getAlpha() { @@ -39,38 +37,43 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidget { return this.easeGUI$cachedCategory; } - @Inject(method = "render", at = @At("HEAD")) - private void easeGUI$onPreRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { - if (this.easeGUI$widgetScope != null) { - this.easeGUI$widgetScope.close(); - this.easeGUI$widgetScope = null; - } - + @WrapMethod(method = "render") + private void easeGUI$wrapWidgetRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, Operation original) { AbstractWidget widget = (AbstractWidget) (Object) this; if (!widget.visible) { + original.call(guiGraphics, mouseX, mouseY, partialTick); return; } var category = this.easeGUI$getCategory(); - if (category == null || category == UIElementCategory.UNKNOWN) return; + if (category == null || category == UIElementCategory.UNKNOWN) { + original.call(guiGraphics, mouseX, mouseY, partialTick); + return; + } - this.easeGUI$widgetScope = WidgetAnimator.beginRender(widget, guiGraphics, category, this.easeGUI$animationState); + try (AnimationScope ignored = WidgetAnimator.beginRender(widget, guiGraphics, category, this.easeGUI$animationState)) { - var profile = ConfigManager.getProfileForCurrentContext(category); - if (profile != null && profile.enabled && this.easeGUI$animationState.init) { - long elapsed = Util.getMillis() - this.easeGUI$animationState.startTime - this.easeGUI$animationState.delay; - if (elapsed < profile.duration) { - this.isHovered = false; + var profile = ConfigManager.getProfileForCurrentContext(category); + boolean shouldBypassHover = false; + + if (profile != null && profile.enabled && this.easeGUI$animationState.init) { + long elapsed = Util.getMillis() - this.easeGUI$animationState.startTime - this.easeGUI$animationState.delay; + if (elapsed < profile.duration) { + shouldBypassHover = true; + } } - } - } - @Inject(method = "render", at = @At("RETURN")) - private void easeGUI$onPostRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { - if (this.easeGUI$widgetScope != null) { - this.easeGUI$widgetScope.close(); - this.easeGUI$widgetScope = null; + if (shouldBypassHover) { + boolean savedHover = this.isHovered; + this.isHovered = false; + + original.call(guiGraphics, mouseX, mouseY, partialTick); + + this.isHovered = savedHover; + } else { + original.call(guiGraphics, mouseX, mouseY, partialTick); + } } } } \ No newline at end of file From 6758a33e2e8d89b45bb0d3a02c1d51083854916c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 21:58:21 +0300 Subject: [PATCH 29/43] ref(anim): migrate AdvancementsScreen animation to updated AnimationContext --- .../client/animator/AdvancementsAnimator.java | 10 ------- .../mixin/gui/AdvancementsScreenMixin.java | 30 ++++++++----------- .../mixin/gui/GuiTextRenderStateMixin.java | 3 +- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java index 46a8187..11c4890 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java @@ -15,11 +15,6 @@ public class AdvancementsAnimator { - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGraphics gg) { ScreenType type = EaseGUIScreenRegistry.from(screen); var titleSettings = ConfigManager.getConfig().screens.get(type.getId()); @@ -39,11 +34,6 @@ public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGra return AnimationSystem.begin(gg, 0, 0, screen.width, screen.height, profile, progress, 1.0f); } - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int tabIndex) { ScreenType type = EaseGUIScreenRegistry.from(screen); var titleSettings = ConfigManager.getConfig().screens.get(type.getId()); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java index 5197355..d37df27 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AdvancementsScreenMixin.java @@ -5,6 +5,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.advancements.AdvancementTab; import net.minecraft.client.gui.screens.advancements.AdvancementsScreen; +import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.AdvancementsAnimator; import net.weyne1.easegui.client.mixin.accessor.AdvancementTabAccessor; @@ -17,10 +18,9 @@ @Mixin(AdvancementsScreen.class) public class AdvancementsScreenMixin { - @Unique - private AnimationScope easeGUI$windowScope = null; + @Unique private AnimationScope easeGUI$windowScope = null; - // === АНИМАЦИЯ ГЛАВНОГО ОКНА === + // Main window animation @Inject( method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementsScreen;renderInside(Lnet/minecraft/client/gui/GuiGraphics;II)V") @@ -28,9 +28,14 @@ public class AdvancementsScreenMixin { private void easeGUI$preRenderWindow(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) { if (this.easeGUI$windowScope != null) { this.easeGUI$windowScope.close(); + AnimationContext.popParentAnimation(); } this.easeGUI$windowScope = AdvancementsAnimator.beginRenderWindow((AdvancementsScreen) (Object) this, guiGraphics); + + if (this.easeGUI$windowScope != null) { + AnimationContext.pushParentAnimation(); + } } @Inject(method = "render", at = @At("RETURN")) @@ -38,10 +43,11 @@ public class AdvancementsScreenMixin { if (this.easeGUI$windowScope != null) { this.easeGUI$windowScope.close(); this.easeGUI$windowScope = null; + AnimationContext.popParentAnimation(); } } - // === АНИМАЦИЯ ВКЛАДОК (ФОН) === + // Tab animation (bg) @WrapOperation( method = "renderWindow", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementTab;drawTab(Lnet/minecraft/client/gui/GuiGraphics;IIIIZ)V") @@ -50,17 +56,12 @@ public class AdvancementsScreenMixin { AdvancementsScreen screen = (AdvancementsScreen) (Object) this; int index = ((AdvancementTabAccessor) tab).easeGUI$getIndex(); - AnimationScope scope = AdvancementsAnimator.beginRenderTab(screen, guiGraphics, index); - if (scope != null) { - try (scope) { - original.call(tab, guiGraphics, x, y, mouseX, mouseY, selected); - } - } else { + try (AnimationScope ignored = AdvancementsAnimator.beginRenderTab(screen, guiGraphics, index)) { original.call(tab, guiGraphics, x, y, mouseX, mouseY, selected); } } - // === АНИМАЦИЯ ВКЛАДОК (ИКОНКИ) === + // Tab animation (fg/icons) @WrapOperation( method = "renderWindow", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/advancements/AdvancementTab;drawIcon(Lnet/minecraft/client/gui/GuiGraphics;II)V") @@ -69,12 +70,7 @@ public class AdvancementsScreenMixin { AdvancementsScreen screen = (AdvancementsScreen) (Object) this; int index = ((AdvancementTabAccessor) tab).easeGUI$getIndex(); - AnimationScope scope = AdvancementsAnimator.beginRenderTab(screen, guiGraphics, index); - if (scope != null) { - try (scope) { - original.call(tab, guiGraphics, offsetX, offsetY); - } - } else { + try (AnimationScope ignored = AdvancementsAnimator.beginRenderTab(screen, guiGraphics, index)) { original.call(tab, guiGraphics, offsetX, offsetY); } } diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java index b003d28..00a091a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiTextRenderStateMixin.java @@ -2,6 +2,7 @@ import net.minecraft.client.gui.render.state.GuiTextRenderState; import net.weyne1.easegui.client.animation.AnimationContext; +import net.weyne1.easegui.client.util.ColorUtils; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; @@ -13,6 +14,6 @@ public class GuiTextRenderStateMixin { @ModifyVariable(method = "", at = @At("HEAD"), argsOnly = true, ordinal = 2) private static int easeGUI$modifyTextStateColor(int color) { if (!AnimationContext.isActive()) return color; - return net.weyne1.easegui.client.util.ColorUtils.getAnimatedColor(color); + return ColorUtils.getAnimatedColor(color); } } \ No newline at end of file From f06856ef5fa082e5b2ab9e4bbd3637344f2886ca Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 22:08:52 +0300 Subject: [PATCH 30/43] ref(anim): migrate ListItem Animation to updated AnimationContext --- .../client/animator/ListItemAnimator.java | 8 -------- .../mixin/gui/AbstractSelectionListMixin.java | 20 +++++++------------ 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java index c479e9e..92acebb 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java @@ -11,16 +11,8 @@ import net.weyne1.easegui.client.config.UIElementCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; -/** - * Animates list entries using cascade timing. - */ public class ListItemAnimator { - /** - * Starts the animation. - * - * @return an {@link AnimationScope} that must be closed, or {@code null} if no animation is needed - */ public static AnimationScope beginRender(GuiGraphics gg, int top, int left, int width, int height) { var profile = ConfigManager.getProfileForCurrentContext(UIElementCategory.LIST_ENTRY); if (profile == null || !profile.enabled) return null; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java index e5616a6..fe454c8 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java @@ -27,29 +27,23 @@ public abstract class AbstractSelectionListMixin { ) ) private void easeGUI$wrapRenderItem(AbstractSelectionList instance, GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, @Coerce Object item, Operation original) { - AnimationContext.pushParentAnimation(); - LayoutElement element = (LayoutElement) item; int left = this.getRowLeft(); int width = this.getRowWidth(); int top = element.getY(); int height = element.getHeight(); - AnimationScope scope = ListItemAnimator.beginRender(guiGraphics, top, left, width, height); + try (AnimationScope scope = ListItemAnimator.beginRender(guiGraphics, top, left, width, height)) { - if (scope != null) { - try (scope) { + if (scope != null) { AnimationContext.pushParentAnimation(); - try { - original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); - } finally { - if (AnimationContext.hasParentAnimation()) { - AnimationContext.popParentAnimation(); - } - } } - } else { + original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); + + if (scope != null) { + AnimationContext.popParentAnimation(); + } } } } \ No newline at end of file From 2f9ae5ef98acc1455058490af6edae435e4de392 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Sat, 11 Jul 2026 22:17:00 +0300 Subject: [PATCH 31/43] ref(anim): migrate Splash Animation to updated AnimationContext --- .../client/animator/SplashAnimator.java | 30 +++++++------------ .../mixin/gui/AbstractSelectionListMixin.java | 13 +++----- .../mixin/gui/title/SplashRendererMixin.java | 6 +++- 3 files changed, 19 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java index 9a0f719..fe3d089 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java @@ -1,10 +1,8 @@ package net.weyne1.easegui.client.animator; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import net.minecraft.client.gui.ActiveTextCollector; -import net.minecraft.client.gui.TextAlignment; -import net.minecraft.network.chat.Component; import net.minecraft.util.Util; +import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.state.ScreenStateTracker; @@ -13,41 +11,33 @@ public class SplashAnimator { private static long lastTrackedSessionTime = -1L; private static long actualStartTime = -1L; - public static void animate( - ActiveTextCollector collector, - TextAlignment textAlignment, - int x, - int y, - ActiveTextCollector.Parameters parameters, - Component text, - Operation original - ) { + public static ActiveTextCollector.Parameters getAnimatedParameters(ActiveTextCollector.Parameters parameters) { trackSessionTime(); var screenConfig = ConfigManager.getConfig().screens.get("title"); if (screenConfig == null || !screenConfig.enabled || screenConfig.splash == null || !screenConfig.splash.enabled) { - original.call(collector, textAlignment, x, y, parameters, text); - return; + return parameters.withOpacity(AnimationContext.getCurrentAlpha()); } var splashConfig = screenConfig.splash; long elapsed = Util.getMillis() - actualStartTime - splashConfig.splashDelay; + float parentAlpha = AnimationContext.getCurrentAlpha(); if (elapsed <= 0) { - return; + return null; } if (elapsed >= splashConfig.splashDuration) { - original.call(collector, textAlignment, x, y, parameters.withOpacity(1.0f), text); - return; + return parameters.withOpacity(parentAlpha); } float progress = AnimationMath.calculateProgress(elapsed, splashConfig.splashDuration, splashConfig.splashEasing); + float finalAlpha = AnimationMath.clamp(progress * parentAlpha, 0f, 1f); - ActiveTextCollector.Parameters animatedParams = parameters.withOpacity(AnimationMath.clamp(progress, 0f, 1f)).withScale(progress); - - original.call(collector, textAlignment, x, y, animatedParams, text); + return parameters + .withOpacity(finalAlpha) + .withScale(progress); } private static void trackSessionTime() { diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java index fe454c8..0bfac78 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractSelectionListMixin.java @@ -33,17 +33,12 @@ public abstract class AbstractSelectionListMixin { int top = element.getY(); int height = element.getHeight(); - try (AnimationScope scope = ListItemAnimator.beginRender(guiGraphics, top, left, width, height)) { - - if (scope != null) { - AnimationContext.pushParentAnimation(); - } + AnimationContext.pushParentAnimation(); + try (AnimationScope ignored = ListItemAnimator.beginRender(guiGraphics, top, left, width, height)) { original.call(instance, guiGraphics, mouseX, mouseY, partialTick, item); - - if (scope != null) { - AnimationContext.popParentAnimation(); - } + } finally { + AnimationContext.popParentAnimation(); } } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java index f4615f5..a91ee6e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/title/SplashRendererMixin.java @@ -29,6 +29,10 @@ public class SplashRendererMixin { Component text, Operation original ) { - SplashAnimator.animate(collector, textAlignment, x, y, parameters, text, original); + ActiveTextCollector.Parameters animatedParams = SplashAnimator.getAnimatedParameters(parameters); + + if (animatedParams != null) { + original.call(collector, textAlignment, x, y, animatedParams, text); + } } } \ No newline at end of file From 212fdcaf251fe9d3a319d0c08a8a25ee60c7dd33 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 22:45:30 +0300 Subject: [PATCH 32/43] feat: add animation for 3D layers within GuiGraphics --- .../client/animation/AnimationScope.java | 32 +++--- .../client/animation/PipTransform.java | 52 +++++++++ .../client/animator/WidgetAnimator.java | 4 +- .../EaseGUIWidgetExtension.java} | 4 +- .../extension/EaseGuiItemExtension.java | 5 + .../client/mixin/gui/AbstractWidgetMixin.java | 4 +- .../client/mixin/gui/GuiGraphicsMixin.java | 101 ++++++++++++++++++ .../mixin/gui/GuiItemRenderStateMixin.java | 28 +++++ .../client/mixin/gui/GuiRendererMixin.java | 42 ++++++++ common/src/main/resources/easegui.mixins.json | 2 + 10 files changed, 256 insertions(+), 18 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/PipTransform.java rename common/src/main/java/net/weyne1/easegui/client/{EaseGUIWidget.java => extension/EaseGUIWidgetExtension.java} (61%) create mode 100644 common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java index 6595bc5..a0d5c29 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationScope.java @@ -17,6 +17,26 @@ public final class AnimationScope implements AutoCloseable { private float scaleX = 1.0f, scaleY = 1.0f; private float pivotX, pivotY; + public float getOffsetX() { return offsetX; } + public float getOffsetY() { return offsetY; } + + public float getScaleX() { return scaleX; } + public float getScaleY() { return scaleY; } + + public float getPivotX() { return pivotX; } + public float getPivotY() { return pivotY; } + + public float getAlpha() { + return alpha; + } + + public boolean isClosed() { + return isClosed; + } + public boolean isSuspended() { + return isSuspended; + } + public AnimationScope(GuiGraphics guiGraphics, float alpha) { this.guiGraphics = guiGraphics; this.alpha = alpha; @@ -88,18 +108,6 @@ public void close() { AnimationContext.popScope(this); } - public boolean isClosed() { - return isClosed; - } - - public boolean isSuspended() { - return isSuspended; - } - - public float getAlpha() { - return alpha; - } - private static float clampScale(float scale) { if (Math.abs(scale) < MIN_SCALE) { return Math.copySign(MIN_SCALE, scale == 0.0f ? 1.0f : scale); diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/PipTransform.java b/common/src/main/java/net/weyne1/easegui/client/animation/PipTransform.java new file mode 100644 index 0000000..9e83dd2 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/animation/PipTransform.java @@ -0,0 +1,52 @@ +package net.weyne1.easegui.client.animation; + +/** + * Utility for applying UI animation transformations (scale, offset) + * to Minecraft's Picture-in-Picture (PiP) render states. + *

+ * Used to smoothly animate 3D models (skins, books, banners, etc.) + * relative to the current {@link AnimationScope} pivot. + */ +public final class PipTransform { + private PipTransform() {} + + private static final int MIN_SIZE = 1; + + public static int[] transformRangeX(int x0, int x1) { + return transformRange(x0, x1, true); + } + + public static int[] transformRangeY(int y0, int y1) { + return transformRange(y0, y1, false); + } + + private static int[] transformRange(int start, int end, boolean horizontal) { + AnimationScope scope = AnimationContext.getCurrentScope(); + if (scope == null || scope.isSuspended()) { + return new int[]{start, end}; + } + + float pivot = horizontal ? scope.getPivotX() : scope.getPivotY(); + float offset = horizontal ? scope.getOffsetX() : scope.getOffsetY(); + float scale = horizontal ? scope.getScaleX() : scope.getScaleY(); + + float newStart = pivot + offset + (start - pivot) * scale; + float newEnd = pivot + offset + (end - pivot) * scale; + + int roundedStart = Math.round(newStart); + int roundedEnd = Math.round(newEnd); + + if (Math.abs(roundedEnd - roundedStart) < MIN_SIZE) { + int sign = (newEnd >= newStart) ? 1 : -1; + roundedEnd = roundedStart + sign * MIN_SIZE; + } + + return new int[]{roundedStart, roundedEnd}; + } + + public static float scale(float scale) { + AnimationScope scope = AnimationContext.getCurrentScope(); + if (scope == null || scope.isSuspended()) return scale; + return scale * (scope.getScaleX() + scope.getScaleY()) * 0.5f; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index ba0f693..d49e838 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.weyne1.easegui.client.EaseGUIWidget; +import net.weyne1.easegui.client.extension.EaseGUIWidgetExtension; import net.weyne1.easegui.client.animation.*; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.config.UIElementCategory; @@ -50,7 +50,7 @@ public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, widget.getHeight(), profile, progress, - ((EaseGUIWidget) widget).easeGUI$getAlpha() + ((EaseGUIWidgetExtension) widget).easeGUI$getAlpha() ); } diff --git a/common/src/main/java/net/weyne1/easegui/client/EaseGUIWidget.java b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java similarity index 61% rename from common/src/main/java/net/weyne1/easegui/client/EaseGUIWidget.java rename to common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java index e600718..a6e68a9 100644 --- a/common/src/main/java/net/weyne1/easegui/client/EaseGUIWidget.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java @@ -1,8 +1,8 @@ -package net.weyne1.easegui.client; +package net.weyne1.easegui.client.extension; import net.weyne1.easegui.client.config.UIElementCategory; -public interface EaseGUIWidget { +public interface EaseGUIWidgetExtension { UIElementCategory easeGUI$getCategory(); float easeGUI$getAlpha(); diff --git a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java new file mode 100644 index 0000000..e2936d0 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java @@ -0,0 +1,5 @@ +package net.weyne1.easegui.client.extension; + +public interface EaseGuiItemExtension { + float easegui$getAlpha(); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index d2cc835..d3d7e48 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -5,7 +5,7 @@ import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.*; -import net.weyne1.easegui.client.EaseGUIWidget; +import net.weyne1.easegui.client.extension.EaseGUIWidgetExtension; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationState; import net.weyne1.easegui.client.animator.WidgetAnimator; @@ -16,7 +16,7 @@ import org.spongepowered.asm.mixin.Unique; @Mixin(AbstractWidget.class) -public abstract class AbstractWidgetMixin implements EaseGUIWidget { +public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { @Shadow protected float alpha; @Shadow protected boolean isHovered; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java index f8d016f..1780077 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiGraphicsMixin.java @@ -1,8 +1,24 @@ package net.weyne1.easegui.client.mixin.gui; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.client.gui.render.state.pip.*; +import net.minecraft.client.model.Model; +import net.minecraft.client.model.object.banner.BannerFlagModel; +import net.minecraft.client.model.object.book.BookModel; +import net.minecraft.client.model.player.PlayerModel; +import net.minecraft.client.renderer.entity.state.EntityRenderState; +import net.minecraft.resources.Identifier; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.level.block.entity.BannerPatternLayers; +import net.minecraft.world.level.block.state.properties.WoodType; import net.weyne1.easegui.client.animation.AnimationContext; +import net.weyne1.easegui.client.animation.PipTransform; import net.weyne1.easegui.client.util.ColorUtils; +import org.joml.Quaternionf; +import org.joml.Vector3f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; @@ -34,4 +50,89 @@ public class GuiGraphicsMixin { if (!AnimationContext.isActive()) return color; return ColorUtils.getAnimatedColor(color); } + + @WrapOperation( + method = "submitEntityRenderState", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/pip/GuiEntityRenderState;") + ) + private GuiEntityRenderState easeGUI$transformEntity( + EntityRenderState renderState, Vector3f translation, Quaternionf rotation, Quaternionf overrideCameraAngle, + int x0, int y0, int x1, int y1, float scale, ScreenRectangle scissorArea, + Operation original) { + + int[] xs = PipTransform.transformRangeX(x0, x1); + int[] ys = PipTransform.transformRangeY(y0, y1); + + return original.call( + renderState, translation, rotation, overrideCameraAngle, + xs[0], ys[0], xs[1], ys[1], PipTransform.scale(scale), scissorArea + ); + } + + @WrapOperation( + method = "submitBookModelRenderState", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/pip/GuiBookModelRenderState;") + ) + private GuiBookModelRenderState easeGUI$transformBook( + BookModel bookModel, Identifier texture, float _open, float flip, + int x0, int y0, int x1, int y1, float scale, ScreenRectangle scissorArea, Operation original) { + + int[] xs = PipTransform.transformRangeX(x0, x1); + int[] ys = PipTransform.transformRangeY(y0, y1); + + return original.call( + bookModel, texture, _open, flip, + xs[0], ys[0], xs[1], ys[1], PipTransform.scale(scale), scissorArea + ); + } + + @WrapOperation( + method = "submitSkinRenderState", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/pip/GuiSkinRenderState;") + ) + private GuiSkinRenderState easeGUI$transformSkin( + PlayerModel playerModel, Identifier texture, float rotationX, float rotationY, float pivotY, + int x0, int y0, int x1, int y1, float scale, ScreenRectangle scissorArea, Operation original) { + + int[] xs = PipTransform.transformRangeX(x0, x1); + int[] ys = PipTransform.transformRangeY(y0, y1); + + return original.call( + playerModel, texture, rotationY, pivotY, + (float) xs[0], ys[0], xs[1], ys[1], Math.round(PipTransform.scale(scale)), rotationX, scissorArea + ); + } + + @WrapOperation( + method = "submitBannerPatternRenderState", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/pip/GuiBannerResultRenderState;") + ) + private GuiBannerResultRenderState easeGUI$transformBanner( + BannerFlagModel flag, DyeColor baseColor, BannerPatternLayers resultBannerPatterns, + int x0, int y0, int x1, int y1, ScreenRectangle scissorArea, + Operation original) { + + int[] xs = PipTransform.transformRangeX(x0, x1); + int[] ys = PipTransform.transformRangeY(y0, y1); + + return original.call(flag, baseColor, resultBannerPatterns, xs[0], ys[0], xs[1], ys[1], scissorArea); + } + + @WrapOperation( + method = "submitSignRenderState", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/pip/GuiSignRenderState;") + ) + private GuiSignRenderState easeGUI$transformSign( + Model.Simple signModel, WoodType woodType, int x0, int y0, int x1, int y1, float scale, ScreenRectangle scissorArea, + Operation original) { + + int[] xs = PipTransform.transformRangeX(x0, x1); + int[] ys = PipTransform.transformRangeY(y0, y1); + + return original.call( + signModel, woodType, + xs[0], ys[0], xs[1], ys[1], + PipTransform.scale(scale), scissorArea + ); + } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java new file mode 100644 index 0000000..e673edb --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java @@ -0,0 +1,28 @@ +package net.weyne1.easegui.client.mixin.gui; + +import net.minecraft.client.gui.render.state.GuiItemRenderState; +import net.weyne1.easegui.client.animation.AnimationContext; +import net.weyne1.easegui.client.extension.EaseGuiItemExtension; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(GuiItemRenderState.class) +public class GuiItemRenderStateMixin implements EaseGuiItemExtension { + @Unique + private float easegui$alpha = 1.0f; + + @Inject(method = "", at = @At("RETURN")) + private void easeGUI$captureAlphaOnCreation(CallbackInfo ci) { + if (AnimationContext.isActive()) { + this.easegui$alpha = AnimationContext.getCurrentAlpha(); + } + } + + @Override + public float easegui$getAlpha() { + return this.easegui$alpha; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java new file mode 100644 index 0000000..2745336 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java @@ -0,0 +1,42 @@ +package net.weyne1.easegui.client.mixin.gui; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.blaze3d.pipeline.RenderPipeline; +import net.minecraft.client.gui.navigation.ScreenRectangle; +import net.minecraft.client.gui.render.TextureSetup; +import net.minecraft.client.gui.render.state.BlitRenderState; +import net.minecraft.client.gui.render.state.GuiItemRenderState; +import net.minecraft.client.gui.render.GuiRenderer; +import net.weyne1.easegui.client.extension.EaseGuiItemExtension; +import org.joml.Matrix3x2f; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(GuiRenderer.class) +public class GuiRendererMixin { + + @SuppressWarnings("NameDoesntMatchTargetClass") + @WrapOperation( + method = "submitBlitFromItemAtlas", + at = @At(value = "NEW", target = "Lnet/minecraft/client/gui/render/state/BlitRenderState;") + ) + private BlitRenderState easeGUI$applyStoredAlphaToItems( + RenderPipeline pipeline, TextureSetup textureSetup, Matrix3x2f pose, + int x0, int y0, int x1, int y1, float u0, float u1, float v0, float v1, int color, + ScreenRectangle scissorArea, ScreenRectangle bounds, + Operation original, + GuiItemRenderState renderState, float x, float y, int itemSize, int atlasSize) { + float alpha = ((EaseGuiItemExtension) (Object) renderState).easegui$getAlpha(); + + if (alpha >= 1.0f) { + return original.call(pipeline, textureSetup, pose, x0, y0, x1, y1, u0, u1, v0, v1, color, scissorArea, bounds); + } + + int a = (int) (alpha * 255) & 0xFF; + + int premultipliedColor = (a << 24) | (a << 16) | (a << 8) | a; + + return original.call(pipeline, textureSetup, pose, x0, y0, x1, y1, u0, u1, v0, v1, premultipliedColor, scissorArea, bounds); + } +} \ No newline at end of file diff --git a/common/src/main/resources/easegui.mixins.json b/common/src/main/resources/easegui.mixins.json index ba771ff..92ed8db 100644 --- a/common/src/main/resources/easegui.mixins.json +++ b/common/src/main/resources/easegui.mixins.json @@ -13,6 +13,8 @@ "gui.AbstractWidgetMixin", "gui.AdvancementsScreenMixin", "gui.GuiGraphicsMixin", + "gui.GuiItemRenderStateMixin", + "gui.GuiRendererMixin", "gui.GuiTextRenderStateMixin", "gui.ScreenLifecycleMixin", "gui.ScreenMixin", From 0bf5a2e9b845f33e2273db5acab3fc475bc714d4 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:01:50 +0300 Subject: [PATCH 33/43] ref: split AnimationProfile into separate classes --- .../client/animation/AnimationMath.java | 2 +- .../client/animation/AnimationProfile.java | 163 +++++++----------- .../client/animation/CascadeDirection.java | 8 + .../client/animation/EasingFunction.java | 6 + .../easegui/client/animation/EasingType.java | 63 +++++++ .../easegui/client/animation/PivotPoint.java | 29 ++++ .../easegui/client/config/EaseGUIConfig.java | 13 +- .../configurator/TitleScreenConfigurator.java | 3 +- .../gui/preview/ProfilePreviewRenderer.java | 13 +- .../gui/screens/ProfileEditorScreen.java | 11 +- .../animation/AnimationMathUtilsTest.java | 11 +- 11 files changed, 196 insertions(+), 126 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/EasingFunction.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java create mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java index 21a38ea..3958413 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java @@ -20,7 +20,7 @@ public static float calculateCurrentOffset(float baseOffset, float progress) { public static float calculateProgress( long elapsed, long duration, - AnimationProfile.EasingType easing + EasingType easing ) { if (elapsed <= 0) return 0f; if (elapsed >= duration) return 1f; diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java index 71b7585..1e02a20 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java @@ -2,127 +2,90 @@ import org.joml.Vector2f; +/** + * Configuration profile holding animation properties and fluent builder methods. + */ @SuppressWarnings("UnusedReturnValue") public class AnimationProfile { + public boolean enabled = true; public long duration = 400; public final Vector2f offset = new Vector2f(0f, 0f); public final Vector2f startScale = new Vector2f(1f, 1f); public float startAlpha = 0.0f; public long cascadeDelay = 0L; + public PivotPoint pivot = PivotPoint.CENTER; public EasingType easing = EasingType.EASE_OUT_QUAD; public CascadeDirection cascadeDirection = CascadeDirection.TOP_TO_BOTTOM; - public AnimationProfile enabled(boolean enabled) { this.enabled = enabled; return this; } - public AnimationProfile duration(long duration) { this.duration = duration; return this; } - public AnimationProfile offset(float x, float y) { this.offset.set(x, y); return this; } - public AnimationProfile offsetX(float x) { this.offset.x = x; return this; } - public AnimationProfile offsetY(float y) { this.offset.y = y; return this; } - public AnimationProfile startAlpha(float startAlpha) { this.startAlpha = startAlpha; return this; } - public AnimationProfile startScale(float x, float y) { this.startScale.set(x, y); return this; } - public AnimationProfile startScale(float scale) { this.startScale.set(scale, scale); return this; } - public AnimationProfile startScaleX(float x) { this.startScale.x = x; return this; } - public AnimationProfile startScaleY(float y) { this.startScale.y = y; return this; } - public AnimationProfile cascadeDelay(long cascadeDelay) { this.cascadeDelay = cascadeDelay; return this; } - public AnimationProfile pivot(PivotPoint pivot) { this.pivot = pivot; return this; } - public AnimationProfile easing(EasingType easing) { this.easing = easing; return this; } - public AnimationProfile cascadeDirection(CascadeDirection cascadeDirection) { this.cascadeDirection = cascadeDirection; return this; } - - @FunctionalInterface - public interface EasingFunction { - float apply(float t); + public AnimationProfile enabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + public AnimationProfile duration(long duration) { + this.duration = duration; + return this; + } + + public AnimationProfile offset(float x, float y) { + this.offset.set(x, y); + return this; + } + + public AnimationProfile offsetX(float x) { + this.offset.x = x; + return this; + } + + public AnimationProfile offsetY(float y) { + this.offset.y = y; + return this; } - public enum PivotPoint { - TOP_LEFT(0.0f, 0.0f), TOP_CENTER(0.5f, 0.0f), TOP_RIGHT(1.0f, 0.0f), - CENTER_LEFT(0.0f, 0.5f), CENTER(0.5f, 0.5f), CENTER_RIGHT(1.0f, 0.5f), - BOTTOM_LEFT(0.0f, 1.0f), BOTTOM_CENTER(0.5f, 1.0f), BOTTOM_RIGHT(1.0f, 1.0f); + public AnimationProfile startAlpha(float startAlpha) { + this.startAlpha = startAlpha; + return this; + } - private final float xFactor; - private final float yFactor; + public AnimationProfile startScale(float x, float y) { + this.startScale.set(x, y); + return this; + } - PivotPoint(float xFactor, float yFactor) { - this.xFactor = xFactor; - this.yFactor = yFactor; - } + public AnimationProfile startScale(float scale) { + this.startScale.set(scale, scale); + return this; + } - public float getX(float x, float width) { - return x + (width * this.xFactor); - } + public AnimationProfile startScaleX(float x) { + this.startScale.x = x; + return this; + } + + public AnimationProfile startScaleY(float y) { + this.startScale.y = y; + return this; + } + + public AnimationProfile cascadeDelay(long cascadeDelay) { + this.cascadeDelay = cascadeDelay; + return this; + } - public float getY(float y, float height) { - return y + (height * this.yFactor); - } + public AnimationProfile pivot(PivotPoint pivot) { + this.pivot = pivot; + return this; } - public enum EasingType { - LINEAR(t -> t), - - EASE_IN_QUAD(t -> t * t), - EASE_OUT_QUAD(t -> 1f - (1f - t) * (1f - t)), - EASE_IN_OUT_QUAD(t -> t < 0.5f ? 2f * t * t : 1f - (float) Math.pow(-2f * t + 2f, 2) / 2f), - - EASE_IN_CUBIC(t -> t * t * t), - EASE_OUT_CUBIC(t -> 1f - (float) Math.pow(1f - t, 3)), - EASE_IN_OUT_CUBIC(t -> t < 0.5f ? 4f * t * t * t : 1f - (float) Math.pow(-2f * t + 2f, 3) / 2f), - - EASE_OUT_QUINT(t -> 1f - (float) Math.pow(1f - t, 5)), - - EASE_OUT_EXPO(t -> t == 1f ? 1f : 1f - (float) Math.pow(2, -10f * t)), - - EASE_IN_BACK(t -> { - float c1 = 1.70158f; - float c3 = c1 + 1f; - return c3 * t * t * t - c1 * t * t; - }), - - EASE_OUT_BACK(t -> { - float c1 = 1.70158f; - float c3 = c1 + 1f; - return 1f + c3 * (float) Math.pow(t - 1f, 3) + c1 * (float) Math.pow(t - 1f, 2); - }), - - EASE_OUT_ELASTIC(t -> { - if (t == 0f) return 0f; - if (t == 1f) return 1f; - float c4 = (2f * (float) Math.PI) / 3f; - return (float) Math.pow(2, -10f * t) * (float) Math.sin((t * 10f - 0.75f) * c4) + 1f; - }), - - EASE_OUT_BOUNCE(t -> { - float n1 = 7.5625f; - float d1 = 2.75f; - - if (t < 1f / d1) { - return n1 * t * t; - } else if (t < 2f / d1) { - float t2 = t - 1.5f / d1; - return n1 * t2 * t2 + 0.75f; - } else if (t < 2.5f / d1) { - float t2 = t - 2.25f / d1; - return n1 * t2 * t2 + 0.9375f; - } else { - float t2 = t - 2.625f / d1; - return n1 * t2 * t2 + 0.984375f; - } - }); - - private final EasingFunction function; - - EasingType(EasingFunction function) { - this.function = function; - } - - public float ease(float t) { - return function.apply(t); - } + public AnimationProfile easing(EasingType easing) { + this.easing = easing; + return this; } - public enum CascadeDirection { - TOP_TO_BOTTOM, - BOTTOM_TO_TOP, - LEFT_TO_RIGHT, - RIGHT_TO_LEFT + public AnimationProfile cascadeDirection(CascadeDirection cascadeDirection) { + this.cascadeDirection = cascadeDirection; + return this; } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java b/common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java new file mode 100644 index 0000000..8f3a166 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java @@ -0,0 +1,8 @@ +package net.weyne1.easegui.client.animation; + +public enum CascadeDirection { + TOP_TO_BOTTOM, + BOTTOM_TO_TOP, + LEFT_TO_RIGHT, + RIGHT_TO_LEFT +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/EasingFunction.java b/common/src/main/java/net/weyne1/easegui/client/animation/EasingFunction.java new file mode 100644 index 0000000..0f4af49 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/animation/EasingFunction.java @@ -0,0 +1,6 @@ +package net.weyne1.easegui.client.animation; + +@FunctionalInterface +public interface EasingFunction { + float apply(float t); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java b/common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java new file mode 100644 index 0000000..70100ab --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java @@ -0,0 +1,63 @@ +package net.weyne1.easegui.client.animation; + +public enum EasingType { + LINEAR(t -> t), + + EASE_IN_QUAD(t -> t * t), + EASE_OUT_QUAD(t -> 1f - (1f - t) * (1f - t)), + EASE_IN_OUT_QUAD(t -> t < 0.5f ? 2f * t * t : 1f - (float) Math.pow(-2f * t + 2f, 2) / 2f), + + EASE_IN_CUBIC(t -> t * t * t), + EASE_OUT_CUBIC(t -> 1f - (float) Math.pow(1f - t, 3)), + EASE_IN_OUT_CUBIC(t -> t < 0.5f ? 4f * t * t * t : 1f - (float) Math.pow(-2f * t + 2f, 3) / 2f), + + EASE_OUT_QUINT(t -> 1f - (float) Math.pow(1f - t, 5)), + EASE_OUT_EXPO(t -> t == 1f ? 1f : 1f - (float) Math.pow(2, -10f * t)), + + EASE_IN_BACK(t -> { + float c1 = 1.70158f; + float c3 = c1 + 1f; + return c3 * t * t * t - c1 * t * t; + }), + + EASE_OUT_BACK(t -> { + float c1 = 1.70158f; + float c3 = c1 + 1f; + return 1f + c3 * (float) Math.pow(t - 1f, 3) + c1 * (float) Math.pow(t - 1f, 2); + }), + + EASE_OUT_ELASTIC(t -> { + if (t == 0f) return 0f; + if (t == 1f) return 1f; + float c4 = (2f * (float) Math.PI) / 3f; + return (float) Math.pow(2, -10f * t) * (float) Math.sin((t * 10f - 0.75f) * c4) + 1f; + }), + + EASE_OUT_BOUNCE(t -> { + float n1 = 7.5625f; + float d1 = 2.75f; + + if (t < 1f / d1) { + return n1 * t * t; + } else if (t < 2f / d1) { + float t2 = t - 1.5f / d1; + return n1 * t2 * t2 + 0.75f; + } else if (t < 2.5f / d1) { + float t2 = t - 2.25f / d1; + return n1 * t2 * t2 + 0.9375f; + } else { + float t2 = t - 2.625f / d1; + return n1 * t2 * t2 + 0.984375f; + } + }); + + private final EasingFunction function; + + EasingType(EasingFunction function) { + this.function = function; + } + + public float ease(float t) { + return function.apply(t); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java b/common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java new file mode 100644 index 0000000..ca176d2 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java @@ -0,0 +1,29 @@ +package net.weyne1.easegui.client.animation; + +public enum PivotPoint { + TOP_LEFT(0.0f, 0.0f), + TOP_CENTER(0.5f, 0.0f), + TOP_RIGHT(1.0f, 0.0f), + CENTER_LEFT(0.0f, 0.5f), + CENTER(0.5f, 0.5f), + CENTER_RIGHT(1.0f, 0.5f), + BOTTOM_LEFT(0.0f, 1.0f), + BOTTOM_CENTER(0.5f, 1.0f), + BOTTOM_RIGHT(1.0f, 1.0f); + + private final float xFactor; + private final float yFactor; + + PivotPoint(float xFactor, float yFactor) { + this.xFactor = xFactor; + this.yFactor = yFactor; + } + + public float getX(float x, float width) { + return x + (width * this.xFactor); + } + + public float getY(float y, float height) { + return y + (height * this.yFactor); + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java index bb667ba..ef68601 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java @@ -1,15 +1,16 @@ package net.weyne1.easegui.client.config; import net.weyne1.easegui.client.animation.AnimationProfile; -import net.weyne1.easegui.client.animation.AnimationProfile.EasingType; +import net.weyne1.easegui.client.animation.EasingType; +import net.weyne1.easegui.client.animation.PivotPoint; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; -import static net.weyne1.easegui.client.animation.AnimationProfile.CascadeDirection.BOTTOM_TO_TOP; -import static net.weyne1.easegui.client.animation.AnimationProfile.CascadeDirection.LEFT_TO_RIGHT; -import static net.weyne1.easegui.client.animation.AnimationProfile.EasingType.*; +import static net.weyne1.easegui.client.animation.CascadeDirection.BOTTOM_TO_TOP; +import static net.weyne1.easegui.client.animation.CascadeDirection.LEFT_TO_RIGHT; +import static net.weyne1.easegui.client.animation.EasingType.*; public class EaseGUIConfig { public static final int CURRENT_SCHEMA_VERSION = 2; @@ -146,7 +147,7 @@ public static class LogoSettings { .cascadeDelay(60L) .cascadeDirection(LEFT_TO_RIGHT) .easing(EASE_OUT_BACK) - .pivot(AnimationProfile.PivotPoint.CENTER); + .pivot(PivotPoint.CENTER); public AnimationProfile editionProfile = new AnimationProfile() .duration(400L) @@ -154,7 +155,7 @@ public static class LogoSettings { .startScale(0.9f) .startAlpha(0.0f) .easing(EASE_OUT_QUAD) - .pivot(AnimationProfile.PivotPoint.CENTER); + .pivot(PivotPoint.CENTER); } public static class SplashSettings { diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java index 89c4cd3..47085cb 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java @@ -5,6 +5,7 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import net.weyne1.easegui.client.animation.EasingType; import net.weyne1.easegui.client.util.StringUtils; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.ConfigManager; @@ -78,7 +79,7 @@ public void populate(SettingsScrollList list, EaseGUIConfig.ScreenSettings setti // Интерполяция сплеша Component easingComp = Component.literal(StringUtils.toTitleCase(splash.splashEasing)); list.addButton(Button.builder(Component.translatable("easegui.config.title.splash.easing", easingComp), btn -> { - AnimationProfile.EasingType[] values = AnimationProfile.EasingType.values(); + EasingType[] values = EasingType.values(); splash.splashEasing = values[(splash.splashEasing.ordinal() + 1) % values.length]; Component updatedEasing = Component.literal(StringUtils.toTitleCase(splash.splashEasing)); btn.setMessage(Component.translatable("easegui.config.title.splash.easing", updatedEasing)); diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java b/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java index 17d4e99..1e38228 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java @@ -3,10 +3,7 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.AnimationMath; -import net.weyne1.easegui.client.animation.AnimationProfile; -import net.weyne1.easegui.client.animation.AnimationScope; -import net.weyne1.easegui.client.animation.AnimationSystem; +import net.weyne1.easegui.client.animation.*; import net.weyne1.easegui.client.config.ProfileFeature; import java.util.EnumSet; @@ -41,8 +38,8 @@ public static void render(GuiGraphics gg, Font font, int screenWidth, int screen int itemCount = isCascadeActive ? 3 : 1; boolean isEnabled = profile.enabled; - boolean isHorizontal = profile.cascadeDirection == AnimationProfile.CascadeDirection.LEFT_TO_RIGHT || - profile.cascadeDirection == AnimationProfile.CascadeDirection.RIGHT_TO_LEFT; + boolean isHorizontal = profile.cascadeDirection == CascadeDirection.LEFT_TO_RIGHT || + profile.cascadeDirection == CascadeDirection.RIGHT_TO_LEFT; int boxWidth = (isHorizontal && isCascadeActive) ? 40 : 120; @@ -172,8 +169,8 @@ private static int calcAlphaColor(float startAlpha, float progress) { } private static long calculateCascadeDelay(AnimationProfile profile, int i) { - boolean reverse = profile.cascadeDirection == AnimationProfile.CascadeDirection.BOTTOM_TO_TOP || - profile.cascadeDirection == AnimationProfile.CascadeDirection.RIGHT_TO_LEFT; + boolean reverse = profile.cascadeDirection == CascadeDirection.BOTTOM_TO_TOP || + profile.cascadeDirection == CascadeDirection.RIGHT_TO_LEFT; int factor = reverse ? (2 - i) : i; return factor * profile.cascadeDelay; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java index 5c3f71a..39c2caa 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java @@ -5,6 +5,9 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import net.weyne1.easegui.client.animation.CascadeDirection; +import net.weyne1.easegui.client.animation.EasingType; +import net.weyne1.easegui.client.animation.PivotPoint; import net.weyne1.easegui.client.util.StringUtils; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.ProfileFeature; @@ -107,7 +110,7 @@ protected void initScreen() { if (activeFeatures.contains(ProfileFeature.CASCADE_DIRECTION)) { Component dirComp = getCascadeDirectionComponent(workingCopy.cascadeDirection); leftScrollList.addButton(Button.builder(Component.translatable("easegui.editor.button.cascade_dir", dirComp), b -> { - AnimationProfile.CascadeDirection[] v = AnimationProfile.CascadeDirection.values(); + CascadeDirection[] v = CascadeDirection.values(); workingCopy.cascadeDirection(v[(workingCopy.cascadeDirection.ordinal() + 1) % v.length]); b.setMessage(Component.translatable("easegui.editor.button.cascade_dir", getCascadeDirectionComponent(workingCopy.cascadeDirection))); }).build()); @@ -117,7 +120,7 @@ protected void initScreen() { if (activeFeatures.contains(ProfileFeature.PIVOT)) { Component pivotComp = Component.translatable("easegui.pivot." + workingCopy.pivot.name().toLowerCase()); leftScrollList.addButton(Button.builder(Component.translatable("easegui.editor.button.pivot", pivotComp), b -> { - AnimationProfile.PivotPoint[] v = AnimationProfile.PivotPoint.values(); + PivotPoint[] v = PivotPoint.values(); workingCopy.pivot(v[(workingCopy.pivot.ordinal() + 1) % v.length]); Component updatedPivot = Component.translatable("easegui.pivot." + workingCopy.pivot.name().toLowerCase()); b.setMessage(Component.translatable("easegui.editor.button.pivot", updatedPivot)); @@ -129,7 +132,7 @@ protected void initScreen() { leftScrollList.addButton(Button.builder( Component.translatable("easegui.editor.button.easing", easingComp), button -> { - AnimationProfile.EasingType[] values = AnimationProfile.EasingType.values(); + EasingType[] values = EasingType.values(); workingCopy.easing(values[(workingCopy.easing.ordinal() + 1) % values.length]); Component updatedEasing = Component.literal(StringUtils.toTitleCase(workingCopy.easing)); button.setMessage(Component.translatable("easegui.editor.button.easing", updatedEasing)); @@ -149,7 +152,7 @@ private EditBox createTextField(String value) { return editBox; } - private Component getCascadeDirectionComponent(AnimationProfile.CascadeDirection dir) { + private Component getCascadeDirectionComponent(CascadeDirection dir) { return Component.translatable(switch (dir) { case TOP_TO_BOTTOM -> "easegui.cascade.top_to_bottom"; case BOTTOM_TO_TOP -> "easegui.cascade.bottom_to_top"; diff --git a/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java b/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java index 755c262..8b732da 100644 --- a/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java +++ b/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java @@ -1,6 +1,5 @@ package net.weyne1.easegui.client.animation; -import net.weyne1.easegui.client.animation.AnimationProfile.PivotPoint; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -43,19 +42,19 @@ void testCalculateCurrentOffset() { "500, 1000, 0.5f" // В середине }) void testAnimationProgress(long timePassed, long duration, float expectedProgress) { - float result = AnimationMath.calculateProgress(timePassed, duration, AnimationProfile.EasingType.LINEAR); + float result = AnimationMath.calculateProgress(timePassed, duration, EasingType.LINEAR); assertEquals(expectedProgress, result, 0.0001f); } @ParameterizedTest - @EnumSource(AnimationProfile.EasingType.class) - void allEasingsReturnZeroAtStart(AnimationProfile.EasingType easing) { + @EnumSource(EasingType.class) + void allEasingsReturnZeroAtStart(EasingType easing) { assertEquals(0.0f, easing.ease(0.0f), 0.0001f); } @ParameterizedTest - @EnumSource(AnimationProfile.EasingType.class) - void allEasingsReturnOneAtEnd(AnimationProfile.EasingType easing) { + @EnumSource(EasingType.class) + void allEasingsReturnOneAtEnd(EasingType easing) { assertEquals(1.0f, easing.ease(1.0f), 0.0001f); } } \ No newline at end of file From 4b6dbf265f9832736588a2260a6dc38f49c26169 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:07:22 +0300 Subject: [PATCH 34/43] ref: move duck-interfaces to extension package --- .../easegui/client/animator/ContainerAnimator.java | 14 +++++++------- .../ContainerScreenExtension.java} | 4 ++-- .../RecipeBookComponentExtension.java} | 4 ++-- .../RecipeBookScreenExtension.java} | 4 ++-- .../easegui/client/mixin/gui/ScreenMixin.java | 4 ++-- .../container/AbstractContainerScreenMixin.java | 4 ++-- .../container/AbstractRecipeBookScreenMixin.java | 4 ++-- .../gui/container/RecipeBookComponentMixin.java | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) rename common/src/main/java/net/weyne1/easegui/client/{accessor/ContainerScreenAccessor.java => extension/ContainerScreenExtension.java} (58%) rename common/src/main/java/net/weyne1/easegui/client/{accessor/RecipeBookComponentAccessor.java => extension/RecipeBookComponentExtension.java} (50%) rename common/src/main/java/net/weyne1/easegui/client/{accessor/RecipeBookScreenAccessor.java => extension/RecipeBookScreenExtension.java} (60%) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index 4bbaa08..10f1b01 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -4,9 +4,9 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; -import net.weyne1.easegui.client.accessor.RecipeBookComponentAccessor; -import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; +import net.weyne1.easegui.client.extension.ContainerScreenExtension; +import net.weyne1.easegui.client.extension.RecipeBookComponentExtension; +import net.weyne1.easegui.client.extension.RecipeBookScreenExtension; import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; @@ -17,7 +17,7 @@ public class ContainerAnimator { public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { - if (!(screen instanceof ContainerScreenAccessor container)) { + if (!(screen instanceof ContainerScreenExtension container)) { return null; } @@ -26,10 +26,10 @@ public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { int maxX = minX + container.easeGUI$getImageWidth(); int maxY = minY + container.easeGUI$getImageHeight(); - if (screen instanceof RecipeBookScreenAccessor recipeScreen) { + if (screen instanceof RecipeBookScreenExtension recipeScreen) { RecipeBookComponent book = recipeScreen.easeGUI$getRecipeBookComponent(); - if (book != null && ((RecipeBookComponentAccessor) book).easeGUI$isVisible()) { - RecipeBookComponentAccessor accessor = (RecipeBookComponentAccessor) book; + if (book != null && ((RecipeBookComponentExtension) book).easeGUI$isVisible()) { + RecipeBookComponentExtension accessor = (RecipeBookComponentExtension) book; minX = Math.min(minX, accessor.easeGUI$getXOrigin()); minY = Math.min(minY, accessor.easeGUI$getYOrigin()); maxX = Math.max(maxX, accessor.easeGUI$getXOrigin() + RecipeBookComponent.IMAGE_WIDTH); diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/ContainerScreenAccessor.java b/common/src/main/java/net/weyne1/easegui/client/extension/ContainerScreenExtension.java similarity index 58% rename from common/src/main/java/net/weyne1/easegui/client/accessor/ContainerScreenAccessor.java rename to common/src/main/java/net/weyne1/easegui/client/extension/ContainerScreenExtension.java index a2bc48e..3eb953f 100644 --- a/common/src/main/java/net/weyne1/easegui/client/accessor/ContainerScreenAccessor.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/ContainerScreenExtension.java @@ -1,6 +1,6 @@ -package net.weyne1.easegui.client.accessor; +package net.weyne1.easegui.client.extension; -public interface ContainerScreenAccessor { +public interface ContainerScreenExtension { int easeGUI$getLeftPos(); int easeGUI$getTopPos(); int easeGUI$getImageWidth(); diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java b/common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookComponentExtension.java similarity index 50% rename from common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java rename to common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookComponentExtension.java index 9fb362b..eb57916 100644 --- a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookComponentAccessor.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookComponentExtension.java @@ -1,6 +1,6 @@ -package net.weyne1.easegui.client.accessor; +package net.weyne1.easegui.client.extension; -public interface RecipeBookComponentAccessor { +public interface RecipeBookComponentExtension { boolean easeGUI$isVisible(); int easeGUI$getXOrigin(); int easeGUI$getYOrigin(); diff --git a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java b/common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookScreenExtension.java similarity index 60% rename from common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java rename to common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookScreenExtension.java index 5aa2f85..9e5e1dd 100644 --- a/common/src/main/java/net/weyne1/easegui/client/accessor/RecipeBookScreenAccessor.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/RecipeBookScreenExtension.java @@ -1,7 +1,7 @@ -package net.weyne1.easegui.client.accessor; +package net.weyne1.easegui.client.extension; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -public interface RecipeBookScreenAccessor { +public interface RecipeBookScreenExtension { RecipeBookComponent easeGUI$getRecipeBookComponent(); } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java index da78145..a35e3f6 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java @@ -6,7 +6,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; -import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; +import net.weyne1.easegui.client.extension.ContainerScreenExtension; import net.weyne1.easegui.client.animation.AnimationContext; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animator.BackgroundAnimator; @@ -30,7 +30,7 @@ public abstract class ScreenMixin { @WrapMethod(method = "renderWithTooltipAndSubtitles") private void easeGUI$wrapScreenRender(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, Operation original) { - if (RenderSystem.isOnRenderThread() && this instanceof ContainerScreenAccessor) { + if (RenderSystem.isOnRenderThread() && this instanceof ContainerScreenExtension) { try (AnimationScope ignored = ContainerAnimator.beginAnimation((Screen) (Object) this, guiGraphics)) { AnimationContext.pushParentAnimation(); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractContainerScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractContainerScreenMixin.java index 2844c11..74ecd22 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractContainerScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractContainerScreenMixin.java @@ -3,12 +3,12 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.accessor.ContainerScreenAccessor; +import net.weyne1.easegui.client.extension.ContainerScreenExtension; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(AbstractContainerScreen.class) -public abstract class AbstractContainerScreenMixin extends Screen implements ContainerScreenAccessor { +public abstract class AbstractContainerScreenMixin extends Screen implements ContainerScreenExtension { @Shadow protected int leftPos; @Shadow protected int topPos; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java index 846478a..b58fcc0 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/AbstractRecipeBookScreenMixin.java @@ -2,13 +2,13 @@ import net.minecraft.client.gui.screens.inventory.AbstractRecipeBookScreen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.weyne1.easegui.client.accessor.RecipeBookScreenAccessor; +import net.weyne1.easegui.client.extension.RecipeBookScreenExtension; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(AbstractRecipeBookScreen.class) -public abstract class AbstractRecipeBookScreenMixin implements RecipeBookScreenAccessor { +public abstract class AbstractRecipeBookScreenMixin implements RecipeBookScreenExtension { @Final @Shadow private RecipeBookComponent recipeBookComponent; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java index cb909e8..3090bfe 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/container/RecipeBookComponentMixin.java @@ -1,13 +1,13 @@ package net.weyne1.easegui.client.mixin.gui.container; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; -import net.weyne1.easegui.client.accessor.RecipeBookComponentAccessor; +import net.weyne1.easegui.client.extension.RecipeBookComponentExtension; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(RecipeBookComponent.class) -public interface RecipeBookComponentMixin extends RecipeBookComponentAccessor { +public interface RecipeBookComponentMixin extends RecipeBookComponentExtension { @Accessor("visible") boolean easeGUI$isVisible(); From bca52f3f1022dbbd9837e2af5534fb1bc4dd650a Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:09:12 +0300 Subject: [PATCH 35/43] ref: move FieldValidator into components package --- .../easegui/client/gui/{ => components}/FieldValidator.java | 2 +- .../easegui/client/gui/configurator/IScreenConfigurator.java | 2 +- .../net/weyne1/easegui/client/gui/screens/MainConfigScreen.java | 2 +- .../weyne1/easegui/client/gui/screens/ProfileEditorScreen.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename common/src/main/java/net/weyne1/easegui/client/gui/{ => components}/FieldValidator.java (97%) diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java b/common/src/main/java/net/weyne1/easegui/client/gui/components/FieldValidator.java similarity index 97% rename from common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java rename to common/src/main/java/net/weyne1/easegui/client/gui/components/FieldValidator.java index 0a546f9..d5b0449 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/FieldValidator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/components/FieldValidator.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client.gui; +package net.weyne1.easegui.client.gui.components; import net.minecraft.client.gui.components.EditBox; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/IScreenConfigurator.java b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/IScreenConfigurator.java index be66d9d..8aae04b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/IScreenConfigurator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/IScreenConfigurator.java @@ -5,7 +5,7 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; import net.weyne1.easegui.client.config.EaseGUIConfig; -import net.weyne1.easegui.client.gui.FieldValidator; +import net.weyne1.easegui.client.gui.components.FieldValidator; import net.weyne1.easegui.client.gui.components.SettingsScrollList; import java.util.HashMap; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java index 4002df0..c7c8c92 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java @@ -7,7 +7,7 @@ import net.minecraft.network.chat.Component; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.*; -import net.weyne1.easegui.client.gui.FieldValidator; +import net.weyne1.easegui.client.gui.components.FieldValidator; import net.weyne1.easegui.client.gui.components.SettingsScrollList; import java.util.Comparator; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java index 39c2caa..0eec6dc 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java @@ -11,7 +11,7 @@ import net.weyne1.easegui.client.util.StringUtils; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.config.ProfileFeature; -import net.weyne1.easegui.client.gui.FieldValidator; +import net.weyne1.easegui.client.gui.components.FieldValidator; import net.weyne1.easegui.client.gui.components.SettingsScrollList; import net.weyne1.easegui.client.gui.preview.ProfilePreviewRenderer; From a75fc7fa3e42dd756c5609a7d8beff75fa65bdb3 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:28:00 +0300 Subject: [PATCH 36/43] ref: centralize timing and progress calculation in AnimationSystem --- .../client/animation/AnimationSystem.java | 23 +++++++++++++++++++ .../client/animator/ContainerAnimator.java | 9 +------- .../client/animator/ListItemAnimator.java | 13 +---------- .../client/animator/WidgetAnimator.java | 21 ++--------------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java index a6ed5e0..830b9e7 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java @@ -1,9 +1,32 @@ package net.weyne1.easegui.client.animation; import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.util.Util; public final class AnimationSystem { + /** + * An entry point for animations with automatic timing and progress calculation. + */ + public static AnimationScope begin( + GuiGraphics gg, + int x, int y, int width, int height, + AnimationProfile profile, + long startTime, + long delay, + float baseAlpha + ) { + long elapsed = Util.getMillis() - startTime - delay; + + if (elapsed >= profile.duration) { + return null; + } + + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + + return begin(gg, x, y, width, height, profile, progress, baseAlpha); + } + public static AnimationScope begin( GuiGraphics gg, int x, int y, int width, int height, diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index 10f1b01..41fe0ea 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -1,13 +1,11 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.recipebook.RecipeBookComponent; import net.weyne1.easegui.client.extension.ContainerScreenExtension; import net.weyne1.easegui.client.extension.RecipeBookComponentExtension; import net.weyne1.easegui.client.extension.RecipeBookScreenExtension; -import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; @@ -41,11 +39,6 @@ public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { if (profile == null || !profile.enabled) return null; long startTime = ScreenStateTracker.getScreenOpenTime(); - long elapsed = Util.getMillis() - startTime; - if (elapsed >= profile.duration) return null; - - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); - - return AnimationSystem.begin(gg, minX, minY, maxX - minX, maxY - minY, profile, progress, 1.0f); + return AnimationSystem.begin(gg, minX, minY, maxX - minX, maxY - minY, profile, startTime, 0L, 1.0f); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java index 92acebb..ee49b13 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java @@ -1,9 +1,7 @@ package net.weyne1.easegui.client.animator; -import net.minecraft.util.Util; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.weyne1.easegui.client.animation.AnimationMath; import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; @@ -20,16 +18,7 @@ public static AnimationScope beginRender(GuiGraphics gg, int top, int left, int long delay = getDelay(top, left, profile); long startTime = ScreenStateTracker.getScreenOpenTime(); - long elapsed = Util.getMillis() - startTime - delay; - - if (elapsed >= profile.duration) return null; - - float progress = 0.0f; - if (elapsed > 0) { - progress = AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); - } - - return AnimationSystem.begin(gg, left, top, width, height, profile, progress, 1.0f); + return AnimationSystem.begin(gg, left, top, width, height, profile, startTime, delay, 1.0f); } private static long getDelay(int top, int left, AnimationProfile profile) { diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index d49e838..28ad461 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -33,25 +33,8 @@ public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, return null; } - long elapsed = now - state.startTime - state.delay; - - if (elapsed >= profile.duration) return null; - - float progress = 0.0f; - if (elapsed > 0) { - progress = AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); - } - - return AnimationSystem.begin( - gg, - widget.getX(), - widget.getY(), - widget.getWidth(), - widget.getHeight(), - profile, - progress, - ((EaseGUIWidgetExtension) widget).easeGUI$getAlpha() - ); + return AnimationSystem.begin(gg, widget.getX(), widget.getY(), widget.getWidth(), widget.getHeight(), profile, + state.startTime, state.delay, ((EaseGUIWidgetExtension) widget).easeGUI$getAlpha()); } /** From b6f3e57acb16d8aa5dc5b437aff3a5409444c003 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:39:00 +0300 Subject: [PATCH 37/43] ref: delegate title screen session tracking to ScreenStateTracker --- .../easegui/client/animator/LogoAnimator.java | 16 +++------------- .../easegui/client/animator/SplashAnimator.java | 13 +------------ .../easegui/client/state/ScreenStateTracker.java | 13 +++++++++++++ 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java index 752c0b2..3fef10a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java @@ -37,17 +37,12 @@ public class LogoAnimator { */ private static final int[] LOGICAL_INDICES = new int[] { 0, 1, 2, 3, 8, 7, 6, 5, 4 }; - private static long lastTrackedSessionTime = -1L; - private static long actualStartTime = -1L; - public static boolean render(GuiGraphics gg, int screenWidth, float transparency, int height, boolean showEasterEgg, boolean keepLogoThroughFade) { var titleSettings = ConfigManager.getConfig().screens.get("title"); if (titleSettings == null || !titleSettings.enabled || titleSettings.logo == null) { return false; } - trackSessionTime(); - var logoConfig = titleSettings.logo; float finalAlpha = keepLogoThroughFade ? 1.0f : transparency; int startX = screenWidth / 2 - (LogoRendererAccessor.easeGUI$getLogoWidth() / 2); @@ -65,6 +60,7 @@ public static boolean render(GuiGraphics gg, int screenWidth, float transparency } private static void renderWholeLogo(GuiGraphics gg, Identifier texture, AnimationProfile profile, int startX, int height, float finalAlpha) { + long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); long elapsed = Util.getMillis() - actualStartTime; int logoWidth = LogoRendererAccessor.easeGUI$getLogoWidth(); int logoHeight = LogoRendererAccessor.easeGUI$getLogoHeight(); @@ -84,6 +80,7 @@ private static void renderWholeLogo(GuiGraphics gg, Identifier texture, Animatio private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profile, int startX, int height, float finalAlpha) { long now = Util.getMillis(); + long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); long maxLogoDelay = (LETTER_TEXTURES.length - 1) * profile.cascadeDelay; int logoWidth = LogoRendererAccessor.easeGUI$getLogoWidth(); int logoHeight = LogoRendererAccessor.easeGUI$getLogoHeight(); @@ -152,6 +149,7 @@ private static long calculateCascadeDelay(AnimationProfile profile, int logicalI } private static long getEditionElapsed(EaseGUIConfig.LogoSettings config) { + long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); long maxLogoDelay = config.animateWholeText ? 0L : switch (config.logoProfile.cascadeDirection) { case LEFT_TO_RIGHT, RIGHT_TO_LEFT -> (LETTER_TEXTURES.length - 1) * config.logoProfile.cascadeDelay; case TOP_TO_BOTTOM, BOTTOM_TO_TOP -> 0L; @@ -159,14 +157,6 @@ private static long getEditionElapsed(EaseGUIConfig.LogoSettings config) { return Util.getMillis() - actualStartTime - maxLogoDelay; } - private static void trackSessionTime() { - long currentSessionTime = ScreenStateTracker.getScreenOpenTime(); - if (lastTrackedSessionTime != currentSessionTime) { - lastTrackedSessionTime = currentSessionTime; - actualStartTime = Util.getMillis(); - } - } - private static void drawLogoTexture(GuiGraphics gg, Identifier texture, int x, int y) { gg.blit(RenderPipelines.GUI_TEXTURED, texture, x, y, 0.0f, 0.0f, LogoRendererAccessor.easeGUI$getLogoWidth(), diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java index fe3d089..4f5c43d 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/SplashAnimator.java @@ -8,12 +8,8 @@ import net.weyne1.easegui.client.state.ScreenStateTracker; public class SplashAnimator { - private static long lastTrackedSessionTime = -1L; - private static long actualStartTime = -1L; public static ActiveTextCollector.Parameters getAnimatedParameters(ActiveTextCollector.Parameters parameters) { - trackSessionTime(); - var screenConfig = ConfigManager.getConfig().screens.get("title"); if (screenConfig == null || !screenConfig.enabled || screenConfig.splash == null || !screenConfig.splash.enabled) { @@ -21,6 +17,7 @@ public static ActiveTextCollector.Parameters getAnimatedParameters(ActiveTextCol } var splashConfig = screenConfig.splash; + long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); long elapsed = Util.getMillis() - actualStartTime - splashConfig.splashDelay; float parentAlpha = AnimationContext.getCurrentAlpha(); @@ -39,12 +36,4 @@ public static ActiveTextCollector.Parameters getAnimatedParameters(ActiveTextCol .withOpacity(finalAlpha) .withScale(progress); } - - private static void trackSessionTime() { - long currentSessionTime = ScreenStateTracker.getScreenOpenTime(); - if (lastTrackedSessionTime != currentSessionTime) { - lastTrackedSessionTime = currentSessionTime; - actualStartTime = Util.getMillis(); - } - } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java b/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java index 12af6f2..cf3c553 100644 --- a/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java +++ b/common/src/main/java/net/weyne1/easegui/client/state/ScreenStateTracker.java @@ -7,6 +7,8 @@ public class ScreenStateTracker { private static long screenOpenTime = -1; + private static long lastTrackedSessionTime = -1L; + private static long titleActualStartTime = -1L; private static int currentFrameId = 0; private static int resizeGraceFrames = 0; private static int lastWidth = -1; @@ -51,6 +53,17 @@ public static void incrementFrame() { } } + public static long getTitleActualStartTime() { + long openTime = getScreenOpenTime(); + + if (lastTrackedSessionTime != openTime) { + lastTrackedSessionTime = openTime; + titleActualStartTime = Util.getMillis(); + } + + return titleActualStartTime; + } + public static long getScreenOpenTime() { if (screenOpenTime == -1) { screenOpenTime = Util.getMillis(); From 5bf0ed1d198f485b76e9cceacd25975b9eeb2738 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Mon, 13 Jul 2026 23:48:21 +0300 Subject: [PATCH 38/43] ref: make bg animation bypass extensible via registry --- .../client/animator/BackgroundAnimator.java | 37 +++++++++++++++---- .../easegui/client/mixin/MinecraftMixin.java | 2 +- .../easegui/client/mixin/gui/ScreenMixin.java | 2 +- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java index 3d472be..3e2478b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java @@ -11,19 +11,30 @@ import net.weyne1.easegui.client.state.ScreenAnimationTracker; import net.weyne1.easegui.client.state.ScreenStateTracker; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + public class BackgroundAnimator { public static boolean skipBackgroundFade = false; - public static boolean isLoadingScreen(Screen screen) { - return screen instanceof LevelLoadingScreen - || screen instanceof ProgressScreen - || screen instanceof ConnectScreen - || screen instanceof GenericWaitingScreen - || screen instanceof BackupConfirmScreen; + private static final Set> IGNORED_SCREEN_CLASSES = ConcurrentHashMap.newKeySet(); + + static { + IGNORED_SCREEN_CLASSES.add(TitleScreen.class); + IGNORED_SCREEN_CLASSES.add(LevelLoadingScreen.class); + IGNORED_SCREEN_CLASSES.add(ProgressScreen.class); + IGNORED_SCREEN_CLASSES.add(ConnectScreen.class); + IGNORED_SCREEN_CLASSES.add(GenericWaitingScreen.class); + IGNORED_SCREEN_CLASSES.add(BackupConfirmScreen.class); + } + + @SuppressWarnings("unused") + public static void registerIgnoredScreen(Class screenClass) { + IGNORED_SCREEN_CLASSES.add(screenClass); } public static boolean shouldAnimateBackground(Screen screen) { - if (screen == null || screen instanceof TitleScreen || isLoadingScreen(screen)) { + if (screen == null || isIgnoredScreen(screen)) { return false; } @@ -60,7 +71,7 @@ public static int getAnimatedColor(Screen screen, int originalColor) { } public static AnimationScope beginRenderMenu(Screen screen, GuiGraphics gg) { - if (isLoadingScreen(screen) || !shouldAnimateBackground(screen) || skipBackgroundFade) { + if (!shouldAnimateBackground(screen) || skipBackgroundFade) { return null; } @@ -73,4 +84,14 @@ public static AnimationScope beginRenderMenu(Screen screen, GuiGraphics gg) { float progress = Math.max(0.0f, Math.min(1.0f, ScreenAnimationTracker.getProgress())); return AnimationSystem.beginAlphaOnly(gg, progress); } + + private static boolean isIgnoredScreen(Screen screen) { + Class screenClass = screen.getClass(); + for (Class ignored : IGNORED_SCREEN_CLASSES) { + if (ignored.isAssignableFrom(screenClass)) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java index 0926c98..d53b874 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/MinecraftMixin.java @@ -18,7 +18,7 @@ public class MinecraftMixin { private void easeGUI$onScreenTransition(Screen guiScreen, CallbackInfo ci) { Screen oldScreen = this.screen; - if (BackgroundAnimator.isLoadingScreen(guiScreen)) { + if (!BackgroundAnimator.shouldAnimateBackground(guiScreen)) { BackgroundAnimator.skipBackgroundFade = true; return; } diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java index a35e3f6..db9d04e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/ScreenMixin.java @@ -88,7 +88,7 @@ public abstract class ScreenMixin { ) private void easeGUI$modifyTransparentBgColors(Args args) { Screen currentScreen = (Screen) (Object) this; - if (BackgroundAnimator.isLoadingScreen(currentScreen)) { + if (!BackgroundAnimator.shouldAnimateBackground(currentScreen)) { return; } From efa78b36ebb7685c46b169038e813f0d4e553a65 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 14 Jul 2026 00:23:57 +0300 Subject: [PATCH 39/43] ref(config): split EaseGUIConfig data structure from initialization and migration logic --- .../easegui/client/config/ConfigManager.java | 8 +- .../easegui/client/config/EaseGUIConfig.java | 197 +---------------- .../client/config/EaseGUIConfigFactory.java | 208 ++++++++++++++++++ 3 files changed, 221 insertions(+), 192 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java index b01618e..b3e3f53 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java @@ -19,7 +19,7 @@ public class ConfigManager { private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - private static EaseGUIConfig currentConfig = new EaseGUIConfig(); + private static EaseGUIConfig currentConfig = EaseGUIConfigFactory.createDefaultConfig(); private static boolean isLoaded = false; private static Screen cachedScreenInstance = null; @@ -54,12 +54,12 @@ public static void load() { currentConfig = GSON.fromJson(jsonConfig, EaseGUIConfig.class); if (currentConfig == null) { - currentConfig = new EaseGUIConfig(); + currentConfig = EaseGUIConfigFactory.createDefaultConfig(); } currentConfig.schemaVersion = EaseGUIConfig.CURRENT_SCHEMA_VERSION; - if (currentConfig.mergeDefaults() || migrated) { + if (EaseGUIConfigFactory.mergeDefaults(currentConfig) || migrated) { LOGGER.info("[EaseGUI] Config schema updated from version {} to {}.", version, EaseGUIConfig.CURRENT_SCHEMA_VERSION); save(); } @@ -67,7 +67,7 @@ public static void load() { LOGGER.info("[EaseGUI] Config successfully loaded from disk."); } catch (Exception e) { LOGGER.error("[EaseGUI] Failed to read config, creating default... Error: {}", e.getMessage()); - currentConfig = new EaseGUIConfig(); + currentConfig = EaseGUIConfigFactory.createDefaultConfig(); save(); } } else { diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java index ef68601..d97198d 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java @@ -2,122 +2,20 @@ import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.animation.EasingType; -import net.weyne1.easegui.client.animation.PivotPoint; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; -import static net.weyne1.easegui.client.animation.CascadeDirection.BOTTOM_TO_TOP; -import static net.weyne1.easegui.client.animation.CascadeDirection.LEFT_TO_RIGHT; -import static net.weyne1.easegui.client.animation.EasingType.*; +import static net.weyne1.easegui.client.animation.EasingType.EASE_OUT_CUBIC; public class EaseGUIConfig { public static final int CURRENT_SCHEMA_VERSION = 2; - public int schemaVersion = CURRENT_SCHEMA_VERSION; - public final GlobalSettings global = new GlobalSettings(); + public int schemaVersion = CURRENT_SCHEMA_VERSION; + public GlobalSettings global = new GlobalSettings(); public Map screens = new HashMap<>(); - public EaseGUIConfig() { - global.elementProfiles.put(UIElementCategory.BUTTON_LIKE, createButtonProfile()); - global.elementProfiles.put(UIElementCategory.TEXT, createTextProfile()); - global.elementProfiles.put(UIElementCategory.SCROLLABLE, createScrollableProfile()); - global.elementProfiles.put(UIElementCategory.LIST_ENTRY, createListEntryProfile()); - global.elementProfiles.put(UIElementCategory.CONTAINERS, createContainerProfile()); - - for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { - screens.put(type.getId(), createDefaultSettingsFor(type)); - } - screens.put(EaseGUIScreenRegistry.OTHER.getId(), createDefaultSettingsFor(EaseGUIScreenRegistry.OTHER)); - } - - /** - * Patches missing structure and runs schema migrations. - * - * @return true if config was modified and should be saved back to disk - */ - public boolean mergeDefaults() { - boolean changed = false; - - if (this.schemaVersion < CURRENT_SCHEMA_VERSION) { - this.schemaVersion = CURRENT_SCHEMA_VERSION; - changed = true; - } - - if (this.screens == null) { - this.screens = new HashMap<>(); - changed = true; - } - - for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { - if (!this.screens.containsKey(type.getId())) { - this.screens.put(type.getId(), createDefaultSettingsFor(type)); - changed = true; - } else { - changed |= patchScreenSettings(type, this.screens.get(type.getId())); - } - } - - if (!this.screens.containsKey(EaseGUIScreenRegistry.OTHER.getId())) { - this.screens.put(EaseGUIScreenRegistry.OTHER.getId(), createDefaultSettingsFor(EaseGUIScreenRegistry.OTHER)); - changed = true; - } - - return changed; - } - - /** - * Applies structural defaults for an existing screen entry. - * This only fills missing nested sections, not arbitrary primitive fields. - */ - private boolean patchScreenSettings(ScreenType type, ScreenSettings settings) { - boolean changed = false; - - if (settings == null) { - this.screens.put(type.getId(), createDefaultSettingsFor(type)); - return true; - } - - if ("title".equals(type.getId())) { - if (settings.logo == null) { - settings.logo = createLogoSettings(); - changed = true; - } - if (settings.splash == null) { - settings.splash = new SplashSettings(); - changed = true; - } - } else if ("advancements".equals(type.getId())) { - if (settings.advancements == null) { - settings.advancements = createAdvancementsSettings(); - changed = true; - } - } - - if (settings.customProfiles == null) { - settings.customProfiles = new EnumMap<>(UIElementCategory.class); - changed = true; - } - - return changed; - } - - private ScreenSettings createDefaultSettingsFor(ScreenType type) { - ScreenSettings settings = new ScreenSettings(); - settings.enabled = type.isEnabledByDefault(); - - switch (type.getId()) { - case "title" -> { - settings.logo = createLogoSettings(); - settings.splash = new SplashSettings(); - } - case "advancements" -> settings.advancements = createAdvancementsSettings(); - } - - return settings; - } - public static class GlobalSettings { public boolean enableSmoothBlur = true; public long blurDuration = 300L; @@ -128,8 +26,7 @@ public static class GlobalSettings { public static class ScreenSettings { public boolean enabled = true; - public Map customProfiles = - new EnumMap<>(UIElementCategory.class); + public Map customProfiles = new EnumMap<>(UIElementCategory.class); public LogoSettings logo = null; public SplashSettings splash = null; @@ -138,95 +35,19 @@ public static class ScreenSettings { public static class LogoSettings { public boolean animateWholeText = false; - - public AnimationProfile logoProfile = new AnimationProfile() - .duration(400L) - .offsetY(10f) - .startScale(0.8f) - .startAlpha(0.0f) - .cascadeDelay(60L) - .cascadeDirection(LEFT_TO_RIGHT) - .easing(EASE_OUT_BACK) - .pivot(PivotPoint.CENTER); - - public AnimationProfile editionProfile = new AnimationProfile() - .duration(400L) - .offsetY(5f) - .startScale(0.9f) - .startAlpha(0.0f) - .easing(EASE_OUT_QUAD) - .pivot(PivotPoint.CENTER); + public AnimationProfile logoProfile; + public AnimationProfile editionProfile; } public static class SplashSettings { public boolean enabled = true; public long splashDelay = 500L; public long splashDuration = 500L; - public EasingType splashEasing = EASE_OUT_BACK; + public EasingType splashEasing; } public static class AdvancementsSettings { - public AnimationProfile windowProfile = new AnimationProfile() - .duration(250) - .startAlpha(0.0f) - .startScale(0.8f) - .easing(EASE_OUT_CUBIC); - - public AnimationProfile tabsProfile = new AnimationProfile() - .duration(400L) - .offsetX(-40f) - .startAlpha(0.0f) - .cascadeDelay(45L) - .cascadeDirection(LEFT_TO_RIGHT) - .easing(EASE_OUT_BACK); - } - - private static AnimationProfile createButtonProfile() { - return new AnimationProfile() - .duration(400) - .offsetY(15f) - .startAlpha(0.0f) - .cascadeDelay(45L) - .cascadeDirection(BOTTOM_TO_TOP) - .easing(EASE_OUT_BACK); - } - - private static AnimationProfile createTextProfile() { - return new AnimationProfile() - .duration(300) - .startAlpha(0.0f) - .easing(LINEAR); - } - - private static AnimationProfile createScrollableProfile() { - return new AnimationProfile() - .duration(300) - .startAlpha(0.0f) - .easing(EASE_OUT_BACK); - } - - private static AnimationProfile createListEntryProfile() { - return new AnimationProfile() - .duration(350) - .offsetY(15f) - .startAlpha(0.0f) - .cascadeDelay(45L) - .easing(EASE_OUT_CUBIC); - } - - private static AnimationProfile createContainerProfile() { - return new AnimationProfile() - .duration(250) - .offsetY(20f) - .startAlpha(0.0f) - .easing(EASE_OUT_CUBIC); - } - - private static LogoSettings createLogoSettings() { - return new LogoSettings(); - } - - private static AdvancementsSettings createAdvancementsSettings() { - return new AdvancementsSettings(); + public AnimationProfile windowProfile; + public AnimationProfile tabsProfile; } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java new file mode 100644 index 0000000..6635e88 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java @@ -0,0 +1,208 @@ +package net.weyne1.easegui.client.config; + +import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.client.animation.PivotPoint; +import java.util.EnumMap; +import java.util.HashMap; + +import static net.weyne1.easegui.client.animation.CascadeDirection.BOTTOM_TO_TOP; +import static net.weyne1.easegui.client.animation.CascadeDirection.LEFT_TO_RIGHT; +import static net.weyne1.easegui.client.animation.EasingType.*; + +/** + * Factory responsible for creating default configurations, applying structural patches, + * and handling schema migrations. + */ +public final class EaseGUIConfigFactory { + + public static EaseGUIConfig createDefaultConfig() { + EaseGUIConfig config = new EaseGUIConfig(); + + config.global.elementProfiles.put(UIElementCategory.BUTTON_LIKE, createButtonProfile()); + config.global.elementProfiles.put(UIElementCategory.TEXT, createTextProfile()); + config.global.elementProfiles.put(UIElementCategory.SCROLLABLE, createScrollableProfile()); + config.global.elementProfiles.put(UIElementCategory.LIST_ENTRY, createListEntryProfile()); + config.global.elementProfiles.put(UIElementCategory.CONTAINERS, createContainerProfile()); + + for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { + config.screens.put(type.getId(), createDefaultSettingsFor(type)); + } + config.screens.put(EaseGUIScreenRegistry.OTHER.getId(), createDefaultSettingsFor(EaseGUIScreenRegistry.OTHER)); + + return config; + } + + /** + * Patches missing structures in an existing config and bumps the schema version if needed. + * Replaces the old non-SRP mergeDefaults() inside the config class. + * + * @return true if config was modified and should be saved back to disk + */ + public static boolean mergeDefaults(EaseGUIConfig config) { + boolean changed = false; + + if (config.schemaVersion < EaseGUIConfig.CURRENT_SCHEMA_VERSION) { + config.schemaVersion = EaseGUIConfig.CURRENT_SCHEMA_VERSION; + changed = true; + } + + if (config.screens == null) { + config.screens = new HashMap<>(); + changed = true; + } + + for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { + if (!config.screens.containsKey(type.getId())) { + config.screens.put(type.getId(), createDefaultSettingsFor(type)); + changed = true; + } else { + changed |= patchScreenSettings(type, config.screens.get(type.getId()), config); + } + } + + if (!config.screens.containsKey(EaseGUIScreenRegistry.OTHER.getId())) { + config.screens.put(EaseGUIScreenRegistry.OTHER.getId(), createDefaultSettingsFor(EaseGUIScreenRegistry.OTHER)); + changed = true; + } + + return changed; + } + + private static boolean patchScreenSettings(ScreenType type, EaseGUIConfig.ScreenSettings settings, EaseGUIConfig config) { + boolean changed = false; + + if (settings == null) { + config.screens.put(type.getId(), createDefaultSettingsFor(type)); + return true; + } + + if ("title".equals(type.getId())) { + if (settings.logo == null) { + settings.logo = createLogoSettings(); + changed = true; + } + if (settings.splash == null) { + settings.splash = createSplashSettings(); + changed = true; + } + } else if ("advancements".equals(type.getId())) { + if (settings.advancements == null) { + settings.advancements = createAdvancementsSettings(); + changed = true; + } + } + + if (settings.customProfiles == null) { + settings.customProfiles = new EnumMap<>(UIElementCategory.class); + changed = true; + } + + return changed; + } + + private static EaseGUIConfig.ScreenSettings createDefaultSettingsFor(ScreenType type) { + EaseGUIConfig.ScreenSettings settings = new EaseGUIConfig.ScreenSettings(); + settings.enabled = type.isEnabledByDefault(); + + switch (type.getId()) { + case "title" -> { + settings.logo = createLogoSettings(); + settings.splash = createSplashSettings(); + } + case "advancements" -> settings.advancements = createAdvancementsSettings(); + } + + return settings; + } + + private static EaseGUIConfig.LogoSettings createLogoSettings() { + EaseGUIConfig.LogoSettings settings = new EaseGUIConfig.LogoSettings(); + settings.animateWholeText = false; + settings.logoProfile = new AnimationProfile() + .duration(400L) + .offsetY(10f) + .startScale(0.8f) + .startAlpha(0.0f) + .cascadeDelay(60L) + .cascadeDirection(LEFT_TO_RIGHT) + .easing(EASE_OUT_BACK) + .pivot(PivotPoint.CENTER); + + settings.editionProfile = new AnimationProfile() + .duration(400L) + .offsetY(5f) + .startScale(0.9f) + .startAlpha(0.0f) + .easing(EASE_OUT_QUAD) + .pivot(PivotPoint.CENTER); + return settings; + } + + private static EaseGUIConfig.SplashSettings createSplashSettings() { + EaseGUIConfig.SplashSettings settings = new EaseGUIConfig.SplashSettings(); + settings.enabled = true; + settings.splashDelay = 500L; + settings.splashDuration = 500L; + settings.splashEasing = EASE_OUT_BACK; + return settings; + } + + private static EaseGUIConfig.AdvancementsSettings createAdvancementsSettings() { + EaseGUIConfig.AdvancementsSettings settings = new EaseGUIConfig.AdvancementsSettings(); + settings.windowProfile = new AnimationProfile() + .duration(250) + .startAlpha(0.0f) + .startScale(0.8f) + .easing(EASE_OUT_CUBIC); + + settings.tabsProfile = new AnimationProfile() + .duration(400L) + .offsetX(-40f) + .startAlpha(0.0f) + .cascadeDelay(45L) + .cascadeDirection(LEFT_TO_RIGHT) + .easing(EASE_OUT_BACK); + return settings; + } + + private static AnimationProfile createButtonProfile() { + return new AnimationProfile() + .duration(400) + .offsetY(15f) + .startAlpha(0.0f) + .cascadeDelay(45L) + .cascadeDirection(BOTTOM_TO_TOP) + .easing(EASE_OUT_BACK); + } + + private static AnimationProfile createTextProfile() { + return new AnimationProfile() + .duration(300) + .startAlpha(0.0f) + .easing(LINEAR); + } + + private static AnimationProfile createScrollableProfile() { + return new AnimationProfile() + .duration(300) + .startAlpha(0.0f) + .easing(EASE_OUT_BACK); + } + + private static AnimationProfile createListEntryProfile() { + return new AnimationProfile() + .duration(350) + .offsetY(15f) + .startAlpha(0.0f) + .cascadeDelay(45L) + .easing(EASE_OUT_CUBIC); + } + + private static AnimationProfile createContainerProfile() { + return new AnimationProfile() + .duration(250) + .offsetY(20f) + .startAlpha(0.0f) + .easing(EASE_OUT_CUBIC); + } +} \ No newline at end of file From d1f34e4f5431b276a8b6bff0b00233a917e87382 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 14 Jul 2026 00:43:09 +0300 Subject: [PATCH 40/43] feat(config): implement dev API for registering custom screen animation defaults --- .../client/animator/ContainerAnimator.java | 4 +- .../client/animator/ListItemAnimator.java | 4 +- .../client/animator/WidgetAnimator.java | 4 +- .../easegui/client/config/ConfigManager.java | 4 +- .../easegui/client/config/EaseGUIConfig.java | 4 +- .../client/config/EaseGUIConfigFactory.java | 18 +++-- .../client/config/EaseGUIElementCategory.java | 81 +++++++++++++++++++ .../client/config/EaseGUIScreenRegistry.java | 68 ++++++++++++++-- .../easegui/client/config/ScreenType.java | 1 + .../client/config/UIElementCategory.java | 42 ---------- .../extension/EaseGUIWidgetExtension.java | 4 +- .../client/gui/screens/MainConfigScreen.java | 12 +-- .../screens/ScreenSpecificConfigScreen.java | 4 +- .../client/mixin/gui/AbstractWidgetMixin.java | 10 +-- 14 files changed, 180 insertions(+), 80 deletions(-) create mode 100644 common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java delete mode 100644 common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index 41fe0ea..af86251 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -9,7 +9,7 @@ import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.UIElementCategory; +import net.weyne1.easegui.client.config.EaseGUIElementCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; public class ContainerAnimator { @@ -35,7 +35,7 @@ public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { } } - var profile = ConfigManager.getProfileForCurrentContext(UIElementCategory.CONTAINERS); + var profile = ConfigManager.getProfileForCurrentContext(EaseGUIElementCategory.CONTAINERS); if (profile == null || !profile.enabled) return null; long startTime = ScreenStateTracker.getScreenOpenTime(); diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java index ee49b13..02215d6 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java @@ -6,13 +6,13 @@ import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.UIElementCategory; +import net.weyne1.easegui.client.config.EaseGUIElementCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; public class ListItemAnimator { public static AnimationScope beginRender(GuiGraphics gg, int top, int left, int width, int height) { - var profile = ConfigManager.getProfileForCurrentContext(UIElementCategory.LIST_ENTRY); + var profile = ConfigManager.getProfileForCurrentContext(EaseGUIElementCategory.LIST_ENTRY); if (profile == null || !profile.enabled) return null; long delay = getDelay(top, left, profile); diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index 28ad461..de9e19e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -8,7 +8,7 @@ import net.weyne1.easegui.client.extension.EaseGUIWidgetExtension; import net.weyne1.easegui.client.animation.*; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.UIElementCategory; +import net.weyne1.easegui.client.config.EaseGUIElementCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; /** @@ -16,7 +16,7 @@ */ public class WidgetAnimator { - public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, UIElementCategory category, AnimationState state) { + public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, EaseGUIElementCategory category, AnimationState state) { if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { return null; } diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java index b3e3f53..1841c91 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java @@ -91,8 +91,8 @@ public static EaseGUIConfig getConfig() { return currentConfig; } - public static AnimationProfile getProfileForCurrentContext(UIElementCategory category) { - if (category == null || category == UIElementCategory.UNKNOWN) return null; + public static AnimationProfile getProfileForCurrentContext(EaseGUIElementCategory category) { + if (category == null || category == EaseGUIElementCategory.UNKNOWN) return null; if (!isLoaded) load(); Screen currentScreen = Minecraft.getInstance().screen; diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java index d97198d..426c526 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java @@ -21,12 +21,12 @@ public static class GlobalSettings { public long blurDuration = 300L; public boolean blurContainers = true; public EasingType dimmingEasing = EASE_OUT_CUBIC; - public final Map elementProfiles = new EnumMap<>(UIElementCategory.class); + public final Map elementProfiles = new EnumMap<>(EaseGUIElementCategory.class); } public static class ScreenSettings { public boolean enabled = true; - public Map customProfiles = new EnumMap<>(UIElementCategory.class); + public Map customProfiles = new EnumMap<>(EaseGUIElementCategory.class); public LogoSettings logo = null; public SplashSettings splash = null; diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java index 6635e88..353aa7e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java @@ -18,11 +18,11 @@ public final class EaseGUIConfigFactory { public static EaseGUIConfig createDefaultConfig() { EaseGUIConfig config = new EaseGUIConfig(); - config.global.elementProfiles.put(UIElementCategory.BUTTON_LIKE, createButtonProfile()); - config.global.elementProfiles.put(UIElementCategory.TEXT, createTextProfile()); - config.global.elementProfiles.put(UIElementCategory.SCROLLABLE, createScrollableProfile()); - config.global.elementProfiles.put(UIElementCategory.LIST_ENTRY, createListEntryProfile()); - config.global.elementProfiles.put(UIElementCategory.CONTAINERS, createContainerProfile()); + config.global.elementProfiles.put(EaseGUIElementCategory.BUTTON_LIKE, createButtonProfile()); + config.global.elementProfiles.put(EaseGUIElementCategory.TEXT, createTextProfile()); + config.global.elementProfiles.put(EaseGUIElementCategory.SCROLLABLE, createScrollableProfile()); + config.global.elementProfiles.put(EaseGUIElementCategory.LIST_ENTRY, createListEntryProfile()); + config.global.elementProfiles.put(EaseGUIElementCategory.CONTAINERS, createContainerProfile()); for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { config.screens.put(type.getId(), createDefaultSettingsFor(type)); @@ -93,10 +93,13 @@ private static boolean patchScreenSettings(ScreenType type, EaseGUIConfig.Screen } if (settings.customProfiles == null) { - settings.customProfiles = new EnumMap<>(UIElementCategory.class); + settings.customProfiles = new EnumMap<>(EaseGUIElementCategory.class); changed = true; } + // Apply external developer animation defaults over user settings + changed |= EaseGUIScreenRegistry.patchDefaults(type.getId(), settings); + return changed; } @@ -112,6 +115,9 @@ private static EaseGUIConfig.ScreenSettings createDefaultSettingsFor(ScreenType case "advancements" -> settings.advancements = createAdvancementsSettings(); } + // Allow external mods to apply their default profile configurations on screen creation + EaseGUIScreenRegistry.configureDefaults(type.getId(), settings); + return settings; } diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java new file mode 100644 index 0000000..6664ef0 --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java @@ -0,0 +1,81 @@ +package net.weyne1.easegui.client.config; + +import net.minecraft.client.gui.components.*; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumSet; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Represents the logical category of a UI element, defining which animation features + * are permitted and how classes map to these categories. + */ +public enum EaseGUIElementCategory { + BUTTON_LIKE(EnumSet.allOf(ProfileFeature.class)), + TEXT(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), + SCROLLABLE(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA)), + LIST_ENTRY(EnumSet.allOf(ProfileFeature.class)), + CONTAINERS(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), + UNKNOWN(EnumSet.noneOf(ProfileFeature.class)); + + private static final Map, EaseGUIElementCategory> CUSTOM_MAPPINGS = new ConcurrentHashMap<>(); + + private final EnumSet allowedFeatures; + + EaseGUIElementCategory(EnumSet allowedFeatures) { + this.allowedFeatures = allowedFeatures; + } + + public EnumSet getAllowedFeatures() { + return EnumSet.copyOf(this.allowedFeatures); + } + + /** + * Registers a custom class mapping to a specific UI element category. + * This allows third-party mods with custom UI frameworks to support EaseGUI animations. + * + * @param clazz the target widget class to map + * @param category the category to assign to this class and its descendants + */ + @SuppressWarnings("unused") + public static void registerMapping(@NotNull Class clazz, @NotNull EaseGUIElementCategory category) { + CUSTOM_MAPPINGS.put(clazz, category); + } + + /** + * Resolves a UIElementCategory for a given class type. + * Evaluates custom developer mappings first, then falls back to standard vanilla rules. + * + * @param clazz the class of the active UI element + * @return the matched category, or {@link #UNKNOWN} if no match is found + */ + @NotNull + public static EaseGUIElementCategory fromClass(Class clazz) { + if (clazz == null) return UNKNOWN; + + for (Map.Entry, EaseGUIElementCategory> entry : CUSTOM_MAPPINGS.entrySet()) { + if (entry.getKey().isAssignableFrom(clazz)) { + return entry.getValue(); + } + } + + if (AbstractButton.class.isAssignableFrom(clazz) || + AbstractSliderButton.class.isAssignableFrom(clazz) || + EditBox.class.isAssignableFrom(clazz)) { + return BUTTON_LIKE; + } + if (AbstractStringWidget.class.isAssignableFrom(clazz)) { + return TEXT; + } + if (AbstractSelectionList.class.isAssignableFrom(clazz)) { + return SCROLLABLE; + } + if (AbstractContainerScreen.class.isAssignableFrom(clazz)) { + return CONTAINERS; + } + + return UNKNOWN; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java index 61f4d8f..a5b7419 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java @@ -13,10 +13,12 @@ import net.minecraft.client.gui.screens.packs.PackSelectionScreen; import net.minecraft.client.gui.screens.social.SocialInteractionsScreen; import net.minecraft.client.gui.screens.worldselection.*; +import net.weyne1.easegui.client.animation.AnimationProfile; import net.weyne1.easegui.client.gui.screens.EaseGUIAbstractSplitScreen; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; /** * Registry that maps Minecraft Screen classes to ScreenType definitions. @@ -24,21 +26,19 @@ *

This is used by EaseGUI to decide how different screens should be categorized * and animated. Matching works in two steps: *

    - *
  • Fast exact class lookup (cache)
  • - *
  • Fallback hierarchy scan using isAssignableFrom
  • + *
  • Fast exact class lookup (cache)
  • + *
  • Fallback hierarchy scan using isAssignableFrom
  • *
* - *

Mod developers can register custom screens to integrate them into animation system. + *

Mod developers can register custom screens and default animation parameters + * to integrate them into the EaseGUI animation system. */ public final class EaseGUIScreenRegistry { - /** Cache for exact class → ScreenType mapping to avoid hierarchy checks */ private static final Map, ScreenType> EXACT_MATCH_CACHE = new ConcurrentHashMap<>(); - - /** Sorted list of screen types used for inheritance-based matching */ + private static final Map> DEFAULT_CONFIGURATORS = new ConcurrentHashMap<>(); private static final List HIERARCHY_LIST = new ArrayList<>(); - /** Fallback type used when no match is found */ public static final ScreenType OTHER = new ScreenType("other", Screen.class, Integer.MIN_VALUE, ScreenGroup.OTHER, false); static { @@ -114,6 +114,60 @@ public final class EaseGUIScreenRegistry { } } + /** + * Registers a custom configurator callback for a specific screen ID. + * This is intended for third-party developers to populate custom default configurations. + * + * @param id the unique screen ID (e.g. "mymod:grinder") + * @param configurator the consumer that configures the default {@link EaseGUIConfig.ScreenSettings} + */ + @SuppressWarnings("unused") + public static void registerConfigurator(String id, Consumer configurator) { + DEFAULT_CONFIGURATORS.put(id, configurator); + } + + /** + * Configures the screen settings with registered developer defaults. + * Primarily called by the config factory during clean setup initialization. + * + * @param id the screen identifier + * @param settings the target settings to configure + */ + public static void configureDefaults(String id, EaseGUIConfig.ScreenSettings settings) { + Consumer configurator = DEFAULT_CONFIGURATORS.get(id); + if (configurator != null) { + configurator.accept(settings); + } + } + + /** + * Patches the existing screen settings with newly introduced developer defaults. + * Ensures that new categories or default entries are added safely without + * overwriting any manual modifications made by the user in the config file. + * + * @param id the screen identifier + * @param settings the user's existing settings + * @return true if the settings were modified and need to be saved + */ + public static boolean patchDefaults(String id, EaseGUIConfig.ScreenSettings settings) { + Consumer configurator = DEFAULT_CONFIGURATORS.get(id); + if (configurator == null) return false; + + EaseGUIConfig.ScreenSettings defaultSettings = new EaseGUIConfig.ScreenSettings(); + configurator.accept(defaultSettings); + + boolean changed = false; + + for (Map.Entry entry : defaultSettings.customProfiles.entrySet()) { + if (!settings.customProfiles.containsKey(entry.getKey())) { + settings.customProfiles.put(entry.getKey(), entry.getValue()); + changed = true; + } + } + + return changed; + } + /** * Registers a screen type with default enabled state (true). */ diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java b/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java index 4c12e7d..fd9592a 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java @@ -59,6 +59,7 @@ public ScreenType( /** * Creates a screen type enabled by default. */ + @SuppressWarnings("unused") public ScreenType( String id, Class screenClass, diff --git a/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java b/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java deleted file mode 100644 index cf00245..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/config/UIElementCategory.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.weyne1.easegui.client.config; - -import net.minecraft.client.gui.components.*; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import org.jetbrains.annotations.NotNull; - -import java.util.EnumSet; - -public enum UIElementCategory { - BUTTON_LIKE(EnumSet.allOf(ProfileFeature.class)), - TEXT(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), - SCROLLABLE(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA)), - LIST_ENTRY(EnumSet.allOf(ProfileFeature.class)), - CONTAINERS(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), - UNKNOWN(EnumSet.noneOf(ProfileFeature.class)); - - private final EnumSet allowedFeatures; - - UIElementCategory(EnumSet allowedFeatures) { - this.allowedFeatures = allowedFeatures; - } - - public EnumSet getAllowedFeatures() { - return EnumSet.copyOf(this.allowedFeatures); - } - - @NotNull public static UIElementCategory fromClass(Class clazz) { - if (AbstractButton.class.isAssignableFrom(clazz) || AbstractSliderButton.class.isAssignableFrom(clazz) || EditBox.class.isAssignableFrom(clazz)) { - return BUTTON_LIKE; - } - if (AbstractStringWidget.class.isAssignableFrom(clazz)) { - return TEXT; - } - if (AbstractSelectionList.class.isAssignableFrom(clazz)) { - return SCROLLABLE; - } - if (AbstractContainerScreen.class.isAssignableFrom(clazz)) { - return CONTAINERS; - } - return UNKNOWN; - } -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java index a6e68a9..1d95f81 100644 --- a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java @@ -1,9 +1,9 @@ package net.weyne1.easegui.client.extension; -import net.weyne1.easegui.client.config.UIElementCategory; +import net.weyne1.easegui.client.config.EaseGUIElementCategory; public interface EaseGUIWidgetExtension { - UIElementCategory easeGUI$getCategory(); + EaseGUIElementCategory easeGUI$getCategory(); float easeGUI$getAlpha(); } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java index c7c8c92..970f2cd 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java @@ -77,11 +77,11 @@ protected void initScreen() { leftList.addHeader(Component.translatable("easegui.config.title.elements").getString()); - addGlobalProfileButton(leftList, config, mc, UIElementCategory.BUTTON_LIKE, "easegui.main.button.button_like"); - addGlobalProfileButton(leftList, config, mc, UIElementCategory.TEXT, "easegui.main.button.text"); - addGlobalProfileButton(leftList, config, mc, UIElementCategory.SCROLLABLE, "easegui.main.button.scrollable"); - addGlobalProfileButton(leftList, config, mc, UIElementCategory.LIST_ENTRY, "easegui.main.button.list_entry"); - addGlobalProfileButton(leftList, config, mc, UIElementCategory.CONTAINERS, "easegui.main.button.containers"); + addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.BUTTON_LIKE, "easegui.main.button.button_like"); + addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.TEXT, "easegui.main.button.text"); + addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.SCROLLABLE, "easegui.main.button.scrollable"); + addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.LIST_ENTRY, "easegui.main.button.list_entry"); + addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.CONTAINERS, "easegui.main.button.containers"); this.addRenderableWidget(leftList); @@ -124,7 +124,7 @@ protected void initScreen() { ).bounds(halfWidth - 100, this.height - 30, 200, 20).build()); } - private void addGlobalProfileButton(SettingsScrollList list, EaseGUIConfig config, Minecraft mc, UIElementCategory category, String translationKey) { + private void addGlobalProfileButton(SettingsScrollList list, EaseGUIConfig config, Minecraft mc, EaseGUIElementCategory category, String translationKey) { AnimationProfile cleanDefault = new EaseGUIConfig().global.elementProfiles.get(category); if (cleanDefault == null) cleanDefault = new AnimationProfile(); AnimationProfile finalCleanDefault = cleanDefault; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java index 778aa81..913d684 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java @@ -107,9 +107,9 @@ protected void initScreen() { } private void setupCategoryButtons(SettingsScrollList rightScrollList, EaseGUIConfig.ScreenSettings settings, EaseGUIConfig config) { - EnumSet overridableCategories = EnumSet.complementOf(EnumSet.of(UIElementCategory.UNKNOWN)); + EnumSet overridableCategories = EnumSet.complementOf(EnumSet.of(EaseGUIElementCategory.UNKNOWN)); - for (UIElementCategory category : overridableCategories) { + for (EaseGUIElementCategory category : overridableCategories) { boolean hasCustom = settings.customProfiles.containsKey(category); Component categoryLabel = Component.translatable("easegui.category." + category.name().toLowerCase()); diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index d3d7e48..c89b9ec 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -10,7 +10,7 @@ import net.weyne1.easegui.client.animation.AnimationState; import net.weyne1.easegui.client.animator.WidgetAnimator; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.UIElementCategory; +import net.weyne1.easegui.client.config.EaseGUIElementCategory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -22,7 +22,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { @Shadow protected boolean isHovered; @Unique private final AnimationState easeGUI$animationState = new AnimationState(); - @Unique private UIElementCategory easeGUI$cachedCategory = null; + @Unique private EaseGUIElementCategory easeGUI$cachedCategory = null; @Override public float easeGUI$getAlpha() { @@ -30,9 +30,9 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { } @Override - public UIElementCategory easeGUI$getCategory() { + public EaseGUIElementCategory easeGUI$getCategory() { if (this.easeGUI$cachedCategory == null) { - this.easeGUI$cachedCategory = UIElementCategory.fromClass(this.getClass()); + this.easeGUI$cachedCategory = EaseGUIElementCategory.fromClass(this.getClass()); } return this.easeGUI$cachedCategory; } @@ -47,7 +47,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { } var category = this.easeGUI$getCategory(); - if (category == null || category == UIElementCategory.UNKNOWN) { + if (category == null || category == EaseGUIElementCategory.UNKNOWN) { original.call(guiGraphics, mouseX, mouseY, partialTick); return; } From 538cc3dd50402497bf3ee62982568f577ea529b8 Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 14 Jul 2026 01:31:15 +0300 Subject: [PATCH 41/43] ref: moving API classes to a separate package --- .../EaseGUIScreenGroup.java} | 6 +- .../config => api}/EaseGUIScreenRegistry.java | 137 +++++++------- .../EaseGUIScreenType.java} | 16 +- .../WidgetCategory.java} | 15 +- .../api/animation/AnimationProfile.java | 177 ++++++++++++++++++ .../animation/CascadeDirection.java | 2 +- .../{client => api}/animation/EasingType.java | 4 +- .../{client => api}/animation/PivotPoint.java | 2 +- .../client/animation/AnimationMath.java | 2 + .../client/animation/AnimationProfile.java | 91 --------- .../client/animation/AnimationSystem.java | 19 +- .../client/animator/AdvancementsAnimator.java | 22 +-- .../client/animator/BackgroundAnimator.java | 6 +- .../client/animator/ContainerAnimator.java | 6 +- .../client/animator/ListItemAnimator.java | 12 +- .../easegui/client/animator/LogoAnimator.java | 28 +-- .../client/animator/WidgetAnimator.java | 17 +- .../easegui/client/config/ConfigManager.java | 13 +- .../easegui/client/config/EaseGUIConfig.java | 11 +- .../client/config/EaseGUIConfigFactory.java | 33 ++-- .../extension/EaseGUIWidgetExtension.java | 9 - ...iItemExtension.java => ItemExtension.java} | 2 +- .../client/extension/WidgetExtension.java | 9 + .../AdvancementsScreenConfigurator.java | 2 +- .../configurator/TitleScreenConfigurator.java | 4 +- .../gui/preview/ProfilePreviewRenderer.java | 26 +-- .../client/gui/screens/MainConfigScreen.java | 24 ++- .../gui/screens/ProfileEditorScreen.java | 64 +++---- .../screens/ScreenSpecificConfigScreen.java | 30 +-- .../client/mixin/gui/AbstractWidgetMixin.java | 18 +- .../mixin/gui/GuiItemRenderStateMixin.java | 4 +- .../client/mixin/gui/GuiRendererMixin.java | 4 +- .../animation/AnimationMathUtilsTest.java | 1 + 33 files changed, 463 insertions(+), 353 deletions(-) rename common/src/main/java/net/weyne1/easegui/{client/config/ScreenGroup.java => api/EaseGUIScreenGroup.java} (77%) rename common/src/main/java/net/weyne1/easegui/{client/config => api}/EaseGUIScreenRegistry.java (63%) rename common/src/main/java/net/weyne1/easegui/{client/config/ScreenType.java => api/EaseGUIScreenType.java} (88%) rename common/src/main/java/net/weyne1/easegui/{client/config/EaseGUIElementCategory.java => api/WidgetCategory.java} (85%) create mode 100644 common/src/main/java/net/weyne1/easegui/api/animation/AnimationProfile.java rename common/src/main/java/net/weyne1/easegui/{client => api}/animation/CascadeDirection.java (70%) rename common/src/main/java/net/weyne1/easegui/{client => api}/animation/EasingType.java (94%) rename common/src/main/java/net/weyne1/easegui/{client => api}/animation/PivotPoint.java (93%) delete mode 100644 common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java delete mode 100644 common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java rename common/src/main/java/net/weyne1/easegui/client/extension/{EaseGuiItemExtension.java => ItemExtension.java} (65%) create mode 100644 common/src/main/java/net/weyne1/easegui/client/extension/WidgetExtension.java diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ScreenGroup.java b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenGroup.java similarity index 77% rename from common/src/main/java/net/weyne1/easegui/client/config/ScreenGroup.java rename to common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenGroup.java index 26963b7..b32afbd 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ScreenGroup.java +++ b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenGroup.java @@ -1,6 +1,6 @@ -package net.weyne1.easegui.client.config; +package net.weyne1.easegui.api; -public enum ScreenGroup { +public enum EaseGUIScreenGroup { BASIC("easegui.screen_group.basic"), EDITORS("easegui.screen_group.editors"), WORLDS("easegui.screen_group.worlds"), @@ -9,7 +9,7 @@ public enum ScreenGroup { private final String translationKey; - ScreenGroup(String translationKey) { + EaseGUIScreenGroup(String translationKey) { this.translationKey = translationKey; } diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenRegistry.java similarity index 63% rename from common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java rename to common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenRegistry.java index a5b7419..86d07f5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIScreenRegistry.java +++ b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenRegistry.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client.config; +package net.weyne1.easegui.api; import com.mojang.realmsclient.RealmsMainScreen; import net.minecraft.client.gui.screens.*; @@ -13,7 +13,8 @@ import net.minecraft.client.gui.screens.packs.PackSelectionScreen; import net.minecraft.client.gui.screens.social.SocialInteractionsScreen; import net.minecraft.client.gui.screens.worldselection.*; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; +import net.weyne1.easegui.client.config.EaseGUIConfig; import net.weyne1.easegui.client.gui.screens.EaseGUIAbstractSplitScreen; import java.util.*; @@ -35,80 +36,80 @@ */ public final class EaseGUIScreenRegistry { - private static final Map, ScreenType> EXACT_MATCH_CACHE = new ConcurrentHashMap<>(); + private static final Map, EaseGUIScreenType> EXACT_MATCH_CACHE = new ConcurrentHashMap<>(); private static final Map> DEFAULT_CONFIGURATORS = new ConcurrentHashMap<>(); - private static final List HIERARCHY_LIST = new ArrayList<>(); + private static final List HIERARCHY_LIST = new ArrayList<>(); - public static final ScreenType OTHER = new ScreenType("other", Screen.class, Integer.MIN_VALUE, ScreenGroup.OTHER, false); + public static final EaseGUIScreenType OTHER = new EaseGUIScreenType("other", Screen.class, Integer.MIN_VALUE, EaseGUIScreenGroup.OTHER, false); static { // Vanilla UI screens - register("title", TitleScreen.class, 1000, ScreenGroup.BASIC); - register("options", OptionsScreen.class, 1000, ScreenGroup.BASIC); - register("options_sub", OptionsSubScreen.class, 1000, ScreenGroup.BASIC); - register("pack_selection", PackSelectionScreen.class, 1000, ScreenGroup.BASIC); - register("advancements", AdvancementsScreen.class, 1000, ScreenGroup.BASIC); - register("statistics", StatsScreen.class, 1000, ScreenGroup.BASIC); - register("warning", WarningScreen.class, 1000, ScreenGroup.BASIC); - register("pause", PauseScreen.class, 1000, ScreenGroup.BASIC); - register("share_to_lan", ShareToLanScreen.class, 1000, ScreenGroup.BASIC); - register("death", DeathScreen.class, 1000, ScreenGroup.BASIC); - register("social_interactions", SocialInteractionsScreen.class, 1000, ScreenGroup.BASIC); + register("title", TitleScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("options", OptionsScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("options_sub", OptionsSubScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("pack_selection", PackSelectionScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("advancements", AdvancementsScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("statistics", StatsScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("warning", WarningScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("pause", PauseScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("share_to_lan", ShareToLanScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("death", DeathScreen.class, 1000, EaseGUIScreenGroup.BASIC); + register("social_interactions", SocialInteractionsScreen.class, 1000, EaseGUIScreenGroup.BASIC); // Editors - register("sign_edit", AbstractSignEditScreen.class, 1000, ScreenGroup.EDITORS); - register("book_edit", BookEditScreen.class, 1000, ScreenGroup.EDITORS); - register("book_view", BookViewScreen.class, 1000, ScreenGroup.EDITORS); - register("command_block_edit", AbstractCommandBlockEditScreen.class, 1000, ScreenGroup.EDITORS); - register("structure_block_edit", StructureBlockEditScreen.class, 1000, ScreenGroup.EDITORS); - register("jigsaw_block_edit", JigsawBlockEditScreen.class, 1000, ScreenGroup.EDITORS); + register("sign_edit", AbstractSignEditScreen.class, 1000, EaseGUIScreenGroup.EDITORS); + register("book_edit", BookEditScreen.class, 1000, EaseGUIScreenGroup.EDITORS); + register("book_view", BookViewScreen.class, 1000, EaseGUIScreenGroup.EDITORS); + register("command_block_edit", AbstractCommandBlockEditScreen.class, 1000, EaseGUIScreenGroup.EDITORS); + register("structure_block_edit", StructureBlockEditScreen.class, 1000, EaseGUIScreenGroup.EDITORS); + register("jigsaw_block_edit", JigsawBlockEditScreen.class, 1000, EaseGUIScreenGroup.EDITORS); // World / multiplayer menus - register("world_selection", SelectWorldScreen.class, 1000, ScreenGroup.WORLDS); - register("server_selection", JoinMultiplayerScreen.class, 1000, ScreenGroup.WORLDS); - register("realms_main", RealmsMainScreen.class, 1000, ScreenGroup.WORLDS); - register("create_world", CreateWorldScreen.class, 1000, ScreenGroup.WORLDS); - register("create_flat_world", CreateFlatWorldScreen.class, 1000, ScreenGroup.WORLDS); - register("direct_join_server", DirectJoinServerScreen.class, 1000, ScreenGroup.WORLDS); - register("edit_world", EditWorldScreen.class, 1000, ScreenGroup.WORLDS); - register("edit_server", ManageServerScreen.class, 1000, ScreenGroup.WORLDS); - register("edit_game_rules", EditGameRulesScreen.class, 1000, ScreenGroup.WORLDS); - register("experiments", ExperimentsScreen.class, 1000, ScreenGroup.WORLDS); - register("connecting", ConnectScreen.class, 1000, ScreenGroup.WORLDS); - register("disconnected", DisconnectedScreen.class, 1000, ScreenGroup.WORLDS); - register("server_reconfig", ServerReconfigScreen.class, 1000, ScreenGroup.WORLDS); - register("credits", CreditsAndAttributionScreen.class, 1000, ScreenGroup.WORLDS); + register("world_selection", SelectWorldScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("server_selection", JoinMultiplayerScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("realms_main", RealmsMainScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("create_world", CreateWorldScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("create_flat_world", CreateFlatWorldScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("direct_join_server", DirectJoinServerScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("edit_world", EditWorldScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("edit_server", ManageServerScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("edit_game_rules", EditGameRulesScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("experiments", ExperimentsScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("connecting", ConnectScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("disconnected", DisconnectedScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("server_reconfig", ServerReconfigScreen.class, 1000, EaseGUIScreenGroup.WORLDS); + register("credits", CreditsAndAttributionScreen.class, 1000, EaseGUIScreenGroup.WORLDS); // Containers / inventories - register("creative_inventory", CreativeModeInventoryScreen.class, 500, ScreenGroup.CONTAINERS); - register("survival_inventory", InventoryScreen.class, 500, ScreenGroup.CONTAINERS); - register("anvil", AnvilScreen.class, 500, ScreenGroup.CONTAINERS); - register("enchanting_table", EnchantmentScreen.class, 500, ScreenGroup.CONTAINERS); - register("container", ContainerScreen.class, 500, ScreenGroup.CONTAINERS); - register("smithing", SmithingScreen.class, 500, ScreenGroup.CONTAINERS); - register("dispenser", DispenserScreen.class, 500, ScreenGroup.CONTAINERS); - register("beacon", BeaconScreen.class, 500, ScreenGroup.CONTAINERS); - register("crafter", CrafterScreen.class, 500, ScreenGroup.CONTAINERS); - register("crafting", CraftingScreen.class, 500, ScreenGroup.CONTAINERS); - register("brewing_stand", BrewingStandScreen.class, 500, ScreenGroup.CONTAINERS); - register("cartography_table", CartographyTableScreen.class, 500, ScreenGroup.CONTAINERS); - register("furnace", AbstractFurnaceScreen.class, 500, ScreenGroup.CONTAINERS); - register("grindstone", GrindstoneScreen.class, 500, ScreenGroup.CONTAINERS); - register("hopper", HopperScreen.class, 500, ScreenGroup.CONTAINERS); - register("horse_inventory", HorseInventoryScreen.class, 500, ScreenGroup.CONTAINERS); - register("lectern", LecternScreen.class, 500, ScreenGroup.CONTAINERS); - register("loom", LoomScreen.class, 500, ScreenGroup.CONTAINERS); - register("shulker_box", ShulkerBoxScreen.class, 500, ScreenGroup.CONTAINERS); - register("stonecutter", StonecutterScreen.class, 500, ScreenGroup.CONTAINERS); - register("other_containers", AbstractContainerScreen.class, 100, ScreenGroup.CONTAINERS); + register("creative_inventory", CreativeModeInventoryScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("survival_inventory", InventoryScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("anvil", AnvilScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("enchanting_table", EnchantmentScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("container", ContainerScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("smithing", SmithingScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("dispenser", DispenserScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("beacon", BeaconScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("crafter", CrafterScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("crafting", CraftingScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("brewing_stand", BrewingStandScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("cartography_table", CartographyTableScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("furnace", AbstractFurnaceScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("grindstone", GrindstoneScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("hopper", HopperScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("horse_inventory", HorseInventoryScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("lectern", LecternScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("loom", LoomScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("shulker_box", ShulkerBoxScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("stonecutter", StonecutterScreen.class, 500, EaseGUIScreenGroup.CONTAINERS); + register("other_containers", AbstractContainerScreen.class, 100, EaseGUIScreenGroup.CONTAINERS); // Internal config UI - register("ease_gui_config", EaseGUIAbstractSplitScreen.class, 100, ScreenGroup.OTHER); + register("ease_gui_config", EaseGUIAbstractSplitScreen.class, 100, EaseGUIScreenGroup.OTHER); // Optional mod integration (Mod Menu) try { Class modMenuScreenClass = Class.forName("com.terraformersmc.modmenu.gui.ModsScreen"); - register("modmenu", modMenuScreenClass.asSubclass(Screen.class), 1000, ScreenGroup.BASIC, false); + register("modmenu", modMenuScreenClass.asSubclass(Screen.class), 1000, EaseGUIScreenGroup.BASIC, false); } catch (ClassNotFoundException ignored) { // Mod Menu is not installed — safely skip registration } @@ -158,7 +159,7 @@ public static boolean patchDefaults(String id, EaseGUIConfig.ScreenSettings sett boolean changed = false; - for (Map.Entry entry : defaultSettings.customProfiles.entrySet()) { + for (Map.Entry entry : defaultSettings.customProfiles.entrySet()) { if (!settings.customProfiles.containsKey(entry.getKey())) { settings.customProfiles.put(entry.getKey(), entry.getValue()); changed = true; @@ -175,7 +176,7 @@ public static synchronized void register( String id, Class screenClass, int priority, - ScreenGroup category + EaseGUIScreenGroup category ) { register(id, screenClass, priority, category, true); } @@ -193,16 +194,16 @@ public static synchronized void register( String id, Class screenClass, int priority, - ScreenGroup category, + EaseGUIScreenGroup category, boolean enabledByDefault ) { - ScreenType type = new ScreenType(id, screenClass, priority, category, enabledByDefault); + EaseGUIScreenType type = new EaseGUIScreenType(id, screenClass, priority, category, enabledByDefault); EXACT_MATCH_CACHE.put(screenClass, type); HIERARCHY_LIST.removeIf(t -> t.getId().equals(id)); HIERARCHY_LIST.add(type); - HIERARCHY_LIST.sort(Comparator.comparingInt(ScreenType::getPriority).reversed()); + HIERARCHY_LIST.sort(Comparator.comparingInt(EaseGUIScreenType::getPriority).reversed()); } /** @@ -215,15 +216,15 @@ public static synchronized void register( *

  • Fallback to OTHER
  • * */ - public static ScreenType from(Screen screen) { + public static EaseGUIScreenType from(Screen screen) { if (screen == null) return OTHER; Class screenClass = screen.getClass(); - ScreenType exact = EXACT_MATCH_CACHE.get(screenClass); + EaseGUIScreenType exact = EXACT_MATCH_CACHE.get(screenClass); if (exact != null) return exact; - for (ScreenType type : HIERARCHY_LIST) { + for (EaseGUIScreenType type : HIERARCHY_LIST) { if (type.getScreenClass().isAssignableFrom(screenClass)) { EXACT_MATCH_CACHE.put(screenClass, type); return type; @@ -236,7 +237,7 @@ public static ScreenType from(Screen screen) { /** * Returns all registered screen types (read-only view). */ - public static Collection getRegisteredTypes() { + public static Collection getRegisteredTypes() { return Collections.unmodifiableList(HIERARCHY_LIST); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenType.java similarity index 88% rename from common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java rename to common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenType.java index fd9592a..346bf9b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ScreenType.java +++ b/common/src/main/java/net/weyne1/easegui/api/EaseGUIScreenType.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client.config; +package net.weyne1.easegui.api; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -17,13 +17,13 @@ *
  • UI grouping
  • * */ -public final class ScreenType { +public final class EaseGUIScreenType { private final String id; private final Class screenClass; private final String translationKey; private final int priority; - private final ScreenGroup group; + private final EaseGUIScreenGroup group; private final boolean enabledByDefault; /** @@ -35,11 +35,11 @@ public final class ScreenType { *
  • "modid:screen" → "modid.screen_type.screen"
  • * */ - public ScreenType( + public EaseGUIScreenType( String id, Class screenClass, int priority, - ScreenGroup group, + EaseGUIScreenGroup group, boolean enabledByDefault ) { this.id = id; @@ -60,11 +60,11 @@ public ScreenType( * Creates a screen type enabled by default. */ @SuppressWarnings("unused") - public ScreenType( + public EaseGUIScreenType( String id, Class screenClass, int priority, - ScreenGroup group + EaseGUIScreenGroup group ) { this(id, screenClass, priority, group, true); } @@ -81,7 +81,7 @@ public int getPriority() { return priority; } - public ScreenGroup getGroup() { + public EaseGUIScreenGroup getGroup() { return group; } diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java b/common/src/main/java/net/weyne1/easegui/api/WidgetCategory.java similarity index 85% rename from common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java rename to common/src/main/java/net/weyne1/easegui/api/WidgetCategory.java index 6664ef0..d1f4309 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIElementCategory.java +++ b/common/src/main/java/net/weyne1/easegui/api/WidgetCategory.java @@ -1,7 +1,8 @@ -package net.weyne1.easegui.client.config; +package net.weyne1.easegui.api; import net.minecraft.client.gui.components.*; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.weyne1.easegui.client.config.ProfileFeature; import org.jetbrains.annotations.NotNull; import java.util.EnumSet; @@ -12,7 +13,7 @@ * Represents the logical category of a UI element, defining which animation features * are permitted and how classes map to these categories. */ -public enum EaseGUIElementCategory { +public enum WidgetCategory { BUTTON_LIKE(EnumSet.allOf(ProfileFeature.class)), TEXT(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), SCROLLABLE(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA)), @@ -20,11 +21,11 @@ public enum EaseGUIElementCategory { CONTAINERS(EnumSet.of(ProfileFeature.OFFSET, ProfileFeature.SCALE, ProfileFeature.ALPHA, ProfileFeature.PIVOT)), UNKNOWN(EnumSet.noneOf(ProfileFeature.class)); - private static final Map, EaseGUIElementCategory> CUSTOM_MAPPINGS = new ConcurrentHashMap<>(); + private static final Map, WidgetCategory> CUSTOM_MAPPINGS = new ConcurrentHashMap<>(); private final EnumSet allowedFeatures; - EaseGUIElementCategory(EnumSet allowedFeatures) { + WidgetCategory(EnumSet allowedFeatures) { this.allowedFeatures = allowedFeatures; } @@ -40,7 +41,7 @@ public EnumSet getAllowedFeatures() { * @param category the category to assign to this class and its descendants */ @SuppressWarnings("unused") - public static void registerMapping(@NotNull Class clazz, @NotNull EaseGUIElementCategory category) { + public static void registerMapping(@NotNull Class clazz, @NotNull WidgetCategory category) { CUSTOM_MAPPINGS.put(clazz, category); } @@ -52,10 +53,10 @@ public static void registerMapping(@NotNull Class clazz, @NotNull EaseGUIElem * @return the matched category, or {@link #UNKNOWN} if no match is found */ @NotNull - public static EaseGUIElementCategory fromClass(Class clazz) { + public static WidgetCategory fromClass(Class clazz) { if (clazz == null) return UNKNOWN; - for (Map.Entry, EaseGUIElementCategory> entry : CUSTOM_MAPPINGS.entrySet()) { + for (Map.Entry, WidgetCategory> entry : CUSTOM_MAPPINGS.entrySet()) { if (entry.getKey().isAssignableFrom(clazz)) { return entry.getValue(); } diff --git a/common/src/main/java/net/weyne1/easegui/api/animation/AnimationProfile.java b/common/src/main/java/net/weyne1/easegui/api/animation/AnimationProfile.java new file mode 100644 index 0000000..a0da75d --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/api/animation/AnimationProfile.java @@ -0,0 +1,177 @@ +package net.weyne1.easegui.api.animation; + +import org.joml.Vector2f; + +/** + * Configuration profile holding animation properties and fluent builder methods. + */ +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class AnimationProfile { + + private boolean enabled = true; + private long duration = 400; + private final Vector2f offset = new Vector2f(); + private final Vector2f startScale = new Vector2f(1f, 1f); + private float startAlpha = 0.0f; + private long cascadeDelay = 0L; + + private PivotPoint pivot = PivotPoint.CENTER; + private EasingType easing = EasingType.EASE_OUT_QUAD; + private CascadeDirection cascadeDirection = CascadeDirection.TOP_TO_BOTTOM; + + public boolean isEnabled() { + return enabled; + } + + public long getDuration() { + return duration; + } + + public float getOffsetX() { + return offset.x; + } + + public float getOffsetY() { + return offset.y; + } + + public float getStartScaleX() { + return startScale.x; + } + + public float getStartScaleY() { + return startScale.y; + } + + public float getStartAlpha() { + return startAlpha; + } + + public long getCascadeDelay() { + return cascadeDelay; + } + + public PivotPoint getPivot() { + return pivot; + } + + public EasingType getEasing() { + return easing; + } + + public CascadeDirection getCascadeDirection() { + return cascadeDirection; + } + + public AnimationProfile enabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + public AnimationProfile duration(long duration) { + if (duration < 0) { + throw new IllegalArgumentException("Duration must be non-negative."); + } + + this.duration = duration; + return this; + } + + public AnimationProfile offset(float x, float y) { + this.offset.set(x, y); + return this; + } + + public AnimationProfile offsetX(float x) { + this.offset.x = x; + return this; + } + + public AnimationProfile offsetY(float y) { + this.offset.y = y; + return this; + } + + public AnimationProfile startAlpha(float startAlpha) { + if (startAlpha < 0.0f || startAlpha > 1.0f) { + throw new IllegalArgumentException("Start alpha must be between 0.0 and 1.0."); + } + + this.startAlpha = startAlpha; + return this; + } + + public AnimationProfile startScale(float x, float y) { + this.startScale.set(x, y); + return this; + } + + public AnimationProfile startScale(float scale) { + return startScale(scale, scale); + } + + public AnimationProfile startScaleX(float x) { + this.startScale.x = x; + return this; + } + + public AnimationProfile startScaleY(float y) { + this.startScale.y = y; + return this; + } + + public AnimationProfile cascadeDelay(long cascadeDelay) { + if (cascadeDelay < 0) { + throw new IllegalArgumentException("Cascade delay must be non-negative."); + } + + this.cascadeDelay = cascadeDelay; + return this; + } + + public AnimationProfile pivot(PivotPoint pivot) { + if (pivot == null) { + throw new NullPointerException("Pivot point cannot be null."); + } + + this.pivot = pivot; + return this; + } + + public AnimationProfile easing(EasingType easing) { + if (easing == null) { + throw new NullPointerException("Easing type cannot be null."); + } + + this.easing = easing; + return this; + } + + public AnimationProfile cascadeDirection(CascadeDirection cascadeDirection) { + if (cascadeDirection == null) { + throw new NullPointerException("Cascade direction cannot be null."); + } + + this.cascadeDirection = cascadeDirection; + return this; + } + + /** + * Creates a deep copy of this animation profile. + */ + public AnimationProfile copy() { + AnimationProfile copy = new AnimationProfile(); + + copy.enabled = this.enabled; + copy.duration = this.duration; + copy.offset.set(this.offset); + copy.startScale.set(this.startScale); + copy.startAlpha = this.startAlpha; + copy.cascadeDelay = this.cascadeDelay; + copy.pivot = this.pivot; + copy.easing = this.easing; + copy.cascadeDirection = this.cascadeDirection; + + return copy; + } +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java b/common/src/main/java/net/weyne1/easegui/api/animation/CascadeDirection.java similarity index 70% rename from common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java rename to common/src/main/java/net/weyne1/easegui/api/animation/CascadeDirection.java index 8f3a166..ba8a36c 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/CascadeDirection.java +++ b/common/src/main/java/net/weyne1/easegui/api/animation/CascadeDirection.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client.animation; +package net.weyne1.easegui.api.animation; public enum CascadeDirection { TOP_TO_BOTTOM, diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java b/common/src/main/java/net/weyne1/easegui/api/animation/EasingType.java similarity index 94% rename from common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java rename to common/src/main/java/net/weyne1/easegui/api/animation/EasingType.java index 70100ab..8c465f1 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/EasingType.java +++ b/common/src/main/java/net/weyne1/easegui/api/animation/EasingType.java @@ -1,4 +1,6 @@ -package net.weyne1.easegui.client.animation; +package net.weyne1.easegui.api.animation; + +import net.weyne1.easegui.client.animation.EasingFunction; public enum EasingType { LINEAR(t -> t), diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java b/common/src/main/java/net/weyne1/easegui/api/animation/PivotPoint.java similarity index 93% rename from common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java rename to common/src/main/java/net/weyne1/easegui/api/animation/PivotPoint.java index ca176d2..7958764 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/PivotPoint.java +++ b/common/src/main/java/net/weyne1/easegui/api/animation/PivotPoint.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.client.animation; +package net.weyne1.easegui.api.animation; public enum PivotPoint { TOP_LEFT(0.0f, 0.0f), diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java index 3958413..6ad3b46 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationMath.java @@ -1,5 +1,7 @@ package net.weyne1.easegui.client.animation; +import net.weyne1.easegui.api.animation.EasingType; + public final class AnimationMath { private AnimationMath() { } diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java deleted file mode 100644 index 1e02a20..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationProfile.java +++ /dev/null @@ -1,91 +0,0 @@ -package net.weyne1.easegui.client.animation; - -import org.joml.Vector2f; - -/** - * Configuration profile holding animation properties and fluent builder methods. - */ -@SuppressWarnings("UnusedReturnValue") -public class AnimationProfile { - - public boolean enabled = true; - public long duration = 400; - public final Vector2f offset = new Vector2f(0f, 0f); - public final Vector2f startScale = new Vector2f(1f, 1f); - public float startAlpha = 0.0f; - public long cascadeDelay = 0L; - - public PivotPoint pivot = PivotPoint.CENTER; - public EasingType easing = EasingType.EASE_OUT_QUAD; - public CascadeDirection cascadeDirection = CascadeDirection.TOP_TO_BOTTOM; - - public AnimationProfile enabled(boolean enabled) { - this.enabled = enabled; - return this; - } - - public AnimationProfile duration(long duration) { - this.duration = duration; - return this; - } - - public AnimationProfile offset(float x, float y) { - this.offset.set(x, y); - return this; - } - - public AnimationProfile offsetX(float x) { - this.offset.x = x; - return this; - } - - public AnimationProfile offsetY(float y) { - this.offset.y = y; - return this; - } - - public AnimationProfile startAlpha(float startAlpha) { - this.startAlpha = startAlpha; - return this; - } - - public AnimationProfile startScale(float x, float y) { - this.startScale.set(x, y); - return this; - } - - public AnimationProfile startScale(float scale) { - this.startScale.set(scale, scale); - return this; - } - - public AnimationProfile startScaleX(float x) { - this.startScale.x = x; - return this; - } - - public AnimationProfile startScaleY(float y) { - this.startScale.y = y; - return this; - } - - public AnimationProfile cascadeDelay(long cascadeDelay) { - this.cascadeDelay = cascadeDelay; - return this; - } - - public AnimationProfile pivot(PivotPoint pivot) { - this.pivot = pivot; - return this; - } - - public AnimationProfile easing(EasingType easing) { - this.easing = easing; - return this; - } - - public AnimationProfile cascadeDirection(CascadeDirection cascadeDirection) { - this.cascadeDirection = cascadeDirection; - return this; - } -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java index 830b9e7..317da5b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java +++ b/common/src/main/java/net/weyne1/easegui/client/animation/AnimationSystem.java @@ -2,6 +2,7 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.util.Util; +import net.weyne1.easegui.api.animation.AnimationProfile; public final class AnimationSystem { @@ -18,11 +19,11 @@ public static AnimationScope begin( ) { long elapsed = Util.getMillis() - startTime - delay; - if (elapsed >= profile.duration) { + if (elapsed >= profile.getDuration()) { return null; } - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); return begin(gg, x, y, width, height, profile, progress, baseAlpha); } @@ -35,17 +36,17 @@ public static AnimationScope begin( float baseAlpha ) { float alphaProgress = AnimationMath.clamp(progress, 0.0f, 1.0f); - float lerpedAlpha = AnimationMath.lerp(profile.startAlpha, 1.0f, alphaProgress); + float lerpedAlpha = AnimationMath.lerp(profile.getStartAlpha(), 1.0f, alphaProgress); float finalAlpha = AnimationMath.clamp(baseAlpha * lerpedAlpha, 0.0f, 1.0f); AnimationScope scope = new AnimationScope(gg, finalAlpha); scope.setTransformParams( - AnimationMath.calculateCurrentOffset(profile.offset.x, progress), - AnimationMath.calculateCurrentOffset(profile.offset.y, progress), - AnimationMath.lerp(profile.startScale.x, 1.0f, progress), - AnimationMath.lerp(profile.startScale.y, 1.0f, progress), - profile.pivot.getX(x, width), - profile.pivot.getY(y, height) + AnimationMath.calculateCurrentOffset(profile.getOffsetX(), progress), + AnimationMath.calculateCurrentOffset(profile.getOffsetY(), progress), + AnimationMath.lerp(profile.getStartScaleX(), 1.0f, progress), + AnimationMath.lerp(profile.getStartScaleY(), 1.0f, progress), + profile.getPivot().getX(x, width), + profile.getPivot().getY(y, height) ); return scope; } diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java index 11c4890..e745b49 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/AdvancementsAnimator.java @@ -9,17 +9,17 @@ import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIScreenRegistry; -import net.weyne1.easegui.client.config.ScreenType; +import net.weyne1.easegui.api.EaseGUIScreenRegistry; +import net.weyne1.easegui.api.EaseGUIScreenType; import net.weyne1.easegui.client.state.ScreenStateTracker; public class AdvancementsAnimator { public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGraphics gg) { - ScreenType type = EaseGUIScreenRegistry.from(screen); + EaseGUIScreenType type = EaseGUIScreenRegistry.from(screen); var titleSettings = ConfigManager.getConfig().screens.get(type.getId()); - if (titleSettings == null || !titleSettings.enabled || titleSettings.advancements == null || !titleSettings.advancements.windowProfile.enabled) { + if (titleSettings == null || !titleSettings.enabled || titleSettings.advancements == null || !titleSettings.advancements.windowProfile.isEnabled()) { return null; } @@ -27,18 +27,18 @@ public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGra long startTime = ScreenStateTracker.getScreenOpenTime(); long elapsed = Util.getMillis() - startTime; - if (elapsed >= profile.duration) return null; + if (elapsed >= profile.getDuration()) return null; - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); return AnimationSystem.begin(gg, 0, 0, screen.width, screen.height, profile, progress, 1.0f); } public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int tabIndex) { - ScreenType type = EaseGUIScreenRegistry.from(screen); + EaseGUIScreenType type = EaseGUIScreenRegistry.from(screen); var titleSettings = ConfigManager.getConfig().screens.get(type.getId()); - if (titleSettings == null || !titleSettings.enabled || titleSettings.advancements == null || !titleSettings.advancements.tabsProfile.enabled) { + if (titleSettings == null || !titleSettings.enabled || titleSettings.advancements == null || !titleSettings.advancements.tabsProfile.isEnabled()) { return null; } @@ -50,15 +50,15 @@ public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int t var profile = titleSettings.advancements.tabsProfile; long startTime = ScreenStateTracker.getScreenOpenTime(); - long tabDelay = tabIndex * profile.cascadeDelay; + long tabDelay = tabIndex * profile.getCascadeDelay(); long elapsed = Util.getMillis() - startTime - tabDelay; - if (elapsed >= profile.duration) return null; + if (elapsed >= profile.getDuration()) return null; float progress = 0.0f; if (elapsed > 0) { - progress = AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + progress = AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); } return AnimationSystem.begin(gg, 0, 0, 28, 32, profile, progress, parentAlpha); diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java index 3e2478b..3db1d5e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/BackgroundAnimator.java @@ -6,8 +6,8 @@ import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.config.EaseGUIConfig; -import net.weyne1.easegui.client.config.EaseGUIScreenRegistry; -import net.weyne1.easegui.client.config.ScreenType; +import net.weyne1.easegui.api.EaseGUIScreenRegistry; +import net.weyne1.easegui.api.EaseGUIScreenType; import net.weyne1.easegui.client.state.ScreenAnimationTracker; import net.weyne1.easegui.client.state.ScreenStateTracker; @@ -42,7 +42,7 @@ public static boolean shouldAnimateBackground(Screen screen) { if (!config.global.enableSmoothBlur) return false; try { - ScreenType screenType = EaseGUIScreenRegistry.from(screen); + EaseGUIScreenType screenType = EaseGUIScreenRegistry.from(screen); if (screenType == null) return true; EaseGUIConfig.ScreenSettings screenSettings = config.screens.get(screenType.getId()); diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java index af86251..7ce80a1 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ContainerAnimator.java @@ -9,7 +9,7 @@ import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIElementCategory; +import net.weyne1.easegui.api.WidgetCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; public class ContainerAnimator { @@ -35,8 +35,8 @@ public static AnimationScope beginAnimation(Screen screen, GuiGraphics gg) { } } - var profile = ConfigManager.getProfileForCurrentContext(EaseGUIElementCategory.CONTAINERS); - if (profile == null || !profile.enabled) return null; + var profile = ConfigManager.getProfileForCurrentContext(WidgetCategory.CONTAINERS); + if (profile == null || !profile.isEnabled()) return null; long startTime = ScreenStateTracker.getScreenOpenTime(); return AnimationSystem.begin(gg, minX, minY, maxX - minX, maxY - minY, profile, startTime, 0L, 1.0f); diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java index 02215d6..c4c10be 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/ListItemAnimator.java @@ -2,18 +2,18 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIElementCategory; +import net.weyne1.easegui.api.WidgetCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; public class ListItemAnimator { public static AnimationScope beginRender(GuiGraphics gg, int top, int left, int width, int height) { - var profile = ConfigManager.getProfileForCurrentContext(EaseGUIElementCategory.LIST_ENTRY); - if (profile == null || !profile.enabled) return null; + var profile = ConfigManager.getProfileForCurrentContext(WidgetCategory.LIST_ENTRY); + if (profile == null || !profile.isEnabled()) return null; long delay = getDelay(top, left, profile); long startTime = ScreenStateTracker.getScreenOpenTime(); @@ -26,13 +26,13 @@ private static long getDelay(int top, int left, AnimationProfile profile) { int screenHeight = window.getGuiScaledHeight(); int screenWidth = window.getGuiScaledWidth(); - float distance = switch (profile.cascadeDirection) { + float distance = switch (profile.getCascadeDirection()) { case TOP_TO_BOTTOM -> top; case BOTTOM_TO_TOP -> Math.max(0f, screenHeight - top); case LEFT_TO_RIGHT -> left; case RIGHT_TO_LEFT -> Math.max(0f, screenWidth - left); }; - return (long) (distance * (profile.cascadeDelay / 100.0f)); + return (long) (distance * (profile.getCascadeDelay() / 100.0f)); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java index 3fef10a..8125fa5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/LogoAnimator.java @@ -6,7 +6,7 @@ import net.minecraft.client.gui.components.LogoRenderer; import net.minecraft.resources.Identifier; import net.weyne1.easegui.client.animation.AnimationMath; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationSystem; import net.weyne1.easegui.client.config.ConfigManager; @@ -65,14 +65,14 @@ private static void renderWholeLogo(GuiGraphics gg, Identifier texture, Animatio int logoWidth = LogoRendererAccessor.easeGUI$getLogoWidth(); int logoHeight = LogoRendererAccessor.easeGUI$getLogoHeight(); - if (elapsed >= profile.duration) { + if (elapsed >= profile.getDuration()) { try (AnimationScope ignored = AnimationSystem.beginAlphaOnly(gg, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); } return; } - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); try (AnimationScope ignored = AnimationSystem.begin(gg, startX, height, logoWidth, logoHeight, profile, progress, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); } @@ -81,11 +81,11 @@ private static void renderWholeLogo(GuiGraphics gg, Identifier texture, Animatio private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profile, int startX, int height, float finalAlpha) { long now = Util.getMillis(); long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); - long maxLogoDelay = (LETTER_TEXTURES.length - 1) * profile.cascadeDelay; + long maxLogoDelay = (LETTER_TEXTURES.length - 1) * profile.getCascadeDelay(); int logoWidth = LogoRendererAccessor.easeGUI$getLogoWidth(); int logoHeight = LogoRendererAccessor.easeGUI$getLogoHeight(); - if (now - actualStartTime >= maxLogoDelay + profile.duration) { + if (now - actualStartTime >= maxLogoDelay + profile.getDuration()) { try (AnimationScope ignored = AnimationSystem.beginAlphaOnly(gg, finalAlpha)) { for (Identifier texture : LETTER_TEXTURES) { drawLogoTexture(gg, texture, startX, height); @@ -100,7 +100,7 @@ private static void renderCascadedLetters(GuiGraphics gg, AnimationProfile profi long cascadeDelay = calculateCascadeDelay(profile, logicalIndex); long elapsed = now - actualStartTime - cascadeDelay; - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); try (AnimationScope ignored = AnimationSystem.begin(gg, startX, height, logoWidth, logoHeight, profile, progress, finalAlpha)) { drawLogoTexture(gg, texture, startX, height); @@ -116,19 +116,19 @@ private static void renderEditionText(GuiGraphics gg, EaseGUIConfig.LogoSettings int y = height + logoHeight - 7; var profile = config.editionProfile; - if (profile == null || !profile.enabled) { + if (profile == null || !profile.isEnabled()) { drawStaticEdition(gg, x, y, finalAlpha); return; } long elapsed = getEditionElapsed(config); - if (elapsed >= profile.duration) { + if (elapsed >= profile.getDuration()) { drawStaticEdition(gg, x, y, finalAlpha); return; } - float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.duration, profile.easing); + float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing()); try (AnimationScope ignored = AnimationSystem.begin(gg, x, y, editionWidth, editionHeight, profile, progress, finalAlpha)) { drawEditionTexture(gg, x, y); } @@ -141,17 +141,17 @@ private static void drawStaticEdition(GuiGraphics gg, int x, int y, float finalA } private static long calculateCascadeDelay(AnimationProfile profile, int logicalIndex) { - return switch (profile.cascadeDirection) { - case LEFT_TO_RIGHT -> logicalIndex * profile.cascadeDelay; - case RIGHT_TO_LEFT -> (LETTER_TEXTURES.length - 1 - logicalIndex) * profile.cascadeDelay; + return switch (profile.getCascadeDirection()) { + case LEFT_TO_RIGHT -> logicalIndex * profile.getCascadeDelay(); + case RIGHT_TO_LEFT -> (LETTER_TEXTURES.length - 1 - logicalIndex) * profile.getCascadeDelay(); case TOP_TO_BOTTOM, BOTTOM_TO_TOP -> 0L; }; } private static long getEditionElapsed(EaseGUIConfig.LogoSettings config) { long actualStartTime = ScreenStateTracker.getTitleActualStartTime(); - long maxLogoDelay = config.animateWholeText ? 0L : switch (config.logoProfile.cascadeDirection) { - case LEFT_TO_RIGHT, RIGHT_TO_LEFT -> (LETTER_TEXTURES.length - 1) * config.logoProfile.cascadeDelay; + long maxLogoDelay = config.animateWholeText ? 0L : switch (config.logoProfile.getCascadeDirection()) { + case LEFT_TO_RIGHT, RIGHT_TO_LEFT -> (LETTER_TEXTURES.length - 1) * config.logoProfile.getCascadeDelay(); case TOP_TO_BOTTOM, BOTTOM_TO_TOP -> 0L; }; return Util.getMillis() - actualStartTime - maxLogoDelay; diff --git a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java index de9e19e..e2054dc 100644 --- a/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java +++ b/common/src/main/java/net/weyne1/easegui/client/animator/WidgetAnimator.java @@ -5,10 +5,11 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.weyne1.easegui.client.extension.EaseGUIWidgetExtension; +import net.weyne1.easegui.api.animation.AnimationProfile; +import net.weyne1.easegui.client.extension.WidgetExtension; import net.weyne1.easegui.client.animation.*; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIElementCategory; +import net.weyne1.easegui.api.WidgetCategory; import net.weyne1.easegui.client.state.ScreenStateTracker; /** @@ -16,25 +17,25 @@ */ public class WidgetAnimator { - public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, EaseGUIElementCategory category, AnimationState state) { + public static AnimationScope beginRender(AbstractWidget widget, GuiGraphics gg, WidgetCategory category, AnimationState state) { if (Minecraft.getInstance().screen instanceof AbstractContainerScreen) { return null; } var profile = ConfigManager.getProfileForCurrentContext(category); - if (profile == null || !profile.enabled) return null; + if (profile == null || !profile.isEnabled()) return null; long now = Util.getMillis(); updateAnimationState(widget, state, now, profile); if (ScreenStateTracker.isResizeFrame() || AnimationContext.hasParentAnimation()) { - state.startTime = now - profile.duration - state.delay; + state.startTime = now - profile.getDuration() - state.delay; return null; } return AnimationSystem.begin(gg, widget.getX(), widget.getY(), widget.getWidth(), widget.getHeight(), profile, - state.startTime, state.delay, ((EaseGUIWidgetExtension) widget).easeGUI$getAlpha()); + state.startTime, state.delay, ((WidgetExtension) widget).easeGUI$getAlpha()); } /** @@ -54,7 +55,7 @@ private static void updateAnimationState(AbstractWidget widget, AnimationState s float distance = getDistance(widget, profile); - float delayMultiplier = profile.cascadeDelay / 100.0f; + float delayMultiplier = profile.getCascadeDelay() / 100.0f; state.delay = (long) (distance * delayMultiplier); } @@ -76,7 +77,7 @@ private static float getDistance(AbstractWidget widget, AnimationProfile profile final float BASELINE_WIDTH = 960.0f; final float BASELINE_HEIGHT = 540.0f; - return switch (profile.cascadeDirection) { + return switch (profile.getCascadeDirection()) { case TOP_TO_BOTTOM -> (Math.max(0, y) / (float) screenHeight) * BASELINE_HEIGHT; case BOTTOM_TO_TOP -> (Math.max(0f, screenHeight - y) / (float) screenHeight) * BASELINE_HEIGHT; case LEFT_TO_RIGHT -> (Math.max(0, x) / (float) screenWidth) * BASELINE_WIDTH; diff --git a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java index 1841c91..c35fdd6 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/ConfigManager.java @@ -5,7 +5,10 @@ import com.google.gson.JsonObject; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.WidgetCategory; +import net.weyne1.easegui.api.EaseGUIScreenRegistry; +import net.weyne1.easegui.api.EaseGUIScreenType; +import net.weyne1.easegui.api.animation.AnimationProfile; import java.io.File; import java.io.FileReader; @@ -23,7 +26,7 @@ public class ConfigManager { private static boolean isLoaded = false; private static Screen cachedScreenInstance = null; - private static ScreenType cachedScreenType = EaseGUIScreenRegistry.OTHER; + private static EaseGUIScreenType cachedScreenType = EaseGUIScreenRegistry.OTHER; public static void load() { if (isLoaded) return; @@ -91,8 +94,8 @@ public static EaseGUIConfig getConfig() { return currentConfig; } - public static AnimationProfile getProfileForCurrentContext(EaseGUIElementCategory category) { - if (category == null || category == EaseGUIElementCategory.UNKNOWN) return null; + public static AnimationProfile getProfileForCurrentContext(WidgetCategory category) { + if (category == null || category == WidgetCategory.UNKNOWN) return null; if (!isLoaded) load(); Screen currentScreen = Minecraft.getInstance().screen; @@ -109,7 +112,7 @@ public static AnimationProfile getProfileForCurrentContext(EaseGUIElementCategor AnimationProfile customProfile = screenSettings.customProfiles.get(category); if (customProfile != null) { - return customProfile.enabled ? customProfile : null; + return customProfile.isEnabled() ? customProfile : null; } } diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java index 426c526..d1a740c 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfig.java @@ -1,13 +1,14 @@ package net.weyne1.easegui.client.config; -import net.weyne1.easegui.client.animation.AnimationProfile; -import net.weyne1.easegui.client.animation.EasingType; +import net.weyne1.easegui.api.WidgetCategory; +import net.weyne1.easegui.api.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.EasingType; import java.util.EnumMap; import java.util.HashMap; import java.util.Map; -import static net.weyne1.easegui.client.animation.EasingType.EASE_OUT_CUBIC; +import static net.weyne1.easegui.api.animation.EasingType.EASE_OUT_CUBIC; public class EaseGUIConfig { public static final int CURRENT_SCHEMA_VERSION = 2; @@ -21,12 +22,12 @@ public static class GlobalSettings { public long blurDuration = 300L; public boolean blurContainers = true; public EasingType dimmingEasing = EASE_OUT_CUBIC; - public final Map elementProfiles = new EnumMap<>(EaseGUIElementCategory.class); + public final Map elementProfiles = new EnumMap<>(WidgetCategory.class); } public static class ScreenSettings { public boolean enabled = true; - public Map customProfiles = new EnumMap<>(EaseGUIElementCategory.class); + public Map customProfiles = new EnumMap<>(WidgetCategory.class); public LogoSettings logo = null; public SplashSettings splash = null; diff --git a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java index 353aa7e..26cd38e 100644 --- a/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java +++ b/common/src/main/java/net/weyne1/easegui/client/config/EaseGUIConfigFactory.java @@ -1,13 +1,16 @@ package net.weyne1.easegui.client.config; -import net.weyne1.easegui.client.animation.AnimationProfile; -import net.weyne1.easegui.client.animation.PivotPoint; +import net.weyne1.easegui.api.WidgetCategory; +import net.weyne1.easegui.api.EaseGUIScreenRegistry; +import net.weyne1.easegui.api.EaseGUIScreenType; +import net.weyne1.easegui.api.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.PivotPoint; import java.util.EnumMap; import java.util.HashMap; -import static net.weyne1.easegui.client.animation.CascadeDirection.BOTTOM_TO_TOP; -import static net.weyne1.easegui.client.animation.CascadeDirection.LEFT_TO_RIGHT; -import static net.weyne1.easegui.client.animation.EasingType.*; +import static net.weyne1.easegui.api.animation.CascadeDirection.BOTTOM_TO_TOP; +import static net.weyne1.easegui.api.animation.CascadeDirection.LEFT_TO_RIGHT; +import static net.weyne1.easegui.api.animation.EasingType.*; /** * Factory responsible for creating default configurations, applying structural patches, @@ -18,13 +21,13 @@ public final class EaseGUIConfigFactory { public static EaseGUIConfig createDefaultConfig() { EaseGUIConfig config = new EaseGUIConfig(); - config.global.elementProfiles.put(EaseGUIElementCategory.BUTTON_LIKE, createButtonProfile()); - config.global.elementProfiles.put(EaseGUIElementCategory.TEXT, createTextProfile()); - config.global.elementProfiles.put(EaseGUIElementCategory.SCROLLABLE, createScrollableProfile()); - config.global.elementProfiles.put(EaseGUIElementCategory.LIST_ENTRY, createListEntryProfile()); - config.global.elementProfiles.put(EaseGUIElementCategory.CONTAINERS, createContainerProfile()); + config.global.elementProfiles.put(WidgetCategory.BUTTON_LIKE, createButtonProfile()); + config.global.elementProfiles.put(WidgetCategory.TEXT, createTextProfile()); + config.global.elementProfiles.put(WidgetCategory.SCROLLABLE, createScrollableProfile()); + config.global.elementProfiles.put(WidgetCategory.LIST_ENTRY, createListEntryProfile()); + config.global.elementProfiles.put(WidgetCategory.CONTAINERS, createContainerProfile()); - for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { + for (EaseGUIScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { config.screens.put(type.getId(), createDefaultSettingsFor(type)); } config.screens.put(EaseGUIScreenRegistry.OTHER.getId(), createDefaultSettingsFor(EaseGUIScreenRegistry.OTHER)); @@ -51,7 +54,7 @@ public static boolean mergeDefaults(EaseGUIConfig config) { changed = true; } - for (ScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { + for (EaseGUIScreenType type : EaseGUIScreenRegistry.getRegisteredTypes()) { if (!config.screens.containsKey(type.getId())) { config.screens.put(type.getId(), createDefaultSettingsFor(type)); changed = true; @@ -68,7 +71,7 @@ public static boolean mergeDefaults(EaseGUIConfig config) { return changed; } - private static boolean patchScreenSettings(ScreenType type, EaseGUIConfig.ScreenSettings settings, EaseGUIConfig config) { + private static boolean patchScreenSettings(EaseGUIScreenType type, EaseGUIConfig.ScreenSettings settings, EaseGUIConfig config) { boolean changed = false; if (settings == null) { @@ -93,7 +96,7 @@ private static boolean patchScreenSettings(ScreenType type, EaseGUIConfig.Screen } if (settings.customProfiles == null) { - settings.customProfiles = new EnumMap<>(EaseGUIElementCategory.class); + settings.customProfiles = new EnumMap<>(WidgetCategory.class); changed = true; } @@ -103,7 +106,7 @@ private static boolean patchScreenSettings(ScreenType type, EaseGUIConfig.Screen return changed; } - private static EaseGUIConfig.ScreenSettings createDefaultSettingsFor(ScreenType type) { + private static EaseGUIConfig.ScreenSettings createDefaultSettingsFor(EaseGUIScreenType type) { EaseGUIConfig.ScreenSettings settings = new EaseGUIConfig.ScreenSettings(); settings.enabled = type.isEnabledByDefault(); diff --git a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java b/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java deleted file mode 100644 index 1d95f81..0000000 --- a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGUIWidgetExtension.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.weyne1.easegui.client.extension; - -import net.weyne1.easegui.client.config.EaseGUIElementCategory; - -public interface EaseGUIWidgetExtension { - EaseGUIElementCategory easeGUI$getCategory(); - - float easeGUI$getAlpha(); -} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java b/common/src/main/java/net/weyne1/easegui/client/extension/ItemExtension.java similarity index 65% rename from common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java rename to common/src/main/java/net/weyne1/easegui/client/extension/ItemExtension.java index e2936d0..ff4084b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/extension/EaseGuiItemExtension.java +++ b/common/src/main/java/net/weyne1/easegui/client/extension/ItemExtension.java @@ -1,5 +1,5 @@ package net.weyne1.easegui.client.extension; -public interface EaseGuiItemExtension { +public interface ItemExtension { float easegui$getAlpha(); } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/extension/WidgetExtension.java b/common/src/main/java/net/weyne1/easegui/client/extension/WidgetExtension.java new file mode 100644 index 0000000..3e0cc9c --- /dev/null +++ b/common/src/main/java/net/weyne1/easegui/client/extension/WidgetExtension.java @@ -0,0 +1,9 @@ +package net.weyne1.easegui.client.extension; + +import net.weyne1.easegui.api.WidgetCategory; + +public interface WidgetExtension { + WidgetCategory easeGUI$getCategory(); + + float easeGUI$getAlpha(); +} \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/AdvancementsScreenConfigurator.java b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/AdvancementsScreenConfigurator.java index 914ad72..b550167 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/AdvancementsScreenConfigurator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/AdvancementsScreenConfigurator.java @@ -4,7 +4,7 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.config.EaseGUIConfig; import net.weyne1.easegui.client.config.ProfileFeature; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java index 47085cb..9e9351b 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/configurator/TitleScreenConfigurator.java @@ -5,9 +5,9 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.EasingType; +import net.weyne1.easegui.api.animation.EasingType; import net.weyne1.easegui.client.util.StringUtils; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.config.ConfigManager; import net.weyne1.easegui.client.config.EaseGUIConfig; import net.weyne1.easegui.client.config.ProfileFeature; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java b/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java index 1e38228..fb34573 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/preview/ProfilePreviewRenderer.java @@ -3,6 +3,8 @@ import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.network.chat.Component; +import net.weyne1.easegui.api.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.CascadeDirection; import net.weyne1.easegui.client.animation.*; import net.weyne1.easegui.client.config.ProfileFeature; @@ -36,10 +38,10 @@ public static void render(GuiGraphics gg, Font font, int screenWidth, int screen boolean isCascadeActive = activeFeatures.contains(ProfileFeature.CASCADE_DELAY); int itemCount = isCascadeActive ? 3 : 1; - boolean isEnabled = profile.enabled; + boolean isEnabled = profile.isEnabled(); - boolean isHorizontal = profile.cascadeDirection == CascadeDirection.LEFT_TO_RIGHT || - profile.cascadeDirection == CascadeDirection.RIGHT_TO_LEFT; + boolean isHorizontal = profile.getCascadeDirection() == CascadeDirection.LEFT_TO_RIGHT || + profile.getCascadeDirection() == CascadeDirection.RIGHT_TO_LEFT; int boxWidth = (isHorizontal && isCascadeActive) ? 40 : 120; @@ -61,9 +63,9 @@ private static void renderStaticBounds(GuiGraphics gg, int centerX, int centerY, } private static void renderAnimatedElements(GuiGraphics gg, Font font, int centerX, int centerY, AnimationProfile profile, boolean isCascade, int count, boolean isHorizontal, int boxWidth) { - boolean isEnabled = profile.enabled; - long duration = Math.max(profile.duration, 50L); - long totalLoopTime = duration + (isCascade ? (2 * profile.cascadeDelay) : 0L) + LOOP_PADDING_MS; + boolean isEnabled = profile.isEnabled(); + long duration = Math.max(profile.getDuration(), 50L); + long totalLoopTime = duration + (isCascade ? (2 * profile.getCascadeDelay()) : 0L) + LOOP_PADDING_MS; long currentTime = isEnabled ? (System.currentTimeMillis() % totalLoopTime) : 0L; int halfW = boxWidth / 2; @@ -78,7 +80,7 @@ private static void renderAnimatedElements(GuiGraphics gg, Font font, int center long itemDelay = isCascade ? calculateCascadeDelay(profile, i) : 0L; long itemTime = currentTime - itemDelay; float progress = itemTime >= duration ? 1.0f : (itemTime > 0 ? (float) itemTime / duration : 0.0f); - easedProgress = profile.easing != null ? profile.easing.ease(progress) : progress; + easedProgress = profile.getEasing() != null ? profile.getEasing().ease(progress) : progress; } int targetX = getTargetX(centerX, isCascade, isHorizontal, i); @@ -88,7 +90,7 @@ private static void renderAnimatedElements(GuiGraphics gg, Font font, int center int y = targetY - halfH; try (AnimationScope ignored = AnimationSystem.begin(gg, x, y, boxWidth, BOX_HEIGHT, profile, easedProgress, 1.0f)) { - int bgAlpha = calcAlphaColor(profile.startAlpha, easedProgress); + int bgAlpha = calcAlphaColor(profile.getStartAlpha(), easedProgress); int boxColor = isEnabled ? 0x353535 : 0x222222; gg.fill(x, y, x + boxWidth, y + BOX_HEIGHT, (bgAlpha << 24) | boxColor); @@ -96,7 +98,7 @@ private static void renderAnimatedElements(GuiGraphics gg, Font font, int center ? (isHorizontal ? CASCADE_SHORT_LABELS[i] : CASCADE_LABELS[i]) : STATIC_LABEL; - int fontAlpha = calcAlphaColor(profile.startAlpha, easedProgress); + int fontAlpha = calcAlphaColor(profile.getStartAlpha(), easedProgress); int textColor = isEnabled ? 0xE0E0E0 : 0x888888; gg.drawCenteredString(font, label, targetX, targetY - 4, (fontAlpha << 24) | textColor); @@ -169,10 +171,10 @@ private static int calcAlphaColor(float startAlpha, float progress) { } private static long calculateCascadeDelay(AnimationProfile profile, int i) { - boolean reverse = profile.cascadeDirection == CascadeDirection.BOTTOM_TO_TOP || - profile.cascadeDirection == CascadeDirection.RIGHT_TO_LEFT; + boolean reverse = profile.getCascadeDirection() == CascadeDirection.BOTTOM_TO_TOP || + profile.getCascadeDirection() == CascadeDirection.RIGHT_TO_LEFT; int factor = reverse ? (2 - i) : i; - return factor * profile.cascadeDelay; + return factor * profile.getCascadeDelay(); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java index 970f2cd..5debbc7 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/MainConfigScreen.java @@ -5,7 +5,11 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.WidgetCategory; +import net.weyne1.easegui.api.EaseGUIScreenRegistry; +import net.weyne1.easegui.api.EaseGUIScreenGroup; +import net.weyne1.easegui.api.EaseGUIScreenType; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.config.*; import net.weyne1.easegui.client.gui.components.FieldValidator; import net.weyne1.easegui.client.gui.components.SettingsScrollList; @@ -77,11 +81,11 @@ protected void initScreen() { leftList.addHeader(Component.translatable("easegui.config.title.elements").getString()); - addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.BUTTON_LIKE, "easegui.main.button.button_like"); - addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.TEXT, "easegui.main.button.text"); - addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.SCROLLABLE, "easegui.main.button.scrollable"); - addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.LIST_ENTRY, "easegui.main.button.list_entry"); - addGlobalProfileButton(leftList, config, mc, EaseGUIElementCategory.CONTAINERS, "easegui.main.button.containers"); + addGlobalProfileButton(leftList, config, mc, WidgetCategory.BUTTON_LIKE, "easegui.main.button.button_like"); + addGlobalProfileButton(leftList, config, mc, WidgetCategory.TEXT, "easegui.main.button.text"); + addGlobalProfileButton(leftList, config, mc, WidgetCategory.SCROLLABLE, "easegui.main.button.scrollable"); + addGlobalProfileButton(leftList, config, mc, WidgetCategory.LIST_ENTRY, "easegui.main.button.list_entry"); + addGlobalProfileButton(leftList, config, mc, WidgetCategory.CONTAINERS, "easegui.main.button.containers"); this.addRenderableWidget(leftList); @@ -91,8 +95,8 @@ protected void initScreen() { rightList.setX(rightX); rightList.setY(50); - for (ScreenGroup category : ScreenGroup.values()) { - List categoryScreens = EaseGUIScreenRegistry.getRegisteredTypes().stream() + for (EaseGUIScreenGroup category : EaseGUIScreenGroup.values()) { + List categoryScreens = EaseGUIScreenRegistry.getRegisteredTypes().stream() .filter(type -> type.getGroup() == category) .sorted(Comparator.comparing(type -> type.getDisplayName().getString())) .toList(); @@ -100,7 +104,7 @@ protected void initScreen() { if (!categoryScreens.isEmpty()) { rightList.addHeader(Component.translatable(category.getTranslationKey()).getString()); - for (ScreenType type : categoryScreens) { + for (EaseGUIScreenType type : categoryScreens) { rightList.addButton(Button.builder( type.getDisplayName(), b -> mc.setScreen(new ScreenSpecificConfigScreen(this, type)) @@ -124,7 +128,7 @@ protected void initScreen() { ).bounds(halfWidth - 100, this.height - 30, 200, 20).build()); } - private void addGlobalProfileButton(SettingsScrollList list, EaseGUIConfig config, Minecraft mc, EaseGUIElementCategory category, String translationKey) { + private void addGlobalProfileButton(SettingsScrollList list, EaseGUIConfig config, Minecraft mc, WidgetCategory category, String translationKey) { AnimationProfile cleanDefault = new EaseGUIConfig().global.elementProfiles.get(category); if (cleanDefault == null) cleanDefault = new AnimationProfile(); AnimationProfile finalCleanDefault = cleanDefault; diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java index 0eec6dc..89896fb 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ProfileEditorScreen.java @@ -5,11 +5,11 @@ import net.minecraft.client.gui.components.EditBox; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.CascadeDirection; -import net.weyne1.easegui.client.animation.EasingType; -import net.weyne1.easegui.client.animation.PivotPoint; +import net.weyne1.easegui.api.animation.CascadeDirection; +import net.weyne1.easegui.api.animation.EasingType; +import net.weyne1.easegui.api.animation.PivotPoint; import net.weyne1.easegui.client.util.StringUtils; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.config.ProfileFeature; import net.weyne1.easegui.client.gui.components.FieldValidator; import net.weyne1.easegui.client.gui.components.SettingsScrollList; @@ -45,12 +45,12 @@ protected void initScreen() { leftScrollList.setY(50); // --- 0. Переключатель "Включено / Выключено" + кнопка "Reset" --- - Component statusComp = workingCopy.enabled ? Component.translatable("easegui.generic.on") : Component.translatable("easegui.generic.off"); + Component statusComp = workingCopy.isEnabled() ? Component.translatable("easegui.generic.on") : Component.translatable("easegui.generic.off"); Button toggleBtn = Button.builder( Component.translatable("easegui.editor.button.enabled", statusComp), button -> { - workingCopy.enabled(!workingCopy.enabled); - Component newStatus = workingCopy.enabled ? Component.translatable("easegui.generic.on") : Component.translatable("easegui.generic.off"); + workingCopy.enabled(!workingCopy.isEnabled()); + Component newStatus = workingCopy.isEnabled() ? Component.translatable("easegui.generic.on") : Component.translatable("easegui.generic.off"); button.setMessage(Component.translatable("easegui.editor.button.enabled", newStatus)); } ).build(); @@ -66,16 +66,16 @@ protected void initScreen() { leftScrollList.addTwoButtons(toggleBtn, resetBtn, 0.70f); // --- 1. Длительность (Лимит: от 0 до 5000 мс) --- - EditBox durationField = createTextField(String.valueOf(workingCopy.duration)); + EditBox durationField = createTextField(String.valueOf(workingCopy.getDuration())); FieldValidator.registerLongValidator(durationField, 0L, 5000L, workingCopy::duration); leftScrollList.addField(Component.translatable("easegui.editor.field.duration").getString(), durationField); // --- 2. Смещение (Лимит: от -1000 до 1000 пикселей) --- if (activeFeatures.contains(ProfileFeature.OFFSET)) { - EditBox ox = createTextField(String.valueOf(workingCopy.offset.x)); + EditBox ox = createTextField(String.valueOf(workingCopy.getOffsetX())); FieldValidator.registerFloatValidator(ox, -1000f, 1000f, workingCopy::offsetX); - EditBox oy = createTextField(String.valueOf(workingCopy.offset.y)); + EditBox oy = createTextField(String.valueOf(workingCopy.getOffsetY())); FieldValidator.registerFloatValidator(oy, -1000f, 1000f, workingCopy::offsetY); leftScrollList.addTwoFields(Component.translatable("easegui.editor.field.offset").getString(), ox, oy); @@ -83,10 +83,10 @@ protected void initScreen() { // --- 3. Масштаб (Лимит: от 0.0 до 10.0 крат) --- if (activeFeatures.contains(ProfileFeature.SCALE)) { - EditBox sx = createTextField(String.valueOf(workingCopy.startScale.x)); + EditBox sx = createTextField(String.valueOf(workingCopy.getStartScaleX())); FieldValidator.registerFloatValidator(sx, 0.0f, 10.0f, workingCopy::startScaleX); - EditBox sy = createTextField(String.valueOf(workingCopy.startScale.y)); + EditBox sy = createTextField(String.valueOf(workingCopy.getStartScaleY())); FieldValidator.registerFloatValidator(sy, 0.0f, 10.0f, workingCopy::startScaleY); leftScrollList.addTwoFields(Component.translatable("easegui.editor.field.scale").getString(), sx, sy); @@ -94,47 +94,47 @@ protected void initScreen() { // --- 4. Прозрачность (Лимит: от 0.0 до 1.0) --- if (activeFeatures.contains(ProfileFeature.ALPHA)) { - EditBox alphaField = createTextField(String.valueOf(workingCopy.startAlpha)); + EditBox alphaField = createTextField(String.valueOf(workingCopy.getStartAlpha())); FieldValidator.registerFloatValidator(alphaField, 0.0f, 1.0f, workingCopy::startAlpha); leftScrollList.addField(Component.translatable("easegui.editor.field.alpha").getString(), alphaField); } // --- 5. Каскадность (Лимит: от 0 до 1000 мс) --- if (activeFeatures.contains(ProfileFeature.CASCADE_DELAY)) { - EditBox cascadeField = createTextField(String.valueOf(workingCopy.cascadeDelay)); + EditBox cascadeField = createTextField(String.valueOf(workingCopy.getCascadeDelay())); FieldValidator.registerLongValidator(cascadeField, 0L, 1000L, workingCopy::cascadeDelay); leftScrollList.addField(Component.translatable("easegui.editor.field.cascade_delay").getString(), cascadeField); } // --- 5.1. Направление каскада if (activeFeatures.contains(ProfileFeature.CASCADE_DIRECTION)) { - Component dirComp = getCascadeDirectionComponent(workingCopy.cascadeDirection); + Component dirComp = getCascadeDirectionComponent(workingCopy.getCascadeDirection()); leftScrollList.addButton(Button.builder(Component.translatable("easegui.editor.button.cascade_dir", dirComp), b -> { CascadeDirection[] v = CascadeDirection.values(); - workingCopy.cascadeDirection(v[(workingCopy.cascadeDirection.ordinal() + 1) % v.length]); - b.setMessage(Component.translatable("easegui.editor.button.cascade_dir", getCascadeDirectionComponent(workingCopy.cascadeDirection))); + workingCopy.cascadeDirection(v[(workingCopy.getCascadeDirection().ordinal() + 1) % v.length]); + b.setMessage(Component.translatable("easegui.editor.button.cascade_dir", getCascadeDirectionComponent(workingCopy.getCascadeDirection()))); }).build()); } // --- 6. Точка опоры (Pivot) --- if (activeFeatures.contains(ProfileFeature.PIVOT)) { - Component pivotComp = Component.translatable("easegui.pivot." + workingCopy.pivot.name().toLowerCase()); + Component pivotComp = Component.translatable("easegui.pivot." + workingCopy.getPivot().name().toLowerCase()); leftScrollList.addButton(Button.builder(Component.translatable("easegui.editor.button.pivot", pivotComp), b -> { PivotPoint[] v = PivotPoint.values(); - workingCopy.pivot(v[(workingCopy.pivot.ordinal() + 1) % v.length]); - Component updatedPivot = Component.translatable("easegui.pivot." + workingCopy.pivot.name().toLowerCase()); + workingCopy.pivot(v[(workingCopy.getPivot().ordinal() + 1) % v.length]); + Component updatedPivot = Component.translatable("easegui.pivot." + workingCopy.getPivot().name().toLowerCase()); b.setMessage(Component.translatable("easegui.editor.button.pivot", updatedPivot)); }).build()); } // --- 7. Интерполяция (Easing) --- - Component easingComp = Component.literal(StringUtils.toTitleCase(workingCopy.easing)); + Component easingComp = Component.literal(StringUtils.toTitleCase(workingCopy.getEasing())); leftScrollList.addButton(Button.builder( Component.translatable("easegui.editor.button.easing", easingComp), button -> { EasingType[] values = EasingType.values(); - workingCopy.easing(values[(workingCopy.easing.ordinal() + 1) % values.length]); - Component updatedEasing = Component.literal(StringUtils.toTitleCase(workingCopy.easing)); + workingCopy.easing(values[(workingCopy.getEasing().ordinal() + 1) % values.length]); + Component updatedEasing = Component.literal(StringUtils.toTitleCase(workingCopy.getEasing())); button.setMessage(Component.translatable("easegui.editor.button.easing", updatedEasing)); } ).build()); @@ -180,14 +180,14 @@ private AnimationProfile cloneProfile(AnimationProfile s) { private AnimationProfile applyProfileValues(AnimationProfile target, AnimationProfile source) { return target - .enabled(source.enabled) - .duration(source.duration) - .offset(source.offset.x, source.offset.y) - .startScale(source.startScale.x, source.startScale.y) - .startAlpha(source.startAlpha) - .cascadeDelay(source.cascadeDelay) - .easing(source.easing) - .pivot(source.pivot) - .cascadeDirection(source.cascadeDirection); + .enabled(source.isEnabled()) + .duration(source.getDuration()) + .offset(source.getOffsetX(), source.getOffsetY()) + .startScale(source.getStartScaleX(), source.getStartScaleY()) + .startAlpha(source.getStartAlpha()) + .cascadeDelay(source.getCascadeDelay()) + .easing(source.getEasing()) + .pivot(source.getPivot()) + .cascadeDirection(source.getCascadeDirection()); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java index 913d684..82912a5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java +++ b/common/src/main/java/net/weyne1/easegui/client/gui/screens/ScreenSpecificConfigScreen.java @@ -6,7 +6,9 @@ import net.minecraft.client.gui.components.StringWidget; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; -import net.weyne1.easegui.client.animation.AnimationProfile; +import net.weyne1.easegui.api.WidgetCategory; +import net.weyne1.easegui.api.EaseGUIScreenType; +import net.weyne1.easegui.api.animation.AnimationProfile; import net.weyne1.easegui.client.config.*; import net.weyne1.easegui.client.gui.components.SettingsScrollList; import net.weyne1.easegui.client.gui.configurator.IScreenConfigurator; @@ -15,9 +17,9 @@ import java.util.EnumSet; public class ScreenSpecificConfigScreen extends EaseGUIAbstractSplitScreen { - private final ScreenType screenType; + private final EaseGUIScreenType screenType; - public ScreenSpecificConfigScreen(Screen parent, ScreenType type) { + public ScreenSpecificConfigScreen(Screen parent, EaseGUIScreenType type) { super(type.getDisplayName(), parent); this.screenType = type; } @@ -107,9 +109,9 @@ protected void initScreen() { } private void setupCategoryButtons(SettingsScrollList rightScrollList, EaseGUIConfig.ScreenSettings settings, EaseGUIConfig config) { - EnumSet overridableCategories = EnumSet.complementOf(EnumSet.of(EaseGUIElementCategory.UNKNOWN)); + EnumSet overridableCategories = EnumSet.complementOf(EnumSet.of(WidgetCategory.UNKNOWN)); - for (EaseGUIElementCategory category : overridableCategories) { + for (WidgetCategory category : overridableCategories) { boolean hasCustom = settings.customProfiles.containsKey(category); Component categoryLabel = Component.translatable("easegui.category." + category.name().toLowerCase()); @@ -157,14 +159,14 @@ private AnimationProfile cloneProfile(AnimationProfile src) { AnimationProfile dest = new AnimationProfile(); if (src == null) return dest; return dest - .enabled(src.enabled) - .duration(src.duration) - .offset(src.offset.x, src.offset.y) - .startScale(src.startScale.x, src.startScale.y) - .startAlpha(src.startAlpha) - .cascadeDelay(src.cascadeDelay) - .easing(src.easing) - .pivot(src.pivot) - .cascadeDirection(src.cascadeDirection); + .enabled(src.isEnabled()) + .duration(src.getDuration()) + .offset(src.getOffsetX(), src.getOffsetY()) + .startScale(src.getStartScaleX(), src.getStartScaleY()) + .startAlpha(src.getStartAlpha()) + .cascadeDelay(src.getCascadeDelay()) + .easing(src.getEasing()) + .pivot(src.getPivot()) + .cascadeDirection(src.getCascadeDirection()); } } \ No newline at end of file diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java index c89b9ec..32422e5 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/AbstractWidgetMixin.java @@ -5,24 +5,24 @@ import net.minecraft.util.Util; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.*; -import net.weyne1.easegui.client.extension.EaseGUIWidgetExtension; +import net.weyne1.easegui.client.extension.WidgetExtension; import net.weyne1.easegui.client.animation.AnimationScope; import net.weyne1.easegui.client.animation.AnimationState; import net.weyne1.easegui.client.animator.WidgetAnimator; import net.weyne1.easegui.client.config.ConfigManager; -import net.weyne1.easegui.client.config.EaseGUIElementCategory; +import net.weyne1.easegui.api.WidgetCategory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @Mixin(AbstractWidget.class) -public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { +public abstract class AbstractWidgetMixin implements WidgetExtension { @Shadow protected float alpha; @Shadow protected boolean isHovered; @Unique private final AnimationState easeGUI$animationState = new AnimationState(); - @Unique private EaseGUIElementCategory easeGUI$cachedCategory = null; + @Unique private WidgetCategory easeGUI$cachedCategory = null; @Override public float easeGUI$getAlpha() { @@ -30,9 +30,9 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { } @Override - public EaseGUIElementCategory easeGUI$getCategory() { + public WidgetCategory easeGUI$getCategory() { if (this.easeGUI$cachedCategory == null) { - this.easeGUI$cachedCategory = EaseGUIElementCategory.fromClass(this.getClass()); + this.easeGUI$cachedCategory = WidgetCategory.fromClass(this.getClass()); } return this.easeGUI$cachedCategory; } @@ -47,7 +47,7 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { } var category = this.easeGUI$getCategory(); - if (category == null || category == EaseGUIElementCategory.UNKNOWN) { + if (category == null || category == WidgetCategory.UNKNOWN) { original.call(guiGraphics, mouseX, mouseY, partialTick); return; } @@ -57,9 +57,9 @@ public abstract class AbstractWidgetMixin implements EaseGUIWidgetExtension { var profile = ConfigManager.getProfileForCurrentContext(category); boolean shouldBypassHover = false; - if (profile != null && profile.enabled && this.easeGUI$animationState.init) { + if (profile != null && profile.isEnabled() && this.easeGUI$animationState.init) { long elapsed = Util.getMillis() - this.easeGUI$animationState.startTime - this.easeGUI$animationState.delay; - if (elapsed < profile.duration) { + if (elapsed < profile.getDuration()) { shouldBypassHover = true; } } diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java index e673edb..3447d8f 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiItemRenderStateMixin.java @@ -2,7 +2,7 @@ import net.minecraft.client.gui.render.state.GuiItemRenderState; import net.weyne1.easegui.client.animation.AnimationContext; -import net.weyne1.easegui.client.extension.EaseGuiItemExtension; +import net.weyne1.easegui.client.extension.ItemExtension; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GuiItemRenderState.class) -public class GuiItemRenderStateMixin implements EaseGuiItemExtension { +public class GuiItemRenderStateMixin implements ItemExtension { @Unique private float easegui$alpha = 1.0f; diff --git a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java index 2745336..abe81df 100644 --- a/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java +++ b/common/src/main/java/net/weyne1/easegui/client/mixin/gui/GuiRendererMixin.java @@ -8,7 +8,7 @@ import net.minecraft.client.gui.render.state.BlitRenderState; import net.minecraft.client.gui.render.state.GuiItemRenderState; import net.minecraft.client.gui.render.GuiRenderer; -import net.weyne1.easegui.client.extension.EaseGuiItemExtension; +import net.weyne1.easegui.client.extension.ItemExtension; import org.joml.Matrix3x2f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -27,7 +27,7 @@ public class GuiRendererMixin { ScreenRectangle scissorArea, ScreenRectangle bounds, Operation original, GuiItemRenderState renderState, float x, float y, int itemSize, int atlasSize) { - float alpha = ((EaseGuiItemExtension) (Object) renderState).easegui$getAlpha(); + float alpha = ((ItemExtension) (Object) renderState).easegui$getAlpha(); if (alpha >= 1.0f) { return original.call(pipeline, textureSetup, pose, x0, y0, x1, y1, u0, u1, v0, v1, color, scissorArea, bounds); diff --git a/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java b/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java index 8b732da..4743827 100644 --- a/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java +++ b/common/src/test/java/net/weyne1/easegui/client/animation/AnimationMathUtilsTest.java @@ -1,5 +1,6 @@ package net.weyne1.easegui.client.animation; +import net.weyne1.easegui.api.animation.EasingType; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; From c07cfbb0714f25e433824d137a0a1607a37e829c Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 14 Jul 2026 15:12:08 +0300 Subject: [PATCH 42/43] ref: oops the fabric package was named neoforge --- .../{neoforge => fabric}/client/EaseGUIFabricClient.java | 2 +- .../{neoforge => fabric}/client/ModMenuIntegration.java | 2 +- fabric/src/main/resources/fabric.mod.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename fabric/src/main/java/net/weyne1/easegui/{neoforge => fabric}/client/EaseGUIFabricClient.java (84%) rename fabric/src/main/java/net/weyne1/easegui/{neoforge => fabric}/client/ModMenuIntegration.java (88%) diff --git a/fabric/src/main/java/net/weyne1/easegui/neoforge/client/EaseGUIFabricClient.java b/fabric/src/main/java/net/weyne1/easegui/fabric/client/EaseGUIFabricClient.java similarity index 84% rename from fabric/src/main/java/net/weyne1/easegui/neoforge/client/EaseGUIFabricClient.java rename to fabric/src/main/java/net/weyne1/easegui/fabric/client/EaseGUIFabricClient.java index 66cd58b..5ba5b4a 100644 --- a/fabric/src/main/java/net/weyne1/easegui/neoforge/client/EaseGUIFabricClient.java +++ b/fabric/src/main/java/net/weyne1/easegui/fabric/client/EaseGUIFabricClient.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.neoforge.client; +package net.weyne1.easegui.fabric.client; import net.fabricmc.api.ClientModInitializer; import net.weyne1.easegui.client.EaseGUIClient; diff --git a/fabric/src/main/java/net/weyne1/easegui/neoforge/client/ModMenuIntegration.java b/fabric/src/main/java/net/weyne1/easegui/fabric/client/ModMenuIntegration.java similarity index 88% rename from fabric/src/main/java/net/weyne1/easegui/neoforge/client/ModMenuIntegration.java rename to fabric/src/main/java/net/weyne1/easegui/fabric/client/ModMenuIntegration.java index 1efaf69..93664e0 100644 --- a/fabric/src/main/java/net/weyne1/easegui/neoforge/client/ModMenuIntegration.java +++ b/fabric/src/main/java/net/weyne1/easegui/fabric/client/ModMenuIntegration.java @@ -1,4 +1,4 @@ -package net.weyne1.easegui.neoforge.client; +package net.weyne1.easegui.fabric.client; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 85427c1..09fb815 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -17,10 +17,10 @@ "environment": "client", "entrypoints": { "client": [ - "net.weyne1.easegui.neoforge.client.EaseGUIFabricClient" + "net.weyne1.easegui.fabric.client.EaseGUIFabricClient" ], "modmenu": [ - "net.weyne1.easegui.neoforge.client.ModMenuIntegration" + "net.weyne1.easegui.fabric.client.ModMenuIntegration" ] }, "mixins": [ From ea6f79e55f40036002ee2a30517fd9f3a2cd79fc Mon Sep 17 00:00:00 2001 From: Weyne1 Date: Tue, 14 Jul 2026 15:13:29 +0300 Subject: [PATCH 43/43] chore: bump version to 0.4.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bbfa650..b64e679 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ org.gradle.configuration-cache=false minecraft_version=1.21.11 # Mod Properties -mod_version=0.3.0 +mod_version=0.4.0 maven_group=net.weyne1.easegui archives_name=easegui enabled_platforms=fabric,neoforge