[Change] Migrated ModMenu Screen to new Layout Engine
This commit is contained in:
parent
399a2c8a4e
commit
bebd7e1c70
21 changed files with 289 additions and 152 deletions
|
@ -1,60 +1,65 @@
|
||||||
package org.betterx.bclib.client.gui.modmenu;
|
package org.betterx.bclib.client.gui.modmenu;
|
||||||
|
|
||||||
import org.betterx.bclib.client.gui.gridlayout.*;
|
import org.betterx.bclib.BCLib;
|
||||||
import org.betterx.bclib.config.ConfigKeeper;
|
import org.betterx.bclib.config.ConfigKeeper;
|
||||||
import org.betterx.bclib.config.Configs;
|
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.layout.values.Value;
|
||||||
|
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 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;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class MainScreen extends GridScreen {
|
public class MainScreen extends LayoutScreenWithIcon {
|
||||||
|
static final ResourceLocation BCLIB_LOGO_LOCATION = new ResourceLocation(BCLib.MOD_ID, "icon.png");
|
||||||
|
|
||||||
public MainScreen(@Nullable Screen parent) {
|
public MainScreen(@Nullable Screen parent) {
|
||||||
super(parent, Component.translatable("title.bclib.modmenu.main"), 10, false);
|
super(parent, BCLIB_LOGO_LOCATION, Component.translatable("title.bclib.modmenu.main"), 10, 10, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T> Component getComponent(NamedPathConfig config, ConfigTokenDescription<T> option, String type) {
|
protected <T> Component getComponent(NamedPathConfig config, ConfigTokenDescription<T> option, String type) {
|
||||||
return Component.translatable(type + ".config." + config.configID + option.getPath());
|
return Component.translatable(type + ".config." + config.configID + option.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<GridWidgetWithEnabledState, Supplier<Boolean>> dependentWidgets = new HashMap<>();
|
Map<Checkbox, Supplier<Boolean>> dependentWidgets = new HashMap<>();
|
||||||
|
|
||||||
protected void updateEnabledState() {
|
protected void updateEnabledState() {
|
||||||
dependentWidgets.forEach((cb, supl) -> cb.setEnabled(supl.get()));
|
dependentWidgets.forEach((cb, supl) -> cb.setEnabled(supl.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> void addRow(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<T> option) {
|
protected <T> void addRow(VerticalStack grid, NamedPathConfig config, ConfigTokenDescription<T> option) {
|
||||||
if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(option.token.type)) {
|
if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(option.token.type)) {
|
||||||
addCheckbox(grid, config, (ConfigTokenDescription<Boolean>) option);
|
addCheckbox(grid, config, (ConfigTokenDescription<Boolean>) option);
|
||||||
}
|
}
|
||||||
|
|
||||||
grid.addSpacerRow(2);
|
grid.addSpacer(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void addCheckbox(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<Boolean> option) {
|
protected void addCheckbox(VerticalStack grid, NamedPathConfig config, ConfigTokenDescription<Boolean> option) {
|
||||||
if (option.topPadding > 0) {
|
if (option.topPadding > 0) {
|
||||||
grid.addSpacerRow(option.topPadding);
|
grid.addSpacer(option.topPadding);
|
||||||
}
|
}
|
||||||
GridRow row = grid.addRow();
|
HorizontalStack row = grid.addRow();
|
||||||
if (option.leftPadding > 0) {
|
if (option.leftPadding > 0) {
|
||||||
row.addSpacer(option.leftPadding);
|
row.addSpacer(option.leftPadding);
|
||||||
}
|
}
|
||||||
GridCheckboxCell cb = row.addCheckbox(
|
Checkbox cb = row.addCheckbox(
|
||||||
|
Value.fit(), Value.fit(),
|
||||||
getComponent(config, option, "title"),
|
getComponent(config, option, "title"),
|
||||||
config.getRaw(option.token),
|
config.getRaw(option.token),
|
||||||
font,
|
(caller, state) -> {
|
||||||
(state) -> {
|
|
||||||
config.set(option.token, state);
|
config.set(option.token, state);
|
||||||
updateEnabledState();
|
updateEnabledState();
|
||||||
}
|
}
|
||||||
|
@ -71,34 +76,39 @@ public class MainScreen extends GridScreen {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initLayout() {
|
protected LayoutComponent initContent() {
|
||||||
final int BUTTON_HEIGHT = 20;
|
|
||||||
|
VerticalStack content = new VerticalStack(Value.fit(), Value.fit());
|
||||||
|
|
||||||
Configs.GENERATOR_CONFIG.getAllOptions()
|
Configs.GENERATOR_CONFIG.getAllOptions()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(o -> !o.hidden)
|
.filter(o -> !o.hidden)
|
||||||
.forEach(o -> addRow(grid, Configs.GENERATOR_CONFIG, o));
|
.forEach(o -> addRow(content, Configs.GENERATOR_CONFIG, o));
|
||||||
grid.addSpacerRow(12);
|
content.addSpacer(12);
|
||||||
Configs.MAIN_CONFIG.getAllOptions()
|
Configs.MAIN_CONFIG.getAllOptions()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(o -> !o.hidden)
|
.filter(o -> !o.hidden)
|
||||||
.forEach(o -> addRow(grid, Configs.MAIN_CONFIG, o));
|
.forEach(o -> addRow(content, Configs.MAIN_CONFIG, o));
|
||||||
grid.addSpacerRow(12);
|
content.addSpacer(12);
|
||||||
Configs.CLIENT_CONFIG.getAllOptions()
|
Configs.CLIENT_CONFIG.getAllOptions()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(o -> !o.hidden)
|
.filter(o -> !o.hidden)
|
||||||
.forEach(o -> addRow(grid, Configs.CLIENT_CONFIG, o));
|
.forEach(o -> addRow(content, Configs.CLIENT_CONFIG, o));
|
||||||
|
|
||||||
grid.addSpacerRow(15);
|
|
||||||
GridRow row = grid.addRow();
|
VerticalStack grid = new VerticalStack(Value.fill(), Value.fill());
|
||||||
|
grid.add(VerticalScroll.create(Value.fill(), Value.fill(), content));
|
||||||
|
grid.addSpacer(8);
|
||||||
|
HorizontalStack row = grid.addRow();
|
||||||
row.addFiller();
|
row.addFiller();
|
||||||
row.addButton(CommonComponents.GUI_DONE, BUTTON_HEIGHT, font, (button) -> {
|
grid.addButton(Value.fit(), Value.fit(), CommonComponents.GUI_DONE, (button) -> {
|
||||||
Configs.CLIENT_CONFIG.saveChanges();
|
Configs.CLIENT_CONFIG.saveChanges();
|
||||||
Configs.GENERATOR_CONFIG.saveChanges();
|
Configs.GENERATOR_CONFIG.saveChanges();
|
||||||
Configs.MAIN_CONFIG.saveChanges();
|
Configs.MAIN_CONFIG.saveChanges();
|
||||||
onClose();
|
onClose();
|
||||||
});
|
}).alignRight();
|
||||||
grid.addSpacerRow(10);
|
return grid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ 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.ColorUtil;
|
||||||
import org.betterx.ui.layout.components.*;
|
import org.betterx.ui.layout.components.*;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Size;
|
import org.betterx.ui.layout.values.Size;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
import org.betterx.ui.vanilla.LayoutScreen;
|
import org.betterx.ui.vanilla.LayoutScreen;
|
||||||
|
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
@ -24,36 +24,36 @@ public class TestScreen extends LayoutScreen {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected org.betterx.ui.layout.components.Component<?> initContent() {
|
protected LayoutComponent<?> initContent() {
|
||||||
VerticalStack rows = new VerticalStack(DynamicSize.fit(), DynamicSize.fitOrFill());
|
VerticalStack rows = new VerticalStack(Value.fit(), Value.fitOrFill());
|
||||||
|
|
||||||
rows.addFiller();
|
rows.addFiller();
|
||||||
rows.add(new Text(
|
rows.add(new Text(
|
||||||
DynamicSize.fitOrFill(), DynamicSize.fixed(20),
|
Value.fitOrFill(), Value.fixed(20),
|
||||||
Component.literal("Some Text")
|
Component.literal("Some Text")
|
||||||
).alignRight()
|
).alignRight()
|
||||||
);
|
);
|
||||||
rows.add(new Text(
|
rows.add(new Text(
|
||||||
DynamicSize.fitOrFill(), DynamicSize.fixed(20),
|
Value.fitOrFill(), Value.fixed(20),
|
||||||
Component.literal("Some other, longer Text")
|
Component.literal("Some other, longer Text")
|
||||||
).centerHorizontal()
|
).centerHorizontal()
|
||||||
);
|
);
|
||||||
rows.addSpacer(16);
|
rows.addSpacer(16);
|
||||||
rows.add(new Image(
|
rows.add(new Image(
|
||||||
DynamicSize.fixed(24), DynamicSize.fixed(24),
|
Value.fixed(24), Value.fixed(24),
|
||||||
BCLib.makeID("icon.png"),
|
BCLib.makeID("icon.png"),
|
||||||
new Size(512, 512)
|
new Size(512, 512)
|
||||||
).centerHorizontal()
|
).centerHorizontal()
|
||||||
);
|
);
|
||||||
rows.add(new MultiLineText(
|
rows.add(new MultiLineText(
|
||||||
DynamicSize.fill(), DynamicSize.fit(),
|
Value.fill(), Value.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(ColorUtil.LIGHT_PURPLE).centerHorizontal()
|
||||||
);
|
);
|
||||||
rows.addSpacer(16);
|
rows.addSpacer(16);
|
||||||
rows.add(new Range<>(
|
rows.add(new Range<>(
|
||||||
DynamicSize.fill(), DynamicSize.fit(),
|
Value.fill(), Value.fit(),
|
||||||
Component.literal("Integer"),
|
Component.literal("Integer"),
|
||||||
10, 90, 20,
|
10, 90, 20,
|
||||||
(slider, value) -> {
|
(slider, value) -> {
|
||||||
|
@ -62,7 +62,7 @@ public class TestScreen extends LayoutScreen {
|
||||||
));
|
));
|
||||||
rows.addSpacer(8);
|
rows.addSpacer(8);
|
||||||
rows.add(new Range<>(
|
rows.add(new Range<>(
|
||||||
DynamicSize.fill(), DynamicSize.fit(),
|
Value.fill(), Value.fit(),
|
||||||
Component.literal("Float"),
|
Component.literal("Float"),
|
||||||
10f, 90f, 20f,
|
10f, 90f, 20f,
|
||||||
(slider, value) -> {
|
(slider, value) -> {
|
||||||
|
@ -71,7 +71,7 @@ public class TestScreen extends LayoutScreen {
|
||||||
));
|
));
|
||||||
rows.addSpacer(16);
|
rows.addSpacer(16);
|
||||||
Checkbox cb1 = new Checkbox(
|
Checkbox cb1 = new Checkbox(
|
||||||
DynamicSize.fit(), DynamicSize.fit(),
|
Value.fit(), Value.fit(),
|
||||||
Component.literal("Some Sub-State"),
|
Component.literal("Some Sub-State"),
|
||||||
false, true,
|
false, true,
|
||||||
(checkbox, value) -> {
|
(checkbox, value) -> {
|
||||||
|
@ -79,7 +79,7 @@ public class TestScreen extends LayoutScreen {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
rows.add(new Checkbox(
|
rows.add(new Checkbox(
|
||||||
DynamicSize.fit(), DynamicSize.fit(),
|
Value.fit(), Value.fit(),
|
||||||
Component.literal("Some Selectable State"),
|
Component.literal("Some Selectable State"),
|
||||||
false, true,
|
false, true,
|
||||||
(checkbox, value) -> {
|
(checkbox, value) -> {
|
||||||
|
@ -90,7 +90,7 @@ public class TestScreen extends LayoutScreen {
|
||||||
rows.add(cb1);
|
rows.add(cb1);
|
||||||
rows.addSpacer(16);
|
rows.addSpacer(16);
|
||||||
rows.add(new Button(
|
rows.add(new Button(
|
||||||
DynamicSize.fit(), DynamicSize.fit(),
|
Value.fit(), Value.fit(),
|
||||||
Component.literal("test"),
|
Component.literal("test"),
|
||||||
(bt) -> {
|
(bt) -> {
|
||||||
System.out.println("clicked test");
|
System.out.println("clicked test");
|
||||||
|
@ -101,7 +101,7 @@ public class TestScreen extends LayoutScreen {
|
||||||
);
|
);
|
||||||
rows.addSpacer(8);
|
rows.addSpacer(8);
|
||||||
rows.add(new Button(
|
rows.add(new Button(
|
||||||
DynamicSize.fit(), DynamicSize.fit(),
|
Value.fit(), Value.fit(),
|
||||||
Component.literal("Hello World"),
|
Component.literal("Hello World"),
|
||||||
(bt) -> {
|
(bt) -> {
|
||||||
System.out.println("clicked hello");
|
System.out.println("clicked hello");
|
||||||
|
@ -112,6 +112,6 @@ public class TestScreen extends LayoutScreen {
|
||||||
);
|
);
|
||||||
rows.addFiller();
|
rows.addFiller();
|
||||||
|
|
||||||
return HorizontalStack.centered(VerticalScroll.create(DynamicSize.fit(), DynamicSize.relative(1), rows));
|
return HorizontalStack.centered(VerticalScroll.create(Value.fit(), Value.relative(1), rows));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,14 @@ package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
||||||
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
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 com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
@ -16,14 +19,14 @@ import java.util.List;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public abstract class AbstractStack<R extends ComponentRenderer, T extends AbstractStack<R, T>> extends Component<R> implements RelativeContainerEventHandler {
|
public abstract class AbstractStack<R extends ComponentRenderer, T extends AbstractStack<R, T>> extends LayoutComponent<R> implements RelativeContainerEventHandler {
|
||||||
protected final List<Component<?>> components = new LinkedList<>();
|
protected final List<LayoutComponent<?>> components = new LinkedList<>();
|
||||||
|
|
||||||
public AbstractStack(DynamicSize width, DynamicSize height) {
|
public AbstractStack(Value width, Value height) {
|
||||||
this(width, height, null);
|
this(width, height, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractStack(DynamicSize width, DynamicSize height, R renderer) {
|
public AbstractStack(Value width, Value height, R renderer) {
|
||||||
super(width, height, renderer);
|
super(width, height, renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,28 +56,28 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
|
||||||
Rectangle clipRect
|
Rectangle clipRect
|
||||||
) {
|
) {
|
||||||
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
c.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
c.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T add(Component<?> c) {
|
public T add(LayoutComponent<?> c) {
|
||||||
this.components.add(c);
|
this.components.add(c);
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract T addEmpty(DynamicSize size);
|
protected abstract T addEmpty(Value size);
|
||||||
|
|
||||||
public T addSpacer(int size) {
|
public T addSpacer(int size) {
|
||||||
return addEmpty(DynamicSize.fixed(size));
|
return addEmpty(Value.fixed(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public T addSpacer(float percentage) {
|
public T addSpacer(float percentage) {
|
||||||
return addEmpty(DynamicSize.relative(percentage));
|
return addEmpty(Value.relative(percentage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public T addFiller() {
|
public T addFiller() {
|
||||||
return addEmpty(DynamicSize.fill());
|
return addEmpty(Value.fill());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,5 +114,46 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
|
||||||
public void setFocused(@Nullable GuiEventListener guiEventListener) {
|
public void setFocused(@Nullable GuiEventListener guiEventListener) {
|
||||||
focused = guiEventListener;
|
focused = guiEventListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Image addIcon(ResourceLocation location, Size resourceSize) {
|
||||||
|
Image i = new Image(Value.fixed(24), Value.fixed(24), location, resourceSize);
|
||||||
|
add(i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image addImage(Value width, Value height, ResourceLocation location, Size resourceSize) {
|
||||||
|
Image i = new Image(width, height, location, resourceSize);
|
||||||
|
add(i);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Checkbox addCheckbox(
|
||||||
|
Value width, Value height, Component component,
|
||||||
|
boolean selected,
|
||||||
|
Checkbox.SelectionChanged onSelectionChange
|
||||||
|
) {
|
||||||
|
Checkbox c = new Checkbox(width, height, component, selected, true, onSelectionChange);
|
||||||
|
add(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button addButton(
|
||||||
|
Value width, Value height,
|
||||||
|
Component component,
|
||||||
|
net.minecraft.client.gui.components.Button.OnPress onPress
|
||||||
|
) {
|
||||||
|
return addButton(width, height, component, onPress, net.minecraft.client.gui.components.Button.NO_TOOLTIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button addButton(
|
||||||
|
Value width, Value height,
|
||||||
|
Component component,
|
||||||
|
net.minecraft.client.gui.components.Button.OnPress onPress,
|
||||||
|
net.minecraft.client.gui.components.Button.OnTooltip onTooltip
|
||||||
|
) {
|
||||||
|
Button b = new Button(width, height, component, onPress, onTooltip);
|
||||||
|
add(b);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.minecraft.client.gui.components.AbstractWidget;
|
import net.minecraft.client.gui.components.AbstractWidget;
|
||||||
|
|
||||||
public abstract class AbstractVanillaComponent<C extends AbstractWidget, V extends AbstractVanillaComponent<C, V>> extends Component<AbstractVanillaComponentRenderer<C, V>> {
|
public abstract class AbstractVanillaComponent<C extends AbstractWidget, V extends AbstractVanillaComponent<C, V>> extends LayoutComponent<AbstractVanillaComponentRenderer<C, V>> {
|
||||||
protected C vanillaComponent;
|
protected C vanillaComponent;
|
||||||
protected final net.minecraft.network.chat.Component component;
|
protected final net.minecraft.network.chat.Component component;
|
||||||
protected float alpha = 1.0f;
|
protected float alpha = 1.0f;
|
||||||
protected boolean enabled = true;
|
protected boolean enabled = true;
|
||||||
|
|
||||||
public AbstractVanillaComponent(
|
public AbstractVanillaComponent(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
AbstractVanillaComponentRenderer<C, V> renderer,
|
AbstractVanillaComponentRenderer<C, V> renderer,
|
||||||
net.minecraft.network.chat.Component component
|
net.minecraft.network.chat.Component component
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.render.ButtonRenderer;
|
import org.betterx.ui.layout.components.render.ButtonRenderer;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
@ -12,8 +12,8 @@ public class Button extends AbstractVanillaComponent<net.minecraft.client.gui.co
|
||||||
final net.minecraft.client.gui.components.Button.OnTooltip onTooltip;
|
final net.minecraft.client.gui.components.Button.OnTooltip onTooltip;
|
||||||
|
|
||||||
public Button(
|
public Button(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
net.minecraft.network.chat.Component component,
|
net.minecraft.network.chat.Component component,
|
||||||
net.minecraft.client.gui.components.Button.OnPress onPress,
|
net.minecraft.client.gui.components.Button.OnPress onPress,
|
||||||
net.minecraft.client.gui.components.Button.OnTooltip onTooltip
|
net.minecraft.client.gui.components.Button.OnTooltip onTooltip
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.render.CheckboxRenderer;
|
import org.betterx.ui.layout.components.render.CheckboxRenderer;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ public class Checkbox extends AbstractVanillaComponent<net.minecraft.client.gui.
|
||||||
private final SelectionChanged onSelectionChange;
|
private final SelectionChanged onSelectionChange;
|
||||||
|
|
||||||
public Checkbox(
|
public Checkbox(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
Component component,
|
Component component,
|
||||||
boolean selected, boolean showLabel,
|
boolean selected, boolean showLabel,
|
||||||
SelectionChanged onSelectionChange
|
SelectionChanged onSelectionChange
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@ import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public abstract class CustomRenderComponent<C extends CustomRenderComponent<C>> extends Component<CustomRenderComponent.CustomRenderRenderer<C>> {
|
public abstract class CustomRenderComponent<C extends CustomRenderComponent<C>> extends LayoutComponent<CustomRenderComponent.CustomRenderRenderer<C>> {
|
||||||
public CustomRenderComponent(
|
public CustomRenderComponent(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height
|
Value height
|
||||||
) {
|
) {
|
||||||
super(width, height, new CustomRenderRenderer<>());
|
super(width, height, new CustomRenderRenderer<>());
|
||||||
renderer.linkedComponent = (C) this;
|
renderer.linkedComponent = (C) this;
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class Empty extends Component {
|
public class Empty extends LayoutComponent {
|
||||||
public Empty(
|
public Empty(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height
|
Value height
|
||||||
) {
|
) {
|
||||||
super(width, height, null);
|
super(width, height, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@ package org.betterx.ui.layout.components;
|
||||||
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
||||||
import org.betterx.ui.layout.components.render.NullRenderer;
|
import org.betterx.ui.layout.components.render.NullRenderer;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack> implements RelativeContainerEventHandler {
|
public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack> implements RelativeContainerEventHandler {
|
||||||
public HorizontalStack(DynamicSize width, DynamicSize height) {
|
public HorizontalStack(Value width, Value height) {
|
||||||
super(width, height);
|
super(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
|
||||||
int freeWidth = Math.max(0, myWidth - fixedWidth);
|
int freeWidth = Math.max(0, myWidth - fixedWidth);
|
||||||
fillWidth(myWidth, freeWidth);
|
fillWidth(myWidth, freeWidth);
|
||||||
|
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
c.updateContainerWidth(c.width.calculatedSize());
|
c.updateContainerWidth(c.width.calculatedSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
|
||||||
protected int updateContainerHeight(int containerHeight) {
|
protected int updateContainerHeight(int containerHeight) {
|
||||||
int myHeight = height.calculateOrFill(containerHeight);
|
int myHeight = height.calculateOrFill(containerHeight);
|
||||||
components.stream().forEach(c -> c.height.calculateOrFill(myHeight));
|
components.stream().forEach(c -> c.height.calculateOrFill(myHeight));
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
c.updateContainerHeight(c.height.calculatedSize());
|
c.updateContainerHeight(c.height.calculatedSize());
|
||||||
}
|
}
|
||||||
return myHeight;
|
return myHeight;
|
||||||
|
@ -45,7 +45,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
|
||||||
super.setRelativeBounds(left, top);
|
super.setRelativeBounds(left, top);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
int delta = relativeBounds.height - c.height.calculatedSize();
|
int delta = relativeBounds.height - c.height.calculatedSize();
|
||||||
if (c.hAlign == Alignment.MIN) delta = 0;
|
if (c.hAlign == Alignment.MIN) delta = 0;
|
||||||
else if (c.hAlign == Alignment.CENTER) delta /= 2;
|
else if (c.hAlign == Alignment.CENTER) delta /= 2;
|
||||||
|
@ -67,16 +67,27 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
|
||||||
return components.stream().map(c -> c.height.calculateFixed()).reduce(0, Integer::max);
|
return components.stream().map(c -> c.height.calculateFixed()).reduce(0, Integer::max);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HorizontalStack centered(Component<?> c) {
|
public static HorizontalStack centered(LayoutComponent<?> c) {
|
||||||
return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).addFiller().add(c).addFiller();
|
return new HorizontalStack(Value.fill(), Value.fill()).addFiller().add(c).addFiller();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HorizontalStack bottom(Component<?> c) {
|
public static HorizontalStack bottom(LayoutComponent<?> c) {
|
||||||
return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).add(c).addFiller();
|
return new HorizontalStack(Value.fill(), Value.fill()).add(c).addFiller();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HorizontalStack addEmpty(DynamicSize size) {
|
protected HorizontalStack addEmpty(Value size) {
|
||||||
this.components.add(new Empty(size, DynamicSize.fixed(0)));
|
this.components.add(new Empty(size, Value.fixed(0)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VerticalStack addColumn(Value width, Value height) {
|
||||||
|
VerticalStack stack = new VerticalStack(width, height);
|
||||||
|
add(stack);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public VerticalStack addColumn() {
|
||||||
|
return addColumn(Value.fit(), Value.fit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
import org.betterx.ui.layout.values.Size;
|
import org.betterx.ui.layout.values.Size;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
@ -21,11 +21,11 @@ public class Image extends CustomRenderComponent {
|
||||||
protected float alpha;
|
protected float alpha;
|
||||||
protected Size resourceSize;
|
protected Size resourceSize;
|
||||||
|
|
||||||
public Image(DynamicSize width, DynamicSize height, ResourceLocation location) {
|
public Image(Value width, Value height, ResourceLocation location) {
|
||||||
this(width, height, location, new Size(16, 16));
|
this(width, height, location, new Size(16, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image(DynamicSize width, DynamicSize height, ResourceLocation location, Size resourceSize) {
|
public Image(Value width, Value height, ResourceLocation location, Size resourceSize) {
|
||||||
super(width, height);
|
super(width, height);
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.uvRect = new Rectangle(0, 0, resourceSize.width(), resourceSize.height());
|
this.uvRect = new Rectangle(0, 0, resourceSize.width(), resourceSize.height());
|
||||||
|
|
|
@ -2,8 +2,8 @@ package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
@ -14,15 +14,15 @@ import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public abstract class Component<R extends ComponentRenderer> implements ComponentWithBounds, GuiEventListener {
|
public abstract class LayoutComponent<R extends ComponentRenderer> implements ComponentWithBounds, GuiEventListener {
|
||||||
protected final R renderer;
|
protected final R renderer;
|
||||||
protected final DynamicSize width;
|
protected final Value width;
|
||||||
protected final DynamicSize height;
|
protected final Value height;
|
||||||
protected Rectangle relativeBounds;
|
protected Rectangle relativeBounds;
|
||||||
protected Alignment vAlign = Alignment.MIN;
|
protected Alignment vAlign = Alignment.MIN;
|
||||||
protected Alignment hAlign = Alignment.MIN;
|
protected Alignment hAlign = Alignment.MIN;
|
||||||
|
|
||||||
public Component(DynamicSize width, DynamicSize height, R renderer) {
|
public LayoutComponent(Value width, Value height, R renderer) {
|
||||||
this.width = width.attachComponent(this::getContentWidth);
|
this.width = width.attachComponent(this::getContentWidth);
|
||||||
this.height = height.attachComponent(this::getContentHeight);
|
this.height = height.attachComponent(this::getContentHeight);
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
|
@ -120,32 +120,32 @@ public abstract class Component<R extends ComponentRenderer> implements Componen
|
||||||
return super.toString() + "(" + relativeBounds + ", " + width.calculatedSize() + "x" + height.calculatedSize() + ")";
|
return super.toString() + "(" + relativeBounds + ", " + width.calculatedSize() + "x" + height.calculatedSize() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> alignTop() {
|
public LayoutComponent<R> alignTop() {
|
||||||
vAlign = Alignment.MIN;
|
vAlign = Alignment.MIN;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> alignBottom() {
|
public LayoutComponent<R> alignBottom() {
|
||||||
vAlign = Alignment.MAX;
|
vAlign = Alignment.MAX;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> centerVertical() {
|
public LayoutComponent<R> centerVertical() {
|
||||||
vAlign = Alignment.CENTER;
|
vAlign = Alignment.CENTER;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> alignLeft() {
|
public LayoutComponent<R> alignLeft() {
|
||||||
hAlign = Alignment.MIN;
|
hAlign = Alignment.MIN;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> alignRight() {
|
public LayoutComponent<R> alignRight() {
|
||||||
hAlign = Alignment.MAX;
|
hAlign = Alignment.MAX;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component<R> centerHorizontal() {
|
public LayoutComponent<R> centerHorizontal() {
|
||||||
hAlign = Alignment.CENTER;
|
hAlign = Alignment.CENTER;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
|
@ -4,20 +4,20 @@ import org.betterx.ui.ColorUtil;
|
||||||
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.components.render.TextProvider;
|
import org.betterx.ui.layout.components.render.TextProvider;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.gui.components.MultiLineLabel;
|
import net.minecraft.client.gui.components.MultiLineLabel;
|
||||||
|
|
||||||
public class MultiLineText extends Component<MultiLineText.MultiLineTextRenderer> {
|
public class MultiLineText extends LayoutComponent<MultiLineText.MultiLineTextRenderer> {
|
||||||
final net.minecraft.network.chat.Component text;
|
final net.minecraft.network.chat.Component text;
|
||||||
int color = ColorUtil.DEFAULT_TEXT;
|
int color = ColorUtil.DEFAULT_TEXT;
|
||||||
protected MultiLineLabel multiLineLabel;
|
protected MultiLineLabel multiLineLabel;
|
||||||
|
|
||||||
public MultiLineText(
|
public MultiLineText(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
final net.minecraft.network.chat.Component text
|
final net.minecraft.network.chat.Component text
|
||||||
) {
|
) {
|
||||||
super(width, height, new MultiLineTextRenderer());
|
super(width, height, new MultiLineTextRenderer());
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class Panel implements ComponentWithBounds, RelativeContainerEventHandler, NarratableEntry, Widget {
|
public class Panel implements ComponentWithBounds, RelativeContainerEventHandler, NarratableEntry, Widget {
|
||||||
protected Component<?> child;
|
protected LayoutComponent<?> child;
|
||||||
List<? extends GuiEventListener> listeners = List.of();
|
List<? extends GuiEventListener> listeners = List.of();
|
||||||
public final Rectangle bounds;
|
public final Rectangle bounds;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ public class Panel implements ComponentWithBounds, RelativeContainerEventHandler
|
||||||
bounds = new Rectangle(left, top, width, height);
|
bounds = new Rectangle(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChild(Component<?> c) {
|
public void setChild(LayoutComponent<?> c) {
|
||||||
this.child = c;
|
this.child = c;
|
||||||
listeners = List.of(c);
|
listeners = List.of(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.betterx.ui.layout.components;
|
package org.betterx.ui.layout.components;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.render.RangeRenderer;
|
import org.betterx.ui.layout.components.render.RangeRenderer;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
import org.betterx.ui.vanilla.Slider;
|
import org.betterx.ui.vanilla.Slider;
|
||||||
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
|
@ -17,8 +17,8 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
|
||||||
private final N initialValue;
|
private final N initialValue;
|
||||||
|
|
||||||
public Range(
|
public Range(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
Component component,
|
Component component,
|
||||||
N minValue,
|
N minValue,
|
||||||
N maxValue,
|
N maxValue,
|
||||||
|
@ -33,8 +33,8 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
public Range(
|
public Range(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
N minValue,
|
N minValue,
|
||||||
N maxValue,
|
N maxValue,
|
||||||
N initialValue,
|
N initialValue,
|
||||||
|
|
|
@ -4,19 +4,19 @@ import org.betterx.ui.ColorUtil;
|
||||||
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.components.render.TextProvider;
|
import org.betterx.ui.layout.components.render.TextProvider;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
|
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;
|
||||||
|
|
||||||
public class Text extends Component<Text.TextRenderer> {
|
public class Text extends LayoutComponent<Text.TextRenderer> {
|
||||||
final net.minecraft.network.chat.Component text;
|
final net.minecraft.network.chat.Component text;
|
||||||
int color = ColorUtil.DEFAULT_TEXT;
|
int color = ColorUtil.DEFAULT_TEXT;
|
||||||
|
|
||||||
public Text(
|
public Text(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
net.minecraft.network.chat.Component text
|
net.minecraft.network.chat.Component text
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -4,8 +4,8 @@ import org.betterx.ui.layout.components.render.ComponentRenderer;
|
||||||
import org.betterx.ui.layout.components.render.NullRenderer;
|
import org.betterx.ui.layout.components.render.NullRenderer;
|
||||||
import org.betterx.ui.layout.components.render.ScrollerRenderer;
|
import org.betterx.ui.layout.components.render.ScrollerRenderer;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
import org.betterx.ui.layout.values.Rectangle;
|
import org.betterx.ui.layout.values.Rectangle;
|
||||||
|
import org.betterx.ui.layout.values.Value;
|
||||||
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
|
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
@ -14,8 +14,8 @@ import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRenderer> extends Component<R> {
|
public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRenderer> extends LayoutComponent<R> {
|
||||||
protected Component<?> child;
|
protected LayoutComponent<?> child;
|
||||||
protected final RS scrollerRenderer;
|
protected final RS scrollerRenderer;
|
||||||
|
|
||||||
protected int dist;
|
protected int dist;
|
||||||
|
@ -24,23 +24,23 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
||||||
protected int travel;
|
protected int travel;
|
||||||
protected int topOffset;
|
protected int topOffset;
|
||||||
|
|
||||||
public VerticalScroll(DynamicSize width, DynamicSize height, RS scrollerRenderer) {
|
public VerticalScroll(Value width, Value height, RS scrollerRenderer) {
|
||||||
this(width, height, scrollerRenderer, null);
|
this(width, height, scrollerRenderer, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerticalScroll(DynamicSize width, DynamicSize height, RS scrollerRenderer, R renderer) {
|
public VerticalScroll(Value width, Value height, RS scrollerRenderer, R renderer) {
|
||||||
super(width, height, renderer);
|
super(width, height, renderer);
|
||||||
this.scrollerRenderer = scrollerRenderer;
|
this.scrollerRenderer = scrollerRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(Component<?> c) {
|
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(LayoutComponent<?> c) {
|
||||||
return create(DynamicSize.relative(1), DynamicSize.relative(1), c);
|
return create(Value.relative(1), Value.relative(1), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(
|
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(
|
||||||
DynamicSize width,
|
Value width,
|
||||||
DynamicSize height,
|
Value height,
|
||||||
Component<?> c
|
LayoutComponent<?> c
|
||||||
) {
|
) {
|
||||||
VerticalScroll<NullRenderer, VanillaScrollerRenderer> res = new VerticalScroll<>(
|
VerticalScroll<NullRenderer, VanillaScrollerRenderer> res = new VerticalScroll<>(
|
||||||
width,
|
width,
|
||||||
|
@ -52,7 +52,7 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChild(Component<?> c) {
|
public void setChild(LayoutComponent<?> c) {
|
||||||
this.child = c;
|
this.child = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,14 @@ package org.betterx.ui.layout.components;
|
||||||
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
import org.betterx.ui.layout.components.input.RelativeContainerEventHandler;
|
||||||
import org.betterx.ui.layout.components.render.NullRenderer;
|
import org.betterx.ui.layout.components.render.NullRenderer;
|
||||||
import org.betterx.ui.layout.values.Alignment;
|
import org.betterx.ui.layout.values.Alignment;
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
import org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> implements RelativeContainerEventHandler {
|
public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> implements RelativeContainerEventHandler {
|
||||||
public VerticalStack(DynamicSize width, DynamicSize height) {
|
public VerticalStack(Value width, Value height) {
|
||||||
super(width, height);
|
super(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
|
||||||
protected int updateContainerWidth(int containerWidth) {
|
protected int updateContainerWidth(int containerWidth) {
|
||||||
int myWidth = width.calculateOrFill(containerWidth);
|
int myWidth = width.calculateOrFill(containerWidth);
|
||||||
components.stream().forEach(c -> c.width.calculateOrFill(myWidth));
|
components.stream().forEach(c -> c.width.calculateOrFill(myWidth));
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
c.updateContainerWidth(c.width.calculatedSize());
|
c.updateContainerWidth(c.width.calculatedSize());
|
||||||
}
|
}
|
||||||
return myWidth;
|
return myWidth;
|
||||||
|
@ -33,7 +33,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
|
||||||
int freeHeight = Math.max(0, myHeight - fixedHeight);
|
int freeHeight = Math.max(0, myHeight - fixedHeight);
|
||||||
fillHeight(myHeight, freeHeight);
|
fillHeight(myHeight, freeHeight);
|
||||||
|
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
c.updateContainerHeight(c.height.calculatedSize());
|
c.updateContainerHeight(c.height.calculatedSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
|
||||||
super.setRelativeBounds(left, top);
|
super.setRelativeBounds(left, top);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
for (Component<?> c : components) {
|
for (LayoutComponent<?> c : components) {
|
||||||
int delta = relativeBounds.width - c.width.calculatedSize();
|
int delta = relativeBounds.width - c.width.calculatedSize();
|
||||||
if (c.hAlign == Alignment.MIN) delta = 0;
|
if (c.hAlign == Alignment.MIN) delta = 0;
|
||||||
else if (c.hAlign == Alignment.CENTER) delta /= 2;
|
else if (c.hAlign == Alignment.CENTER) delta /= 2;
|
||||||
|
@ -67,16 +67,26 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
|
||||||
return (int) (fixedHeight / (1 - percentage));
|
return (int) (fixedHeight / (1 - percentage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VerticalStack centered(Component<?> c) {
|
public static VerticalStack centered(LayoutComponent<?> c) {
|
||||||
return new VerticalStack(DynamicSize.relative(1), DynamicSize.relative(1)).addFiller().add(c).addFiller();
|
return new VerticalStack(Value.relative(1), Value.relative(1)).addFiller().add(c).addFiller();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VerticalStack bottom(Component<?> c) {
|
public static VerticalStack bottom(LayoutComponent<?> c) {
|
||||||
return new VerticalStack(DynamicSize.relative(1), DynamicSize.relative(1)).add(c).addFiller();
|
return new VerticalStack(Value.relative(1), Value.relative(1)).add(c).addFiller();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VerticalStack addEmpty(DynamicSize size) {
|
protected VerticalStack addEmpty(Value size) {
|
||||||
this.components.add(new Empty(DynamicSize.fixed(0), size));
|
this.components.add(new Empty(Value.fixed(0), size));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HorizontalStack addRow(Value width, Value height) {
|
||||||
|
HorizontalStack stack = new HorizontalStack(width, height);
|
||||||
|
add(stack);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HorizontalStack addRow() {
|
||||||
|
return addRow(Value.fit(), Value.fit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
package org.betterx.ui.layout.values;
|
package org.betterx.ui.layout.values;
|
||||||
|
|
||||||
public record Size(int width, int height) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,33 +4,33 @@ import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
|
||||||
@Environment(EnvType.CLIENT)
|
@Environment(EnvType.CLIENT)
|
||||||
public class DynamicSize {
|
public class Value {
|
||||||
private SizeType sizeType;
|
private SizeType sizeType;
|
||||||
private int calculatedSize;
|
private int calculatedSize;
|
||||||
|
|
||||||
public DynamicSize(SizeType sizeType) {
|
public Value(SizeType sizeType) {
|
||||||
this.sizeType = sizeType;
|
this.sizeType = sizeType;
|
||||||
this.calculatedSize = 0;
|
this.calculatedSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DynamicSize fixed(int size) {
|
public static Value fixed(int size) {
|
||||||
return new DynamicSize(new SizeType.Fixed(size));
|
return new Value(new SizeType.Fixed(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DynamicSize relative(double percentage) {
|
public static Value relative(double percentage) {
|
||||||
return new DynamicSize(new SizeType.Relative(percentage));
|
return new Value(new SizeType.Relative(percentage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DynamicSize fill() {
|
public static Value fill() {
|
||||||
return new DynamicSize(SizeType.FILL);
|
return new Value(SizeType.FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DynamicSize fit() {
|
public static Value fit() {
|
||||||
return new DynamicSize(SizeType.FIT_CONTENT);
|
return new Value(SizeType.FIT_CONTENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DynamicSize fitOrFill() {
|
public static Value fitOrFill() {
|
||||||
return new DynamicSize(SizeType.FIT_CONTENT_OR_FILL);
|
return new Value(SizeType.FIT_CONTENT_OR_FILL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int calculatedSize() {
|
public int calculatedSize() {
|
||||||
|
@ -42,7 +42,7 @@ public class DynamicSize {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicSize attachComponent(SizeType.FitContent.ContentSizeSupplier c) {
|
public Value attachComponent(SizeType.FitContent.ContentSizeSupplier c) {
|
||||||
if (sizeType instanceof SizeType.FitContent fit && fit.contentSize() == null) {
|
if (sizeType instanceof SizeType.FitContent fit && fit.contentSize() == null) {
|
||||||
sizeType = fit.copyForSupplier(c);
|
sizeType = fit.copyForSupplier(c);
|
||||||
}
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package org.betterx.ui.vanilla;
|
package org.betterx.ui.vanilla;
|
||||||
|
|
||||||
import org.betterx.ui.layout.components.HorizontalStack;
|
import org.betterx.ui.layout.components.*;
|
||||||
import org.betterx.ui.layout.components.Panel;
|
import org.betterx.ui.layout.values.Value;
|
||||||
import org.betterx.ui.layout.components.Text;
|
|
||||||
import org.betterx.ui.layout.components.VerticalStack;
|
|
||||||
import org.betterx.ui.layout.values.DynamicSize;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.client.gui.screens.Screen;
|
import net.minecraft.client.gui.screens.Screen;
|
||||||
|
@ -49,7 +46,7 @@ public abstract class LayoutScreen extends Screen {
|
||||||
@Nullable
|
@Nullable
|
||||||
public final Screen parent;
|
public final Screen parent;
|
||||||
|
|
||||||
protected abstract org.betterx.ui.layout.components.Component<?> initContent();
|
protected abstract LayoutComponent<?> initContent();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void init() {
|
protected final void init() {
|
||||||
|
@ -61,18 +58,24 @@ public abstract class LayoutScreen extends Screen {
|
||||||
addRenderableWidget(main);
|
addRenderableWidget(main);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected org.betterx.ui.layout.components.Component<?> addTitle(org.betterx.ui.layout.components.Component<?> content) {
|
protected LayoutComponent<?> buildTitle() {
|
||||||
VerticalStack rows = new VerticalStack(DynamicSize.fill(), DynamicSize.fill());
|
|
||||||
|
var text = new Text(Value.fill(), Value.fit(), title).centerHorizontal();
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected LayoutComponent<?> addTitle(LayoutComponent<?> content) {
|
||||||
|
VerticalStack rows = new VerticalStack(Value.fill(), Value.fill());
|
||||||
|
|
||||||
if (topPadding > 0) rows.addSpacer(topPadding);
|
if (topPadding > 0) rows.addSpacer(topPadding);
|
||||||
rows.add(new Text(DynamicSize.fill(), DynamicSize.fit(), title).centerHorizontal());
|
rows.add(buildTitle());
|
||||||
rows.addSpacer(15);
|
rows.addSpacer(15);
|
||||||
rows.add(content);
|
rows.add(content);
|
||||||
if (bottomPadding > 0) rows.addSpacer(bottomPadding);
|
if (bottomPadding > 0) rows.addSpacer(bottomPadding);
|
||||||
|
|
||||||
if (sidePadding <= 0) return rows;
|
if (sidePadding <= 0) return rows;
|
||||||
|
|
||||||
HorizontalStack cols = new HorizontalStack(DynamicSize.fill(), DynamicSize.fill());
|
HorizontalStack cols = new HorizontalStack(Value.fill(), Value.fill());
|
||||||
cols.addSpacer(sidePadding);
|
cols.addSpacer(sidePadding);
|
||||||
cols.add(rows);
|
cols.add(rows);
|
||||||
cols.addSpacer(sidePadding);
|
cols.addSpacer(sidePadding);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
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 org.betterx.ui.layout.values.Value;
|
||||||
|
|
||||||
|
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(Value.fill(), Value.fit());
|
||||||
|
row.addFiller();
|
||||||
|
row.addIcon(icon, Size.of(512));
|
||||||
|
row.addSpacer(4);
|
||||||
|
row.add(title);
|
||||||
|
row.addFiller();
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue