Reworked ENTIRE UI (God help me) and cleaned up MyScreen.java (from 700 lines to 400)
This commit is contained in:
@@ -44,6 +44,7 @@ public class Config {
|
||||
public boolean effectsNameEnabled = true;
|
||||
|
||||
public float panelBlur = 5.0f;
|
||||
public boolean darkMode = false;
|
||||
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
package de.fullrisk.citrusDev.UI;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
import de.fullrisk.citrusDev.UIHelper.*;
|
||||
import io.wispforest.owo.ui.base.BaseOwoScreen;
|
||||
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;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MainUI extends BaseOwoScreen<FlowLayout> {
|
||||
|
||||
public static final Identifier MC_FIVE = Identifier.fromNamespaceAndPath("citrus-dev", "minecraft_five");
|
||||
|
||||
public static Surface PANEL_SURFACE = buildPanelSurface();
|
||||
public static Surface GLASS_PANEL = buildGlassSurface();
|
||||
public static Surface DISABLED = buildDisabledSurface();
|
||||
public static Surface FLAT = buildFlatSurface();
|
||||
|
||||
private static Surface buildPanelSurface() {
|
||||
float blur = Config.get().panelBlur;
|
||||
int fill = Config.get().darkMode ? 0x601c1c1c : 0x40FFFFFF;
|
||||
if (blur <= 0f) return Surface.flat(fill).and(Surface.outline(0x64de4b));
|
||||
return Surface.blur(blur, 15f).and(Surface.flat(fill)).and(Surface.outline(0x64de4b));
|
||||
}
|
||||
|
||||
private static Surface buildGlassSurface() {
|
||||
int fill = Config.get().darkMode ? 0x70282828 : 0x40FFFFFF;
|
||||
return Surface.blur(5f, 15f).and(Surface.flat(fill)).and(Surface.outline(0x64de4b));
|
||||
}
|
||||
|
||||
private static Surface buildDisabledSurface() {
|
||||
int fill = Config.get().darkMode ? 0x30050505 : 0x401c1c1c;
|
||||
return Surface.blur(5f, 15f).and(Surface.flat(fill));
|
||||
}
|
||||
|
||||
private static Surface buildFlatSurface() {
|
||||
int fill = Config.get().darkMode ? 0x601c1c1c : 0x40FFFFFF;
|
||||
return Surface.blur(5f, 15f).and(Surface.flat(fill));
|
||||
}
|
||||
|
||||
public static void rebuildSurfaces() {
|
||||
PANEL_SURFACE = buildPanelSurface();
|
||||
GLASS_PANEL = buildGlassSurface();
|
||||
DISABLED = buildDisabledSurface();
|
||||
FLAT = buildFlatSurface();
|
||||
if (panelRef != null) panelRef.surface(PANEL_SURFACE);
|
||||
}
|
||||
|
||||
private static int text() { return Config.get().darkMode ? 0xFFd0d4da : 0xFFb0b6c0; }
|
||||
private static int bright() { return 0xFFFFFF; }
|
||||
private static int tabText() { return 0xCCCCCC; }
|
||||
|
||||
public static final int PANEL_WIDTH = 320;
|
||||
public static final int PANEL_HEIGHT = 190;
|
||||
public static final int INNER_WIDTH = PANEL_WIDTH - 4;
|
||||
public static final int INNER_HEIGHT = PANEL_HEIGHT - 4;
|
||||
public static final int NAVBAR_HEIGHT = 24;
|
||||
public static final int DIVIDER_SIZE = 1;
|
||||
public static final int SIDEBAR_WIDTH = 44;
|
||||
public static final int ROW_HEIGHT = INNER_HEIGHT - NAVBAR_HEIGHT - DIVIDER_SIZE;
|
||||
public static final int CONTENT_WIDTH = INNER_WIDTH - SIDEBAR_WIDTH - DIVIDER_SIZE;
|
||||
|
||||
private static final Map<String, String[]> MODULE_TAGS = Map.of(
|
||||
"FPS", new String[]{"HUD"},
|
||||
"Keystrokes", new String[]{"HUD"},
|
||||
"Coordinates", new String[]{"HUD"},
|
||||
"Fullbright", new String[]{"World"},
|
||||
"Hitbox", new String[]{"Combat"},
|
||||
"Effects", new String[]{"HUD"}
|
||||
);
|
||||
private static final String[] CATEGORIES = {"ALL", "HUD", "Combat", "World"};
|
||||
|
||||
private record TabDef(String label, Runnable onClick) {}
|
||||
|
||||
private FlowLayout content;
|
||||
private final String initialModule;
|
||||
private static FlowLayout panelRef;
|
||||
private String activeCategory = "ALL";
|
||||
private static String searchText = "";
|
||||
private FlowLayout moduleListContainer;
|
||||
private List<ModuleRows.Entry> allModuleRows;
|
||||
|
||||
public MainUI() { this(null); }
|
||||
|
||||
public MainUI(String initialModule) {
|
||||
super(Component.literal("Citrus Dev"));
|
||||
this.initialModule = initialModule;
|
||||
Minecraft.getInstance().getSoundManager().play(
|
||||
SimpleSoundInstance.forUI(SoundEvents.UI_TOAST_IN, 1.5F, 2)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OwoUIAdapter<FlowLayout> createAdapter() {
|
||||
return OwoUIAdapter.create(this, UIContainers::verticalFlow);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void build(FlowLayout rootComponent) {
|
||||
rootComponent.gap(0);
|
||||
rootComponent.horizontalAlignment(HorizontalAlignment.CENTER).verticalAlignment(VerticalAlignment.CENTER);
|
||||
|
||||
FlowLayout panel = UIContainers.verticalFlow(Sizing.content(), Sizing.content());
|
||||
panelRef = panel;
|
||||
panel.gap(0);
|
||||
panel.padding(Insets.of(2));
|
||||
panel.horizontalAlignment(HorizontalAlignment.CENTER).verticalAlignment(VerticalAlignment.CENTER);
|
||||
panel.horizontalSizing(Sizing.fixed(0));
|
||||
panel.verticalSizing(Sizing.fixed(0));
|
||||
panel.horizontalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_WIDTH)).forwards();
|
||||
panel.verticalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_HEIGHT)).forwards();
|
||||
panel.surface(PANEL_SURFACE);
|
||||
|
||||
FlowLayout navbar = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(NAVBAR_HEIGHT));
|
||||
navbar.verticalAlignment(VerticalAlignment.CENTER);
|
||||
navbar.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
navbar.gap(16);
|
||||
|
||||
var logo = UIComponents.texture(Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/citrus-logo.png"), 0, 0, 30, 30, 30, 30);
|
||||
logo.positioning(Positioning.absolute(4, (NAVBAR_HEIGHT - 30) / 2));
|
||||
navbar.child(logo);
|
||||
|
||||
for (TabDef tab : List.of(
|
||||
new TabDef("general", () -> switchToContent(c -> buildGeneralPanel(c))),
|
||||
new TabDef("quests", () -> switchToContent(c -> QuestsPanel.build(c, CONTENT_WIDTH, ROW_HEIGHT))),
|
||||
new TabDef("settings", () -> switchToContent(this::buildSettingsPanel))
|
||||
)) {
|
||||
navbar.child(makeTab(tab.label(), tab.onClick()));
|
||||
}
|
||||
panel.child(navbar);
|
||||
|
||||
FlowLayout navDividerSpacer = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(DIVIDER_SIZE));
|
||||
panel.child(navDividerSpacer);
|
||||
|
||||
FlowLayout navDivider = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(DIVIDER_SIZE));
|
||||
navDivider.surface(Surface.flat(0x80FFFFFF));
|
||||
navDivider.positioning(Positioning.absolute(0, NAVBAR_HEIGHT));
|
||||
panel.child(navDivider);
|
||||
|
||||
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
row.gap(0);
|
||||
row.child(buildSidebar());
|
||||
|
||||
content = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
content.gap(2);
|
||||
content.padding(Insets.of(4));
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
row.child(content);
|
||||
panel.child(row);
|
||||
|
||||
var version = new ScalableLabel(Component.literal("Citrus-Dev v2.0"));
|
||||
version.horizontalTextAlignment(HorizontalAlignment.RIGHT);
|
||||
version.verticalTextAlignment(VerticalAlignment.BOTTOM);
|
||||
version.horizontalSizing(Sizing.fixed(CONTENT_WIDTH - 8));
|
||||
version.verticalSizing(Sizing.fixed(12));
|
||||
version.positioning(Positioning.relative(100, 100));
|
||||
version.scale().set(new ScaleValue(0.7f));
|
||||
panel.child(version);
|
||||
|
||||
rootComponent.child(panel);
|
||||
|
||||
if (initialModule != null) openModuleByKey(initialModule);
|
||||
else buildGeneralPanel(content);
|
||||
}
|
||||
|
||||
private void switchToContent(java.util.function.Consumer<FlowLayout> builder) {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
builder.accept(content);
|
||||
}
|
||||
|
||||
private FlowLayout makeTab(String text, Runnable onClick) {
|
||||
FlowLayout tab = UIContainers.verticalFlow(Sizing.content(), Sizing.content());
|
||||
tab.verticalAlignment(VerticalAlignment.CENTER);
|
||||
tab.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
tab.padding(Insets.of(2, 0, 2, 2));
|
||||
tab.gap(2);
|
||||
|
||||
var label = UIComponents.label(Component.literal(text).withStyle(s -> s.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(tabText())).shadow(true);
|
||||
tab.child(label);
|
||||
|
||||
FlowLayout underline = UIContainers.horizontalFlow(Sizing.fixed(Math.max(text.length() * 6, 10)), Sizing.fixed(1));
|
||||
underline.surface(Surface.flat(0x00FFFFFF));
|
||||
tab.child(underline);
|
||||
|
||||
tab.mouseEnter().subscribe(() -> { label.color(Color.ofRgb(bright())); underline.surface(Surface.flat(0xFFFFFFFF)); });
|
||||
tab.mouseLeave().subscribe(() -> { label.color(Color.ofRgb(tabText())); underline.surface(Surface.flat(0x00FFFFFF)); });
|
||||
tab.mouseDown().subscribe((click, doubled) -> {
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2));
|
||||
onClick.run();
|
||||
return true;
|
||||
});
|
||||
return tab;
|
||||
}
|
||||
|
||||
// --- Sidebar ---
|
||||
private static int sidebarBtnFill() { return Config.get().darkMode ? 0x803a3a3a : 0x80FFFFFF; }
|
||||
private static int sidebarBtnHover() { return Config.get().darkMode ? 0xA0505050 : 0xA0FFFFFF; }
|
||||
private static int sidebarBtnOutline() { return Config.get().darkMode ? 0xFF888888 : 0xFFFFFFFF; }
|
||||
private static int sidebarBtnHoverOutline() { return Config.get().darkMode ? 0xFFcccccc : 0xFFFFFFFF; }
|
||||
|
||||
private FlowLayout buildSidebar() {
|
||||
FlowLayout sidebar = UIContainers.verticalFlow(Sizing.fixed(SIDEBAR_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
sidebar.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
sidebar.verticalAlignment(VerticalAlignment.TOP);
|
||||
sidebar.padding(Insets.of(4));
|
||||
sidebar.gap(2);
|
||||
|
||||
sidebar.child(makeSidebarButton("-", 430));
|
||||
sidebar.child(makeSidebarButton("+", 400));
|
||||
sidebar.child(UIComponents.spacer());
|
||||
|
||||
// Edit button
|
||||
FlowLayout editButton = UIContainers.verticalFlow(Sizing.fixed(36), Sizing.fixed(18));
|
||||
editButton.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
editButton.verticalAlignment(VerticalAlignment.CENTER);
|
||||
editButton.surface(Surface.flat(sidebarBtnFill()).and(Surface.outline(sidebarBtnOutline())));
|
||||
editButton.child(UIComponents.texture(Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/edit.png"), 0, 0, 16, 16, 16, 16));
|
||||
editButton.mouseEnter().subscribe(() -> editButton.surface(Surface.flat(sidebarBtnHover()).and(Surface.outline(sidebarBtnHoverOutline()))));
|
||||
editButton.mouseLeave().subscribe(() -> editButton.surface(Surface.flat(sidebarBtnFill()).and(Surface.outline(sidebarBtnOutline()))));
|
||||
editButton.mouseDown().subscribe((click, doubled) -> {
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2));
|
||||
DraggableHud.setEditMode(true);
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
return true;
|
||||
});
|
||||
sidebar.child(editButton);
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
private ScalableButton makeSidebarButton(String symbol, int animateDelay) {
|
||||
var button = new ScalableButton(Component.literal(symbol), btn ->
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2)),
|
||||
sidebarBtnFill(), sidebarBtnHover(), sidebarBtnOutline(), sidebarBtnHoverOutline(), 1);
|
||||
button.horizontalSizing(Sizing.fixed(36));
|
||||
button.verticalSizing(Sizing.fixed(18));
|
||||
button.scale().set(new ScaleValue(0f));
|
||||
button.scale().animate(animateDelay, Easing.CUBIC, new ScaleValue(1f)).forwards();
|
||||
button.mouseEnter().subscribe(() -> button.scale().animate(120, Easing.CUBIC, new ScaleValue(1.1f)).forwards());
|
||||
button.mouseLeave().subscribe(() -> button.scale().animate(120, Easing.CUBIC, new ScaleValue(1.0f)).forwards());
|
||||
return button;
|
||||
}
|
||||
|
||||
// --- Category bar ---
|
||||
private FlowLayout buildCategoryBar(Runnable onFilterChanged) {
|
||||
FlowLayout bar = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(18));
|
||||
bar.gap(4);
|
||||
bar.verticalAlignment(VerticalAlignment.CENTER);
|
||||
bar.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
|
||||
for (String cat : CATEGORIES) {
|
||||
boolean isActive = cat.equals(activeCategory);
|
||||
FlowLayout catButton = UIContainers.verticalFlow(Sizing.fixed(Math.max(cat.length() * 7 + 8, 30)), Sizing.fixed(16));
|
||||
catButton.verticalAlignment(VerticalAlignment.CENTER);
|
||||
catButton.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
catButton.padding(Insets.of(2, 0, 2, 0));
|
||||
catButton.surface(isActive
|
||||
? Surface.flat(0x6064de4b).and(Surface.outline(0x64de4b))
|
||||
: Surface.flat(0x30FFFFFF).and(Surface.outline(0x64de4b)));
|
||||
|
||||
var catLabel = UIComponents.label(Component.literal(cat).withStyle(s -> s.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(isActive ? bright() : tabText()))
|
||||
.horizontalTextAlignment(HorizontalAlignment.CENTER);
|
||||
catButton.child(catLabel);
|
||||
|
||||
catButton.mouseEnter().subscribe(() -> { if (!cat.equals(activeCategory)) catButton.surface(Surface.flat(0x50FFFFFF).and(Surface.outline(0xFFFFFFFF))); });
|
||||
catButton.mouseLeave().subscribe(() -> { if (!cat.equals(activeCategory)) catButton.surface(Surface.flat(0x30FFFFFF).and(Surface.outline(0x64de4b))); });
|
||||
catButton.mouseDown().subscribe((click, doubled) -> {
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2));
|
||||
activeCategory = cat;
|
||||
onFilterChanged.run();
|
||||
return true;
|
||||
});
|
||||
bar.child(catButton);
|
||||
}
|
||||
|
||||
bar.child(UIComponents.spacer());
|
||||
|
||||
FlowLayout searchWrapper = UIContainers.horizontalFlow(Sizing.fixed(90), Sizing.fixed(16));
|
||||
searchWrapper.verticalAlignment(VerticalAlignment.CENTER);
|
||||
searchWrapper.horizontalAlignment(HorizontalAlignment.RIGHT);
|
||||
searchWrapper.padding(Insets.of(0, 4, 0, 4));
|
||||
searchWrapper.surface(FLAT.and(Surface.outline(0x64de4b)));
|
||||
|
||||
var searchBox = UIComponents.textBox(Sizing.fixed(82));
|
||||
searchBox.setValue(searchText);
|
||||
searchBox.setTextColor(text());
|
||||
searchBox.setHint(Component.literal("Search...").withStyle(s -> s.withColor(tabText())));
|
||||
searchBox.setFilter(s -> true);
|
||||
searchBox.setBordered(false);
|
||||
searchBox.onChanged().subscribe(newText -> {
|
||||
searchText = newText;
|
||||
rebuildModuleList();
|
||||
});
|
||||
searchWrapper.child(searchBox);
|
||||
|
||||
bar.child(searchWrapper);
|
||||
|
||||
return bar;
|
||||
}
|
||||
|
||||
private boolean matchesFilter(String moduleName) {
|
||||
if (!activeCategory.equals("ALL")) {
|
||||
String[] tags = MODULE_TAGS.get(moduleName);
|
||||
if (tags == null || !Arrays.asList(tags).contains(activeCategory)) return false;
|
||||
}
|
||||
return searchText.isEmpty() || moduleName.toLowerCase().contains(searchText.toLowerCase());
|
||||
}
|
||||
|
||||
// --- General panel ---
|
||||
private void buildGeneralPanel(FlowLayout content) {
|
||||
content.child(buildCategoryBar(() -> { content.clearChildren(); buildGeneralPanel(content); }));
|
||||
|
||||
allModuleRows = ModuleRows.buildAll(this::openModuleByKey);
|
||||
moduleListContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
moduleListContainer.gap(4);
|
||||
moduleListContainer.verticalAlignment(VerticalAlignment.TOP);
|
||||
moduleListContainer.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
rebuildModuleList();
|
||||
|
||||
content.child(UIContainers.verticalScroll(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(ROW_HEIGHT - 24), moduleListContainer));
|
||||
}
|
||||
|
||||
private void rebuildModuleList() {
|
||||
moduleListContainer.clearChildren();
|
||||
for (ModuleRows.Entry entry : allModuleRows) {
|
||||
if (matchesFilter(entry.name())) moduleListContainer.child(entry.row());
|
||||
}
|
||||
}
|
||||
|
||||
// --- Settings panel ---
|
||||
private void buildSettingsPanel(FlowLayout content) {
|
||||
FlowLayout rows = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
rows.gap(8);
|
||||
rows.verticalAlignment(VerticalAlignment.TOP);
|
||||
rows.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
|
||||
// Blur slider
|
||||
rows.child(makeSettingRow("Panel Blur", SettingsControls.makeSlider(
|
||||
FLAT, 80, 0.0, 15.0, Config.get().panelBlur,
|
||||
value -> (int) value + "px",
|
||||
value -> { Config.get().panelBlur = (float) (double) value; Config.get().save(); rebuildSurfaces(); }
|
||||
)));
|
||||
|
||||
// Dark mode toggle
|
||||
rows.child(makeSettingRow("Dark Mode", SettingsControls.makeCheckbox(
|
||||
FLAT, GLASS_PANEL, Config.get().darkMode, value -> {
|
||||
Config.get().darkMode = value;
|
||||
Config.get().save();
|
||||
rebuildSurfaces();
|
||||
Minecraft.getInstance().setScreen(new MainUI());
|
||||
}
|
||||
)));
|
||||
|
||||
content.child(rows);
|
||||
}
|
||||
|
||||
private FlowLayout makeSettingRow(String label, FlowLayout control) {
|
||||
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16));
|
||||
row.verticalAlignment(VerticalAlignment.CENTER);
|
||||
row.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
row.gap(4);
|
||||
row.child(UIComponents.label(Component.literal(label).withStyle(s -> s.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(text())));
|
||||
row.child(UIComponents.spacer());
|
||||
row.child(control);
|
||||
return row;
|
||||
}
|
||||
|
||||
// --- Module settings ---
|
||||
private void openModuleSettings(String title, List<ModuleSettings.SettingRow> rows) {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
|
||||
// Header with back button
|
||||
FlowLayout header = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
header.verticalAlignment(VerticalAlignment.CENTER);
|
||||
header.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
header.gap(4);
|
||||
header.child(SettingsControls.makeTextButton(FLAT, "<", () -> switchToContent(this::buildGeneralPanel)));
|
||||
header.child(UIComponents.label(Component.literal(title).withStyle(s -> s.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(bright())));
|
||||
content.child(header);
|
||||
|
||||
// Setting rows
|
||||
FlowLayout rowsContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
rowsContainer.gap(1);
|
||||
rowsContainer.verticalAlignment(VerticalAlignment.TOP);
|
||||
rowsContainer.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
|
||||
for (ModuleSettings.SettingRow setting : rows) {
|
||||
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16));
|
||||
row.verticalAlignment(VerticalAlignment.CENTER);
|
||||
row.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
row.gap(4);
|
||||
row.child(UIComponents.label(Component.literal(setting.label()).withStyle(s -> s.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(text())));
|
||||
row.child(UIComponents.spacer());
|
||||
row.child(setting.control());
|
||||
rowsContainer.child(row);
|
||||
}
|
||||
|
||||
content.child(UIContainers.verticalScroll(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(ROW_HEIGHT - 24), rowsContainer));
|
||||
}
|
||||
|
||||
private void openModuleByKey(String key) {
|
||||
switch (key) {
|
||||
case "FPS" -> openModuleSettings("FPS", ModuleSettings.fps());
|
||||
case "Key" -> openModuleSettings("Keystrokes", ModuleSettings.keystrokes());
|
||||
case "Coords" -> openModuleSettings("Coordinates", ModuleSettings.coords());
|
||||
case "Hitbox" -> openModuleSettings("Hitbox", ModuleSettings.hitbox(this::openModuleByKey));
|
||||
case "Effects" -> openModuleSettings("Effects", ModuleSettings.effects());
|
||||
default -> buildGeneralPanel(content);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() { return false; }
|
||||
}
|
||||
@@ -1,730 +0,0 @@
|
||||
package de.fullrisk.citrusDev.UI;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
import de.fullrisk.citrusDev.UIHelper.*;
|
||||
import io.wispforest.owo.ui.base.BaseOwoScreen;
|
||||
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;
|
||||
import de.fullrisk.citrusDev.client.PlaytimeTracker;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
import static de.fullrisk.citrusDev.UI.Module_FPS.fpsContainer;
|
||||
import static de.fullrisk.citrusDev.UI.Module_FPS.toggle;
|
||||
|
||||
public class MyScreen extends BaseOwoScreen<FlowLayout> {
|
||||
|
||||
static final Identifier MC_FIVE = Identifier.fromNamespaceAndPath("citrus-dev", "minecraft_five");
|
||||
|
||||
static Surface PANEL_SURFACE = buildPanelSurface();
|
||||
|
||||
static Surface GLASS_PANEL = Surface.blur(5f, 15f)
|
||||
.and(Surface.flat(0x40FFFFFF))
|
||||
.and(Surface.outline(0x64de4b));
|
||||
|
||||
private static Surface DISABLED = Surface.blur(5f, 15f)
|
||||
.and(Surface.flat(0x401c1c1c));
|
||||
|
||||
private static Surface FLAT = Surface.blur(5f, 15f)
|
||||
.and(Surface.flat(0x40FFFFFF));
|
||||
|
||||
private static Surface buildPanelSurface() {
|
||||
float blur = Config.get().panelBlur;
|
||||
if (blur <= 0f) {
|
||||
return Surface.flat(0x40FFFFFF)
|
||||
.and(Surface.outline(0x64de4b));
|
||||
}
|
||||
return Surface.blur(blur, 15f)
|
||||
.and(Surface.flat(0x40FFFFFF))
|
||||
.and(Surface.outline(0x64de4b));
|
||||
}
|
||||
|
||||
public static void rebuildSurfaces() {
|
||||
PANEL_SURFACE = buildPanelSurface();
|
||||
if (panelRef != null) {
|
||||
panelRef.surface(PANEL_SURFACE);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int PANEL_WIDTH = 250;
|
||||
private static final int PANEL_HEIGHT = 150;
|
||||
private static final int INNER_WIDTH = PANEL_WIDTH - 4;
|
||||
private static final int INNER_HEIGHT = PANEL_HEIGHT - 4;
|
||||
private static final int NAVBAR_HEIGHT = 24;
|
||||
private static final int DIVIDER_SIZE = 1;
|
||||
private static final int SIDEBAR_WIDTH = 34;
|
||||
private static final int ROW_HEIGHT = INNER_HEIGHT - NAVBAR_HEIGHT - DIVIDER_SIZE;
|
||||
private static final int CONTENT_WIDTH = INNER_WIDTH - SIDEBAR_WIDTH - DIVIDER_SIZE;
|
||||
|
||||
private record TabDef(String label, Runnable onClick) {}
|
||||
private record SettingRow(String label, FlowLayout control) {}
|
||||
private record QuestData(String title, String description, int requiredPlaytime) {
|
||||
boolean isUnlocked() {
|
||||
return PlaytimeTracker.getCurrentPlaytimeSeconds() >= requiredPlaytime;
|
||||
}
|
||||
}
|
||||
|
||||
private FlowLayout content;
|
||||
private final String initialModule;
|
||||
private static FlowLayout panelRef;
|
||||
|
||||
|
||||
public MyScreen() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public MyScreen(String initialModule) {
|
||||
super(Component.literal("Citrus Dev"));
|
||||
this.initialModule = initialModule;
|
||||
Minecraft.getInstance().getSoundManager().play(
|
||||
SimpleSoundInstance.forUI(SoundEvents.UI_TOAST_IN, 1.5F, 2)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OwoUIAdapter<FlowLayout> createAdapter() {
|
||||
return OwoUIAdapter.create(this, UIContainers::verticalFlow);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void build(FlowLayout rootComponent) {
|
||||
rootComponent.gap(0);
|
||||
rootComponent
|
||||
.horizontalAlignment(HorizontalAlignment.CENTER)
|
||||
.verticalAlignment(VerticalAlignment.CENTER);
|
||||
|
||||
FlowLayout panel = UIContainers.verticalFlow(Sizing.content(), Sizing.content());
|
||||
panelRef = panel;
|
||||
panel.gap(0);
|
||||
panel.padding(Insets.of(2));
|
||||
panel.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
panel.verticalAlignment(VerticalAlignment.CENTER);
|
||||
panel.horizontalSizing(Sizing.fixed(0));
|
||||
panel.verticalSizing(Sizing.fixed(0));
|
||||
panel.horizontalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_WIDTH)).forwards();
|
||||
panel.verticalSizing().animate(300, Easing.CUBIC, Sizing.fixed(PANEL_HEIGHT)).forwards();
|
||||
panel.surface(PANEL_SURFACE);
|
||||
|
||||
FlowLayout navbar = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(NAVBAR_HEIGHT));
|
||||
buildNavbar(navbar);
|
||||
panel.child(navbar);
|
||||
|
||||
FlowLayout navDivider = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(DIVIDER_SIZE));
|
||||
navDivider.surface(Surface.flat(0x80FFFFFF));
|
||||
panel.child(navDivider);
|
||||
|
||||
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(INNER_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
row.gap(0);
|
||||
|
||||
FlowLayout sidebar = buildSidebar();
|
||||
row.child(sidebar);
|
||||
|
||||
content = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
content.gap(2);
|
||||
content.padding(Insets.of(4));
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
row.child(content);
|
||||
|
||||
panel.child(row);
|
||||
|
||||
FlowLayout sidebarDivider = UIContainers.verticalFlow(Sizing.fixed(DIVIDER_SIZE), Sizing.fixed(INNER_HEIGHT));
|
||||
sidebarDivider.surface(Surface.flat(0x80FFFFFF));
|
||||
sidebarDivider.positioning(Positioning.absolute(SIDEBAR_WIDTH, 0));
|
||||
panel.child(sidebarDivider);
|
||||
|
||||
var version = new ScalableLabel(Component.literal("Citrus-Dev v2.0"));
|
||||
version.horizontalTextAlignment(HorizontalAlignment.RIGHT);
|
||||
version.verticalTextAlignment(VerticalAlignment.BOTTOM);
|
||||
version.horizontalSizing(Sizing.fixed(202));
|
||||
version.verticalSizing(Sizing.fixed(12));
|
||||
version.positioning(Positioning.relative(125, 100));
|
||||
version.scale().set(new ScaleValue(0.7f));
|
||||
panel.child(version);
|
||||
|
||||
rootComponent.child(panel);
|
||||
|
||||
if (initialModule != null) {
|
||||
openModuleByKey(initialModule);
|
||||
} else {
|
||||
buildGeneralPanel(content);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildNavbar(FlowLayout navbar) {
|
||||
navbar.horizontalAlignment(HorizontalAlignment.RIGHT);
|
||||
navbar.verticalAlignment(VerticalAlignment.CENTER);
|
||||
navbar.padding(Insets.of(0, 0, 0, 24));
|
||||
navbar.gap(16);
|
||||
navbar.child(UIComponents.texture(
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/citrus-logo.png"),
|
||||
0, 0, 30, 30, 30, 30
|
||||
)).horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
|
||||
List<TabDef> tabs = List.of(
|
||||
new TabDef("general", () -> {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
buildGeneralPanel(content);
|
||||
}),
|
||||
new TabDef("quests", () -> {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
QuestsPanel.build(content, CONTENT_WIDTH, ROW_HEIGHT);
|
||||
}),
|
||||
new TabDef("settings", () -> {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
buildSettingsPanel(content);
|
||||
})
|
||||
);
|
||||
|
||||
for (TabDef tab : tabs) {
|
||||
navbar.child(makeTab(tab.label(), tab.onClick()));
|
||||
}
|
||||
}
|
||||
|
||||
private FlowLayout makeTab(String text, Runnable onClick) {
|
||||
FlowLayout tab = UIContainers.verticalFlow(Sizing.content(), Sizing.content());
|
||||
tab.verticalAlignment(VerticalAlignment.CENTER);
|
||||
tab.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
tab.padding(Insets.of(2, 0, 2, 2));
|
||||
tab.gap(2);
|
||||
|
||||
var label = UIComponents.label(Component.literal(text)
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(0xCCCCCC))
|
||||
.shadow(true);;
|
||||
tab.child(label);
|
||||
|
||||
int underlineWidth = Math.max(text.length() * 6, 10);
|
||||
FlowLayout underline = UIContainers.horizontalFlow(Sizing.fixed(underlineWidth), Sizing.fixed(1));
|
||||
underline.surface(Surface.flat(0x00FFFFFF));
|
||||
tab.child(underline);
|
||||
|
||||
tab.mouseEnter().subscribe(() -> {
|
||||
label.color(Color.ofRgb(0xFFFFFF));
|
||||
underline.surface(Surface.flat(0xFFFFFFFF));
|
||||
});
|
||||
tab.mouseLeave().subscribe(() -> {
|
||||
label.color(Color.ofRgb(0xCCCCCC));
|
||||
underline.surface(Surface.flat(0x00FFFFFF));
|
||||
});
|
||||
|
||||
tab.mouseDown().subscribe((click, doubled) -> {
|
||||
Minecraft.getInstance().getSoundManager().play(
|
||||
SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2)
|
||||
);
|
||||
onClick.run();
|
||||
return true;
|
||||
});
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
private FlowLayout buildSidebar() {
|
||||
FlowLayout sidebar = UIContainers.verticalFlow(Sizing.fixed(SIDEBAR_WIDTH), Sizing.fixed(ROW_HEIGHT));
|
||||
sidebar.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
sidebar.verticalAlignment(VerticalAlignment.TOP);
|
||||
sidebar.padding(Insets.of(4));
|
||||
sidebar.gap(2);
|
||||
|
||||
sidebar.child(makeSidebarButton("-", 430));
|
||||
sidebar.child(makeSidebarButton("+", 400));
|
||||
|
||||
sidebar.child(UIComponents.spacer());
|
||||
|
||||
FlowLayout editButton = UIContainers.verticalFlow(Sizing.fixed(20), Sizing.fixed(20));
|
||||
editButton.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
editButton.verticalAlignment(VerticalAlignment.CENTER);
|
||||
editButton.surface(Surface.flat(0x80FFFFFF).and(Surface.outline(0xFFFFFFFF)));
|
||||
editButton.child(UIComponents.texture(
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/edit.png"),
|
||||
0, 0, 16, 16, 16, 16
|
||||
));
|
||||
|
||||
editButton.mouseEnter().subscribe(() ->
|
||||
editButton.surface(Surface.flat(0xA0FFFFFF).and(Surface.outline(0xFFFFFFFF))));
|
||||
editButton.mouseLeave().subscribe(() ->
|
||||
editButton.surface(Surface.flat(0x80FFFFFF).and(Surface.outline(0xFFFFFFFF))));
|
||||
|
||||
editButton.mouseDown().subscribe((click, doubled) -> {
|
||||
Minecraft.getInstance().getSoundManager().play(
|
||||
SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2)
|
||||
);
|
||||
DraggableHud.setEditMode(true);
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
return true;
|
||||
});
|
||||
|
||||
sidebar.child(editButton);
|
||||
|
||||
return sidebar;
|
||||
}
|
||||
|
||||
private ScalableButton makeSidebarButton(String symbol, int animateDelay) {
|
||||
var button = new ScalableButton(Component.literal(symbol), btn -> {
|
||||
Minecraft.getInstance().getSoundManager().play(
|
||||
SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK.value(), 2.0F, 2)
|
||||
);
|
||||
},
|
||||
0x80FFFFFF,
|
||||
0xA0FFFFFF,
|
||||
0xFFFFFFFF,
|
||||
0xFFFFFFFF,
|
||||
1
|
||||
);
|
||||
button.horizontalSizing(Sizing.fixed(20));
|
||||
button.verticalSizing(Sizing.fixed(20));
|
||||
|
||||
button.scale().set(new ScaleValue(0f));
|
||||
button.scale().animate(animateDelay, Easing.CUBIC, new ScaleValue(1f)).forwards();
|
||||
|
||||
button.mouseEnter().subscribe(() -> button.scale().animate(120, Easing.CUBIC, new ScaleValue(1.1f)).forwards());
|
||||
button.mouseLeave().subscribe(() -> button.scale().animate(120, Easing.CUBIC, new ScaleValue(1.0f)).forwards());
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
private void buildGeneralPanel(FlowLayout content) {
|
||||
|
||||
FlowLayout fpsRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fps.png"),
|
||||
18, 18,
|
||||
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"
|
||||
);
|
||||
|
||||
FlowLayout keyStrokesRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/keystrokes.png"),
|
||||
24, 24,
|
||||
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"
|
||||
);
|
||||
|
||||
FlowLayout coordinatesRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("minecraft", "textures/item/map.png"),
|
||||
18, 18,
|
||||
MC_FIVE,
|
||||
"Coordinates",
|
||||
"Shows your Position",
|
||||
new ModuleRow.ToggleState() {
|
||||
public boolean get() { return Module_Coords.toggle; }
|
||||
public void set(boolean value) {
|
||||
Module_Coords.toggle = value;
|
||||
Config.get().coordsEnabled = value;
|
||||
Config.get().save();
|
||||
}
|
||||
},
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"),
|
||||
() -> {
|
||||
Config.get().lastModule = "Coords";
|
||||
Config.get().save();
|
||||
openModuleSettings("Coords", CoordsSettings());
|
||||
},
|
||||
"Module Enabled", "Keystrokes is now active",
|
||||
"Module Disabled", "Keystrokes is now inactive"
|
||||
);
|
||||
|
||||
FlowLayout fullbrightRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fullbright.png"),
|
||||
18, 18,
|
||||
MC_FIVE,
|
||||
"Fullbright",
|
||||
"Max brightness",
|
||||
new ModuleRow.ToggleState() {
|
||||
public boolean get() { return Module_Fullbright.isEnabled(); }
|
||||
public void set(boolean value) { Module_Fullbright.setEnabled(value); }
|
||||
},
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"),
|
||||
() -> {
|
||||
Config.get().lastModule = "Fullbright";
|
||||
Config.get().save();
|
||||
},
|
||||
"Module Enabled", "Fullbright is now active",
|
||||
"Module Disabled", "Fullbright is now inactive"
|
||||
);
|
||||
|
||||
FlowLayout hitboxRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"),
|
||||
18, 12,
|
||||
MC_FIVE,
|
||||
"hitbox",
|
||||
"Customize hitboxes",
|
||||
new ModuleRow.ToggleState() {
|
||||
public boolean get() { return Module_Hitbox.isEnabled(); }
|
||||
public void set(boolean value) { Module_Hitbox.setEnabled(value); }
|
||||
},
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"),
|
||||
() -> {
|
||||
Config.get().lastModule = "Hitbox";
|
||||
Config.get().save();
|
||||
openModuleSettings("Hitbox", hitboxSettings());
|
||||
},
|
||||
"Module Enabled", "Hitbox color is now active",
|
||||
"Module Disabled", "Hitbox color is now inactive"
|
||||
);
|
||||
|
||||
FlowLayout effectsRow = ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/effect.png"),
|
||||
18, 18,
|
||||
MC_FIVE,
|
||||
"Effects",
|
||||
"Shows active effects",
|
||||
new ModuleRow.ToggleState() {
|
||||
public boolean get() { return Module_Effects.isEnabled(); }
|
||||
public void set(boolean value) { Module_Effects.setEnabled(value); }
|
||||
},
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png"),
|
||||
() -> {
|
||||
Config.get().lastModule = "Effects";
|
||||
Config.get().save();
|
||||
openModuleSettings("Effects", effectsSettings());
|
||||
},
|
||||
"Module Enabled", "Effects display is now active",
|
||||
"Module Disabled", "Effects display is now inactive"
|
||||
);
|
||||
|
||||
FlowLayout rowsContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
rowsContainer.gap(4);
|
||||
rowsContainer.verticalAlignment(VerticalAlignment.TOP);
|
||||
rowsContainer.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
|
||||
rowsContainer.child(effectsRow);
|
||||
rowsContainer.child(hitboxRow);
|
||||
rowsContainer.child(coordinatesRow);
|
||||
rowsContainer.child(keyStrokesRow);
|
||||
rowsContainer.child(fpsRow);
|
||||
rowsContainer.child(fullbrightRow);
|
||||
|
||||
var scrollArea = UIContainers.verticalScroll(
|
||||
Sizing.fixed(CONTENT_WIDTH - 8),
|
||||
Sizing.fixed(ROW_HEIGHT- 8),
|
||||
rowsContainer
|
||||
);
|
||||
|
||||
content.child(scrollArea);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void buildSettingsPanel(FlowLayout content) {
|
||||
FlowLayout rowsContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
rowsContainer.gap(8);
|
||||
rowsContainer.verticalAlignment(VerticalAlignment.TOP);
|
||||
rowsContainer.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
rowsContainer.padding(Insets.of(0));
|
||||
|
||||
FlowLayout blurSlider = SettingsControls.makeSlider(
|
||||
FLAT,
|
||||
80,
|
||||
0.0, 15.0,
|
||||
Config.get().panelBlur,
|
||||
value -> (int) value + "px",
|
||||
value -> {
|
||||
Config.get().panelBlur = (float) (double) value;
|
||||
Config.get().save();
|
||||
rebuildSurfaces();
|
||||
}
|
||||
);
|
||||
|
||||
FlowLayout blurRow = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16));
|
||||
blurRow.verticalAlignment(VerticalAlignment.CENTER);
|
||||
blurRow.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
blurRow.padding(Insets.of(0));
|
||||
blurRow.gap(4);
|
||||
blurRow.child(UIComponents.label(Component.literal("Panel Blur")
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(0xFF5c5c66)));
|
||||
blurRow.child(UIComponents.spacer());
|
||||
blurRow.child(blurSlider);
|
||||
rowsContainer.child(blurRow);
|
||||
|
||||
content.child(rowsContainer);
|
||||
}
|
||||
|
||||
private void openModuleSettings(String title, List<SettingRow> rows) {
|
||||
content.clearChildren();
|
||||
|
||||
content.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
|
||||
FlowLayout header = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
header.verticalAlignment(VerticalAlignment.CENTER);
|
||||
header.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
header.gap(4);
|
||||
|
||||
header.child(SettingsControls.makeTextButton(FLAT, "<", () -> {
|
||||
content.clearChildren();
|
||||
content.horizontalAlignment(HorizontalAlignment.CENTER);
|
||||
content.verticalAlignment(VerticalAlignment.TOP);
|
||||
buildGeneralPanel(content);
|
||||
}));
|
||||
|
||||
header.child(UIComponents.label(Component.literal(title)
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(0x80FFFFFF)));
|
||||
|
||||
content.child(header);
|
||||
|
||||
FlowLayout rowsContainer = UIContainers.verticalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.content());
|
||||
rowsContainer.gap(1);
|
||||
rowsContainer.verticalAlignment(VerticalAlignment.TOP);
|
||||
rowsContainer.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
rowsContainer.padding(Insets.of(0));
|
||||
|
||||
for (SettingRow row : rows) {
|
||||
FlowLayout settingRow = makeSettingRow(row);
|
||||
settingRow.verticalSizing(Sizing.fixed(16));
|
||||
rowsContainer.child(settingRow);
|
||||
}
|
||||
|
||||
var scrollArea = UIContainers.verticalScroll(
|
||||
Sizing.fixed(CONTENT_WIDTH - 8),
|
||||
Sizing.fixed(ROW_HEIGHT - 24),
|
||||
rowsContainer
|
||||
);
|
||||
content.child(scrollArea);
|
||||
}
|
||||
|
||||
private void openModuleByKey(String key) {
|
||||
switch (key) {
|
||||
case "FPS" -> openModuleSettings("FPS", fpsModuleSettings());
|
||||
case "Key" -> openModuleSettings("Keystrokes", keyStrokesSettings());
|
||||
case "Coords" -> openModuleSettings("Coordinates", CoordsSettings());
|
||||
case "Hitbox" -> openModuleSettings("Hitbox", hitboxSettings());
|
||||
case "Effects" -> openModuleSettings("Effects", effectsSettings());
|
||||
default -> buildGeneralPanel(content);
|
||||
}
|
||||
}
|
||||
|
||||
private FlowLayout makeSettingRow(SettingRow setting) {
|
||||
FlowLayout row = UIContainers.horizontalFlow(Sizing.fixed(CONTENT_WIDTH - 8), Sizing.fixed(16));
|
||||
row.verticalAlignment(VerticalAlignment.CENTER);
|
||||
row.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
row.padding(Insets.of(0));
|
||||
row.gap(4);
|
||||
|
||||
row.child(UIComponents.label(Component.literal(setting.label())
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(0xFF5c5c66)));
|
||||
row.child(UIComponents.spacer());
|
||||
row.child(setting.control());
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private List<SettingRow> fpsModuleSettings() {
|
||||
List<SettingsControls.ButtonState> positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_FPS.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_FPS.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_FPS.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_FPS.setPosition(1, 99))
|
||||
);
|
||||
|
||||
FlowLayout paddingSlider = SettingsControls.makeSlider(
|
||||
FLAT,
|
||||
80,
|
||||
0.0, 15.0,
|
||||
Config.get().fpsSize,
|
||||
value -> (int) value + "px",
|
||||
value -> Module_FPS.setFpsPadding((int) value)
|
||||
);
|
||||
|
||||
|
||||
int currentIndex = positionIndex(Config.get().fpsX, Config.get().fpsY);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)),
|
||||
new SettingRow("", SettingsControls.makeSectionHeader(CONTENT_WIDTH - 8, "Display Options")),
|
||||
new SettingRow("Padding", paddingSlider)
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
private List<SettingRow> keyStrokesSettings() {
|
||||
List<SettingsControls.ButtonState> 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,
|
||||
10.0, 30.0,
|
||||
Config.get().keySize,
|
||||
value -> (int) value + "px",
|
||||
value -> Module_KeyStrokes.setKeySize((int) value)
|
||||
);
|
||||
|
||||
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 List<SettingRow> CoordsSettings() {
|
||||
List<SettingsControls.ButtonState> positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_Coords.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_Coords.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_Coords.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Coords.setPosition(1, 99))
|
||||
);
|
||||
|
||||
int currentIndex = positionIndex(Config.get().fpsX, Config.get().fpsY);
|
||||
|
||||
FlowLayout biomeCheckbox = SettingsControls.makeCheckbox(
|
||||
FLAT,
|
||||
GLASS_PANEL,
|
||||
Module_Coords.isBiomeEnabled(),
|
||||
Module_Coords::setBiomeEnabled
|
||||
);
|
||||
|
||||
FlowLayout sizeSlider = SettingsControls.makeSlider(
|
||||
FLAT,
|
||||
80,
|
||||
0.0, 15.0,
|
||||
Config.get().coordsP,
|
||||
value -> (int) value + "px",
|
||||
value -> Module_Coords.setCoordsPadding((int) value)
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)),
|
||||
new SettingRow("Show Biome", biomeCheckbox),
|
||||
new SettingRow("Padding", sizeSlider)
|
||||
);
|
||||
}
|
||||
|
||||
private List<SettingRow> hitboxSettings() {
|
||||
|
||||
FlowLayout enabledCheckbox = SettingsControls.makeCheckbox(
|
||||
FLAT,
|
||||
GLASS_PANEL,
|
||||
Module_Hitbox.isEnabled(),
|
||||
value -> {
|
||||
Module_Hitbox.setEnabled(value);
|
||||
openModuleSettings("Hitbox", hitboxSettings());
|
||||
}
|
||||
);
|
||||
|
||||
List<SettingRow> rows = new java.util.ArrayList<>();
|
||||
rows.add(new SettingRow("Custom Color", enabledCheckbox));
|
||||
|
||||
if (Module_Hitbox.isEnabled()) {
|
||||
FlowLayout hueSlider = SettingsControls.makeSlider(
|
||||
FLAT,
|
||||
80,
|
||||
0.0, 360.0,
|
||||
Module_Hitbox.getHue(),
|
||||
value -> (int) (double) value + "°",
|
||||
value -> Module_Hitbox.setHue((int) (double) value)
|
||||
);
|
||||
rows.add(new SettingRow("Color", hueSlider));
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
private List<SettingRow> effectsSettings() {
|
||||
List<SettingsControls.ButtonState> positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_Effects.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_Effects.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_Effects.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Effects.setPosition(1, 99))
|
||||
);
|
||||
|
||||
int currentIndex = positionIndex(Config.get().effectsX, Config.get().effectsY);
|
||||
|
||||
FlowLayout bgCheck = SettingsControls.makeCheckbox(
|
||||
FLAT,
|
||||
GLASS_PANEL,
|
||||
Module_Effects.isBackgroundEnabled(),
|
||||
Module_Effects::setBackgroundEnabled
|
||||
);
|
||||
|
||||
FlowLayout timerCheck = SettingsControls.makeCheckbox(
|
||||
FLAT,
|
||||
GLASS_PANEL,
|
||||
Module_Effects.isTimerEnabled(),
|
||||
Module_Effects::setTimerEnabled
|
||||
);
|
||||
|
||||
FlowLayout nameCheck = SettingsControls.makeCheckbox(
|
||||
FLAT,
|
||||
GLASS_PANEL,
|
||||
Module_Effects.isNameEnabled(),
|
||||
Module_Effects::setNameEnabled
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, currentIndex)),
|
||||
new SettingRow("Show Background", bgCheck),
|
||||
new SettingRow("Show Timer", timerCheck),
|
||||
new SettingRow("Show Name", nameCheck)
|
||||
);
|
||||
}
|
||||
|
||||
private int positionIndex(int x, int y) {
|
||||
boolean right = x > 50;
|
||||
boolean bottom = y > 50;
|
||||
if (!right && !bottom) return 0;
|
||||
if (right && !bottom) return 1;
|
||||
if (right && bottom) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public class QuestsPanel {
|
||||
statusBar.padding(Insets.of(4));
|
||||
statusBar.verticalAlignment(VerticalAlignment.CENTER);
|
||||
statusBar.horizontalAlignment(HorizontalAlignment.LEFT);
|
||||
statusBar.surface(MyScreen.GLASS_PANEL);
|
||||
statusBar.surface(MainUI.GLASS_PANEL);
|
||||
|
||||
LabelComponent playtimeLabel = UIComponents.label(Component.literal(formatPlaytime(playtime)));
|
||||
playtimeLabel.color(Color.ofRgb(0xFFFFFF));
|
||||
@@ -112,7 +112,7 @@ public class QuestsPanel {
|
||||
|
||||
summaryRow.child(UIComponents.label(
|
||||
Component.literal("quests " + unlockedCount + "/" + quests.size())
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MyScreen.MC_FIVE))))
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MainUI.MC_FIVE))))
|
||||
.color(Color.ofRgb(0xFF5c5c66)));
|
||||
|
||||
content.child(summaryRow);
|
||||
@@ -201,7 +201,7 @@ public class QuestsPanel {
|
||||
textStack.verticalAlignment(VerticalAlignment.TOP);
|
||||
|
||||
var titleLabel = UIComponents.label(Component.literal(quest.title())
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MyScreen.MC_FIVE))))
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MainUI.MC_FIVE))))
|
||||
.color(Color.ofRgb(unlocked ? 0xFFFFFF : 0x797b86));
|
||||
textStack.child(titleLabel);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.fullrisk.citrusDev.UIHelper;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
import io.wispforest.owo.ui.component.UIComponents;
|
||||
import io.wispforest.owo.ui.container.FlowLayout;
|
||||
import io.wispforest.owo.ui.container.UIContainers;
|
||||
@@ -18,6 +19,17 @@ public class ModuleRow {
|
||||
void set(boolean value);
|
||||
}
|
||||
|
||||
private static int titleColor(boolean enabled) {
|
||||
if (Config.get().darkMode) {
|
||||
return enabled ? 0xffffff : 0xFF8a8e96;
|
||||
}
|
||||
return enabled ? 0xffffff : 0xFFaab0b8;
|
||||
}
|
||||
|
||||
private static int descColor() {
|
||||
return Config.get().darkMode ? 0xFFa0a4aa : 0xFF6a6e76;
|
||||
}
|
||||
|
||||
public static FlowLayout build(
|
||||
Surface enabledSurface,
|
||||
Surface disabledSurface,
|
||||
@@ -58,12 +70,12 @@ public class ModuleRow {
|
||||
Component.literal(title)
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(titleFont)))
|
||||
);
|
||||
titleLabel.color(Color.ofRgb(state.get() ? 0xffffff : 0x797b86));
|
||||
titleLabel.color(Color.ofRgb(titleColor(state.get())));
|
||||
textStack.child(titleLabel);
|
||||
|
||||
textStack.child(UIComponents.label(Component.literal(description))
|
||||
.color(Color.ofRgb(0xFF5c5c66))
|
||||
.maxWidth(130));
|
||||
.color(Color.ofRgb(descColor()))
|
||||
.maxWidth(190));
|
||||
|
||||
row.child(textStack);
|
||||
row.child(UIComponents.spacer());
|
||||
@@ -78,7 +90,7 @@ public class ModuleRow {
|
||||
boolean newState = !state.get();
|
||||
state.set(newState);
|
||||
|
||||
titleLabel.color(Color.ofRgb(newState ? 0xffffff : 0x797b86));
|
||||
titleLabel.color(Color.ofRgb(titleColor(newState)));
|
||||
row.surface(newState ? enabledSurface : disabledSurface);
|
||||
|
||||
if (newState) {
|
||||
@@ -93,9 +105,9 @@ public class ModuleRow {
|
||||
return true;
|
||||
});
|
||||
|
||||
row.horizontalSizing().animate(150, Easing.CUBIC, Sizing.fixed(200)).forwards();
|
||||
row.horizontalSizing().animate(150, Easing.CUBIC, Sizing.fixed(260)).forwards();
|
||||
row.verticalSizing().animate(150, Easing.CUBIC, Sizing.fixed(35)).forwards();
|
||||
|
||||
return row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package de.fullrisk.citrusDev.UIHelper;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
import de.fullrisk.citrusDev.UI.*;
|
||||
import io.wispforest.owo.ui.container.FlowLayout;
|
||||
import net.minecraft.resources.Identifier;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static de.fullrisk.citrusDev.UI.MainUI.*;
|
||||
|
||||
public class ModuleRows {
|
||||
|
||||
public record Entry(String name, FlowLayout row) {}
|
||||
|
||||
private static final Identifier SETTINGS_ICON = Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/settings.png");
|
||||
|
||||
public static List<Entry> buildAll(Consumer<String> openSettingsByKey) {
|
||||
return List.of(
|
||||
entry("Effects", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/effect.png"), 18, 18, MC_FIVE,
|
||||
"Effects", "Shows active effects",
|
||||
toggleState(Module_Effects::isEnabled, Module_Effects::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "Effects"; Config.get().save(); openSettingsByKey.accept("Effects"); },
|
||||
"Module Enabled", "Effects display is now active",
|
||||
"Module Disabled", "Effects display is now inactive")),
|
||||
entry("Hitbox", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/block_culling_file.png"), 18, 12, MC_FIVE,
|
||||
"Hitbox", "Customize hitboxes",
|
||||
toggleState(Module_Hitbox::isEnabled, Module_Hitbox::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "Hitbox"; Config.get().save(); openSettingsByKey.accept("Hitbox"); },
|
||||
"Module Enabled", "Hitbox color is now active",
|
||||
"Module Disabled", "Hitbox color is now inactive")),
|
||||
entry("Coordinates", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("minecraft", "textures/item/map.png"), 18, 18, MC_FIVE,
|
||||
"Coordinates", "Shows your Position",
|
||||
toggleState(Module_Coords::isEnabled, Module_Coords::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "Coords"; Config.get().save(); openSettingsByKey.accept("Coords"); },
|
||||
"Module Enabled", "Coordinates is now active",
|
||||
"Module Disabled", "Coordinates is now inactive")),
|
||||
entry("Keystrokes", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/keystrokes.png"), 24, 24, MC_FIVE,
|
||||
"Keystrokes", "Current Key Presses",
|
||||
toggleState(Module_KeyStrokes::isEnabled, Module_KeyStrokes::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "Key"; Config.get().save(); openSettingsByKey.accept("Key"); },
|
||||
"Module Enabled", "Keystrokes is now active",
|
||||
"Module Disabled", "KeyStrokes is now inactive")),
|
||||
entry("FPS", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fps.png"), 18, 18, MC_FIVE,
|
||||
"FPS", "Displays your FPS",
|
||||
toggleState(Module_FPS::isEnabled, Module_FPS::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "FPS"; Config.get().save(); openSettingsByKey.accept("FPS"); },
|
||||
"Module Enabled", "FPS counter is now active",
|
||||
"Module Disabled", "FPS counter is now inactive")),
|
||||
entry("Fullbright", ModuleRow.build(
|
||||
GLASS_PANEL, DISABLED, FLAT,
|
||||
Identifier.fromNamespaceAndPath("citrus-dev", "textures/icons/fullbright.png"), 18, 18, MC_FIVE,
|
||||
"Fullbright", "Max brightness",
|
||||
toggleState(Module_Fullbright::isEnabled, Module_Fullbright::setEnabled),
|
||||
SETTINGS_ICON, () -> { Config.get().lastModule = "Fullbright"; Config.get().save(); },
|
||||
"Module Enabled", "Fullbright is now active",
|
||||
"Module Disabled", "Fullbright is now inactive"))
|
||||
);
|
||||
}
|
||||
|
||||
private static Entry entry(String name, FlowLayout row) {
|
||||
return new Entry(name, row);
|
||||
}
|
||||
|
||||
private static ModuleRow.ToggleState toggleState(java.util.function.BooleanSupplier get, java.util.function.Consumer<Boolean> set) {
|
||||
return new ModuleRow.ToggleState() {
|
||||
public boolean get() { return get.getAsBoolean(); }
|
||||
public void set(boolean value) { set.accept(value); }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package de.fullrisk.citrusDev.UIHelper;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
import de.fullrisk.citrusDev.UI.Module_Coords;
|
||||
import de.fullrisk.citrusDev.UI.Module_Effects;
|
||||
import de.fullrisk.citrusDev.UI.Module_FPS;
|
||||
import de.fullrisk.citrusDev.UI.Module_Hitbox;
|
||||
import de.fullrisk.citrusDev.UI.Module_KeyStrokes;
|
||||
import io.wispforest.owo.ui.container.FlowLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static de.fullrisk.citrusDev.UI.MainUI.*;
|
||||
|
||||
public class ModuleSettings {
|
||||
|
||||
public record SettingRow(String label, FlowLayout control) {}
|
||||
|
||||
public static int positionIndex(int x, int y) {
|
||||
boolean right = x > 50;
|
||||
boolean bottom = y > 50;
|
||||
if (!right && !bottom) return 0;
|
||||
if (right && !bottom) return 1;
|
||||
if (right && bottom) return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
public static List<SettingRow> fps() {
|
||||
var positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_FPS.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_FPS.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_FPS.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_FPS.setPosition(1, 99))
|
||||
);
|
||||
|
||||
FlowLayout paddingSlider = SettingsControls.makeSlider(
|
||||
FLAT, 80, 0.0, 15.0, Config.get().fpsSize,
|
||||
value -> (int) value + "px",
|
||||
value -> Module_FPS.setFpsPadding((int) value)
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, positionIndex(Config.get().fpsX, Config.get().fpsY))),
|
||||
new SettingRow("", SettingsControls.makeSectionHeader(CONTENT_WIDTH - 8, "Display Options")),
|
||||
new SettingRow("Padding", paddingSlider)
|
||||
);
|
||||
}
|
||||
|
||||
public static List<SettingRow> keystrokes() {
|
||||
var 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, 10.0, 30.0, Config.get().keySize,
|
||||
value -> (int) value + "px",
|
||||
value -> Module_KeyStrokes.setKeySize((int) value)
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, positionIndex(Config.get().keyX, Config.get().keyY))),
|
||||
new SettingRow("Size", sizeSlider)
|
||||
);
|
||||
}
|
||||
|
||||
public static List<SettingRow> coords() {
|
||||
var positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_Coords.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_Coords.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_Coords.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Coords.setPosition(1, 99))
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, positionIndex(Config.get().fpsX, Config.get().fpsY))),
|
||||
new SettingRow("Show Biome", SettingsControls.makeCheckbox(FLAT, GLASS_PANEL, Module_Coords.isBiomeEnabled(), Module_Coords::setBiomeEnabled)),
|
||||
new SettingRow("Padding", SettingsControls.makeSlider(FLAT, 80, 0.0, 15.0, Config.get().coordsP, value -> (int) value + "px", value -> Module_Coords.setCoordsPadding((int) value)))
|
||||
);
|
||||
}
|
||||
|
||||
public static List<SettingRow> hitbox(Consumer<String> reopenSettings) {
|
||||
List<SettingRow> rows = new ArrayList<>();
|
||||
rows.add(new SettingRow("Custom Color", SettingsControls.makeCheckbox(
|
||||
FLAT, GLASS_PANEL, Module_Hitbox.isEnabled(),
|
||||
value -> { Module_Hitbox.setEnabled(value); reopenSettings.accept("Hitbox"); }
|
||||
)));
|
||||
if (Module_Hitbox.isEnabled()) {
|
||||
rows.add(new SettingRow("Color", SettingsControls.makeSlider(
|
||||
FLAT, 80, 0.0, 360.0, Module_Hitbox.getHue(),
|
||||
value -> (int) (double) value + "\u00B0",
|
||||
value -> Module_Hitbox.setHue((int) (double) value)
|
||||
)));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
public static List<SettingRow> effects() {
|
||||
var positionStates = List.of(
|
||||
new SettingsControls.ButtonState("L-TOP", () -> Module_Effects.setPosition(1, 1)),
|
||||
new SettingsControls.ButtonState("R-TOP", () -> Module_Effects.setPosition(99, 1)),
|
||||
new SettingsControls.ButtonState("R-BOTTOM", () -> Module_Effects.setPosition(99, 99)),
|
||||
new SettingsControls.ButtonState("L-BOTTOM", () -> Module_Effects.setPosition(1, 99))
|
||||
);
|
||||
|
||||
return List.of(
|
||||
new SettingRow("Position", SettingsControls.makeCyclingButton(GLASS_PANEL, positionStates, positionIndex(Config.get().effectsX, Config.get().effectsY))),
|
||||
new SettingRow("Show Background", SettingsControls.makeCheckbox(FLAT, GLASS_PANEL, Module_Effects.isBackgroundEnabled(), Module_Effects::setBackgroundEnabled)),
|
||||
new SettingRow("Show Timer", SettingsControls.makeCheckbox(FLAT, GLASS_PANEL, Module_Effects.isTimerEnabled(), Module_Effects::setTimerEnabled)),
|
||||
new SettingRow("Show Name", SettingsControls.makeCheckbox(FLAT, GLASS_PANEL, Module_Effects.isNameEnabled(), Module_Effects::setNameEnabled))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import net.minecraft.network.chat.FontDescription;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
|
||||
import de.fullrisk.citrusDev.Config;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.DoubleConsumer;
|
||||
import java.util.function.DoubleFunction;
|
||||
@@ -21,9 +23,9 @@ public class SettingsControls {
|
||||
|
||||
private static final Identifier MC_FIVE = Identifier.fromNamespaceAndPath("citrus-dev", "minecraft_five");
|
||||
|
||||
private static final Surface GLASS_PANEL = Surface.blur(5f, 15f)
|
||||
.and(Surface.flat(0x40FFFFFF))
|
||||
.and(Surface.outline(0x64de4b));
|
||||
private static int secColor() {
|
||||
return Config.get().darkMode ? 0xFFd0d4da : 0xFFb0b6c0;
|
||||
}
|
||||
|
||||
public record ButtonState(String label, Runnable onSelect) {}
|
||||
|
||||
@@ -106,7 +108,7 @@ public class SettingsControls {
|
||||
return true;
|
||||
});
|
||||
button.mouseEnter().subscribe(() -> label.color(Color.ofRgb(0xFFFFFF)));
|
||||
button.mouseLeave().subscribe(() -> label.color(Color.ofRgb(0xCCCCCC)));
|
||||
button.mouseLeave().subscribe(() -> label.color(Color.ofRgb(0xDDDDDD)));
|
||||
|
||||
return button;
|
||||
}
|
||||
@@ -198,7 +200,7 @@ public class SettingsControls {
|
||||
|
||||
var label = UIComponents.label(Component.literal(text.toUpperCase())
|
||||
.withStyle(style -> style.withFont(new FontDescription.Resource(MC_FIVE))))
|
||||
.color(Color.ofRgb(0xFF5c5c66));
|
||||
.color(Color.ofRgb(secColor()));
|
||||
row.child(label);
|
||||
|
||||
FlowLayout longLine = UIContainers.horizontalFlow(Sizing.fill(100), Sizing.fixed(1));
|
||||
|
||||
@@ -71,9 +71,9 @@ public class CitrusDevClient implements ClientModInitializer {
|
||||
while (openScreenKey.consumeClick()) {
|
||||
if (client.player != null && client.player.isShiftKeyDown()) {
|
||||
String lastModule = Config.get().lastModule;
|
||||
client.setScreen(new MyScreen(lastModule));
|
||||
client.setScreen(new MainUI(lastModule));
|
||||
} else {
|
||||
client.setScreen(new MyScreen(null));
|
||||
client.setScreen(new MainUI(null));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user