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.resources.Identifier; import net.minecraft.sounds.SoundEvents; import java.util.List; import java.util.function.DoubleConsumer; import java.util.function.DoubleFunction; public class SettingsControls { private static final Surface GLASS_PANEL = Surface.blur(5f, 15f) .and(Surface.flat(0x40FFFFFF)) .and(Surface.outline(0x64de4b)); public record ButtonState(String label, Runnable onSelect) {} public static FlowLayout makeSmallButton(Surface baseSurface, Identifier texture, Runnable onClick) { FlowLayout button = UIContainers.verticalFlow(Sizing.fixed(16), Sizing.fixed(16)); button.verticalAlignment(VerticalAlignment.CENTER); button.horizontalAlignment(HorizontalAlignment.CENTER); button.surface(baseSurface); button.child(UIComponents.texture(texture, 0, 0, 12, 12, 12, 12)) .horizontalAlignment(HorizontalAlignment.CENTER) .verticalAlignment(VerticalAlignment.CENTER); button.mouseEnter().subscribe(() -> button.surface( Surface.blur(5f, 15f).and(Surface.flat(0x70FFFFFF)).and(Surface.outline(0xFFFFFFFF)) )); button.mouseLeave().subscribe(() -> button.surface(baseSurface)); button.mouseDown().subscribe((click, doubled) -> { Minecraft.getInstance().getSoundManager().play( SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2) ); onClick.run(); return true; }); return button; } public static FlowLayout makeTextButton(Surface baseSurface, String text, Runnable onClick) { FlowLayout button = UIContainers.verticalFlow(Sizing.content(), Sizing.content()); button.verticalAlignment(VerticalAlignment.CENTER); button.horizontalAlignment(HorizontalAlignment.CENTER); button.padding(Insets.of(2, 2, 4, 4)); button.surface(baseSurface); button.child(UIComponents.label(Component.literal(text)).color(Color.ofRgb(0xFFFFFF))); button.mouseEnter().subscribe(() -> button.surface( Surface.blur(5f, 15f).and(Surface.flat(0x70FFFFFF)).and(Surface.outline(0xFFFFFFFF)) )); button.mouseLeave().subscribe(() -> button.surface(baseSurface)); button.mouseDown().subscribe((click, doubled) -> { Minecraft.getInstance().getSoundManager().play( SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2) ); onClick.run(); return true; }); return button; } 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(initialIndex).label())) .color(Color.ofRgb(0xFFFFFF)); button.child(label); button.mouseDown().subscribe((click, doubled) -> { Minecraft.getInstance().getSoundManager().play( SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2) ); currentIndex[0] = (currentIndex[0] + 1) % states.size(); ButtonState newState = states.get(currentIndex[0]); label.text(Component.literal(newState.label())); newState.onSelect().run(); return true; }); button.mouseEnter().subscribe(() -> label.color(Color.ofRgb(0xFFFFFF))); button.mouseLeave().subscribe(() -> label.color(Color.ofRgb(0xCCCCCC))); 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; int sliderWidth = width - labelWidth - 6; FlowLayout wrapper = UIContainers.horizontalFlow(Sizing.fixed(width), Sizing.fixed(16)); wrapper.verticalAlignment(VerticalAlignment.CENTER); wrapper.horizontalAlignment(HorizontalAlignment.LEFT); wrapper.padding(Insets.of(2, 2, 4, 0)); wrapper.gap(2); var valueLabel = UIComponents.label(Component.literal(labelFormatter.apply(initial))); valueLabel.color(Color.ofRgb(0xFFFFFF)); valueLabel.horizontalSizing(Sizing.fixed(labelWidth)); wrapper.child(valueLabel); var slider = UIComponents.discreteSlider(Sizing.fixed(sliderWidth), min, max); slider.horizontalSizing(Sizing.fixed(sliderWidth)); slider.verticalSizing(Sizing.fixed(10)); slider.setFromDiscreteValue(initial); slider.cursorStyle(CursorStyle.POINTER); slider.mouseDown().subscribe((click, doubled) -> { return doubled; }); slider.onChanged().subscribe(value -> { valueLabel.text(Component.literal(labelFormatter.apply(value))); onChange.accept(value); }); wrapper.child(slider); return wrapper; } }