diff options
author | DeDiamondPro <67508414+DeDiamondPro@users.noreply.github.com> | 2022-08-24 22:51:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-24 22:51:58 +0200 |
commit | daed9569a0f1d2231c4f824f6cffd72d5f8ae8bd (patch) | |
tree | 6efee702c616d96e40a3e69ce89425f0936a7598 /src/main | |
parent | a76b49be6dbeb0be3f88870e33d3e10e0e7f8e1c (diff) | |
download | OneConfig-daed9569a0f1d2231c4f824f6cffd72d5f8ae8bd.tar.gz OneConfig-daed9569a0f1d2231c4f824f6cffd72d5f8ae8bd.tar.bz2 OneConfig-daed9569a0f1d2231c4f824f6cffd72d5f8ae8bd.zip |
Notifs (#111)
* Start on notifications
* Finish notifications (pog)
* oop
* internalizing
* misc: set default duration to 4000ms
* Scaling notifs stuff
Co-authored-by: Wyvest <45589059+Wyvest@users.noreply.github.com>
Diffstat (limited to 'src/main')
13 files changed, 702 insertions, 175 deletions
diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java index 9017230..db2ea8b 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/OneConfigGui.java @@ -66,7 +66,6 @@ public class OneConfigGui extends OneUIScreen { public boolean allowClose = true; protected Page currentPage; protected Page prevPage; - private float scale = 1f; private Animation animation; public OneConfigGui() { @@ -93,10 +92,7 @@ public class OneConfigGui extends OneUIScreen { NanoVG.nvgTranslate(vg, UResolution.getWindowWidth(), UResolution.getWindowHeight()); NanoVG.nvgRotate(vg, (float) Math.toRadians(180)); } - scale = Preferences.enableCustomScale ? Preferences.customScale : Math.min(UResolution.getWindowWidth() / 1920f, UResolution.getWindowHeight() / 1080f); - if (scale < 1 && !Preferences.enableCustomScale) - scale = Math.min(Math.min(1f, UResolution.getWindowWidth() / 1280f), Math.min(1f, UResolution.getWindowHeight() / 800f)); - scale = (float) (Math.floor(scale / 0.05f) * 0.05f); + float scale = getScaleFactor(); int x = (int) ((UResolution.getWindowWidth() - 1280 * scale) / 2f / scale); int y = (int) ((UResolution.getWindowHeight() - 800 * scale) / 2f / scale); RenderManager.scale(vg, scale, scale); @@ -198,6 +194,7 @@ public class OneConfigGui extends OneUIScreen { if (currentColorSelector != null) { currentColorSelector.draw(vg); } + RenderManager.resetTransform(vg); } @Override @@ -280,8 +277,11 @@ public class OneConfigGui extends OneUIScreen { return currentColorSelector.getColor(); } - public float getScaleFactor() { - return scale; + public static float getScaleFactor() { + float scale = Preferences.enableCustomScale ? Preferences.customScale : Math.min(UResolution.getWindowWidth() / 1920f, UResolution.getWindowHeight() / 1080f); + if (scale < 1 && !Preferences.enableCustomScale) + scale = Math.min(Math.min(1f, UResolution.getWindowWidth() / 1280f), Math.min(1f, UResolution.getWindowHeight() / 800f)); + return (float) (Math.floor(scale / 0.05f) * 0.05f); } public String getSearchValue() { @@ -303,4 +303,8 @@ public class OneConfigGui extends OneUIScreen { public boolean hasBackgroundBlur() { return Preferences.enableBlur; } + + public static boolean isOpen() { + return Platform.getGuiPlatform().getCurrentScreen() instanceof OneConfigGui; + } } diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/animations/Animation.java b/src/main/java/cc/polyfrost/oneconfig/gui/animations/Animation.java index 4040164..f85132b 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/animations/Animation.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/animations/Animation.java @@ -29,11 +29,11 @@ package cc.polyfrost.oneconfig.gui.animations; import cc.polyfrost.oneconfig.utils.gui.GuiUtils; public abstract class Animation { - private final boolean reverse; - private final float duration; - private final float start; - private final float change; - private float timePassed = 0; + protected final boolean reverse; + protected final float duration; + protected final float start; + protected final float change; + protected float timePassed = 0; /** * @param duration The duration of the animation @@ -84,5 +84,19 @@ public abstract class Animation { return reverse; } + /** + * @return The start position of the animation + */ + public float getStart() { + return start; + } + + /** + * @return The end position of the animation + */ + public float getEnd() { + return start + change; + } + protected abstract float animate(float x); } diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/notifications/Notifications.java b/src/main/java/cc/polyfrost/oneconfig/gui/animations/ChainedAnimation.java index 4038355..63be4a0 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/notifications/Notifications.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/animations/ChainedAnimation.java @@ -24,35 +24,33 @@ * <https://polyfrost.cc/legal/oneconfig/additional-terms> */ -package cc.polyfrost.oneconfig.utils.notifications; +package cc.polyfrost.oneconfig.gui.animations; -/** - * @deprecated Reserved for future use, not implemented yet. - */ -@Deprecated -public final class Notifications { - public static final Notifications INSTANCE = new Notifications(); - private Notifications() { - - } - - public void send(String title, String message) { - - } - - public void send(String title, String message, Runnable action) { +public class ChainedAnimation extends Animation { + private final Animation[] animations; + private int currentAnimation = 0; + private float value; + public ChainedAnimation(Animation... animations) { + super(1, 0, 0, false); + this.animations = animations; } - public void send(String title, String message, float duration) { - + @Override + public float get(float deltaTime) { + if (currentAnimation >= animations.length) return value; + value = animations[currentAnimation].get(deltaTime); + if (animations[currentAnimation].isFinished()) currentAnimation++; + return value; } - public void send(String title, String message, float duration, Runnable action) { - + @Override + public boolean isFinished() { + return currentAnimation >= animations.length; } - public void send(String title, String message, float duration, Runnable action, Runnable onClose) { - + @Override + protected float animate(float x) { + return 0; } } diff --git a/src/main/java/cc/polyfrost/oneconfig/gui/animations/DummyAnimation.java b/src/main/java/cc/polyfrost/oneconfig/gui/animations/DummyAnimation.java index ca9bc17..62cbed7 100644 --- a/src/main/java/cc/polyfrost/oneconfig/gui/animations/DummyAnimation.java +++ b/src/main/java/cc/polyfrost/oneconfig/gui/animations/DummyAnimation.java @@ -26,23 +26,56 @@ package cc.polyfrost.oneconfig.gui.animations; +import java.util.concurrent.Callable; + public class DummyAnimation extends Animation { protected final float value; + protected Callable<Boolean> done = null; /** * @param value The value that is returned + * @param done A callable that returns if the animation is finished */ - public DummyAnimation(float value) { - super(value, value, value, false); + public DummyAnimation(float value, Callable<Boolean> done) { + super(0, value, value, false); + this.value = value; + this.done = done; + } + + /** + * @param value The value that is returned + * @param duration The duration of the animation + */ + public DummyAnimation(float value, float duration) { + super(duration, value, value, false); this.value = value; } + /** + * @param value The value that is returned + */ + public DummyAnimation(float value) { + this(value, 0); + } + @Override public float get(float deltaTime) { + timePassed += deltaTime; return value; } @Override + public boolean isFinished() { + if (done != null) { + try { + return done.call(); + } catch (Exception ignored) { + } + } + return super.isFinished(); + } + + @Override protected float animate(float x) { return x; } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java b/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java index 88f726e..bc0e3a9 100644 --- a/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java +++ b/src/main/java/cc/polyfrost/oneconfig/internal/config/Preferences.java @@ -26,10 +26,7 @@ package cc.polyfrost.oneconfig.internal.config; -import cc.polyfrost.oneconfig.config.annotations.Exclude; -import cc.polyfrost.oneconfig.config.annotations.KeyBind; -import cc.polyfrost.oneconfig.config.annotations.Slider; -import cc.polyfrost.oneconfig.config.annotations.Switch; +import cc.polyfrost.oneconfig.config.annotations.*; import cc.polyfrost.oneconfig.config.core.OneKeyBind; import cc.polyfrost.oneconfig.gui.OneConfigGui; import cc.polyfrost.oneconfig.internal.gui.BlurHandler; @@ -49,6 +46,12 @@ public class Preferences extends InternalConfig { ) public static OneKeyBind oneConfigKeyBind = new OneKeyBind(UKeyboard.KEY_RSHIFT); + @Dropdown( + name = "Release Channel", + options = {"Releases", "Pre-Releases"}, + size = 2 + ) + public static int updateChannel = 0; @Switch( name = "Use custom GUI scale", @@ -73,6 +76,10 @@ public class Preferences extends InternalConfig { initialize(); addListener("enableBlur", () -> BlurHandler.INSTANCE.reloadBlur(Platform.getGuiPlatform().getCurrentScreen())); registerKeyBind(oneConfigKeyBind, () -> new TickDelay(() -> Platform.getGuiPlatform().setCurrentScreen(OneConfigGui.create()), 1)); + addListener("updateChannel", () -> { + OneConfigConfig.updateChannel = updateChannel; + OneConfigConfig.getInstance().save(); + }); INSTANCE = this; } diff --git a/src/main/java/cc/polyfrost/oneconfig/internal/utils/Notification.java b/src/main/java/cc/polyfrost/oneconfig/internal/utils/Notification.java new file mode 100644 index 0000000..e2c0b05 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/internal/utils/Notification.java @@ -0,0 +1,118 @@ +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + */ + +package cc.polyfrost.oneconfig.internal.utils; + +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.animations.*; +import cc.polyfrost.oneconfig.internal.assets.Colors; +import cc.polyfrost.oneconfig.libs.universal.UResolution; +import cc.polyfrost.oneconfig.renderer.Icon; +import cc.polyfrost.oneconfig.renderer.RenderManager; +import cc.polyfrost.oneconfig.renderer.font.Fonts; +import cc.polyfrost.oneconfig.renderer.scissor.Scissor; +import cc.polyfrost.oneconfig.renderer.scissor.ScissorManager; +import cc.polyfrost.oneconfig.utils.InputHandler; +import cc.polyfrost.oneconfig.utils.MathUtils; +import cc.polyfrost.oneconfig.utils.color.ColorPalette; +import cc.polyfrost.oneconfig.utils.gui.GuiUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.Callable; + +public final class Notification { + private final String title; + private final String message; + private final Icon icon; + private final Animation animation; + private final Callable<Float> progressBar; + private final Runnable action; + private final InputHandler inputHandler = new InputHandler(); + private final ColorAnimation bgColor = new ColorAnimation(new ColorPalette(Colors.GRAY_800, Colors.GRAY_700, Colors.GRAY_900)); + private final ColorAnimation titleColor = new ColorAnimation(new ColorPalette(Colors.WHITE_80, Colors.WHITE, Colors.WHITE)); + private final ColorAnimation messageColor = new ColorAnimation(new ColorPalette(Colors.WHITE_60, Colors.WHITE_90, Colors.WHITE_90)); + private boolean hovered = false; + + public Notification(String title, String message, @Nullable Icon icon, float duration, @Nullable Callable<Float> progressBar, @Nullable Runnable action) { + this.title = title; + this.message = message; + this.icon = icon; + this.animation = new ChainedAnimation( + new EaseInOutQuad(250, 0, 330, false), + progressBar == null ? new DummyAnimation(330, duration) : new DummyAnimation(330, () -> progressBar.call() >= 1f), + new EaseInOutQuad(250, 330, 0, false) + ); + this.progressBar = progressBar; + this.action = action; + } + + public float draw(final long vg, float y, float scale) { + RenderManager.scale(vg, scale, scale); + inputHandler.scale(scale, scale); + float x = (UResolution.getWindowWidth() / scale - animation.get(hovered ? 0 : GuiUtils.getDeltaTime())); + float textX = icon == null ? x + 16 : x + 64; + float textMaxLength = icon == null ? 268 : 220; + float messageHeight = RenderManager.getWrappedStringHeight(vg, message, textMaxLength, 12f, 1.75f, Fonts.REGULAR); + float height = getHeight(messageHeight); + y -= height; + hovered = inputHandler.isAreaHovered(x, y, 314, height); + if (hovered && inputHandler.isClicked() && action != null) action.run(); + int bgColor = this.bgColor.getColor(hovered, hovered && inputHandler.isMouseDown()); + int titleColor = this.titleColor.getColor(hovered, hovered && inputHandler.isMouseDown()); + int messageColor = this.messageColor.getColor(hovered, hovered && inputHandler.isMouseDown()); + RenderManager.drawRoundedRect(vg, x, y, 314f, height, bgColor, 8f); + if (icon != null) + icon.draw(vg, x + 16f, y + (height - (progressBar == null ? 0f : 5f)) / 2f - 16f, 32f, 32f, titleColor, scale); + RenderManager.drawText(vg, title, textX, y + 30, titleColor, 16f, Fonts.SEMIBOLD); + RenderManager.drawWrappedString(vg, message, textX, y + 46, textMaxLength, messageColor, 12f, 1.75f, Fonts.REGULAR); + if (progressBar != null) { + try { + float progress = MathUtils.clamp(progressBar.call()); + Scissor scissor1 = ScissorManager.scissor(vg, x + 314f * progress, y + height - 5f, 314f * (1 - progress), 5f); + RenderManager.drawRoundedRect(vg, x, y, 314f, height, Colors.PRIMARY_800, 8f); + ScissorManager.resetScissor(vg, scissor1); + Scissor scissor2 = ScissorManager.scissor(vg, x, y + height - 5f, 314f * progress - (314f * progress < 2.5f || 311.5f * progress > 2.5f ? 0f : 2.5f), 5f); + RenderManager.drawRoundedRect(vg, x, y, 314f, height, Colors.PRIMARY_500, 8f); + ScissorManager.resetScissor(vg, scissor2); + if (314f * progress >= 2.5f && 311.5f * progress <= 2.5f) + RenderManager.drawRoundedRect(vg, x + 2.5f, y + height - 5f, Math.max(0, 314f * progress - 5f), 5f, Colors.PRIMARY_500, 2.5f); + } catch (Exception ignored) { + } + } + RenderManager.resetTransform(vg); + return height; + } + + private float getHeight(float messageHeight) { + float height = 68 + messageHeight; + if (progressBar != null) height += 5f; + return height; + } + + public boolean isFinished() { + return animation.isFinished(); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/Icon.java b/src/main/java/cc/polyfrost/oneconfig/renderer/Icon.java new file mode 100644 index 0000000..a256b57 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/renderer/Icon.java @@ -0,0 +1,88 @@ +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + */ + +package cc.polyfrost.oneconfig.renderer; + +import com.google.gson.annotations.SerializedName; + +public class Icon { + private final Object icon; + public final Type type; + + public Icon(String filePath) { + this.icon = filePath; + this.type = filePath.endsWith(".svg") ? Type.SVG : Type.IMAGE; + } + + public Icon(SVG svg) { + this.icon = svg; + this.type = Type.SVG; + } + + public Icon(Image image) { + this.icon = image; + this.type = Type.IMAGE; + } + + public SVG getSVG() { + return (SVG) icon; + } + + public Image getImage() { + return (Image) icon; + } + + public void draw(long vg, float x, float y, float width, float height, int color, float scale) { + if (type == Type.SVG) { + RenderManager.drawSvg(vg, getSVG(), x, y, width, height, color, scale); + } else if (type == Type.IMAGE) { + RenderManager.drawImage(vg, getImage(), x, y, width, height, color); + } + } + + public void draw(long vg, float x, float y, float width, float height, int color) { + if (type == Type.SVG) { + RenderManager.drawSvg(vg, getSVG(), x, y, width, height, color); + } else if (type == Type.IMAGE) { + RenderManager.drawImage(vg, getImage(), x, y, width, height, color); + } + } + + public void draw(long vg, float x, float y, float width, float height) { + if (type == Type.SVG) { + RenderManager.drawSvg(vg, getSVG(), x, y, width, height); + } else if (type == Type.IMAGE) { + RenderManager.drawImage(vg, getImage(), x, y, width, height); + } + } + + public enum Type { + @SerializedName("0") + SVG, + @SerializedName("1") + IMAGE + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java b/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java index cfdb4ad..4d54621 100644 --- a/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java +++ b/src/main/java/cc/polyfrost/oneconfig/renderer/RenderManager.java @@ -42,6 +42,7 @@ import org.lwjgl.nanovg.NVGColor; import org.lwjgl.nanovg.NVGPaint; import org.lwjgl.opengl.GL11; +import java.util.Arrays; import java.util.function.LongConsumer; import java.util.regex.Pattern; @@ -320,17 +321,27 @@ public final class RenderManager { * @param size The size. * @param font The font. */ - public static void drawWrappedString(long vg, String text, float x, float y, float width, int color, float size, Font font) { + public static void drawWrappedString(long vg, String text, float x, float y, float width, int color, float size, float lineHeight, Font font) { nvgBeginPath(vg); nvgFontSize(vg, size); nvgFontFace(vg, font.getName()); - nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); + nvgTextLineHeight(vg, lineHeight); + nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_TOP); // Align top because center is weird with wrapping NVGColor nvgColor = color(vg, color); nvgTextBox(vg, x, y, width, text); nvgFill(vg); nvgColor.free(); } + public static float getWrappedStringHeight(long vg, String text, float width, float fontSize, float lineHeight, Font font) { + float[] bounds = new float[4]; + nvgFontSize(vg, fontSize); + nvgFontFace(vg, font.getName()); + nvgTextLineHeight(vg, lineHeight); + nvgTextBoxBounds(vg, 0, 0, width, text, bounds); + return bounds[3] - bounds[1]; + } + /** * Draw a formatted URL (a string in blue with an underline) that when clicked, opens the given text. * @@ -567,6 +578,26 @@ public final class RenderManager { } /** + * Translate to a location + * + * @param vg The NanoVG context + * @param x The x scale + * @param y The y scale + */ + public static void translate(long vg, float x, float y) { + nvgTranslate(vg, x, y); + } + + /** + * Reset all transforms + * + * @param vg The NanoVG context + */ + public static void resetTransform(long vg) { + nvgResetTransform(vg); + } + + /** * Sets the global alpha value to render with. * * @param vg The NanoVG context. @@ -577,7 +608,7 @@ public final class RenderManager { } /** - * Draws a SVG with the provided file path and parameters. + * Draws an SVG with the provided file path and parameters. * * @param vg The NanoVG context. * @param filePath The file path. @@ -585,11 +616,12 @@ public final class RenderManager { * @param y The y position. * @param width The width. * @param height The height. + * @param scale The scale */ - public static void drawSvg(long vg, String filePath, float x, float y, float width, float height) { - float w = width; - float h = height; - if (OneConfigGui.INSTANCE != null) { + public static void drawSvg(long vg, String filePath, float x, float y, float width, float height, float scale) { + float w = width * scale; + float h = height * scale; + if (OneConfigGui.INSTANCE != null && OneConfigGui.isOpen()) { w *= OneConfigGui.INSTANCE.getScaleFactor(); h *= OneConfigGui.INSTANCE.getScaleFactor(); } @@ -606,7 +638,7 @@ public final class RenderManager { } /** - * Draws a SVG with the provided file path and parameters. + * Draws an SVG with the provided file path and parameters. * * @param vg The NanoVG context. * @param filePath The file path. @@ -614,15 +646,30 @@ public final class RenderManager { * @param y The y position. * @param width The width. * @param height The height. - * @param color The color. */ - public static void drawSvg(long vg, String filePath, float x, float y, float width, float height, int color) { - float w = width; - float h = height; - if (OneConfigGui.INSTANCE != null) { - w *= OneConfigGui.INSTANCE.getScaleFactor(); - h *= OneConfigGui.INSTANCE.getScaleFactor(); + public static void drawSvg(long vg, String filePath, float x, float y, float width, float height) { + float scale = 1; + if (OneConfigGui.isOpen()) { + scale = OneConfigGui.getScaleFactor(); } + drawSvg(vg, filePath, x, y, width, height, scale); + } + + /** + * Draws an SVG with the provided file path and parameters. + * + * @param vg The NanoVG context. + * @param filePath The file path. + * @param x The x position. + * @param y The y position. + * @param width The width. + * @param height The height. + * @param color The color. + * @param scale The scale + */ + public static void drawSvg(long vg, String filePath, float x, float y, float width, float height, int color, float scale) { + float w = width * scale; + float h = height * scale; if (AssetLoader.INSTANCE.loadSVG(vg, filePath, w, h)) { NVGPaint imagePaint = NVGPaint.calloc(); int image = AssetLoader.INSTANCE.getSVG(filePath, w, h); @@ -639,15 +686,30 @@ public final class RenderManager { /** * Draws an SVG with the provided file path and parameters. * - * @see RenderManager#drawSvg(long, String, float, float, float, float) + * @param vg The NanoVG context. + * @param filePath The file path. + * @param x The x position. + * @param y The y position. + * @param width The width. + * @param height The height. + * @param color The color. */ - public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height) { - float w = width; - float h = height; - if (OneConfigGui.INSTANCE != null) { - w *= OneConfigGui.INSTANCE.getScaleFactor(); - h *= OneConfigGui.INSTANCE.getScaleFactor(); + public static void drawSvg(long vg, String filePath, float x, float y, float width, float height, int color) { + float scale = 1; + if (OneConfigGui.isOpen()) { + scale = OneConfigGui.getScaleFactor(); } + drawSvg(vg, filePath, x, y, width, height, color, scale); + } + + /** + * Draws an SVG with the provided file path and parameters. + * + * @see RenderManager#drawSvg(long, String, float, float, float, float) + */ + public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height, float scale) { + float w = width * scale; + float h = height * scale; if (AssetLoader.INSTANCE.loadSVG(vg, svg, w, h)) { drawSvg(vg, svg.filePath, x, y, width, height); } @@ -656,21 +718,43 @@ public final class RenderManager { /** * Draws an SVG with the provided file path and parameters. * - * @see RenderManager#drawSvg(long, String, float, float, float, float, int) + * @see RenderManager#drawSvg(long, String, float, float, float, float) */ - public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height, int color) { - float w = width; - float h = height; - if (OneConfigGui.INSTANCE != null) { - w *= OneConfigGui.INSTANCE.getScaleFactor(); - h *= OneConfigGui.INSTANCE.getScaleFactor(); + public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height) { + float scale = 1; + if (OneConfigGui.isOpen()) { + scale = OneConfigGui.getScaleFactor(); } + drawSvg(vg, svg, x, y, width, height, scale); + } + + /** + * Draws an SVG with the provided file path and parameters. + * + * @see RenderManager#drawSvg(long, String, float, float, float, float, int) + */ + public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height, int color, float scale) { + float w = width * scale; + float h = height * scale; if (AssetLoader.INSTANCE.loadSVG(vg, svg, w, h)) { drawSvg(vg, svg.filePath, x, y, width, height, color); } } /** + * Draws an SVG with the provided file path and parameters. + * + * @see RenderManager#drawSvg(long, String, float, float, float, float) + */ + public static void drawSvg(long vg, SVG svg, float x, float y, float width, float height, int color) { + float scale = 1; + if (OneConfigGui.isOpen()) { + scale = OneConfigGui.getScaleFactor(); + } + drawSvg(vg, svg, x, y, width, height, color, scale); + } + + /** * Draw a circle with an info icon inside of it * * @param vg The NanoVG context. diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/InputHandler.java b/src/main/java/cc/polyfrost/oneconfig/utils/InputHandler.java index 6bd8207..809e55c 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/InputHandler.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/InputHandler.java @@ -135,6 +135,21 @@ public class InputHandler { } /** + * @param button The button + * @return If the button is down + */ + public boolean isMouseDown(int button) { + return Platform.getMousePlatform().isButtonDown(button); + } + + /** + * @return If the left mouse button is down + */ + public boolean isMouseDown() { + return isMouseDown(0); + } + + /** * Gets the current mouse X position. * <p> * All values returned from this class are not scaled to Minecraft's GUI scale. diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/Notifications.java b/src/main/java/cc/polyfrost/oneconfig/utils/Notifications.java new file mode 100644 index 0000000..b1fb387 --- /dev/null +++ b/src/main/java/cc/polyfrost/oneconfig/utils/Notifications.java @@ -0,0 +1,238 @@ +/* + * This file is part of OneConfig. + * OneConfig - Next Generation Config Library for Minecraft: Java Edition + * Copyright (C) 2021, 2022 Polyfrost. + * <https://polyfrost.cc> <https://github.com/Polyfrost/> + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * OneConfig is licensed under the terms of version 3 of the GNU Lesser + * General Public License as published by the Free Software Foundation, AND + * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, + * either version 1.0 of the Additional Terms, 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License. If not, see <https://www.gnu.org/licenses/>. You should + * have also received a copy of the Additional Terms Applicable + * to OneConfig, as published by Polyfrost. If not, see + * <https://polyfrost.cc/legal/oneconfig/additional-terms> + */ + +package cc.polyfrost.oneconfig.utils; + +import cc.polyfrost.oneconfig.events.event.HudRenderEvent; +import cc.polyfrost.oneconfig.gui.OneConfigGui; +import cc.polyfrost.oneconfig.gui.animations.Animation; +import cc.polyfrost.oneconfig.gui.animations.DummyAnimation; +import cc.polyfrost.oneconfig.gui.animations.EaseInOutQuad; +import cc.polyfrost.oneconfig.internal.utils.Notification; +import cc.polyfrost.oneconfig.libs.eventbus.Subscribe; +import cc.polyfrost.oneconfig.libs.universal.UResolution; +import cc.polyfrost.oneconfig.renderer.Icon; +import cc.polyfrost.oneconfig.renderer.RenderManager; +import org.jetbrains.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Callable; + +public final class Notifications { + public static final Notifications INSTANCE = new Notifications(); + // animation stores the bottom y of the notification + private final LinkedHashMap<Notification, Animation> notifications = new LinkedHashMap<>(); + private final float DEFAULT_DURATION = 4000; + + private Notifications() { + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param duration The duration the notification is on screen in ms + * @param progressbar A callable that returns the progress from 0-1 + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, @Nullable Icon icon, float duration, @Nullable Callable<Float> progressbar, @Nullable Runnable action) { + Notification notification = new Notification(title, message, icon, duration, progressbar, action); + notifications.put(notification, new DummyAnimation(-1)); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param duration The duration the notification is on screen in ms + * @param progressbar A callable that returns the progress from 0-1 + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, float duration, @Nullable Callable<Float> progressbar, @Nullable Runnable action) { + send(title, message, null, duration, progressbar, action); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param duration The duration the notification is on screen in ms + * @param progressbar A callable that returns the progress from 0-1 + */ + public void send(String title, String message, @Nullable Icon icon, float duration, @Nullable Callable<Float> progressbar) { + send(title, message, icon, duration, progressbar, null); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param duration The duration the notification is on screen in ms + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, @Nullable Icon icon, float duration, @Nullable Runnable action) { + send(title, message, icon, duration, null, action); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param duration The duration the notification is on screen in ms + * @param progressbar A callable that returns the progress from 0-1 + */ + public void send(String title, String message, float duration, @Nullable Callable<Float> progressbar) { + send(title, message, duration, progressbar, null); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param duration The duration the notification is on screen in ms + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, float duration, @Nullable Runnable action) { + send(title, message, duration, null, action); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param progressbar A callable that returns the progress from 0-1 + */ + public void send(String title, String message, @Nullable Icon icon, @Nullable Callable<Float> progressbar) { + send(title, message, icon, DEFAULT_DURATION, progressbar); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, @Nullable Icon icon, @Nullable Runnable action) { + send(title, message, icon, DEFAULT_DURATION, action); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param progressbar A callable that returns the progress from 0-1 + */ + public void send(String title, String message, @Nullable Callable<Float> progressbar) { + send(title, message, DEFAULT_DURATION, progressbar); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + * @param duration The duration the notification is on screen in ms + */ + public void send(String title, String message, @Nullable Icon icon, float duration) { + send(title, message, icon, duration, (Callable<Float>) null); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param action The action executed when the notification is pressed + */ + public void send(String title, String message, @Nullable Runnable action) { + send(title, message, DEFAULT_DURATION, action); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param duration The duration the notification is on screen in ms + */ + public void send(String title, String message, float duration) { + send(title, message, duration, (Callable<Float>) null); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + * @param icon The icon of the notification, null for none + */ + public void send(String title, String message, @Nullable Icon icon) { + send(title, message, icon, (Callable<Float>) null); + } + + /** + * Send a notification to the user + * + * @param title The title of the notification + * @param message The message of the notification + */ + public void send(String title, String message) { + send(title, message, (Callable<Float>) null); + } + + @Subscribe + private void onHudRender(HudRenderEvent event) { + RenderManager.setupAndDraw((vg) -> { + float desiredPosition = -16f; + float scale = OneConfigGui.getScaleFactor(); + for (Map.Entry<Notification, Animation> entry : notifications.entrySet()) { + if (entry.getValue().getEnd() == -1f) + entry.setValue(new DummyAnimation(desiredPosition)); + else if (desiredPosition != entry.getValue().getEnd()) + entry.setValue(new EaseInOutQuad(250, entry.getValue().get(0), desiredPosition, false)); + float height = entry.getKey().draw(vg, UResolution.getWindowHeight() / scale + entry.getValue().get(), scale); + desiredPosition -= height + 16f; + } + notifications.entrySet().removeIf(entry -> entry.getKey().isFinished()); + }); + } +} diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java b/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java index 1fdd7e7..bc6e9c0 100644 --- a/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java +++ b/src/main/java/cc/polyfrost/oneconfig/utils/TextUtils.java @@ -28,13 +28,13 @@ package cc.polyfrost.oneconfig.utils; import cc.polyfrost.oneconfig.renderer.RenderManager; import cc.polyfrost.oneconfig.renderer.font.Font; -import cc.polyfrost.oneconfig.renderer.font.Fonts; import java.util.ArrayList; /** - * Simple text utility class for NanoVG text rendering. + * @deprecated Use RenderManager's functions for wrapping text and getting the height of it instead */ +@Deprecated public final class TextUtils { /** diff --git a/src/main/java/cc/polyfrost/oneconfig/utils/notifications/Notification.java b/src/main/java/cc/polyfrost/oneconfig/utils/notifications/Notification.java deleted file mode 100644 index 2e28c2c..0000000 --- a/src/main/java/cc/polyfrost/oneconfig/utils/notifications/Notification.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of OneConfig. - * OneConfig - Next Generation Config Library for Minecraft: Java Edition - * Copyright (C) 2021, 2022 Polyfrost. - * <https://polyfrost.cc> <https://github.com/Polyfrost/> - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * OneConfig is licensed under the terms of version 3 of the GNU Lesser - * General Public License as published by the Free Software Foundation, AND - * under the Additional Terms Applicable to OneConfig, as published by Polyfrost, - * either version 1.0 of the Additional Terms, 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License. If not, see <https://www.gnu.org/licenses/>. You should - * have also received a copy of the Additional Terms Applicable - * to OneConfig, as published by Polyfrost. If not, see - * <https://polyfrost.cc/legal/oneconfig/additional-terms> - */ - -package cc.polyfrost.oneconfig.utils.notifications; - -/** - * @deprecated Reserved for future use, not implemented yet. - */ -@Deprecated -public final class Notification { - private String title; - private String message; - private final float duration; - private float x; - private float y; - - private final Runnable action; - private final Runnable onClose; - - Notification(String title, String message, float duration, float x, float y, Runnable action, Runnable onClose) { - this.title = title; - this.message = message; - this.duration = duration; - this.x = x; - this.y = y; - this.action = action; - this.onClose = onClose; - } - - void draw(final long vg) { - - } - - public String getTitle() { - return title; - } - - public String getMessage() { - return message; - } - - public float getDuration() { - return duration; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } - - public Runnable getAction() { - return action; - } - - public Runnable getOnClose() { - return onClose; - } - - public void setTitle(String title) { - this.title = title; - } - - public void setMessage(String message) { - this.message = message; - } - - void setX(float x) { - this.x = x; - } - - void setY(float y) { - this.y = y; - } -} diff --git a/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/RenderManagerDSL.kt b/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/RenderManagerDSL.kt index ac6ff9c..9015361 100644 --- a/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/RenderManagerDSL.kt +++ b/src/main/kotlin/cc/polyfrost/oneconfig/utils/dsl/RenderManagerDSL.kt @@ -164,11 +164,11 @@ fun Long.drawText(text: String, x: Number, y: Number, color: Int, size: Number, fun VG.drawText(text: String, x: Number, y: Number, color: Int, size: Number, font: Font) = instance.drawText(text, x, y, color, size, font) -fun Long.drawWrappedString(text: String, x: Number, y: Number, width: Number, color: Int, size: Number, font: Font) = - RenderManager.drawWrappedString(this, text, x.toFloat(), y.toFloat(), width.toFloat(), color, size.toFloat(), font) +fun Long.drawWrappedString(text: String, x: Number, y: Number, width: Number, color: Int, size: Number, lineHeight: Number, font: Font) = + RenderManager.drawWrappedString(this, text, x.toFloat(), y.toFloat(), width.toFloat(), color, size.toFloat(), lineHeight.toFloat(), font) -fun VG.drawWrappedString(text: String, x: Number, y: Number, width: Number, color: Int, size: Number, font: Font) = - instance.drawWrappedString(text, x, y, width, color, size, font) +fun VG.drawWrappedString(text: String, x: Number, y: Number, width: Number, color: Int, size: Number, lineHeight: Number, font: Font) = + instance.drawWrappedString(text, x, y, width, color, size, lineHeight, font) fun Long.drawURL(url: String, x: Number, y: Number, size: Number, font: Font, inputHandler: InputHandler) = RenderManager.drawURL(this, url, x.toFloat(), y.toFloat(), size.toFloat(), font, inputHandler) @@ -259,10 +259,20 @@ fun NVGColor.fill(r: Float, g: Float, b: Float, a: Float) = RenderManager.fillNV fun Long.scale(x: Float, y: Float) = RenderManager.scale(this, x, y) fun VG.scale(x: Float, y: Float) = instance.scale(x, y) +fun Long.translate(x: Float, y: Float) = RenderManager.translate(this, x, y) +fun VG.translate(x: Float, y: Float) = instance.translate(x, y) + +fun Long.resetTransform() = RenderManager.resetTransform(this) +fun VG.resetTransform() = instance.resetTransform() fun Long.setAlpha(alpha: Float) = RenderManager.setAlpha(this, alpha) fun VG.setAlpha(alpha: Float) = instance.setAlpha(alpha) +fun Long.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, scale: Number) = + RenderManager.drawSvg(this, filePath, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), scale.toFloat()) + +fun VG.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, scale: Number) = + instance.drawSVG(filePath, x, y, width, height, scale) fun Long.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number) = RenderManager.drawSvg(this, filePath, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) @@ -270,18 +280,36 @@ fun Long.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: fun VG.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number) = instance.drawSVG(filePath, x, y, width, height) +fun Long.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, color: Int, scale: Number) = + RenderManager.drawSvg(this, filePath, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), color, scale.toFloat()) + +fun VG.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, color: Int, scale: Number) = + instance.drawSVG(filePath, x, y, width, height, color, scale.toFloat()) + fun Long.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, color: Int) = RenderManager.drawSvg(this, filePath, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), color) fun VG.drawSVG(filePath: String, x: Number, y: Number, width: Number, height: Number, color: Int) = instance.drawSVG(filePath, x, y, width, height, color) +fun Long.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number, scale: Number) = + RenderManager.drawSvg(this, svg, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), scale.toFloat()) + +fun VG.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number, scale: Number) = + instance.drawSVG(svg, x, y, width, height, scale) + fun Long.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number) = RenderManager.drawSvg(this, svg, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat()) fun VG.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number) = instance.drawSVG(svg, x, y, width, height) +fun Long.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number, color: Int, scale: Number) = + RenderManager.drawSvg(this, svg, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), color, scale.toFloat()) + +fun VG.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number, color: Int, scale: Number) = + instance.drawSVG(svg, x, y, width, height, color, scale) + fun Long.drawSVG(svg: SVG, x: Number, y: Number, width: Number, height: Number, color: Int) = RenderManager.drawSvg(this, svg, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), color) |