From bf75ac785babcd02043fff87ecb7b1685b47600d Mon Sep 17 00:00:00 2001 From: Shiewk Date: Sat, 14 Feb 2026 12:47:42 +0100 Subject: [PATCH] Backport 2.3.0 to mc-1.21.6 --- README.md | 13 +- gradle.properties | 4 +- .../java/de/shiewk/widgets/ModWidget.java | 7 +- .../de/shiewk/widgets/WidgetSettings.java | 17 +- .../shiewk/widgets/client/WidgetRenderer.java | 6 +- .../client/screen/ContextMenuScreen.java | 10 +- .../screen/EditWidgetPositionsScreen.java | 7 +- .../client/screen/WidgetConfigScreen.java | 2 +- .../client/screen/WidgetSettingsScreen.java | 17 +- .../client/screen/WidgetVisibilityToggle.java | 7 + .../components/WidgetDisplayWidget.java | 55 ++ .../components/WidgetSettingsEditWidget.java | 16 +- .../GradientEditorColorSection.java | 216 ++++++ .../gradienteditor/GradientEditorScreen.java | 200 +++++ .../GradientEditorSettingsSection.java | 688 ++++++++++++++++++ .../de/shiewk/widgets/color/GradientMode.java | 18 + .../shiewk/widgets/color/GradientOptions.java | 153 ++++ .../shiewk/widgets/color/GradientPreset.java | 29 + .../HorizontalGradientGuiRenderState.java | 102 +++ .../de/shiewk/widgets/utils/WidgetUtils.java | 22 + .../widgets/widgets/ArmorHudWidget.java | 53 +- .../widgets/widgets/BandwidthWidget.java | 19 +- .../widgets/widgets/BasicTextWidget.java | 56 +- .../shiewk/widgets/widgets/BiomeWidget.java | 2 +- .../de/shiewk/widgets/widgets/CPSWidget.java | 12 +- .../shiewk/widgets/widgets/ClockWidget.java | 8 +- .../shiewk/widgets/widgets/ComboWidget.java | 4 +- .../widgets/widgets/CoordinatesWidget.java | 64 +- .../de/shiewk/widgets/widgets/FPSWidget.java | 2 +- .../widgets/widgets/InventoryWidget.java | 80 +- .../widgets/widgets/KeyStrokesWidget.java | 101 +-- .../widgets/widgets/MemoryUsageWidget.java | 6 +- .../de/shiewk/widgets/widgets/PingWidget.java | 17 +- .../widgets/widgets/PlainTextWidget.java | 2 +- .../widgets/widgets/PlayTimeWidget.java | 2 +- .../widgets/widgets/PlayerCountWidget.java | 4 +- .../widgets/widgets/ResizableWidget.java | 10 +- .../widgets/widgets/ServerIPWidget.java | 4 +- .../shiewk/widgets/widgets/SpeedWidget.java | 12 +- .../de/shiewk/widgets/widgets/TPSWidget.java | 19 +- .../widgets/settings/EnumWidgetSetting.java | 4 +- .../settings/GradientWidgetSetting.java | 123 ++++ .../settings/IntSliderWidgetSetting.java | 7 +- .../settings/RGBAColorWidgetSetting.java | 21 +- .../TextFieldWidgetSettingOption.java | 4 +- .../widgets/settings/ToggleWidgetSetting.java | 7 +- .../settings}/WidgetSettingOption.java | 8 +- .../resources/assets/widgets/lang/de_de.json | 28 +- .../resources/assets/widgets/lang/en_us.json | 26 +- .../widgets/textures/gui/arrow_down.png | Bin 0 -> 511 bytes .../widgets/textures/gui/button_plus.png | Bin 0 -> 550 bytes 51 files changed, 1950 insertions(+), 344 deletions(-) create mode 100644 src/main/java/de/shiewk/widgets/client/screen/WidgetVisibilityToggle.java create mode 100644 src/main/java/de/shiewk/widgets/client/screen/components/WidgetDisplayWidget.java create mode 100644 src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorColorSection.java create mode 100644 src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorScreen.java create mode 100644 src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorSettingsSection.java create mode 100644 src/main/java/de/shiewk/widgets/color/GradientMode.java create mode 100644 src/main/java/de/shiewk/widgets/color/GradientOptions.java create mode 100644 src/main/java/de/shiewk/widgets/color/GradientPreset.java create mode 100644 src/main/java/de/shiewk/widgets/render/state/HorizontalGradientGuiRenderState.java create mode 100644 src/main/java/de/shiewk/widgets/widgets/settings/GradientWidgetSetting.java rename src/main/java/de/shiewk/widgets/{ => widgets/settings}/WidgetSettingOption.java (91%) create mode 100644 src/main/resources/assets/widgets/textures/gui/arrow_down.png create mode 100644 src/main/resources/assets/widgets/textures/gui/button_plus.png diff --git a/README.md b/README.md index 7690ca3..7e4a8c0 100644 --- a/README.md +++ b/README.md @@ -41,4 +41,15 @@ Right-clicking on this screen will bring up a useful context menu with additiona When you're done, just press Escape until you return to the game. -Now, everything is done. Your widgets automatically save for the next time you play. \ No newline at end of file +Now, everything is done. Your widgets automatically save for the next time you play. + +## Color editor + +Newer mod versions (2.3.0+) include a **color editor** which provides full customization for your widgets' background and text colors: + +![Color editor screen](assets/images/color-editor.webp) + +The color list on the left shows the colors which are currently configured; if you add more than one, it becomes a gradient. Clicking on the colors will select them. + +The settings bar on the right of the color list can be used to customize gradient settings, import from other widgets, or use presets. +Below that, the color which is currently selected can be changed or deleted. \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2f52ab7..90ece57 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -# Done to increase the memory available to gradle. +# Done to increase the memory available to Gradle. org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html @@ -6,7 +6,7 @@ minecraft_version=1.21.6 yarn_mappings=1.21.6+build.1 loader_version=0.17.2 # Mod Properties -mod_version=2.2.0 +mod_version=2.3.0 maven_group=de.shiewk archives_base_name=Widgets # Dependencies diff --git a/src/main/java/de/shiewk/widgets/ModWidget.java b/src/main/java/de/shiewk/widgets/ModWidget.java index 03b6b86..006a46b 100644 --- a/src/main/java/de/shiewk/widgets/ModWidget.java +++ b/src/main/java/de/shiewk/widgets/ModWidget.java @@ -1,5 +1,6 @@ package de.shiewk.widgets; +import de.shiewk.widgets.widgets.settings.WidgetSettingOption; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; @@ -13,7 +14,7 @@ public abstract class ModWidget { private final Identifier id; private final WidgetSettings settings; - protected ModWidget(Identifier id, List customSettings) { + protected ModWidget(Identifier id, List> customSettings) { Objects.requireNonNull(id, "id"); this.id = id; this.settings = WidgetSettings.ofId(id, customSettings); @@ -36,6 +37,10 @@ public abstract class ModWidget { public abstract Text getDescription(); public abstract void onSettingsChanged(WidgetSettings settings); + public void onSettingsChanged() { + this.onSettingsChanged(this.getSettings()); + } + public int getX(int scaledScreenWidth){ return settings.anchor.getAlignStartPosX(scaledScreenWidth) + settings.offsetX; } diff --git a/src/main/java/de/shiewk/widgets/WidgetSettings.java b/src/main/java/de/shiewk/widgets/WidgetSettings.java index de99835..7b99986 100644 --- a/src/main/java/de/shiewk/widgets/WidgetSettings.java +++ b/src/main/java/de/shiewk/widgets/WidgetSettings.java @@ -4,6 +4,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import de.shiewk.widgets.client.WidgetManager; +import de.shiewk.widgets.widgets.settings.WidgetSettingOption; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.util.Identifier; @@ -18,9 +19,9 @@ public class WidgetSettings { public int offsetX = 0; public int offsetY = 0; private boolean enabled = false; - private final ObjectArrayList customSettings; + private final ObjectArrayList> customSettings; - private WidgetSettings(JsonObject data, List settings){ + private WidgetSettings(JsonObject data, List> settings){ customSettings = new ObjectArrayList<>(settings); if (data != null){ try { @@ -39,7 +40,7 @@ public class WidgetSettings { final JsonElement s = data.get("settings"); if (s != null && s.isJsonObject()){ final JsonObject savedSettings = s.getAsJsonObject(); - for (WidgetSettingOption setting : this.customSettings) { + for (WidgetSettingOption setting : this.customSettings) { final String settingId = setting.getId(); if (savedSettings.has(settingId)){ try { @@ -56,7 +57,7 @@ public class WidgetSettings { } } } - public static WidgetSettings ofId(Identifier id, List customSettings){ + public static WidgetSettings ofId(Identifier id, List> customSettings){ final JsonObject data = WidgetManager.loadWidget(id); return new WidgetSettings(data, customSettings); } @@ -92,7 +93,7 @@ public class WidgetSettings { object.add("oy", gson.toJsonTree(this.offsetY)); JsonObject customSettings = new JsonObject(); - for (WidgetSettingOption customSetting : this.customSettings) { + for (WidgetSettingOption customSetting : this.customSettings) { customSettings.add(customSetting.getId(), customSetting.saveState()); } object.add("settings", customSettings); @@ -100,8 +101,8 @@ public class WidgetSettings { return object; } - public WidgetSettingOption optionById(String id){ - for (WidgetSettingOption customSetting : customSettings) { + public WidgetSettingOption optionById(String id){ + for (WidgetSettingOption customSetting : customSettings) { if (customSetting.getId().equals(id)){ return customSetting; } @@ -109,7 +110,7 @@ public class WidgetSettings { return null; } - public ObjectArrayList getCustomSettings() { + public ObjectArrayList> getCustomSettings() { return customSettings.clone(); } } diff --git a/src/main/java/de/shiewk/widgets/client/WidgetRenderer.java b/src/main/java/de/shiewk/widgets/client/WidgetRenderer.java index 8ec8692..16754a7 100644 --- a/src/main/java/de/shiewk/widgets/client/WidgetRenderer.java +++ b/src/main/java/de/shiewk/widgets/client/WidgetRenderer.java @@ -2,7 +2,7 @@ package de.shiewk.widgets.client; import de.shiewk.widgets.ModWidget; import de.shiewk.widgets.WidgetsMod; -import de.shiewk.widgets.client.screen.EditWidgetPositionsScreen; +import de.shiewk.widgets.client.screen.WidgetVisibilityToggle; import de.shiewk.widgets.client.screen.WidgetConfigScreen; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; @@ -32,7 +32,7 @@ public class WidgetRenderer implements ClientTickEvents.StartTick, ClientLifecyc public void renderWidgets(DrawContext drawContext, RenderTickCounter tickCounter) { if (client.options.hudHidden) return; - if (client.currentScreen instanceof EditWidgetPositionsScreen) return; + if (client.currentScreen instanceof WidgetVisibilityToggle vt && !vt.shouldRenderWidgets()) return; final Profiler profiler = Profilers.get(); profiler.push("widgets"); final TextRenderer textRenderer = client.textRenderer; @@ -81,7 +81,7 @@ public class WidgetRenderer implements ClientTickEvents.StartTick, ClientLifecyc @Override public void onClientStarted(MinecraftClient client) { for (ModWidget widget : WidgetManager.getAllWidgets()) { - widget.onSettingsChanged(widget.getSettings()); + widget.onSettingsChanged(); } } } diff --git a/src/main/java/de/shiewk/widgets/client/screen/ContextMenuScreen.java b/src/main/java/de/shiewk/widgets/client/screen/ContextMenuScreen.java index 73dcc6d..9325e38 100644 --- a/src/main/java/de/shiewk/widgets/client/screen/ContextMenuScreen.java +++ b/src/main/java/de/shiewk/widgets/client/screen/ContextMenuScreen.java @@ -8,7 +8,7 @@ import net.minecraft.text.Text; import java.util.List; -public class ContextMenuScreen extends Screen { +public class ContextMenuScreen extends Screen implements WidgetVisibilityToggle { public record Option(Text title, boolean highlighted, Runnable action){ @@ -130,4 +130,12 @@ public class ContextMenuScreen extends Screen { y += 15; } } + + @Override + public boolean shouldRenderWidgets() { + if (parent instanceof WidgetVisibilityToggle t) { + return t.shouldRenderWidgets(); + } + return true; + } } diff --git a/src/main/java/de/shiewk/widgets/client/screen/EditWidgetPositionsScreen.java b/src/main/java/de/shiewk/widgets/client/screen/EditWidgetPositionsScreen.java index 7490009..b47ed11 100644 --- a/src/main/java/de/shiewk/widgets/client/screen/EditWidgetPositionsScreen.java +++ b/src/main/java/de/shiewk/widgets/client/screen/EditWidgetPositionsScreen.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Locale; import java.util.function.Consumer; -public class EditWidgetPositionsScreen extends AnimatedScreen { +public class EditWidgetPositionsScreen extends AnimatedScreen implements WidgetVisibilityToggle { private final Screen parent; private final Consumer onEdit; @@ -38,6 +38,11 @@ public class EditWidgetPositionsScreen extends AnimatedScreen { client.setScreen(parent); } + @Override + public boolean shouldRenderWidgets() { + return false; + } + private record AlignResult(double result, boolean isEnd){} private static final int SELECT_COLOR = Color.GREEN.getRGB(), ALIGN_COLOR = Color.ORANGE.getRGB(), ALIGN_DISABLED_COLOR = Color.GRAY.getRGB(); diff --git a/src/main/java/de/shiewk/widgets/client/screen/WidgetConfigScreen.java b/src/main/java/de/shiewk/widgets/client/screen/WidgetConfigScreen.java index 0ff2e8a..59f5c43 100644 --- a/src/main/java/de/shiewk/widgets/client/screen/WidgetConfigScreen.java +++ b/src/main/java/de/shiewk/widgets/client/screen/WidgetConfigScreen.java @@ -38,7 +38,7 @@ public class WidgetConfigScreen extends Screen { public void close() { WidgetManager.saveWidgets(widgetsEdited); for (ModWidget widget : widgetsEdited) { - widget.onSettingsChanged(widget.getSettings()); + widget.onSettingsChanged(); } assert client != null; client.setScreen(parent); diff --git a/src/main/java/de/shiewk/widgets/client/screen/WidgetSettingsScreen.java b/src/main/java/de/shiewk/widgets/client/screen/WidgetSettingsScreen.java index 2872b61..22352d6 100644 --- a/src/main/java/de/shiewk/widgets/client/screen/WidgetSettingsScreen.java +++ b/src/main/java/de/shiewk/widgets/client/screen/WidgetSettingsScreen.java @@ -11,7 +11,7 @@ import net.minecraft.util.Util; import java.util.function.Consumer; -public class WidgetSettingsScreen extends AnimatedScreen { +public class WidgetSettingsScreen extends AnimatedScreen implements WidgetVisibilityToggle { private static final Text previewText = Text.translatable("widgets.ui.preview"); private final ModWidget widget; private final Runnable onChange; @@ -19,7 +19,7 @@ public class WidgetSettingsScreen extends AnimatedScreen { super(Text.translatable("widgets.ui.widgetSettings", widget.getName()), parent, 500); this.widget = widget; onChange = () -> { - widget.onSettingsChanged(widget.getSettings()); + widget.onSettingsChanged(); changedWidgetConsumer.accept(widget); }; } @@ -59,4 +59,17 @@ public class WidgetSettingsScreen extends AnimatedScreen { widget.tick(); } } + + @Override + public boolean shouldRenderWidgets() { + return false; + } + + public ModWidget getWidget() { + return widget; + } + + public Runnable getOnChange() { + return onChange; + } } diff --git a/src/main/java/de/shiewk/widgets/client/screen/WidgetVisibilityToggle.java b/src/main/java/de/shiewk/widgets/client/screen/WidgetVisibilityToggle.java new file mode 100644 index 0000000..4da1b3e --- /dev/null +++ b/src/main/java/de/shiewk/widgets/client/screen/WidgetVisibilityToggle.java @@ -0,0 +1,7 @@ +package de.shiewk.widgets.client.screen; + +public interface WidgetVisibilityToggle { + + boolean shouldRenderWidgets(); + +} diff --git a/src/main/java/de/shiewk/widgets/client/screen/components/WidgetDisplayWidget.java b/src/main/java/de/shiewk/widgets/client/screen/components/WidgetDisplayWidget.java new file mode 100644 index 0000000..c02d145 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/client/screen/components/WidgetDisplayWidget.java @@ -0,0 +1,55 @@ +package de.shiewk.widgets.client.screen.components; + +import de.shiewk.widgets.ModWidget; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; +import net.minecraft.client.gui.screen.narration.NarrationPart; +import net.minecraft.client.gui.widget.ClickableWidget; +import net.minecraft.util.Util; + +public class WidgetDisplayWidget extends ClickableWidget { + + protected final ModWidget widget; + protected final TextRenderer textRenderer; + protected final int centerX; + protected final int centerY; + + public WidgetDisplayWidget(ModWidget widget, TextRenderer textRenderer, int centerX, int centerY) { + super(0, 0, (int) widget.scaledWidth(), (int) widget.scaledHeight(), widget.getName()); + this.widget = widget; + this.textRenderer = textRenderer; + this.centerX = centerX; + this.centerY = centerY; + } + + @Override + public int getX() { + return (int) (centerX - (widget.scaledWidth() / 2f)); + } + + @Override + public int getY() { + return (int) (centerY - (widget.scaledHeight() / 2f)); + } + + @Override + public int getWidth() { + return (int) widget.scaledWidth(); + } + + @Override + public int getHeight() { + return (int) widget.scaledHeight(); + } + + @Override + protected void renderWidget(DrawContext context, int mouseX, int mouseY, float deltaTicks) { + widget.render(context, Util.getMeasuringTimeNano(), textRenderer, getX(), getY()); + } + + @Override + protected void appendClickableNarrations(NarrationMessageBuilder builder) { + builder.put(NarrationPart.HINT, widget.getName()); + } +} diff --git a/src/main/java/de/shiewk/widgets/client/screen/components/WidgetSettingsEditWidget.java b/src/main/java/de/shiewk/widgets/client/screen/components/WidgetSettingsEditWidget.java index c1605fd..0ec488e 100644 --- a/src/main/java/de/shiewk/widgets/client/screen/components/WidgetSettingsEditWidget.java +++ b/src/main/java/de/shiewk/widgets/client/screen/components/WidgetSettingsEditWidget.java @@ -1,7 +1,7 @@ package de.shiewk.widgets.client.screen.components; import de.shiewk.widgets.ModWidget; -import de.shiewk.widgets.WidgetSettingOption; +import de.shiewk.widgets.widgets.settings.WidgetSettingOption; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; @@ -16,7 +16,7 @@ public class WidgetSettingsEditWidget extends ScrollableWidget { private final TextRenderer textRenderer; private final ModWidget widget; private final Runnable onChange; - private WidgetSettingOption focus = null; + private WidgetSettingOption focus = null; private int contentsHeight = 10; public WidgetSettingsEditWidget(int x, int y, int width, int height, TextRenderer textRenderer, ModWidget widget, Runnable onChange) { @@ -24,16 +24,16 @@ public class WidgetSettingsEditWidget extends ScrollableWidget { this.widget = widget; this.textRenderer = textRenderer; this.onChange = onChange; - for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { + for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { customSetting.setFocused(false); } setWidth(width); - widget.onSettingsChanged(widget.getSettings()); + widget.onSettingsChanged(); } @Override public void setWidth(int width) { - for (WidgetSettingOption setting : widget.getSettings().getCustomSettings()) { + for (WidgetSettingOption setting : widget.getSettings().getCustomSettings()) { setting.setMaxRenderWidth(width - 10); } super.setWidth(width); @@ -60,7 +60,7 @@ public class WidgetSettingsEditWidget extends ScrollableWidget { context.drawText(textRenderer, widget.getName(), this.width / 4 - textRenderer.getWidth(widget.getName()) / 2, this.height / 100, COLOR_FG, true); matrices.popMatrix(); int y = textRenderer.fontHeight * 2 + this.height / 50 + 5; - for (WidgetSettingOption setting : widget.getSettings().getCustomSettings()) { + for (WidgetSettingOption setting : widget.getSettings().getCustomSettings()) { if (!setting.shouldShow()) continue; if (this.width - setting.getWidth() > textRenderer.getWidth(setting.getName()) + 20){ setting.setX(this.getX() + this.width - setting.getWidth() - 5); @@ -83,7 +83,7 @@ public class WidgetSettingsEditWidget extends ScrollableWidget { @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { mouseY += getScrollY(); - for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { + for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { if (!customSetting.shouldShow()) continue; if (customSetting.isHovered(mouseX, mouseY)){ focus = customSetting; @@ -101,7 +101,7 @@ public class WidgetSettingsEditWidget extends ScrollableWidget { @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { - for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { + for (WidgetSettingOption customSetting : widget.getSettings().getCustomSettings()) { if (!customSetting.shouldShow()) continue; if (customSetting.mouseReleased(mouseX, mouseY + getScrollY())){ onChange.run(); diff --git a/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorColorSection.java b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorColorSection.java new file mode 100644 index 0000000..42a18c0 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorColorSection.java @@ -0,0 +1,216 @@ +package de.shiewk.widgets.client.screen.gradienteditor; + +import de.shiewk.widgets.WidgetsMod; +import de.shiewk.widgets.utils.WidgetUtils; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gl.RenderPipelines; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.IntSupplier; + +import static net.minecraft.text.Text.empty; +import static net.minecraft.text.Text.translatable; + +public class GradientEditorColorSection extends AlwaysSelectedEntryListWidget { + + private final GradientEditorScreen editor; + private static final Identifier TEXTURE_BUTTON_PLUS = Identifier.of(WidgetsMod.MOD_ID, "textures/gui/button_plus.png"), + TEXTURE_ARROW_DOWN = Identifier.of(WidgetsMod.MOD_ID, "textures/gui/arrow_down.png"); + + private final List colorEntries; + + public GradientEditorColorSection(GradientEditorScreen editor, MinecraftClient client, int x, int y, int width, int height, int focusedIndex) { + super(client, width, height, y, 64); + setX(x); + this.editor = editor; + colorEntries = new ObjectArrayList<>(editor.colors.size()); + addEntry(new HeadingEntry(client.textRenderer)); + + IntArrayList colors = editor.colors; + for (int i = 0; i < colors.size(); i++) { + int finalI = i; + ColorEntry col = new ColorEntry(() -> colors.getInt(finalI)); + colorEntries.add(col); + addEntry(col); + addEntry(new ArrowDownEntry()); + } + + addEntry(new AddButtonEntry()); + setFocused(colorEntries.get(focusedIndex)); + } + + @Override + public int getRowWidth() { + return 64; + } + + @Override + protected void drawSelectionHighlight(DrawContext context, int y, int entryWidth, int entryHeight, int borderColor, int fillColor) {} + + @Override + protected void drawMenuListBackground(DrawContext context) { + context.fill(getX(), getY(), getX()+getWidth(), getY()+getHeight(), 0x50_00_00_00); + } + + @Override + protected void drawHeaderAndFooterSeparators(DrawContext context) {} + + @Override + protected void drawScrollbar(DrawContext context) {} + + @Override + public void setFocused(@Nullable Element focused) { + if (focused == null) return; + if (focused instanceof ListEntry se && !se.canFocus()) return; + + if (super.getFocused() != focused){ + WidgetUtils.playSound(SoundEvents.BLOCK_COPPER_BULB_TURN_ON); + } + if (focused instanceof ColorEntry color){ + editor.setCurrentColorIndex(colorEntries.indexOf(color)); + } + super.setFocused(focused); + } + + public void focusLast() { + setFocused(colorEntries.getLast()); + } + + public abstract static class ListEntry extends AlwaysSelectedEntryListWidget.Entry { + + public boolean canFocus(){ + return false; + } + + @Override + public Text getNarration() { + return empty(); + } + } + + public static class ColorEntry extends ListEntry { + + private final IntSupplier color; + + public ColorEntry(IntSupplier color) { + this.color = color; + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + int color = this.color.getAsInt(); + + if (hovered && !isFocused()){ + context.fill(x, y, x+entryWidth, y+entryHeight, 0x30_ff_ff_ff); + } + + int outlineColor; + if (isFocused() || hovered){ + outlineColor = 0xff_ff_ff_00; + } else { + outlineColor = color | 0xff000000; + } + + context.fill(x+1, y+1, x+entryWidth-1, y+entryHeight-1, color); + + // Outline: + context.fill(x+1, y, x+entryWidth-1, y+1, outlineColor); + context.fill(x+1, y+entryHeight-1, x+entryWidth-1, y+entryHeight, outlineColor); + context.fill(x, y+1, x+1, y+entryHeight-1, outlineColor); + context.fill(x+entryWidth-1, y+1, x+entryWidth, y+entryHeight-1, outlineColor); + } + + @Override + public boolean canFocus() { + return true; + } + } + + private static class ArrowDownEntry extends ListEntry { + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + context.drawTexture( + RenderPipelines.GUI_TEXTURED, + TEXTURE_ARROW_DOWN, + x + 16, + y + 16, + 0, + 0, + 32, + 32, + 32, + 32, + 0xff_8d_8d_8d + ); + } + } + + private static class HeadingEntry extends ListEntry { + + private final TextRenderer textRenderer; + + private HeadingEntry(TextRenderer textRenderer) { + this.textRenderer = textRenderer; + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + Text text = translatable("widgets.ui.gradientEditor.colors"); + + y += 2; + int rowWidth = 64; + + int textWidth = textRenderer.getWidth(text); + int textX = x + (rowWidth - textWidth) / 2; + context.drawText(textRenderer, text, textX, y, 0xffffffff, true); + } + } + + private class AddButtonEntry extends ListEntry { + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + context.drawTexture( + RenderPipelines.GUI_TEXTURED, + TEXTURE_BUTTON_PLUS, + x, + y, + 0, + 0, + 64, + 64, + 64, + 64, + hovered ? 0xff_cf_cf_cf : 0xff_8d_8d_8d + ); + if (hovered){ + context.drawTooltip(client.textRenderer, List.of( + translatable("widgets.ui.gradientEditor.colors.add.tooltip.0"), + translatable("widgets.ui.gradientEditor.colors.add.tooltip.1") + ), mouseX, mouseY); + } + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + editor.addNewColor(editor.getCurrentColor()); + return true; + } + } + + @Override + public boolean isFocused() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorScreen.java b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorScreen.java new file mode 100644 index 0000000..0321ed3 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorScreen.java @@ -0,0 +1,200 @@ +package de.shiewk.widgets.client.screen.gradienteditor; + +import de.shiewk.widgets.ModWidget; +import de.shiewk.widgets.client.screen.WidgetVisibilityToggle; +import de.shiewk.widgets.client.screen.components.WidgetDisplayWidget; +import de.shiewk.widgets.color.GradientMode; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.GradientWidgetSetting; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.Text; +import net.minecraft.util.Util; +import org.joml.Matrix3x2fStack; + +import static net.minecraft.text.Text.translatable; + +public class GradientEditorScreen extends Screen implements WidgetVisibilityToggle { + + private static final GradientOptions topBarGradient = new GradientOptions(50, 20, new int[]{0xa0_00_00_00, 0x50_00_00_00}); + + final Screen parent; + final ModWidget widget; + final GradientWidgetSetting setting; + final Runnable onChange; + + GradientMode mode; + final IntArrayList colors; + int gradientSpeed; + int gradientSize; + + int currentColorIndex = 0; + + private GradientEditorColorSection colorSection; + private GradientEditorSettingsSection settingsSection; + + public GradientEditorScreen(Screen parent, ModWidget widget, GradientWidgetSetting setting, Runnable onChange) { + super(translatable("widgets.ui.gradientEditor")); + this.parent = parent; + this.widget = widget; + this.setting = setting; + this.onChange = onChange; + GradientOptions options = setting.getValue(); + this.mode = options.mode(); + this.gradientSpeed = (int) options.gradientSpeed(); + this.gradientSize = (int) options.gradientSize(); + this.colors = IntArrayList.of(options.colors()); + } + + @Override + protected void init() { + super.init(); + reloadComponents(); + } + + private int getTopBarHeight() { + return 8 + this.textRenderer.fontHeight * 2; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) { + super.render(context, mouseX, mouseY, deltaTicks); + + Matrix3x2fStack matrices = context.getMatrices(); + long timeNanos = Util.getMeasuringTimeNano(); + + // Render top bar + topBarGradient.fillHorizontal(context, timeNanos, 0, 0, this.width, this.getTopBarHeight()); + + Text topBarText = translatable("widgets.ui.gradientEditor"); + int width = textRenderer.getWidth(topBarText); + + matrices.pushMatrix().translate(this.width / 2f - width, 5).scale(2); + context.drawText(textRenderer, topBarText, 0, 0, 0xff_ff_ff_ff, true); + matrices.popMatrix(); + } + + public void reloadComponents(){ + clearChildren(); + + double colorScrollY = 0; + double settingsScrollY = 0; + if (this.colorSection != null){ + colorScrollY = colorSection.getScrollY(); + settingsScrollY = settingsSection.getScrollY(); + } + int topBarHeight = getTopBarHeight(); + + + int colorSectionWidth = 90; + int settingsSectionWidth = 110; + int mainAreaWidth = this.width - colorSectionWidth - settingsSectionWidth; + int mainAreaHeight = this.height - topBarHeight; + + // sidebar + this.colorSection = new GradientEditorColorSection(this, this.client, 0, topBarHeight, colorSectionWidth, mainAreaHeight, this.getCurrentColorIndex()); + this.settingsSection = new GradientEditorSettingsSection(this, this.client, colorSectionWidth, topBarHeight, settingsSectionWidth, mainAreaHeight); + addDrawableChild(this.colorSection); + addDrawableChild(this.settingsSection); + colorSection.setScrollY(colorScrollY); + settingsSection.setScrollY(settingsScrollY); + + // main area + int mainAreaX = colorSectionWidth + settingsSectionWidth; + int mainAreaCenterX = mainAreaX + (mainAreaWidth / 2); + + addDrawable(new WidgetDisplayWidget(this.widget, this.textRenderer, mainAreaCenterX, (mainAreaHeight) / 2 + topBarHeight)); + } + + @Override + public void renderBackground(DrawContext context, int mouseX, int mouseY, float deltaTicks) { + super.renderBackground(context, mouseX, mouseY, deltaTicks); + } + + @Override + public void close() { + refreshSettingValue(); + client.setScreen(parent); + } + + private void refreshSettingValue() { + settingsSection.onUpdatedColor(); + setting.setValue(toGradientOptions()); + widget.onSettingsChanged(); + onChange.run(); + } + + private GradientOptions toGradientOptions() { + return new GradientOptions(this.mode, this.gradientSize, this.gradientSpeed, this.colors.toIntArray()); + } + + @Override + public boolean shouldRenderWidgets() { + return false; + } + + public void addNewColor(int initialColor) { + colors.add(initialColor); + this.reloadComponents(); + this.colorSection.focusLast(); + refreshSettingValue(); + } + + public void setGradientSize(double v) { + this.gradientSize = (int) v; + refreshSettingValue(); + } + + public void setGradientSpeed(double v) { + this.gradientSpeed = (int) v; + refreshSettingValue(); + } + + public int getCurrentColor() { + return colors.getInt(currentColorIndex); + } + + public int getCurrentColorIndex() { + return currentColorIndex; + } + + public void setCurrentColorIndex(int i) { + this.currentColorIndex = i; + if (settingsSection != null) settingsSection.onUpdatedColor(); + } + + public void setCurrentColor(int newColor) { + colors.set(getCurrentColorIndex(), newColor); + refreshSettingValue(); + } + + public void removeCurrentColor() { + colors.removeInt(getCurrentColorIndex()); + setCurrentColorIndex(0); + refreshSettingValue(); + reloadComponents(); + } + + public void cycleMode() { + this.mode = GradientMode.values()[(this.mode.ordinal() + 1) % GradientMode.values().length]; + refreshSettingValue(); + } + + public void swapColors(int[] colors) { + this.colors.clear(); + for (int color : colors) { + this.colors.add(color); + } + setCurrentColorIndex(0); + this.reloadComponents(); + refreshSettingValue(); + } + + public void swap(GradientOptions options) { + setGradientSize(options.gradientSize()); + setGradientSpeed(options.gradientSpeed()); + this.mode = options.mode(); + swapColors(options.colors()); + } +} diff --git a/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorSettingsSection.java b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorSettingsSection.java new file mode 100644 index 0000000..72d895d --- /dev/null +++ b/src/main/java/de/shiewk/widgets/client/screen/gradienteditor/GradientEditorSettingsSection.java @@ -0,0 +1,688 @@ +package de.shiewk.widgets.client.screen.gradienteditor; + +import de.shiewk.widgets.WidgetsMod; +import de.shiewk.widgets.client.WidgetManager; +import de.shiewk.widgets.client.screen.ContextMenuScreen; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.color.GradientPreset; +import de.shiewk.widgets.widgets.settings.GradientWidgetSetting; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gl.RenderPipelines; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.tooltip.Tooltip; +import net.minecraft.client.gui.widget.AlwaysSelectedEntryListWidget; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.SliderWidget; +import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.NativeImageBackedTexture; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.glfw.GLFW; + +import java.awt.*; +import java.util.Arrays; +import java.util.function.IntConsumer; +import java.util.function.IntFunction; + +import static de.shiewk.widgets.utils.WidgetUtils.colorARGBToHexRGBA; +import static net.minecraft.text.Text.empty; +import static net.minecraft.text.Text.translatable; + +public class GradientEditorSettingsSection extends AlwaysSelectedEntryListWidget { + + private final GradientEditorScreen editor; + private final HexValueInputEntry hexInput; + private final ColorPickerHueSliderEntry hueSlider; + + public GradientEditorSettingsSection(GradientEditorScreen editor, MinecraftClient client, int x, int y, int width, int height) { + super(client, width, height, y, 22); + setX(x); + this.editor = editor; + + addEntry(new HeadingEntry(translatable("widgets.ui.gradientEditor.gradientSettings"))); + + addEntry(new SliderEntry(1, 100, editor.gradientSize, d -> translatable("widgets.ui.gradientEditor.size", d), editor::setGradientSize)); + addEntry(new SliderEntry(0, 100, editor.gradientSpeed, d -> translatable("widgets.ui.gradientEditor.speed", d), editor::setGradientSpeed)); + addEntry(new ToggleModeButtonEntry()); + addEntry(new ImportButtonEntry()); + addEntry(new UsePresetButtonEntry()); + + addEntry(new HeadingEntry(translatable("widgets.ui.gradientEditor.editColor"))); + + addEntry(new ColorChangerEntry(0)); + addEntry(new ColorChangerEntry(1)); + addEntry(new ColorChangerEntry(2)); + addEntry(new ColorChangerEntry(3)); + + addEntry(new HeadingEntry(translatable("widgets.ui.gradientEditor.editColor.orPick"))); + + ColorPickerEntry colorPicker = new ColorPickerEntry(); + addEntry(colorPicker); + addEntry(new DelegateEntry(colorPicker)); + addEntry(new DelegateEntry(colorPicker)); + addEntry(new DelegateEntry(colorPicker)); + addEntry(new DelegateEntry(colorPicker)); + + addEntry(hueSlider = new ColorPickerHueSliderEntry()); + addEntry(new ColorChangerEntry(3, false)); + addEntry(hexInput = new HexValueInputEntry()); + + addEntry(new RemoveColorButtonEntry()); + } + + @Override + public int getRowWidth() { + return 100; + } + + @Override + protected void drawMenuListBackground(DrawContext context) { + context.fill(getX(), getY(), getX()+getWidth(), getY()+getHeight(), 0x20_00_00_00); + } + + @Override protected void drawHeaderAndFooterSeparators(DrawContext context) {} + @Override protected void drawSelectionHighlight(DrawContext context, int y, int entryWidth, int entryHeight, int borderColor, int fillColor) {} + @Override protected void drawScrollbar(DrawContext context) {} + + public abstract static class ListEntry extends Entry { + + @Override + public Text getNarration() { + return empty(); + } + } + + public void onUpdatedColor(){ + hexInput.refreshText(); + hueSlider.refreshHue(); + } + + private float getCurrentHue(){ + float[] hsb = getHsb(); + return hsb[0]; + } + + private float @NotNull [] getHsb() { + int currentRGBA = editor.getCurrentColor(); + return Color.RGBtoHSB((currentRGBA >> 16) & 0xff, (currentRGBA >> 8) & 0xff, currentRGBA & 0xff, null); + } + + + private class HeadingEntry extends ListEntry { + + private final Text text; + + private HeadingEntry(Text text) { + this.text = text; + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + y += 2; + int rowWidth = 110; + + int textWidth = client.textRenderer.getWidth(text); + int textX = getX() + (rowWidth - textWidth) / 2; + context.drawText(client.textRenderer, text, textX, y, 0xffffffff, true); + } + } + + private class SliderEntry extends ListEntry { + + private final SliderWidget slider; + + private SliderEntry(int min, int max, int initial, IntFunction textGetter, IntConsumer onUpdateValue) { + double value = (double) (initial - min) / (max - min); + slider = new Slider(textGetter, value, onUpdateValue, min, max); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + slider.active = editor.colors.size() > 1; + slider.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + slider.render(context, mouseX, mouseY, tickDelta); + if (hovered && !slider.active) { + slider.setTooltip(Tooltip.of(translatable("widgets.ui.gradientEditor.gradientSettings.addMoreColors"))); + } else { + slider.setTooltip(null); + } + } + + @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { return slider.mouseClicked(mouseX, mouseY, button); } + @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double offsetX, double offsetY) { return slider.mouseDragged(mouseX, mouseY, button, offsetX, offsetY); } + @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { return slider.mouseReleased(mouseX, mouseY, button); } + @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { return slider.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } + @Override public void mouseMoved(double mouseX, double mouseY) { slider.mouseMoved(mouseX, mouseY); } + + private static class Slider extends SliderWidget { + + private final IntFunction textGetter; + private final IntConsumer onUpdateValue; + private final int min; + private final int max; + + public Slider(IntFunction textGetter, double value, IntConsumer onUpdateValue, int min, int max) { + super(0, 0, 0, 0, empty(), value); + this.textGetter = textGetter; + this.onUpdateValue = onUpdateValue; + this.min = min; + this.max = max; + this.updateMessage(); + } + + @Override + protected void updateMessage() { + this.setMessage(textGetter.apply(getTranslatedValue())); + } + + @Override + protected void applyValue() { + onUpdateValue.accept(getTranslatedValue()); + } + + private int getTranslatedValue() { + return (int) (min + (this.value * (max - min))); + } + + } + } + + private class ToggleModeButtonEntry extends ListEntry { + + private final ButtonWidget button = new ButtonWidget.Builder(empty(), this::press).build(); + + public ToggleModeButtonEntry() { + refreshButtonValues(); + } + + private void press(ButtonWidget button) { + editor.cycleMode(); + refreshButtonValues(); + } + + private void refreshButtonValues() { + button.setMessage(translatable("widgets.ui.gradientEditor.mode", editor.mode.name)); + if (editor.colors.size() > 1){ + button.setTooltip(Tooltip.of(editor.mode.description)); + } else { + button.setTooltip(Tooltip.of(translatable("widgets.ui.gradientEditor.gradientSettings.addMoreColors"))); + } + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + button.active = editor.colors.size() > 1; + button.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + button.render(context, mouseX, mouseY, tickDelta); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.button.mouseClicked(mouseX, mouseY, button); + } + } + + private class ImportButtonEntry extends ListEntry { + + private final ButtonWidget button = new ButtonWidget.Builder(translatable("widgets.ui.gradientEditor.importOther"), this::press).build(); + + private void press(ButtonWidget button) { + Screen currentScreen = client.currentScreen; + int menuX = (int) (client.mouse.getX() / client.getWindow().getScaleFactor()); + int menuY = (int) (client.mouse.getY() / client.getWindow().getScaleFactor()); + client.setScreen(new ContextMenuScreen( + button.getMessage(), + currentScreen, + menuX, menuY, + WidgetManager.getAllWidgets() + .stream() + .map(widget -> new ContextMenuScreen.Option( + widget.getName(), + () -> client.setScreen(new ContextMenuScreen( + widget.getName(), + currentScreen, + menuX, + menuY, + widget.getSettings().getCustomSettings() + .stream() + .filter(o -> o instanceof GradientWidgetSetting) + .map(option -> new ContextMenuScreen.Option( + option.getName(), + () -> editor.swap(((GradientWidgetSetting) option).getValue()) + )).toList() + )) + )).toList() + )); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + button.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + button.render(context, mouseX, mouseY, tickDelta); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.button.mouseClicked(mouseX, mouseY, button); + } + } + + private class UsePresetButtonEntry extends ListEntry { + + private final ButtonWidget button = new ButtonWidget.Builder(translatable("widgets.ui.gradientEditor.usePreset"), this::press).build(); + + private void press(ButtonWidget button) { + Screen currentScreen = client.currentScreen; + int menuX = (int) (client.mouse.getX() / client.getWindow().getScaleFactor()); + int menuY = (int) (client.mouse.getY() / client.getWindow().getScaleFactor()); + client.setScreen(new ContextMenuScreen( + translatable("widgets.ui.gradientEditor.usePreset"), + currentScreen, + menuX, menuY, + Arrays.stream(GradientPreset.presets).map(preset -> new ContextMenuScreen.Option( + preset.name(), + () -> editor.swap(preset.gradient()) + )).toList() + )); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + button.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + button.render(context, mouseX, mouseY, tickDelta); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.button.mouseClicked(mouseX, mouseY, button); + } + } + + private class ColorChangerEntry extends ListEntry { + + private final int component; + private final boolean showLabel; + private int posX; + private int width; + + public ColorChangerEntry(int component) { + this(component, true); + } + + public ColorChangerEntry(int component, boolean showLabel) { + this.component = component; + this.showLabel = showLabel; + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + double sliderProg = getComponentValue() / 255d; + this.posX = x; + this.width = entryWidth; + + GradientOptions bg = new GradientOptions(100, 0, new int[]{getBackgroundStartColor(), getBackgroundEndColor()}); + + bg.fillHorizontal(context, 0, x, y + 1, x + entryWidth, y + entryHeight - 1); + + context.drawVerticalLine((int) (x + (entryWidth * sliderProg)), y - 1, y + entryHeight, 0xff_ff_ff_ff); + if (showLabel){ + String label = getLabelWithValue(); + int w = client.textRenderer.getWidth(label); + context.drawText(client.textRenderer, label, x + (entryWidth - w) / 2, y + 5, 0xffffffff, true); + } + } + + private int getComponentValue() { + int currentColor = editor.getCurrentColor(); + return switch (component) { + case 0 -> (currentColor & 0x00_ff_00_00) >>> 16; + case 1 -> (currentColor & 0x00_00_ff_00) >>> 8; + case 2 -> (currentColor & 0x00_00_00_ff); + case 3 -> (currentColor & 0xff_00_00_00) >>> 24; + default -> throw new IllegalStateException(); + }; + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + int newComponentValue = (int) ((mouseX - this.posX) / this.width * 255); + setComponentValue(newComponentValue); + return true; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return mouseDragged(mouseX, mouseY, button, 0, 0); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + if (keyCode == GLFW.GLFW_KEY_LEFT) { + setComponentValue(getComponentValue() - 1); + } else if (keyCode == GLFW.GLFW_KEY_RIGHT) { + setComponentValue(getComponentValue() + 1); + } + return true; + } + + private void setComponentValue(int val) { + val = MathHelper.clamp(val, 0, 255); + final int currentColor = editor.getCurrentColor(); + int newColor = switch (component){ + case 0 -> (currentColor & 0xff_00_ff_ff) | val << 16; + case 1 -> (currentColor & 0xff_ff_00_ff) | val << 8; + case 2 -> (currentColor & 0xff_ff_ff_00) | val; + case 3 -> (currentColor & 0x00_ff_ff_ff) | val << 24; + default -> throw new IllegalStateException(); + }; + editor.setCurrentColor(newColor); + } + + private String getLabelWithValue() { + return switch (component){ + case 0 -> "R: " + getComponentValue(); + case 1 -> "G: " + getComponentValue(); + case 2 -> "B: " + getComponentValue(); + case 3 -> "A: " + getComponentValue(); + default -> throw new IllegalStateException(); + }; + } + + private int getBackgroundEndColor() { + final int currentColor = editor.getCurrentColor(); + return switch (component){ + case 0 -> currentColor | 0x00_ff_00_00; + case 1 -> currentColor | 0x00_00_ff_00; + case 2 -> currentColor | 0x00_00_00_ff; + case 3 -> currentColor | 0xff_00_00_00; + default -> throw new IllegalStateException(); + }; + } + + private int getBackgroundStartColor() { + final int currentColor = editor.getCurrentColor(); + return switch (component){ + case 0 -> currentColor & 0xff_00_ff_ff; + case 1 -> currentColor & 0xff_ff_00_ff; + case 2 -> currentColor & 0xff_ff_ff_00; + case 3 -> currentColor & 0x00_ff_ff_ff; + default -> throw new IllegalStateException(); + }; + } + } + + private class RemoveColorButtonEntry extends ListEntry { + + private final ButtonWidget button = new ButtonWidget.Builder(translatable("widgets.ui.gradientEditor.removeColor"), this::press).build(); + + private void press(ButtonWidget button) { + button.active = false; + editor.removeCurrentColor(); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + button.active = editor.colors.size() > 1; + button.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + button.render(context, mouseX, mouseY, tickDelta); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.button.mouseClicked(mouseX, mouseY, button); + } + } + + private class HexValueInputEntry extends ListEntry { + + private final TextFieldWidget inputField = new TextFieldWidget(client.textRenderer, 0, 0, empty()); + + public HexValueInputEntry() { + this.refreshText(); + inputField.setMaxLength(9); + } + + private void onChangeInputField(String s) { + boolean valid = false; + if (s.startsWith("#")) s = s.substring(1); + if (s.length() == 6) { + s += "ff"; + } + if (s.length() == 8) { + try { + String alpha = s.substring(6, 8); + String rgb = s.substring(0, 6); + String argbHex = alpha + rgb; + + int cl = Integer.parseUnsignedInt(argbHex, 16); + + if (cl != editor.getCurrentColor()) { + editor.setCurrentColor(cl); + } + valid = true; + } catch (NumberFormatException ignored) {} + } + + inputField.setEditableColor(valid ? 0xffffffff : 0xffff0000); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + inputField.setDimensionsAndPosition(entryWidth, entryHeight, x, y); + inputField.render(context, mouseX, mouseY, tickDelta); + } + + public void refreshText(){ + inputField.setChangedListener(null); + inputField.setText('#' + colorARGBToHexRGBA(editor.getCurrentColor())); + inputField.setCursorToStart(false); + inputField.setEditableColor(0xffffffff); + inputField.setChangedListener(this::onChangeInputField); + } + + @Override + public void setFocused(boolean focused) { + inputField.setFocused(focused); + } + + @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { return inputField.mouseClicked(mouseX, mouseY, button); } + @Override public boolean mouseDragged(double mouseX, double mouseY, int button, double offsetX, double offsetY) { return inputField.mouseDragged(mouseX, mouseY, button, offsetX, offsetY); } + @Override public boolean mouseReleased(double mouseX, double mouseY, int button) { return inputField.mouseReleased(mouseX, mouseY, button); } + @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { return inputField.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } + @Override public void mouseMoved(double mouseX, double mouseY) { inputField.mouseMoved(mouseX, mouseY); } + @Override public boolean charTyped(char chr, int modifiers) { return inputField.charTyped(chr, modifiers); } + @Override public boolean keyReleased(int keyCode, int scanCode, int modifiers) { return inputField.keyReleased(keyCode, scanCode, modifiers); } + @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { return inputField.keyPressed(keyCode, scanCode, modifiers); } + } + + private class ColorPickerEntry extends ListEntry { + + private int posX, posY, width, height; + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + this.posX = x; this.posY = y; this.width = entryWidth; this.height = entryHeight = entryWidth; + context.fill( + x, + y, + x + entryWidth, + y + entryHeight, + getBackgroundFillColor() + ); + context.drawTexture( + RenderPipelines.GUI_TEXTURED, + getOverlayTextureIdentifier(), + x, y, + 0, 0, + entryWidth, entryHeight, + entryWidth, entryHeight + ); + + float[] hsb = getHsb(); + int pointerOffsetX = (int) (hsb[1] * entryWidth); + int pointerOffsetY = (int) ((1f - hsb[2]) * entryHeight); + context.fill( + x + pointerOffsetX - 2, y + pointerOffsetY - 2, + x + pointerOffsetX + 2, y + pointerOffsetY + 2, + 0xffffffff + ); + context.fill( + x + pointerOffsetX - 1, y + pointerOffsetY - 1, + x + pointerOffsetX + 1, y + pointerOffsetY + 1, + editor.getCurrentColor() | 0xff000000 + ); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double offsetX, double offsetY) { + double x = mouseX - this.posX; + double y = mouseY - this.posY; + float saturation = (float) Math.clamp(x / this.width, 0d, 1d); + float brightness = (float) Math.clamp(1d - y / this.height, 0d, 1d); + + int newColorRgb = Color.HSBtoRGB(hueSlider.sliderProgress, saturation, brightness) & 0x00ffffff; + int alpha = editor.getCurrentColor() & 0xff000000; + + editor.setCurrentColor(newColorRgb | alpha); + return true; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.mouseDragged(mouseX, mouseY, button, mouseX, mouseY); + } + + private int getBackgroundFillColor() { + return Color.HSBtoRGB(hueSlider.sliderProgress, 1, 1); + } + + private static Identifier OVERLAY_TEXTURE_ID; + + public Identifier getOverlayTextureIdentifier(){ + if (OVERLAY_TEXTURE_ID == null){ + NativeImageBackedTexture texture = generateOverlayTexture(); + OVERLAY_TEXTURE_ID = Identifier.of(WidgetsMod.MOD_ID, "textures/gui/generated/color-picker-overlay"); + client.getTextureManager().registerTexture(OVERLAY_TEXTURE_ID, texture); + } + return OVERLAY_TEXTURE_ID; + } + + private NativeImageBackedTexture generateOverlayTexture() { + NativeImageBackedTexture texture = new NativeImageBackedTexture("widgets:textures/gui/generated/color-picker-overlay", 256, 256, false); + NativeImage image = texture.getImage(); + + for (int x = 0; x < 256; x++) { + for (int y = 0; y < 256; y++) { + double alphaWhite = (255d - x) / 255d; + double alphaBlack = y / 255d; + double outAlpha = alphaBlack + alphaWhite * (1d - alphaBlack); + + int rgb = (int) Math.round(outAlpha > 0 ? (255d * alphaWhite * (1d - alphaBlack)) / outAlpha : 0); + int a = (int) Math.round(outAlpha * 255.0); + + image.setColorArgb(x, y, new Color(rgb, rgb, rgb, a).getRGB()); + } + } + + texture.upload(); + return texture; + } + + } + + private class ColorPickerHueSliderEntry extends ListEntry { + + private static final GradientOptions sliderGradient = new GradientOptions( + 16.666666f, + 0, + new int[]{0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff, 0xff0000ff, 0xffff00ff, 0xffff0000} + ); + private float sliderProgress; + private int x, width; + + public ColorPickerHueSliderEntry(){ + refreshHue(); + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + this.x = x; this.width = entryWidth; + sliderGradient.fillHorizontal(context, 0, x, y + 1, x + entryWidth, y + entryHeight - 1); + context.drawVerticalLine((int) (x + (entryWidth * sliderProgress)), y - 1, y + entryHeight, 0xff_ff_ff_ff); + } + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + double x = mouseX - this.x; + float newHue = (float) Math.clamp(x / this.width, 0, 1); + this.sliderProgress = newHue; + + float[] hsb = getHsb(); + int newRgb = Color.HSBtoRGB(newHue, hsb[1], hsb[2]) & 0x00ffffff; + int alpha = editor.getCurrentColor() & 0xff000000; + int newColor = newRgb | alpha; + + if (newColor != editor.getCurrentColor()){ + editor.setCurrentColor(newColor); + } + return true; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return this.mouseDragged(mouseX, mouseY, button, 0, 0); + } + + public void refreshHue() { + this.sliderProgress = getCurrentHue(); + } + } + + // ugly solution but it works ig 1.21.4 is outdated + private static class DelegateEntry extends ListEntry { + + private final ListEntry delegate; + + public DelegateEntry(ListEntry delegate) { + super(); + this.delegate = delegate; + } + + @Override + public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {} + + @Override + public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { + return delegate.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + return delegate.mouseClicked(mouseX, mouseY, button); + } + + @Override + public void mouseMoved(double mouseX, double mouseY) { + delegate.mouseMoved(mouseX, mouseY); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { + return delegate.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); + } + + @Override + public boolean mouseReleased(double mouseX, double mouseY, int button) { + return delegate.mouseReleased(mouseX, mouseY, button); + } + + @Override + public boolean isMouseOver(double mouseX, double mouseY) { + return delegate.isMouseOver(mouseX, mouseY); + } + } +} \ No newline at end of file diff --git a/src/main/java/de/shiewk/widgets/color/GradientMode.java b/src/main/java/de/shiewk/widgets/color/GradientMode.java new file mode 100644 index 0000000..75a65a7 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/color/GradientMode.java @@ -0,0 +1,18 @@ +package de.shiewk.widgets.color; + +import net.minecraft.text.Text; + +import static net.minecraft.text.Text.translatable; + +public enum GradientMode { + SWEEP(translatable("widgets.gradient.sweep"), translatable("widgets.gradient.sweep.description")), + PULSE(translatable("widgets.gradient.pulse"), translatable("widgets.gradient.pulse.description")); + + public final Text name; + public final Text description; + + GradientMode(Text name, Text description) { + this.name = name; + this.description = description; + } +} diff --git a/src/main/java/de/shiewk/widgets/color/GradientOptions.java b/src/main/java/de/shiewk/widgets/color/GradientOptions.java new file mode 100644 index 0000000..c4cbba4 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/color/GradientOptions.java @@ -0,0 +1,153 @@ +package de.shiewk.widgets.color; + +import de.shiewk.widgets.render.state.HorizontalGradientGuiRenderState; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.text.Text; +import org.joml.Matrix3x2fStack; + +import java.util.Objects; + +import static de.shiewk.widgets.utils.WidgetUtils.fadeColor; + +public record GradientOptions(GradientMode mode, float gradientSize, float gradientSpeed, int[] colors) { + + public GradientOptions(GradientMode mode, float gradientSize, float gradientSpeed, int[] colors) { + this.mode = Objects.requireNonNullElse(mode, GradientMode.SWEEP); + this.gradientSize = gradientSize; + this.gradientSpeed = gradientSpeed; + this.colors = Objects.requireNonNullElse(colors, new int[]{ -1 }); + } + + public GradientOptions(float gradientSize, float gradientSpeed, int[] colors) { + this(GradientMode.SWEEP, gradientSize, gradientSpeed, colors); + } + + public void fillHorizontal(DrawContext context, long timeNanos, int x, int y, int endX, int endY) { + if (colors.length == 1) { + context.fill(x, y, endX, endY, colors[0]); + return; + } + switch (mode){ + case SWEEP -> fillHorizonalSweep(context, timeNanos, x, y, endX, endY); + case PULSE -> fillHorizonalPulse(context, timeNanos, x, y, endX, endY); + } + } + + private void fillHorizonalSweep(DrawContext context, long timeNanos, int x, int y, int endX, int endY) { + context.enableScissor(x, y, endX, endY); + + int width = endX - x; + float sizeFactor = gradientSize / 100f; + int partSize = Math.max(1, Math.round(width * sizeFactor)); + + int totalGradientCycle = colors.length * partSize; + + float speedPxPerSec = width * (gradientSpeed / 100f); + float timeSeconds = timeNanos / 1_000_000_000f; + float offset = gradientSpeed == 0 ? 0 : (timeSeconds * speedPxPerSec + x) % totalGradientCycle; + + Matrix3x2fStack matrices = context.getMatrices().pushMatrix(); + matrices.translate(-offset, 0); + + int currentPos = 0; + int colorIndex = 0; + + while (currentPos < width + totalGradientCycle) { + int color1 = colors[colorIndex % colors.length]; + int color2 = colors[(colorIndex + 1) % colors.length]; + + HorizontalGradientGuiRenderState.draw( + context, x + currentPos, y, x + currentPos + partSize, endY, + color1, color2 + ); + + currentPos += partSize; + colorIndex++; + } + + matrices.popMatrix(); + context.disableScissor(); + } + + private void fillHorizonalPulse(DrawContext context, long timeNanos, int x, int y, int endX, int endY) { + context.fill(x, y, endX, endY, getCurrentPulseColor(timeNanos)); + } + + private int getCurrentPulseColor(long timeNanos) { + float progress = timeNanos / 1_000_000_000f * gradientSpeed / gradientSize; + int color1 = colors[(int) (progress % colors.length)]; + int color2 = colors[(int) ((progress + 1) % colors.length)]; + float delta = progress % 1; + return fadeColor(color1, color2, delta); + } + + public void drawHorizontalLine(DrawContext context, long mt, int posX, int endX, int posY) { + this.fillHorizontal(context, mt, posX, posY, endX, posY + 1); + } + + public void drawText(DrawContext context, TextRenderer textRenderer, long timeNanos, String displayText, int x, int y, boolean shadow) { + if (colors.length == 1){ + context.drawText(textRenderer, displayText, x, y, colors[0], shadow); + } else { + switch (mode){ + case SWEEP -> drawTextSweep(context, textRenderer, timeNanos, displayText, x, y, shadow); + case PULSE -> drawTextPulse(context, textRenderer, timeNanos, displayText, x, y, shadow); + } + } + } + + public void drawText(DrawContext context, TextRenderer textRenderer, long timeNanos, Text displayText, int x, int y, boolean shadow) { + if (colors.length == 1){ + context.drawText(textRenderer, displayText, x, y, colors[0], shadow); + } + this.drawText(context, textRenderer, timeNanos, displayText.getString(), x, y, shadow); + } + + private void drawTextSweep(DrawContext context, TextRenderer textRenderer, long timeNanos, String displayText, int x, int y, boolean shadow) { + int pos = 0; + for (int i = 0; i < displayText.length(); i++) { + String s = String.valueOf(displayText.charAt(i)); + int w = textRenderer.getWidth(s); + int col = computeSweepTextColorAt(gradientSpeed == 0 ? pos : pos + x, timeNanos); + context.drawText(textRenderer, s, x +pos, y, col, shadow); + pos += w; + } + } + + private int computeSweepTextColorAt(float pos, long timeNanos) { + pos += timeNanos / 500_000_000f * gradientSpeed; + + float partSize = gradientSize * 2; + int part = (int) (pos / partSize); + double off = pos % partSize / partSize; + + int color1 = colors[part % colors.length]; + int color2 = colors[(part+1) % colors.length]; + + return fadeColor(color1, color2, off); + } + + private void drawTextPulse(DrawContext context, TextRenderer textRenderer, long timeNanos, String displayText, int x, int y, boolean shadow) { + context.drawText(textRenderer, displayText, x, y, getCurrentPulseColor(timeNanos), shadow); + } + + public static GradientOptions solidColor(int color) { + return new GradientOptions(1, 0, new int[]{color}); + } + + public void drawVerticalLine(DrawContext context, long timeNanos, int posX, int posY, int endY) { + fillHorizontal(context, timeNanos, posX, posY, posX + 1, endY); + } + + public GradientOptions multiplyAlpha(double v) { + int[] newColors = new int[colors.length]; + for (int i = 0; i < colors.length; i++) { + int color = colors[i]; + int rgb = color & 0xffffff; + int newAlpha = (int) (((color & 0xff000000) >>> 24) * v); + newColors[i] = (newAlpha << 24) | rgb; + } + return new GradientOptions(mode, gradientSize, gradientSpeed, newColors); + } +} \ No newline at end of file diff --git a/src/main/java/de/shiewk/widgets/color/GradientPreset.java b/src/main/java/de/shiewk/widgets/color/GradientPreset.java new file mode 100644 index 0000000..d84043b --- /dev/null +++ b/src/main/java/de/shiewk/widgets/color/GradientPreset.java @@ -0,0 +1,29 @@ +package de.shiewk.widgets.color; + +import net.minecraft.text.Text; + +import static net.minecraft.text.Text.translatable; + +public record GradientPreset(Text name, GradientOptions gradient) { + + public static final GradientPreset[] presets = new GradientPreset[]{ + new GradientPreset( + translatable("widgets.gradient.preset.rainbow"), + new GradientOptions( + GradientMode.PULSE, + 14, + 20, + new int[]{ + 0xff_ff_00_00, + 0xff_ff_88_00, + 0xff_ff_ff_00, + 0xff_00_ff_00, + 0xff_00_ff_ff, + 0xff_50_00_80, + 0xff_ff_00_ff, + } + ) + ) + }; + +} diff --git a/src/main/java/de/shiewk/widgets/render/state/HorizontalGradientGuiRenderState.java b/src/main/java/de/shiewk/widgets/render/state/HorizontalGradientGuiRenderState.java new file mode 100644 index 0000000..63a6963 --- /dev/null +++ b/src/main/java/de/shiewk/widgets/render/state/HorizontalGradientGuiRenderState.java @@ -0,0 +1,102 @@ +package de.shiewk.widgets.render.state; + +import com.mojang.blaze3d.pipeline.RenderPipeline; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.gl.RenderPipelines; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.ScreenRect; +import net.minecraft.client.gui.render.state.SimpleGuiElementRenderState; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.texture.TextureSetup; +import org.jetbrains.annotations.Nullable; +import org.joml.Matrix3x2f; + +@Environment(EnvType.CLIENT) +public final class HorizontalGradientGuiRenderState implements SimpleGuiElementRenderState { + + private final RenderPipeline pipeline; + private final TextureSetup textureSetup; + private final Matrix3x2f pose; + private final ScreenRect scissorArea; + private final ScreenRect bounds; + + private final int x; + private final int y; + + private final int endX; + private final int endY; + + private final int colorLeft; + private final int colorRight; + + private HorizontalGradientGuiRenderState( + RenderPipeline pipeline, + TextureSetup textureSetup, + Matrix3x2f pose, + ScreenRect scissorArea, + int x, + int y, + int endX, + int endY, int colorLeft, int colorRight + ) { + this.pipeline = pipeline; + this.textureSetup = textureSetup; + this.pose = pose; + this.scissorArea = scissorArea; + this.x = x; + this.y = y; + this.endX = endX; + this.endY = endY; + this.colorLeft = colorLeft; + this.colorRight = colorRight; + this.bounds = createBounds(x, y, endX, endY, pose, scissorArea); + } + + @Override + public void setupVertices(VertexConsumer vertices, float depth) { + vertices.vertex(pose, x, y, depth).color(colorLeft); + vertices.vertex(pose, x, endY, depth).color(colorLeft); + vertices.vertex(pose, endX, endY, depth).color(colorRight); + vertices.vertex(pose, endX, y, depth).color(colorRight); + } + + @Override + public RenderPipeline pipeline() { + return pipeline; + } + + @Override + public TextureSetup textureSetup() { + return textureSetup; + } + + @Override + public @Nullable ScreenRect scissorArea() { + return scissorArea; + } + + @Nullable + private static ScreenRect createBounds(int x0, int y0, int x1, int y1, Matrix3x2f pose, @Nullable ScreenRect scissorArea) { + ScreenRect screenRect = (new ScreenRect(x0, y0, x1 - x0 + 1, y1 - y0)).transformEachVertex(pose); + return scissorArea != null ? scissorArea.intersection(screenRect) : screenRect; + } + + @Override + public @Nullable ScreenRect bounds() { + return bounds; + } + + public static void draw(DrawContext context, int x, int y, int endX, int endY, int colorLeft, int colorRight) { + context.state.addSimpleElement( + new HorizontalGradientGuiRenderState( + RenderPipelines.GUI, + TextureSetup.empty(), + new Matrix3x2f(context.getMatrices()), + context.scissorStack.peekLast(), + x, y, endX, endY, + colorLeft, colorRight + ) + ); + } +} diff --git a/src/main/java/de/shiewk/widgets/utils/WidgetUtils.java b/src/main/java/de/shiewk/widgets/utils/WidgetUtils.java index 5129f14..8cb7236 100644 --- a/src/main/java/de/shiewk/widgets/utils/WidgetUtils.java +++ b/src/main/java/de/shiewk/widgets/utils/WidgetUtils.java @@ -3,6 +3,7 @@ package de.shiewk.widgets.utils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.sound.PositionedSoundInstance; import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.tick.TickManager; import java.util.function.BooleanSupplier; @@ -35,4 +36,25 @@ public class WidgetUtils { MinecraftClient.getInstance().getSoundManager().play(PositionedSoundInstance.master(ev, 1f, 1f)); } + public static int fadeColor(int color1, int color2, double delta) { + int alpha = (int) MathHelper.lerp(delta, (color1 >> 24) & 0xff, (color2 >> 24) & 0xff); + int red = (int) MathHelper.lerp(delta, (color1 >> 16) & 0xff, (color2 >> 16) & 0xff); + int green = (int) MathHelper.lerp(delta, (color1 >> 8) & 0xff, (color2 >> 8) & 0xff); + int blue = (int) MathHelper.lerp(delta, color1 & 0xff, color2 & 0xff); + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + + public static String colorARGBToHexRGBA(int color) { + int a = color >> 24 & 0xff; + int r = color >> 16 & 0xff; + int g = color >> 8 & 0xff; + int b = color & 0xff; + return toHexSingle(r) + toHexSingle(g) + toHexSingle(b) + toHexSingle(a); + } + + private static String toHexSingle(int comp){ + String s = Integer.toHexString(comp); + return "0".repeat(2 - s.length()) + s; + } + } diff --git a/src/main/java/de/shiewk/widgets/widgets/ArmorHudWidget.java b/src/main/java/de/shiewk/widgets/widgets/ArmorHudWidget.java index a87cccb..374df5b 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ArmorHudWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ArmorHudWidget.java @@ -1,10 +1,8 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; -import de.shiewk.widgets.widgets.settings.EnumWidgetSetting; -import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; -import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting; -import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; @@ -28,17 +26,13 @@ public class ArmorHudWidget extends ResizableWidget { new ToggleWidgetSetting("show_durability", translatable("widgets.widgets.armorHud.showDurability"), true), new IntSliderWidgetSetting("width", translatable("widgets.widgets.basictext.width"), 16, 42, 128), new EnumWidgetSetting<>("alignment", translatable("widgets.widgets.basictext.alignment"), BasicTextWidget.TextAlignment.class, BasicTextWidget.TextAlignment.CENTER, BasicTextWidget.TextAlignment::displayText), - new RGBAColorWidgetSetting("backgroundcolor", translatable("widgets.widgets.basictext.background"), 0, 0, 0, 80), + new GradientWidgetSetting("backgroundcolor", translatable("widgets.widgets.basictext.background"), 0x50_00_00_00), new EnumWidgetSetting<>("durability_style", translatable("widgets.widgets.armorHud.durabilityStyle"), DurabilityStyle.class, DurabilityStyle.NUMBER, DurabilityStyle::getDisplayName), - new ToggleWidgetSetting("rainbow", translatable("widgets.widgets.common.rainbow"), false), - new IntSliderWidgetSetting("rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10), - new RGBAColorWidgetSetting("textcolor", translatable("widgets.widgets.basictext.textcolor"), 255, 255, 255, 255) + new GradientWidgetSetting("textcolor", translatable("widgets.widgets.basictext.textcolor"), 0xff_ff_ff_ff) )); getSettings().optionById("width").setShowCondition(() -> this.showDurability); getSettings().optionById("alignment").setShowCondition(() -> this.showDurability); getSettings().optionById("durability_style").setShowCondition(() -> this.showDurability); - getSettings().optionById("rainbow_speed").setShowCondition(() -> this.rainbow); - getSettings().optionById("textcolor").setShowCondition(() -> !this.rainbow); } public enum DurabilityStyle { @@ -50,22 +44,25 @@ public class ArmorHudWidget extends ResizableWidget { } } - private int padding = 1; - private boolean showDurability = true; - private DurabilityStyle durabilityStyle; + protected int padding = 1; + protected boolean showDurability = true; + protected DurabilityStyle durabilityStyle; protected ItemStack helmet; protected ItemStack chestplate; protected ItemStack leggings; protected ItemStack boots; - protected boolean rainbow = false; - protected int rainbowSpeed = 3; protected int preferredWidth = 42; protected BasicTextWidget.TextAlignment textAlignment = BasicTextWidget.TextAlignment.CENTER; - protected int backgroundColor = 0x50_00_00_00, textColor = 0xff_ff_ff_ff; + protected GradientOptions backgroundColor, textColor; @Override public void renderScaled(DrawContext context, long measuringTimeNano, TextRenderer textRenderer, int posX, int posY) { - context.fill(posX, posY, posX+width(), posY+height(), backgroundColor); + backgroundColor.fillHorizontal( + context, + measuringTimeNano, + posX, posY, + posX+width(), posY+height() + ); if (helmet != null){ renderItem(context, measuringTimeNano, textRenderer, helmet, posX + padding, posY + padding); } @@ -99,14 +96,14 @@ public class ArmorHudWidget extends ResizableWidget { switch (textAlignment){ case RIGHT -> { int width = textRenderer.getWidth(text); - context.drawText(textRenderer, text, posX + width() - width - padding * 2, posY + 5, rainbow ? BasicTextWidget.rainbowColor(mt, rainbowSpeed) : textColor, true); + textColor.drawText(context, textRenderer, mt, text, posX + width() - width - padding * 2, posY + 5, true); } case CENTER -> { int width = textRenderer.getWidth(text); - context.drawText(textRenderer, text, posX + ((preferredWidth + padding*2) - width) / 2 + 8, posY + 5, rainbow ? BasicTextWidget.rainbowColor(mt, rainbowSpeed) : textColor, true); + textColor.drawText(context, textRenderer, mt, text, posX + ((preferredWidth + padding*2) - width) / 2 + 8, posY + 5, true); } case LEFT -> { - context.drawText(textRenderer, text, posX + 16 + padding, posY + 5, rainbow ? BasicTextWidget.rainbowColor(mt, rainbowSpeed) : textColor, true); + textColor.drawText(context, textRenderer, mt, text, posX + 16 + padding, posY + 5, true); } } } @@ -153,14 +150,12 @@ public class ArmorHudWidget extends ResizableWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.padding = ((IntSliderWidgetSetting) settings.optionById("padding")).getValue(); - this.showDurability = ((ToggleWidgetSetting) settings.optionById("show_durability")).getValue(); - this.durabilityStyle = (DurabilityStyle) ((EnumWidgetSetting) settings.optionById("durability_style")).getValue(); - this.rainbow = ((ToggleWidgetSetting) settings.optionById("rainbow")).getValue(); - this.rainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("rainbow_speed")).getValue(); - this.textColor = ((RGBAColorWidgetSetting) settings.optionById("textcolor")).getColor(); - this.backgroundColor = ((RGBAColorWidgetSetting) settings.optionById("backgroundcolor")).getColor(); - this.preferredWidth = ((IntSliderWidgetSetting) settings.optionById("width")).getValue(); - this.textAlignment = (BasicTextWidget.TextAlignment) ((EnumWidgetSetting) settings.optionById("alignment")).getValue(); + this.padding = (int) settings.optionById("padding").getValue(); + this.showDurability = (boolean) settings.optionById("show_durability").getValue(); + this.durabilityStyle = (DurabilityStyle) settings.optionById("durability_style").getValue(); + this.textColor = (GradientOptions) settings.optionById("textcolor").getValue(); + this.backgroundColor = (GradientOptions) settings.optionById("backgroundcolor").getValue(); + this.preferredWidth = (int) settings.optionById("width").getValue(); + this.textAlignment = (BasicTextWidget.TextAlignment) settings.optionById("alignment").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java b/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java index 697c380..50f712e 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BandwidthWidget.java @@ -1,6 +1,7 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; +import de.shiewk.widgets.color.GradientOptions; import de.shiewk.widgets.utils.WidgetUtils; import de.shiewk.widgets.widgets.settings.EnumWidgetSetting; import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; @@ -52,9 +53,7 @@ public class BandwidthWidget extends BasicTextWidget { new EnumWidgetSetting<>("unit", Text.translatable("widgets.widgets.bandwidth.unit"), Unit.class, Unit.KB, unit -> literal(unit.name)), new ToggleWidgetSetting("fastupdate", translatable("widgets.widgets.bandwidth.fastupdate"), false) )); - getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor && !this.rainbow); - getSettings().optionById("rainbow").setShowCondition(() -> !this.dynamicColor); - getSettings().optionById("rainbow_speed").setShowCondition(() -> !this.dynamicColor && this.rainbow); + getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor); } private int t = 0; @@ -75,11 +74,11 @@ public class BandwidthWidget extends BasicTextWidget { formatAndSetRenderText(literal(unit.sizeFormatter.apply(avgBytesPerSecond))); if (this.dynamicColor){ if (avgBytesPerSecond < 100000){ - this.textColor = 0xff00ff00; + this.textColor = GradientOptions.solidColor(0xff00ff00); } else if (avgBytesPerSecond < 750000) { - this.textColor = 0xffffff00; + this.textColor = GradientOptions.solidColor(0xffffff00); } else { - this.textColor = 0xffff3030; + this.textColor = GradientOptions.solidColor(0xffff3030); } } } @@ -100,10 +99,10 @@ public class BandwidthWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.dynamicColor = ((ToggleWidgetSetting) settings.optionById("dynamic_color")).getValue(); - this.hideInSingleplayer = ((ToggleWidgetSetting) settings.optionById("hide_in_singleplayer")).getValue(); - this.unit = (Unit) ((EnumWidgetSetting) settings.optionById("unit")).getValue(); - this.fastUpdate = ((ToggleWidgetSetting) settings.optionById("fastupdate")).getValue(); + this.dynamicColor = (boolean) settings.optionById("dynamic_color").getValue(); + this.hideInSingleplayer = (boolean) settings.optionById("hide_in_singleplayer").getValue(); + this.unit = (Unit) settings.optionById("unit").getValue(); + this.fastUpdate = (boolean) settings.optionById("fastupdate").getValue(); } @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java b/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java index 6e43f85..778c708 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BasicTextWidget.java @@ -1,12 +1,9 @@ package de.shiewk.widgets.widgets; -import de.shiewk.widgets.WidgetSettingOption; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.*; import de.shiewk.widgets.WidgetSettings; import de.shiewk.widgets.client.WidgetRenderer; -import de.shiewk.widgets.widgets.settings.EnumWidgetSetting; -import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; -import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting; -import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; @@ -67,15 +64,11 @@ public abstract class BasicTextWidget extends ResizableWidget { private int padding = 0; private TextRenderer renderer = null; private boolean textShadow = true; - protected boolean rainbow = false; - private int rainbowSpeed = 3; - private static ObjectArrayList getCustomSettings(List otherCustomOptions) { - final ObjectArrayList list = new ObjectArrayList<>(otherCustomOptions); - list.add(new RGBAColorWidgetSetting("backgroundcolor", translatable("widgets.widgets.basictext.background"), 0, 0, 0, 80)); - list.add(new ToggleWidgetSetting("rainbow", translatable("widgets.widgets.common.rainbow"), false)); - list.add(new RGBAColorWidgetSetting("textcolor", translatable("widgets.widgets.basictext.textcolor"), 255, 255, 255, 255)); - list.add(new IntSliderWidgetSetting("rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10)); + private static ObjectArrayList> getCustomSettings(List> otherCustomOptions) { + final ObjectArrayList> list = new ObjectArrayList<>(otherCustomOptions); + list.add(new GradientWidgetSetting("backgroundcolor", translatable("widgets.widgets.basictext.background"), 0x50_00_00_00)); + list.add(new GradientWidgetSetting("textcolor", translatable("widgets.widgets.basictext.textcolor"), 0xff_ff_ff_ff)); list.add(new IntSliderWidgetSetting("width", translatable("widgets.widgets.basictext.width"), 10, DEFAULT_WIDTH, 80*3)); list.add(new IntSliderWidgetSetting("height", translatable("widgets.widgets.basictext.height"), 9, DEFAULT_HEIGHT, 80)); list.add(new ToggleWidgetSetting("shadow", translatable("widgets.widgets.basictext.textshadow"), true)); @@ -84,20 +77,17 @@ public abstract class BasicTextWidget extends ResizableWidget { list.add(new EnumWidgetSetting<>("text_style", translatable("widgets.widgets.basictext.textstyle"), TextStyle.class, TextStyle.PLAIN, TextStyle::displayText)); return list; } - protected BasicTextWidget(Identifier id, List otherCustomOptions) { + protected BasicTextWidget(Identifier id, List> otherCustomOptions) { super(id, getCustomSettings(otherCustomOptions)); getSettings().optionById("padding").setShowCondition(() -> this.textAlignment != TextAlignment.CENTER); - getSettings().optionById("textcolor").setShowCondition(() -> !this.rainbow); - getSettings().optionById("rainbow_speed").setShowCondition(() -> this.rainbow); } protected static final int DEFAULT_WIDTH = 80, - DEFAULT_HEIGHT = 9 + 12, - DEFAULT_BACKGROUND_COLOR = new Color(0, 0, 0, 80).getRGB(), - DEFAULT_TEXT_COLOR = new Color(255, 255 ,255, 255).getRGB(); + DEFAULT_HEIGHT = 9 + 12; - protected int backgroundColor = DEFAULT_BACKGROUND_COLOR, textColor = DEFAULT_TEXT_COLOR, width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT; + protected int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT; + protected GradientOptions backgroundColor, textColor; protected TextAlignment textAlignment = TextAlignment.CENTER; protected TextStyle textStyle = TextStyle.PLAIN; @@ -115,18 +105,14 @@ public abstract class BasicTextWidget extends ResizableWidget { public void renderScaled(DrawContext context, long n, TextRenderer textRenderer, int posX, int posY) { if (!shouldRender) return; renderer = textRenderer; - context.fill(posX, posY, posX + width(), posY + height(), this.backgroundColor); + this.backgroundColor.fillHorizontal(context, n, posX, posY, posX + width(), posY + height()); Matrix3x2fStack matrices = context.getMatrices() .pushMatrix(); matrices.translate(posX + textX, posY + textY, matrices); - context.drawText(textRenderer, renderText, 0, 0, rainbow ? rainbowColor(n, rainbowSpeed) : this.textColor, textShadow); + this.textColor.drawText(context, textRenderer, n, renderText, 0, 0, textShadow); matrices.popMatrix(); } - public static int rainbowColor(long n, float speed) { - return Color.HSBtoRGB(n / 10_000_000_000f * speed, 1, 1); - } - @Override public final void tick() { tickWidget(); @@ -165,15 +151,13 @@ public abstract class BasicTextWidget extends ResizableWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.backgroundColor = ((RGBAColorWidgetSetting) settings.optionById("backgroundcolor")).getColor(); - this.textColor = ((RGBAColorWidgetSetting) settings.optionById("textcolor")).getColor(); - this.width = ((IntSliderWidgetSetting) settings.optionById("width")).getValue(); - this.height = ((IntSliderWidgetSetting) settings.optionById("height")).getValue(); - this.textAlignment = (TextAlignment) ((EnumWidgetSetting) settings.optionById("alignment")).getValue(); - this.padding = ((IntSliderWidgetSetting) settings.optionById("padding")).getValue(); - this.textShadow = ((ToggleWidgetSetting) settings.optionById("shadow")).getValue(); - this.textStyle = (TextStyle) ((EnumWidgetSetting) settings.optionById("text_style")).getValue(); - this.rainbow = ((ToggleWidgetSetting) settings.optionById("rainbow")).getValue(); - this.rainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("rainbow_speed")).getValue(); + this.backgroundColor = (GradientOptions) settings.optionById("backgroundcolor").getValue(); + this.textColor = (GradientOptions) settings.optionById("textcolor").getValue(); + this.width = (int) settings.optionById("width").getValue(); + this.height = (int) settings.optionById("height").getValue(); + this.textAlignment = (TextAlignment) settings.optionById("alignment").getValue(); + this.padding = (int) settings.optionById("padding").getValue(); + this.textShadow = (boolean) settings.optionById("shadow").getValue(); + this.textStyle = (TextStyle) settings.optionById("text_style").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java b/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java index 8007531..70d0f2c 100644 --- a/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/BiomeWidget.java @@ -68,6 +68,6 @@ public class BiomeWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.showLabel = ((ToggleWidgetSetting) settings.optionById("show_label")).getValue(); + this.showLabel = (boolean) settings.optionById("show_label").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/CPSWidget.java b/src/main/java/de/shiewk/widgets/widgets/CPSWidget.java index 935ec88..c6f10b8 100644 --- a/src/main/java/de/shiewk/widgets/widgets/CPSWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/CPSWidget.java @@ -141,11 +141,11 @@ public class CPSWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - countLeftClicks = ((ToggleWidgetSetting) settings.optionById("left")).getValue(); - countMiddleClicks = ((ToggleWidgetSetting) settings.optionById("middle")).getValue(); - countRightClicks = ((ToggleWidgetSetting) settings.optionById("right")).getValue(); - appearance = (Appearance) ((EnumWidgetSetting) settings.optionById("appearance")).getValue(); - showLabel = ((ToggleWidgetSetting) settings.optionById("show_label")).getValue(); + countLeftClicks = (boolean) settings.optionById("left").getValue(); + countMiddleClicks = (boolean) settings.optionById("middle").getValue(); + countRightClicks = (boolean) settings.optionById("right").getValue(); + appearance = (Appearance) settings.optionById("appearance").getValue(); + showLabel = (boolean) settings.optionById("show_label").getValue(); } @Override @@ -157,4 +157,4 @@ public class CPSWidget extends BasicTextWidget { public Text getDescription() { return translatable("widgets.widgets.cps.description"); } -} \ No newline at end of file +} diff --git a/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java b/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java index bec496e..11c3595 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ClockWidget.java @@ -104,10 +104,10 @@ public class ClockWidget extends BasicTextWidget { public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); String datePattern = "HH:mm:ss"; - TimeOption timeOption = (TimeOption) ((EnumWidgetSetting) settings.optionById("hour_format")).getValue(); - DateOption dateOption = (DateOption) ((EnumWidgetSetting) settings.optionById("date_format")).getValue(); - WeekOption weekOption = (WeekOption) ((EnumWidgetSetting) settings.optionById("week_format")).getValue(); - boolean showSeconds = ((ToggleWidgetSetting) settings.optionById("show_seconds")).getValue(); + TimeOption timeOption = (TimeOption) settings.optionById("hour_format").getValue(); + DateOption dateOption = (DateOption) settings.optionById("date_format").getValue(); + WeekOption weekOption = (WeekOption) settings.optionById("week_format").getValue(); + boolean showSeconds = (boolean) settings.optionById("show_seconds").getValue(); if (timeOption == TimeOption.HOUR_24){ datePattern = showSeconds ? "HH:mm:ss" : "HH:mm"; } else if (timeOption == TimeOption.AM_PM){ diff --git a/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java b/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java index e071417..3eea3a8 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ComboWidget.java @@ -106,8 +106,8 @@ public class ComboWidget extends BasicTextWidget implements AttackEntityCallback @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.displayThreshold = ((IntSliderWidgetSetting) settings.optionById("display_threshold")).getValue(); - this.showLabel = ((ToggleWidgetSetting) settings.optionById("show_label")).getValue(); + this.displayThreshold = (int) settings.optionById("display_threshold").getValue(); + this.showLabel = (boolean) settings.optionById("show_label").getValue(); updateComboText(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/CoordinatesWidget.java b/src/main/java/de/shiewk/widgets/widgets/CoordinatesWidget.java index b99ba3b..ea6addc 100644 --- a/src/main/java/de/shiewk/widgets/widgets/CoordinatesWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/CoordinatesWidget.java @@ -1,8 +1,9 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.GradientWidgetSetting; import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; -import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting; import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; @@ -14,58 +15,48 @@ import net.minecraft.util.Identifier; import java.awt.*; import java.util.List; -import static net.minecraft.text.Text.translatable; - public class CoordinatesWidget extends ResizableWidget { public CoordinatesWidget(Identifier id) { super(id, List.of( new ToggleWidgetSetting("x", Text.translatable("widgets.widgets.coordinates.showX"), true), new ToggleWidgetSetting("y", Text.translatable("widgets.widgets.coordinates.showY"), true), new ToggleWidgetSetting("z", Text.translatable("widgets.widgets.coordinates.showZ"), true), - new RGBAColorWidgetSetting("backgroundcolor", Text.translatable("widgets.widgets.basictext.background"), 0, 0, 0, 80), - new ToggleWidgetSetting("rainbow", translatable("widgets.widgets.common.rainbow"), false), - new RGBAColorWidgetSetting("textcolor", Text.translatable("widgets.widgets.basictext.textcolor"), 255, 255, 255, 255), - new IntSliderWidgetSetting("rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10), + new GradientWidgetSetting("backgroundcolor", Text.translatable("widgets.widgets.basictext.background"), 0x50_00_00_00), + new GradientWidgetSetting("textcolor", Text.translatable("widgets.widgets.basictext.textcolor"), 0xffffffff), new IntSliderWidgetSetting("width", Text.translatable("widgets.widgets.basictext.width"), 10, WIDTH, 80*3), new IntSliderWidgetSetting("paddingX", Text.translatable("widgets.widgets.basictext.paddingX"), 0, 5, 20), new IntSliderWidgetSetting("paddingY", Text.translatable("widgets.widgets.basictext.paddingY"), 0, 5, 20), new ToggleWidgetSetting("shadow", Text.translatable("widgets.widgets.basictext.textshadow"), true) )); - getSettings().optionById("textcolor").setShowCondition(() -> !this.rainbow); - getSettings().optionById("rainbow_speed").setShowCondition(() -> this.rainbow); } private String textX = "X", textY = "Y", textZ = "Z"; - private int txc = 0, tyc = 0, tzc = 0, rainbowSpeed = 3; - private boolean shadow = true, rainbow = false; + private int txc = 0, tyc = 0, tzc = 0; + private boolean shadow = true; @Override public void renderScaled(DrawContext context, long mt, TextRenderer textRenderer, int posX, int posY) { - context.fill(posX, posY, posX + width(), posY + height(), this.backgroundColor); + this.backgroundColor.fillHorizontal(context, mt, posX, posY, posX + width(), posY + height()); int y = this.paddingY; if (showX){ y++; - context.drawText(textRenderer, "X: ", posX + paddingX, posY + y, textColor(mt), shadow); - context.drawText(textRenderer, textX, posX + txc, posY + y, textColor(mt), shadow); + this.textColor.drawText(context, textRenderer, mt, "X: ", posX + paddingX, posY + y, shadow); + this.textColor.drawText(context, textRenderer, mt, textX, posX + txc, posY + y, shadow); y += textRenderer.fontHeight + 1; } if (showY){ y++; - context.drawText(textRenderer, "Y: ", posX + paddingX, posY + y, textColor(mt), shadow); - context.drawText(textRenderer, textY, posX + tyc, posY + y, textColor(mt), shadow); + this.textColor.drawText(context, textRenderer, mt, "Y: ", posX + paddingX, posY + y, shadow); + this.textColor.drawText(context, textRenderer, mt, textY, posX + tyc, posY + y, shadow); y += textRenderer.fontHeight + 1; } if (showZ){ y++; - context.drawText(textRenderer, "Z: ", posX + paddingX, posY + y, textColor(mt), shadow); - context.drawText(textRenderer, textZ, posX + tzc, posY + y, textColor(mt), shadow); + this.textColor.drawText(context, textRenderer, mt, "Z: ", posX + paddingX, posY + y, shadow); + this.textColor.drawText(context, textRenderer, mt, textZ, posX + tzc, posY + y, shadow); } } - private int textColor(long n) { - return rainbow ? BasicTextWidget.rainbowColor(n, rainbowSpeed) : textColor; - } - @Override public void tick() { final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; @@ -95,29 +86,24 @@ public class CoordinatesWidget extends ResizableWidget { return Text.translatable("widgets.widgets.coordinates.description"); } - protected static final int - WIDTH = 80, - PADDING = 6, - DEFAULT_BACKGROUND_COLOR = new Color(0, 0, 0, 80).getRGB(), - DEFAULT_TEXT_COLOR = new Color(255, 255 ,255, 255).getRGB(); + protected static final int WIDTH = 80, PADDING = 6; - protected int backgroundColor = DEFAULT_BACKGROUND_COLOR, textColor = DEFAULT_TEXT_COLOR, paddingX = PADDING, paddingY = PADDING, width = WIDTH; + protected GradientOptions backgroundColor, textColor; + protected int paddingX = PADDING, paddingY = PADDING, width = WIDTH; protected boolean showX = true, showY = true, showZ = true; @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.backgroundColor = ((RGBAColorWidgetSetting) settings.optionById("backgroundcolor")).getColor(); - this.textColor = ((RGBAColorWidgetSetting) settings.optionById("textcolor")).getColor(); - this.showX = ((ToggleWidgetSetting) settings.optionById("x")).getValue(); - this.showY = ((ToggleWidgetSetting) settings.optionById("y")).getValue(); - this.showZ = ((ToggleWidgetSetting) settings.optionById("z")).getValue(); - this.paddingX = ((IntSliderWidgetSetting) settings.optionById("paddingX")).getValue(); - this.paddingY = ((IntSliderWidgetSetting) settings.optionById("paddingY")).getValue(); - this.width = ((IntSliderWidgetSetting) settings.optionById("width")).getValue(); - this.shadow = ((ToggleWidgetSetting) settings.optionById("shadow")).getValue(); - this.rainbow = ((ToggleWidgetSetting) settings.optionById("rainbow")).getValue(); - this.rainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("rainbow_speed")).getValue(); + this.backgroundColor = (GradientOptions) settings.optionById("backgroundcolor").getValue(); + this.textColor = (GradientOptions) settings.optionById("textcolor").getValue(); + this.showX = (boolean) settings.optionById("x").getValue(); + this.showY = (boolean) settings.optionById("y").getValue(); + this.showZ = (boolean) settings.optionById("z").getValue(); + this.paddingX = (int) settings.optionById("paddingX").getValue(); + this.paddingY = (int) settings.optionById("paddingY").getValue(); + this.width = (int) settings.optionById("width").getValue(); + this.shadow = (boolean) settings.optionById("shadow").getValue(); } @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java b/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java index 000b794..c0af842 100644 --- a/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/FPSWidget.java @@ -57,7 +57,7 @@ public class FPSWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.realtime = ((ToggleWidgetSetting) settings.optionById("realtime")).getValue(); + this.realtime = (boolean) settings.optionById("realtime").getValue(); timedFrames = this.realtime ? new LinkedList<>() : null; } diff --git a/src/main/java/de/shiewk/widgets/widgets/InventoryWidget.java b/src/main/java/de/shiewk/widgets/widgets/InventoryWidget.java index 7a3568f..d729877 100644 --- a/src/main/java/de/shiewk/widgets/widgets/InventoryWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/InventoryWidget.java @@ -1,10 +1,8 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; -import de.shiewk.widgets.widgets.settings.EnumWidgetSetting; -import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; -import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting; -import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gl.RenderPipelines; @@ -51,34 +49,18 @@ public class InventoryWidget extends ResizableWidget { super(id, List.of( new EnumWidgetSetting<>("mode", translatable("widgets.widgets.inventory.mode"), InventoryMode.class, InventoryMode.TEXTURE_PACK, InventoryMode::display), new ToggleWidgetSetting("show_hotbar", translatable("widgets.widgets.inventory.showHotbar"), true), - new ToggleWidgetSetting("rainbow_grid", translatable("widgets.widgets.inventory.rainbowGrid"), false), - new IntSliderWidgetSetting("grid_rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10), - new RGBAColorWidgetSetting("grid_color", translatable("widgets.widgets.inventory.gridColor"), 0, 0, 0, 255), - new ToggleWidgetSetting("rainbow_boxes", translatable("widgets.widgets.inventory.rainbowBoxes"), false), - new IntSliderWidgetSetting("box_rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10), - new RGBAColorWidgetSetting("box_color", translatable("widgets.widgets.inventory.boxColor"), 80, 80, 80, 128) + new GradientWidgetSetting("grid_color", translatable("widgets.widgets.inventory.gridColor"), 0xff000000), + new GradientWidgetSetting("box_color", translatable("widgets.widgets.inventory.boxColor"), 0x88505050) )); - getSettings().optionById("rainbow_grid").setShowCondition(() -> this.mode == InventoryMode.GRID); - getSettings().optionById("grid_rainbow_speed").setShowCondition(() -> this.mode == InventoryMode.GRID && this.rainbowGrid); - getSettings().optionById("grid_color").setShowCondition(() -> this.mode == InventoryMode.GRID && !this.rainbowGrid); - - getSettings().optionById("rainbow_boxes").setShowCondition(() -> this.mode == InventoryMode.BOXES); - getSettings().optionById("box_rainbow_speed").setShowCondition(() -> this.mode == InventoryMode.BOXES && this.rainbowBoxes); - getSettings().optionById("box_color").setShowCondition(() -> this.mode == InventoryMode.BOXES && !this.rainbowBoxes); - + getSettings().optionById("grid_color").setShowCondition(() -> this.mode == InventoryMode.GRID); + getSettings().optionById("box_color").setShowCondition(() -> this.mode == InventoryMode.BOXES); getSettings().optionById("show_hotbar").setShowCondition(() -> this.mode.canDisableHotbar); } private InventoryMode mode = InventoryMode.TEXTURE_PACK; private PlayerInventory inventory; - private boolean rainbowGrid = false; - private int gridColor = 0xff000000; - private int gridRainbowSpeed = 3; - - private boolean rainbowBoxes = false; - private int boxColor = 0xff000000; - private int boxRainbowSpeed = 3; + private GradientOptions gridColor, boxColor; private boolean showHotbar = false; @Override @@ -109,30 +91,28 @@ public class InventoryWidget extends ResizableWidget { context.disableScissor(); } case GRID -> { - int gridColor = rainbowGrid ? BasicTextWidget.rainbowColor(mt, gridRainbowSpeed) : this.gridColor; - context.drawHorizontalLine(posX, posX+width(), posY, gridColor); - context.drawHorizontalLine(posX, posX+width(), posY + 18, gridColor); - context.drawHorizontalLine(posX, posX+width(), posY + 36, gridColor); - context.drawHorizontalLine(posX, posX+width(), posY + 54, gridColor); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY + 18); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY + 36); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY + 54); if (showHotbar){ - context.drawHorizontalLine(posX, posX+width(), posY + 58, gridColor); - context.drawHorizontalLine(posX, posX+width(), posY + 76, gridColor); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY + 58); + gridColor.drawHorizontalLine(context, mt, posX, posX+width(), posY + 76); } - context.drawVerticalLine(posX, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*2, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*3, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*4, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*5, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*6, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*7, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*8, posY, posY+height(), gridColor); - context.drawVerticalLine(posX+18*9, posY, posY+height(), gridColor); + gridColor.drawVerticalLine(context, mt, posX, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*2, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*3, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*4, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*5, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*6, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*7, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*8, posY, posY+height()); + gridColor.drawVerticalLine(context, mt, posX+18*9, posY, posY+height()); } case BOXES -> { - int boxColor = rainbowBoxes ? ((BasicTextWidget.rainbowColor(mt, boxRainbowSpeed) & 0xffffff) | (this.boxColor & 0xff000000)) : this.boxColor; for (int ry = 0; ry < 4; ry++) { if (ry == 0 && !showHotbar) continue; for (int rx = 0; rx < 9; rx++) { @@ -140,7 +120,7 @@ public class InventoryWidget extends ResizableWidget { int itemY = ry == 0 ? posY + 58 : posY + (ry-1) * 18; int itemX = posX + rx * 18; - context.fill(itemX, itemY, itemX + 16, itemY + 16, boxColor); + boxColor.fillHorizontal(context, mt, itemX, itemY, itemX + 16, itemY + 16); } } } @@ -205,15 +185,11 @@ public class InventoryWidget extends ResizableWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.mode = ((InventoryMode) ((EnumWidgetSetting) settings.optionById("mode")).getValue()); - this.rainbowGrid = ((ToggleWidgetSetting) settings.optionById("rainbow_grid")).getValue(); - this.gridRainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("grid_rainbow_speed")).getValue(); - this.gridColor = ((RGBAColorWidgetSetting) settings.optionById("grid_color")).getColor(); + this.mode = (InventoryMode) settings.optionById("mode").getValue(); - this.rainbowBoxes = ((ToggleWidgetSetting) settings.optionById("rainbow_boxes")).getValue(); - this.boxRainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("box_rainbow_speed")).getValue(); - this.boxColor = ((RGBAColorWidgetSetting) settings.optionById("box_color")).getColor(); + this.gridColor = (GradientOptions) settings.optionById("grid_color").getValue(); + this.boxColor = (GradientOptions) settings.optionById("box_color").getValue(); - this.showHotbar = ((ToggleWidgetSetting) settings.optionById("show_hotbar")).getValue() || !mode.canDisableHotbar; + this.showHotbar = (boolean) settings.optionById("show_hotbar").getValue() || !mode.canDisableHotbar; } } diff --git a/src/main/java/de/shiewk/widgets/widgets/KeyStrokesWidget.java b/src/main/java/de/shiewk/widgets/widgets/KeyStrokesWidget.java index dd46f11..411feb5 100644 --- a/src/main/java/de/shiewk/widgets/widgets/KeyStrokesWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/KeyStrokesWidget.java @@ -1,8 +1,8 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; -import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; -import de.shiewk.widgets.widgets.settings.RGBAColorWidgetSetting; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.widgets.settings.GradientWidgetSetting; import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; @@ -11,52 +11,24 @@ import net.minecraft.client.option.KeyBinding; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; -import net.minecraft.util.math.MathHelper; -import java.awt.*; import java.util.List; import java.util.Objects; -import static net.minecraft.text.Text.translatable; - public class KeyStrokesWidget extends ResizableWidget { public KeyStrokesWidget(Identifier id) { super(id, List.of( new ToggleWidgetSetting("showjump", Text.translatable("widgets.widgets.keystrokes.showJumpKey"), true), - new RGBAColorWidgetSetting("bgpressed", Text.translatable("widgets.widgets.keystrokes.colorBackgroundPressed"), 255, 255, 255, 80), - new RGBAColorWidgetSetting("bgunpressed", Text.translatable("widgets.widgets.keystrokes.colorBackgroundUnpressed"), 0, 0, 0, 80), - new ToggleWidgetSetting("rainbow", translatable("widgets.widgets.common.rainbow"), false), - new IntSliderWidgetSetting("rainbow_speed", translatable("widgets.widgets.common.rainbow.speed"), 1, 3, 10), - new RGBAColorWidgetSetting("keypressed", Text.translatable("widgets.widgets.keystrokes.colorKeyPressed"), 255, 255, 255, 255), - new RGBAColorWidgetSetting("keyunpressed", Text.translatable("widgets.widgets.keystrokes.colorKeyUnpressed"), 255, 255, 255, 255) + new GradientWidgetSetting("bgpressed", Text.translatable("widgets.widgets.keystrokes.colorBackgroundPressed"), 0x50ffffff), + new GradientWidgetSetting("bgunpressed", Text.translatable("widgets.widgets.keystrokes.colorBackgroundUnpressed"), 0x50000000), + new GradientWidgetSetting("keypressed", Text.translatable("widgets.widgets.keystrokes.colorKeyPressed"), 0xffffffff), + new GradientWidgetSetting("keyunpressed", Text.translatable("widgets.widgets.keystrokes.colorKeyUnpressed"), 0xffffffff) )); - getSettings().optionById("keypressed").setShowCondition(() -> !this.rainbow); - getSettings().optionById("keyunpressed").setShowCondition(() -> !this.rainbow); - getSettings().optionById("rainbow_speed").setShowCondition(() -> this.rainbow); - } - - @Override - public void onSettingsChanged(WidgetSettings settings) { - super.onSettingsChanged(settings); - this.showJumpKey = ((ToggleWidgetSetting) settings.optionById("showjump")).getValue(); - this.colorBackgroundPressed = ((RGBAColorWidgetSetting) settings.optionById("bgpressed")).getColor(); - this.colorBackgroundUnpressed = ((RGBAColorWidgetSetting) settings.optionById("bgunpressed")).getColor(); - this.colorKeyPressed = ((RGBAColorWidgetSetting) settings.optionById("keypressed")).getColor(); - this.colorKeyUnpressed = ((RGBAColorWidgetSetting) settings.optionById("keyunpressed")).getColor(); - this.rainbow = ((ToggleWidgetSetting) settings.optionById("rainbow")).getValue(); - this.rainbowSpeed = ((IntSliderWidgetSetting) settings.optionById("rainbow_speed")).getValue(); } + private GradientOptions colorBackgroundPressed, colorBackgroundUnpressed, colorKeyUnpressed, colorKeyPressed; private boolean showJumpKey = true; - private int colorBackgroundPressed = new Color(255, 255, 255, 80).getRGB(), - colorBackgroundUnpressed = new Color(0, 0, 0, 80).getRGB(), - colorKeyUnpressed = 0xffffffff, - colorKeyPressed = 0xffffffff; - - protected boolean rainbow = false; - protected int rainbowSpeed = 3; - protected static class Key { protected final KeyBinding binding; protected boolean isPressed; @@ -90,49 +62,28 @@ public class KeyStrokesWidget extends ResizableWidget { if (showJumpKey) renderSpaceBar(context, measuringTimeNano, posX, posY + 44, KEY_JUMP); } - protected void renderSpaceBar(final DrawContext context, - final long measuringTimeNano, - final int posX, - final int posY, - final Key key){ - long l = measuringTimeNano - key.lastChanged; + protected void renderSpaceBar(final DrawContext context, long mt, int posX, int posY, Key key){ + long l = mt - key.lastChanged; if (l < 100000000){ - if (key.isPressed){ - context.fill(posX, posY, posX + 64, posY + 10, fadeColor(colorBackgroundUnpressed, colorBackgroundPressed, 0.00000001d * l)); - } else { - context.fill(posX, posY, posX + 64, posY + 10, fadeColor(colorBackgroundPressed, colorBackgroundUnpressed, 0.00000001d * l)); - } + double alpha = 0.00000001d * l; + colorBackgroundUnpressed.multiplyAlpha(key.isPressed ? 1-alpha : alpha).fillHorizontal(context, mt, posX, posY, posX + 64, posY + 10); + colorBackgroundPressed.multiplyAlpha(key.isPressed ? alpha : 1-alpha).fillHorizontal(context, mt, posX, posY, posX + 64, posY + 10); } else { - context.fill(posX, posY, posX + 64, posY + 10, key.isPressed ? colorBackgroundPressed : colorBackgroundUnpressed); + (key.isPressed ? colorBackgroundPressed : colorBackgroundUnpressed).fillHorizontal(context, mt, posX, posY, posX + 64, posY + 10); } - context.fill(posX + 5, posY + 4, posX + 59, posY + 5, rainbow ? BasicTextWidget.rainbowColor(measuringTimeNano, rainbowSpeed) : (key.isPressed ? colorKeyPressed : colorKeyUnpressed)); + (key.isPressed ? colorKeyPressed : colorKeyUnpressed).fillHorizontal(context, mt, posX + 5, posY + 4, posX + 59, posY + 5); } - protected void renderKeyStroke(final DrawContext context, - final TextRenderer textRenderer, - final long measuringTimeNano, - final int posX, - final int posY, - final KeyLarge key){ - long l = measuringTimeNano - key.lastChanged; + protected void renderKeyStroke(DrawContext context, TextRenderer textRenderer, long mt, int posX, int posY, KeyLarge key){ + long l = mt - key.lastChanged; if (l < 100000000){ - if (key.isPressed){ - context.fill(posX, posY, posX+20, posY+20, fadeColor(colorBackgroundUnpressed, colorBackgroundPressed, 0.00000001d * l)); - } else { - context.fill(posX, posY, posX+20, posY+20, fadeColor(colorBackgroundPressed, colorBackgroundUnpressed, 0.00000001d * l)); - } + double alpha = 0.00000001d * l; + colorBackgroundUnpressed.multiplyAlpha(key.isPressed ? 1-alpha : alpha).fillHorizontal(context, mt, posX, posY, posX + 20, posY + 20); + colorBackgroundPressed.multiplyAlpha(key.isPressed ? alpha : 1-alpha).fillHorizontal(context, mt, posX, posY, posX + 20, posY + 20); } else { - context.fill(posX, posY, posX+20, posY+20, key.isPressed ? colorBackgroundPressed : colorBackgroundUnpressed); + (key.isPressed ? colorBackgroundPressed : colorBackgroundUnpressed).fillHorizontal(context, mt, posX, posY, posX + 20, posY + 20); } - context.drawText(textRenderer, key.boundToKey, posX+10-(key.boundToLength/2), posY + 6, rainbow ? BasicTextWidget.rainbowColor(measuringTimeNano, rainbowSpeed) : (key.isPressed ? colorKeyPressed : colorKeyUnpressed), true); - } - - private int fadeColor(int color1, int color2, double delta) { - int alpha = (int) MathHelper.lerp(delta, (color1 >> 24) & 0xff, (color2 >> 24) & 0xff); - int red = (int) MathHelper.lerp(delta, (color1 >> 16) & 0xff, (color2 >> 16) & 0xff); - int green = (int) MathHelper.lerp(delta, (color1 >> 8) & 0xff, (color2 >> 8) & 0xff); - int blue = (int) MathHelper.lerp(delta, color1 & 0xff, color2 & 0xff); - return (alpha << 24) | (red << 16) | (green << 8) | blue; + (key.isPressed ? colorKeyPressed : colorKeyUnpressed).drawText(context, textRenderer, mt, key.boundToKey, posX+10-(key.boundToLength/2), posY+6, true); } @Override @@ -175,4 +126,14 @@ public class KeyStrokesWidget extends ResizableWidget { public int height() { return showJumpKey ? 56 : 44; } + + @Override + public void onSettingsChanged(WidgetSettings settings) { + super.onSettingsChanged(settings); + this.showJumpKey = (boolean) settings.optionById("showjump").getValue(); + this.colorBackgroundPressed = (GradientOptions) settings.optionById("bgpressed").getValue(); + this.colorBackgroundUnpressed = (GradientOptions) settings.optionById("bgunpressed").getValue(); + this.colorKeyPressed = (GradientOptions) settings.optionById("keypressed").getValue(); + this.colorKeyUnpressed = (GradientOptions) settings.optionById("keyunpressed").getValue(); + } } diff --git a/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java b/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java index 2f5b1c9..f055176 100644 --- a/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/MemoryUsageWidget.java @@ -71,8 +71,8 @@ public class MemoryUsageWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.showPercentage = ((ToggleWidgetSetting) settings.optionById("percentage")).getValue(); - this.showLabel = ((ToggleWidgetSetting) settings.optionById("label")).getValue(); - this.realtime = ((ToggleWidgetSetting) settings.optionById("realtime")).getValue(); + this.showPercentage = (boolean) settings.optionById("percentage").getValue(); + this.showLabel = (boolean) settings.optionById("label").getValue(); + this.realtime = (boolean) settings.optionById("realtime").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/PingWidget.java b/src/main/java/de/shiewk/widgets/widgets/PingWidget.java index 664081d..da2a76f 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PingWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PingWidget.java @@ -1,6 +1,7 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; +import de.shiewk.widgets.color.GradientOptions; import de.shiewk.widgets.utils.WidgetUtils; import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; import net.minecraft.client.MinecraftClient; @@ -21,9 +22,7 @@ public class PingWidget extends BasicTextWidget { new ToggleWidgetSetting("dynamic_color", Text.translatable("widgets.widgets.ping.dynamicColor"), true), new ToggleWidgetSetting("hide_in_singleplayer", Text.translatable("widgets.widgets.common.hideInSingleplayer"), false) )); - getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor && !this.rainbow); - getSettings().optionById("rainbow").setShowCondition(() -> !this.dynamicColor); - getSettings().optionById("rainbow_speed").setShowCondition(() -> !this.dynamicColor && this.rainbow); + getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor); } private boolean dynamicColor = false; @@ -53,18 +52,18 @@ public class PingWidget extends BasicTextWidget { } if (valuesRead == 0){ formatAndSetRenderText(literal("??? ms")); - if (this.dynamicColor) this.textColor = 0xff00ff00; + if (this.dynamicColor) this.textColor = GradientOptions.solidColor(0xff00ff00); return; } long avgPing = ping / valuesRead; formatAndSetRenderText(literal(avgPing + " ms")); if (this.dynamicColor){ if (avgPing < 50){ - this.textColor = 0xff00ff00; + this.textColor = GradientOptions.solidColor(0xff00ff00); } else if (avgPing < 120) { - this.textColor = 0xffffff00; + this.textColor = GradientOptions.solidColor(0xffffff00); } else { - this.textColor = 0xffff3030; + this.textColor = GradientOptions.solidColor(0xffff3030); } } } @@ -73,8 +72,8 @@ public class PingWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.dynamicColor = ((ToggleWidgetSetting) settings.optionById("dynamic_color")).getValue(); - this.hideInSingleplayer = ((ToggleWidgetSetting) settings.optionById("hide_in_singleplayer")).getValue(); + this.dynamicColor = (boolean) settings.optionById("dynamic_color").getValue(); + this.hideInSingleplayer = (boolean) settings.optionById("hide_in_singleplayer").getValue(); } @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java b/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java index 8577132..9a47984 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PlainTextWidget.java @@ -32,6 +32,6 @@ public class PlainTextWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - formatAndSetRenderText(literal(((TextFieldWidgetSettingOption) settings.optionById("text")).getValue())); + formatAndSetRenderText(literal((String) settings.optionById("text").getValue())); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/PlayTimeWidget.java b/src/main/java/de/shiewk/widgets/widgets/PlayTimeWidget.java index 42b4d41..fe74574 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PlayTimeWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PlayTimeWidget.java @@ -73,6 +73,6 @@ public class PlayTimeWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.labelStyle = (LabelStyle) ((EnumWidgetSetting) settings.optionById("labelstyle")).getValue(); + this.labelStyle = (LabelStyle) settings.optionById("labelstyle").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/PlayerCountWidget.java b/src/main/java/de/shiewk/widgets/widgets/PlayerCountWidget.java index 2b9964e..0603ff3 100644 --- a/src/main/java/de/shiewk/widgets/widgets/PlayerCountWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/PlayerCountWidget.java @@ -45,8 +45,8 @@ public class PlayerCountWidget extends BasicTextWidget{ @Override public void onSettingsChanged(WidgetSettings settings) { - showLabel = ((ToggleWidgetSetting) settings.optionById("showlabel")).getValue(); - hideInSingleplayer = ((ToggleWidgetSetting) settings.optionById("hide_in_singleplayer")).getValue(); + showLabel = (boolean) settings.optionById("showlabel").getValue(); + hideInSingleplayer = (boolean) settings.optionById("hide_in_singleplayer").getValue(); super.onSettingsChanged(settings); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/ResizableWidget.java b/src/main/java/de/shiewk/widgets/widgets/ResizableWidget.java index 2eab8e2..3c73216 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ResizableWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ResizableWidget.java @@ -1,7 +1,7 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.ModWidget; -import de.shiewk.widgets.WidgetSettingOption; +import de.shiewk.widgets.widgets.settings.WidgetSettingOption; import de.shiewk.widgets.WidgetSettings; import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; import net.minecraft.client.font.TextRenderer; @@ -15,12 +15,12 @@ import java.util.List; public abstract class ResizableWidget extends ModWidget { - protected ResizableWidget(Identifier id, List customSettings) { + protected ResizableWidget(Identifier id, List> customSettings) { super(id, addScaleSetting(customSettings)); } - private static List addScaleSetting(List target) { - ArrayList settings = new ArrayList<>(target); + private static List> addScaleSetting(List> target) { + ArrayList> settings = new ArrayList<>(target); settings.add(new IntSliderWidgetSetting("size", Text.translatable("widgets.widgets.common.sizePercent"), 25, 100, 400)); return settings; } @@ -43,7 +43,7 @@ public abstract class ResizableWidget extends ModWidget { @Override public void onSettingsChanged(WidgetSettings settings) { - this.size = 0.01f * ((IntSliderWidgetSetting) settings.optionById("size")).getValue(); + this.size = 0.01f * (int) settings.optionById("size").getValue(); } @Override diff --git a/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java b/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java index d4c27f9..1369400 100644 --- a/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/ServerIPWidget.java @@ -63,7 +63,7 @@ public class ServerIPWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.dynamicWidth = ((ToggleWidgetSetting) settings.optionById("dynamicwidth")).getValue(); - this.hideInSingleplayer = ((ToggleWidgetSetting) settings.optionById("hide_in_singleplayer")).getValue(); + this.dynamicWidth = (boolean) settings.optionById("dynamicwidth").getValue(); + this.hideInSingleplayer = (boolean) settings.optionById("hide_in_singleplayer").getValue(); } } diff --git a/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java b/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java index 2d618a0..b5b9d82 100644 --- a/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/SpeedWidget.java @@ -104,12 +104,12 @@ public class SpeedWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.unit = ((Unit) ((EnumWidgetSetting) settings.optionById("unit")).getValue()); - this.withXVelocity = ((ToggleWidgetSetting) settings.optionById("with_x")).getValue(); - this.withYVelocity = ((ToggleWidgetSetting) settings.optionById("with_y")).getValue(); - this.withZVelocity = ((ToggleWidgetSetting) settings.optionById("with_z")).getValue(); - this.digitsAfterComma = ((IntSliderWidgetSetting) settings.optionById("digits")).getValue(); + this.unit = (Unit) settings.optionById("unit").getValue(); + this.withXVelocity = (boolean) settings.optionById("with_x").getValue(); + this.withYVelocity = (boolean) settings.optionById("with_y").getValue(); + this.withZVelocity = (boolean) settings.optionById("with_z").getValue(); + this.digitsAfterComma = (int) settings.optionById("digits").getValue(); this.windowPointer = 0; - this.averagingWindow = new double[((IntSliderWidgetSetting) settings.optionById("window_size")).getValue()]; + this.averagingWindow = new double[(int) settings.optionById("window_size").getValue()]; } } diff --git a/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java b/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java index 21ad950..a477c66 100644 --- a/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java +++ b/src/main/java/de/shiewk/widgets/widgets/TPSWidget.java @@ -2,6 +2,7 @@ package de.shiewk.widgets.widgets; import de.shiewk.widgets.WidgetSettings; import de.shiewk.widgets.WidgetsMod; +import de.shiewk.widgets.color.GradientOptions; import de.shiewk.widgets.widgets.settings.IntSliderWidgetSetting; import de.shiewk.widgets.widgets.settings.ToggleWidgetSetting; import net.minecraft.client.MinecraftClient; @@ -22,9 +23,7 @@ public class TPSWidget extends BasicTextWidget { new ToggleWidgetSetting("dynamic_color", translatable("widgets.widgets.tps.dynamicColor"), true), new IntSliderWidgetSetting("window_size", translatable("widgets.widgets.tps.windowSize"), 2, 5, 20) )); - getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor && !this.rainbow); - getSettings().optionById("rainbow").setShowCondition(() -> !this.dynamicColor); - getSettings().optionById("rainbow_speed").setShowCondition(() -> !this.dynamicColor && this.rainbow); + getSettings().optionById("textcolor").setShowCondition(() -> !this.dynamicColor); } public static final TPSWidget INSTANCE = new TPSWidget(Identifier.of(WidgetsMod.MOD_ID, "tps")); @@ -86,7 +85,7 @@ public class TPSWidget extends BasicTextWidget { } else { formatAndSetRenderText(literal("???")); } - if (dynamicColor) this.textColor = 0xff00ff00; + if (dynamicColor) this.textColor = GradientOptions.solidColor(0xff00ff00); } else { tps = Math.round(tps * 10f) / 10f; if (showLabel){ @@ -96,11 +95,11 @@ public class TPSWidget extends BasicTextWidget { } if (dynamicColor){ if (tps >= targetTickRate * 0.990){ - this.textColor = 0xff00ff00; + this.textColor = GradientOptions.solidColor(0xff00ff00); } else if (tps >= targetTickRate * 0.740){ - this.textColor = 0xffffff00; + this.textColor = GradientOptions.solidColor(0xffffff00); } else { - this.textColor = 0xffff0000; + this.textColor = GradientOptions.solidColor(0xffff0000); } } } @@ -124,10 +123,10 @@ public class TPSWidget extends BasicTextWidget { @Override public void onSettingsChanged(WidgetSettings settings) { super.onSettingsChanged(settings); - this.dynamicColor = ((ToggleWidgetSetting) settings.optionById("dynamic_color")).getValue(); - this.showLabel = ((ToggleWidgetSetting) settings.optionById("show_label")).getValue(); + this.dynamicColor = (boolean) settings.optionById("dynamic_color").getValue(); + this.showLabel = (boolean) settings.optionById("show_label").getValue(); - int windowSize = ((IntSliderWidgetSetting) settings.optionById("window_size")).getValue(); + int windowSize = (int) settings.optionById("window_size").getValue(); updatePointer = 0; updatesSinceWorldChange = 0; lastUpdates = new long[windowSize]; diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/EnumWidgetSetting.java b/src/main/java/de/shiewk/widgets/widgets/settings/EnumWidgetSetting.java index ebffb22..67469cf 100644 --- a/src/main/java/de/shiewk/widgets/widgets/settings/EnumWidgetSetting.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/EnumWidgetSetting.java @@ -2,7 +2,6 @@ package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import de.shiewk.widgets.WidgetSettingOption; import de.shiewk.widgets.utils.WidgetUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; @@ -13,7 +12,7 @@ import net.minecraft.text.Text; import java.awt.*; import java.util.function.Function; -public class EnumWidgetSetting> extends WidgetSettingOption { +public class EnumWidgetSetting> extends WidgetSettingOption { private final Class enumClass; private T value; @@ -29,6 +28,7 @@ public class EnumWidgetSetting> extends WidgetSettingOption { this.enumNameGetter = enumNameGetter; } + @Override public T getValue(){ return value; } diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/GradientWidgetSetting.java b/src/main/java/de/shiewk/widgets/widgets/settings/GradientWidgetSetting.java new file mode 100644 index 0000000..22288bd --- /dev/null +++ b/src/main/java/de/shiewk/widgets/widgets/settings/GradientWidgetSetting.java @@ -0,0 +1,123 @@ +package de.shiewk.widgets.widgets.settings; + +import com.google.gson.JsonElement; +import de.shiewk.widgets.client.screen.WidgetSettingsScreen; +import de.shiewk.widgets.client.screen.gradienteditor.GradientEditorScreen; +import de.shiewk.widgets.color.GradientMode; +import de.shiewk.widgets.color.GradientOptions; +import de.shiewk.widgets.utils.WidgetUtils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.sound.SoundEvents; +import net.minecraft.text.Text; +import net.minecraft.util.Util; + +import static de.shiewk.widgets.client.WidgetManager.gson; +import static de.shiewk.widgets.utils.WidgetUtils.colorARGBToHexRGBA; + +public class GradientWidgetSetting extends WidgetSettingOption { + + public GradientWidgetSetting(String id, Text name, GradientMode defaultMode, int defaultGradientSize, int defaultGradientSpeed, int defaultColor) { + super(id, name); + this.value = new GradientOptions( + defaultMode, + defaultGradientSize, + defaultGradientSpeed, + new int[]{defaultColor} + ); + } + + public GradientWidgetSetting(String id, Text name, int defaultColor) { + this(id, name, GradientMode.SWEEP, 40, 10, defaultColor); + } + + private GradientOptions value; + + @Override + public JsonElement saveState() { + return gson.toJsonTree(getValue()); + } + + @Override + public void loadState(JsonElement state) { + if (state.isJsonPrimitive() && state.getAsJsonPrimitive().isNumber()){ + this.value = new GradientOptions( + this.value.mode(), + this.value.gradientSize(), + this.value.gradientSpeed(), + new int[]{ state.getAsInt() } + ); + } else { + this.value = gson.fromJson(state, GradientOptions.class); + } + } + + @Override + public GradientOptions getValue() { + return this.value; + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) { + final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + final long n = Util.getMeasuringTimeNano(); + GradientOptions gradient = this.getValue(); + gradient.fillHorizontal( + context, + n, + getX(), + getY(), + getX() + getWidth(), + getY() + getHeight() + ); + int outlineColor; + String displayText; + int[] colors = gradient.colors(); + if (colors.length == 1){ + outlineColor = colors[0] | 0xff_00_00_00; + displayText = "#" + colorARGBToHexRGBA(colors[0]); + } else { + outlineColor = 0xff_ff_ff_ff; + displayText = Text.translatable("widgets.ui.widgetSettings.colors", colors.length).getString(); + } + context.drawHorizontalLine(getX(), getX()+getWidth(), getY(), outlineColor); + context.drawHorizontalLine(getX(), getX()+getWidth(), getY()+getHeight(), outlineColor); + context.drawVerticalLine(getX(), getY(), getY() + getHeight(), outlineColor); + context.drawVerticalLine(getX() + getWidth(), getY(), getY() + getHeight(), outlineColor); + + int width = textRenderer.getWidth(displayText); + context.drawText( + textRenderer, + displayText, + getX() + (getWidth() / 2 - (width / 2)), + getY() + (getHeight() / 2 - 4), + 0xff_ff_ff_ff, + true + ); + } + + @Override + public int getWidth() { + return 72; + } + + @Override + public int getHeight() { + return 24; + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + MinecraftClient client = MinecraftClient.getInstance(); + if (client.currentScreen instanceof WidgetSettingsScreen screen) { + WidgetUtils.playSound(SoundEvents.BLOCK_COPPER_BULB_TURN_ON); + client.setScreen(new GradientEditorScreen(client.currentScreen, screen.getWidget(), this, screen.getOnChange())); + } + return true; + } + + public void setValue(GradientOptions value) { + this.value = value; + } +} diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/IntSliderWidgetSetting.java b/src/main/java/de/shiewk/widgets/widgets/settings/IntSliderWidgetSetting.java index 172e535..0f7f104 100644 --- a/src/main/java/de/shiewk/widgets/widgets/settings/IntSliderWidgetSetting.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/IntSliderWidgetSetting.java @@ -2,15 +2,15 @@ package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import de.shiewk.widgets.WidgetSettingOption; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; -public class IntSliderWidgetSetting extends WidgetSettingOption { +public class IntSliderWidgetSetting extends WidgetSettingOption { private int value; private int minValue; @@ -93,7 +93,8 @@ public class IntSliderWidgetSetting extends WidgetSettingOption { return t; } - public int getValue() { + @Override + public @NotNull Integer getValue() { return value; } diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/RGBAColorWidgetSetting.java b/src/main/java/de/shiewk/widgets/widgets/settings/RGBAColorWidgetSetting.java index 4675381..e932e86 100644 --- a/src/main/java/de/shiewk/widgets/widgets/settings/RGBAColorWidgetSetting.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/RGBAColorWidgetSetting.java @@ -2,7 +2,7 @@ package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import de.shiewk.widgets.WidgetSettingOption; +import de.shiewk.widgets.client.screen.WidgetVisibilityToggle; import de.shiewk.widgets.utils.WidgetUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; @@ -13,11 +13,16 @@ import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.NotNull; import org.lwjgl.glfw.GLFW; import java.awt.*; -public class RGBAColorWidgetSetting extends WidgetSettingOption { +/** + * @deprecated Use {@link GradientWidgetSetting} + */ +@Deprecated(forRemoval = true, since = "2.3.0") +public class RGBAColorWidgetSetting extends WidgetSettingOption { public RGBAColorWidgetSetting(String id, Text name, int defaultR, int defaultG, int defaultB, int defaultAlpha) { super(id, name); this.r = defaultR; @@ -40,6 +45,11 @@ public class RGBAColorWidgetSetting extends WidgetSettingOption { return a << 24 | r << 16 | g << 8 | b; } + @Override + public @NotNull Integer getValue(){ + return getColor(); + } + @Override public void loadState(JsonElement state) { if (state.isJsonPrimitive() && state.getAsJsonPrimitive().isNumber()){ @@ -107,7 +117,7 @@ public class RGBAColorWidgetSetting extends WidgetSettingOption { return true; } - public class ChangeScreen extends Screen { + public class ChangeScreen extends Screen implements WidgetVisibilityToggle { private final Screen parent; private int x; @@ -194,6 +204,11 @@ public class RGBAColorWidgetSetting extends WidgetSettingOption { return super.mouseClicked(mouseX, mouseY, button); } + @Override + public boolean shouldRenderWidgets() { + return false; + } + public class ColorBar extends ClickableWidget { private final int component; diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/TextFieldWidgetSettingOption.java b/src/main/java/de/shiewk/widgets/widgets/settings/TextFieldWidgetSettingOption.java index 3271caa..45fdf2a 100644 --- a/src/main/java/de/shiewk/widgets/widgets/settings/TextFieldWidgetSettingOption.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/TextFieldWidgetSettingOption.java @@ -2,7 +2,6 @@ package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import de.shiewk.widgets.WidgetSettingOption; import de.shiewk.widgets.WidgetsMod; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; @@ -10,7 +9,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.text.Text; -public class TextFieldWidgetSettingOption extends WidgetSettingOption { +public class TextFieldWidgetSettingOption extends WidgetSettingOption { private TextField textField = null; private final Text initialValue; @@ -52,6 +51,7 @@ public class TextFieldWidgetSettingOption extends WidgetSettingOption { textField.setText(value.isEmpty() ? initialValue.getString() : value); } + @Override public String getValue(){ return value; } diff --git a/src/main/java/de/shiewk/widgets/widgets/settings/ToggleWidgetSetting.java b/src/main/java/de/shiewk/widgets/widgets/settings/ToggleWidgetSetting.java index ef453c2..8a43f75 100644 --- a/src/main/java/de/shiewk/widgets/widgets/settings/ToggleWidgetSetting.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/ToggleWidgetSetting.java @@ -2,17 +2,17 @@ package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import de.shiewk.widgets.WidgetSettingOption; import de.shiewk.widgets.utils.WidgetUtils; import net.minecraft.client.gui.DrawContext; import net.minecraft.sound.SoundEvents; import net.minecraft.text.Text; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; +import org.jetbrains.annotations.NotNull; import java.awt.*; -public class ToggleWidgetSetting extends WidgetSettingOption { +public class ToggleWidgetSetting extends WidgetSettingOption { private boolean value; private long toggleTime = 0; @@ -22,7 +22,8 @@ public class ToggleWidgetSetting extends WidgetSettingOption { this.value = defaultValue; } - public boolean getValue(){ + @Override + public @NotNull Boolean getValue(){ return value; } diff --git a/src/main/java/de/shiewk/widgets/WidgetSettingOption.java b/src/main/java/de/shiewk/widgets/widgets/settings/WidgetSettingOption.java similarity index 91% rename from src/main/java/de/shiewk/widgets/WidgetSettingOption.java rename to src/main/java/de/shiewk/widgets/widgets/settings/WidgetSettingOption.java index 6df8415..60bb715 100644 --- a/src/main/java/de/shiewk/widgets/WidgetSettingOption.java +++ b/src/main/java/de/shiewk/widgets/widgets/settings/WidgetSettingOption.java @@ -1,4 +1,4 @@ -package de.shiewk.widgets; +package de.shiewk.widgets.widgets.settings; import com.google.gson.JsonElement; import de.shiewk.widgets.utils.WidgetUtils; @@ -10,7 +10,8 @@ import net.minecraft.text.Text; import java.util.function.BooleanSupplier; import java.util.function.Consumer; -public abstract class WidgetSettingOption implements Drawable, Widget { +public abstract class WidgetSettingOption implements Drawable, Widget { + private final String id; private final Text name; private int x = 0; @@ -42,6 +43,7 @@ public abstract class WidgetSettingOption implements Drawable, Widget { public abstract JsonElement saveState(); public abstract void loadState(JsonElement state); + public abstract T getValue(); public boolean mouseClicked(double mouseX, double mouseY, int button) { return false; @@ -105,7 +107,7 @@ public abstract class WidgetSettingOption implements Drawable, Widget { return shouldShow.getAsBoolean(); } - public WidgetSettingOption setShowCondition(BooleanSupplier shouldShow){ + public WidgetSettingOption setShowCondition(BooleanSupplier shouldShow){ this.shouldShow = shouldShow; return this; } diff --git a/src/main/resources/assets/widgets/lang/de_de.json b/src/main/resources/assets/widgets/lang/de_de.json index b76c3d0..f029dec 100644 --- a/src/main/resources/assets/widgets/lang/de_de.json +++ b/src/main/resources/assets/widgets/lang/de_de.json @@ -1,6 +1,11 @@ { + "widgets.gradient.preset.rainbow": "Regenbogen", + "widgets.gradient.pulse": "Pulse", + "widgets.gradient.pulse.description": "Färbt Text oder Oberfläche mit einer einzelnen Farbe und geht dabei zwischen den ausgewählten Farben über", + "widgets.gradient.sweep": "Sweep", + "widgets.gradient.sweep.description": "Färbt Text oder Oberfläche mit einem sich bewegenden Farbverlauf", "widgets.key.category": "Widgets", - "widgets.key.config": "Öffne Widgets-Einstellungen", + "widgets.key.config": "Widgets-Einstellungen öffnen", "widgets.ui.anchor.bottom_center": "Unten mittig", "widgets.ui.anchor.bottom_left": "Unten links", "widgets.ui.anchor.bottom_right": "Unten rechts", @@ -20,9 +25,24 @@ "widgets.ui.editPositions.snap": "Positionen ausrichten: %s", "widgets.ui.editPositions.snap.help": "Richtet die Position des Widgets mit Positionen der anderen Widgets aus", "widgets.ui.enabled": "Aktiviert", + "widgets.ui.gradientEditor": "Farbe bearbeiten", + "widgets.ui.gradientEditor.colors": "Dieser Verlauf:", + "widgets.ui.gradientEditor.colors.add.tooltip.0": "Diesem Farbverlauf eine Farbe hinzufügen", + "widgets.ui.gradientEditor.colors.add.tooltip.1": "(Bleibe bei einer Farbe, um den Farbverlauf zu deaktivieren)", + "widgets.ui.gradientEditor.editColor": "Farbe bearbeiten:", + "widgets.ui.gradientEditor.editColor.orPick": "Alternative Auswahl:", + "widgets.ui.gradientEditor.gradientSettings": "Verlaufsoptionen:", + "widgets.ui.gradientEditor.gradientSettings.addMoreColors": "Füge mindestens zwei Farben hinzu, um den Farbverlauf zu bearbeiten.", + "widgets.ui.gradientEditor.importOther": "Von Widget importieren", + "widgets.ui.gradientEditor.mode": "Modus: %s", + "widgets.ui.gradientEditor.removeColor": "Farbe entfernen", + "widgets.ui.gradientEditor.size": "Größe: %s%%", + "widgets.ui.gradientEditor.speed": "Geschwindigkeit: %s%%", + "widgets.ui.gradientEditor.usePreset": "Voreinstellung nutzen", "widgets.ui.preview": "Vorschau", "widgets.ui.search": "Suchen...", "widgets.ui.widgetSettings": "Bearbeite %s Einstellungen", + "widgets.ui.widgetSettings.colors": "%s Farben", "widgets.widgets.armorHud": "Rüstungsstatus", "widgets.widgets.armorHud.description": "Zeigt die Rüstung, die du gerade trägst, und ihre Haltbarkeit.", "widgets.widgets.armorHud.durabilityStyle": "Haltbarkeitsstil", @@ -31,7 +51,7 @@ "widgets.widgets.armorHud.padding": "Abstand", "widgets.widgets.armorHud.showDurability": "Haltbarkeitsbeschriftung anzeigen", "widgets.widgets.bandwidth": "Bandbreite", - "widgets.widgets.bandwidth.description": "Zeigt, wie viele Daten an den aktuell Server gesendet werden/vom Server an den Klient gesendet werden.", + "widgets.widgets.bandwidth.description": "Zeigt, wie viele Daten aktuell vom Server an den Klienten gesendet werden.", "widgets.widgets.bandwidth.dynamicColor": "Farbe dynamisch anzeigen", "widgets.widgets.bandwidth.fastupdate": "Schnelle Aktualisierung", "widgets.widgets.bandwidth.unit": "Einheit", @@ -70,8 +90,6 @@ "widgets.widgets.combo.description": "Zeigt deine momentane Combo an", "widgets.widgets.combo.displayThreshold": "Minimum sichtbar", "widgets.widgets.common.hideInSingleplayer": "In Einzelspielerwelten verbergen", - "widgets.widgets.common.rainbow": "Regenbogen-Text", - "widgets.widgets.common.rainbow.speed": "Regenbogengeschwindigkeit", "widgets.widgets.common.realtime": "Echtzeit-Update (braucht mehr Leistung)", "widgets.widgets.common.showLabel": "Beschriftung anzeigen", "widgets.widgets.common.sizePercent": "Widgetgröße (%)", @@ -101,8 +119,6 @@ "widgets.widgets.inventory.mode.texture_pack": "Texturenpaket", "widgets.widgets.inventory.mode.transparent": "Transparent", "widgets.widgets.inventory.mode.vanilla": "Standard", - "widgets.widgets.inventory.rainbowBoxes": "Regenbogenzellen", - "widgets.widgets.inventory.rainbowGrid": "Regenbogengitter", "widgets.widgets.inventory.showHotbar": "Schnellzugriffsleiste anzeigen", "widgets.widgets.keystrokes": "Keystrokes", "widgets.widgets.keystrokes.colorBackgroundPressed": "Hintergrundfarbe (Taste gedrückt)", diff --git a/src/main/resources/assets/widgets/lang/en_us.json b/src/main/resources/assets/widgets/lang/en_us.json index 9b4b852..47d6577 100644 --- a/src/main/resources/assets/widgets/lang/en_us.json +++ b/src/main/resources/assets/widgets/lang/en_us.json @@ -1,4 +1,9 @@ { + "widgets.gradient.preset.rainbow": "Rainbow", + "widgets.gradient.pulse": "Pulse", + "widgets.gradient.pulse.description": "Paints the text or surface with one solid color, cycling through your selected palette", + "widgets.gradient.sweep": "Sweep", + "widgets.gradient.sweep.description": "Paints the text or surface with a moving gradient", "widgets.key.category": "Widgets", "widgets.key.config": "Open Widget Management", "widgets.ui.anchor.bottom_center": "Bottom center", @@ -20,9 +25,24 @@ "widgets.ui.editPositions.snap": "Align positions: %s", "widgets.ui.editPositions.snap.help": "Aligns the widget with positions of other widgets", "widgets.ui.enabled": "Enabled", + "widgets.ui.gradientEditor": "Color editor", + "widgets.ui.gradientEditor.colors": "This gradient:", + "widgets.ui.gradientEditor.colors.add.tooltip.0": "Add a color to this gradient", + "widgets.ui.gradientEditor.colors.add.tooltip.1": "(Leave this as one color to disable the gradient)", + "widgets.ui.gradientEditor.editColor": "Edit color:", + "widgets.ui.gradientEditor.editColor.orPick": "Alternative picker:", + "widgets.ui.gradientEditor.gradientSettings": "Gradient settings:", + "widgets.ui.gradientEditor.gradientSettings.addMoreColors": "Add more than one color to customize the gradient", + "widgets.ui.gradientEditor.importOther": "Import from widget", + "widgets.ui.gradientEditor.mode": "Mode: %s", + "widgets.ui.gradientEditor.removeColor": "Remove color", + "widgets.ui.gradientEditor.size": "Size: %s%%", + "widgets.ui.gradientEditor.speed": "Speed: %s%%", + "widgets.ui.gradientEditor.usePreset": "Use preset", "widgets.ui.preview": "Preview", "widgets.ui.search": "Search...", "widgets.ui.widgetSettings": "Edit %s settings", + "widgets.ui.widgetSettings.colors": "%s colors", "widgets.widgets.armorHud": "Armor Status", "widgets.widgets.armorHud.description": "Shows the armor you are currently wearing and its durability.", "widgets.widgets.armorHud.durabilityStyle": "Durability style", @@ -31,7 +51,7 @@ "widgets.widgets.armorHud.padding": "Padding", "widgets.widgets.armorHud.showDurability": "Show durability label", "widgets.widgets.bandwidth": "Bandwidth", - "widgets.widgets.bandwidth.description": "Shows how much data is being read/sent from the server you're connected to.", + "widgets.widgets.bandwidth.description": "Shows how much data the server you're connected to is sending.", "widgets.widgets.bandwidth.dynamicColor": "Dynamic Color", "widgets.widgets.bandwidth.fastupdate": "Fast update", "widgets.widgets.bandwidth.unit": "Unit", @@ -70,8 +90,6 @@ "widgets.widgets.combo.description": "Shows your current Combo.", "widgets.widgets.combo.displayThreshold": "Display Threshold", "widgets.widgets.common.hideInSingleplayer": "Hide in singleplayer worlds", - "widgets.widgets.common.rainbow": "Rainbow text", - "widgets.widgets.common.rainbow.speed": "Rainbow speed", "widgets.widgets.common.realtime": "Real-time updating (may use more performance)", "widgets.widgets.common.showLabel": "Show label", "widgets.widgets.common.sizePercent": "Widget size (%)", @@ -101,8 +119,6 @@ "widgets.widgets.inventory.mode.texture_pack": "Texture pack", "widgets.widgets.inventory.mode.transparent": "Transparent", "widgets.widgets.inventory.mode.vanilla": "Vanilla", - "widgets.widgets.inventory.rainbowBoxes": "Rainbow boxes", - "widgets.widgets.inventory.rainbowGrid": "Rainbow Grid", "widgets.widgets.inventory.showHotbar": "Show hotbar", "widgets.widgets.keystrokes": "Keystrokes", "widgets.widgets.keystrokes.colorBackgroundPressed": "Background color (key pressed)", diff --git a/src/main/resources/assets/widgets/textures/gui/arrow_down.png b/src/main/resources/assets/widgets/textures/gui/arrow_down.png new file mode 100644 index 0000000000000000000000000000000000000000..e7bcf166f642d0f5d85abb28d8d9ca3ab60da77c GIT binary patch literal 511 zcmVEX>4Tx04R~2kg-a`P!xv0R8f)YqBy8S2GOabnH;PNK~RXXg4HQaQYo|GgJlb`qxL>^`JfRk(h)f7!pX=ig|v!7@8+ z2Vt3aJ@16Z^ZANp^rd6Gn&ZhRv>@CgbqO)7+*VXBX$DuiC`rm{UA#28Kx&)D|IOdxThqPCdBGZ zG*fXSD&^#IAnJ*9n})pgI?q$eKprD`nS?u1d73=T|9-E1oYkAw+B6S}pl;2mTEii{ zKf+QUR-R$;x*==f_uCp~oOyy+779H*NB{r;8FWQhbVF}#ZDnqB07G(R zVRU6=Aa`kWXdp*PO;A^X4i^9b06a-VK~yNuV_+Z+{Qs}}A60~jkd_gm03JZ-02W|S z6T%r$HRv&DqKPnsF(B&>!)6Uk2@YwP50@?kEP)kdg0003aX+uL$Nkc;* zaB^>EX>4Tx04R~2kg-a`P!xv0R8f)YqBy8S2GOabnH;PNK~RXXg4HQaQYo|GgJlb`qxL>^`JfRk(h)f7!pX=ig|v!7@8+ z2Vt3aJ@16Z^ZANp^rd6Gn&ZhRv>@CgbqO)7+*VXBX$DuiC`rm{UA#28Kx&)D|IOdxThqPCdBGZ zG*fXSD&^#IAnJ*9n})pgI?q$eKprD`nS?u1d73=T|9-E1oYkAw+B6S}pl;2mTEii{ zKf+QUR-R$;x*==f_uCp~oOyy+1&)J!mH+?%h)G02R7l6=Ra*{#APnma z*TMUr0}oU`20~&$*}la6kPup$?gcnQ^dJpT0f3|2w=>Px# literal 0 HcmV?d00001