From 3e740aab87878867b3256194a5f0327ecd90a6e6 Mon Sep 17 00:00:00 2001 From: flowerinsnow Date: Thu, 7 Nov 2024 18:37:15 +0800 Subject: [PATCH] feat: 24w45a supported --- {24w33a-fabric => 24w33a-24w45a}/build.gradle | 49 ++- 24w33a-24w45a/gradle.properties | 21 + .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 2 +- {24w33a-fabric => 24w33a-24w45a}/gradlew | 0 {24w33a-fabric => 24w33a-24w45a}/gradlew.bat | 0 .../settings.gradle | 0 .../GreatScrollableTooltips.java | 93 +++++ .../event/PreScreenKeyPressedEvent.java | 23 ++ .../event/PreScreenMouseScrollEvent.java | 23 ++ .../event/RenderTooltipEvent.java | 41 ++ .../event/ScreenCloseEvent.java | 23 ++ .../listener/EventTriggerListener.java | 21 + .../listener/KeyScrollListener.java | 34 ++ .../listener/MouseScrollListener.java | 41 ++ .../listener/ScrollingStatusListener.java | 55 +++ .../manager/KeyBindingManager.java | 23 ++ .../mixin/AccessorSliderWidget.java | 2 +- .../mixin/MixinDrawContext.java | 42 ++ .../mixin/MixinHandledScreen.java | 51 ++- .../modmenu/ModMenuImpl.java | 16 + .../screen/ConfigScreen.java | 143 +++++++ .../greatscrollabletooltips/util/Lazy.java | 26 ++ .../assets/great-scrollable-tooltips/icon.png | Bin .../great-scrollable-tooltips/lang/en_us.json | 0 .../great-scrollable-tooltips/lang/zh_cn.json | 0 24w33a-24w45a/src/main/resources/config.toml | 3 + .../src/main/resources/fabric.mod.json | 18 +- .../great-scrollable-tooltips.mixins.json | 13 + 24w33a-fabric/gradle.properties | 19 - .../GreatScrollableTooltips.java | 152 ------- .../config/Config.java | 82 ---- .../event/HandledScreenKeyPressedEvent.java | 22 -- .../MouseScrolledInParentElementEvent.java | 23 -- .../event/RenderMouseoverTooltipEvent.java | 42 -- .../listener/CursorKeyListener.java | 32 -- .../mixin/MixinDrawContext.java | 42 -- .../mixin/MixinInventoryScreen.java | 29 -- .../mixinplugin/GSTMixinPlugin.java | 41 -- .../screen/ConfigScreen.java | 122 ------ 24w33a-fabric/src/main/resources/LICENSE | 373 ------------------ 24w33a-fabric/src/main/resources/config.conf | 3 - .../great-scrollable-tooltips.mixins.json | 15 - README.md | 2 +- README/zh_cn.md | 2 +- 45 files changed, 707 insertions(+), 1057 deletions(-) rename {24w33a-fabric => 24w33a-24w45a}/build.gradle (55%) create mode 100644 24w33a-24w45a/gradle.properties rename {24w33a-fabric => 24w33a-24w45a}/gradle/wrapper/gradle-wrapper.jar (100%) rename {24w33a-fabric => 24w33a-24w45a}/gradle/wrapper/gradle-wrapper.properties (93%) rename {24w33a-fabric => 24w33a-24w45a}/gradlew (100%) mode change 100755 => 100644 rename {24w33a-fabric => 24w33a-24w45a}/gradlew.bat (100%) rename {24w33a-fabric => 24w33a-24w45a}/settings.gradle (100%) create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenKeyPressedEvent.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenMouseScrollEvent.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/RenderTooltipEvent.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/ScreenCloseEvent.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/EventTriggerListener.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/KeyScrollListener.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/MouseScrollListener.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/ScrollingStatusListener.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/manager/KeyBindingManager.java rename {24w33a-fabric/src/main/java/online => 24w33a-24w45a/src/main/java/cn}/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java (85%) create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java rename {24w33a-fabric/src/main/java/online => 24w33a-24w45a/src/main/java/cn}/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java (52%) create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/modmenu/ModMenuImpl.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java create mode 100644 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/util/Lazy.java rename {24w33a-fabric => 24w33a-24w45a}/src/main/resources/assets/great-scrollable-tooltips/icon.png (100%) rename {24w33a-fabric => 24w33a-24w45a}/src/main/resources/assets/great-scrollable-tooltips/lang/en_us.json (100%) rename {24w33a-fabric => 24w33a-24w45a}/src/main/resources/assets/great-scrollable-tooltips/lang/zh_cn.json (100%) create mode 100644 24w33a-24w45a/src/main/resources/config.toml rename {24w33a-fabric => 24w33a-24w45a}/src/main/resources/fabric.mod.json (55%) create mode 100644 24w33a-24w45a/src/main/resources/great-scrollable-tooltips.mixins.json delete mode 100644 24w33a-fabric/gradle.properties delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/config/Config.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/HandledScreenKeyPressedEvent.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/MouseScrolledInParentElementEvent.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/RenderMouseoverTooltipEvent.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/listener/CursorKeyListener.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinInventoryScreen.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixinplugin/GSTMixinPlugin.java delete mode 100644 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java delete mode 100644 24w33a-fabric/src/main/resources/LICENSE delete mode 100644 24w33a-fabric/src/main/resources/config.conf delete mode 100644 24w33a-fabric/src/main/resources/great-scrollable-tooltips.mixins.json diff --git a/24w33a-fabric/build.gradle b/24w33a-24w45a/build.gradle similarity index 55% rename from 24w33a-fabric/build.gradle rename to 24w33a-24w45a/build.gradle index 2499d05..15e4c30 100644 --- a/24w33a-fabric/build.gradle +++ b/24w33a-24w45a/build.gradle @@ -1,6 +1,6 @@ plugins() { - id('fabric-loom').version("${fabric_loom_version}") - id('maven-publish') + id('fabric-loom').version("${loom_version}") + id('maven-publish') } version = project.mod_version @@ -11,14 +11,20 @@ base() { } repositories() { - mavenCentral() + maven() { + url = 'https://www.cursemaven.com/' + } maven() { - url = 'https://maven.terraformersmc.com/releases/' + url = 'https://maven.pkg.github.com/flowerinsnowdh/GreatScrollableTooltips' + credentials() { + username = "${System.getenv('GITHUB_USERNAME')}" + password = "${System.getenv('GITHUB_TOKEN')}" + } } maven() { - url = 'https://repo.flowerinsnow.online/repository/maven-opensources/' + url = 'https://maven.terraformersmc.com/releases/' } } @@ -36,14 +42,15 @@ dependencies() { // modImplementation "net.fabricmc.fabric-api:fabric-api-deprecated:${project.fabric_version}" - include(api("online.flowerinsnow.fnml4j:interface:${fnml4j_version}")) - include(api("online.flowerinsnow.fnml4j:core:${fnml4j_version}")) + modImplementation("com.terraformersmc:modmenu:${modmenu_version}") + modImplementation('curse.maven:legendary-tooltips-fabric-542478:5591020') + include(api("cn.flowerinsnow.greatscrollabletooltips:common:${common_module_version}")) + include(api("com.electronwill.night-config:core:${night_config_version}")) + include(api("com.electronwill.night-config:toml:${night_config_version}")) } processResources() { - LinkedHashMap props = [ - 'version' : project.version - ] + LinkedHashMap props = ['version' : project.version] props.forEach(inputs::property) filesMatching('fabric.mod.json') { @@ -56,28 +63,28 @@ tasks.withType(JavaCompile).configureEach() { } java() { - withSourcesJar() - sourceCompatibility = JavaVersion.VERSION_21 targetCompatibility = JavaVersion.VERSION_21 } +jar() { + from(file('../LICENSE')) + from(file('../NOTICE')) +} + // configure the maven publication publishing() { publications() { mavenJava(MavenPublication) { - artifactId = project.archives_base_name from(components.java) } } + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. repositories() { - maven() { - url = "${System.getenv('PUBLISH_REPO_URL')}" - credentials() { - username = "${System.getenv('PUBLISH_REPO_USERNAME')}" - password = "${System.getenv('PUBLISH_REPO_PASSWORD')}" - } - } + // Add repositories to publish to here. + // Notice: This block does NOT have the same function as the block in the top level. + // The repositories here will be used for publishing your artifact, not for + // retrieving dependencies. } -} \ No newline at end of file +} diff --git a/24w33a-24w45a/gradle.properties b/24w33a-24w45a/gradle.properties new file mode 100644 index 0000000..967d01c --- /dev/null +++ b/24w33a-24w45a/gradle.properties @@ -0,0 +1,21 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G -Dfile.encoding=UTF-8 +org.gradle.parallel=true + +# Fabric Properties +# check these on https://fabricmc.net/develop +minecraft_version=24w45a +yarn_mappings=24w45a+build.1 +loader_version=0.16.9 + +# Mod Properties +mod_version=16.1.0+fabric +maven_group=cn.flowerinsnow.greatscrollabletooltips +archives_base_name=great-scrollable-tooltips + +# Dependencies +loom_version=1.8.12 +fabric_version=0.107.2+1.21.4 +modmenu_version=12.0.0-beta.1 +night_config_version=3.8.1 +common_module_version=1.1.0 \ No newline at end of file diff --git a/24w33a-fabric/gradle/wrapper/gradle-wrapper.jar b/24w33a-24w45a/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from 24w33a-fabric/gradle/wrapper/gradle-wrapper.jar rename to 24w33a-24w45a/gradle/wrapper/gradle-wrapper.jar diff --git a/24w33a-fabric/gradle/wrapper/gradle-wrapper.properties b/24w33a-24w45a/gradle/wrapper/gradle-wrapper.properties similarity index 93% rename from 24w33a-fabric/gradle/wrapper/gradle-wrapper.properties rename to 24w33a-24w45a/gradle/wrapper/gradle-wrapper.properties index 9355b41..df97d72 100644 --- a/24w33a-fabric/gradle/wrapper/gradle-wrapper.properties +++ b/24w33a-24w45a/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/24w33a-fabric/gradlew b/24w33a-24w45a/gradlew old mode 100755 new mode 100644 similarity index 100% rename from 24w33a-fabric/gradlew rename to 24w33a-24w45a/gradlew diff --git a/24w33a-fabric/gradlew.bat b/24w33a-24w45a/gradlew.bat similarity index 100% rename from 24w33a-fabric/gradlew.bat rename to 24w33a-24w45a/gradlew.bat diff --git a/24w33a-fabric/settings.gradle b/24w33a-24w45a/settings.gradle similarity index 100% rename from 24w33a-fabric/settings.gradle rename to 24w33a-24w45a/settings.gradle diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java new file mode 100644 index 0000000..ffbd207 --- /dev/null +++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java @@ -0,0 +1,93 @@ +package cn.flowerinsnow.greatscrollabletooltips; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.item.ItemStack; +import net.minecraft.util.crash.CrashReport; +import cn.flowerinsnow.greatscrollabletooltips.common.config.GreatScrollableTooltipsConfig; +import cn.flowerinsnow.greatscrollabletooltips.common.object.ScrollSession; +import cn.flowerinsnow.greatscrollabletooltips.common.provider.ModEnvironmentProvider; +import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenKeyPressedEvent; +import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenMouseScrollEvent; +import cn.flowerinsnow.greatscrollabletooltips.event.RenderTooltipEvent; +import cn.flowerinsnow.greatscrollabletooltips.event.ScreenCloseEvent; +import cn.flowerinsnow.greatscrollabletooltips.listener.EventTriggerListener; +import cn.flowerinsnow.greatscrollabletooltips.listener.KeyScrollListener; +import cn.flowerinsnow.greatscrollabletooltips.listener.MouseScrollListener; +import cn.flowerinsnow.greatscrollabletooltips.listener.ScrollingStatusListener; +import cn.flowerinsnow.greatscrollabletooltips.manager.KeyBindingManager; + +import java.io.InputStream; +import java.nio.file.Path; + +@Environment(EnvType.CLIENT) +public class GreatScrollableTooltips implements ClientModInitializer { + public static final String MODID = "great-scrollable-tooltips"; + + private static GreatScrollableTooltips instance; + + private GreatScrollableTooltipsConfig config; + + private ScrollSession scrollSession; + + @Override + public void onInitializeClient() { + GreatScrollableTooltips.instance = this; + this.scrollSession = new ScrollSession<>(); + + this.initConfig(); + this.initListeners(); + this.initKeyBindings(); + } + + private void initConfig() { + this.config = new GreatScrollableTooltipsConfig(new ModEnvironmentProvider() { + @Override + public InputStream getDefaultConfigAsStream() { + return GreatScrollableTooltips.class.getResourceAsStream("/config.toml"); + } + + @Override + public Path getConfigFile() { + return FabricLoader.getInstance().getConfigDir().resolve(GreatScrollableTooltips.MODID + ".toml"); + } + + @Override + public void crash(Throwable throwable, String msg) { + MinecraftClient.getInstance().printCrashReport(CrashReport.create(throwable, msg)); + } + }); + this.config.saveDefaultConfig(); + this.config.load(); + } + + private void initListeners() { + ClientTickEvents.END_CLIENT_TICK.register(new EventTriggerListener()); + PreScreenKeyPressedEvent.EVENT.register(new KeyScrollListener(this)); + PreScreenMouseScrollEvent.EVENT.register(new MouseScrollListener(this)); + ScrollingStatusListener scrollingStatusListener = new ScrollingStatusListener(this); + RenderTooltipEvent.Pre.EVENT.register(scrollingStatusListener); + RenderTooltipEvent.Miss.EVENT.register(scrollingStatusListener); + ScreenCloseEvent.EVENT.register(scrollingStatusListener); + } + + private void initKeyBindings() { + KeyBindingManager.registerAll(); + } + + public static GreatScrollableTooltips getInstance() { + return GreatScrollableTooltips.instance; + } + + public GreatScrollableTooltipsConfig getConfig() { + return this.config; + } + + public ScrollSession getScrollSession() { + return this.scrollSession; + } +} diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenKeyPressedEvent.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenKeyPressedEvent.java new file mode 100644 index 0000000..c0e635b --- /dev/null +++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenKeyPressedEvent.java @@ -0,0 +1,23 @@ +package cn.flowerinsnow.greatscrollabletooltips.event; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.util.ActionResult; + +@Environment(EnvType.CLIENT) +public interface PreScreenKeyPressedEvent { + Event EVENT = EventFactory.createArrayBacked(PreScreenKeyPressedEvent.class, listeners -> (screen, keyCode, scanCode, modifiers) -> { + for (PreScreenKeyPressedEvent listener : listeners) { + ActionResult actionResult = listener.preScreenKeyPressed(screen, keyCode, scanCode, modifiers); + if (actionResult != ActionResult.PASS) { + return actionResult; + } + } + return ActionResult.PASS; + }); + + ActionResult preScreenKeyPressed(HandledScreen screen, int keyCode, int scanCode, int modifiers); +} diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenMouseScrollEvent.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenMouseScrollEvent.java new file mode 100644 index 0000000..601f19c --- /dev/null +++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/PreScreenMouseScrollEvent.java @@ -0,0 +1,23 @@ +package cn.flowerinsnow.greatscrollabletooltips.event; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.util.ActionResult; + +@Environment(EnvType.CLIENT) +public interface PreScreenMouseScrollEvent { + Event EVENT = EventFactory.createArrayBacked(PreScreenMouseScrollEvent.class, listeners -> (screen, mouseX, mouseY, horizontalAmount, verticalAmount) -> { + for (PreScreenMouseScrollEvent listener : listeners) { + ActionResult actionResult = listener.preScreenMouseScrolled(screen, mouseX, mouseY, horizontalAmount, verticalAmount); + if (actionResult != ActionResult.PASS) { + return actionResult; + } + } + return ActionResult.PASS; + }); + + ActionResult preScreenMouseScrolled(HandledScreen screen, double mouseX, double mouseY, double horizontalAmount, double verticalAmount); +} diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/RenderTooltipEvent.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/RenderTooltipEvent.java new file mode 100644 index 0000000..7d27e4a --- /dev/null +++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/RenderTooltipEvent.java @@ -0,0 +1,41 @@ +package cn.flowerinsnow.greatscrollabletooltips.event; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.screen.slot.Slot; +import net.minecraft.util.ActionResult; + +@Environment(EnvType.CLIENT) +public interface RenderTooltipEvent { + interface Pre { + Event
 EVENT = EventFactory.createArrayBacked(Pre.class, listeners -> (screen, context, x, y, focusedSlot) -> {
+            for (Pre listener : listeners) {
+                ActionResult actionResult = listener.preRenderTooltip(screen, context, x, y, focusedSlot);
+                if (actionResult != ActionResult.PASS) {
+                    return actionResult;
+                }
+            }
+            return ActionResult.PASS;
+        });
+
+        ActionResult preRenderTooltip(HandledScreen screen, DrawContext context, int x, int y, Slot focusedSlot);
+    }
+
+    interface Miss {
+        Event EVENT = EventFactory.createArrayBacked(Miss.class, listeners -> screen -> {
+            for (Miss listener : listeners) {
+                ActionResult actionResult = listener.missRenderTooltip(screen);
+                if (actionResult != ActionResult.PASS) {
+                    return actionResult;
+                }
+            }
+            return ActionResult.PASS;
+        });
+
+        ActionResult missRenderTooltip(HandledScreen screen);
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/ScreenCloseEvent.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/ScreenCloseEvent.java
new file mode 100644
index 0000000..f73549e
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/event/ScreenCloseEvent.java
@@ -0,0 +1,23 @@
+package cn.flowerinsnow.greatscrollabletooltips.event;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.event.Event;
+import net.fabricmc.fabric.api.event.EventFactory;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.util.ActionResult;
+
+@Environment(EnvType.CLIENT)
+public interface ScreenCloseEvent {
+    Event EVENT = EventFactory.createArrayBacked(ScreenCloseEvent.class, listeners -> (screen) -> {
+        for (ScreenCloseEvent event : listeners) {
+            ActionResult actionResult = event.onScreenClose(screen);
+            if (actionResult != ActionResult.PASS) {
+                return actionResult;
+            }
+        }
+        return ActionResult.PASS;
+    });
+
+    ActionResult onScreenClose(Screen oldScreen);
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/EventTriggerListener.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/EventTriggerListener.java
new file mode 100644
index 0000000..62d68b3
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/EventTriggerListener.java
@@ -0,0 +1,21 @@
+package cn.flowerinsnow.greatscrollabletooltips.listener;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import cn.flowerinsnow.greatscrollabletooltips.event.ScreenCloseEvent;
+
+@Environment(EnvType.CLIENT)
+public class EventTriggerListener implements ClientTickEvents.EndTick {
+    private Screen oldScreen;
+
+    @Override
+    public void onEndTick(MinecraftClient client) {
+        if (this.oldScreen != client.currentScreen) {
+            ScreenCloseEvent.EVENT.invoker().onScreenClose(this.oldScreen);
+            this.oldScreen = client.currentScreen;
+        }
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/KeyScrollListener.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/KeyScrollListener.java
new file mode 100644
index 0000000..f9567cc
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/KeyScrollListener.java
@@ -0,0 +1,34 @@
+package cn.flowerinsnow.greatscrollabletooltips.listener;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ActionResult;
+import cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips;
+import cn.flowerinsnow.greatscrollabletooltips.common.object.ScrollSession;
+import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenKeyPressedEvent;
+import cn.flowerinsnow.greatscrollabletooltips.manager.KeyBindingManager;
+
+@Environment(EnvType.CLIENT)
+public record KeyScrollListener(GreatScrollableTooltips main) implements PreScreenKeyPressedEvent {
+    @Override
+    public ActionResult preScreenKeyPressed(HandledScreen screen, int keyCode, int scanCode, int modifiers) {
+        ScrollSession session = this.main.getScrollSession();
+        if (session.isRendering()) {
+            if (KeyBindingManager.KEY_BINDING_SCROLL_UP.get().matchesKey(keyCode, scanCode)) {
+                session.addVertical(1);
+            }
+            if (KeyBindingManager.KEY_BINDING_SCROLL_LEFT.get().matchesKey(keyCode, scanCode)) {
+                session.addHorizontal(1);
+            }
+            if (KeyBindingManager.KEY_BINDING_SCROLL_DOWN.get().matchesKey(keyCode, scanCode)) {
+                session.addVertical(-1);
+            }
+            if (KeyBindingManager.KEY_BINDING_SCROLL_RIGHT.get().matchesKey(keyCode, scanCode)) {
+                session.addHorizontal(-1);
+            }
+        }
+        return ActionResult.PASS;
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/MouseScrollListener.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/MouseScrollListener.java
new file mode 100644
index 0000000..c18abc7
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/MouseScrollListener.java
@@ -0,0 +1,41 @@
+package cn.flowerinsnow.greatscrollabletooltips.listener;
+
+import cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips;
+import cn.flowerinsnow.greatscrollabletooltips.common.object.ScrollSession;
+import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenMouseScrollEvent;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ActionResult;
+
+@Environment(EnvType.CLIENT)
+public record MouseScrollListener(GreatScrollableTooltips main) implements PreScreenMouseScrollEvent {
+    @Override
+    public ActionResult preScreenMouseScrolled(HandledScreen screen, double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
+        if (!this.main.getConfig().enable) {
+            return ActionResult.PASS;
+        }
+
+        ScrollSession session = this.main.getScrollSession();
+        if (!session.isRendering()) {
+            return ActionResult.PASS;
+        }
+
+        int i = Double.compare(horizontalAmount, 0.0);
+        if (!Screen.hasShiftDown()) {
+            session.addHorizontal(i);
+        } else {
+            session.addVertical(i);
+        }
+
+        i = Double.compare(verticalAmount, 0.0);
+        if (!Screen.hasShiftDown()) {
+            session.addVertical(i);
+        } else {
+            session.addHorizontal(i);
+        }
+        return ActionResult.PASS;
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/ScrollingStatusListener.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/ScrollingStatusListener.java
new file mode 100644
index 0000000..d9e195c
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/listener/ScrollingStatusListener.java
@@ -0,0 +1,55 @@
+package cn.flowerinsnow.greatscrollabletooltips.listener;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.item.ItemStack;
+import net.minecraft.screen.slot.Slot;
+import net.minecraft.util.ActionResult;
+import cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips;
+import cn.flowerinsnow.greatscrollabletooltips.common.object.ScrollSession;
+import cn.flowerinsnow.greatscrollabletooltips.event.RenderTooltipEvent;
+import cn.flowerinsnow.greatscrollabletooltips.event.ScreenCloseEvent;
+
+/**
+ * 处理滚动状态
+ */
+@Environment(EnvType.CLIENT)
+public record ScrollingStatusListener(GreatScrollableTooltips main) implements RenderTooltipEvent.Pre, RenderTooltipEvent.Miss, ScreenCloseEvent {
+    @Override
+    public ActionResult preRenderTooltip(HandledScreen screen, DrawContext context, int x, int y, Slot focusedSlot) {
+        ScrollSession session = this.main.getScrollSession();
+        session.setRendering(true);
+        ItemStack itemStack = focusedSlot.getStack();
+        if (itemStack != session.getLastItemStackRendered()) {
+            session.setLastItemStackRendered(itemStack);
+
+            if (this.main.getConfig().autoReset) {
+                session.resetScroll();
+            }
+        }
+        return ActionResult.PASS;
+    }
+
+    @Override
+    public ActionResult missRenderTooltip(HandledScreen screen) {
+        ScrollSession session = this.main.getScrollSession();
+        session.setRendering(false);
+        session.setLastItemStackRendered(null);
+        if (this.main.getConfig().autoReset) {
+            session.resetScroll();;
+        }
+        return ActionResult.PASS;
+    }
+
+    @Override
+    public ActionResult onScreenClose(Screen oldScreen) {
+        ScrollSession session = this.main.getScrollSession();
+        session.setLastItemStackRendered(null);
+        session.setRendering(false);
+        session.resetScroll();
+        return ActionResult.PASS;
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/manager/KeyBindingManager.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/manager/KeyBindingManager.java
new file mode 100644
index 0000000..875b856
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/manager/KeyBindingManager.java
@@ -0,0 +1,23 @@
+package cn.flowerinsnow.greatscrollabletooltips.manager;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
+import net.minecraft.client.option.KeyBinding;
+import cn.flowerinsnow.greatscrollabletooltips.util.Lazy;
+import org.lwjgl.glfw.GLFW;
+
+@Environment(EnvType.CLIENT)
+public class KeyBindingManager {
+    public static final Lazy KEY_BINDING_SCROLL_UP = new Lazy<>(() -> new KeyBinding("great-scrollable-tooltips.key-binding.scroll-up", GLFW.GLFW_KEY_UP, "great-scrollable-tooltips.key-binding.category"));
+    public static final Lazy KEY_BINDING_SCROLL_LEFT = new Lazy<>(() -> new KeyBinding("great-scrollable-tooltips.key-binding.scroll-left", GLFW.GLFW_KEY_LEFT, "great-scrollable-tooltips.key-binding.category"));
+    public static final Lazy KEY_BINDING_SCROLL_DOWN = new Lazy<>(() -> new KeyBinding("great-scrollable-tooltips.key-binding.scroll-down", GLFW.GLFW_KEY_DOWN, "great-scrollable-tooltips.key-binding.category"));
+    public static final Lazy KEY_BINDING_SCROLL_RIGHT = new Lazy<>(() -> new KeyBinding("great-scrollable-tooltips.key-binding.scroll-right", GLFW.GLFW_KEY_RIGHT, "great-scrollable-tooltips.key-binding.category"));
+
+    public static void registerAll() {
+        KeyBindingHelper.registerKeyBinding(KEY_BINDING_SCROLL_UP.get());
+        KeyBindingHelper.registerKeyBinding(KEY_BINDING_SCROLL_LEFT.get());
+        KeyBindingHelper.registerKeyBinding(KEY_BINDING_SCROLL_DOWN.get());
+        KeyBindingHelper.registerKeyBinding(KEY_BINDING_SCROLL_RIGHT.get());
+    }
+}
diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java
similarity index 85%
rename from 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java
rename to 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java
index de367f7..5ab5dab 100644
--- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/AccessorSliderWidget.java
@@ -1,4 +1,4 @@
-package online.flowerinsnow.greatscrollabletooltips.mixin;
+package cn.flowerinsnow.greatscrollabletooltips.mixin;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java
new file mode 100644
index 0000000..f6d2eac
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java
@@ -0,0 +1,42 @@
+package cn.flowerinsnow.greatscrollabletooltips.mixin;
+
+import cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.gui.DrawContext;
+import org.objectweb.asm.Opcodes;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+
+@Mixin(DrawContext.class)
+@Environment(EnvType.CLIENT)
+public class MixinDrawContext {
+    @ModifyVariable(
+            method = "drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;IILnet/minecraft/client/gui/tooltip/TooltipPositioner;Lnet/minecraft/util/Identifier;)V",
+            at = @At(
+                    value = "STORE",
+                    opcode = Opcodes.ISTORE,
+                    ordinal = 0
+            ),
+            index = 12
+    )
+    public int modifyX(int x) {
+        GreatScrollableTooltips main = GreatScrollableTooltips.getInstance();
+        return x + (main.getScrollSession().getHorizontal() * main.getConfig().sensitivity);
+    }
+
+    @ModifyVariable(
+            method = "drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;IILnet/minecraft/client/gui/tooltip/TooltipPositioner;Lnet/minecraft/util/Identifier;)V",
+            at = @At(
+                    value = "STORE",
+                    opcode = Opcodes.ISTORE,
+                    ordinal = 0
+            ),
+            index = 13
+    )
+    public int modifyY(int x) {
+        GreatScrollableTooltips main = GreatScrollableTooltips.getInstance();
+        return x + (main.getScrollSession().getVertical() * main.getConfig().sensitivity);
+    }
+}
diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java
similarity index 52%
rename from 24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java
rename to 24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java
index d0517ae..7d10310 100644
--- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/mixin/MixinHandledScreen.java
@@ -1,17 +1,15 @@
-package online.flowerinsnow.greatscrollabletooltips.mixin;
+package cn.flowerinsnow.greatscrollabletooltips.mixin;
 
 import net.fabricmc.api.EnvType;
 import net.fabricmc.api.Environment;
 import net.minecraft.client.gui.DrawContext;
 import net.minecraft.client.gui.screen.Screen;
 import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import net.minecraft.item.ItemStack;
 import net.minecraft.screen.ScreenHandler;
 import net.minecraft.screen.slot.Slot;
-import net.minecraft.text.Text;
-import net.minecraft.util.ActionResult;
-import online.flowerinsnow.greatscrollabletooltips.event.HandledScreenKeyPressedEvent;
-import online.flowerinsnow.greatscrollabletooltips.event.RenderMouseoverTooltipEvent;
+import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenKeyPressedEvent;
+import cn.flowerinsnow.greatscrollabletooltips.event.PreScreenMouseScrollEvent;
+import cn.flowerinsnow.greatscrollabletooltips.event.RenderTooltipEvent;
 import org.spongepowered.asm.mixin.Final;
 import org.spongepowered.asm.mixin.Mixin;
 import org.spongepowered.asm.mixin.Shadow;
@@ -21,11 +19,9 @@
 import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
 import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
 
-import java.util.List;
-
 @Mixin(HandledScreen.class)
 @Environment(EnvType.CLIENT)
-public abstract class MixinHandledScreen extends Screen {
+public class MixinHandledScreen extends Screen {
     @Unique
     @SuppressWarnings("unchecked")
     private final HandledScreen THIS = (HandledScreen) (Object) this;
@@ -37,36 +33,33 @@ public abstract class MixinHandledScreen extends Screen
     @Shadow
     protected Slot focusedSlot;
 
-    @Shadow
-    protected abstract List getTooltipFromItem(ItemStack stack);
-
     protected MixinHandledScreen() {
         super(null);
     }
 
-
-    @Inject(
-            method = "keyPressed",
-            at = @At("HEAD"),
-            cancellable = true
-    )
-    public void keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) {
-        ActionResult actionResult = HandledScreenKeyPressedEvent.EVENT.invoker().keyPressed(keyCode, scanCode, modifiers);
-        if (actionResult == ActionResult.SUCCESS || actionResult == ActionResult.FAIL) {
-            cir.setReturnValue(false);
-        }
-    }
-
     @Inject(
             method = "drawMouseoverTooltip",
-            at = @At("RETURN")
+            at = @At("HEAD")
     )
     public void drawMouseoverTooltip(DrawContext context, int x, int y, CallbackInfo ci) {
         if (this.handler.getCursorStack().isEmpty() && this.focusedSlot != null && this.focusedSlot.hasStack()) {
-            ItemStack itemStack = this.focusedSlot.getStack();
-            RenderMouseoverTooltipEvent.Post.EVENT.invoker().endDrawMouseoverTooltip(this.THIS, this.textRenderer, itemStack, this.getTooltipFromItem(itemStack), context, x, y);
+            RenderTooltipEvent.Pre.EVENT.invoker().preRenderTooltip(this.THIS, context, x, y, this.focusedSlot);
         } else {
-            RenderMouseoverTooltipEvent.Miss.EVENT.invoker().onMiss(THIS);
+            RenderTooltipEvent.Miss.EVENT.invoker().missRenderTooltip(this.THIS);
         }
     }
+
+    @Inject(
+            method = "keyPressed",
+            at = @At("HEAD")
+    )
+    public void preKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) {
+        PreScreenKeyPressedEvent.EVENT.invoker().preScreenKeyPressed(this.THIS, keyCode, scanCode, modifiers);
+    }
+
+    @Override
+    public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
+        PreScreenMouseScrollEvent.EVENT.invoker().preScreenMouseScrolled(this.THIS, mouseX, mouseY, horizontalAmount, verticalAmount);
+        return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount);
+    }
 }
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/modmenu/ModMenuImpl.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/modmenu/ModMenuImpl.java
new file mode 100644
index 0000000..37e11d3
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/modmenu/ModMenuImpl.java
@@ -0,0 +1,16 @@
+package cn.flowerinsnow.greatscrollabletooltips.modmenu;
+
+import com.terraformersmc.modmenu.api.ConfigScreenFactory;
+import com.terraformersmc.modmenu.api.ModMenuApi;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips;
+import cn.flowerinsnow.greatscrollabletooltips.screen.ConfigScreen;
+
+@Environment(EnvType.CLIENT)
+public class ModMenuImpl implements ModMenuApi {
+    @Override
+    public ConfigScreenFactory getModConfigScreenFactory() {
+        return parent -> new ConfigScreen(parent, GreatScrollableTooltips.getInstance().getConfig());
+    }
+}
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java
new file mode 100644
index 0000000..53ddad4
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java
@@ -0,0 +1,143 @@
+package cn.flowerinsnow.greatscrollabletooltips.screen;
+
+import cn.flowerinsnow.greatscrollabletooltips.common.config.GreatScrollableTooltipsConfig;
+import cn.flowerinsnow.greatscrollabletooltips.mixin.AccessorSliderWidget;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.client.gui.widget.SliderWidget;
+import net.minecraft.text.Text;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+@Environment(EnvType.CLIENT)
+public class ConfigScreen extends Screen {
+    private final Screen parent;
+    private final GreatScrollableTooltipsConfig config;
+    private SliderWidget sensitivitySlider;
+    public ConfigScreen(Screen parent, GreatScrollableTooltipsConfig config) {
+        super(Text.translatable("great-scrollable-tooltips.ui.title"));
+        this.parent = parent;
+        this.config = config;
+    }
+
+    @Override
+    protected void init() {
+        this.addDrawableChild(
+                ButtonWidget.builder(
+                        Text.translatable(this.config.enable ? "great-scrollable-tooltips.ui.config.enable.true" : "great-scrollable-tooltips.ui.config.enable.false"),
+                        button -> {
+                            GreatScrollableTooltipsConfig config = ConfigScreen.this.config;
+                            button.setMessage(Text.translatable(config.enable ? "great-scrollable-tooltips.ui.config.enable.false" : "great-scrollable-tooltips.ui.config.enable.true"));
+                            config.enable = !config.enable;
+                        }
+                )
+                        .position(this.width / 2 - 100, this.height / 2 - 70)
+                        .size(200, 20)
+                        .build()
+        );
+
+        this.addDrawableChild(
+                ButtonWidget.builder(
+                                Text.translatable(this.config.autoReset ? "great-scrollable-tooltips.ui.config.auto-reset.true" : "great-scrollable-tooltips.ui.config.auto-reset.false"),
+                                button -> {
+                                    GreatScrollableTooltipsConfig config = ConfigScreen.this.config;
+                                    button.setMessage(Text.translatable(config.autoReset ? "great-scrollable-tooltips.ui.config.auto-reset.false" : "great-scrollable-tooltips.ui.config.auto-reset.true"));
+                                    config.autoReset = !config.autoReset;
+                                }
+                )
+                        .position(this.width / 2 - 100, this.height / 2 - 45)
+                        .size(200, 20)
+                        .build()
+        );
+
+        this.addDrawableChild(
+                this.sensitivitySlider = new SliderWidget(
+                        this.width / 2 - 100, this.height / 2 - 20,
+                        200, 20,
+                        Text.translatable("great-scrollable-tooltips.ui.config.sensitivity", this.config.sensitivity),
+                        new BigDecimal(this.config.sensitivity)
+                                .add(new BigDecimal(-1))
+                                .divide(new BigDecimal(99), 2, RoundingMode.UP)
+                                .doubleValue()
+                ) {
+                    @Override
+                    protected void updateMessage() {
+                        this.setMessage(
+                                Text.translatable(
+                                        "great-scrollable-tooltips.ui.config.sensitivity",
+                                        BigDecimal.valueOf(this.value)
+                                                .multiply(new BigDecimal(99))
+                                                .add(BigDecimal.ONE)
+                                                .setScale(0, RoundingMode.DOWN)
+                                                .intValue()
+                                )
+                        );
+                    }
+
+                    @Override
+                    protected void applyValue() {
+                    }
+                }
+        );
+
+        this.addDrawableChild(
+                ButtonWidget.builder(
+                                Text.translatable("great-scrollable-tooltips.ui.config.reload"),
+                                button -> {
+                                    ConfigScreen instance = ConfigScreen.this;
+                                    instance.config.load();
+                                    MinecraftClient.getInstance().setScreen(new ConfigScreen(instance.parent, instance.config));
+                                }
+                )
+                        .position(this.width / 2 - 100, this.height / 2 + 5)
+                        .size(200, 20)
+                        .build()
+        );
+
+        this.addDrawableChild(
+                ButtonWidget.builder(
+                        Text.translatable("great-scrollable-tooltips.ui.config.save-and-exit"),
+                        button -> {
+                            ConfigScreen screen = ConfigScreen.this;
+                            GreatScrollableTooltipsConfig config = screen.config;
+                            config.sensitivity = BigDecimal.valueOf(((AccessorSliderWidget) screen.sensitivitySlider).getValue())
+                                    .multiply(new BigDecimal(99))
+                                    .add(BigDecimal.ONE)
+                                    .setScale(0, RoundingMode.DOWN)
+                                    .intValue();
+                            config.save();
+                            MinecraftClient.getInstance().setScreen(screen.parent);
+                        }
+                )
+                        .position(this.width / 2 - 100, this.height / 2 + 30)
+                        .size(200, 20)
+                        .build()
+        );
+
+        this.addDrawableChild(
+                ButtonWidget.builder(
+                        Text.translatable("great-scrollable-tooltips.ui.config.discard-and-exit"),
+                        button -> MinecraftClient.getInstance().setScreen(ConfigScreen.this.parent)
+                )
+                        .position(this.width / 2 - 100, this.height / 2 + 55)
+                        .size(200, 20)
+                        .build()
+        );
+    }
+
+    @Override
+    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+        this.renderBackground(context, mouseX, mouseY, delta);
+        super.render(context, mouseX, mouseY, delta);
+        context.drawCenteredTextWithShadow(
+                this.textRenderer,
+                Text.translatable("great-scrollable-tooltips.ui.title"),
+                this.width / 2, 20, 0xFFFFFF
+        );
+    }
+}
\ No newline at end of file
diff --git a/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/util/Lazy.java b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/util/Lazy.java
new file mode 100644
index 0000000..2bc8605
--- /dev/null
+++ b/24w33a-24w45a/src/main/java/cn/flowerinsnow/greatscrollabletooltips/util/Lazy.java
@@ -0,0 +1,26 @@
+package cn.flowerinsnow.greatscrollabletooltips.util;
+
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+
+import java.util.Objects;
+import java.util.function.Supplier;
+
+@Environment(EnvType.CLIENT)
+public class Lazy {
+    private T value;
+    private final Supplier supplier;
+    private boolean supplied;
+
+    public Lazy(Supplier supplier) {
+        this.supplier = Objects.requireNonNull(supplier);
+    }
+
+    public T get() {
+        if (this.supplied) {
+            return this.value;
+        }
+        this.supplied = true;
+        return (this.value = this.supplier.get());
+    }
+}
\ No newline at end of file
diff --git a/24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/icon.png b/24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/icon.png
similarity index 100%
rename from 24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/icon.png
rename to 24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/icon.png
diff --git a/24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/lang/en_us.json b/24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/lang/en_us.json
similarity index 100%
rename from 24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/lang/en_us.json
rename to 24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/lang/en_us.json
diff --git a/24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/lang/zh_cn.json b/24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/lang/zh_cn.json
similarity index 100%
rename from 24w33a-fabric/src/main/resources/assets/great-scrollable-tooltips/lang/zh_cn.json
rename to 24w33a-24w45a/src/main/resources/assets/great-scrollable-tooltips/lang/zh_cn.json
diff --git a/24w33a-24w45a/src/main/resources/config.toml b/24w33a-24w45a/src/main/resources/config.toml
new file mode 100644
index 0000000..993c42c
--- /dev/null
+++ b/24w33a-24w45a/src/main/resources/config.toml
@@ -0,0 +1,3 @@
+enable = true
+sensitivity = 10
+auto_reset = true
\ No newline at end of file
diff --git a/24w33a-fabric/src/main/resources/fabric.mod.json b/24w33a-24w45a/src/main/resources/fabric.mod.json
similarity index 55%
rename from 24w33a-fabric/src/main/resources/fabric.mod.json
rename to 24w33a-24w45a/src/main/resources/fabric.mod.json
index 4eec639..3b003c8 100644
--- a/24w33a-fabric/src/main/resources/fabric.mod.json
+++ b/24w33a-24w45a/src/main/resources/fabric.mod.json
@@ -9,15 +9,18 @@
 	],
 	"contact": {
 		"homepage": "https://modrinth.com/project/great-scrollable-tooltips",
-		"sources": "https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips",
-		"issues": "https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues"
+		"sources": "https://github.com/flowerinsnowdh/GreatScrollableTooltips",
+		"issues": "https://github.com/flowerinsnowdh/GreatScrollableTooltips/issues"
 	},
 	"license": "MPL-2.0",
 	"icon": "assets/great-scrollable-tooltips/icon.png",
 	"environment": "client",
 	"entrypoints": {
 		"client": [
-			"online.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips"
+			"cn.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips"
+		],
+		"modmenu": [
+			"cn.flowerinsnow.greatscrollabletooltips.modmenu.ModMenuImpl"
 		]
 	},
 	"mixins": [
@@ -25,9 +28,12 @@
 	],
 	"depends": {
 		"fabricloader": ">=0.16.2",
-		"minecraft": "1.21.2-alpha.24.33.a",
+		"minecraft": ">=1.21.2-alpha.24.33.a <=1.21.4-alpha.24.45.a",
 		"java": ">=21",
-		"fabric-api": ">=0.102.2+1.21.2"
+		"fabric-api": ">=0.102.2"
+	},
+	"suggests": {
+		"modmenu": ">=12.0.0-alpha.1"
 	},
 	"breaks": {
 		"optifabric": "*"
@@ -35,7 +41,7 @@
 	"custom": {
 		"modmenu": {
 			"links": {
-				"modmenu.github_releases": "https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/releases"
+				"modmenu.github_releases": "https://github.com/flowerinsnowdh/GreatScrollableTooltips/releases"
 			}
 		}
 	}
diff --git a/24w33a-24w45a/src/main/resources/great-scrollable-tooltips.mixins.json b/24w33a-24w45a/src/main/resources/great-scrollable-tooltips.mixins.json
new file mode 100644
index 0000000..3c1f7b2
--- /dev/null
+++ b/24w33a-24w45a/src/main/resources/great-scrollable-tooltips.mixins.json
@@ -0,0 +1,13 @@
+{
+    "required": true,
+    "package": "cn.flowerinsnow.greatscrollabletooltips.mixin",
+    "compatibilityLevel": "JAVA_21",
+    "client": [
+        "AccessorSliderWidget",
+        "MixinDrawContext",
+        "MixinHandledScreen"
+    ],
+    "injectors": {
+        "defaultRequire": 1
+	}
+}
\ No newline at end of file
diff --git a/24w33a-fabric/gradle.properties b/24w33a-fabric/gradle.properties
deleted file mode 100644
index e64b242..0000000
--- a/24w33a-fabric/gradle.properties
+++ /dev/null
@@ -1,19 +0,0 @@
-# Done to increase the memory available to gradle.
-org.gradle.jvmargs=-Xmx1G -Dfile.encoding=UTF-8
-org.gradle.parallel=true
-
-# Fabric Properties
-# check these on https://fabricmc.net/develop
-minecraft_version=24w33a
-yarn_mappings=24w33a+build.21
-loader_version=0.16.2
-
-# Mod Properties
-mod_version=16.0.0-beta.1+fabric
-maven_group=online.flowerinsnow.greatscrollabletooltips
-archives_base_name=great-scrollable-tooltips
-
-# Dependencies
-fabric_version=0.102.2+1.21.2
-fnml4j_version=2.0.0-beta.3
-fabric_loom_version=1.8.0-alpha.6
\ No newline at end of file
diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java
deleted file mode 100644
index cc83daa..0000000
--- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/GreatScrollableTooltips.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package online.flowerinsnow.greatscrollabletooltips;
-
-import net.fabricmc.api.ClientModInitializer;
-import net.fabricmc.api.EnvType;
-import net.fabricmc.api.Environment;
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
-import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.ParentElement;
-import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.option.KeyBinding;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.ActionResult;
-import online.flowerinsnow.greatscrollabletooltips.config.Config;
-import online.flowerinsnow.greatscrollabletooltips.event.HandledScreenKeyPressedEvent;
-import online.flowerinsnow.greatscrollabletooltips.event.MouseScrolledInParentElementEvent;
-import online.flowerinsnow.greatscrollabletooltips.event.RenderMouseoverTooltipEvent;
-import online.flowerinsnow.greatscrollabletooltips.listener.CursorKeyListener;
-import org.lwjgl.glfw.GLFW;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Environment(EnvType.CLIENT)
-public class GreatScrollableTooltips implements ClientModInitializer {
-	public static final String MODID = "great-scrollable-tooltips";
-	public static final Logger LOGGER = LoggerFactory.getLogger(MODID);
-
-	private static GreatScrollableTooltips instance;
-
-	private Config config;
-
-	private int horizontal;
-	private int vertical;
-	private boolean rendering;
-
-	/**
-	 * 

最后一次渲染的物品

- *

记录以方便

- */ - private ItemStack lastItemStackRendered; - - public static final KeyBinding KEY_BINDING_SCROLL_UP = new KeyBinding("great-scrollable-tooltips.key-binding.scroll-up", GLFW.GLFW_KEY_UP, "great-scrollable-tooltips.key-binding.category"); - public static final KeyBinding KEY_BINDING_SCROLL_LEFT = new KeyBinding("great-scrollable-tooltips.key-binding.scroll-left", GLFW.GLFW_KEY_LEFT, "great-scrollable-tooltips.key-binding.category"); - public static final KeyBinding KEY_BINDING_SCROLL_DOWN = new KeyBinding("great-scrollable-tooltips.key-binding.scroll-down", GLFW.GLFW_KEY_DOWN, "great-scrollable-tooltips.key-binding.category"); - public static final KeyBinding KEY_BINDING_SCROLL_RIGHT = new KeyBinding("great-scrollable-tooltips.key-binding.scroll-right", GLFW.GLFW_KEY_RIGHT, "great-scrollable-tooltips.key-binding.category"); - - @Override - public void onInitializeClient() { - GreatScrollableTooltips.instance = this; - - this.config = new Config(); - this.config.saveDefaultConfig(); - this.config.load(); - - // 鼠标滚动时 - MouseScrolledInParentElementEvent.EVENT.register((ParentElement parentElement, double mouseX, double mouseY, double horizontalAmount, double verticalAmount) -> { - MinecraftClient client = MinecraftClient.getInstance(); - if (client.currentScreen != null && this.config.enable && this.rendering) { // 只有渲染物品提示时才允许滚动 - if (Screen.hasShiftDown()) { - this.horizontal += (int) verticalAmount; - this.vertical += (int) horizontalAmount; - } else { - this.horizontal += (int) horizontalAmount; - this.vertical += (int) verticalAmount; - } - } - return ActionResult.PASS; - }); - - // 渲染后 - RenderMouseoverTooltipEvent.Post.EVENT.register((screen, textRenderer, itemStack, tooltip, context, x, y) -> { - GreatScrollableTooltips instance = GreatScrollableTooltips.this; - instance.rendering = true; - if (itemStack != instance.lastItemStackRendered) { - instance.lastItemStackRendered = itemStack; - - if (instance.config.autoReset) { - instance.resetScroll(); - } - } - return ActionResult.PASS; - }); - - // 未渲染时 - RenderMouseoverTooltipEvent.Miss.EVENT.register(screen -> { - GreatScrollableTooltips instance = GreatScrollableTooltips.this; - instance.rendering = false; - instance.lastItemStackRendered = null; - if (instance.config.autoReset) { - instance.resetScroll(); - } - return ActionResult.PASS; - }); - - ClientTickEvents.END_CLIENT_TICK.register(client -> { - if (client.currentScreen == null) { - GreatScrollableTooltips.this.resetScroll(); - } - }); - - HandledScreenKeyPressedEvent.EVENT.register(new CursorKeyListener()); - - KeyBindingHelper.registerKeyBinding(GreatScrollableTooltips.KEY_BINDING_SCROLL_UP); - KeyBindingHelper.registerKeyBinding(GreatScrollableTooltips.KEY_BINDING_SCROLL_LEFT); - KeyBindingHelper.registerKeyBinding(GreatScrollableTooltips.KEY_BINDING_SCROLL_DOWN); - KeyBindingHelper.registerKeyBinding(GreatScrollableTooltips.KEY_BINDING_SCROLL_RIGHT); - } - - public static GreatScrollableTooltips getInstance() { - return instance; - } - - public Config getConfig() { - return this.config; - } - - public int getHorizontal() { - return this.horizontal; - } - - public void setHorizontal(int horizontal) { - this.horizontal = horizontal; - } - - public int getVertical() { - return this.vertical; - } - - public void setVertical(int vertical) { - this.vertical = vertical; - } - - /** - *

滚动回正

- */ - public void resetScroll() { - this.horizontal = 0; - this.vertical = 0; - } - - public boolean isRendering() { - return this.rendering; - } - - public int getModX() { - return this.getHorizontal() * this.getConfig().sensitivity; - } - - public int getModY() { - return this.getVertical() * this.getConfig().sensitivity; - } -} \ No newline at end of file diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/config/Config.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/config/Config.java deleted file mode 100644 index 8468959..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/config/Config.java +++ /dev/null @@ -1,82 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.config; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.util.crash.CrashReport; -import online.flowerinsnow.fnml4j.api.node.ObjectNode; -import online.flowerinsnow.fnml4j.api.node.StringNode; -import online.flowerinsnow.fnml4j.api.parser.present.FNML4JPresentParser; -import online.flowerinsnow.fnml4j.core.FNML4J; -import online.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.function.BiConsumer; - -@Environment(EnvType.CLIENT) -public class Config { - private ObjectNode rootNode; - - public boolean enable; - public int sensitivity; - public boolean autoReset; - - public void saveDefaultConfig() { - BiConsumer crashFunction = crashFunction(); - Path configFile = getConfigFile(); - File file = configFile.toFile(); - if (!file.exists()) { - try { - //noinspection ResultOfMethodCallIgnored - file.createNewFile(); - int len; - byte[] bytes = new byte[1024]; - try (InputStream in = GreatScrollableTooltips.class.getResourceAsStream("/config.conf")) { - try (FileOutputStream fos = new FileOutputStream(file)) { - //noinspection DataFlowIssue - while ((len = in.read(bytes)) != -1) { - fos.write(bytes, 0, len); - } - } - } - } catch (IOException e) { - crashFunction.accept(e, "Failed to save default config."); - } - } - } - - public void load() { - BiConsumer crashFunction = crashFunction(); - try { - this.rootNode = FNML4J.parse(getConfigFile(), StandardCharsets.UTF_8); - this.enable = Boolean.parseBoolean(this.rootNode.getChildNode("enable", FNML4JPresentParser.STRING, StringNode.class)); - this.sensitivity = this.rootNode.getChildNodeNotNull("sensitivity", FNML4JPresentParser.INT, StringNode.class); - this.autoReset = Boolean.parseBoolean(this.rootNode.getChildNode("auto_reset", FNML4JPresentParser.STRING, StringNode.class)); - } catch (IOException e) { - crashFunction.accept(e, "Failed to load config."); - } - } - - public void save() { - BiConsumer crashFunction = crashFunction(); - try (FileWriter fw = new FileWriter(getConfigFile().toFile(), StandardCharsets.UTF_8)) { - this.rootNode.set("enable", new StringNode(Boolean.toString(this.enable))); - this.rootNode.set("sensitivity", new StringNode(Integer.toString(this.sensitivity))); - this.rootNode.set("auto_reset", new StringNode(Boolean.toString(this.autoReset))); - this.rootNode.writeRoot(0, fw); - } catch (IOException e) { - crashFunction.accept(e, "Failed to save config."); - } - } - - public Path getConfigFile() { - return FabricLoader.getInstance().getConfigDir().resolve(GreatScrollableTooltips.MODID + ".conf"); - } - - private BiConsumer crashFunction() { - return (e, msg) -> MinecraftClient.getInstance().printCrashReport(CrashReport.create(e, msg)); - } -} \ No newline at end of file diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/HandledScreenKeyPressedEvent.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/HandledScreenKeyPressedEvent.java deleted file mode 100644 index 2ed72e8..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/HandledScreenKeyPressedEvent.java +++ /dev/null @@ -1,22 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.util.ActionResult; - -/** - * 返回 Success 或 Fail 时取消事件 - */ -public interface HandledScreenKeyPressedEvent { - Event EVENT = EventFactory.createArrayBacked(HandledScreenKeyPressedEvent.class, listeners -> (keyCode, scanCode, modifiers) -> { - for (HandledScreenKeyPressedEvent listener : listeners) { - ActionResult actionResult = listener.keyPressed(keyCode, scanCode, modifiers); - if (actionResult != ActionResult.PASS) { - return actionResult; - } - } - return ActionResult.PASS; - }); - - ActionResult keyPressed(int keyCode, int scanCode, int modifiers); -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/MouseScrolledInParentElementEvent.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/MouseScrolledInParentElementEvent.java deleted file mode 100644 index f3b35c4..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/MouseScrolledInParentElementEvent.java +++ /dev/null @@ -1,23 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.event; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.client.gui.ParentElement; -import net.minecraft.util.ActionResult; - -@Environment(EnvType.CLIENT) -public interface MouseScrolledInParentElementEvent { - Event EVENT = EventFactory.createArrayBacked(MouseScrolledInParentElementEvent.class, listeners -> (parentElement, mouseX, mouseY, horizontalAmount, verticalAmount) -> { - for (MouseScrolledInParentElementEvent listener : listeners) { - ActionResult actionResult = listener.onMouseScrolled(parentElement, mouseX, mouseY, horizontalAmount, verticalAmount); - if (actionResult != ActionResult.PASS) { - return actionResult; - } - } - return ActionResult.PASS; - }); - - ActionResult onMouseScrolled(ParentElement parentElement, double mouseX, double mouseY, double horizontalAmount, double verticalAmount); -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/RenderMouseoverTooltipEvent.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/RenderMouseoverTooltipEvent.java deleted file mode 100644 index 3173f89..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/event/RenderMouseoverTooltipEvent.java +++ /dev/null @@ -1,42 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.event; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.ingame.HandledScreen; -import net.minecraft.item.ItemStack; -import net.minecraft.text.Text; -import net.minecraft.util.ActionResult; - -import java.util.List; - -public interface RenderMouseoverTooltipEvent { - interface Post { - Event EVENT = EventFactory.createArrayBacked(Post.class, listeners -> (handledScreen, textRenderer, itemStack, tooltip, context, x, y) -> { - for (Post listener : listeners) { - ActionResult actionResult = listener.endDrawMouseoverTooltip(handledScreen, textRenderer, itemStack, tooltip, context, x, y); - if (actionResult != ActionResult.PASS) { - return actionResult; - } - } - return ActionResult.PASS; - }); - - ActionResult endDrawMouseoverTooltip(HandledScreen screen, TextRenderer textRenderer, ItemStack itemStack, List tooltip, DrawContext context, int x, int y); - } - - interface Miss { - Event EVENT = EventFactory.createArrayBacked(Miss.class, listeners -> screen -> { - for (Miss listener : listeners) { - ActionResult actionResult = listener.onMiss(screen); - if (actionResult != ActionResult.PASS) { - return actionResult; - } - } - return ActionResult.PASS; - }); - - ActionResult onMiss(HandledScreen screen); - } -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/listener/CursorKeyListener.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/listener/CursorKeyListener.java deleted file mode 100644 index 1575b2b..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/listener/CursorKeyListener.java +++ /dev/null @@ -1,32 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.listener; - -import net.minecraft.util.ActionResult; -import online.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips; -import online.flowerinsnow.greatscrollabletooltips.event.HandledScreenKeyPressedEvent; - -public class CursorKeyListener implements HandledScreenKeyPressedEvent { - @Override - public ActionResult keyPressed(int keyCode, int scanCode, int modifiers) { - final GreatScrollableTooltips instance = GreatScrollableTooltips.getInstance(); - - if (instance.isRendering()) { - if (GreatScrollableTooltips.KEY_BINDING_SCROLL_UP.matchesKey(keyCode, scanCode)) { - instance.setVertical(instance.getVertical() + 1); - return ActionResult.SUCCESS; - } - if (GreatScrollableTooltips.KEY_BINDING_SCROLL_LEFT.matchesKey(keyCode, scanCode)) { - instance.setHorizontal(instance.getHorizontal() + 1); - return ActionResult.SUCCESS; - } - if (GreatScrollableTooltips.KEY_BINDING_SCROLL_DOWN.matchesKey(keyCode, scanCode)) { - instance.setVertical(instance.getVertical() - 1); - return ActionResult.SUCCESS; - } - if (GreatScrollableTooltips.KEY_BINDING_SCROLL_RIGHT.matchesKey(keyCode, scanCode)) { - instance.setHorizontal(instance.getHorizontal() - 1); - return ActionResult.SUCCESS; - } - } - return ActionResult.PASS; - } -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java deleted file mode 100644 index 4366270..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinDrawContext.java +++ /dev/null @@ -1,42 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.mixin; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.DrawContext; -import online.flowerinsnow.greatscrollabletooltips.GreatScrollableTooltips; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyArgs; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; - -@Mixin(DrawContext.class) -@Environment(EnvType.CLIENT) -public class MixinDrawContext { - @ModifyArgs( - method = "drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;IILnet/minecraft/client/gui/tooltip/TooltipPositioner;)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/tooltip/TooltipComponent;drawText(Lnet/minecraft/client/font/TextRenderer;IILorg/joml/Matrix4f;Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;)V", - ordinal = 0 - ) - ) - public void modifyTextPos(Args args) { - GreatScrollableTooltips instance = GreatScrollableTooltips.getInstance(); - args.set(1, ((int) args.get(1)) + instance.getModX()); - args.set(2, ((int) args.get(2)) + instance.getModY()); - } - - @ModifyArgs( - method = "drawTooltip(Lnet/minecraft/client/font/TextRenderer;Ljava/util/List;IILnet/minecraft/client/gui/tooltip/TooltipPositioner;)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/gui/tooltip/TooltipBackgroundRenderer;render(Lnet/minecraft/client/gui/DrawContext;IIIII)V", - ordinal = 0 - ) - ) - public void modifyBackground(Args args) { - GreatScrollableTooltips instance = GreatScrollableTooltips.getInstance(); - args.set(1, ((int) args.get(1)) + instance.getModX()); - args.set(2, ((int) args.get(2)) + instance.getModY()); - } -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinInventoryScreen.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinInventoryScreen.java deleted file mode 100644 index c4c9d3d..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixin/MixinInventoryScreen.java +++ /dev/null @@ -1,29 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.mixin; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.screen.PlayerScreenHandler; -import net.minecraft.util.ActionResult; -import online.flowerinsnow.greatscrollabletooltips.event.MouseScrolledInParentElementEvent; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(InventoryScreen.class) -@Environment(EnvType.CLIENT) -public abstract class MixinInventoryScreen extends AbstractInventoryScreen { - public MixinInventoryScreen() { - //noinspection DataFlowIssue - super(null, null, null); - } - - @Override - public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { - ActionResult actionResult = MouseScrolledInParentElementEvent.EVENT.invoker() - .onMouseScrolled(this, mouseX, mouseY, horizontalAmount, verticalAmount); - if (actionResult == ActionResult.FAIL) { - return false; - } - return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); - } -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixinplugin/GSTMixinPlugin.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixinplugin/GSTMixinPlugin.java deleted file mode 100644 index f78e65c..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/mixinplugin/GSTMixinPlugin.java +++ /dev/null @@ -1,41 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.mixinplugin; - -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Set; - -public class GSTMixinPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - return true; - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - } -} diff --git a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java b/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java deleted file mode 100644 index 3ab786e..0000000 --- a/24w33a-fabric/src/main/java/online/flowerinsnow/greatscrollabletooltips/screen/ConfigScreen.java +++ /dev/null @@ -1,122 +0,0 @@ -package online.flowerinsnow.greatscrollabletooltips.screen; - -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.gui.widget.SliderWidget; -import net.minecraft.text.Text; -import online.flowerinsnow.greatscrollabletooltips.config.Config; -import online.flowerinsnow.greatscrollabletooltips.mixin.AccessorSliderWidget; - -import java.math.BigDecimal; -import java.math.RoundingMode; - -@Environment(EnvType.CLIENT) -public class ConfigScreen extends Screen { - private final Screen parent; - private final Config config; - private SliderWidget sensitivitySlider; - public ConfigScreen(Screen parent, Config config) { - super(Text.translatable("great-scrollable-tooltips.ui.title")); - this.parent = parent; - this.config = config; - } - - @Override - protected void init() { - this.addDrawableChild( - ButtonWidget.builder( - Text.translatable(config.enable ? "great-scrollable-tooltips.ui.config.enable.true" : "great-scrollable-tooltips.ui.config.enable.false"), - button -> { - if (config.enable) { - button.setMessage(Text.translatable("great-scrollable-tooltips.ui.config.enable.false")); - config.enable = false; - } else { - button.setMessage(Text.translatable("great-scrollable-tooltips.ui.config.enable.true")); - config.enable = true; - } - }) - .position(this.width / 2 - 100, this.height / 2 - 60) - .size(200, 20) - .build() - ); - - this.addDrawableChild( - ButtonWidget.builder( - Text.translatable(config.autoReset ? "great-scrollable-tooltips.ui.config.auto-reset.true" : "great-scrollable-tooltips.ui.config.auto-reset.false"), - button -> { - if (config.autoReset) { - button.setMessage(Text.translatable("great-scrollable-tooltips.ui.config.auto-reset.false")); - config.autoReset = false; - } else { - button.setMessage(Text.translatable("great-scrollable-tooltips.ui.config.auto-reset.true")); - config.autoReset = true; - } - }) - .position(this.width / 2 - 100, this.height / 2 - 45) - .size(200, 20) - .build() - ); - - this.addDrawableChild( - sensitivitySlider = new SliderWidget(this.width / 2 - 100, this.height / 2 - 35, - 200, 20, Text.translatable( - "great-scrollable-tooltips.ui.config.sensitivity", - config.sensitivity - ), new BigDecimal(config.sensitivity).add(new BigDecimal(-1)).divide(new BigDecimal(99), 2, RoundingMode.UP).doubleValue()) { - @Override - protected void updateMessage() { - setMessage(Text.translatable( - "great-scrollable-tooltips.ui.config.sensitivity", - BigDecimal.valueOf(value).multiply(new BigDecimal(99)).add(BigDecimal.ONE).setScale(0, RoundingMode.DOWN).intValue() - )); - } - - @Override - protected void applyValue() { - } - } - ); - this.addDrawableChild( - ButtonWidget.builder( - Text.translatable("great-scrollable-tooltips.ui.config.reload"), - button -> { - config.load(); - MinecraftClient.getInstance().setScreen(new ConfigScreen(parent, config)); - }) - .position(this.width / 2 - 100, this.height / 2 - 10) - .size(200, 20) - .build() - ); - this.addDrawableChild( - ButtonWidget.builder( - Text.translatable("great-scrollable-tooltips.ui.config.save-and-exit"), - button -> { - config.sensitivity = BigDecimal.valueOf(((AccessorSliderWidget) sensitivitySlider).getValue()).multiply(new BigDecimal(99)).add(BigDecimal.ONE).setScale(0, RoundingMode.DOWN).intValue(); - config.save(); - MinecraftClient.getInstance().setScreen(parent); - }) - .position(this.width / 2 - 100, this.height / 2 + 15) - .size(200, 20) - .build() - ); - this.addDrawableChild( - ButtonWidget.builder( - Text.translatable("great-scrollable-tooltips.ui.config.discard-and-exit"), - button -> MinecraftClient.getInstance().setScreen(parent) - ).position(this.width / 2 - 100, this.height / 2 + 40) - .size(200, 20) - .build() - ); - } - - @Override - public void render(DrawContext context, int mouseX, int mouseY, float delta) { - this.renderBackground(context, mouseX, mouseY, delta); - super.render(context, mouseX, mouseY, delta); - context.drawCenteredTextWithShadow(this.textRenderer, Text.translatable("great-scrollable-tooltips.ui.title"), this.width / 2, 20, 0xFFFFFF); - } -} diff --git a/24w33a-fabric/src/main/resources/LICENSE b/24w33a-fabric/src/main/resources/LICENSE deleted file mode 100644 index d0a1fa1..0000000 --- a/24w33a-fabric/src/main/resources/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at https://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/24w33a-fabric/src/main/resources/config.conf b/24w33a-fabric/src/main/resources/config.conf deleted file mode 100644 index 99eae93..0000000 --- a/24w33a-fabric/src/main/resources/config.conf +++ /dev/null @@ -1,3 +0,0 @@ -enable 'true' -sensitivity '5' -auto_reset 'true' \ No newline at end of file diff --git a/24w33a-fabric/src/main/resources/great-scrollable-tooltips.mixins.json b/24w33a-fabric/src/main/resources/great-scrollable-tooltips.mixins.json deleted file mode 100644 index 238077f..0000000 --- a/24w33a-fabric/src/main/resources/great-scrollable-tooltips.mixins.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "required": true, - "package": "online.flowerinsnow.greatscrollabletooltips.mixin", - "compatibilityLevel": "JAVA_21", - "client": [ - "AccessorSliderWidget", - "MixinDrawContext", - "MixinHandledScreen", - "MixinInventoryScreen" - ], - "injectors": { - "defaultRequire": 1 - }, - "plugin": "online.flowerinsnow.greatscrollabletooltips.mixinplugin.GSTMixinPlugin" -} \ No newline at end of file diff --git a/README.md b/README.md index bbf77e0..163c8e6 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ If you are using the Fabric version, please install Mod [Mod Menu](https://modri | 13.x | 1.20-1.20.1 | ❌ | ❌ | ❌ | ❌ | ❌ | | 14.x | 1.20.2-1.20.4,23w40a-24w13a | ✅ | ✅ | ✅ | ✅ | ❌ | | 15.x | 1.20.5-1.21.1,24w14a-1.21.1rc1 | ✅ | ✅ | ✅ | ✅ | ✅ | -| 16.x | 24w33a | - | - | ✅ | ❌ | ❌ | +| 16.x | 24w33a-24w45a | ✅ | - | ✅ | ✅ | ✅ | ## Forge | Mod version | Minecraft versions | [#38](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/38) | [LegendaryTooltips](https://github.com/AHilyard/LegendaryTooltips) | [#72](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/72) | [#75](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/75) | [#81](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/81) | [#82](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/82) | diff --git a/README/zh_cn.md b/README/zh_cn.md index 584b4c0..3afabc8 100644 --- a/README/zh_cn.md +++ b/README/zh_cn.md @@ -40,7 +40,7 @@ | 13.x | 1.20-1.20.1 | ❌ | ❌ | ❌ | ❌ | ❌ | | 14.x | 1.20.2-1.20.4,23w40a-24w13a | ✅ | ✅ | ✅ | ✅ | ❌ | | 15.x | 1.20.5-1.21.1,24w14a-1.21.1rc1 | ✅ | ✅ | ✅ | ✅ | ✅ | -| 16.x | 24w33a | - | - | ✅ | ❌ | ❌ | +| 16.x | 24w33a-24w45a | ✅ | - | ✅ | ✅ | ✅ | ## Forge | Mod 版本 | Minecraft 版本 | [#38](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/38) | [LegendaryTooltips](https://github.com/AHilyard/LegendaryTooltips) | [#72](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/72) | [#75](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/75) | [#81](https://github.com/flowerinsnow-lights-opensource/GreatScrollableTooltips/issues/81) | [AppleSkin](https://github.com/squeek502/AppleSkin) |