diff options
author | syeyoung <cyoung06@naver.com> | 2023-02-02 23:27:51 +0900 |
---|---|---|
committer | syeyoung <cyoung06@naver.com> | 2023-02-02 23:27:51 +0900 |
commit | 1c4eace48270b2c5ce1a7a8a9eb05fb32d900399 (patch) | |
tree | d5825bcf2f6aa46c1dd26d9b271dc459660c50ec /mod/src/main/java/kr/syeyoung | |
parent | 7e84e31619be4b7e545168b648bd18db54e158e7 (diff) | |
download | Skyblock-Dungeons-Guide-1c4eace48270b2c5ce1a7a8a9eb05fb32d900399.tar.gz Skyblock-Dungeons-Guide-1c4eace48270b2c5ce1a7a8a9eb05fb32d900399.tar.bz2 Skyblock-Dungeons-Guide-1c4eace48270b2c5ce1a7a8a9eb05fb32d900399.zip |
how many times do I have to revamp config
Signed-off-by: syeyoung <cyoung06@naver.com>
Diffstat (limited to 'mod/src/main/java/kr/syeyoung')
33 files changed, 1128 insertions, 105 deletions
diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java index c1f5e8c8..509fbd79 100755 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/DungeonsGuide.java @@ -258,6 +258,9 @@ public class DungeonsGuide implements DGInterface { ProgressManager.pop(progressbar); VersionInfo.checkAndOpen(); + + + Minecraft.getMinecraft().refreshResources(); } // hotswap fails in dev env due to intellij auto log collection or smth. it holds ref to stacktrace. diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java index c1e3c48e..7bd4d489 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java @@ -57,6 +57,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.Tuple; import net.minecraftforge.common.MinecraftForge; +import org.lwjgl.opengl.*; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java index ef361065..c40a0a80 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDungeonsGuide.java @@ -23,6 +23,8 @@ import kr.syeyoung.dungeonsguide.launcher.Main; import kr.syeyoung.dungeonsguide.mod.DungeonsGuide; import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter; import kr.syeyoung.dungeonsguide.mod.config.guiconfig.GuiConfigV2; +import kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3.MainConfigWidget; +import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location2.HUDLocationConfig; import kr.syeyoung.dungeonsguide.mod.cosmetics.CosmeticsManager; import kr.syeyoung.dungeonsguide.mod.discord.DiscordIntegrationManager; import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; @@ -30,12 +32,15 @@ import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.FeatureVi import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.HoverEventRenderPlayer; import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.api.ApiFetcher; import kr.syeyoung.dungeonsguide.mod.features.impl.party.playerpreview.api.SkinFetcher; +import kr.syeyoung.dungeonsguide.mod.guiv2.GuiScreenAdapter; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.GlobalHUDScale; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.image.ImageTexture; import kr.syeyoung.dungeonsguide.mod.party.PartyManager; import kr.syeyoung.dungeonsguide.mod.stomp.StompManager; import kr.syeyoung.dungeonsguide.mod.stomp.StompPayload; import kr.syeyoung.dungeonsguide.mod.wsresource.StaticResourceCache; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.util.BlockPos; @@ -49,7 +54,6 @@ import java.util.Collections; import java.util.List; public class CommandDungeonsGuide extends CommandBase { - private boolean openConfig = false; @Override public String getCommandName() { @@ -65,6 +69,7 @@ public class CommandDungeonsGuide extends CommandBase { private static final String[] SUBCOMMANDS = { "reparty", "gui", + "v3", "pvall", "asktojoin", "atj", @@ -87,7 +92,7 @@ public class CommandDungeonsGuide extends CommandBase { public void processCommand(ICommandSender sender, String[] args) { if (args.length == 0) { - openConfig = true; + target = new GuiConfigV2(); return; } @@ -97,9 +102,11 @@ public class CommandDungeonsGuide extends CommandBase { break; case "gui": - openConfig = true; + target = new GuiScreenAdapter(new GlobalHUDScale(new HUDLocationConfig(null))); + break; + case "v3": + target = new GuiScreenAdapter(new GlobalHUDScale(new MainConfigWidget())); break; - case "pv": pvCommand(args[1], sender); //args[1] is the player name break; @@ -145,12 +152,14 @@ public class CommandDungeonsGuide extends CommandBase { } } + private GuiScreen target; + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent e) { try { - if (openConfig && e.phase == TickEvent.Phase.START) { - openConfig = false; - Minecraft.getMinecraft().displayGuiScreen(new GuiConfigV2()); + if (target != null && e.phase == TickEvent.Phase.START) { + Minecraft.getMinecraft().displayGuiScreen(target); + target = null; } } catch (Throwable t) { t.printStackTrace(); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java index dd6251ae..6db1a9ae 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/RootConfigPanel.java @@ -101,7 +101,7 @@ public class RootConfigPanel extends MPanelScaledGUI { guiRelocate = new MButton(); guiRelocate.setText("Edit Gui Locations"); guiRelocate.setOnActionPerformed(() -> { - Minecraft.getMinecraft().displayGuiScreen(new GuiScreenAdapter(new GlobalHUDScale(new HUDLocationConfig()))); + Minecraft.getMinecraft().displayGuiScreen(new GuiScreenAdapter(new GlobalHUDScale(new HUDLocationConfig(null)))); guiRelocate.setBeingClicked(false); }); guiRelocate.setBorder(RenderUtils.blendTwoColors(0xFF141414,0x7702EE67)); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryItem.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryItem.java new file mode 100644 index 00000000..5a2c6f6c --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryItem.java @@ -0,0 +1,55 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Navigator; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Supplier; + +public class CategoryItem extends AnnotatedImportOnlyWidget { + + @Bind(variableName = "name") + public final BindableAttribute<String> name = new BindableAttribute<>(String.class); + @Bind(variableName = "description") + public final BindableAttribute<String> description = new BindableAttribute<>(String.class); + private Supplier<Widget> pageCreator; + + public CategoryItem(Supplier<Widget> pageCreator, String category, String description) { + super(new ResourceLocation("dungeonsguide:gui/config/categoryitem.gui")); + this.pageCreator = pageCreator; + + this.name.setValue(category); + this.description.setValue(description); + } + + @On(functionName = "click") + public void openPage() { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + Navigator.getNavigator(getDomElement()).openPage(pageCreator.get()); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryPageWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryPageWidget.java new file mode 100644 index 00000000..8565167a --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/CategoryPageWidget.java @@ -0,0 +1,65 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Text; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList; +import net.minecraft.util.ResourceLocation; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CategoryPageWidget extends AnnotatedImportOnlyWidget { + @Bind(variableName = "items") + public final BindableAttribute items = new BindableAttribute<>(WidgetList.class); + @Bind(variableName = "categories") + public final BindableAttribute categories = new BindableAttribute<>(WidgetList.class); + @Bind(variableName = "categoryShow") + public final BindableAttribute<String > showCategory = new BindableAttribute<>(String.class); + public CategoryPageWidget(String category) { + super(new ResourceLocation("dungeonsguide:gui/config/categorypage.gui")); + items.setValue(buildMenu(category)); + List<Widget> widgets; + categories.setValue(widgets = buildCategory(category)); + showCategory.setValue(widgets.isEmpty() ? "hide" : "show"); + } + + private List<Widget> buildCategory(String category) { + return FeatureRegistry.getFeaturesByCategory().keySet().stream().filter(a -> a.startsWith(category+".")) + .map(a -> a.substring(category.length()+1).split("\\.")[0]) + .collect(Collectors.toSet()).stream() + .map( a -> new CategoryItem(() -> new CategoryPageWidget(category+"."+a), a, + FeatureRegistry.getCategoryDescription().getOrDefault(category+"."+a, "idk"))) + .collect(Collectors.toList()); + } + + public List<Widget> buildMenu(String category) { + return FeatureRegistry.getFeaturesByCategory() + .getOrDefault(category, Collections.emptyList()).stream().map( + a -> new FeatureItem(a) + ).collect(Collectors.toList()); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/FeatureItem.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/FeatureItem.java new file mode 100644 index 00000000..e91b20d3 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/FeatureItem.java @@ -0,0 +1,85 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location2.HUDLocationConfig; +import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature; +import kr.syeyoung.dungeonsguide.mod.features.AbstractHUDFeature; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.GuiScreenAdapter; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.GlobalHUDScale; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Navigator; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Supplier; + +public class FeatureItem extends AnnotatedImportOnlyWidget { + + @Bind(variableName = "name") + public final BindableAttribute<String> name = new BindableAttribute<>(String.class); + @Bind(variableName = "description") + public final BindableAttribute<String> description = new BindableAttribute<>(String.class); + + @Bind(variableName = "guiRelocate") + public final BindableAttribute<String> guiRelocateShow = new BindableAttribute<>(String.class); + @Bind(variableName = "configure") + public final BindableAttribute<String> configureShow = new BindableAttribute<>(String.class); + @Bind(variableName = "enable") + public final BindableAttribute<String> enableShow = new BindableAttribute<>(String.class); + + @Bind(variableName = "isEnabled") + public final BindableAttribute<Boolean> enabled = new BindableAttribute<>(Boolean.class); + private AbstractFeature feature; + + public FeatureItem(AbstractFeature feature) { + super(new ResourceLocation("dungeonsguide:gui/config/featureitem.gui")); + this.feature = feature; + + this.name.setValue(feature.getName()); + this.description.setValue(feature.getDescription()); + + guiRelocateShow.setValue(feature instanceof AbstractHUDFeature ? "show" : "hide"); + configureShow.setValue("show"); + enableShow.setValue(feature.isDisyllable() ? "show" : "hide"); + enabled.setValue(feature.isEnabled()); + + enabled.addOnUpdate((old, neu) -> { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + feature.setEnabled(neu); + }); + } + + + @On(functionName = "configure") + public void onEdit() { + // do stuff + } + @On(functionName = "relocate") + public void onRelocate() { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + Minecraft.getMinecraft().displayGuiScreen(new GuiScreenAdapter(new GlobalHUDScale(new HUDLocationConfig((AbstractHUDFeature) feature)))); + // do stuff + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/GUIOpenItem.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/GUIOpenItem.java new file mode 100644 index 00000000..0f3d9cda --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/GUIOpenItem.java @@ -0,0 +1,57 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location2.HUDLocationConfig; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.GuiScreenAdapter; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.GlobalHUDScale; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Navigator; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Supplier; + +public class GUIOpenItem extends AnnotatedImportOnlyWidget { + + @Bind(variableName = "image") + public final BindableAttribute<String> image = new BindableAttribute<>(String.class); + @Bind(variableName = "category") + public final BindableAttribute<String> bindableAttribute = new BindableAttribute<>(String.class); + + private Supplier<Widget> pageCreator; + public GUIOpenItem(String category, Supplier<Widget> creator) { + super(new ResourceLocation("dungeonsguide:gui/config/menuitem.gui")); + this.pageCreator = creator; + + bindableAttribute.setValue(category); + image.setValue("dungeonsguide:textures/config/"+category+".png"); + } + + @On(functionName = "click") + public void openPage() { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + Minecraft.getMinecraft().displayGuiScreen(new GuiScreenAdapter(new GlobalHUDScale(pageCreator.get()))); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainConfigWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainConfigWidget.java new file mode 100644 index 00000000..f22b0c07 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainConfigWidget.java @@ -0,0 +1,67 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.config.guiconfig.location2.HUDLocationConfig; +import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature; +import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Navigator; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Text; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.util.ResourceLocation; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class MainConfigWidget extends AnnotatedImportOnlyWidget { + @Bind(variableName = "menu") + public final BindableAttribute menu = new BindableAttribute<>(WidgetList.class); + @Bind(variableName = "relocate") + public final BindableAttribute<Widget> relocate = new BindableAttribute<>(Widget.class); + + @Bind(variableName = "mainpage") + public final BindableAttribute<Widget> mainPage = new BindableAttribute<>(Widget.class, new MainPageWidget()); + public MainConfigWidget() { + super(new ResourceLocation("dungeonsguide:gui/config/normalconfig.gui")); + menu.setValue(buildMenu()); + relocate.setValue(new GUIOpenItem("GUI Relocate", () -> new HUDLocationConfig(null))); + } + + public List<Widget> buildMenu() { + return FeatureRegistry.getFeaturesByCategory().keySet() + .stream().map(a -> a.split("\\.")[0]) + .collect(Collectors.toSet()).stream().map( + a -> new MenuItem(a, () -> new CategoryPageWidget(a)) + ).collect(Collectors.toList()); + } + + @On(functionName = "back") + public void back() { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + Navigator.getNavigator(getDomElement()).goBack(); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainPageWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainPageWidget.java new file mode 100644 index 00000000..232bb090 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MainPageWidget.java @@ -0,0 +1,50 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList; +import net.minecraft.util.ResourceLocation; + +import java.util.List; +import java.util.stream.Collectors; + +public class MainPageWidget extends AnnotatedImportOnlyWidget { + + @Bind(variableName = "categories") + public final BindableAttribute categories = new BindableAttribute<>(WidgetList.class); + public MainPageWidget() { + super(new ResourceLocation("dungeonsguide:gui/config/mainpage.gui")); + categories.setValue(buildCategory()); + } + + + private List<Widget> buildCategory() { + return FeatureRegistry.getFeaturesByCategory().keySet().stream().map(a -> a.split("\\.")[0]) + .collect(Collectors.toSet()).stream() + .map( a -> new CategoryItem(() -> new CategoryPageWidget(a), a, + FeatureRegistry.getCategoryDescription().getOrDefault(a, "idk"))) + .collect(Collectors.toList()); + } + +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MenuItem.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MenuItem.java new file mode 100644 index 00000000..e88c9e43 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/configv3/MenuItem.java @@ -0,0 +1,54 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.config.guiconfig.configv3; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Navigator; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedImportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Supplier; + +public class MenuItem extends AnnotatedImportOnlyWidget { + + @Bind(variableName = "image") + public final BindableAttribute<String> image = new BindableAttribute<>(String.class); + @Bind(variableName = "category") + public final BindableAttribute<String> bindableAttribute = new BindableAttribute<>(String.class); + + private Supplier<Widget> pageCreator; + public MenuItem(String category, Supplier<Widget> creator) { + super(new ResourceLocation("dungeonsguide:gui/config/menuitem.gui")); + this.pageCreator = creator; + + bindableAttribute.setValue(category); + image.setValue("dungeonsguide:textures/config/"+category+".png"); + } + + @On(functionName = "click") + public void openPage() { + Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + Navigator.getNavigator(getDomElement()).openPage(pageCreator.get()); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDConfigRootWidget.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDConfigRootWidget.java index 6fe1a8e9..4d94ca3c 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDConfigRootWidget.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDConfigRootWidget.java @@ -97,12 +97,15 @@ public class HUDConfigRootWidget extends Widget implements Layouter, Renderer { markersY.add(new Position(0, lastHeight/2)); } - public HUDConfigRootWidget() { + private AbstractHUDFeature filter; + public HUDConfigRootWidget(AbstractHUDFeature filter) { + this.filter = filter; widgets.add(new EventListenerWidget()); for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) { if (!(abstractFeature instanceof AbstractHUDFeature)) continue; if (!abstractFeature.isEnabled() && abstractFeature.isDisyllable()) continue; - HUDWidgetWrapper widgetWrapper = new HUDWidgetWrapper((AbstractHUDFeature) abstractFeature, this); + HUDWidgetWrapper widgetWrapper = new HUDWidgetWrapper((AbstractHUDFeature) abstractFeature, this, + filter == null || abstractFeature == filter); widgets.add(widgetWrapper); widgets2.add(widgetWrapper); } @@ -161,6 +164,7 @@ public class HUDConfigRootWidget extends Widget implements Layouter, Renderer { if (mouseButton != 0) return false; this.sx = relMouseX; this.sy = relMouseY; for (HUDWidgetWrapper widgetWrapper : widgets2) { + if (filter != null && widgetWrapper.getAbstractHUDFeature() != filter) continue; if (widgetWrapper.getDomElement().getAbsBounds().contains(absMouseX, absMouseY)) { target = widgetWrapper; started = widgetWrapper.getDomElement().getRelativeBound(); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDLocationConfig.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDLocationConfig.java index bdae741a..4ef6ff35 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDLocationConfig.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDLocationConfig.java @@ -18,6 +18,7 @@ package kr.syeyoung.dungeonsguide.mod.config.guiconfig.location2; +import kr.syeyoung.dungeonsguide.mod.features.AbstractHUDFeature; import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; @@ -30,14 +31,8 @@ public class HUDLocationConfig extends AnnotatedImportOnlyWidget { @Bind(variableName = "movestuff") public final BindableAttribute<Widget> stuff = new BindableAttribute<>(Widget.class); - public HUDLocationConfig() { + public HUDLocationConfig(AbstractHUDFeature filter) { super(new ResourceLocation("dungeonsguide:gui/config/hudconfig.gui")); - stuff.setValue(new HUDConfigRootWidget()); - } - - @Override - public void onUnmount() { - super.onUnmount(); - //save config or smth + stuff.setValue(new HUDConfigRootWidget(filter)); } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDWidgetWrapper.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDWidgetWrapper.java index df9615d5..63e6d44d 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDWidgetWrapper.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/config/guiconfig/location2/HUDWidgetWrapper.java @@ -59,23 +59,27 @@ public class HUDWidgetWrapper extends Widget implements Layouter { private double widthPlus; @Getter private double heightPlus; - public HUDWidgetWrapper(AbstractHUDFeature hudFeature, HUDConfigRootWidget hudConfigRootWidget) { + private boolean enable; + public HUDWidgetWrapper(AbstractHUDFeature hudFeature, HUDConfigRootWidget hudConfigRootWidget, boolean enable) { this.abstractHUDFeature = hudFeature; + this.enable = enable; positioner = new GUIRectPositioner(hudFeature::getFeatureRect); demoWidget = abstractHUDFeature.instantiateDemoWidget(); built.add(demoWidget); - if (abstractHUDFeature.requiresWidthBound()) { - widthWidget = new WidthWidget(); - built.add(widthWidget); - } - if (abstractHUDFeature.requiresHeightBound()) { - heightWidget = new HeightWidget(); - built.add(heightWidget); - } - if ((abstractHUDFeature.requiresWidthBound() && abstractHUDFeature.requiresHeightBound()) || abstractHUDFeature.getKeepRatio() != null) { - // smth - cornerWidget = new CornerWidget(); - built.add(cornerWidget); + if (enable) { + if (abstractHUDFeature.requiresWidthBound()) { + widthWidget = new WidthWidget(); + built.add(widthWidget); + } + if (abstractHUDFeature.requiresHeightBound()) { + heightWidget = new HeightWidget(); + built.add(heightWidget); + } + if ((abstractHUDFeature.requiresWidthBound() && abstractHUDFeature.requiresHeightBound()) || abstractHUDFeature.getKeepRatio() != null) { + // smth + cornerWidget = new CornerWidget(); + built.add(cornerWidget); + } } rootWidget = hudConfigRootWidget; } @@ -121,17 +125,18 @@ public class HUDWidgetWrapper extends Widget implements Layouter { @Override protected Renderer createRenderer() { - return HoverThingyRenderer.hoverThingyRenderer; + return new HoverThingyRenderer(); } - public static class HoverThingyRenderer extends OnlyChildrenRenderer { - public static final HoverThingyRenderer hoverThingyRenderer = new HoverThingyRenderer(); + public class HoverThingyRenderer extends OnlyChildrenRenderer { @Override public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext renderingContext, DomElement buildContext) { - renderingContext.drawRect(0,0, buildContext.getSize().getWidth(), buildContext.getSize().getHeight(), 0x40000000); + if (enable) + renderingContext.drawRect(0,0, buildContext.getSize().getWidth(), buildContext.getSize().getHeight(), 0x40000000); GlStateManager.pushMatrix(); super.doRender(absMouseX, absMouseY, relMouseX, relMouseY, partialTicks, renderingContext, buildContext); GlStateManager.popMatrix(); + if (!enable) return; if (buildContext.getAbsBounds().contains(absMouseX, absMouseY)) renderingContext.drawRect(0,0, buildContext.getSize().getWidth(), buildContext.getSize().getHeight(), 0x33FFFFFF); } @@ -139,6 +144,7 @@ public class HUDWidgetWrapper extends Widget implements Layouter { @Override public boolean mouseMoved(int absMouseX, int absMouseY, double relMouseX0, double relMouseY0) { + if (!enable) return false; if (Mouse.isButtonDown(0)) getDomElement().setCursor(EnumCursor.CLOSED_HAND); else @@ -149,6 +155,7 @@ public class HUDWidgetWrapper extends Widget implements Layouter { @Override public boolean mouseClicked(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int mouseButton) { if (mouseButton == 0) return false; + if (!enable) return false; PopupMgr.getPopupMgr(getDomElement()).openPopup(new AbsLocationPopup( absMouseX, absMouseY, new WidgetPopupMenu(abstractHUDFeature.getTooltipForEditor()), true diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/AbstractHUDFeature.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/AbstractHUDFeature.java index 59b67d90..06eff88d 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/AbstractHUDFeature.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/AbstractHUDFeature.java @@ -19,14 +19,8 @@ package kr.syeyoung.dungeonsguide.mod.features; import com.google.gson.JsonObject; -import kr.syeyoung.dungeonsguide.mod.config.guiconfig.GuiConfigV2; import kr.syeyoung.dungeonsguide.mod.config.types.GUIPosition; import kr.syeyoung.dungeonsguide.mod.config.types.TypeConverterRegistry; -import kr.syeyoung.dungeonsguide.mod.gui.MPanel; -import kr.syeyoung.dungeonsguide.mod.gui.elements.MButton; -import kr.syeyoung.dungeonsguide.mod.gui.elements.MLabel; -import kr.syeyoung.dungeonsguide.mod.gui.elements.MPassiveLabelAndElement; -import kr.syeyoung.dungeonsguide.mod.gui.elements.MToggleButton; import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.Text; @@ -35,13 +29,8 @@ import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox; import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size; import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext; -import lombok.AccessLevel; import lombok.Getter; -import lombok.Setter; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -126,7 +115,7 @@ public abstract class AbstractHUDFeature extends AbstractGuiFeature { public List<Widget> getTooltipForEditor() { ArrayList<Widget> mPanels = new ArrayList<>(); - mPanels.add(new Text(getName(), 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0)); + mPanels.add(new Text(getName(), 0xFFFFFFFF, Text.TextAlign.CENTER, Text.WordBreak.WORD, 1.0, 8.0)); // mPanels.add(new MButton() { // { // setText("Edit"); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/etc/FeaturePenguins.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/etc/FeaturePenguins.java index 8cca6653..3e4bc78c 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/etc/FeaturePenguins.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/etc/FeaturePenguins.java @@ -54,7 +54,7 @@ public class FeaturePenguins extends SimpleFeature { } @DGEventHandler - public void onTextureStitch(TextureStitchEvent event) { + public void onTextureStitch(TextureStitchEvent.Pre event) { if (event instanceof TextureStitchEvent.Pre) { objModel = null; ResourceLocation modelResourceLocation = new ResourceLocation("dungeonsguide:models/penguin.obj"); @@ -69,6 +69,9 @@ public class FeaturePenguins extends SimpleFeature { e.printStackTrace(); } } + } + @DGEventHandler + public void onTextureStitchPost(TextureStitchEvent.Post event) { if (objModel != null && event instanceof TextureStitchEvent.Post) { model = objModel.bake(objModel.getDefaultState(), DefaultVertexFormats.ITEM, ModelLoader.defaultTextureGetter()); } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/party/playerpreview/FakePlayer.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/party/playerpreview/FakePlayer.java index 1cbb01b5..b817dec7 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/party/playerpreview/FakePlayer.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/party/playerpreview/FakePlayer.java @@ -46,7 +46,8 @@ public class FakePlayer extends EntityOtherPlayerMP { this.skyblockProfile = skyblockProfile; armor = skyblockProfile.getCurrentArmor(); - this.inventory.armorInventory = skyblockProfile.getCurrentArmor().getArmorSlots(); + if (skyblockProfile.getCurrentArmor() != null) + this.inventory.armorInventory = skyblockProfile.getCurrentArmor().getArmorSlots(); int highestDungeonScore = Integer.MIN_VALUE; if (skyblockProfile.getInventory() != null) { diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/secret/mechanicbrowser/WidgetMechanicBrowser.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/secret/mechanicbrowser/WidgetMechanicBrowser.java index aafc9402..7e58cff1 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/secret/mechanicbrowser/WidgetMechanicBrowser.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/features/impl/secret/mechanicbrowser/WidgetMechanicBrowser.java @@ -25,7 +25,11 @@ import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom; import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.GeneralRoomProcessor; import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size; import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget; import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.On; @@ -36,7 +40,7 @@ import net.minecraft.util.ResourceLocation; import java.util.*; -public class WidgetMechanicBrowser extends AnnotatedWidget { +public class WidgetMechanicBrowser extends AnnotatedWidget implements Layouter { @Bind(variableName = "current") public final BindableAttribute<String> current = new BindableAttribute<>(String.class); @Bind(variableName = "children") @@ -112,4 +116,12 @@ public class WidgetMechanicBrowser extends AnnotatedWidget { GeneralRoomProcessor grp = (GeneralRoomProcessor) dungeonRoom.getRoomProcessor(); grp.cancel("MECH-BROWSER"); } + + @Override + public Size layout(DomElement buildContext, ConstraintBox constraintBox) { + FeatureMechanicBrowse featureMechanicBrowse = FeatureRegistry.SECRET_BROWSE; + Double ratio = featureMechanicBrowse.getRatio(); + return new Size(featureMechanicBrowse.getFeatureRect().getWidth(), + ratio != null ? featureMechanicBrowse.getFeatureRect().getWidth() * ratio : featureMechanicBrowse.getFeatureRect().getHeight()); + } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java index 34299f85..cfdbe89f 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Align.java @@ -54,9 +54,11 @@ public class Align extends AnnotatedExportOnlyWidget implements Layouter { Size size = theOnly.getLayouter().layout(theOnly, new ConstraintBox( 0, constraintBox.getMaxWidth(), 0, constraintBox.getMaxHeight() )); - theOnly.setRelativeBound(new Rect( - (constraintBox.getMaxWidth() - size.getWidth())/2, - (constraintBox.getMaxHeight() - size.getHeight())/2, + + double x = hAlign.getValue() == Alignment.START ? 0 : hAlign.getValue() == Alignment.CENTER ? (constraintBox.getMaxWidth() - size.getWidth())/2 : constraintBox.getMaxWidth() - size.getWidth(); + double y = vAlign.getValue() == Alignment.START ? 0 : vAlign.getValue() == Alignment.CENTER ? (constraintBox.getMaxHeight() - size.getHeight())/2 : constraintBox.getMaxHeight() - size.getHeight(); + + theOnly.setRelativeBound(new Rect(x, y, size.getWidth(), size.getHeight() )); return new Size(constraintBox.getMaxWidth(), constraintBox.getMaxHeight()); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Border.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Border.java index 02f14d6d..d9160752 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Border.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Border.java @@ -126,9 +126,11 @@ public class Border extends AnnotatedExportOnlyWidget implements Layouter { if (child.getWidget() == this.right.getValue()) right = child; if (child.getWidget() == this.content.getValue()) content = child; } - return content.getLayouter().getMaxIntrinsicWidth(content, height) - + left.getLayouter().getMaxIntrinsicWidth(left, height) - + right.getLayouter().getMaxIntrinsicWidth(right, height); + double effHeight = height - top.getLayouter().getMaxIntrinsicHeight(top, 0) + - bottom.getLayouter().getMaxIntrinsicHeight(bottom, 0); + return content.getLayouter().getMaxIntrinsicWidth(content, effHeight) + + left.getLayouter().getMaxIntrinsicWidth(left, effHeight) + + right.getLayouter().getMaxIntrinsicWidth(right, effHeight); } @Override @@ -141,7 +143,9 @@ public class Border extends AnnotatedExportOnlyWidget implements Layouter { if (child.getWidget() == this.right.getValue()) right = child; if (child.getWidget() == this.content.getValue()) content = child; } - return content.getLayouter().getMaxIntrinsicHeight(content, width) + double effWidth = width - left.getLayouter().getMaxIntrinsicHeight(top, 0) + - right.getLayouter().getMaxIntrinsicHeight(bottom, 0); + return content.getLayouter().getMaxIntrinsicHeight(content, effWidth) + top.getLayouter().getMaxIntrinsicHeight(top, width) + bottom.getLayouter().getMaxIntrinsicHeight(bottom, width); } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java index 1dc1a330..83f01c52 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Button.java @@ -100,12 +100,13 @@ public class Button extends AnnotatedWidget implements Renderer { public boolean mouseClicked(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int mouseButton) { getDomElement().obtainFocus(); isPressed = true; + + return onClick.getValue() != null; } @Override public void mouseReleased(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int state) { - if (!isPressed) return; isPressed = false; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/CircularRect.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/CircularRect.java new file mode 100644 index 00000000..f5a14693 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/CircularRect.java @@ -0,0 +1,75 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.guiv2.elements; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.SingleChildRenderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; +import kr.syeyoung.dungeonsguide.mod.shader.ShaderManager; +import kr.syeyoung.dungeonsguide.mod.shader.ShaderProgram; +import net.minecraft.client.Minecraft; +import org.lwjgl.opengl.GL20; + +import java.util.Collections; +import java.util.List; + +public class CircularRect extends AnnotatedExportOnlyWidget { + + @Export(attributeName = "backgroundColor") + public final BindableAttribute<Integer> color = new BindableAttribute<>(Integer.class, 0xFFFFFFFF); + + @Export(attributeName = "_") + public final BindableAttribute<Widget> child = new BindableAttribute<>(Widget.class); + + @Override + protected Renderer createRenderer() { + return new BRender(); + } + + @Override + public List<Widget> build(DomElement buildContext) { + return child.getValue() == null ? Collections.EMPTY_LIST : Collections.singletonList(child.getValue()); + } + + public class BRender extends SingleChildRenderer { + @Override + public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext renderingContext, DomElement buildContext) { + Size size = buildContext.getSize(); + double radius = Math.min(size.getWidth(), size.getHeight()) / 2; + + ShaderProgram shaderProgram = ShaderManager.getShader("shaders/roundrect"); + shaderProgram.useShader(); + shaderProgram.uploadUniform("radius", (float)(radius * buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth())); + shaderProgram.uploadUniform("halfSize", (float) buildContext.getAbsBounds().getWidth()/2, (float) buildContext.getAbsBounds().getHeight()/2); + shaderProgram.uploadUniform("centerPos", + (float) (buildContext.getAbsBounds().getX()+buildContext.getAbsBounds().getWidth()/2), + Minecraft.getMinecraft().displayHeight - (float) (buildContext.getAbsBounds().getY() + buildContext.getAbsBounds().getHeight()/2)); + shaderProgram.uploadUniform("smoothness", 1.0f); + renderingContext.drawRect(0,0,buildContext.getSize().getWidth(), buildContext.getSize().getHeight(), color.getValue()); + GL20.glUseProgram(0); + super.doRender(absMouseX, absMouseY, relMouseX, relMouseY, partialTicks, renderingContext, buildContext); + } + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java index 7d0155d6..f8105b6f 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Column.java @@ -119,6 +119,7 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter { if (flexFound) { double remainingHeight = effheight - height; + if (remainingHeight < 0) remainingHeight = 0; double heightPer = remainingHeight / sumFlex; for (DomElement child : buildContext.getChildren()) { @@ -207,27 +208,48 @@ public class Column extends AnnotatedExportOnlyWidget implements Layouter { @Override public double getMaxIntrinsicWidth(DomElement buildContext, double height) { + double startingWidth = 0; + double prevWidth = 0; double maxWidth = 0; - double heightTaken = 0; - int sumFlex = 0; - for (DomElement child : buildContext.getChildren()) { - if (!(child.getWidget() instanceof Flexible)) { - heightTaken += child.getLayouter().getMaxIntrinsicHeight(child, 0); - maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, 0)); - } else { - sumFlex += ((Flexible) child.getWidget()).flex.getValue(); + int circuitBreaker = 0; + do { + circuitBreaker++; + if (circuitBreaker > 100) { + try { + throw new RuntimeException("Caught in infinite loop welp"); + } catch (Exception e) { e.printStackTrace(); } + break; } - } - double leftOver = height - heightTaken; - if (sumFlex > 0) { - double per = leftOver / sumFlex; - if (height == 0) per = 0; + prevWidth = startingWidth; + startingWidth = maxWidth; + double heightTaken = 0; + int sumFlex = 0; for (DomElement child : buildContext.getChildren()) { - if (child.getWidget() instanceof Flexible) { - maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, per * ((Flexible) child.getWidget()).flex.getValue())); + if (!(child.getWidget() instanceof Flexible)) { + heightTaken += child.getLayouter().getMaxIntrinsicHeight(child, startingWidth); + maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, 0)); + } else { + sumFlex += ((Flexible) child.getWidget()).flex.getValue(); } } - } + double leftOver = height - heightTaken; + if (leftOver <= 0) { + leftOver = 0; + if (prevWidth > 0) + maxWidth = prevWidth; + break; + } + if (sumFlex > 0) { + double per = leftOver / sumFlex; + if (height == 0) per = 0; + for (DomElement child : buildContext.getChildren()) { + if (child.getWidget() instanceof Flexible) { + maxWidth = Double.max(maxWidth, child.getLayouter().getMaxIntrinsicWidth(child, per * ((Flexible) child.getWidget()).flex.getValue())); + } + } + } + if (leftOver == 0 || sumFlex == 0) break; + } while (startingWidth != maxWidth); return maxWidth; } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Navigator.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Navigator.java new file mode 100644 index 00000000..5126b7cb --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Navigator.java @@ -0,0 +1,80 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.guiv2.elements; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; + +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +public class Navigator extends AnnotatedExportOnlyWidget { + public Stack<Widget> widgets = new Stack<>(); + + @Export(attributeName = "_") + public final BindableAttribute<Widget> child = new BindableAttribute<>(Widget.class); + + public Widget current; + + public Navigator() { + child.addOnUpdate((old, a) -> { + if (current == null) current = a; + }); + } + + public void openPage(Widget widget) { + widgets.push(current); + getDomElement().removeElement(getDomElement().getChildren().get(0)); + getDomElement().addElement(widget.createDomElement(getDomElement())); + current = widget; + } + + public void goBack() { + getDomElement().removeElement(getDomElement().getChildren().get(0)); + Widget page; + if (widgets.isEmpty()) page = child.getValue(); + else page = widgets.pop(); + getDomElement().addElement(page.createDomElement(getDomElement())); + current = page; + } + + public static Navigator getNavigator(DomElement element) { + return element.getContext().getValue(Navigator.class, "navigator"); + } + + @Override + public List<Widget> build(DomElement buildContext) { + return Collections.singletonList(current); + } + + @Override + public void onMount() { + getDomElement().getContext().CONTEXT.put("navigator", this); + } + + @Override + public void onUnmount() { + getDomElement().getContext().CONTEXT.remove("navigator"); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Padding.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Padding.java index 388b25b1..c5f7fab3 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Padding.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Padding.java @@ -84,12 +84,14 @@ public class Padding extends AnnotatedExportOnlyWidget implements Layouter { @Override public double getMaxIntrinsicWidth(DomElement buildContext, double height) { return left.getValue() + right.getValue() + - (buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicWidth(buildContext.getChildren().get(0), height)); + (buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicWidth(buildContext.getChildren().get(0), + Math.max(0, height - top.getValue() - bottom.getValue()))); } @Override public double getMaxIntrinsicHeight(DomElement buildContext, double width) { return top.getValue() + bottom.getValue() + ( - buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicHeight(buildContext.getChildren().get(0), width)); + buildContext.getChildren().isEmpty() ? 0 : buildContext.getChildren().get(0).getLayouter().getMaxIntrinsicHeight(buildContext.getChildren().get(0), + Math.max(0, width - left.getValue() - right.getValue()))); } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java index fa78cd80..9a11c5bd 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Row.java @@ -121,6 +121,7 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter { if (flexFound) { double remainingWidth = effwidth - width; + if (remainingWidth < 0) remainingWidth = 0; double widthPer = remainingWidth / sumFlex; for (DomElement child : buildContext.getChildren()) { @@ -196,27 +197,50 @@ public class Row extends AnnotatedExportOnlyWidget implements Layouter { @Override public double getMaxIntrinsicHeight(DomElement buildContext, double width) { + double prevHeight = 0; + double startingHeight = 0; double maxHeight = 0; - double widthTaken = 0; - int sumFlex = 0; - for (DomElement child : buildContext.getChildren()) { - if (!(child.getWidget() instanceof Flexible)) { - widthTaken += child.getLayouter().getMaxIntrinsicWidth(child, 0); - maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, 0)); - } else { - sumFlex += ((Flexible) child.getWidget()).flex.getValue(); + int circuitBreaker = 0; + do { + circuitBreaker++; + if (circuitBreaker > 1000) { + try { + throw new RuntimeException("Caught in infinite loop welp"); + } catch (Exception e) { e.printStackTrace(); } + break; } - } - double leftOver = width - widthTaken; - if (sumFlex > 0) { - double per = leftOver / sumFlex; - if (width == 0) per = 0; + prevHeight = startingHeight; + startingHeight = maxHeight; + maxHeight = 0; + double widthTaken = 0; + int sumFlex = 0; for (DomElement child : buildContext.getChildren()) { - if (child.getWidget() instanceof Flexible) { - maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, per * ((Flexible) child.getWidget()).flex.getValue())); + if (!(child.getWidget() instanceof Flexible)) { + widthTaken += child.getLayouter().getMaxIntrinsicWidth(child, startingHeight); + maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, 0)); + } else { + sumFlex += ((Flexible) child.getWidget()).flex.getValue(); } } - } + double leftOver = width - widthTaken; + if (leftOver <= 0) { + leftOver = 0; + if (prevHeight > 0) + maxHeight = prevHeight; + break; + } + if (sumFlex > 0) { + double per = leftOver / sumFlex; + if (width == 0) per = 0; + for (DomElement child : buildContext.getChildren()) { + if (child.getWidget() instanceof Flexible) { + maxHeight = Double.max(maxHeight, child.getLayouter().getMaxIntrinsicHeight(child, per * ((Flexible) child.getWidget()).flex.getValue())); + } + } + } + + if (leftOver == 0 || sumFlex == 0) break; + } while (startingHeight != maxHeight); return maxHeight; } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stencil.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stencil.java new file mode 100644 index 00000000..16282dad --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Stencil.java @@ -0,0 +1,112 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.guiv2.elements; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; +import net.minecraft.client.renderer.GlStateManager; +import org.lwjgl.opengl.GL11; + +import java.util.Arrays; +import java.util.List; + +public class Stencil extends AnnotatedExportOnlyWidget implements Renderer { + @Export(attributeName = "_") + public final BindableAttribute<Widget> children = new BindableAttribute<>(Widget.class); + @Export(attributeName = "_stencil") + public final BindableAttribute<Widget> stencil = new BindableAttribute<>(Widget.class); + + @Override + public List<Widget> build(DomElement buildContext) { + return Arrays.asList(children.getValue(), stencil.getValue()); + } + + @Override + protected Layouter createLayouter() { + return Stack.StackingLayouter.INSTANCE; + } + + @Override + public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext context, DomElement buildContext) { + DomElement theThingToDraw = buildContext.getChildren().get(0); + DomElement stencil = buildContext.getChildren().get(1); + + GL11.glEnable(GL11.GL_STENCIL_TEST); + GL11.glClearStencil(0); + GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT); + + GL11.glStencilMask(0xFF); + GL11.glColorMask(false, false, false, false); + GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 0xFF); + GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_REPLACE, GL11.GL_REPLACE); + + GlStateManager.pushMatrix(); + Rect original = stencil.getRelativeBound(); + GlStateManager.translate(original.getX(), original.getY(), 0); + + double absXScale = buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth(); + double absYScale = buildContext.getAbsBounds().getHeight() / buildContext.getSize().getHeight(); + + Rect elementABSBound = new Rect( + (buildContext.getAbsBounds().getX() + original.getX() * absXScale), + (buildContext.getAbsBounds().getY() + original.getY() * absYScale), + (original.getWidth() * absXScale), + (original.getHeight() * absYScale) + ); + stencil.setAbsBounds(elementABSBound); + + stencil.getRenderer().doRender(absMouseX, absMouseY, + relMouseX - original.getX(), + relMouseY - original.getY(), partialTicks,context, stencil); + GlStateManager.popMatrix(); + + + GL11.glStencilFunc(GL11.GL_EQUAL, 1, 0xFF); + GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP); + GL11.glColorMask(true, true, true, true); + + + original = theThingToDraw.getRelativeBound(); + GlStateManager.translate(original.getX(), original.getY(), 0); + + absXScale = buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth(); + absYScale = buildContext.getAbsBounds().getHeight() / buildContext.getSize().getHeight(); + + elementABSBound = new Rect( + (buildContext.getAbsBounds().getX() + original.getX() * absXScale), + (buildContext.getAbsBounds().getY() + original.getY() * absYScale), + (original.getWidth() * absXScale), + (original.getHeight() * absYScale) + ); + theThingToDraw.setAbsBounds(elementABSBound); + + theThingToDraw.getRenderer().doRender(absMouseX, absMouseY, + relMouseX - original.getX(), + relMouseY - original.getY(), partialTicks,context, theThingToDraw); + + GL11.glDisable(GL11.GL_STENCIL_TEST); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java index abd136db..3a161c55 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Text.java @@ -26,28 +26,19 @@ import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.RichText; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.TextSpan; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.shaders.SingleColorShader; import kr.syeyoung.dungeonsguide.mod.guiv2.elements.richtext.styles.ParentDelegatingTextStyle; -import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter; -import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox; -import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size; -import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; -import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext; import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget; import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; -import lombok.AllArgsConstructor; -import lombok.Data; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.GlStateManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.concurrent.CopyOnWriteArrayList; public class Text extends AnnotatedExportOnlyWidget { @Export(attributeName = "text") public final BindableAttribute<String> text = new BindableAttribute<>(String.class, ""); + @Export(attributeName = "size") + public final BindableAttribute<Double> size = new BindableAttribute<>(Double.class, 8.0); private final ParentDelegatingTextStyle textStyle = ParentDelegatingTextStyle.ofDefault(); private final RichText richText = new RichText(new TextSpan(textStyle, ""), BreakWord.WORD, false,RichText.TextAlign.LEFT); @@ -84,6 +75,9 @@ public class Text extends AnnotatedExportOnlyWidget { lineSpacing.addOnUpdate((a,b) -> { updateText(); }); + size.addOnUpdate((a,b) -> { + updateText(); + }); textAlign.addOnUpdate((a,b) -> { richText.setAlign(b == TextAlign.LEFT ? RichText.TextAlign.LEFT : b == TextAlign.CENTER ? RichText.TextAlign.CENTER : RichText.TextAlign.RIGHT); }); @@ -92,13 +86,14 @@ public class Text extends AnnotatedExportOnlyWidget { }); } - public Text(String text, int color, TextAlign align, WordBreak wordBreak, double lineSpacing) { + public Text(String text, int color, TextAlign align, WordBreak wordBreak, double lineSpacing, double size) { this(); this.text.setValue(text); this.color.setValue(color); this.textAlign.setValue(align); this.wordBreak.setValue(wordBreak); this.lineSpacing.setValue(lineSpacing); + this.size.setValue(size); } private void updateText() { @@ -106,6 +101,7 @@ public class Text extends AnnotatedExportOnlyWidget { textStyle.underlineShader = new SingleColorShader(color.getValue()); textStyle.strikeThroughShader = new SingleColorShader(color.getValue()); textStyle.topAscent = lineSpacing.getValue() - 1; + textStyle.size = size.getValue(); TextSpan textSpan = new TextSpan(textStyle, ""); for (TextSpan textSpan2 : parseText(text.getValue())) { textSpan.addChild(textSpan2); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ToggleButton.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ToggleButton.java new file mode 100644 index 00000000..578e03f4 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/ToggleButton.java @@ -0,0 +1,104 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.guiv2.elements; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.RenderingContext; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Passthrough; +import kr.syeyoung.dungeonsguide.mod.utils.cursor.EnumCursor; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.ResourceLocation; + +@Passthrough(exportName = "_on", bindName = "wgtOn", type = Widget.class) +@Passthrough(exportName = "_off", bindName = "wgtOff", type = Widget.class) +@Passthrough(exportName = "_hoverOn", bindName = "wgtHoverOn", type = Widget.class) +@Passthrough(exportName = "_hoverOff", bindName = "wgtHoverOff", type = Widget.class) +public class ToggleButton extends AnnotatedWidget implements Renderer { + + @Bind(variableName = "refOn") + public final BindableAttribute<DomElement> on = new BindableAttribute<DomElement>(DomElement.class); + @Bind(variableName = "refOff") + public final BindableAttribute<DomElement> off = new BindableAttribute<DomElement>(DomElement.class); + @Bind(variableName = "refHoverOn") + public final BindableAttribute<DomElement> hoverOn = new BindableAttribute<DomElement>(DomElement.class); + @Bind(variableName = "refHoverOff") + public final BindableAttribute<DomElement> hoverOff = new BindableAttribute<DomElement>(DomElement.class); + + + @Export(attributeName = "enabled") + public final BindableAttribute<Boolean> enabled = new BindableAttribute<>(Boolean.class); + + public ToggleButton() { + super(new ResourceLocation("dungeonsguide:gui/elements/toggleButton.gui")); + } + + @Override + protected Layouter createLayouter() { + return Stack.StackingLayouter.INSTANCE; + } + + @Override + public void doRender(int absMouseX, int absMouseY, double relMouseX, double relMouseY, float partialTicks, RenderingContext context, DomElement buildContext) { + boolean isHover = buildContext.getSize().contains(relMouseX, relMouseY); + DomElement value; + if (enabled.getValue()) { + value = isHover ? hoverOn.getValue() : on.getValue(); + } else { + value = isHover ? hoverOff.getValue() : off.getValue(); + } + Rect original = value.getRelativeBound(); + GlStateManager.translate(original.getX(), original.getY(), 0); + + double absXScale = buildContext.getAbsBounds().getWidth() / buildContext.getSize().getWidth(); + double absYScale = buildContext.getAbsBounds().getHeight() / buildContext.getSize().getHeight(); + + Rect elementABSBound = new Rect( + (buildContext.getAbsBounds().getX() + original.getX() * absXScale), + (buildContext.getAbsBounds().getY() + original.getY() * absYScale), + (original.getWidth() * absXScale), + (original.getHeight() * absYScale) + ); + value.setAbsBounds(elementABSBound); + + value.getRenderer().doRender(absMouseX, absMouseY, + relMouseX - original.getX(), + relMouseY - original.getY(), partialTicks, context, value); + } + + @Override + public boolean mouseClicked(int absMouseX, int absMouseY, double relMouseX, double relMouseY, int mouseButton) { + getDomElement().obtainFocus(); + enabled.setValue(!enabled.getValue()); + return true; + } + + @Override + public boolean mouseMoved(int absMouseX, int absMouseY, double relMouseX0, double relMouseY0) { + getDomElement().setCursor(EnumCursor.POINTING_HAND); + return true; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java new file mode 100644 index 00000000..d7c50aad --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/Wrap.java @@ -0,0 +1,131 @@ +/* + * 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 <https://www.gnu.org/licenses/>. + */ + +package kr.syeyoung.dungeonsguide.mod.guiv2.elements; + +import kr.syeyoung.dungeonsguide.mod.guiv2.BindableAttribute; +import kr.syeyoung.dungeonsguide.mod.guiv2.DomElement; +import kr.syeyoung.dungeonsguide.mod.guiv2.Widget; +import kr.syeyoung.dungeonsguide.mod.guiv2.layouter.Layouter; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.ConstraintBox; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Rect; +import kr.syeyoung.dungeonsguide.mod.guiv2.primitive.Size; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.OnlyChildrenRenderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.renderer.Renderer; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.AnnotatedExportOnlyWidget; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Bind; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.annotations.Export; +import kr.syeyoung.dungeonsguide.mod.guiv2.xml.data.WidgetList; + +import java.util.List; + +public class Wrap extends AnnotatedExportOnlyWidget implements Layouter { + + @Export(attributeName = "minimumWidth") + public final BindableAttribute<Double> minimumWidth = new BindableAttribute<>(Double.class); + @Export(attributeName = "gap") + public final BindableAttribute<Double> gap = new BindableAttribute<>(Double.class); + + @Export(attributeName = "_") + public final BindableAttribute<WidgetList> widgetListBindableAttribute = new BindableAttribute<>(WidgetList.class); + + @Override + public List<Widget> build(DomElement buildContext) { + return widgetListBindableAttribute.getValue(); + } + + @Override + public Size layout(DomElement buildContext, ConstraintBox constraintBox) { + List<DomElement> elements = buildContext.getChildren(); + if (elements.isEmpty()) return new Size(constraintBox.getMinWidth(),constraintBox.getMinHeight()); + int itemPerRow = (int) ((constraintBox.getMaxWidth()+gap.getValue()) / (minimumWidth.getValue() + gap.getValue())); + if (itemPerRow == 0) itemPerRow = 1; + if (itemPerRow == Integer.MAX_VALUE) itemPerRow = elements.size(); + int rows = (int) Math.ceil((double)elements.size() / itemPerRow); + + double maxWidth = (constraintBox.getMaxWidth() + gap.getValue()) / itemPerRow - gap.getValue(); + double maxHeight = (constraintBox.getMaxHeight() + gap.getValue()) / rows - gap.getValue(); + double h = 0; + for (int y = 0; y < rows; y++) { + double maxH = 0; + for (int x = 0; x < itemPerRow; x++) { + if (elements.size() <= y * itemPerRow + x) continue; + DomElement element = elements.get(y * itemPerRow + x); + double height = element.getLayouter().getMaxIntrinsicHeight(element, maxWidth); + if (height > maxH) maxH = height; + } + for (int x = 0; x < itemPerRow; x++) { + if (elements.size() <= y * itemPerRow + x) continue; + DomElement element = elements.get(y * itemPerRow + x); + Size size = element.getLayouter().layout(element, new ConstraintBox( + maxWidth, maxWidth, maxH, maxH + )); + element.setRelativeBound(new Rect( + x * (maxWidth + gap.getValue()), + h, + size.getWidth(), + size.getHeight() + )); + } + + h += maxH + gap.getValue(); + } + + return new Size(constraintBox.getMaxWidth(), Layouter.clamp(h - gap.getValue(), 0, constraintBox.getMaxHeight())); + } + + @Override + public double getMaxIntrinsicWidth(DomElement buildContext, double height) { + return buildContext.getChildren().stream() + .map(a -> a.getLayouter().getMaxIntrinsicWidth(a, height) + gap.getValue()) + .reduce(Double::sum) + .orElse(gap.getValue()) - gap.getValue(); + } + + @Override + public double getMaxIntrinsicHeight(DomElement buildContext, double width) { + List<DomElement> elements = buildContext.getChildren(); + if (elements.isEmpty()) return 0; + int itemPerRow = (int) ((width+gap.getValue()) / (minimumWidth.getValue() + gap.getValue())); + if (itemPerRow == 0) itemPerRow = 1; + if (itemPerRow == Integer.MAX_VALUE) itemPerRow = elements.size(); + int rows = (int) Math.ceil((double)elements.size() / itemPerRow); + double maxWidth = (width + gap.getValue()) / itemPerRow - gap.getValue(); + + double sum = 0; + for (int y = 0; y < rows; y++) { + double maxH = 0; + for (int x = 0; x < itemPerRow; x++) { + if (elements.size() <= y * itemPerRow + x) continue; + DomElement element = elements.get(y * itemPerRow + x); + double h = element.getLayouter().getMaxIntrinsicHeight(element, maxWidth); + if (h > maxH) maxH = h; + } + sum += maxH + gap.getValue(); + } + sum -= gap.getValue(); + if (sum < 0) sum = 0; + + return sum; + } + + @Override + protected Renderer createRenderer() { + return OnlyChildrenRenderer.INSTANCE; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/RichText.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/RichText.java index ae09501d..d4d605ff 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/RichText.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/elements/richtext/RichText.java @@ -90,7 +90,12 @@ public class RichText extends Widget implements Layouter, Renderer { line.add(brokenWordData.getFirst()); if (brokenWordData.getFirst().value.length == 0 && first.value.length != 0 && remaining == constraintBox.getMaxWidth()) { - throw new IllegalStateException("Can not fit stuff into this"); + try { + throw new IllegalStateException("Can not fit stuff into this"); + } catch (Exception e) { + e.printStackTrace(); + break; + } } maxHeight = Math.max(maxHeight, first.getHeight()); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java index b34ea8cb..4fcd3fbe 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/guiv2/xml/DomElementRegistry.java @@ -69,6 +69,7 @@ public class DomElementRegistry { register("TextField", new ExportedWidgetConverter(TextField::new)); register("PopupManager", new ExportedWidgetConverter(PopupMgr::new)); register("AbstractButton", new ExportedWidgetConverter(Button::new)); + register("AbstractToggleButton", new ExportedWidgetConverter(ToggleButton::new)); register("ScrollablePanel", new ExportedWidgetConverter(ScrollablePanel::new)); register("AbstractScrollBar", new ExportedWidgetConverter(Scrollbar::new)); register("aspectRatio", new ExportedWidgetConverter(AspectRatioFitter::new)); @@ -77,8 +78,14 @@ public class DomElementRegistry { register("IntrinsicHeight", new ExportedWidgetConverter(IntrinsicHeight::new)); register("TestView", new ExportedWidgetConverter(TestView::new)); register("RoundRect", new ExportedWidgetConverter(RoundRect::new)); + register("CircularRect", new ExportedWidgetConverter(CircularRect::new)); + register("Navigator", new ExportedWidgetConverter(Navigator::new)); + register("Stencil", new ExportedWidgetConverter(Stencil::new)); + register("WrapGrid", new ExportedWidgetConverter(Wrap::new)); register("ColorButton", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleButton.gui"))); + register("RoundButton", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/dgButton.gui"))); + register("SimpleToggleButton", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleToggleButton.gui"))); register("SimpleHorizontalScrollBar", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleHorizontalScrollBar.gui"))); register("SimpleVerticalScrollBar", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/simpleVerticalScrollBar.gui"))); register("SlowList", new DelegatingWidgetConverter(new ResourceLocation("dungeonsguide:gui/elements/slowlist.gui"))); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java index a3c99ae4..818bb363 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/overlay/OverlayManager.java @@ -126,6 +126,7 @@ public class OverlayManager { int j = this.mc.displayHeight - Mouse.getEventY(); if (view.isRelayoutRequested()) { + view.setRelayoutRequested(false); view.getLayouter().layout(view, new ConstraintBox( Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayWidth, |