Changed namespace

This commit is contained in:
Frank 2022-10-29 13:07:44 +02:00
parent 47756e7ebf
commit 01c59be6ae
62 changed files with 107 additions and 4332 deletions

@ -1 +1 @@
Subproject commit 4638cbf4cab6a900cf9969eb353d51b33236eaee Subproject commit 782c5a63e67cb7eb9d31f63a2ddec77b044d2541

View file

@ -6,14 +6,15 @@ import org.betterx.bclib.config.Configs;
import org.betterx.bclib.config.NamedPathConfig; import org.betterx.bclib.config.NamedPathConfig;
import org.betterx.bclib.config.NamedPathConfig.ConfigTokenDescription; import org.betterx.bclib.config.NamedPathConfig.ConfigTokenDescription;
import org.betterx.bclib.config.NamedPathConfig.DependendConfigToken; import org.betterx.bclib.config.NamedPathConfig.DependendConfigToken;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.vanilla.LayoutScreenWithIcon;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import org.wunder.lib.ui.layout.components.*;
import org.wunder.lib.ui.vanilla.LayoutScreenWithIcon;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;

View file

@ -1,10 +1,6 @@
package org.betterx.bclib.client.gui.modmenu; package org.betterx.bclib.client.gui.modmenu;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.vanilla.LayoutScreen;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -12,6 +8,11 @@ import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.*;
import org.wunder.lib.ui.layout.values.Size;
import org.wunder.lib.ui.vanilla.LayoutScreen;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class TestScreen extends LayoutScreen { public class TestScreen extends LayoutScreen {
public TestScreen(Component component) { public TestScreen(Component component) {
@ -77,17 +78,17 @@ public class TestScreen extends LayoutScreen {
VerticalScroll.create(page2) VerticalScroll.create(page2)
)); ));
rows.add(new Input(fitOrFill(), fit(), Component.literal("Input"), "0xff00ff")); rows.add(new Input(fitOrFill(), fit(), Component.literal("Input"), "0xff00ff"));
rows.add(new ColorSwatch(fit(), fit(), ColorUtil.LIGHT_PURPLE).centerHorizontal()); rows.add(new ColorSwatch(fit(), fit(), ColorHelper.LIGHT_PURPLE).centerHorizontal());
rows.add(new ColorPicker( rows.add(new ColorPicker(
fill(), fill(),
fit(), fit(),
Component.literal("Color"), Component.literal("Color"),
ColorUtil.GREEN ColorHelper.GREEN
).centerHorizontal()); ).centerHorizontal());
rows.add(new Text( rows.add(new Text(
fitOrFill(), fixed(20), fitOrFill(), fixed(20),
Component.literal("Some blue text") Component.literal("Some blue text")
).centerHorizontal().setColor(ColorUtil.BLUE) ).centerHorizontal().setColor(ColorHelper.BLUE)
); );
rows.addHLine(fixed(32), fixed(16)); rows.addHLine(fixed(32), fixed(16));
rows.add(c); rows.add(c);
@ -110,7 +111,7 @@ public class TestScreen extends LayoutScreen {
fill(), fit(), fill(), fit(),
Component.literal( Component.literal(
"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.") "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.")
).setColor(ColorUtil.LIGHT_PURPLE).centerHorizontal() ).setColor(ColorHelper.LIGHT_PURPLE).centerHorizontal()
); );
rows.addHorizontalLine(16); rows.addHorizontalLine(16);

View file

@ -1,12 +1,13 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.ui.vanilla.LayoutScreenWithIcon;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import org.wunder.lib.ui.vanilla.LayoutScreenWithIcon;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public abstract class BCLibLayoutScreen extends LayoutScreenWithIcon { public abstract class BCLibLayoutScreen extends LayoutScreenWithIcon {

View file

@ -1,11 +1,6 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.ui.layout.components.Checkbox;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -13,6 +8,11 @@ import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.layout.components.Checkbox;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)

View file

@ -1,15 +1,15 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import org.betterx.ui.layout.values.Value;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
import org.wunder.lib.ui.layout.values.Value;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class ConfirmRestartScreen extends BCLibLayoutScreen { public class ConfirmRestartScreen extends BCLibLayoutScreen {

View file

@ -1,10 +1,5 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
@ -12,6 +7,11 @@ import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class LevelFixErrorScreen extends BCLibLayoutScreen { public class LevelFixErrorScreen extends BCLibLayoutScreen {
private final String[] errors; private final String[] errors;
@ -43,7 +43,7 @@ public class LevelFixErrorScreen extends BCLibLayoutScreen {
row.addText(fit(), fit(), dash); row.addText(fit(), fit(), dash);
row.addSpacer(4); row.addSpacer(4);
row.addText(fit(), fit(), Component.literal(error)).setColor(ColorUtil.RED); row.addText(fit(), fit(), Component.literal(error)).setColor(ColorHelper.RED);
} }
grid.addSpacer(8); grid.addSpacer(8);

View file

@ -2,11 +2,6 @@ package org.betterx.bclib.client.gui.screens;
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient; import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
import org.betterx.bclib.util.Triple; import org.betterx.bclib.util.Triple;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.Text;
import org.betterx.ui.layout.components.VerticalStack;
import org.betterx.worlds.together.util.ModUtil; import org.betterx.worlds.together.util.ModUtil;
import org.betterx.worlds.together.util.PathUtil; import org.betterx.worlds.together.util.PathUtil;
@ -18,6 +13,12 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.metadata.ModEnvironment; import net.fabricmc.loader.api.metadata.ModEnvironment;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.Text;
import org.wunder.lib.ui.layout.components.VerticalStack;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -196,29 +197,29 @@ public class ModListScreen extends BCLibLayoutScreen {
final int state = t.second; final int state = t.second;
final String stateString = t.third; final String stateString = t.third;
int color = ColorUtil.RED; int color = ColorHelper.RED;
final String typeText; final String typeText;
if (state == STATE_VERSION || state == STATE_VERSION_NOT_OFFERED || state == STATE_VERSION_CLIENT_ONLY) { if (state == STATE_VERSION || state == STATE_VERSION_NOT_OFFERED || state == STATE_VERSION_CLIENT_ONLY) {
typeText = "[VERSION]"; typeText = "[VERSION]";
if (state == STATE_VERSION_NOT_OFFERED) { if (state == STATE_VERSION_NOT_OFFERED) {
color = ColorUtil.YELLOW; color = ColorHelper.YELLOW;
} else if (state == STATE_VERSION_CLIENT_ONLY) { } else if (state == STATE_VERSION_CLIENT_ONLY) {
color = ColorUtil.DARK_GREEN; color = ColorHelper.DARK_GREEN;
} }
} else if (state == STATE_MISSING || state == STATE_MISSING_NOT_OFFERED) { } else if (state == STATE_MISSING || state == STATE_MISSING_NOT_OFFERED) {
typeText = "[MISSING]"; typeText = "[MISSING]";
if (state == STATE_MISSING_NOT_OFFERED) { if (state == STATE_MISSING_NOT_OFFERED) {
color = ColorUtil.YELLOW; color = ColorHelper.YELLOW;
} }
} else if (state == STATE_SERVER_MISSING || state == STATE_SERVER_MISSING_CLIENT_MOD) { } else if (state == STATE_SERVER_MISSING || state == STATE_SERVER_MISSING_CLIENT_MOD) {
if (state == STATE_SERVER_MISSING_CLIENT_MOD) { if (state == STATE_SERVER_MISSING_CLIENT_MOD) {
color = ColorUtil.AQUA; color = ColorHelper.AQUA;
typeText = "[OK]"; typeText = "[OK]";
} else { } else {
typeText = "[NOT ON SERVER]"; typeText = "[NOT ON SERVER]";
} }
} else { } else {
color = ColorUtil.DARK_GREEN; color = ColorHelper.DARK_GREEN;
typeText = "[OK]"; typeText = "[OK]";
} }
Component dash = Component.literal("-"); Component dash = Component.literal("-");
@ -237,7 +238,7 @@ public class ModListScreen extends BCLibLayoutScreen {
row = grid.addRow(); row = grid.addRow();
row.addSpacer(4 + dashText.getContentWidth()); row.addSpacer(4 + dashText.getContentWidth());
row.addText(fit(), fit(), Component.literal(stateString)) row.addText(fit(), fit(), Component.literal(stateString))
.setColor(ColorUtil.GRAY); .setColor(ColorHelper.GRAY);
} }
grid.addSpacer(4); grid.addSpacer(4);

View file

@ -1,11 +1,6 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.LayoutScreen;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
@ -17,6 +12,12 @@ import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ProgressListener; import net.minecraft.util.ProgressListener;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.*;
import org.wunder.lib.ui.layout.values.Rectangle;
import org.wunder.lib.ui.layout.values.Value;
import org.wunder.lib.ui.vanilla.LayoutScreen;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -217,7 +218,7 @@ public class ProgressScreen extends LayoutScreen implements ProgressListener, At
VerticalStack textCol = contentRow.addColumn(fit(), fit()).setDebugName("textCol").centerVertical(); VerticalStack textCol = contentRow.addColumn(fit(), fit()).setDebugName("textCol").centerVertical();
textCol.addText(fit(), fit(), description); textCol.addText(fit(), fit(), description);
textCol.addSpacer(4); textCol.addSpacer(4);
progress = textCol.addText(fit(), fit(), getProgressComponent()).setColor(ColorUtil.GRAY); progress = textCol.addText(fit(), fit(), getProgressComponent()).setColor(ColorHelper.GRAY);
grid.addSpacer(20); grid.addSpacer(20);

View file

@ -1,10 +1,6 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient; import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
import org.betterx.ui.layout.components.Checkbox;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import org.betterx.worlds.together.util.ModUtil; import org.betterx.worlds.together.util.ModUtil;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -14,6 +10,11 @@ import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.layout.components.Checkbox;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class SyncFilesScreen extends BCLibLayoutScreen { public class SyncFilesScreen extends BCLibLayoutScreen {
private final Component description; private final Component description;

View file

@ -3,12 +3,6 @@ package org.betterx.bclib.client.gui.screens;
import org.betterx.bclib.BCLib; import org.betterx.bclib.BCLib;
import org.betterx.bclib.config.Configs; import org.betterx.bclib.config.Configs;
import org.betterx.bclib.networking.VersionChecker; import org.betterx.bclib.networking.VersionChecker;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent; import net.minecraft.client.gui.GuiComponent;
@ -24,6 +18,13 @@ import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.metadata.CustomValue; import net.fabricmc.loader.api.metadata.CustomValue;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
import org.wunder.lib.ui.layout.values.Size;
import org.wunder.lib.ui.layout.values.Value;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class UpdatesScreen extends BCLibLayoutScreen { public class UpdatesScreen extends BCLibLayoutScreen {
public static final String DONATION_URL = "https://www.buymeacoffee.com/quiqueck"; public static final String DONATION_URL = "https://www.buymeacoffee.com/quiqueck";
@ -71,14 +72,14 @@ public class UpdatesScreen extends BCLibLayoutScreen {
} }
if (nfo != null) { if (nfo != null) {
row.addText(fit(), fit(), Component.literal(nfo.getMetadata().getName())) row.addText(fit(), fit(), Component.literal(nfo.getMetadata().getName()))
.setColor(ColorUtil.WHITE); .setColor(ColorHelper.WHITE);
} else { } else {
row.addText(fit(), fit(), Component.literal(mod)).setColor(ColorUtil.WHITE); row.addText(fit(), fit(), Component.literal(mod)).setColor(ColorHelper.WHITE);
} }
row.addSpacer(4); row.addSpacer(4);
row.addText(fit(), fit(), Component.literal(cur)); row.addText(fit(), fit(), Component.literal(cur));
row.addText(fit(), fit(), Component.literal(" -> ")); row.addText(fit(), fit(), Component.literal(" -> "));
row.addText(fit(), fit(), Component.literal(updated)).setColor(ColorUtil.GREEN); row.addText(fit(), fit(), Component.literal(updated)).setColor(ColorHelper.GREEN);
row.addFiller(); row.addFiller();
if (nfo != null && nfo.getMetadata().getContact().get("homepage").isPresent()) { if (nfo != null && nfo.getMetadata().getContact().get("homepage").isPresent()) {
row.addButton(fit(), fit(), Component.translatable("bclib.updates.curseforge_link")) row.addButton(fit(), fit(), Component.translatable("bclib.updates.curseforge_link"))
@ -99,7 +100,7 @@ public class UpdatesScreen extends BCLibLayoutScreen {
footer.addButton( footer.addButton(
fit(), fit(),
fit(), fit(),
Component.translatable("bclib.updates.donate").setStyle(Style.EMPTY.withColor(ColorUtil.YELLOW)) Component.translatable("bclib.updates.donate").setStyle(Style.EMPTY.withColor(ColorHelper.YELLOW))
) )
.onPress((bt) -> openLink(DONATION_URL)); .onPress((bt) -> openLink(DONATION_URL));
footer.addSpacer(2); footer.addSpacer(2);

View file

@ -1,15 +1,15 @@
package org.betterx.bclib.client.gui.screens; package org.betterx.bclib.client.gui.screens;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.components.VerticalStack;
import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.layout.components.HorizontalStack;
import org.wunder.lib.ui.layout.components.LayoutComponent;
import org.wunder.lib.ui.layout.components.VerticalStack;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class WarnBCLibVersionMismatch extends BCLibLayoutScreen { public class WarnBCLibVersionMismatch extends BCLibLayoutScreen {
private final Component description; private final Component description;

View file

@ -4,9 +4,6 @@ import org.betterx.bclib.BCLib;
import org.betterx.bclib.config.Configs; import org.betterx.bclib.config.Configs;
import org.betterx.bclib.networking.VersionChecker; import org.betterx.bclib.networking.VersionChecker;
import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.bclib.registry.PresetsRegistry;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Size;
import org.betterx.worlds.together.WorldsTogether; import org.betterx.worlds.together.WorldsTogether;
import org.betterx.worlds.together.worldPreset.WorldPresets; import org.betterx.worlds.together.worldPreset.WorldPresets;
@ -18,6 +15,10 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style; import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import org.wunder.lib.ui.ColorHelper;
import org.wunder.lib.ui.layout.components.*;
import org.wunder.lib.ui.layout.values.Size;
public class WelcomeScreen extends BCLibLayoutScreen { public class WelcomeScreen extends BCLibLayoutScreen {
static final ResourceLocation BETTERX_LOCATION = new ResourceLocation(BCLib.MOD_ID, "betterx.png"); static final ResourceLocation BETTERX_LOCATION = new ResourceLocation(BCLib.MOD_ID, "betterx.png");
static final ResourceLocation BACKGROUND = new ResourceLocation(BCLib.MOD_ID, "header.jpg"); static final ResourceLocation BACKGROUND = new ResourceLocation(BCLib.MOD_ID, "header.jpg");
@ -33,12 +34,12 @@ public class WelcomeScreen extends BCLibLayoutScreen {
VerticalStack content = new VerticalStack(fill(), fit()).setDebugName("content"); VerticalStack content = new VerticalStack(fill(), fit()).setDebugName("content");
content.addImage(fill(), fit(), BACKGROUND, new Size(427, 100)); content.addImage(fill(), fit(), BACKGROUND, new Size(427, 100));
content.addHorizontalLine(1).setColor(ColorUtil.BLACK); content.addHorizontalLine(1).setColor(ColorHelper.BLACK);
content.addSpacer(16); content.addSpacer(16);
HorizontalStack headerRow = content.addRow(fit(), fit()).setDebugName("title bar").centerHorizontal(); HorizontalStack headerRow = content.addRow(fit(), fit()).setDebugName("title bar").centerHorizontal();
headerRow.addIcon(icon, Size.of(512)).setDebugName("icon"); headerRow.addIcon(icon, Size.of(512)).setDebugName("icon");
headerRow.addSpacer(4); headerRow.addSpacer(4);
headerRow.addText(fit(), fit(), title).centerHorizontal().setColor(ColorUtil.WHITE).setDebugName("title"); headerRow.addText(fit(), fit(), title).centerHorizontal().setColor(ColorHelper.WHITE).setDebugName("title");
headerRow.addImage(fixed(178 / 2), fixed(40 / 2), BETTERX_LOCATION, Size.of(178, 40)).setDebugName("betterx"); headerRow.addImage(fixed(178 / 2), fixed(40 / 2), BETTERX_LOCATION, Size.of(178, 40)).setDebugName("betterx");
content.addSpacer(16); content.addSpacer(16);
@ -61,7 +62,7 @@ public class WelcomeScreen extends BCLibLayoutScreen {
donationRow.addSpacer(4); donationRow.addSpacer(4);
donationRow.addButton( donationRow.addButton(
fit(), fit(), fit(), fit(),
Component.translatable("bclib.updates.donate").setStyle(Style.EMPTY.withColor(ColorUtil.YELLOW)) Component.translatable("bclib.updates.donate").setStyle(Style.EMPTY.withColor(ColorHelper.YELLOW))
) )
.onPress((bt) -> openLink(UpdatesScreen.DONATION_URL)).centerVertical(); .onPress((bt) -> openLink(UpdatesScreen.DONATION_URL)).centerVertical();
} }
@ -81,7 +82,7 @@ public class WelcomeScreen extends BCLibLayoutScreen {
innerContent.addSpacer(2); innerContent.addSpacer(2);
HorizontalStack dscBox = innerContent.indent(24); HorizontalStack dscBox = innerContent.indent(24);
dscBox.addMultilineText(fill(), fit(), translatable("description.config.bclib.client.version.check")) dscBox.addMultilineText(fill(), fit(), translatable("description.config.bclib.client.version.check"))
.setColor(ColorUtil.GRAY); .setColor(ColorHelper.GRAY);
dscBox.addSpacer(8); dscBox.addSpacer(8);
// Hide Experimental Dialog // Hide Experimental Dialog
@ -102,7 +103,7 @@ public class WelcomeScreen extends BCLibLayoutScreen {
fit(), fit(),
translatable("description.config.bclib.client.ui.suppressExperimentalDialogOnLoad") translatable("description.config.bclib.client.ui.suppressExperimentalDialogOnLoad")
) )
.setColor(ColorUtil.GRAY); .setColor(ColorHelper.GRAY);
dscBox.addSpacer(8); dscBox.addSpacer(8);
// Use BetterX WorldType // Use BetterX WorldType
@ -123,16 +124,16 @@ public class WelcomeScreen extends BCLibLayoutScreen {
translatable("warning.config.bclib.client.ui.forceBetterXPreset") translatable("warning.config.bclib.client.ui.forceBetterXPreset")
.setStyle(Style.EMPTY .setStyle(Style.EMPTY
.withBold(true) .withBold(true)
.withColor(ColorUtil.RED) .withColor(ColorHelper.RED)
) )
.append(translatable( .append(translatable(
"description.config.bclib.client.ui.forceBetterXPreset").setStyle( "description.config.bclib.client.ui.forceBetterXPreset").setStyle(
Style.EMPTY Style.EMPTY
.withBold(false) .withBold(false)
.withColor(ColorUtil.GRAY)) .withColor(ColorHelper.GRAY))
) )
) )
.setColor(ColorUtil.GRAY); .setColor(ColorHelper.GRAY);
dscBox.addSpacer(8); dscBox.addSpacer(8);
innerContent.addSpacer(16); innerContent.addSpacer(16);

View file

@ -6,11 +6,6 @@ import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig; import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil; import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.bclib.registry.PresetsRegistry;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.vanilla.LayoutScreen;
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset; import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
import org.betterx.worlds.together.worldPreset.WorldGenSettingsComponentAccessor; import org.betterx.worlds.together.worldPreset.WorldGenSettingsComponentAccessor;
@ -32,6 +27,12 @@ import net.minecraft.world.level.levelgen.presets.WorldPresets;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import org.wunder.lib.ui.layout.components.*;
import org.wunder.lib.ui.layout.components.render.RenderHelper;
import org.wunder.lib.ui.layout.values.Rectangle;
import org.wunder.lib.ui.layout.values.Size;
import org.wunder.lib.ui.vanilla.LayoutScreen;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View file

@ -1,5 +1,6 @@
package org.betterx.bclib.util; package org.betterx.bclib.util;
import org.betterx.ui.ColorUtil; import org.betterx.ui.ColorUtil;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -5,7 +5,6 @@ import org.betterx.bclib.util.ColorExtractor;
import org.betterx.bclib.util.MHelper; import org.betterx.bclib.util.MHelper;
import com.mojang.blaze3d.platform.NativeImage; import com.mojang.blaze3d.platform.NativeImage;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -18,6 +17,7 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.wunder.lib.ui.ColorHelper;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,23 +25,23 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class ColorUtil { public class ColorUtil {
public static final int BLACK = ChatFormatting.BLACK.getColor() | 0xFF000000; public static final int BLACK = ColorHelper.BLACK;
public static final int DARK_BLUE = ChatFormatting.DARK_BLUE.getColor() | 0xFF000000; public static final int DARK_BLUE = ColorHelper.DARK_BLUE;
public static final int DARK_GREEN = ChatFormatting.DARK_GREEN.getColor() | 0xFF000000; public static final int DARK_GREEN = ColorHelper.DARK_GREEN;
public static final int DARK_AQUA = ChatFormatting.DARK_AQUA.getColor() | 0xFF000000; public static final int DARK_AQUA = ColorHelper.DARK_AQUA;
public static final int DARK_RED = ChatFormatting.DARK_RED.getColor() | 0xFF000000; public static final int DARK_RED = ColorHelper.DARK_RED;
public static final int DARK_PURPLE = ChatFormatting.DARK_PURPLE.getColor() | 0xFF000000; public static final int DARK_PURPLE = ColorHelper.DARK_PURPLE;
public static final int GOLD = ChatFormatting.GOLD.getColor() | 0xFF000000; public static final int GOLD = ColorHelper.GOLD;
public static final int GRAY = ChatFormatting.GRAY.getColor() | 0xFF000000; public static final int GRAY = ColorHelper.GRAY;
public static final int DARK_GRAY = ChatFormatting.DARK_GRAY.getColor() | 0xFF000000; public static final int DARK_GRAY = ColorHelper.DARK_GRAY;
public static final int BLUE = ChatFormatting.BLUE.getColor() | 0xFF000000; public static final int BLUE = ColorHelper.BLUE;
public static final int GREEN = ChatFormatting.GREEN.getColor() | 0xFF000000; public static final int GREEN = ColorHelper.GREEN;
public static final int AQUA = ChatFormatting.AQUA.getColor() | 0xFF000000; public static final int AQUA = ColorHelper.AQUA;
public static final int RED = ChatFormatting.RED.getColor() | 0xFF000000; public static final int RED = ColorHelper.RED;
public static final int LIGHT_PURPLE = ChatFormatting.LIGHT_PURPLE.getColor() | 0xFF000000; public static final int LIGHT_PURPLE = ColorHelper.LIGHT_PURPLE;
public static final int YELLOW = ChatFormatting.YELLOW.getColor() | 0xFF000000; public static final int YELLOW = ColorHelper.YELLOW;
public static final int WHITE = ChatFormatting.WHITE.getColor() | 0xFF000000; public static final int WHITE = ColorHelper.WHITE;
public static final int DEFAULT_TEXT = WHITE; public static final int DEFAULT_TEXT = ColorHelper.WHITE;
private static final float[] FLOAT_BUFFER = new float[4]; private static final float[] FLOAT_BUFFER = new float[4];
private static final int ALPHA = 255 << 24; private static final int ALPHA = 255 << 24;

View file

@ -1,87 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
import org.betterx.ui.layout.components.render.NullRenderer;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Value;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class AbstractHorizontalStack<S extends AbstractHorizontalStack<S>> extends AbstractStack<NullRenderer, S> implements RelativeContainerEventHandler {
public AbstractHorizontalStack(Value width, Value height) {
super(width, height);
}
@Override
public int updateContainerWidth(int containerWidth) {
int myWidth = width.calculateOrFill(containerWidth);
int fixedWidth = components.stream().map(c -> c.width.calculate(myWidth)).reduce(0, Integer::sum);
int freeWidth = Math.max(0, myWidth - fixedWidth);
fillWidth(myWidth, freeWidth);
for (LayoutComponent<?, ?> c : components) {
c.updateContainerWidth(c.width.calculatedSize());
}
return myWidth;
}
@Override
protected int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
components.stream().forEach(c -> c.height.calculateOrFill(myHeight));
for (LayoutComponent<?, ?> c : components) {
c.updateContainerHeight(c.height.calculatedSize());
}
return myHeight;
}
@Override
void setRelativeBounds(int left, int top) {
super.setRelativeBounds(left, top);
int offset = 0;
for (LayoutComponent<?, ?> c : components) {
int delta = relativeBounds.height - c.height.calculatedSize();
if (c.vAlign == Alignment.MIN) delta = 0;
else if (c.vAlign == Alignment.CENTER) delta /= 2;
c.setRelativeBounds(offset, delta);
offset += c.relativeBounds.width;
}
}
@Override
public int getContentWidth() {
int fixedWidth = components.stream().map(c -> c.width.calculateFixed()).reduce(0, Integer::sum);
double percentage = components.stream().map(c -> c.width.calculateRelative()).reduce(0.0, Double::sum);
return (int) (fixedWidth / (1 - percentage));
}
@Override
public int getContentHeight() {
return components.stream().map(c -> c.height.calculateFixed()).reduce(0, Integer::max);
}
protected S addEmpty(Value size) {
this.components.add(new Empty(size, Value.fixed(0)));
return (S) this;
}
protected VerticalStack addColumn(Value width, Value height) {
VerticalStack stack = new VerticalStack(width, height);
add(stack);
return stack;
}
protected VerticalStack addColumn() {
return addColumn(Value.fit(), Value.fit());
}
}

View file

@ -1,287 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.LinkedList;
import java.util.List;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public abstract class AbstractStack<R extends ComponentRenderer, T extends AbstractStack<R, T>> extends LayoutComponent<R, T> implements RelativeContainerEventHandler {
protected final List<LayoutComponent<?, ?>> components = new LinkedList<>();
public AbstractStack(Value width, Value height) {
this(width, height, null);
}
public AbstractStack(Value width, Value height, R renderer) {
super(width, height, renderer);
}
@Override
public int fillWidth(int parentSize, int fillSize) {
double totalFillWeight = components.stream().map(c -> c.width.fillWeight()).reduce(0.0, Double::sum);
return components.stream()
.map(c -> c.width.fill(fillSize, totalFillWeight))
.reduce(0, Integer::sum);
}
@Override
public int fillHeight(int parentSize, int fillSize) {
double totalFillHeight = components.stream().map(c -> c.height.fillWeight()).reduce(0.0, Double::sum);
return components.stream()
.map(c -> c.height.fill(fillSize, totalFillHeight))
.reduce(0, Integer::sum);
}
@Override
public void updateScreenBounds(int worldX, int worldY) {
super.updateScreenBounds(worldX, worldY);
for (LayoutComponent<?, ?> c : components) {
c.updateScreenBounds(screenBounds.left, screenBounds.top);
}
}
@Override
protected void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle renderBounds,
Rectangle clipRect
) {
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
for (LayoutComponent<?, ?> c : components) {
c.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
}
}
@Override
public List<? extends GuiEventListener> children() {
return components;
}
@Override
public Rectangle getInputBounds() {
return relativeBounds;
}
boolean dragging;
@Override
public boolean isDragging() {
return dragging;
}
@Override
public void setDragging(boolean bl) {
dragging = bl;
}
GuiEventListener focused;
@Nullable
@Override
public GuiEventListener getFocused() {
return focused;
}
@Override
public void setFocused(@Nullable GuiEventListener guiEventListener) {
focused = guiEventListener;
}
public boolean isEmpty() {
return components.isEmpty();
}
protected abstract T addEmpty(Value size);
protected T add(LayoutComponent<?, ?> c) {
this.components.add(c);
return (T) this;
}
protected T addSpacer(int size) {
return addEmpty(Value.fixed(size));
}
protected T addSpacer(float percentage) {
return addEmpty(Value.relative(percentage));
}
protected T addFiller() {
return addEmpty(Value.fill());
}
protected Image addIcon(ResourceLocation location, Size resourceSize) {
Image i = new Image(Value.fixed(24), Value.fixed(24), location, resourceSize);
add(i);
return i;
}
protected Image addImage(Value width, Value height, ResourceLocation location, Size resourceSize) {
Image i = new Image(width, height, location, resourceSize);
add(i);
return i;
}
protected Checkbox addCheckbox(
Value width, Value height, Component component,
boolean selected
) {
Checkbox c = new Checkbox(width, height, component, selected, true);
add(c);
return c;
}
protected Button addButton(
Value width, Value height,
Component component
) {
Button b = new Button(width, height, component);
add(b);
return b;
}
protected VerticalScroll<VanillaScrollerRenderer> addScrollable(LayoutComponent<?, ?> content) {
return addScrollable(Value.fill(), Value.fill(), content);
}
protected VerticalScroll<VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
) {
VerticalScroll<VanillaScrollerRenderer> s = VerticalScroll.create(width, height, content);
add(s);
return s;
}
protected Text addText(Value width, Value height, net.minecraft.network.chat.Component text) {
Text t = new Text(width, height, text);
add(t);
return t;
}
protected MultiLineText addMultilineText(Value width, Value height, net.minecraft.network.chat.Component text) {
MultiLineText t = new MultiLineText(width, height, text);
add(t);
return t;
}
protected Range<Integer> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
int minValue, int maxValue, int initialValue
) {
Range<Integer> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
protected Range<Float> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
float minValue, float maxValue, float initialValue
) {
Range<Float> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
protected Range<Double> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
double minValue, double maxValue, double initialValue
) {
Range<Double> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
protected Input addInput(
Value width, Value height, net.minecraft.network.chat.Component titleOrNull, String initialValue
) {
Input i = new Input(width, height, titleOrNull, initialValue);
add(i);
return i;
}
protected ColorSwatch addColorSwatch(Value width, Value height, int color) {
ColorSwatch c = new ColorSwatch(width, height, color);
add(c);
return c;
}
protected ColorPicker addColorPicker(
Value width,
Value height,
net.minecraft.network.chat.Component titleOrNull,
int color
) {
ColorPicker c = new ColorPicker(width, height, titleOrNull, color);
add(c);
return c;
}
protected HLine addHorizontalSeparator(int height) {
return addHLine(Value.relative(1.0 / 1.618033988749894), Value.fixed(height));
}
protected HLine addHorizontalLine(int height) {
return addHLine(Value.fill(), Value.fixed(height));
}
protected HLine addHLine(Value width, Value height) {
HLine l = new HLine(width, height);
add(l);
return l;
}
protected VLine addVerticalSeparator(int width) {
return addVLine(Value.fixed(width), Value.relative(1.0 / 1.618033988749894));
}
protected VLine addVerticalLine(int width) {
return addVLine(Value.fixed(width), Value.fill());
}
protected VLine addVLine(Value width, Value height) {
VLine l = new VLine(width, height);
add(l);
return l;
}
protected Container addContainered(Value width, Value height, LayoutComponent<?, ?> content) {
Container c = new Container(width, height);
c.addChild(content);
add(c);
return c;
}
protected Item addItem(ItemStack stack) {
Item i = new Item(Value.fit(), Value.fit());
i.setItem(stack);
add(i);
return i;
}
}

View file

@ -1,142 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Value;
import net.minecraft.client.gui.components.AbstractWidget;
public abstract class AbstractVanillaComponent<C extends AbstractWidget, V extends AbstractVanillaComponent<C, V>> extends LayoutComponent<AbstractVanillaComponentRenderer<C, V>, V> {
protected C vanillaComponent;
protected final net.minecraft.network.chat.Component component;
protected float alpha = 1.0f;
protected boolean enabled = true;
public AbstractVanillaComponent(
Value width,
Value height,
AbstractVanillaComponentRenderer<C, V> renderer,
net.minecraft.network.chat.Component component
) {
super(width, height, renderer);
this.component = component;
renderer.linkedComponent = (V) this;
}
protected abstract C createVanillaComponent();
@Override
protected void onBoundsChanged() {
vanillaComponent = createVanillaComponent();
vanillaComponent.setAlpha(this.alpha);
}
protected net.minecraft.network.chat.Component contentComponent() {
return component;
}
@Override
public int getContentWidth() {
return renderer.getWidth(contentComponent());
}
@Override
public int getContentHeight() {
return renderer.getHeight(contentComponent());
}
public float getAlpha() {
return alpha;
}
public V setAlpha(float alpha) {
this.alpha = alpha;
if (vanillaComponent != null) {
vanillaComponent.setAlpha(alpha);
}
return (V) this;
}
public boolean isEnabled() {
return enabled;
}
public V setEnabled(boolean enabled) {
this.enabled = enabled;
return (V) this;
}
@Override
public void mouseMoved(double x, double y) {
if (vanillaComponent != null && enabled)
vanillaComponent.mouseMoved(x - relativeBounds.left, y - relativeBounds.top);
}
@Override
public boolean mouseClicked(double x, double y, int button) {
if (vanillaComponent != null && enabled)
return vanillaComponent.mouseClicked(x - relativeBounds.left, y - relativeBounds.top, button);
return false;
}
@Override
public boolean mouseReleased(double x, double y, int button) {
if (vanillaComponent != null && enabled)
return vanillaComponent.mouseReleased(x - relativeBounds.left, y - relativeBounds.top, button);
return false;
}
@Override
public boolean mouseDragged(double x, double y, int button, double x2, double y2) {
if (vanillaComponent != null && enabled)
return vanillaComponent.mouseDragged(
x - relativeBounds.left,
y - relativeBounds.top,
button,
x2 - relativeBounds.left,
y2 - relativeBounds.top
);
return false;
}
@Override
public boolean mouseScrolled(double x, double y, double f) {
if (vanillaComponent != null && enabled)
return vanillaComponent.mouseScrolled(x - relativeBounds.left, y - relativeBounds.top, f);
return false;
}
@Override
public boolean keyPressed(int i, int j, int k) {
if (vanillaComponent != null && enabled)
return vanillaComponent.keyPressed(i, j, k);
return false;
}
@Override
public boolean keyReleased(int i, int j, int k) {
if (vanillaComponent != null && enabled)
return vanillaComponent.keyReleased(i, j, k);
return false;
}
@Override
public boolean charTyped(char c, int i) {
if (vanillaComponent != null && enabled)
return vanillaComponent.charTyped(c, i);
return false;
}
@Override
public boolean changeFocus(boolean bl) {
if (vanillaComponent != null && enabled)
return vanillaComponent.changeFocus(bl);
return false;
}
@Override
public boolean isMouseOver(double x, double y) {
if (vanillaComponent != null && enabled)
return vanillaComponent.isMouseOver(x - relativeBounds.left, y - relativeBounds.top);
return false;
}
}

View file

@ -1,43 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.components.render.TextProvider;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.AbstractWidget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class AbstractVanillaComponentRenderer<C extends AbstractWidget, V extends AbstractVanillaComponent<C, V>> implements ComponentRenderer, TextProvider {
V linkedComponent;
protected V getLinkedComponent() {
return linkedComponent;
}
@Override
public void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
if (linkedComponent != null) {
if (linkedComponent.vanillaComponent != null) {
if (!linkedComponent.enabled) {
linkedComponent.vanillaComponent.setAlpha(linkedComponent.alpha / 2);
}
linkedComponent.vanillaComponent.render(poseStack, mouseX, mouseY, deltaTicks);
if (!linkedComponent.enabled) {
linkedComponent.vanillaComponent.setAlpha(linkedComponent.alpha);
}
}
}
}
}

View file

@ -1,83 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
import org.betterx.ui.layout.components.render.NullRenderer;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Value;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class AbstractVerticalStack<S extends AbstractVerticalStack<S>> extends AbstractStack<NullRenderer, S> implements RelativeContainerEventHandler {
public AbstractVerticalStack(Value width, Value height) {
super(width, height);
}
@Override
protected int updateContainerWidth(int containerWidth) {
int myWidth = width.calculateOrFill(containerWidth);
components.stream().forEach(c -> c.width.calculateOrFill(myWidth));
for (LayoutComponent<?, ?> c : components) {
c.updateContainerWidth(c.width.calculatedSize());
}
return myWidth;
}
@Override
public int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
int fixedHeight = components.stream().map(c -> c.height.calculate(myHeight)).reduce(0, Integer::sum);
int freeHeight = Math.max(0, myHeight - fixedHeight);
fillHeight(myHeight, freeHeight);
for (LayoutComponent<?, ?> c : components) {
c.updateContainerHeight(c.height.calculatedSize());
}
return myHeight;
}
@Override
void setRelativeBounds(int left, int top) {
super.setRelativeBounds(left, top);
int offset = 0;
for (LayoutComponent<?, ?> c : components) {
int delta = relativeBounds.width - c.width.calculatedSize();
if (c.hAlign == Alignment.MIN) delta = 0;
else if (c.hAlign == Alignment.CENTER) delta /= 2;
c.setRelativeBounds(delta, offset);
offset += c.relativeBounds.height;
}
}
@Override
public int getContentWidth() {
return components.stream().map(c -> c.width.calculateFixed()).reduce(0, Integer::max);
}
@Override
public int getContentHeight() {
int fixedHeight = components.stream().map(c -> c.height.calculateFixed()).reduce(0, Integer::sum);
double percentage = components.stream().map(c -> c.height.calculateRelative()).reduce(0.0, Double::sum);
return (int) (fixedHeight / (1 - percentage));
}
protected S addEmpty(Value size) {
this.components.add(new Empty(Value.fixed(0), size));
return (S) this;
}
protected HorizontalStack addRow(Value width, Value height) {
HorizontalStack stack = new HorizontalStack(width, height);
add(stack);
return stack;
}
protected HorizontalStack addRow() {
return addRow(Value.fit(), Value.fit());
}
}

View file

@ -1,67 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.ButtonRenderer;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Button extends AbstractVanillaComponent<net.minecraft.client.gui.components.Button, Button> {
public static final OnTooltip NO_TOOLTIP = (button, poseStack, i, j) -> {
};
public static final OnPress NO_ACTION = (button) -> {
};
@Environment(EnvType.CLIENT)
public interface OnTooltip {
void onTooltip(Button button, PoseStack poseStack, int mouseX, int mouseY);
}
@Environment(EnvType.CLIENT)
public interface OnPress {
void onPress(Button button);
}
OnPress onPress;
OnTooltip onTooltip;
boolean glow = false;
public Button(
Value width,
Value height,
net.minecraft.network.chat.Component component
) {
super(width, height, new ButtonRenderer(), component);
this.onPress = NO_ACTION;
this.onTooltip = NO_TOOLTIP;
}
public Button onPress(OnPress onPress) {
this.onPress = onPress;
return this;
}
public Button onToolTip(OnTooltip onTooltip) {
this.onTooltip = onTooltip;
return this;
}
@Override
protected net.minecraft.client.gui.components.Button createVanillaComponent() {
Button self = this;
return net.minecraft.client.gui.components.Button
.builder(component, (bt) -> onPress.onPress(self))
.bounds(0, 0, relativeBounds.width, relativeBounds.height)
.tooltip((bt, stack, x, y) -> onTooltip.onTooltip(self, stack, x, y))
.build();
}
public boolean isGlowing() {
return glow;
}
}

View file

@ -1,68 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.CheckboxRenderer;
import org.betterx.ui.layout.values.Value;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Checkbox extends AbstractVanillaComponent<net.minecraft.client.gui.components.Checkbox, Checkbox> {
public static SelectionChanged IGNORE_CHANGE = (a, b) -> {
};
@FunctionalInterface
public interface SelectionChanged {
void now(Checkbox checkBox, boolean selected);
}
private final boolean selected;
private final boolean showLabel;
private SelectionChanged onSelectionChange;
public Checkbox(
Value width,
Value height,
Component component,
boolean selected, boolean showLabel
) {
super(width, height, new CheckboxRenderer(), component);
onSelectionChange = IGNORE_CHANGE;
this.selected = selected;
this.showLabel = showLabel;
}
public Checkbox onChange(SelectionChanged onSelectionChange) {
this.onSelectionChange = onSelectionChange;
return this;
}
public boolean isChecked() {
if (vanillaComponent != null) return vanillaComponent.selected();
return selected;
}
@Override
protected net.minecraft.client.gui.components.Checkbox createVanillaComponent() {
Checkbox self = this;
net.minecraft.client.gui.components.Checkbox cb = new net.minecraft.client.gui.components.Checkbox(
0, 0,
relativeBounds.width, relativeBounds.height,
component,
selected,
showLabel
) {
@Override
public void onPress() {
super.onPress();
onSelectionChange.now(self, this.selected());
}
};
onSelectionChange.now(this, cb.selected());
return cb;
}
}

View file

@ -1,36 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.values.Value;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ColorPicker extends AbstractHorizontalStack<ColorPicker> {
ColorSwatch swatch;
Input input;
public ColorPicker(Value width, Value height, Component title, int color) {
super(width, height);
swatch = addColorSwatch(Value.fixed(20), Value.fixed(20), color);
input = addInput(Value.fill(), Value.fit(), title, ColorUtil.toRGBHex(color));
//input.setFilter(ColorUtil::validHexColor);
input.setResponder(this::inputResponder);
}
private void inputResponder(String value) {
if (ColorUtil.validHexColor(value)) {
int color = ColorUtil.parseHex(value);
swatch.setColor(color);
swatch.setOffsetInner(false);
swatch.setBorderColor(ColorUtil.BLACK);
} else {
swatch.setOffsetInner(true);
swatch.setBorderColor(ColorUtil.RED);
}
}
}

View file

@ -1,68 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ColorSwatch extends CustomRenderComponent<ColorSwatch> {
private int color;
private int borderColor = ColorUtil.BLACK;
private boolean offsetInner = false;
public ColorSwatch(Value width, Value height, int color) {
super(width, height);
this.color = color;
}
@Override
protected void customRender(PoseStack stack, int x, int y, float deltaTicks, Rectangle bounds, Rectangle clipRect) {
int o = offsetInner ? 2 : 1;
RenderHelper.outline(stack, 0, 0, bounds.width, bounds.height, borderColor);
GuiComponent.fill(stack, o, o, bounds.width - o, bounds.height - o, color);
}
public int getColor() {
return color;
}
public ColorSwatch setColor(int color) {
this.color = color;
return this;
}
public int getBorderColor() {
return borderColor;
}
public ColorSwatch setBorderColor(int color) {
this.borderColor = color;
return this;
}
public boolean getOffsetInner() {
return offsetInner;
}
public ColorSwatch setOffsetInner(boolean val) {
this.offsetInner = val;
return this;
}
@Override
public int getContentWidth() {
return 20;
}
@Override
public int getContentHeight() {
return 20;
}
}

View file

@ -1,11 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Rectangle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public interface ComponentWithBounds {
Rectangle getRelativeBounds();
}

View file

@ -1,291 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.LinkedList;
import java.util.List;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class Container extends LayoutComponent<Container.ContainerRenderer, Container> implements RelativeContainerEventHandler {
public static class ContainerRenderer implements ComponentRenderer {
Container linkedContainer;
@Override
public void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
if (linkedContainer != null) {
if ((linkedContainer.backgroundColor & 0xFF000000) != 0)
GuiComponent.fill(stack, 0, 0, bounds.width, bounds.height, linkedContainer.backgroundColor);
if ((linkedContainer.outlineColor & 0xFF000000) != 0)
RenderHelper.outline(stack, 0, 0, bounds.width, bounds.height, linkedContainer.outlineColor);
}
}
}
record Positional(int left, int top, LayoutComponent<?, ?> component) {
public int getMaxX() {
return left + component().getContentWidth();
}
public int getMaxY() {
return top + component().getContentHeight();
}
}
private final List<Positional> children = new LinkedList<>();
boolean dragging = false;
GuiEventListener focused = null;
boolean visible = true;
int paddingLeft, paddingTop, paddingRight, paddingBottom;
int backgroundColor = 0;
int outlineColor = 0;
public Container(
Value width,
Value height
) {
super(width, height, new ContainerRenderer());
renderer.linkedContainer = this;
}
public Container addChild(LayoutComponent<?, ?> child) {
children.add(new Positional(0, 0, child));
return this;
}
public Container addChild(int left, int top, LayoutComponent<?, ?> child) {
children.add(new Positional(left, top, child));
return this;
}
public Container setVisible(boolean v) {
this.visible = v;
return this;
}
public boolean getVisible() {
return this.visible;
}
public Container setBackgroundColor(int color) {
this.backgroundColor = color;
return this;
}
public int getBackgroundColor() {
return backgroundColor;
}
public Container setOutlineColor(int color) {
this.outlineColor = color;
return this;
}
public int getOutlineColor() {
return outlineColor;
}
public Container setPadding(int padding) {
return setPadding(padding, padding, padding, padding);
}
public Container setPadding(int left, int top, int right, int bottom) {
this.paddingLeft = left;
this.paddingTop = top;
this.paddingRight = right;
this.paddingBottom = bottom;
return this;
}
@Override
public int getContentWidth() {
return children.stream()
.map(Positional::getMaxX)
.reduce(0, Math::max) + paddingLeft + paddingRight;
}
@Override
public int getContentHeight() {
return children.stream()
.map(Positional::getMaxY)
.reduce(0, Math::max) + paddingTop + paddingBottom;
}
@Override
public Rectangle getInputBounds() {
return relativeBounds;
}
@Override
public List<? extends GuiEventListener> children() {
return children.stream().map(p -> p.component).toList();
}
@Override
public boolean isDragging() {
return dragging;
}
@Override
public void setDragging(boolean bl) {
dragging = bl;
}
@Nullable
@Override
public GuiEventListener getFocused() {
return focused;
}
@Override
public void setFocused(@Nullable GuiEventListener guiEventListener) {
focused = guiEventListener;
}
@Override
protected int updateContainerWidth(int containerWidth) {
int myWidth = width.calculateOrFill(containerWidth);
for (var child : children) {
child.component.width.calculateOrFill(myWidth - (paddingLeft + paddingRight));
child.component.updateContainerWidth(child.component.width.calculatedSize());
}
return myWidth;
}
@Override
protected int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
for (var child : children) {
child.component.height.calculateOrFill(myHeight - (paddingTop + paddingBottom));
child.component.updateContainerHeight(child.component.height.calculatedSize());
}
return myHeight;
}
@Override
protected void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle renderBounds,
Rectangle clipRect
) {
if (visible) {
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
setClippingRect(clipRect);
for (var child : children) {
child.component.render(
poseStack, mouseX, mouseY, deltaTicks,
renderBounds, clipRect
);
}
setClippingRect(null);
}
}
@Override
void setRelativeBounds(int left, int top) {
super.setRelativeBounds(left, top);
for (var child : children) {
int childLeft = (relativeBounds.width - (paddingLeft + paddingRight)) - child.component.width.calculatedSize();
if (child.component.hAlign == Alignment.MIN) childLeft = 0;
else if (child.component.hAlign == Alignment.CENTER) childLeft /= 2;
int childTop = (relativeBounds.height - (paddingTop + paddingBottom)) - child.component.height.calculatedSize();
if (child.component.vAlign == Alignment.MIN) childTop = 0;
else if (child.component.vAlign == Alignment.CENTER) childTop /= 2;
child.component.setRelativeBounds(child.left + paddingLeft + childLeft, child.top + paddingTop + childTop);
}
}
@Override
public void updateScreenBounds(int worldX, int worldY) {
super.updateScreenBounds(worldX, worldY);
for (Positional p : children) {
p.component.updateScreenBounds(p.left + screenBounds.left, p.top + screenBounds.top);
}
}
@Override
public void mouseMoved(double d, double e) {
if (visible)
RelativeContainerEventHandler.super.mouseMoved(d, e);
}
@Override
public boolean mouseClicked(double d, double e, int i) {
if (visible)
return RelativeContainerEventHandler.super.mouseClicked(d, e, i);
return false;
}
@Override
public boolean mouseReleased(double d, double e, int i) {
if (visible)
return RelativeContainerEventHandler.super.mouseReleased(d, e, i);
return false;
}
@Override
public boolean mouseScrolled(double d, double e, double f) {
if (visible)
return RelativeContainerEventHandler.super.mouseScrolled(d, e, f);
return false;
}
@Override
public boolean mouseDragged(double d, double e, int i, double f, double g) {
if (visible)
return RelativeContainerEventHandler.super.mouseDragged(d, e, i, f, g);
return false;
}
@Override
public boolean isMouseOver(double x, double y) {
if (visible) {
boolean res = false;
for (var child : children) {
res |= child.component.isMouseOver(x, y);
}
return res || relativeBounds.contains(x, y);
}
return false;
}
public static Container create(LayoutComponent<?, ?> content) {
return create(Value.fit(), Value.fit(), content);
}
public static Container create(Value width, Value height, LayoutComponent<?, ?> content) {
Container c = new Container(width, height);
c.addChild(content);
return c;
}
}

View file

@ -1,48 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public abstract class CustomRenderComponent<C extends CustomRenderComponent<C>> extends LayoutComponent<CustomRenderComponent.CustomRenderRenderer<C>, C> {
public CustomRenderComponent(
Value width,
Value height
) {
super(width, height, new CustomRenderRenderer<>());
renderer.linkedComponent = (C) this;
}
protected abstract void customRender(
PoseStack stack,
int x,
int y,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
);
protected static class CustomRenderRenderer<C extends CustomRenderComponent<C>> implements ComponentRenderer {
C linkedComponent;
@Override
public void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
if (linkedComponent != null) {
linkedComponent.customRender(stack, mouseX, mouseY, deltaTicks, bounds, clipRect);
}
}
}
}

View file

@ -1,32 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.NullRenderer;
import org.betterx.ui.layout.values.Value;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Empty extends LayoutComponent<NullRenderer, Empty> {
public Empty(
Value width,
Value height
) {
super(width, height, null);
}
@Override
public int getContentWidth() {
return 0;
}
@Override
public int getContentHeight() {
return 0;
}
@Override
public boolean isMouseOver(double d, double e) {
return false;
}
}

View file

@ -1,46 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HLine extends CustomRenderComponent {
private int color = ColorUtil.DEFAULT_TEXT;
public HLine(Value width, Value height) {
super(width, height);
this.vAlign = Alignment.CENTER;
this.hAlign = Alignment.CENTER;
}
public HLine setColor(int color) {
this.color = color;
return this;
}
@Override
protected void customRender(PoseStack stack, int x, int y, float deltaTicks, Rectangle bounds, Rectangle clipRect) {
int top = bounds.height - getContentHeight();
if (vAlign == Alignment.CENTER) top /= 2;
else if (vAlign == Alignment.MIN) top = 0;
RenderHelper.hLine(stack, 0, bounds.width, top, color);
}
@Override
public int getContentWidth() {
return 0;
}
@Override
public int getContentHeight() {
return 1;
}
}

View file

@ -1,205 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HorizontalStack extends AbstractHorizontalStack<HorizontalStack> {
public HorizontalStack(Value width, Value height) {
super(width, height);
}
public static HorizontalStack centered(LayoutComponent<?, ?> c) {
return new HorizontalStack(Value.fill(), Value.fill()).addFiller().add(c).addFiller();
}
public static HorizontalStack bottom(LayoutComponent<?, ?> c) {
return new HorizontalStack(Value.fill(), Value.fill()).add(c).addFiller();
}
protected HorizontalStack addEmpty(Value size) {
this.components.add(new Empty(size, Value.fixed(0)));
return this;
}
@Override
public HorizontalStack add(LayoutComponent<?, ?> c) {
return super.add(c);
}
public VerticalStack addColumn(Value width, Value height) {
return super.addColumn(width, height);
}
public VerticalStack addColumn() {
return super.addColumn();
}
@Override
public HorizontalStack addSpacer(int size) {
return super.addSpacer(size);
}
@Override
public HorizontalStack addSpacer(float percentage) {
return super.addSpacer(percentage);
}
@Override
public HorizontalStack addFiller() {
return super.addFiller();
}
@Override
public Button addButton(
Value width,
Value height,
Component component
) {
return super.addButton(width, height, component);
}
@Override
public Checkbox addCheckbox(
Value width,
Value height,
Component component,
boolean selected
) {
return super.addCheckbox(width, height, component, selected);
}
@Override
public ColorPicker addColorPicker(Value width, Value height, Component titleOrNull, int color) {
return super.addColorPicker(width, height, titleOrNull, color);
}
@Override
public ColorSwatch addColorSwatch(Value width, Value height, int color) {
return super.addColorSwatch(width, height, color);
}
@Override
public Container addContainered(Value width, Value height, LayoutComponent<?, ?> content) {
return super.addContainered(width, height, content);
}
@Override
public HLine addHLine(Value width, Value height) {
return super.addHLine(width, height);
}
@Override
public HLine addHorizontalLine(int height) {
return super.addHorizontalLine(height);
}
@Override
public HLine addHorizontalSeparator(int height) {
return super.addHorizontalSeparator(height);
}
@Override
public Image addIcon(ResourceLocation location, Size resourceSize) {
return super.addIcon(location, resourceSize);
}
@Override
public Image addImage(Value width, Value height, ResourceLocation location, Size resourceSize) {
return super.addImage(width, height, location, resourceSize);
}
@Override
public Input addInput(Value width, Value height, Component titleOrNull, String initialValue) {
return super.addInput(width, height, titleOrNull, initialValue);
}
@Override
public MultiLineText addMultilineText(Value width, Value height, Component text) {
return super.addMultilineText(width, height, text);
}
@Override
public Range<Double> addRange(
Value width,
Value height,
Component titleOrNull,
double minValue,
double maxValue,
double initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Range<Float> addRange(
Value width,
Value height,
Component titleOrNull,
float minValue,
float maxValue,
float initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Range<Integer> addRange(
Value width,
Value height,
Component titleOrNull,
int minValue,
int maxValue,
int initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Text addText(Value width, Value height, Component text) {
return super.addText(width, height, text);
}
@Override
public VerticalScroll<VanillaScrollerRenderer> addScrollable(LayoutComponent<?, ?> content) {
return super.addScrollable(content);
}
@Override
public VLine addVerticalLine(int width) {
return super.addVerticalLine(width);
}
@Override
public VLine addVerticalSeparator(int width) {
return super.addVerticalSeparator(width);
}
@Override
public VLine addVLine(Value width, Value height) {
return super.addVLine(width, height);
}
@Override
public VerticalScroll<VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
) {
return super.addScrollable(width, height, content);
}
@Override
public Item addItem(ItemStack stack) {
return super.addItem(stack);
}
}

View file

@ -1,98 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.resources.ResourceLocation;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Image extends CustomRenderComponent {
protected Rectangle uvRect;
public final ResourceLocation location;
protected float alpha;
protected Size resourceSize;
public Image(Value width, Value height, ResourceLocation location) {
this(width, height, location, new Size(16, 16));
}
public Image(Value width, Value height, ResourceLocation location, Size resourceSize) {
super(width, height);
this.location = location;
this.uvRect = new Rectangle(0, 0, resourceSize.width(), resourceSize.height());
this.resourceSize = resourceSize;
this.alpha = 1f;
}
public Image setAlpha(float a) {
alpha = a;
return this;
}
public float getAlpha() {
return alpha;
}
public Image setUvRect(int left, int top, int width, int height) {
setUvRect(new Rectangle(left, top, width, height));
return this;
}
public Image setUvRect(Rectangle rect) {
uvRect = rect;
return this;
}
public Rectangle getUvRect() {
return uvRect;
}
public Image setResourceSize(int width, int height) {
return setResourceSize(new Size(width, height));
}
public Image setResourceSize(Size sz) {
resourceSize = sz;
return this;
}
public Size getResourceSize() {
return resourceSize;
}
@Override
public int getContentWidth() {
return uvRect.width;
}
@Override
public int getContentHeight() {
return uvRect.height;
}
@Override
protected void customRender(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
RenderHelper.renderImage(stack, 0, 0, bounds.width, bounds.height, location, resourceSize, uvRect, alpha);
}
@Override
public boolean isMouseOver(double d, double e) {
return false;
}
}

View file

@ -1,96 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.EditBoxRenderer;
import org.betterx.ui.layout.values.Value;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.network.chat.Component;
import net.minecraft.util.FormattedCharSequence;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Predicate;
@Environment(EnvType.CLIENT)
public class Input extends AbstractVanillaComponent<EditBox, Input> {
private Consumer<String> responder;
private BiFunction<String, Integer, FormattedCharSequence> formatter;
private Predicate<String> filter;
private String initialValue = "";
public Input(
Value width,
Value height,
Component component,
String initialValue
) {
super(width, height, new EditBoxRenderer(), component);
this.initialValue = initialValue;
}
@Override
protected EditBox createVanillaComponent() {
EditBox eb = new EditBox(renderer.getFont(),
0, 0,
relativeBounds.width, relativeBounds.height,
null,
component
);
if (responder != null) eb.setResponder(responder);
if (filter != null) eb.setFilter(filter);
if (formatter != null) eb.setFormatter(formatter);
eb.setValue(initialValue);
eb.setBordered(true);
eb.setEditable(true);
return eb;
}
public Input setResponder(Consumer<String> consumer) {
this.responder = consumer;
if (vanillaComponent != null) vanillaComponent.setResponder(responder);
return this;
}
public Input setFormatter(BiFunction<String, Integer, FormattedCharSequence> formatter) {
this.formatter = formatter;
if (vanillaComponent != null) vanillaComponent.setFormatter(formatter);
return this;
}
public Input setFilter(Predicate<String> filter) {
this.filter = filter;
if (vanillaComponent != null) vanillaComponent.setFilter(filter);
return this;
}
public String getValue() {
if (vanillaComponent != null) return vanillaComponent.getValue();
return "";
}
public Input setValue(String value) {
if (vanillaComponent != null) vanillaComponent.setValue(value);
else initialValue = value;
return this;
}
@Override
protected Component contentComponent() {
return Component.literal(initialValue + "..");
}
@Override
public boolean changeFocus(boolean bl) {
return super.changeFocus(bl);
}
@Override
public boolean mouseClicked(double x, double y, int button) {
return super.mouseClicked(x, y, button);
}
}

View file

@ -1,46 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.world.item.ItemStack;
public class Item extends CustomRenderComponent {
private ItemStack itemStack;
public Item(Value width, Value height) {
super(width, height);
}
public Item setItem(ItemStack item) {
this.itemStack = item;
return this;
}
@Override
protected void customRender(PoseStack stack, int x, int y, float deltaTicks, Rectangle bounds, Rectangle clipRect) {
final ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
itemRenderer.renderAndDecorateItem(Minecraft.getInstance().player, itemStack, bounds.left, bounds.top, 0);
itemRenderer.renderGuiItemDecorations(
Minecraft.getInstance().font,
itemStack,
bounds.left,
bounds.top,
"" + itemStack.getCount()
);
}
@Override
public int getContentWidth() {
return 16;
}
@Override
public int getContentHeight() {
return 16;
}
}

View file

@ -1,184 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public abstract class LayoutComponent<R extends ComponentRenderer, L extends LayoutComponent<R, L>> implements ComponentWithBounds, GuiEventListener {
protected final R renderer;
protected final Value width;
protected final Value height;
protected String debugName;
protected Rectangle relativeBounds;
protected Rectangle screenBounds;
protected Alignment vAlign = Alignment.MIN;
protected Alignment hAlign = Alignment.MIN;
public LayoutComponent(Value width, Value height, R renderer) {
this.width = width.attachComponent(this::getContentWidth);
this.height = height.attachComponent(this::getContentHeight);
this.renderer = renderer;
}
public void reCalculateLayout() {
updateContainerWidth(relativeBounds.width);
updateContainerHeight(relativeBounds.height);
setRelativeBounds(relativeBounds.left, relativeBounds.top);
updateScreenBounds(screenBounds.left, screenBounds.top);
}
protected int updateContainerWidth(int containerWidth) {
return width.setCalculatedSize(containerWidth);
}
protected int updateContainerHeight(int containerHeight) {
return height.setCalculatedSize(containerHeight);
}
void setRelativeBounds(int left, int top) {
relativeBounds = new Rectangle(left, top, width.calculatedSize(), height.calculatedSize());
onBoundsChanged();
}
public void updateScreenBounds(int worldX, int worldY) {
screenBounds = relativeBounds.movedBy(worldX, worldY);
}
protected void onBoundsChanged() {
}
public Rectangle getRelativeBounds() {
return relativeBounds;
}
public Rectangle getScreenBounds() {
return screenBounds;
}
public abstract int getContentWidth();
public abstract int getContentHeight();
public int fillWidth(int parentSize, int fillSize) {
return width.fill(fillSize);
}
public int fillHeight(int parentSize, int fillSize) {
return height.fill(fillSize);
}
public int getWidth() {
return width.calculatedSize();
}
public int getHeight() {
return height.calculatedSize();
}
protected final void setClippingRect(Rectangle clippingRect) {
if (clippingRect == null) {
RenderSystem.disableScissor();
return;
}
final double uiScale = Minecraft.getInstance().getWindow().getGuiScale();
final int windowHeight = Minecraft.getInstance().getWindow().getHeight();
RenderSystem.enableScissor(
(int) (clippingRect.left * uiScale),
(int) (windowHeight - (clippingRect.bottom()) * uiScale),
(int) (clippingRect.width * uiScale),
(int) ((clippingRect.height) * uiScale)
);
}
public void render(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle parentBounds,
Rectangle clipRect
) {
Rectangle r = relativeBounds.movedBy(parentBounds.left, parentBounds.top);
Rectangle clip = r.intersect(clipRect);
poseStack.pushPose();
poseStack.translate(relativeBounds.left, relativeBounds.top, 0);
//if (r.overlaps(clip))
{
renderInBounds(poseStack, mouseX - relativeBounds.left, mouseY - relativeBounds.top, deltaTicks, r, clip);
}
poseStack.popPose();
}
protected void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle renderBounds,
Rectangle clipRect
) {
if (renderer != null) {
setClippingRect(clipRect);
renderer.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
setClippingRect(null);
}
}
@Override
public String toString() {
return super.toString() + "(" +
(debugName == null ? "" : debugName + " - ") +
relativeBounds + ", " +
width.calculatedSize() + "x" + height.calculatedSize() +
")";
}
public L alignTop() {
vAlign = Alignment.MIN;
return (L) this;
}
public L alignBottom() {
vAlign = Alignment.MAX;
return (L) this;
}
public L centerVertical() {
vAlign = Alignment.CENTER;
return (L) this;
}
public L alignLeft() {
hAlign = Alignment.MIN;
return (L) this;
}
public L alignRight() {
hAlign = Alignment.MAX;
return (L) this;
}
public L centerHorizontal() {
hAlign = Alignment.CENTER;
return (L) this;
}
public L setDebugName(String d) {
debugName = d;
return (L) this;
}
@Override
public boolean isMouseOver(double d, double e) {
return relativeBounds.contains(d, e);
}
}

View file

@ -1,180 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.components.render.TextProvider;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.MultiLineLabel;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.util.FormattedCharSequence;
import com.google.common.collect.ImmutableList;
import java.util.Iterator;
import java.util.List;
record LineWithWidth(FormattedCharSequence text, int width) {
}
public class MultiLineText extends LayoutComponent<MultiLineText.MultiLineTextRenderer, MultiLineText> {
net.minecraft.network.chat.Component text;
int color = ColorUtil.DEFAULT_TEXT;
protected MultiLineLabel multiLineLabel;
int bufferedContentWidth = 0;
List<LineWithWidth> lines = List.of();
public MultiLineText(
Value width,
Value height,
final net.minecraft.network.chat.Component text
) {
super(width, height, new MultiLineTextRenderer());
renderer.linkedComponent = this;
this.text = text;
updatedContentWidth();
}
public MultiLineText setColor(int cl) {
this.color = cl;
return this;
}
public static Component parse(Component text) {
String[] parts = text.getString().split("\\*\\*");
if (parts.length > 0) {
boolean bold = false;
MutableComponent c = Component.literal(parts[0]);
for (int i = 1; i < parts.length; i++) {
bold = !bold;
c.append(Component.literal(parts[i]).setStyle(Style.EMPTY.withBold(bold)));
}
return c;
}
return text;
}
public MultiLineText setText(Component text) {
this.text = text;
this.updatedContentWidth();
if (multiLineLabel != null) {
multiLineLabel = createVanillaComponent();
}
return this;
}
protected MultiLineLabel createVanillaComponent() {
final int wd = relativeBounds == null ? width.calculatedSize() : relativeBounds.width;
lines = renderer.getFont()
.split(text, wd)
.stream()
.map((component) -> new LineWithWidth(component, renderer.getFont().width(component)))
.collect(ImmutableList.toImmutableList());
return MultiLineLabel.create(renderer.getFont(), text, wd);
}
protected void updatedContentWidth() {
String[] lines = text.getString().split("\n");
if (lines.length == 0) bufferedContentWidth = 0;
else {
String line = lines[0];
for (int i = 1; i < lines.length; i++)
if (lines[i].length() > line.length())
line = lines[i];
bufferedContentWidth = renderer.getWidth(Component.literal(line));
}
}
@Override
protected void onBoundsChanged() {
super.onBoundsChanged();
multiLineLabel = createVanillaComponent();
}
@Override
public int getContentWidth() {
return bufferedContentWidth;
}
@Override
public int getContentHeight() {
return renderer.getHeight(text);
}
protected static class MultiLineTextRenderer implements ComponentRenderer, TextProvider {
MultiLineText linkedComponent;
@Override
public int getWidth(Component c) {
return getFont().width(c.getVisualOrderText());
}
@Override
public int getHeight(net.minecraft.network.chat.Component c) {
if (linkedComponent == null) return 20;
MultiLineLabel ml;
if (linkedComponent.multiLineLabel != null) ml = linkedComponent.multiLineLabel;
else ml = linkedComponent.createVanillaComponent();
return ml.getLineCount() * getLineHeight(c);
}
@Override
public void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
if (linkedComponent != null && linkedComponent.multiLineLabel != null) {
int top = bounds.height - getHeight(linkedComponent.text);
if (linkedComponent.vAlign == Alignment.MIN) top = 0;
if (linkedComponent.vAlign == Alignment.CENTER) top /= 2;
if (linkedComponent.hAlign == Alignment.CENTER) {
linkedComponent.multiLineLabel.renderCentered(
stack, bounds.width / 2, top,
getLineHeight(linkedComponent.text),
linkedComponent.color
);
} else if (linkedComponent.hAlign == Alignment.MAX) {
int lineY = 0;
int lineHeight = getLineHeight(linkedComponent.text);
for (Iterator<LineWithWidth> iter = linkedComponent.lines.iterator(); iter.hasNext(); lineY += lineHeight) {
LineWithWidth textWithWidth = iter.next();
getFont().drawShadow(
stack,
textWithWidth.text(),
linkedComponent.width.calculatedSize() - textWithWidth.width(),
lineY,
linkedComponent.color
);
}
} else {
linkedComponent.multiLineLabel.renderLeftAligned(
stack, 0, top,
getLineHeight(linkedComponent.text),
linkedComponent.color
);
}
}
}
}
@Override
public boolean isMouseOver(double d, double e) {
return false;
}
}

View file

@ -1,108 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.Renderable;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.List;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class Panel implements ComponentWithBounds, RelativeContainerEventHandler, NarratableEntry, Renderable {
protected LayoutComponent<?, ?> child;
List<? extends GuiEventListener> listeners = List.of();
public final Rectangle bounds;
public Panel(int width, int height) {
this(0, 0, width, height);
}
public Panel(int left, int top, int width, int height) {
bounds = new Rectangle(left, top, width, height);
}
public void setChild(LayoutComponent<?, ?> c) {
this.child = c;
listeners = List.of(c);
}
public void calculateLayout() {
if (child != null) {
child.updateContainerWidth(bounds.width);
child.updateContainerHeight(bounds.height);
child.setRelativeBounds(0, 0);
child.updateScreenBounds(bounds.left, bounds.top);
}
}
@Override
public Rectangle getRelativeBounds() {
return bounds;
}
@Override
public List<? extends GuiEventListener> children() {
return listeners;
}
@Override
public Rectangle getInputBounds() {
return bounds;
}
boolean dragging = false;
@Override
public boolean isDragging() {
return dragging;
}
@Override
public void setDragging(boolean bl) {
dragging = bl;
}
GuiEventListener focused;
@Nullable
@Override
public GuiEventListener getFocused() {
return focused;
}
@Override
public void setFocused(@Nullable GuiEventListener guiEventListener) {
focused = guiEventListener;
}
@Override
public NarrationPriority narrationPriority() {
return NarrationPriority.NONE;
}
@Override
public void updateNarration(NarrationElementOutput narrationElementOutput) {
}
@Override
public void render(PoseStack poseStack, int mouseX, int mouseY, float deltaTicks) {
if (child != null) {
poseStack.pushPose();
poseStack.translate(bounds.left, bounds.top, 0);
child.render(poseStack, mouseX - bounds.left, mouseY - bounds.top, deltaTicks, bounds, bounds);
poseStack.popPose();
}
}
}

View file

@ -1,92 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.RangeRenderer;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.Slider;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>, Range<N>> {
@FunctionalInterface
public interface ValueChanged<N extends Number> {
void now(Range<N> range, N newValue);
}
private ValueChanged<N> onChange;
private final N minValue;
private final N maxValue;
private final N initialValue;
public Range(
Value width,
Value height,
Component component,
N minValue,
N maxValue,
N initialValue
) {
super(width, height, new RangeRenderer<>(), component);
this.onChange = (a, b) -> {
};
this.minValue = minValue;
this.maxValue = maxValue;
this.initialValue = initialValue;
}
public Range(
Value width,
Value height,
N minValue,
N maxValue,
N initialValue
) {
this(width, height, null, minValue, maxValue, initialValue);
}
public Range<N> onChange(ValueChanged<N> onChange) {
this.onChange = onChange;
return this;
}
@Override
protected Slider<N> createVanillaComponent() {
Range<N> self = this;
return new Slider<>(
0,
0,
relativeBounds.width,
relativeBounds.height,
component,
minValue,
maxValue,
initialValue,
(s, v) -> onChange.now(self, v)
);
}
public N getValue() {
return vanillaComponent.currentValue();
}
@Override
protected Component contentComponent() {
Slider<N> dummy = new Slider<>(
0,
0,
100,
20,
component,
minValue,
maxValue,
initialValue,
(a, b) -> {
}
);
return dummy.getValueComponent(maxValue);
}
}

View file

@ -1,158 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Value;
import net.minecraft.network.chat.Component;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.LinkedList;
import java.util.List;
@Environment(EnvType.CLIENT)
public class Tabs extends AbstractVerticalStack<Tabs> {
@FunctionalInterface
public interface OnPageChange {
void now(Tabs tabs, int pageIndex);
}
private final HorizontalStack buttons;
private final Container content;
private final List<Container> pageList = new LinkedList<>();
private final List<Button> buttonList = new LinkedList<>();
private int initialPage = 0;
private OnPageChange onPageChange;
public Tabs(Value width, Value height) {
super(width, height);
buttons = new HorizontalStack(Value.fill(), Value.fit());
content = new Container(Value.fill(), Value.fill());
this.add(buttons);
this.add(content);
setBackgroundColor(0x77000000);
setPadding(4);
}
public Tabs addPage(Component title, LayoutComponent<?, ?> content) {
final Container c = new Container(Value.fill(), Value.fill());
c.addChild(content);
this.content.addChild(c);
pageList.add(c);
if (!buttons.isEmpty()) buttons.addSpacer(4);
Button b = new Button(Value.fit(), Value.fit(), title).alignBottom();
b.onPress((bt) -> {
for (Container cc : pageList) {
cc.setVisible(cc == c);
}
for (Button bb : buttonList) {
bb.glow = bb == b;
}
if (onPageChange != null) {
for (int i = 0; i < buttonList.size(); i++) {
if (buttonList.get(i).glow) onPageChange.now(this, i);
}
}
});
buttons.add(b);
buttonList.add(b);
return this;
}
public Tabs onPageChange(OnPageChange e) {
this.onPageChange = e;
return this;
}
public Button getButton(int idx) {
return buttonList.get(idx);
}
public Tabs setBackgroundColor(int color) {
content.setBackgroundColor(color);
return this;
}
public int getBackgroundColor() {
return content.getBackgroundColor();
}
public Tabs setOutlineColor(int color) {
content.setOutlineColor(color);
return this;
}
public int getOutlineColor() {
return content.getOutlineColor();
}
public Tabs setPadding(int padding) {
content.setPadding(padding);
return this;
}
public Tabs setPadding(int left, int top, int right, int bottom) {
content.setPadding(left, top, right, bottom);
return this;
}
@Override
public int getContentWidth() {
return content.getContentWidth();
}
public Tabs selectPage(int idx) {
for (int i = 0; i < pageList.size(); i++) {
pageList.get(i).setVisible(i == idx);
buttonList.get(i).glow = i == idx;
}
initialPage = idx;
return this;
}
public int getSelectedPage() {
return initialPage;
}
public Tabs addComponent(LayoutComponent<?, ?> title) {
buttons.add(title);
return this;
}
@Override
protected void onBoundsChanged() {
super.onBoundsChanged();
selectPage(initialPage);
}
@Override
public Tabs addFiller() {
buttons.addFiller();
return this;
}
@Override
public Tabs addSpacer(int size) {
buttons.addSpacer(size);
return this;
}
@Override
public Tabs addSpacer(float percentage) {
buttons.addSpacer(percentage);
return this;
}
}

View file

@ -1,89 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.render.ComponentRenderer;
import org.betterx.ui.layout.components.render.TextProvider;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.network.chat.Component;
public class Text extends LayoutComponent<Text.TextRenderer, Text> {
net.minecraft.network.chat.Component text;
int color = ColorUtil.DEFAULT_TEXT;
public Text(
Value width,
Value height,
net.minecraft.network.chat.Component text
) {
super(width, height, new TextRenderer());
vAlign = Alignment.CENTER;
renderer.linkedComponent = this;
this.text = text;
}
public Text setColor(int cl) {
this.color = cl;
return this;
}
public Text setText(Component text) {
this.text = text;
return this;
}
@Override
public int getContentWidth() {
return renderer.getWidth(text);
}
@Override
public int getContentHeight() {
return renderer.getHeight(text);
}
public static class TextRenderer implements ComponentRenderer, TextProvider {
Text linkedComponent;
@Override
public int getWidth(net.minecraft.network.chat.Component c) {
return getFont().width(c.getVisualOrderText());
}
@Override
public int getHeight(net.minecraft.network.chat.Component c) {
return TextProvider.super.getLineHeight(c);
}
@Override
public void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
if (linkedComponent != null) {
int left = bounds.width - getWidth(linkedComponent.text);
if (linkedComponent.hAlign == Alignment.MIN) left = 0;
if (linkedComponent.hAlign == Alignment.CENTER) left /= 2;
int top = bounds.height - getLineHeight(linkedComponent.text);
if (linkedComponent.vAlign == Alignment.MIN) top = 0;
if (linkedComponent.vAlign == Alignment.CENTER) top = top / 2 + 1;
GuiComponent.drawString(stack, getFont(), linkedComponent.text, left, top, linkedComponent.color);
}
}
}
@Override
public boolean isMouseOver(double d, double e) {
return false;
}
}

View file

@ -1,51 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.render.RenderHelper;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class VLine extends CustomRenderComponent {
private int color = ColorUtil.DEFAULT_TEXT;
public VLine(Value width, Value height) {
super(width, height);
this.vAlign = Alignment.CENTER;
this.hAlign = Alignment.CENTER;
}
public VLine setColor(int color) {
this.color = color;
return this;
}
@Override
protected void customRender(PoseStack stack, int x, int y, float deltaTicks, Rectangle bounds, Rectangle clipRect) {
int left = bounds.height - getContentHeight();
if (hAlign == Alignment.CENTER) left /= 2;
else if (hAlign == Alignment.MIN) left = 0;
RenderHelper.vLine(stack, left, 0, bounds.height, color);
}
@Override
public int getContentWidth() {
return 1;
}
@Override
public int getContentHeight() {
return 0;
}
@Override
public boolean isMouseOver(double d, double e) {
return false;
}
}

View file

@ -1,314 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.components.render.NullRenderer;
import org.betterx.ui.layout.components.render.ScrollerRenderer;
import org.betterx.ui.layout.values.Alignment;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.components.events.ContainerEventHandler;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.List;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class VerticalScroll<RS extends ScrollerRenderer> extends LayoutComponent<NullRenderer, VerticalScroll<RS>> implements ContainerEventHandler {
protected LayoutComponent<?, ?> child;
protected final RS scrollerRenderer;
protected int dist;
protected double scrollerY;
protected int scrollerHeight;
protected int travel;
protected int topOffset;
protected int scrollerPadding;
protected boolean keepSpaceForScrollbar = true;
public VerticalScroll(Value width, Value height, RS scrollerRenderer) {
super(width, height, new NullRenderer());
this.scrollerRenderer = scrollerRenderer;
this.scrollerPadding = scrollerRenderer.scrollerPadding();
}
public static VerticalScroll<VanillaScrollerRenderer> create(LayoutComponent<?, ?> c) {
return create(Value.relative(1), Value.relative(1), c);
}
public static VerticalScroll<VanillaScrollerRenderer> create(
Value width,
Value height,
LayoutComponent<?, ?> c
) {
VerticalScroll<VanillaScrollerRenderer> res = new VerticalScroll<>(
width,
height,
VanillaScrollerRenderer.DEFAULT
);
res.setChild(c);
return res;
}
List<LayoutComponent<?, ?>> children = List.of();
public VerticalScroll<RS> setChild(LayoutComponent<?, ?> c) {
this.child = c;
children = List.of(child);
return this;
}
public VerticalScroll<RS> setScrollerPadding(int pad) {
this.scrollerPadding = pad;
return this;
}
public VerticalScroll<RS> setKeepSpaceForScrollbar(boolean value) {
keepSpaceForScrollbar = value;
return this;
}
@Override
protected int updateContainerWidth(int containerWidth) {
int myWidth = width.calculateOrFill(containerWidth);
if (child != null) {
child.width.calculateOrFill(myWidth - scrollerWidth());
child.updateContainerWidth(child.width.calculatedSize());
}
return myWidth;
}
@Override
protected int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
if (child != null) {
child.height.calculateOrFill(myHeight);
child.updateContainerHeight(child.height.calculatedSize());
}
return myHeight;
}
protected int scrollerWidth() {
return scrollerRenderer.scrollerWidth() + scrollerPadding;
}
@Override
public int getContentWidth() {
return scrollerWidth() + (child != null
? child.getContentWidth()
: 0);
}
@Override
public int getContentHeight() {
return child != null ? child.getContentHeight() : 0;
}
@Override
void setRelativeBounds(int left, int top) {
super.setRelativeBounds(left, top);
if (child != null) {
int width = relativeBounds.width;
boolean willNeedScrollBar = keepSpaceForScrollbar || child.height.calculatedSize() > relativeBounds.height;
if (willNeedScrollBar) width -= scrollerWidth();
int childLeft = width - child.width.calculatedSize();
if (child.hAlign == Alignment.MIN) childLeft = 0;
else if (child.hAlign == Alignment.CENTER) childLeft /= 2;
int childTop = relativeBounds.height - child.height.calculatedSize();
if (child.vAlign == Alignment.MIN) childTop = 0;
else if (child.vAlign == Alignment.CENTER) childTop /= 2;
child.setRelativeBounds(childLeft, childTop);
}
updateScrollViewMetrics();
}
@Override
public void updateScreenBounds(int worldX, int worldY) {
super.updateScreenBounds(worldX, worldY);
child.updateScreenBounds(screenBounds.left, screenBounds.top);
}
@Override
protected void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle renderBounds,
Rectangle clipRect
) {
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
if (showScrollBar()) {
if (child != null) {
poseStack.pushPose();
poseStack.translate(0, scrollerOffset(), 0);
setClippingRect(clipRect);
child.render(
poseStack, mouseX, mouseY - scrollerOffset(), deltaTicks,
renderBounds.movedBy(0, scrollerOffset(), scrollerWidth(), 0),
clipRect
);
setClippingRect(null);
poseStack.popPose();
}
scrollerRenderer.renderScrollBar(renderBounds, saveScrollerY(), scrollerHeight);
} else {
if (child != null) {
child.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
}
}
}
private boolean mouseDown = false;
private int mouseDownY = 0;
private int scrollerDownY = 0;
protected void updateScrollViewMetrics() {
final int view = relativeBounds.height;
final int content = child.relativeBounds.height;
this.dist = content - view;
this.scrollerHeight = Math.max(scrollerRenderer.scrollerHeight(), (view * view) / content);
this.travel = view - this.scrollerHeight;
this.topOffset = 0;
this.scrollerY = 0;
}
protected int saveScrollerY() {
return (int) Math.max(0, Math.min(travel, scrollerY));
}
protected int scrollerOffset() {
return -((int) (((float) saveScrollerY() / travel) * this.dist));
}
public boolean showScrollBar() {
return child.relativeBounds.height > relativeBounds.height;
}
@Override
public void mouseMoved(double x, double y) {
if (child != null && relativeBounds.contains(x, y))
ContainerEventHandler.super.mouseMoved(x - relativeBounds.left, y - relativeBounds.top - scrollerOffset());
}
@Override
public List<? extends GuiEventListener> children() {
return children;
}
@Override
public boolean mouseClicked(double x, double y, int button) {
Rectangle scroller = scrollerRenderer.getScrollerBounds(relativeBounds);
Rectangle picker = scrollerRenderer.getPickerBounds(scroller, saveScrollerY(), scrollerHeight);
if (picker.contains((int) x, (int) y)) {
mouseDown = true;
mouseDownY = (int) y;
scrollerDownY = saveScrollerY();
return true;
}
if (child != null && relativeBounds.contains(x, y))
return ContainerEventHandler.super.mouseClicked(
x - relativeBounds.left,
y - relativeBounds.top - scrollerOffset(),
button
);
return false;
}
@Override
public boolean mouseReleased(double x, double y, int button) {
mouseDown = false;
if (child != null && relativeBounds.contains(x, y))
return ContainerEventHandler.super.mouseReleased(
x - relativeBounds.left,
y - relativeBounds.top - scrollerOffset(),
button
);
return false;
}
@Override
public boolean mouseDragged(double x, double y, int button, double x2, double y2) {
if (mouseDown) {
int delta = (int) y - mouseDownY;
scrollerY = scrollerDownY + delta;
return true;
}
if (child != null && relativeBounds.contains(x, y))
return ContainerEventHandler.super.mouseDragged(
x - relativeBounds.left,
y - relativeBounds.top - scrollerOffset(),
button,
x2,
y2
);
return false;
}
@Override
public boolean mouseScrolled(double x, double y, double delta) {
boolean didCapture = false;
if (child != null && relativeBounds.contains(x, y)) {
didCapture = ContainerEventHandler.super.mouseScrolled(
x - relativeBounds.left,
y - relativeBounds.top - scrollerOffset(),
delta
);
}
if (!didCapture) {
scrollerY = Math.max(0, Math.min(travel, scrollerY)) + delta;
return true;
} else {
System.out.println("Child did capture scroll");
}
return false;
}
GuiEventListener focused;
@Override
@Nullable
public GuiEventListener getFocused() {
return focused;
}
@Override
public void setFocused(@Nullable GuiEventListener guiEventListener) {
focused = guiEventListener;
}
boolean dragging;
@Override
public boolean isDragging() {
return this.dragging;
}
@Override
public void setDragging(boolean bl) {
dragging = bl;
}
@Override
public boolean isMouseOver(double x, double y) {
if (child != null) {
if (child.isMouseOver(x - relativeBounds.left, y - relativeBounds.top - scrollerOffset()))
return true;
}
return relativeBounds.contains(x, y);
}
}

View file

@ -1,217 +0,0 @@
package org.betterx.ui.layout.components;
import org.betterx.ui.layout.values.Size;
import org.betterx.ui.layout.values.Value;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class VerticalStack extends AbstractVerticalStack<VerticalStack> {
public VerticalStack(Value width, Value height) {
super(width, height);
}
public static VerticalStack centered(LayoutComponent<?, ?> c) {
return new VerticalStack(Value.relative(1), Value.relative(1)).addFiller().add(c).addFiller();
}
public static VerticalStack bottom(LayoutComponent<?, ?> c) {
return new VerticalStack(Value.relative(1), Value.relative(1)).add(c).addFiller();
}
@Override
protected VerticalStack addEmpty(Value size) {
this.components.add(new Empty(Value.fixed(0), size));
return this;
}
public HorizontalStack indent(int width) {
var h = new HorizontalStack(Value.fitOrFill(), Value.fit());
h.addSpacer(width);
add(h);
return h;
}
@Override
public HorizontalStack addRow(Value width, Value height) {
return super.addRow(width, height);
}
@Override
public HorizontalStack addRow() {
return super.addRow();
}
@Override
public VerticalStack add(LayoutComponent<?, ?> c) {
return super.add(c);
}
@Override
public VerticalStack addSpacer(int size) {
return super.addSpacer(size);
}
@Override
public VerticalStack addSpacer(float percentage) {
return super.addSpacer(percentage);
}
@Override
public VerticalStack addFiller() {
return super.addFiller();
}
@Override
public Button addButton(
Value width,
Value height,
Component component
) {
return super.addButton(width, height, component);
}
@Override
public Checkbox addCheckbox(
Value width,
Value height,
Component component,
boolean selected
) {
return super.addCheckbox(width, height, component, selected);
}
@Override
public ColorPicker addColorPicker(Value width, Value height, Component titleOrNull, int color) {
return super.addColorPicker(width, height, titleOrNull, color);
}
@Override
public ColorSwatch addColorSwatch(Value width, Value height, int color) {
return super.addColorSwatch(width, height, color);
}
@Override
public Container addContainered(Value width, Value height, LayoutComponent<?, ?> content) {
return super.addContainered(width, height, content);
}
@Override
public HLine addHLine(Value width, Value height) {
return super.addHLine(width, height);
}
@Override
public HLine addHorizontalLine(int height) {
return super.addHorizontalLine(height);
}
@Override
public HLine addHorizontalSeparator(int height) {
return super.addHorizontalSeparator(height);
}
@Override
public Image addIcon(ResourceLocation location, Size resourceSize) {
return super.addIcon(location, resourceSize);
}
@Override
public Image addImage(Value width, Value height, ResourceLocation location, Size resourceSize) {
return super.addImage(width, height, location, resourceSize);
}
@Override
public Input addInput(Value width, Value height, Component titleOrNull, String initialValue) {
return super.addInput(width, height, titleOrNull, initialValue);
}
@Override
public MultiLineText addMultilineText(Value width, Value height, Component text) {
return super.addMultilineText(width, height, text);
}
@Override
public Range<Double> addRange(
Value width,
Value height,
Component titleOrNull,
double minValue,
double maxValue,
double initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Range<Float> addRange(
Value width,
Value height,
Component titleOrNull,
float minValue,
float maxValue,
float initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Range<Integer> addRange(
Value width,
Value height,
Component titleOrNull,
int minValue,
int maxValue,
int initialValue
) {
return super.addRange(width, height, titleOrNull, minValue, maxValue, initialValue);
}
@Override
public Text addText(Value width, Value height, Component text) {
return super.addText(width, height, text);
}
@Override
public VerticalScroll<VanillaScrollerRenderer> addScrollable(LayoutComponent<?, ?> content) {
return super.addScrollable(content);
}
@Override
public VLine addVerticalLine(int width) {
return super.addVerticalLine(width);
}
@Override
public VLine addVerticalSeparator(int width) {
return super.addVerticalSeparator(width);
}
@Override
public VLine addVLine(Value width, Value height) {
return super.addVLine(width, height);
}
@Override
public VerticalScroll<VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
) {
return super.addScrollable(width, height, content);
}
@Override
public Item addItem(ItemStack stack) {
return super.addItem(stack);
}
}

View file

@ -1,55 +0,0 @@
package org.betterx.ui.layout.components.input;
import org.betterx.ui.layout.values.Rectangle;
import net.minecraft.client.gui.components.events.ContainerEventHandler;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.Optional;
@Environment(EnvType.CLIENT)
public interface RelativeContainerEventHandler extends ContainerEventHandler {
Rectangle getInputBounds();
default Optional<GuiEventListener> getChildAt(double d, double e) {
Rectangle r = getInputBounds();
return ContainerEventHandler.super.getChildAt(d, e);
}
default boolean mouseClicked(double d, double e, int i) {
if (getFocused() != null) {
//getFocused().mouseClicked(d, e, i);
}
Rectangle r = getInputBounds();
return ContainerEventHandler.super.mouseClicked(d - r.left, e - r.top, i);
}
default boolean mouseReleased(double d, double e, int i) {
Rectangle r = getInputBounds();
return ContainerEventHandler.super.mouseReleased(d - r.left, e - r.top, i);
}
default boolean mouseDragged(double d, double e, int i, double f, double g) {
Rectangle r = getInputBounds();
return ContainerEventHandler.super.mouseDragged(d - r.left, e - r.top, i, f - r.left, g - r.top);
}
default boolean mouseScrolled(double d, double e, double f) {
Rectangle r = getInputBounds();
return ContainerEventHandler.super.mouseScrolled(d - r.left, e - r.top, f);
}
default boolean isMouseOver(double x, double y) {
Rectangle r = getInputBounds();
boolean res = false;
for (GuiEventListener c : children()) {
res |= c.isMouseOver(x - r.left, y - r.top);
}
return res || r.contains(x, y);
}
}

View file

@ -1,96 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.AbstractVanillaComponentRenderer;
import org.betterx.ui.layout.components.Button;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.GuiComponent;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ButtonRenderer extends AbstractVanillaComponentRenderer<net.minecraft.client.gui.components.Button, Button> {
double deltaSum = 0;
double deltaSum2 = .34;
double deltaSum3 = .12;
@Override
public void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, bounds, clipRect);
deltaSum += deltaTicks * 0.03;
deltaSum2 += deltaTicks * 0.032;
deltaSum3 += deltaTicks * 0.028;
if (getLinkedComponent() != null && getLinkedComponent().isGlowing()) {
RenderHelper.outline(poseStack, 0, 0, bounds.width, bounds.height, ColorUtil.YELLOW);
int len = 2 * bounds.width + 2 * bounds.height;
deltaSum = deltaSum - (int) deltaSum;
int pos = (int) (len * deltaSum);
drawMoving(poseStack, bounds, pos);
drawMoving(poseStack, bounds, pos + 2);
drawMoving(poseStack, bounds, pos + 3);
drawMoving(poseStack, bounds, pos + 4);
drawMoving(poseStack, bounds, pos + 5);
drawMoving(poseStack, bounds, pos + 7);
deltaSum2 = deltaSum2 - (int) deltaSum2;
pos = (int) (len * deltaSum2);
drawMoving(poseStack, bounds, pos + len / 3);
drawMoving(poseStack, bounds, pos + 2 + len / 3);
drawMoving(poseStack, bounds, pos + 3 + len / 3);
drawMoving(poseStack, bounds, pos + 4 + len / 3);
drawMoving(poseStack, bounds, pos + 5 + len / 3);
drawMoving(poseStack, bounds, pos + 7 + len / 3);
deltaSum3 = deltaSum3 - (int) deltaSum3;
pos = (int) (len * deltaSum3);
drawMoving(poseStack, bounds, pos + 2 * len / 3);
drawMoving(poseStack, bounds, pos + 2 + 2 * len / 3);
drawMoving(poseStack, bounds, pos + 3 + 2 * len / 3);
drawMoving(poseStack, bounds, pos + 4 + 2 * len / 3);
drawMoving(poseStack, bounds, pos + 5 + 2 * len / 3);
drawMoving(poseStack, bounds, pos + 7 + 2 * len / 3);
}
}
private void drawMoving(PoseStack poseStack, Rectangle bounds, int pos) {
int bh = bounds.width + bounds.height;
pos = pos % (2 * bh);
int x, y;
/**
* pos <= w : x=pos, y=0
* pos > w && pos<=w+h : x=w, y=pos-w
* pos >w+h && pos<=2w+h : x=2w +h - pos, y=h
* pos>2w+h : x=0, y=2w+2h-pos
*/
if (pos <= bounds.width) {
x = pos;
y = 0;
} else if (pos <= bh) {
x = bounds.width - 1;
y = pos - bounds.width;
} else if (pos <= bh + bounds.width) {
x = bh + bounds.width - pos;
y = bounds.height - 1;
} else {
x = 0;
y = 2 * bh - pos;
}
GuiComponent.fill(poseStack, x, y, x + 1, y + 1, ColorUtil.BLACK);
}
}

View file

@ -1,11 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.components.AbstractVanillaComponentRenderer;
import org.betterx.ui.layout.components.Checkbox;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class CheckboxRenderer extends AbstractVanillaComponentRenderer<net.minecraft.client.gui.components.Checkbox, Checkbox> {
}

View file

@ -1,20 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public interface ComponentRenderer {
void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
);
}

View file

@ -1,13 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.components.AbstractVanillaComponentRenderer;
import org.betterx.ui.layout.components.Input;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class EditBoxRenderer extends AbstractVanillaComponentRenderer<net.minecraft.client.gui.components.EditBox, Input> {
}

View file

@ -1,23 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.vertex.PoseStack;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class NullRenderer implements ComponentRenderer {
@Override
public void renderInBounds(
PoseStack stack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
}
}

View file

@ -1,13 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.components.AbstractVanillaComponentRenderer;
import org.betterx.ui.layout.components.Range;
import org.betterx.ui.vanilla.Slider;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class RangeRenderer<N extends Number> extends AbstractVanillaComponentRenderer<Slider<N>, Range<N>> {
}

View file

@ -1,125 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.values.Rectangle;
import org.betterx.ui.layout.values.Size;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.*;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.resources.ResourceLocation;
import org.joml.Matrix4f;
public class RenderHelper {
public static void outline(PoseStack poseStack, int x0, int y0, int x1, int y1, int color) {
outline(poseStack, x0, y0, x1, y1, color, color);
}
public static void outline(PoseStack poseStack, int x0, int y0, int x1, int y1, int color1, int color2) {
int n;
if (x1 < x0) {
n = x0;
x0 = x1;
x1 = n;
}
if (y1 < y0) {
n = y0;
y0 = y1;
y1 = n;
}
y1--;
x1--;
Matrix4f transform = poseStack.last().pose();
innerHLine(transform, x0, x1, y0, color1);
innerVLine(transform, x0, y0 + 1, y1, color1);
innerHLine(transform, x0 + 1, x1, y1, color2);
innerVLine(transform, x1, y0 + 1, y1 - 1, color2);
}
public static void hLine(PoseStack poseStack, int x0, int x1, int y, int color) {
if (x1 < x0) {
int m = x0;
x0 = x1;
x1 = m;
}
innerHLine(poseStack.last().pose(), x0, x1, y, color);
}
protected static void innerHLine(Matrix4f transform, int x0, int x1, int y, int color) {
innerFill(transform, x0, y, x1 + 1, y + 1, color);
}
public static void vLine(PoseStack poseStack, int x, int y0, int y1, int color) {
if (y1 < y0) {
int m = y0;
y0 = y1;
y1 = m;
}
innerVLine(poseStack.last().pose(), x, y0, y1, color);
}
protected static void innerVLine(Matrix4f transform, int x, int y0, int y1, int color) {
innerFill(transform, x, y0, x + 1, y1 + 1, color);
}
private static void innerFill(Matrix4f transform, int x0, int y0, int x1, int y1, int color) {
float[] cl = ColorUtil.toFloatArray(color);
BufferBuilder bufferBuilder = Tesselator.getInstance().getBuilder();
RenderSystem.enableBlend();
RenderSystem.disableTexture();
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
bufferBuilder.vertex(transform, (float) x0, (float) y1, 0.0F).color(cl[0], cl[1], cl[2], cl[3]).endVertex();
bufferBuilder.vertex(transform, (float) x1, (float) y1, 0.0F).color(cl[0], cl[1], cl[2], cl[3]).endVertex();
bufferBuilder.vertex(transform, (float) x1, (float) y0, 0.0F).color(cl[0], cl[1], cl[2], cl[3]).endVertex();
bufferBuilder.vertex(transform, (float) x0, (float) y0, 0.0F).color(cl[0], cl[1], cl[2], cl[3]).endVertex();
BufferUploader.drawWithShader(bufferBuilder.end());
RenderSystem.enableTexture();
RenderSystem.disableBlend();
}
public static void renderImage(
PoseStack stack,
int left, int top,
ResourceLocation location,
Size resourceSize, Rectangle uvRect,
float alpha
) {
renderImage(stack, left, top, uvRect.width, uvRect.height, location, resourceSize, uvRect, alpha);
}
public static void renderImage(
PoseStack stack,
int left, int top, int width, int height,
ResourceLocation location,
Size resourceSize, Rectangle uvRect,
float alpha
) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, location);
RenderSystem.enableBlend();
RenderSystem.blendFunc(
GlStateManager.SourceFactor.SRC_ALPHA,
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA
);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha);
GuiComponent.blit(
stack,
left, top, width, height,
uvRect.left,
uvRect.top,
uvRect.width,
uvRect.height,
resourceSize.width(),
resourceSize.height()
);
}
}

View file

@ -1,41 +0,0 @@
package org.betterx.ui.layout.components.render;
import org.betterx.ui.layout.values.Rectangle;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public interface ScrollerRenderer {
default int scrollerHeight() {
return 16;
}
default int scrollerWidth() {
return 8;
}
default int scrollerPadding() {
return 2;
}
default Rectangle getScrollerBounds(Rectangle renderBounds) {
return new Rectangle(
renderBounds.right() - this.scrollerWidth(),
renderBounds.top,
this.scrollerWidth(),
renderBounds.height
);
}
default Rectangle getPickerBounds(Rectangle renderBounds, int pickerOffset, int pickerSize) {
return new Rectangle(
renderBounds.left,
renderBounds.top + pickerOffset,
renderBounds.width,
pickerSize
);
}
void renderScrollBar(Rectangle renderBounds, int pickerOffset, int pickerSize);
}

View file

@ -1,26 +0,0 @@
package org.betterx.ui.layout.components.render;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public interface TextProvider {
default Font getFont() {
return Minecraft.getInstance().font;
}
default int getWidth(net.minecraft.network.chat.Component c) {
return getFont().width(c.getVisualOrderText()) + 24;
}
default int getLineHeight(net.minecraft.network.chat.Component c) {
return getFont().lineHeight;
}
default int getHeight(net.minecraft.network.chat.Component c) {
return getLineHeight(c) + 11;
}
}

View file

@ -1,9 +0,0 @@
package org.betterx.ui.layout.values;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public enum Alignment {
MIN, MAX, CENTER
}

View file

@ -1,91 +0,0 @@
package org.betterx.ui.layout.values;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Rectangle {
public static final Rectangle ZERO = new Rectangle(0, 0, 0, 0);
public final int left;
public final int top;
public final int width;
public final int height;
public Rectangle(int left, int top, int width, int height) {
this.left = left;
this.top = top;
this.width = width;
this.height = height;
}
public float aspect() {
return (float) width / height;
}
public Size sizeFromWidth(int width) {
return new Size(width, (int) (width / aspect()));
}
public Size sizeFromHeight(int height) {
return new Size((int) (height * aspect()), height);
}
public Size size(float scale) {
return new Size((int) (width * scale), (int) (height * scale));
}
public Size size() {
return new Size(width, height);
}
public int right() {
return left + width;
}
public int bottom() {
return top + height;
}
public Rectangle movedBy(int left, int top) {
return new Rectangle(this.left + left, this.top + top, this.width, this.height);
}
public Rectangle movedBy(int left, int top, int deltaWidth, int deltaHeight) {
return new Rectangle(this.left + left, this.top + top, this.width + deltaWidth, this.height + deltaHeight);
}
public boolean overlaps(Rectangle r) {
return this.left < r.right() && this.right() > r.left &&
this.top < r.bottom() && this.bottom() > r.top;
}
public boolean contains(int x, int y) {
return x >= left && x <= right() && y >= top && y <= bottom();
}
public boolean contains(double x, double y) {
return x >= left && x <= right() && y >= top && y <= bottom();
}
public Rectangle intersect(Rectangle r) {
if (!overlaps(r)) return ZERO;
int left = Math.max(this.left, r.left);
int top = Math.max(this.top, r.top);
int right = Math.min(this.right(), r.right());
int bottom = Math.min(this.bottom(), r.bottom());
return new Rectangle(left, top, right - left, bottom - top);
}
@Override
public String toString() {
return "rectangle{" +
left +
"x" + top +
", " + right() +
"x" + bottom() +
" [" + width +
"x" + height +
"]}";
}
}

View file

@ -1,11 +0,0 @@
package org.betterx.ui.layout.values;
public record Size(int width, int height) {
public static Size of(int size) {
return new Size(size, size);
}
public static Size of(int width, int height) {
return new Size(width, height);
}
}

View file

@ -1,74 +0,0 @@
package org.betterx.ui.layout.values;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public interface SizeType {
FitContent FIT_CONTENT = new FitContent();
FitContentOrFill FIT_CONTENT_OR_FILL = new FitContentOrFill();
Fill FILL = new Fill();
record Fill() implements SizeType {
}
class FitContentOrFill extends FitContent {
public FitContentOrFill(ContentSizeSupplier contentSize) {
super(contentSize);
}
public FitContentOrFill() {
super();
}
@Override
public FitContentOrFill copyForSupplier(ContentSizeSupplier component) {
return new FitContentOrFill(component);
}
}
class FitContent implements SizeType {
private final ContentSizeSupplier contentSize;
public FitContent(ContentSizeSupplier contentSize) {
this.contentSize = contentSize;
}
@FunctionalInterface
public interface ContentSizeSupplier {
int get();
}
public FitContent() {
this(null);
}
public FitContent copyForSupplier(ContentSizeSupplier component) {
return new FitContent(component);
}
public ContentSizeSupplier contentSize() {
return contentSize;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
}
record Fixed(int size) implements SizeType {
@Override
public String toString() {
return getClass().getSimpleName() + "(" + size + ")";
}
}
record Relative(double percentage) implements SizeType {
@Override
public String toString() {
return getClass().getSimpleName() + "(" + percentage + ")";
}
}
}

View file

@ -1,110 +0,0 @@
package org.betterx.ui.layout.values;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Value {
private SizeType sizeType;
private int calculatedSize;
public Value(SizeType sizeType) {
this.sizeType = sizeType;
this.calculatedSize = 0;
}
public static Value fixed(int size) {
return new Value(new SizeType.Fixed(size));
}
public static Value relative(double percentage) {
return new Value(new SizeType.Relative(percentage));
}
public static Value fill() {
return new Value(SizeType.FILL);
}
public static Value fit() {
return new Value(SizeType.FIT_CONTENT);
}
public static Value fitOrFill() {
return new Value(SizeType.FIT_CONTENT_OR_FILL);
}
public int calculatedSize() {
return calculatedSize;
}
public int setCalculatedSize(int value) {
calculatedSize = value;
return value;
}
public Value attachComponent(SizeType.FitContent.ContentSizeSupplier c) {
if (sizeType instanceof SizeType.FitContent fit && fit.contentSize() == null) {
sizeType = fit.copyForSupplier(c);
}
return this;
}
public int calculateFixed() {
return calculate(0);
}
public double calculateRelative() {
if (sizeType instanceof SizeType.Relative rel) {
return rel.percentage();
}
return 0;
}
public int calculate(int parentSize) {
calculatedSize = 0;
if (sizeType instanceof SizeType.Fixed fixed) {
calculatedSize = fixed.size();
} else if (sizeType instanceof SizeType.FitContent fit) {
calculatedSize = fit.contentSize().get();
} else if (sizeType instanceof SizeType.Relative rel) {
calculatedSize = (int) (parentSize * rel.percentage());
}
return calculatedSize;
}
public int calculateOrFill(int parentSize) {
calculatedSize = calculate(parentSize);
if (sizeType instanceof SizeType.Fill || sizeType instanceof SizeType.FitContentOrFill) {
calculatedSize = Math.max(parentSize, calculatedSize);
}
return calculatedSize;
}
public double fillWeight() {
if (sizeType instanceof SizeType.Fill fill || sizeType instanceof SizeType.FitContentOrFill) {
return 1;
}
return 0;
}
public int fill(int fillSize) {
return fill(fillSize, fillWeight());
}
public int fill(int fillSize, double totalFillWeight) {
if (sizeType instanceof SizeType.Fill) {
calculatedSize = (int) Math.round(fillSize * (fillWeight() / totalFillWeight));
}
return calculatedSize;
}
@Override
public String toString() {
return "DynamicSize{" +
"sizeType=" + sizeType.getClass().getSimpleName() +
", calculatedSize=" + calculatedSize +
'}';
}
}

View file

@ -1,150 +0,0 @@
package org.betterx.ui.vanilla;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ConfirmLinkScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public abstract class LayoutScreen extends Screen {
protected final int topPadding;
protected final int bottomPadding;
protected final int sidePadding;
public LayoutScreen(Component component) {
this(null, component, 20, 10, 20);
}
public LayoutScreen(@Nullable Screen parent, Component component) {
this(parent, component, 20, 10, 20);
}
public LayoutScreen(
@Nullable Screen parent,
Component component,
int topPadding,
int bottomPadding,
int sidePadding
) {
super(component);
this.parent = parent;
this.topPadding = topPadding;
this.bottomPadding = topPadding;
this.sidePadding = sidePadding;
}
@Nullable
protected Panel main;
@Nullable
public final Screen parent;
protected abstract LayoutComponent<?, ?> initContent();
protected void openLink(String uri) {
ConfirmLinkScreen cls = new ConfirmLinkScreen(bl -> {
if (bl) {
Util.getPlatform().openUri(uri);
}
this.minecraft.setScreen(this);
}, uri, true);
Minecraft.getInstance().setScreen(cls);
}
@Override
protected final void init() {
super.init();
main = new Panel(this.width, this.height);
main.setChild(addTitle(initContent()));
main.calculateLayout();
addRenderableWidget(main);
}
protected LayoutComponent<?, ?> buildTitle() {
var text = new Text(fit(), fit(), title).centerHorizontal()
.setColor(ColorUtil.WHITE)
.setDebugName("title");
return text;
}
protected LayoutComponent<?, ?> addTitle(LayoutComponent<?, ?> content) {
VerticalStack rows = new VerticalStack(fill(), fill()).setDebugName("title stack");
if (topPadding > 0) rows.addSpacer(topPadding);
rows.add(buildTitle());
rows.addSpacer(15);
rows.add(content);
if (bottomPadding > 0) rows.addSpacer(bottomPadding);
if (sidePadding <= 0) return rows;
HorizontalStack cols = new HorizontalStack(fill(), fill()).setDebugName("padded side");
cols.addSpacer(sidePadding);
cols.add(rows);
cols.addSpacer(sidePadding);
return cols;
}
protected void renderBackground(PoseStack poseStack, int i, int j, float f) {
renderDirtBackground(i);
}
@Override
public void render(PoseStack poseStack, int i, int j, float f) {
renderBackground(poseStack, i, j, f);
super.render(poseStack, i, j, f);
}
@Override
public void onClose() {
this.minecraft.setScreen(parent);
}
@Override
public boolean isPauseScreen() {
return true;
}
public static Value fit() {
return Value.fit();
}
public static Value fitOrFill() {
return Value.fitOrFill();
}
public static Value fill() {
return Value.fill();
}
public static Value fixed(int size) {
return Value.fixed(size);
}
public static Value relative(double percentage) {
return Value.relative(percentage);
}
public static MutableComponent translatable(String key) {
return Component.translatable(key);
}
public static MutableComponent literal(String content) {
return Component.literal(content);
}
}

View file

@ -1,51 +0,0 @@
package org.betterx.ui.vanilla;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.LayoutComponent;
import org.betterx.ui.layout.values.Size;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
public abstract class LayoutScreenWithIcon extends LayoutScreen {
protected final ResourceLocation icon;
public LayoutScreenWithIcon(ResourceLocation icon, Component component) {
this(null, icon, component);
}
public LayoutScreenWithIcon(
@Nullable Screen parent,
ResourceLocation icon,
Component component
) {
this(parent, icon, component, 20, 10, 20);
}
public LayoutScreenWithIcon(
@Nullable Screen parent,
ResourceLocation icon,
Component component,
int topPadding,
int bottomPadding,
int sidePadding
) {
super(parent, component, topPadding, bottomPadding, sidePadding);
this.icon = icon;
}
@Override
protected LayoutComponent<?, ?> buildTitle() {
LayoutComponent<?, ?> title = super.buildTitle();
HorizontalStack row = new HorizontalStack(fill(), fit()).setDebugName("title bar");
row.addFiller();
row.addIcon(icon, Size.of(512)).setDebugName("icon");
row.addSpacer(4);
row.add(title);
row.addFiller();
return row;
}
}

View file

@ -1,115 +0,0 @@
package org.betterx.ui.vanilla;
import net.minecraft.client.gui.components.AbstractSliderButton;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
public class Slider<N extends Number> extends AbstractSliderButton {
@FunctionalInterface
public interface SliderValueChanged<N extends Number> {
void now(Slider<N> slider, N newValue);
}
protected final Component title;
protected final N minValue;
protected final N maxValue;
protected final SliderValueChanged<N> onChange;
public Slider(
int x,
int y,
int width,
int height,
N minValue,
N maxValue,
N initialValue,
SliderValueChanged<N> onChange
) {
this(x, y, width, height, null, minValue, maxValue, initialValue, onChange);
}
public Slider(
int x,
int y,
int width,
int height,
Component title,
N minValue,
N maxValue,
N initialValue,
SliderValueChanged<N> onChange
) {
super(
x,
y,
width,
height,
CommonComponents.EMPTY,
(initialValue.doubleValue() - minValue.doubleValue()) / (maxValue.doubleValue() - minValue.doubleValue())
);
this.title = title;
this.minValue = minValue;
this.maxValue = maxValue;
this.onChange = onChange;
this.updateMessage();
}
public N currentValue() {
Double res = value * (maxValue.doubleValue() - minValue.doubleValue()) + minValue.doubleValue();
if (minValue instanceof Integer) {
return (N) (Integer) res.intValue();
}
if (minValue instanceof Byte) {
return (N) (Byte) res.byteValue();
}
if (minValue instanceof Short) {
return (N) (Short) res.shortValue();
}
if (minValue instanceof Long) {
return (N) (Long) res.longValue();
}
if (minValue instanceof Float) {
return (N) (Float) res.floatValue();
}
if (minValue instanceof Double) {
return (N) res;
}
throw new IllegalStateException("The Type " + minValue.getClass()
.getSimpleName() + " is not nativley supported. Please override currentValue with an implementation ofr that type");
}
protected String valueToString(N value) {
if (minValue instanceof Float || minValue instanceof Double) {
double v = value.doubleValue();
double m = maxValue.doubleValue();
if (m > 1000)
return "" + (int) v;
if (m > 100)
return String.format("%.1f", v);
if (m > 10)
return String.format("%.2f", v);
return String.format("%.4f", v);
}
return "" + value;
}
public Component getValueComponent(N value) {
return Component.literal("" + this.valueToString(value));
}
@Override
protected void updateMessage() {
final Component valueComponent = getValueComponent(this.currentValue());
this.setMessage(title == null ? valueComponent : title.copy()
.append(": ")
.append(valueComponent));
}
@Override
protected void applyValue() {
onChange.now(this, currentValue());
}
}

View file

@ -1,54 +0,0 @@
package org.betterx.ui.vanilla;
import org.betterx.ui.layout.components.render.ScrollerRenderer;
import org.betterx.ui.layout.values.Rectangle;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.Tesselator;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.GameRenderer;
public class VanillaScrollerRenderer implements ScrollerRenderer {
public static final VanillaScrollerRenderer DEFAULT = new VanillaScrollerRenderer();
@Override
public void renderScrollBar(Rectangle b, int pickerOffset, int pickerSize) {
b = this.getScrollerBounds(b);
Rectangle p = this.getPickerBounds(b, pickerOffset, pickerSize);
Tesselator tesselator = Tesselator.getInstance();
BufferBuilder bufferBuilder = tesselator.getBuilder();
RenderSystem.disableTexture();
RenderSystem.setShader(GameRenderer::getPositionColorShader);
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
//scroller background
bufferBuilder.vertex(b.left, b.bottom(), 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(b.right(), b.bottom(), 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(b.right(), b.top, 0.0D).color(0, 0, 0, 255).endVertex();
bufferBuilder.vertex(b.left, b.top, 0.0D).color(0, 0, 0, 255).endVertex();
//scroll widget shadow
bufferBuilder.vertex(p.left, p.bottom(), 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(p.right(), p.bottom(), 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(p.right(), p.top, 0.0D).color(128, 128, 128, 255).endVertex();
bufferBuilder.vertex(p.left, p.top, 0.0D).color(128, 128, 128, 255).endVertex();
//scroll widget
bufferBuilder.vertex(p.left, p.bottom() - 1, 0.0D)
.color(192, 192, 192, 255)
.endVertex();
bufferBuilder.vertex(p.right() - 1, p.bottom() - 1, 0.0D)
.color(192, 192, 192, 255)
.endVertex();
bufferBuilder.vertex(p.right() - 1, p.top, 0.0D).color(192, 192, 192, 255).endVertex();
bufferBuilder.vertex(p.left, p.top, 0.0D).color(192, 192, 192, 255).endVertex();
tesselator.end();
}
}