Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: setup jdk
uses: actions/setup-java@v5
with:
java-version: '21'
java-version: '25'
distribution: 'microsoft'

- name: make gradle wrapper executable
Expand Down
20 changes: 6 additions & 14 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'dev.architectury.loom' version '1.13.467' apply false
id 'architectury-plugin' version '3.4-SNAPSHOT'
id "dev.architectury.loom-no-remap" version "1.14-SNAPSHOT" apply false
id "architectury-plugin" version "3.5-SNAPSHOT"
id 'com.gradleup.shadow' version '8.3.6' apply false
}

Expand Down Expand Up @@ -30,7 +30,7 @@ allprojects {
}

subprojects {
apply plugin: 'dev.architectury.loom'
apply plugin: "dev.architectury.loom-no-remap"
apply plugin: 'architectury-plugin'
apply plugin: 'maven-publish'

Expand All @@ -48,10 +48,6 @@ subprojects {
}
}

tasks.named('remapJar') {
archiveVersion.set("")
}

loom {
silentMojangMappingsLicense()

Expand All @@ -69,20 +65,16 @@ subprojects {

dependencies {
minecraft "net.minecraft:minecraft:$rootProject.minecraft_version"
mappings loom.layered() {
officialMojangMappings()
parchment("org.parchmentmc.data:parchment-${rootProject.minecraft_version}:${rootProject.parchment_version}@zip")
}
}

java {
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_25
targetCompatibility = JavaVersion.VERSION_25
}

tasks.withType(JavaCompile).configureEach {
it.options.release = 21
it.options.release = 25
}

processResources {
Expand Down
2 changes: 1 addition & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ architectury {
}

dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
implementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"

testImplementation "org.junit.jupiter:junit-jupiter:${rootProject.junit_version}"
testRuntimeOnly "org.junit.platform:junit-platform-launcher"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public final class EaseGUIScreenRegistry {
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("multiplayer_options", MultiplayerOptionsScreen.class, 1000, EaseGUIScreenGroup.BASIC);
register("death", DeathScreen.class, 1000, EaseGUIScreenGroup.BASIC);
register("social_interactions", SocialInteractionsScreen.class, 1000, EaseGUIScreenGroup.BASIC);

Expand All @@ -73,7 +73,7 @@ public final class EaseGUIScreenRegistry {
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("edit_game_rules", AbstractGameRulesScreen.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);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package net.weyne1.easegui.client.animation;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.weyne1.easegui.client.EaseGUIDebug;
import org.joml.Matrix3x2fStack;

public final class AnimationScope implements AutoCloseable {
private static final float MIN_SCALE = 0.001f;

private final GuiGraphics guiGraphics;
private final GuiGraphicsExtractor graphics;
private final float alpha;

private boolean isClosed = false;
Expand Down Expand Up @@ -37,23 +37,23 @@ public boolean isSuspended() {
return isSuspended;
}

public AnimationScope(GuiGraphics guiGraphics, float alpha) {
this.guiGraphics = guiGraphics;
public AnimationScope(GuiGraphicsExtractor graphics, float alpha) {
this.graphics = graphics;
this.alpha = alpha;

AnimationContext.pushScope(this);
this.guiGraphics.pose().pushMatrix();
this.graphics.pose().pushMatrix();
}

public void setTransformParams(float offsetX, float offsetY, float scaleX, float scaleY, float pivotX, float pivotY) {
void setTransformParams(float offsetX, float offsetY, float scaleX, float scaleY, float pivotX, float pivotY) {
this.offsetX = offsetX;
this.offsetY = offsetY;
this.scaleX = clampScale(scaleX);
this.scaleY = clampScale(scaleY);
this.pivotX = pivotX;
this.pivotY = pivotY;

Matrix3x2fStack poseStack = guiGraphics.pose();
Matrix3x2fStack poseStack = graphics.pose();

if (this.scaleX != 1.0f || this.scaleY != 1.0f) {
poseStack.translate(offsetX + pivotX, offsetY + pivotY);
Expand All @@ -67,7 +67,7 @@ public void setTransformParams(float offsetX, float offsetY, float scaleX, float
public void suspend() {
if (isClosed || isSuspended) return;

Matrix3x2fStack poseStack = guiGraphics.pose();
Matrix3x2fStack poseStack = graphics.pose();
poseStack.pushMatrix();

if (scaleX != 1.0f || scaleY != 1.0f) {
Expand All @@ -84,7 +84,7 @@ public void suspend() {
public void resume() {
if (isClosed || !isSuspended) return;

guiGraphics.pose().popMatrix();
graphics.pose().popMatrix();

isSuspended = false;
}
Expand All @@ -95,12 +95,12 @@ public void close() {
isClosed = true;

if (isSuspended) {
guiGraphics.pose().popMatrix();
graphics.pose().popMatrix();
isSuspended = false;
}

try {
guiGraphics.pose().popMatrix();
graphics.pose().popMatrix();
} catch (IllegalStateException e) {
EaseGUIDebug.reportError("pose_stack_underflow", () -> "PoseStack underflow inside AnimationScope close!");
}
Expand All @@ -109,9 +109,6 @@ public void close() {
}

private static float clampScale(float scale) {
if (Math.abs(scale) < MIN_SCALE) {
return Math.copySign(MIN_SCALE, scale == 0.0f ? 1.0f : scale);
}
return scale;
return Math.max(MIN_SCALE, Math.abs(scale));
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,107 @@
package net.weyne1.easegui.client.animation;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.util.Util;
import net.weyne1.easegui.api.animation.AnimationProfile;
import net.weyne1.easegui.api.animation.EasingType;

public final class AnimationSystem {

private AnimationSystem() {}

/**
* An entry point for animations with automatic timing and progress calculation.
* Begins an animation scope using start timestamp and delay.
* Use this overload for real-time game elements tied to a specific open time or start timestamp.
*
* @param startTime time in milliseconds when the screen/animation sequence started
* @param delay delay in milliseconds before this specific element begins animating
* @return active {@link AnimationScope}, or {@code null} if the duration has elapsed
*/
public static AnimationScope begin(
GuiGraphics gg,
int x, int y, int width, int height,
GuiGraphicsExtractor graphics,
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.getDuration()) return null;

if (elapsed >= profile.getDuration()) {
return null;
}
float rawProgress = elapsed <= 0 ? 0.0f : Math.min(1.0f, elapsed / (float) profile.getDuration());
return begin(graphics, x, y, width, height, profile, rawProgress, baseAlpha);
}

float progress = elapsed <= 0 ? 0.0f : AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing());
/**
* Begins an animation scope using pre-calculated elapsed time.
* Preferred when elapsed time is already calculated or adjusted for cascade delays.
*
* @param elapsed time passed since the element's animation start, in milliseconds
* @return active {@link AnimationScope}, or {@code null} if the duration has elapsed
*/
public static AnimationScope begin(
GuiGraphicsExtractor graphics,
int x,
int y,
int width,
int height,
AnimationProfile profile,
long elapsed,
float baseAlpha
) {
if (elapsed >= profile.getDuration()) return null;

return begin(gg, x, y, width, height, profile, progress, baseAlpha);
float rawProgress = elapsed <= 0 ? 0.0f : Math.min(1.0f, elapsed / (float) profile.getDuration());
return begin(graphics, x, y, width, height, profile, rawProgress, baseAlpha);
}

/**
* Core overload accepting linear raw progress [0.0..1.0].
* Use this overload when driving animations from looped UI timers (e.g. editor preview).
*
* @param rawProgress linear progress between 0.0f and 1.0f. Do NOT pre-apply easing functions!
* @return active {@link AnimationScope} context
*/
public static AnimationScope begin(
GuiGraphics gg,
int x, int y, int width, int height,
GuiGraphicsExtractor graphics,
int x,
int y,
int width,
int height,
AnimationProfile profile,
float progress,
float rawProgress,
float baseAlpha
) {
float alphaProgress = AnimationMath.clamp(progress, 0.0f, 1.0f);
float lerpedAlpha = AnimationMath.lerp(profile.getStartAlpha(), 1.0f, alphaProgress);
float clampedRaw = AnimationMath.clamp(rawProgress, 0.0f, 1.0f);

float spatialProgress = profile.getEasing() != null
? profile.getEasing().ease(clampedRaw)
: clampedRaw;

float alphaProgress = EasingType.EASE_OUT_CUBIC.ease(clampedRaw);

float lerpedAlpha = (clampedRaw <= 0.0f)
? profile.getStartAlpha()
: AnimationMath.lerp(profile.getStartAlpha(), 1.0f, alphaProgress);

float finalAlpha = AnimationMath.clamp(baseAlpha * lerpedAlpha, 0.0f, 1.0f);

AnimationScope scope = new AnimationScope(gg, finalAlpha);
AnimationScope scope = new AnimationScope(graphics, finalAlpha);
scope.setTransformParams(
AnimationMath.calculateCurrentOffset(profile.getOffsetX(), progress),
AnimationMath.calculateCurrentOffset(profile.getOffsetY(), progress),
AnimationMath.lerp(profile.getStartScaleX(), 1.0f, progress),
AnimationMath.lerp(profile.getStartScaleY(), 1.0f, progress),
AnimationMath.calculateCurrentOffset(profile.getOffsetX(), spatialProgress),
AnimationMath.calculateCurrentOffset(profile.getOffsetY(), spatialProgress),
AnimationMath.lerp(profile.getStartScaleX(), 1.0f, spatialProgress),
AnimationMath.lerp(profile.getStartScaleY(), 1.0f, spatialProgress),
profile.getPivot().getX(x, width),
profile.getPivot().getY(y, height)
);
return scope;
}

public static AnimationScope beginAlphaOnly(GuiGraphics gg, float alpha) {
public static AnimationScope beginAlphaOnly(GuiGraphicsExtractor gg, float alpha) {
return new AnimationScope(gg, alpha);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,21 @@ private static int[] transformRange(int start, int end, boolean horizontal) {
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;
int min = Math.min(roundedStart, roundedEnd);
int max = Math.max(roundedStart, roundedEnd);

if (max - min < MIN_SIZE) {
max = min + MIN_SIZE;
}

return new int[]{roundedStart, roundedEnd};
return new int[]{min, max};
}

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;

float animScale = (Math.abs(scope.getScaleX()) + Math.abs(scope.getScaleY())) * 0.5f;
return scale * animScale;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package net.weyne1.easegui.client.animator;

import net.minecraft.util.Util;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.advancements.AdvancementsScreen;
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;
import net.weyne1.easegui.client.config.ConfigManager;
Expand All @@ -15,7 +14,7 @@

public class AdvancementsAnimator {

public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGraphics gg) {
public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGraphicsExtractor graphics) {
EaseGUIScreenType type = EaseGUIScreenRegistry.from(screen);
var titleSettings = ConfigManager.getConfig().screens.get(type.getId());

Expand All @@ -29,12 +28,10 @@ public static AnimationScope beginRenderWindow(AdvancementsScreen screen, GuiGra

if (elapsed >= profile.getDuration()) return null;

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);
return AnimationSystem.begin(graphics, 0, 0, screen.width, screen.height, profile, elapsed, 1.0f);
}

public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int tabIndex) {
public static AnimationScope beginRenderTab(Screen screen, GuiGraphicsExtractor graphics, int tabIndex) {
EaseGUIScreenType type = EaseGUIScreenRegistry.from(screen);
var titleSettings = ConfigManager.getConfig().screens.get(type.getId());

Expand All @@ -45,7 +42,7 @@ public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int t
float parentAlpha = AnimationContext.getCurrentAlpha();

if (tabIndex == 0) {
return AnimationSystem.beginAlphaOnly(gg, parentAlpha);
return AnimationSystem.beginAlphaOnly(graphics, parentAlpha);
}

var profile = titleSettings.advancements.tabsProfile;
Expand All @@ -56,11 +53,6 @@ public static AnimationScope beginRenderTab(Screen screen, GuiGraphics gg, int t

if (elapsed >= profile.getDuration()) return null;

float progress = 0.0f;
if (elapsed > 0) {
progress = AnimationMath.calculateProgress(elapsed, profile.getDuration(), profile.getEasing());
}

return AnimationSystem.begin(gg, 0, 0, 28, 32, profile, progress, parentAlpha);
return AnimationSystem.begin(graphics, 0, 0, 28, 32, profile, elapsed, parentAlpha);
}
}
Loading