From 652fe728e18cae65e5d4e6af27c6b546b5727b84 Mon Sep 17 00:00:00 2001 From: FullRisk Date: Sat, 11 Jul 2026 10:46:47 +0200 Subject: [PATCH] Added Quests and Real Settings (yay) --- .../java/de/fullrisk/citrusDev/Config.java | 3 + .../citrusDev/UI/Module_KeyStrokes.java | 130 ++++++++++++++++ .../de/fullrisk/citrusDev/UI/MyScreen.java | 144 ++++++++++-------- .../de/fullrisk/citrusDev/UI/QuestsPanel.java | 72 +++++++-- .../citrusDev/UIHelper/ModuleRow.java | 102 +++++++++++++ .../citrusDev/UIHelper/SettingsControls.java | 11 +- .../citrusDev/client/CitrusDevClient.java | 7 +- 7 files changed, 392 insertions(+), 77 deletions(-) create mode 100644 src/main/java/de/fullrisk/citrusDev/UI/Module_KeyStrokes.java create mode 100644 src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java diff --git a/src/main/java/de/fullrisk/citrusDev/Config.java b/src/main/java/de/fullrisk/citrusDev/Config.java index c60dc5c..585a7a2 100644 --- a/src/main/java/de/fullrisk/citrusDev/Config.java +++ b/src/main/java/de/fullrisk/citrusDev/Config.java @@ -18,6 +18,9 @@ public class Config { public int fpsY = 1; public String lastModule = "FPS"; + public int keyX = 1; + public int keyY = 1; + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static final Path PATH = FabricLoader.getInstance() .getConfigDir() diff --git a/src/main/java/de/fullrisk/citrusDev/UI/Module_KeyStrokes.java b/src/main/java/de/fullrisk/citrusDev/UI/Module_KeyStrokes.java new file mode 100644 index 0000000..a2be002 --- /dev/null +++ b/src/main/java/de/fullrisk/citrusDev/UI/Module_KeyStrokes.java @@ -0,0 +1,130 @@ +package de.fullrisk.citrusDev.UI; + +import io.wispforest.owo.ui.component.LabelComponent; +import io.wispforest.owo.ui.component.UIComponents; +import io.wispforest.owo.ui.container.FlowLayout; +import io.wispforest.owo.ui.container.UIContainers; +import io.wispforest.owo.ui.core.*; +import io.wispforest.owo.ui.hud.Hud; +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.Identifier; +import de.fullrisk.citrusDev.Config; + +public class Module_KeyStrokes { + + private static FlowLayout keyContainer; + private static FlowLayout topRow; + private static FlowLayout bottomRow; + + private static FlowLayout wBox, aBox, sBox, dBox; + private static LabelComponent wLabel, aLabel, sLabel, dLabel; + + static boolean toggle = true; + private static boolean shown = false; + public static boolean isEnabled() { + return toggle; + } + + public static void setEnabled(boolean value) { + toggle = value; + } + + private static final Config CONFIG = Config.get(); + + private static final Surface GLASS_PANEL = Surface.blur(5f, 15f) + .and(Surface.flat(0x40FFFFFF)); + + private static final int KEY_SIZE = 16; + private static final int PRESSED_COLOR = 0xFF64de4b; + private static final int IDLE_COLOR = 0x40FFFFFF; + + public static void setPosition(int x, int y) { + if (keyContainer != null) { + keyContainer.positioning(Positioning.relative(x, y)); + } + CONFIG.keyX = x; + CONFIG.keyY = y; + CONFIG.save(); + } + + public static void register() { + Hud.add(Identifier.fromNamespaceAndPath("citrus-dev", "keystrokes_display"), () -> { + if (keyContainer == null) { + wLabel = UIComponents.label(Component.literal("W")); + aLabel = UIComponents.label(Component.literal("A")); + sLabel = UIComponents.label(Component.literal("S")); + dLabel = UIComponents.label(Component.literal("D")); + + wBox = makeKeyBox(wLabel); + aBox = makeKeyBox(aLabel); + sBox = makeKeyBox(sLabel); + dBox = makeKeyBox(dLabel); + + topRow = UIContainers.horizontalFlow(Sizing.content(), Sizing.content()); + topRow.gap(2); + topRow.horizontalAlignment(HorizontalAlignment.CENTER); + topRow.child(UIContainers.horizontalFlow(Sizing.fixed(KEY_SIZE), Sizing.fixed(KEY_SIZE))); // spacer + topRow.child(wBox); + topRow.child(UIContainers.horizontalFlow(Sizing.fixed(KEY_SIZE), Sizing.fixed(KEY_SIZE))); // spacer + + bottomRow = UIContainers.horizontalFlow(Sizing.content(), Sizing.content()); + bottomRow.gap(2); + bottomRow.horizontalAlignment(HorizontalAlignment.CENTER); + bottomRow.child(aBox); + bottomRow.child(sBox); + bottomRow.child(dBox); + + keyContainer = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); + keyContainer.gap(2); + keyContainer.verticalAlignment(VerticalAlignment.CENTER); + keyContainer.horizontalAlignment(HorizontalAlignment.CENTER); + keyContainer.padding(Insets.of(0)); + + keyContainer.positioning(Positioning.relative(CONFIG.keyX, CONFIG.keyY)); + } + return keyContainer; + }); + } + + private static FlowLayout makeKeyBox(LabelComponent label) { + FlowLayout box = UIContainers.verticalFlow(Sizing.fixed(KEY_SIZE), Sizing.fixed(KEY_SIZE)); + box.horizontalAlignment(HorizontalAlignment.CENTER); + box.verticalAlignment(VerticalAlignment.CENTER); + box.surface(Surface.flat(IDLE_COLOR)); + box.child(label); + return box; + } + + public static void tick() { + if (keyContainer == null) return; + + if (toggle && !shown) { + keyContainer.clearChildren(); // <-- safety net against duplicate adds + keyContainer.surface(GLASS_PANEL); + keyContainer.padding(Insets.of(Config.get().fpsP)); + keyContainer.child(topRow); + keyContainer.child(bottomRow); + shown = true; + } else if (!toggle && shown) { + keyContainer.clearChildren(); + keyContainer.surface(Surface.flat(0)); + keyContainer.padding(Insets.of(0)); + shown = false; + } + + if (!toggle) return; + + Minecraft client = Minecraft.getInstance(); + KeyMapping up = client.options.keyUp; + KeyMapping left = client.options.keyLeft; + KeyMapping down = client.options.keyDown; + KeyMapping right = client.options.keyRight; + + wBox.surface(Surface.flat(up.isDown() ? PRESSED_COLOR : IDLE_COLOR)); + aBox.surface(Surface.flat(left.isDown() ? PRESSED_COLOR : IDLE_COLOR)); + sBox.surface(Surface.flat(down.isDown() ? PRESSED_COLOR : IDLE_COLOR)); + dBox.surface(Surface.flat(right.isDown() ? PRESSED_COLOR : IDLE_COLOR)); + } +} \ No newline at end of file diff --git a/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java b/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java index 87eb9d2..f8d2632 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/MyScreen.java @@ -56,6 +56,7 @@ public class MyScreen extends BaseOwoScreen { private FlowLayout content; private final String initialModule; + public MyScreen() { this(null); } @@ -130,8 +131,8 @@ public class MyScreen extends BaseOwoScreen { rootComponent.child(panel); - if ("FPS".equals(initialModule)) { - openModuleSettings("FPS", fpsModuleSettings()); + if (initialModule != null) { + openModuleByKey(initialModule); } else { buildGeneralPanel(content); } @@ -249,72 +250,51 @@ public class MyScreen extends BaseOwoScreen { } private void buildGeneralPanel(FlowLayout content) { - FlowLayout iconButton = UIContainers.horizontalFlow(Sizing.content(), Sizing.content()); - iconButton.gap(8); - iconButton.verticalAlignment(VerticalAlignment.TOP); - iconButton.horizontalAlignment(HorizontalAlignment.CENTER); - iconButton.padding(Insets.of(6)); - iconButton.horizontalSizing(Sizing.fixed(0)); - iconButton.verticalSizing(Sizing.fixed(0)); - iconButton.surface(toggle ? GLASS_PANEL : DISABLED); - iconButton.child(UIComponents.texture( - Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), - 0, 0, 18, 12, 18, 12 - )).horizontalAlignment(HorizontalAlignment.LEFT) - .verticalAlignment(VerticalAlignment.CENTER); - - FlowLayout textStack = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); - textStack.gap(2); - textStack.horizontalAlignment(HorizontalAlignment.LEFT); - textStack.verticalAlignment(VerticalAlignment.CENTER); - - var fpsLabel = UIComponents.label( - Component.literal("FPS") - .withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))) - ).color(Color.ofRgb(toggle ? 0xffffff : 0x797b86)); - - textStack.child(fpsLabel); - - textStack.child(UIComponents.label( - Component.literal("Displays your FPS")) - .color(Color.ofRgb(0xa3a3ac)) - .maxWidth(130) - ); - - iconButton.child(textStack); - iconButton.child(UIComponents.spacer()); - - FlowLayout settingsButton = SettingsControls.makeSmallButton( - FLAT, + FlowLayout fpsRow = ModuleRow.build( + GLASS_PANEL, DISABLED, FLAT, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), + 18, 12, + MC_FIVE, + "FPS", + "Displays your FPS", + new ModuleRow.ToggleState() { + public boolean get() { return toggle; } + public void set(boolean value) { toggle = value; } + }, Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"), () -> { Config.get().lastModule = "FPS"; Config.get().save(); - openModuleSettings("FPS", fpsModuleSettings()); - } + }, + "Module Enabled", "FPS counter is now active", + "Module Disabled", "FPS counter is now inactive" ); - iconButton.child(settingsButton); - iconButton.mouseEnter().subscribe(() -> iconButton.surface(toggle ? GLASS_PANEL : DISABLED)); - iconButton.mouseLeave().subscribe(() -> iconButton.surface(toggle ? GLASS_PANEL : DISABLED)); + FlowLayout keyStrokesRow = ModuleRow.build( + GLASS_PANEL, DISABLED, FLAT, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), + 18, 12, + MC_FIVE, + "Keystrokes", + "Current Key Presses", + new ModuleRow.ToggleState() { + public boolean get() { return Module_KeyStrokes.isEnabled(); } + public void set(boolean value) { Module_KeyStrokes.setEnabled(value); } + }, + Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"), + () -> { + Config.get().lastModule = "Key"; + Config.get().save(); + openModuleSettings("Key", keyStrokesSettings()); + }, + "Module Enabled", "Keystrokes is now active", + "Module Disabled", "KeyStrokes is now inactive" + ); + content.child(keyStrokesRow); + content.child(fpsRow); - iconButton.mouseDown().subscribe((click, doubled) -> { - toggle = !toggle; - fpsLabel.color(Color.ofRgb(toggle ? 0xffffff : 0x797b86)); - iconButton.surface(toggle ? GLASS_PANEL : DISABLED); - CitrusToast.show("Module Enabled", "FPS counter is now active"); - Minecraft.getInstance().getSoundManager().play( - SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2) - ); - return true; - }); - - iconButton.horizontalSizing().animate(150, Easing.CUBIC, Sizing.fixed(200)).forwards(); - iconButton.verticalSizing().animate(150, Easing.CUBIC, Sizing.fixed(35)).forwards(); - - content.child(iconButton); } @@ -366,6 +346,14 @@ public class MyScreen extends BaseOwoScreen { content.child(scrollArea); } + private void openModuleByKey(String key) { + switch (key) { + case "FPS" -> openModuleSettings("FPS", fpsModuleSettings()); + case "Key" -> openModuleSettings("Keystrokes", keyStrokesSettings()); + default -> buildGeneralPanel(content); + } + } + private FlowLayout makeSettingRow(SettingRow setting) { FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16)); row.verticalAlignment(VerticalAlignment.CENTER); @@ -398,12 +386,48 @@ public class MyScreen extends BaseOwoScreen { value -> Module_FPS.fpsContainer.gap((int) value) ); + int currentIndex = positionIndex(Config.get().fpsX, Config.get().fpsY); + return List.of( - new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates)), + new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), new SettingRow("Size", sizeSlider) ); } + private List keyStrokesSettings() { + List positionStates = List.of( + new SettingsControls.ButtonState("L-TOP", () -> Module_KeyStrokes.setPosition(1, 1)), + new SettingsControls.ButtonState("R-TOP", () -> Module_KeyStrokes.setPosition(99, 1)), + new SettingsControls.ButtonState("R-BOTTOM", () -> Module_KeyStrokes.setPosition(99, 99)), + new SettingsControls.ButtonState("L-BOTTOM", () -> Module_KeyStrokes.setPosition(1, 99)) + ); + + FlowLayout sizeSlider = SettingsControls.makeSlider( + FLAT, + 80, + 0.0, 20.0, + 4.0, + value -> (int) value + "px", + value -> {} // fixed: was Module_FPS.fpsContainer.gap(...) + ); + + int currentIndex = positionIndex(Config.get().keyX, Config.get().keyY); + + return List.of( + new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)), + new SettingRow("Size", sizeSlider) + ); + } + + private int positionIndex(int x, int y) { + boolean right = x > 50; + boolean bottom = y > 50; + if (!right && !bottom) return 0; // L-TOP + if (right && !bottom) return 1; // R-TOP + if (right && bottom) return 2; // R-BOTTOM + return 3; // L-BOTTOM + } + @Override public boolean isPauseScreen() { return false; diff --git a/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java b/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java index 28daacb..a8cda9b 100644 --- a/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java +++ b/src/main/java/de/fullrisk/citrusDev/UI/QuestsPanel.java @@ -1,5 +1,6 @@ package de.fullrisk.citrusDev.UI; +import io.wispforest.owo.ui.component.LabelComponent; import io.wispforest.owo.ui.component.UIComponents; import io.wispforest.owo.ui.container.FlowLayout; import io.wispforest.owo.ui.container.UIContainers; @@ -7,12 +8,15 @@ import io.wispforest.owo.ui.core.*; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.FontDescription; import de.fullrisk.citrusDev.client.PlaytimeTracker; +import de.fullrisk.citrusDev.UIHelper.CitrusToast; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class QuestsPanel { - private static final int ACCENT = 0xbaff86; + private static final int ACCENT = 0x64de4b; private record QuestData(String title, String description, int requiredPlaytime) { boolean isUnlocked() { @@ -20,7 +24,50 @@ public class QuestsPanel { } } - public static void build(FlowLayout content, int contentWidth, int contentHeight) { + public static class Handle { + private final LabelComponent playtimeLabel; + private final LabelComponent percentLabel; + private final FlowLayout barFill; + private final int barWidth; + private final List quests; + private final Set notifiedTitles = new HashSet<>(); + + private Handle(LabelComponent playtimeLabel, LabelComponent percentLabel, FlowLayout barFill, int barWidth, List quests) { + this.playtimeLabel = playtimeLabel; + this.percentLabel = percentLabel; + this.barFill = barFill; + this.barWidth = barWidth; + this.quests = quests; + + // seed with whatever's already unlocked on open, so we don't spam + // toasts for quests the player unlocked before opening this screen + for (QuestData quest : quests) { + if (quest.isUnlocked()) { + notifiedTitles.add(quest.title()); + } + } + } + + public void refresh() { + int playtime = PlaytimeTracker.getCurrentPlaytimeSeconds(); + int maxPlaytime = 360; + int progress = Math.min(playtime * 100 / maxPlaytime, 100); + + playtimeLabel.text(Component.literal(formatPlaytime(playtime))); + percentLabel.text(Component.literal(progress + "%")); + + int fillWidth = Math.max(barWidth * progress / 100, progress > 0 ? 2 : 0); + barFill.horizontalSizing(Sizing.fixed(fillWidth)); + + for (QuestData quest : quests) { + if (quest.isUnlocked() && notifiedTitles.add(quest.title())) { + CitrusToast.show("Quest Unlocked", quest.title()); + } + } + } + } + + public static Handle build(FlowLayout content, int contentWidth, int contentHeight) { List quests = quests(); int playtime = PlaytimeTracker.getCurrentPlaytimeSeconds(); int maxPlaytime = 360; @@ -28,7 +75,6 @@ public class QuestsPanel { int barWidth = contentWidth - 8; long unlockedCount = quests.stream().filter(QuestData::isUnlocked).count(); - // --- status row: playtime + percentage --- FlowLayout statusBar = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.fixed(20)); statusBar.gap(4); statusBar.padding(Insets.of(4)); @@ -36,15 +82,17 @@ public class QuestsPanel { statusBar.horizontalAlignment(HorizontalAlignment.LEFT); statusBar.surface(MyScreen.GLASS_PANEL); - statusBar.child(UIComponents.label(Component.literal("Playtime: " + formatPlaytime(playtime))) - .color(Color.ofRgb(0xFFFFFF))); + LabelComponent playtimeLabel = UIComponents.label(Component.literal(formatPlaytime(playtime))); + playtimeLabel.color(Color.ofRgb(0xFFFFFF)); + statusBar.child(playtimeLabel); statusBar.child(UIComponents.spacer()); - statusBar.child(UIComponents.label(Component.literal(progress + "%")) - .color(Color.ofRgb(ACCENT))); + + LabelComponent percentLabel = UIComponents.label(Component.literal(progress + "%")); + percentLabel.color(Color.ofRgb(ACCENT)); + statusBar.child(percentLabel); content.child(statusBar); - // --- progress bar --- FlowLayout barBg = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.fixed(6)); barBg.surface(Surface.flat(0x30FFFFFF).and(Surface.outline(0x30FFFFFF))); barBg.horizontalAlignment(HorizontalAlignment.LEFT); @@ -58,7 +106,6 @@ public class QuestsPanel { content.child(barBg); - // --- unlocked count summary --- FlowLayout summaryRow = UIContainers.horizontalFlow(Sizing.fixed(barWidth), Sizing.content()); summaryRow.padding(Insets.of(3, 0, 2, 2)); @@ -69,7 +116,6 @@ public class QuestsPanel { content.child(summaryRow); - // --- quest list (scrollable) --- FlowLayout questList = UIContainers.verticalFlow(Sizing.fixed(barWidth), Sizing.content()); questList.gap(3); questList.padding(Insets.of(2, 0, 2, 2)); @@ -78,7 +124,7 @@ public class QuestsPanel { questList.child(buildQuestEntry(quest, contentWidth)); } - int usedHeight = 20 + 6 + 18 + 6; // statusBar + barBg + summaryRow + gaps + int usedHeight = 20 + 6 + 18 + 6; int scrollHeight = contentHeight - usedHeight; var scrollArea = UIContainers.verticalScroll( @@ -87,6 +133,8 @@ public class QuestsPanel { questList ); content.child(scrollArea); + + return new Handle(playtimeLabel, percentLabel, barFill, barWidth, quests); } private static String formatPlaytime(int seconds) { @@ -130,7 +178,7 @@ public class QuestsPanel { : Surface.flat(0x40FFFFFF)); iconBox.horizontalAlignment(HorizontalAlignment.CENTER); iconBox.verticalAlignment(VerticalAlignment.CENTER); - iconBox.child(UIComponents.label(Component.literal(unlocked ? "✓" : "")) + iconBox.child(UIComponents.label(Component.literal("")) .color(Color.ofRgb(0x1c1c1c))); row.child(iconBox); diff --git a/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java b/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java new file mode 100644 index 0000000..e3e1a65 --- /dev/null +++ b/src/main/java/de/fullrisk/citrusDev/UIHelper/ModuleRow.java @@ -0,0 +1,102 @@ +package de.fullrisk.citrusDev.UIHelper; + +import io.wispforest.owo.ui.component.UIComponents; +import io.wispforest.owo.ui.container.FlowLayout; +import io.wispforest.owo.ui.container.UIContainers; +import io.wispforest.owo.ui.core.*; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FontDescription; +import net.minecraft.resources.Identifier; +import net.minecraft.sounds.SoundEvents; + +public class ModuleRow { + + /** Bridge to whatever boolean field actually holds the module's on/off state. */ + public interface ToggleState { + boolean get(); + void set(boolean value); + } + + public static FlowLayout build( + Surface enabledSurface, + Surface disabledSurface, + Surface flatSurface, + Identifier icon, + int iconWidth, + int iconHeight, + Identifier titleFont, + String title, + String description, + ToggleState state, + Identifier settingsIcon, + Runnable onSettingsClick, + String enabledToastTitle, + String enabledToastMessage, + String disabledToastTitle, + String disabledToastMessage + ) { + FlowLayout row = UIContainers.horizontalFlow(Sizing.content(), Sizing.content()); + row.gap(8); + row.verticalAlignment(VerticalAlignment.TOP); + row.horizontalAlignment(HorizontalAlignment.CENTER); + row.padding(Insets.of(6)); + row.horizontalSizing(Sizing.fixed(0)); + row.verticalSizing(Sizing.fixed(0)); + row.surface(state.get() ? enabledSurface : disabledSurface); + + row.child(UIComponents.texture(icon, 0, 0, iconWidth, iconHeight, iconWidth, iconHeight)) + .horizontalAlignment(HorizontalAlignment.LEFT) + .verticalAlignment(VerticalAlignment.CENTER); + + FlowLayout textStack = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); + textStack.gap(2); + textStack.horizontalAlignment(HorizontalAlignment.LEFT); + textStack.verticalAlignment(VerticalAlignment.CENTER); + + var titleLabel = UIComponents.label( + Component.literal(title) + .withStyle(style -> style.withFont(new FontDescription.Resource(titleFont))) + ); + titleLabel.color(Color.ofRgb(state.get() ? 0xffffff : 0x797b86)); + textStack.child(titleLabel); + + textStack.child(UIComponents.label(Component.literal(description)) + .color(Color.ofRgb(0xa3a3ac)) + .maxWidth(130)); + + row.child(textStack); + row.child(UIComponents.spacer()); + + FlowLayout settingsButton = SettingsControls.makeSmallButton(flatSurface, settingsIcon, onSettingsClick); + row.child(settingsButton); + + row.mouseEnter().subscribe(() -> row.surface(state.get() ? enabledSurface : disabledSurface)); + row.mouseLeave().subscribe(() -> row.surface(state.get() ? enabledSurface : disabledSurface)); + + row.mouseDown().subscribe((click, doubled) -> { + boolean newState = !state.get(); + state.set(newState); + + titleLabel.color(Color.ofRgb(newState ? 0xffffff : 0x797b86)); + row.surface(newState ? enabledSurface : disabledSurface); + + if (newState) { + CitrusToast.show(enabledToastTitle, enabledToastMessage); + } else { + CitrusToast.show(disabledToastTitle, disabledToastMessage); + } + + Minecraft.getInstance().getSoundManager().play( + SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2) + ); + return true; + }); + + row.horizontalSizing().animate(150, Easing.CUBIC, Sizing.fixed(200)).forwards(); + row.verticalSizing().animate(150, Easing.CUBIC, Sizing.fixed(35)).forwards(); + + return row; + } +} \ No newline at end of file diff --git a/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java b/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java index 954c5fe..825b151 100644 --- a/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java +++ b/src/main/java/de/fullrisk/citrusDev/UIHelper/SettingsControls.java @@ -73,15 +73,15 @@ public class SettingsControls { return button; } - public static FlowLayout makeCyclingButton(Surface baseSurface, List states) { - int[] currentIndex = {0}; + public static FlowLayout makeCyclingButton(Surface baseSurface, List states, int initialIndex) { + int[] currentIndex = { initialIndex }; FlowLayout button = UIContainers.verticalFlow(Sizing.fixed(50), Sizing.fixed(16)); button.verticalAlignment(VerticalAlignment.CENTER); button.horizontalAlignment(HorizontalAlignment.CENTER); button.surface(baseSurface); - var label = UIComponents.label(Component.literal(states.get(0).label())) + var label = UIComponents.label(Component.literal(states.get(initialIndex).label())) .color(Color.ofRgb(0xFFFFFF)); button.child(label); @@ -104,6 +104,11 @@ public class SettingsControls { return button; } + // keep the old call sites compiling; defaults to index 0 + public static FlowLayout makeCyclingButton(Surface baseSurface, List states) { + return makeCyclingButton(baseSurface, states, 0); + } + public static FlowLayout makeSlider(Surface baseSurface, int width, double min, double max, double initial, DoubleFunction labelFormatter, DoubleConsumer onChange) { int labelWidth = 34; diff --git a/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java b/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java index d1094cc..243ecf8 100644 --- a/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java +++ b/src/main/java/de/fullrisk/citrusDev/client/CitrusDevClient.java @@ -3,6 +3,7 @@ package de.fullrisk.citrusDev.client; import de.fullrisk.citrusDev.Config; import de.fullrisk.citrusDev.UI.Module_FPS; +import de.fullrisk.citrusDev.UI.Module_KeyStrokes; import de.fullrisk.citrusDev.UI.MyScreen; import de.fullrisk.citrusDev.UI.OverviewScreen; import io.wispforest.owo.ui.hud.Hud; @@ -21,6 +22,7 @@ public class CitrusDevClient implements ClientModInitializer { @Override public void onInitializeClient() { Module_FPS.register(); + Module_KeyStrokes.register(); KeyMapping.Category category = KeyMapping.Category.register( Identifier.fromNamespaceAndPath("citrus-dev", "general")); @@ -41,8 +43,9 @@ public class CitrusDevClient implements ClientModInitializer { PlaytimeTracker.tick(); } - Module_FPS.tick(); // update every tick, unconditionally - while (openScreenKey.consumeClick()) { + Module_FPS.tick(); + Module_KeyStrokes.tick(); + while (openScreenKey.consumeClick()) { client.setScreen(new MyScreen(null)); // always general tab }