From eaf7078a48ea04680e3743a1563c581c043fc3c5 Mon Sep 17 00:00:00 2001 From: syeyoung Date: Sun, 5 Feb 2023 02:15:59 +0900 Subject: - auto closing tooltip Signed-off-by: syeyoung --- .../kr/syeyoung/dungeonsguide/launcher/Main.java | 21 +- .../dungeonsguide/launcher/auth/AuthManager.java | 25 +- .../launcher/gui/screen/GuiChooseVersion.java | 7 +- .../launcher/gui/screen/GuiLoadingError.java | 6 +- .../launcher/gui/tooltip/NotificationManager.java | 363 ++++++++++++--------- .../gui/tooltip/NotificationManagerRootWidget.java | 56 ++++ .../launcher/gui/tooltip/WidgetNotification.java | 64 ++++ .../gui/tooltip/WidgetNotificationAutoClose.java | 86 +++++ .../launcher/guiv2/elements/Text.java | 1 + 9 files changed, 457 insertions(+), 172 deletions(-) create mode 100644 loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManagerRootWidget.java create mode 100644 loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotification.java create mode 100644 loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotificationAutoClose.java (limited to 'loader/src/main/java/kr') diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java index b4d9622a..42d5244d 100755 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/Main.java @@ -30,6 +30,9 @@ import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError; import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiUnloadingError; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager; +import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification; +import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotificationAutoClose; +import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.richtext.fonts.DefaultFontRenderer; import kr.syeyoung.dungeonsguide.launcher.loader.*; import kr.syeyoung.dungeonsguide.launcher.util.ProgressStateHolder; import lombok.Getter; @@ -92,9 +95,9 @@ public class Main public void initEvent(FMLInitializationEvent initializationEvent) throws ClassNotFoundException, InstantiationException, IllegalAccessException { MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(GuiDisplayer.INSTANCE); - MinecraftForge.EVENT_BUS.register(NotificationManager.INSTANCE); + MinecraftForge.EVENT_BUS.register(NotificationManager.getEventHandler()); - NotificationManager.INSTANCE.updateNotification(dgUnloaded, Notification.builder() + NotificationManager.getInstance().updateNotification(dgUnloaded, new WidgetNotification(dgUnloaded, Notification.builder() .title("Dungeons Guide Not Loaded") .titleColor(0xFFFF0000) .description("Click to try reloading....") @@ -102,7 +105,7 @@ public class Main GuiDisplayer.INSTANCE.displayGui(new GuiChooseVersion(new RuntimeException("just unloaded"))); }) .unremovable(true) - .build()); + .build())); try { File f = new File(configDir, "loader.cfg"); @@ -159,7 +162,7 @@ public class Main listener.unloadReference(); } - NotificationManager.INSTANCE.updateNotification(dgUnloaded, Notification.builder() + NotificationManager.getInstance().updateNotification(dgUnloaded, new WidgetNotification(dgUnloaded, Notification.builder() .title("Dungeons Guide Not Loaded") .titleColor(0xFFFF0000) .description("Click to try reloading....") @@ -167,7 +170,7 @@ public class Main GuiDisplayer.INSTANCE.displayGui(new GuiChooseVersion(new RuntimeException("just unloaded"))); }) .unremovable(true) - .build()); + .build())); if (currentLoader != null) { currentLoader.unloadDungeonsGuide(); } @@ -188,15 +191,16 @@ public class Main listener.onLoad(dgInterface); } + UUID uid = UUID.randomUUID(); - NotificationManager.INSTANCE.updateNotification(UUID.randomUUID(), Notification.builder() + NotificationManager.getInstance().updateNotification(uid, new WidgetNotificationAutoClose(uid, Notification.builder() .title("Dungeons Guide Loaded!") .description("Successfully Loaded Dungeons Guide!\nLoader: "+currentLoader.loaderName()+"\nVersion: "+currentLoader.version()) .titleColor(0xFF00FF00) - .build()); + .build(), 10000L)); - NotificationManager.INSTANCE.removeNotification(dgUnloaded); + NotificationManager.getInstance().removeNotification(dgUnloaded); } private volatile IDGLoader reqLoader = null; @@ -301,6 +305,7 @@ public class Main ((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(a -> { if (dgInterface != null) dgInterface.onResourceReload(a); + DefaultFontRenderer.DEFAULT_RENDERER.onResourceManagerReload(); }); } diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java index f582ba6f..6c8fa7bc 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/auth/AuthManager.java @@ -30,6 +30,7 @@ import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiLoadingError; import kr.syeyoung.dungeonsguide.launcher.gui.screen.GuiPrivacyPolicy; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager; +import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification; import net.minecraft.client.Minecraft; import net.minecraftforge.common.MinecraftForge; import org.apache.logging.log4j.LogManager; @@ -135,11 +136,11 @@ public class AuthManager { } - NotificationManager.INSTANCE.removeNotification(authenticationFailure); - NotificationManager.INSTANCE.removeNotification(privacyPolicyRequired); + NotificationManager.getInstance().removeNotification(authenticationFailure); + NotificationManager.getInstance().removeNotification(privacyPolicyRequired); } catch (Exception e) { if (e instanceof PrivacyPolicyRequiredException) { - NotificationManager.INSTANCE.updateNotification(privacyPolicyRequired, Notification.builder() + NotificationManager.getInstance().updateNotification(privacyPolicyRequired, new WidgetNotification(privacyPolicyRequired, Notification.builder() .title("Privacy Policy") .description("Please accept Dungeons Guide\nPrivacy Policy to enjoy server based\nfeatures of Dungeons Guide\n\n(Including Auto-Update/Remote-Jar)") .titleColor(0xFFFF0000) @@ -147,10 +148,10 @@ public class AuthManager { .onClick(() -> { GuiDisplayer.INSTANCE.displayGui(new GuiPrivacyPolicy()); }) - .build()); + .build())); } else { currentToken = new FailedAuthToken(e); - NotificationManager.INSTANCE.updateNotification(authenticationFailure, Notification.builder() + NotificationManager.getInstance().updateNotification(authenticationFailure, new WidgetNotification(authenticationFailure, Notification.builder() .title("Auth Error") .description("Authentication Error Occurred\n"+e.getMessage()) .titleColor(0xFFFF0000) @@ -158,7 +159,7 @@ public class AuthManager { .onClick(() -> { GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e)); }) - .build()); + .build())); } logger.error("Re-auth failed with message {}, trying again in a 2 seconds", String.valueOf(Throwables.getRootCause(e))); throw new AuthFailedException(e); @@ -177,14 +178,14 @@ public class AuthManager { if (currentToken instanceof PrivacyPolicyRequiredToken) { reauthLock = true; - NotificationManager.INSTANCE.removeNotification(authenticationFailure); - NotificationManager.INSTANCE.removeNotification(privacyPolicyRequired); + NotificationManager.getInstance().removeNotification(authenticationFailure); + NotificationManager.getInstance().removeNotification(privacyPolicyRequired); try { currentToken = DgAuthUtil.acceptNewPrivacyPolicy(currentToken.getToken(), version); if (currentToken instanceof PrivacyPolicyRequiredToken) throw new PrivacyPolicyRequiredException(); } catch (Exception e) { if (e instanceof PrivacyPolicyRequiredException) { - NotificationManager.INSTANCE.updateNotification(privacyPolicyRequired, Notification.builder() + NotificationManager.getInstance().updateNotification(privacyPolicyRequired, new WidgetNotification(privacyPolicyRequired, Notification.builder() .title("Privacy Policy") .description("Please accept the Dungeons Guide\nPrivacy Policy to enjoy server based\nfeatures of Dungeons Guide\n\n(Including Auto-Update/Remote-Jar)") .titleColor(0xFFFF0000) @@ -192,10 +193,10 @@ public class AuthManager { .onClick(() -> { GuiDisplayer.INSTANCE.displayGui(new GuiPrivacyPolicy()); }) - .build()); + .build())); } else { currentToken = new FailedAuthToken(e); - NotificationManager.INSTANCE.updateNotification(authenticationFailure, Notification.builder() + NotificationManager.getInstance().updateNotification(authenticationFailure, new WidgetNotification(authenticationFailure, Notification.builder() .title("Auth Error") .description("Authentication Error Occurred\n"+e.getMessage()) .titleColor(0xFFFF0000) @@ -203,7 +204,7 @@ public class AuthManager { .onClick(() -> { GuiDisplayer.INSTANCE.displayGui(new GuiLoadingError(e)); }) - .build()); + .build())); } logger.error("Accepting the Privacy Policy failed with message {}, trying again in a 2 seconds", String.valueOf(Throwables.getRootCause(e))); throw new AuthFailedException(e); diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java index 9f55cc7c..27954eca 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiChooseVersion.java @@ -25,6 +25,7 @@ import kr.syeyoung.dungeonsguide.launcher.branch.UpdateBranch; import kr.syeyoung.dungeonsguide.launcher.branch.UpdateRetrieverUtil; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager; +import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification; import kr.syeyoung.dungeonsguide.launcher.loader.JarLoader; import kr.syeyoung.dungeonsguide.launcher.loader.LocalLoader; import kr.syeyoung.dungeonsguide.launcher.loader.RemoteLoader; @@ -158,11 +159,13 @@ public class GuiChooseVersion extends SpecialGuiScreen { null ); - NotificationManager.INSTANCE.updateNotification(UUID.randomUUID(), Notification.builder() + UUID random = UUID.randomUUID(); + NotificationManager.getInstance().updateNotification(random, + new WidgetNotification(random, Notification.builder() .title("Successfully Copied!") .description("") .titleColor(0xFF00FF00) - .build()); + .build())); } else if (button.id == 0) { dismiss(); Main.getMain().tryReloadingWithSplash(new LocalLoader()); diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java index d85909dd..d3622464 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/screen/GuiLoadingError.java @@ -20,6 +20,7 @@ package kr.syeyoung.dungeonsguide.launcher.gui.screen; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.Notification; import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.NotificationManager; +import kr.syeyoung.dungeonsguide.launcher.gui.tooltip.WidgetNotification; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; @@ -69,11 +70,12 @@ public class GuiLoadingError extends SpecialGuiScreen { null ); - NotificationManager.INSTANCE.updateNotification(UUID.randomUUID(), Notification.builder() + UUID uuid = UUID.randomUUID(); + NotificationManager.getInstance().updateNotification(uuid, new WidgetNotification(uuid, Notification.builder() .title("Successfully Copied!") .description("") .titleColor(0xFF00FF00) - .build()); + .build())); } } diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManager.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManager.java index 6328a831..7e4ccdce 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManager.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManager.java @@ -1,6 +1,6 @@ /* * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - * Copyright (C) 2022 cyoung06 (syeyoung) + * Copyright (C) 2023 cyoung06 (syeyoung) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published @@ -18,196 +18,263 @@ package kr.syeyoung.dungeonsguide.launcher.gui.tooltip; +import kr.syeyoung.dungeonsguide.launcher.guiv2.RootDom; +import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.GlobalHUDScale; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.ConstraintBox; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.Rect; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.Size; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.RenderingContext; +import kr.syeyoung.dungeonsguide.launcher.util.cursor.EnumCursor; +import kr.syeyoung.dungeonsguide.launcher.util.cursor.GLCursors; +import lombok.Getter; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.GlStateManager; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.GL11; -import java.awt.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.io.IOException; + +import static org.lwjgl.opengl.GL11.GL_GREATER; public class NotificationManager { - public static final NotificationManager INSTANCE = new NotificationManager(); - private NotificationManager() { + private final RootDom view; + private final Minecraft mc; + + private static final NotificationManager INSTANCE = new NotificationManager(); + @Getter + private final NotificationManagerRootWidget root = new NotificationManagerRootWidget(); - } - private final Map tooltipList = new HashMap<>(); + public static NotificationManager getEventHandler() { + return INSTANCE; + } - public void updateNotification(UUID uid, Notification tooltip) { - tooltipList.put(uid, tooltip); + public static NotificationManagerRootWidget getInstance() { + return getEventHandler().root; } - public void removeNotification(UUID uid) { - tooltipList.remove(uid); + + + private NotificationManager() { + this.mc = Minecraft.getMinecraft(); + + view = new RootDom(new GlobalHUDScale(root)); + guiResize(null); + view.setMounted(true); } + @SubscribeEvent() + public void guiResize(GuiScreenEvent.InitGuiEvent.Post post){ + try { + view.setRelativeBound(new Rect(0,0, Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight)); + view.setAbsBounds(new Rect(0,0, Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight)); + view.setSize(new Size(Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight)); + view.getLayouter().layout(view, new ConstraintBox( + Minecraft.getMinecraft().displayWidth, + Minecraft.getMinecraft().displayWidth, + Minecraft.getMinecraft().displayHeight, + Minecraft.getMinecraft().displayHeight + )); + } catch (Exception e) { + e.printStackTrace(); + } + } @SubscribeEvent - public void onRender(RenderGameOverlayEvent.Post postRender) { - if (!(postRender.type == RenderGameOverlayEvent.ElementType.EXPERIENCE || postRender.type == RenderGameOverlayEvent.ElementType.JUMPBAR)) - return; + public void renderOverlay(RenderGameOverlayEvent.Post postRender) { + try { + if (!(postRender.type == RenderGameOverlayEvent.ElementType.ALL)) + return; + drawScreen(postRender.partialTicks); + } catch (Exception e) { + e.printStackTrace(); + } + } - ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft()); - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int widthX = fr.getStringWidth("X"); + @SubscribeEvent + public void renderGui(GuiScreenEvent.DrawScreenEvent.Post postRender) { + try { + drawScreen(postRender.renderPartialTicks); + } catch (Exception e) { + e.printStackTrace(); + } + } - GlStateManager.pushMatrix(); - GlStateManager.disableDepth(); - GlStateManager.translate(sr.getScaledWidth() - 5, sr.getScaledHeight() -5, 0); - - int currY = sr.getScaledHeight() - 5; - - for (Notification tooltip : tooltipList.values()) { - int width, height; - String[] description = tooltip.getDescription().split("\n"); - width = - Math.max( - fr.getStringWidth(tooltip.getTitle()), - Arrays.stream(description).map(fr::getStringWidth).max(Integer::compareTo).orElse(300) - ) + 10; - height = description.length * fr.FONT_HEIGHT + 15 + fr.FONT_HEIGHT; - - GlStateManager.translate(0, -height, 0); - currY -= height; - - GlStateManager.pushMatrix(); - GlStateManager.translate(-width, 0, 0); - Gui.drawRect(0, 0,width,height, 0xFF23272a); - Gui.drawRect(1, 1, width-1, height-1, 0XFF2c2f33); - - if (!tooltip.isUnremovable()) { - fr.drawString("X", width - widthX - 2, 2, 0xFFFF0000); - } - GlStateManager.translate(5,5,0); - fr.drawString(tooltip.getTitle(), 0,0, tooltip.getTitleColor()); - GlStateManager.translate(0, fr.FONT_HEIGHT + 5, 0); - int y = 0; - for (String line : description) { - fr.drawString(line, 0, y, 0xFFAAAAAA); - y += fr.FONT_HEIGHT; - } - GlStateManager.popMatrix(); + private void drawScreen( float partialTicks) { + int i = Mouse.getEventX(); + int j = this.mc.displayHeight - Mouse.getEventY(); - tooltip.setBoundRect(new Rectangle( - sr.getScaledWidth() - width - 5, - currY, - width, - height + if (view.isRelayoutRequested()) { + view.setRelayoutRequested(false); + view.getLayouter().layout(view, new ConstraintBox( + Minecraft.getMinecraft().displayWidth, + Minecraft.getMinecraft().displayWidth, + Minecraft.getMinecraft().displayHeight, + Minecraft.getMinecraft().displayHeight )); + } + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + GlStateManager.pushMatrix(); + GlStateManager.translate(0,0,50); + GlStateManager.disableDepth(); + GlStateManager.enableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.alphaFunc(GL_GREATER, 0); + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.scale(1.0 / scaledResolution.getScaleFactor(), 1.0 / scaledResolution.getScaleFactor(), 1.0d); + view.getRenderer().doRender(i, j, i, j, partialTicks, new RenderingContext(), view); + GlStateManager.alphaFunc(GL_GREATER, 0.1f); + GlStateManager.popMatrix(); + GlStateManager.enableDepth(); + GL11.glDisable(GL11.GL_SCISSOR_TEST); + } - currY -= 5; - GlStateManager.translate(0, -5, 0); + private void keyTyped(char typedChar, int keyCode) throws IOException { + try { + view.keyPressed0(typedChar, keyCode); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); } + } - GlStateManager.enableDepth(); - GlStateManager.popMatrix(); + private void keyHeld(int keyCode, char typedChar) throws IOException { + try { + view.keyHeld0(typedChar, keyCode); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } } - @SubscribeEvent - public void onGuiPostRender(GuiScreenEvent.DrawScreenEvent.Post rendered) { - ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft()); - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int widthX = fr.getStringWidth("X"); - GlStateManager.pushMatrix(); - GlStateManager.disableDepth(); - GlStateManager.translate(sr.getScaledWidth() - 5, sr.getScaledHeight() -5, 0); - - int currY = sr.getScaledHeight() - 5; - - for (Notification tooltip : tooltipList.values()) { - int width, height; - String[] description = tooltip.getDescription().split("\n"); - width = - Math.max( - fr.getStringWidth(tooltip.getTitle()), - Arrays.stream(description).map(fr::getStringWidth).max(Integer::compareTo).orElse(300) - ) + 10; - height = description.length * fr.FONT_HEIGHT + 15 + fr.FONT_HEIGHT; - - GlStateManager.translate(0, -height, 0); - currY -= height; - - GlStateManager.pushMatrix(); - GlStateManager.translate(-width, 0, 0); - Gui.drawRect(0, 0,width,height, 0xFF23272a); - Gui.drawRect(1, 1, width-1, height-1, 0XFF2c2f33); - - if (!tooltip.isUnremovable()) { - if (rendered.mouseX >= sr.getScaledWidth() - 5 - widthX - 2 && rendered.mouseX <= sr.getScaledWidth() - 2 - && rendered.mouseY >= currY + 2 && rendered.mouseY <= currY + 2 + fr.FONT_HEIGHT) { - fr.drawString("X", width - widthX - 2, 2, 0xFFFFAAAA); - } else { - fr.drawString("X", width - widthX - 2, 2, 0xFFFF0000); - } - } + private void keyReleased(int keyCode, char typedChar) throws IOException { + try { + view.keyReleased0(typedChar, keyCode); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } + } - GlStateManager.translate(5,5,0); - fr.drawString(tooltip.getTitle(), 0,0, tooltip.getTitleColor()); - GlStateManager.translate(0, fr.FONT_HEIGHT + 5, 0); - int y = 0; - for (String line : description) { - fr.drawString(line, 0, y, 0xFFAAAAAA); - y += fr.FONT_HEIGHT; - } - GlStateManager.popMatrix(); + private boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { + try { + return view.mouseClicked0(mouseX, mouseY + , mouseX, mouseY, mouseButton); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } + return false; + } - tooltip.setBoundRect(new Rectangle( - sr.getScaledWidth() - width - 5, - currY, - width, - height - )); + private void mouseReleased(int mouseX, int mouseY, int state) { + try { + view.mouseReleased0(mouseX, mouseY + , mouseX, mouseY, state); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } + } - currY -= 5; - GlStateManager.translate(0, -5, 0); + private void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) { + try { + view.mouseClickMove0(mouseX, mouseY + , mouseX, mouseY, clickedMouseButton, timeSinceLastClick); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); } + } - GlStateManager.enableDepth(); - GlStateManager.popMatrix(); + private void mouseMove(int mouseX, int mouseY) { + try { + view.mouseMoved0(mouseX, mouseY + , mouseX, mouseY, true); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } } + private int touchValue; + private int eventButton; + private long lastMouseEvent; + + + private int lastX, lastY; + + @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) { - ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft()); - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int mouseX = Mouse.getX() / sr.getScaleFactor(); - int mouseY = (Minecraft.getMinecraft().displayHeight - Mouse.getY() +3)/ sr.getScaleFactor(); - for (Map.Entry tooltip_ : tooltipList.entrySet()) { - Notification tooltip = tooltip_.getValue(); - if (tooltip.getBoundRect() == null) continue;; - if (tooltip.getBoundRect().contains(mouseX, mouseY)) { - - mouseInputEvent.setCanceled(true); - - if (Mouse.getEventButton() == -1) return; - if (!Mouse.getEventButtonState()) return; - - int dx = mouseX - tooltip.getBoundRect().x; - int dy = mouseY - tooltip.getBoundRect().y; - - if (!tooltip.isUnremovable()) { - tooltipList.remove(tooltip_.getKey()); + public void handleMouseInput(GuiScreenEvent.MouseInputEvent.Pre mouseInputEvent) throws IOException { + try { + int i = Mouse.getEventX(); + int j = this.mc.displayHeight - Mouse.getEventY(); + int k = Mouse.getEventButton(); + + if (Mouse.getEventButtonState()) { + if (this.mc.gameSettings.touchscreen && this.touchValue++ > 0) { + return; } - if (dx >= tooltip.getBoundRect().width - 2 - fr.getStringWidth("X") && dx <= tooltip.getBoundRect().width - 2 - && dy >= 2 && dy <= 2 + fr.FONT_HEIGHT) { - } else { - if (tooltip.getOnClick() != null) tooltip.getOnClick().run(); + + this.eventButton = k; + this.lastMouseEvent = Minecraft.getSystemTime(); + if (this.mouseClicked(i, j, this.eventButton)) + mouseInputEvent.setCanceled(true); + } else if (k != -1) { + if (this.mc.gameSettings.touchscreen && --this.touchValue > 0) { + return; } - return; + this.eventButton = -1; + this.mouseReleased(i, j, k); + } else if (this.eventButton != -1 && this.lastMouseEvent > 0L) { + long l = Minecraft.getSystemTime() - this.lastMouseEvent; + this.mouseClickMove(i, j, this.eventButton, l); } + if (lastX != i || lastY != j) { + try { + EnumCursor prevCursor = view.getCurrentCursor(); + view.setCursor(EnumCursor.DEFAULT); + this.mouseMove(i, j); + EnumCursor newCursor = view.getCurrentCursor(); + if (prevCursor != newCursor) Mouse.setNativeCursor(GLCursors.getCursor(newCursor)); + } catch (Throwable e) { + if (e.getMessage() == null || !e.getMessage().contains("hack to stop")) + e.printStackTrace(); + } + } + + + int wheel = Mouse.getEventDWheel(); + if (wheel != 0) { + boolean cancel = view.mouseScrolled0(i, j, i, j, wheel); + if (cancel) mouseInputEvent.setCanceled(true); + } + lastX = i; + lastY = j; + } catch (Throwable e) { + e.printStackTrace(); } } + @SubscribeEvent(priority = EventPriority.HIGHEST) + public void handleKeyboardInput(GuiScreenEvent.KeyboardInputEvent.Pre keyboardInputEvent) throws IOException { + if (Keyboard.getEventKeyState()) { + if (Keyboard.isRepeatEvent()) + this.keyHeld(Keyboard.getEventKey(), Keyboard.getEventCharacter()); + else + this.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); + } else { + this.keyReleased(Keyboard.getEventKey(), Keyboard.getEventCharacter()); + } + } } diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManagerRootWidget.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManagerRootWidget.java new file mode 100644 index 00000000..6cbe78c6 --- /dev/null +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/NotificationManagerRootWidget.java @@ -0,0 +1,56 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.launcher.gui.tooltip; + +import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget; +import kr.syeyoung.dungeonsguide.launcher.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.launcher.guiv2.Widget; +import kr.syeyoung.dungeonsguide.launcher.guiv2.elements.Column; +import kr.syeyoung.dungeonsguide.launcher.guiv2.layouter.Layouter; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.ConstraintBox; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.Size; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.OnlyChildrenRenderer; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind; +import net.minecraft.util.ResourceLocation; + +import java.util.*; + +public class NotificationManagerRootWidget extends AnnotatedImportOnlyWidget { + @Bind(variableName = "listApi") + public final BindableAttribute api = new BindableAttribute<>(Column.class); + + public NotificationManagerRootWidget() { + super(new ResourceLocation("dungeons_guide_loader:gui/tooltips/tooltipHolder.gui")); + } + + private final Map tooltipList = new HashMap<>(); + + public void updateNotification(UUID uid, Widget tooltip) { + Widget old = tooltipList.put(uid, tooltip); + if (old != null) api.getValue().removeWidget(old); + api.getValue().addWidget(tooltip); + } + public void removeNotification(UUID uid) { + Widget old = tooltipList.remove(uid); + if (old != null) api.getValue().removeWidget(old); + } +} diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotification.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotification.java new file mode 100644 index 00000000..8683b4fd --- /dev/null +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotification.java @@ -0,0 +1,64 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.launcher.gui.tooltip; + +import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On; +import net.minecraft.util.ResourceLocation; + +import java.util.UUID; + +public class WidgetNotification extends AnnotatedImportOnlyWidget { + private Notification notification; + + + @Bind(variableName = "title") + public final BindableAttribute title = new BindableAttribute<>(String.class); + @Bind(variableName = "description") + public final BindableAttribute description = new BindableAttribute<>(String.class); + @Bind(variableName = "color") + public final BindableAttribute color = new BindableAttribute<>(Integer.class); + @Bind(variableName = "closeVisibility") + public final BindableAttribute closeVisibility = new BindableAttribute<>(String.class); + + private UUID uuid; + public WidgetNotification(UUID uuid, Notification notification) { + super(new ResourceLocation("dungeons_guide_loader:gui/tooltips/tooltip.gui")); + this.notification =notification; + title.setValue(notification.getTitle()); + color.setValue(notification.getTitleColor()); + description.setValue(notification.getDescription()); + closeVisibility.setValue(notification.isUnremovable() ? "hide" : "show"); + this.uuid = uuid; + } + + @On(functionName = "close") + public void close() { + if (!notification.isUnremovable()) + NotificationManager.getInstance().removeNotification(uuid); + } + + @Override + public boolean mouseClicked(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int mouseButton) { + if (notification.getOnClick() != null) notification.getOnClick().run(); + return true; + } +} diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotificationAutoClose.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotificationAutoClose.java new file mode 100644 index 00000000..90e2359b --- /dev/null +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/gui/tooltip/WidgetNotificationAutoClose.java @@ -0,0 +1,86 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.launcher.gui.tooltip; + +import kr.syeyoung.dungeonsguide.launcher.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.launcher.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.launcher.guiv2.primitive.Size; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.RenderingContext; +import kr.syeyoung.dungeonsguide.launcher.guiv2.renderer.SingleChildRenderer; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.launcher.guiv2.xml.annotations.On; +import net.minecraft.util.ResourceLocation; + +import java.util.UUID; + +public class WidgetNotificationAutoClose extends AnnotatedImportOnlyWidget implements Renderer { + private Notification notification; + + + @Bind(variableName = "title") + public final BindableAttribute title = new BindableAttribute<>(String.class); + @Bind(variableName = "description") + public final BindableAttribute description = new BindableAttribute<>(String.class); + @Bind(variableName = "color") + public final BindableAttribute color = new BindableAttribute<>(Integer.class); + @Bind(variableName = "closeVisibility") + public final BindableAttribute closeVisibility = new BindableAttribute<>(String.class); + @Bind(variableName = "size") + public final BindableAttribute size = new BindableAttribute<>(Size.class); + @Bind(variableName = "width") + public final BindableAttribute width = new BindableAttribute<>(Double.class); + + private UUID uuid; + private long delay; + private long now = -1; + public WidgetNotificationAutoClose(UUID uuid, Notification notification, long delay) { + super(new ResourceLocation("dungeons_guide_loader:gui/tooltips/tooltipClosing.gui")); + this.notification =notification; + title.setValue(notification.getTitle()); + color.setValue(notification.getTitleColor()); + description.setValue(notification.getDescription()); + closeVisibility.setValue(notification.isUnremovable() ? "hide" : "show"); + this.uuid = uuid; + this.delay = delay; + + } + + @On(functionName = "close") + public void close() { + if (!notification.isUnremovable()) + NotificationManager.getInstance().removeNotification(uuid); + } + + @Override + public boolean mouseClicked(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int mouseButton) { + if (notification.getOnClick() != null) notification.getOnClick().run(); + return true; + } + + @Override + public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext context, DomElement buildContext) { + if (now == -1) now = System.currentTimeMillis(); + width.setValue((System.currentTimeMillis() - now)* size.getValue().getWidth() /delay ); + if (System.currentTimeMillis() - now > delay) + NotificationManager.getInstance().removeNotification(uuid); + SingleChildRenderer.INSTANCE.doRender(absMouseX, absMouseY, relMouseX, relMouseY, partialTicks, context, buildContext); + } +} diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Text.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Text.java index 761c7a0d..14bb30e3 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Text.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/guiv2/elements/Text.java @@ -100,6 +100,7 @@ public class Text extends AnnotatedExportOnlyWidget { textStyle.textShader = new SingleColorShader(color.getValue()); textStyle.underlineShader = new SingleColorShader(color.getValue()); textStyle.strikeThroughShader = new SingleColorShader(color.getValue()); + textStyle.backgroundShader = null; textStyle.topAscent = lineSpacing.getValue() - 1; textStyle.size = size.getValue(); TextSpan textSpan = new TextSpan(textStyle, ""); -- cgit