[Change] Migrated ModMenu Screen to new Layout Engine

This commit is contained in:
Frank 2022-07-16 13:55:02 +02:00
parent 399a2c8a4e
commit bebd7e1c70
21 changed files with 289 additions and 152 deletions

View file

@ -2,11 +2,14 @@ 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.DynamicSize;
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.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.Environment;
@ -16,14 +19,14 @@ 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 Component<R> implements RelativeContainerEventHandler {
protected final List<Component<?>> components = new LinkedList<>();
public abstract class AbstractStack<R extends ComponentRenderer, T extends AbstractStack<R, T>> extends LayoutComponent<R> implements RelativeContainerEventHandler {
protected final List<LayoutComponent<?>> components = new LinkedList<>();
public AbstractStack(DynamicSize width, DynamicSize height) {
public AbstractStack(Value width, Value height) {
this(width, height, null);
}
public AbstractStack(DynamicSize width, DynamicSize height, R renderer) {
public AbstractStack(Value width, Value height, R renderer) {
super(width, height, renderer);
}
@ -53,28 +56,28 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
Rectangle 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);
}
}
public T add(Component<?> c) {
public T add(LayoutComponent<?> c) {
this.components.add(c);
return (T) this;
}
protected abstract T addEmpty(DynamicSize size);
protected abstract T addEmpty(Value size);
public T addSpacer(int size) {
return addEmpty(DynamicSize.fixed(size));
return addEmpty(Value.fixed(size));
}
public T addSpacer(float percentage) {
return addEmpty(DynamicSize.relative(percentage));
return addEmpty(Value.relative(percentage));
}
public T addFiller() {
return addEmpty(DynamicSize.fill());
return addEmpty(Value.fill());
}
@Override
@ -111,5 +114,46 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
public void setFocused(@Nullable GuiEventListener 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;
}
}

View file

@ -1,18 +1,18 @@
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;
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 final net.minecraft.network.chat.Component component;
protected float alpha = 1.0f;
protected boolean enabled = true;
public AbstractVanillaComponent(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
AbstractVanillaComponentRenderer<C, V> renderer,
net.minecraft.network.chat.Component component
) {

View file

@ -1,7 +1,7 @@
package org.betterx.ui.layout.components;
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.Environment;
@ -12,8 +12,8 @@ public class Button extends AbstractVanillaComponent<net.minecraft.client.gui.co
final net.minecraft.client.gui.components.Button.OnTooltip onTooltip;
public Button(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
net.minecraft.network.chat.Component component,
net.minecraft.client.gui.components.Button.OnPress onPress,
net.minecraft.client.gui.components.Button.OnTooltip onTooltip

View file

@ -1,7 +1,7 @@
package org.betterx.ui.layout.components;
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;
@ -21,8 +21,8 @@ public class Checkbox extends AbstractVanillaComponent<net.minecraft.client.gui.
private final SelectionChanged onSelectionChange;
public Checkbox(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
Component component,
boolean selected, boolean showLabel,
SelectionChanged onSelectionChange

View file

@ -1,8 +1,8 @@
package org.betterx.ui.layout.components;
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.Value;
import com.mojang.blaze3d.vertex.PoseStack;
@ -10,10 +10,10 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@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(
DynamicSize width,
DynamicSize height
Value width,
Value height
) {
super(width, height, new CustomRenderRenderer<>());
renderer.linkedComponent = (C) this;

View file

@ -1,15 +1,15 @@
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.Environment;
@Environment(EnvType.CLIENT)
public class Empty extends Component {
public class Empty extends LayoutComponent {
public Empty(
DynamicSize width,
DynamicSize height
Value width,
Value height
) {
super(width, height, null);
}

View file

@ -3,14 +3,14 @@ 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.DynamicSize;
import org.betterx.ui.layout.values.Value;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack> implements RelativeContainerEventHandler {
public HorizontalStack(DynamicSize width, DynamicSize height) {
public HorizontalStack(Value width, Value height) {
super(width, height);
}
@ -22,7 +22,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
int freeWidth = Math.max(0, myWidth - fixedWidth);
fillWidth(myWidth, freeWidth);
for (Component<?> c : components) {
for (LayoutComponent<?> c : components) {
c.updateContainerWidth(c.width.calculatedSize());
}
@ -33,7 +33,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
protected int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
components.stream().forEach(c -> c.height.calculateOrFill(myHeight));
for (Component<?> c : components) {
for (LayoutComponent<?> c : components) {
c.updateContainerHeight(c.height.calculatedSize());
}
return myHeight;
@ -45,7 +45,7 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
super.setRelativeBounds(left, top);
int offset = 0;
for (Component<?> c : components) {
for (LayoutComponent<?> c : components) {
int delta = relativeBounds.height - c.height.calculatedSize();
if (c.hAlign == Alignment.MIN) delta = 0;
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);
}
public static HorizontalStack centered(Component<?> c) {
return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).addFiller().add(c).addFiller();
public static HorizontalStack centered(LayoutComponent<?> c) {
return new HorizontalStack(Value.fill(), Value.fill()).addFiller().add(c).addFiller();
}
public static HorizontalStack bottom(Component<?> c) {
return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).add(c).addFiller();
public static HorizontalStack bottom(LayoutComponent<?> c) {
return new HorizontalStack(Value.fill(), Value.fill()).add(c).addFiller();
}
protected HorizontalStack addEmpty(DynamicSize size) {
this.components.add(new Empty(size, DynamicSize.fixed(0)));
protected HorizontalStack addEmpty(Value size) {
this.components.add(new Empty(size, Value.fixed(0)));
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());
}
}

View file

@ -1,8 +1,8 @@
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.Size;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
@ -21,11 +21,11 @@ public class Image extends CustomRenderComponent {
protected float alpha;
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));
}
public Image(DynamicSize width, DynamicSize height, ResourceLocation location, Size resourceSize) {
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());

View file

@ -2,8 +2,8 @@ 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.DynamicSize;
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;
@ -14,15 +14,15 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@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 DynamicSize width;
protected final DynamicSize height;
protected final Value width;
protected final Value height;
protected Rectangle relativeBounds;
protected Alignment vAlign = 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.height = height.attachComponent(this::getContentHeight);
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() + ")";
}
public Component<R> alignTop() {
public LayoutComponent<R> alignTop() {
vAlign = Alignment.MIN;
return this;
}
public Component<R> alignBottom() {
public LayoutComponent<R> alignBottom() {
vAlign = Alignment.MAX;
return this;
}
public Component<R> centerVertical() {
public LayoutComponent<R> centerVertical() {
vAlign = Alignment.CENTER;
return this;
}
public Component<R> alignLeft() {
public LayoutComponent<R> alignLeft() {
hAlign = Alignment.MIN;
return this;
}
public Component<R> alignRight() {
public LayoutComponent<R> alignRight() {
hAlign = Alignment.MAX;
return this;
}
public Component<R> centerHorizontal() {
public LayoutComponent<R> centerHorizontal() {
hAlign = Alignment.CENTER;
return this;
}

View file

@ -4,20 +4,20 @@ 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.DynamicSize;
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;
public class MultiLineText extends Component<MultiLineText.MultiLineTextRenderer> {
public class MultiLineText extends LayoutComponent<MultiLineText.MultiLineTextRenderer> {
final net.minecraft.network.chat.Component text;
int color = ColorUtil.DEFAULT_TEXT;
protected MultiLineLabel multiLineLabel;
public MultiLineText(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
final net.minecraft.network.chat.Component text
) {
super(width, height, new MultiLineTextRenderer());

View file

@ -18,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class Panel implements ComponentWithBounds, RelativeContainerEventHandler, NarratableEntry, Widget {
protected Component<?> child;
protected LayoutComponent<?> child;
List<? extends GuiEventListener> listeners = List.of();
public final Rectangle bounds;
@ -30,7 +30,7 @@ public class Panel implements ComponentWithBounds, RelativeContainerEventHandler
bounds = new Rectangle(left, top, width, height);
}
public void setChild(Component<?> c) {
public void setChild(LayoutComponent<?> c) {
this.child = c;
listeners = List.of(c);
}

View file

@ -1,7 +1,7 @@
package org.betterx.ui.layout.components;
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 net.minecraft.network.chat.Component;
@ -17,8 +17,8 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
private final N initialValue;
public Range(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
Component component,
N minValue,
N maxValue,
@ -33,8 +33,8 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
}
public Range(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
N minValue,
N maxValue,
N initialValue,

View file

@ -4,19 +4,19 @@ 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.DynamicSize;
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;
public class Text extends Component<Text.TextRenderer> {
public class Text extends LayoutComponent<Text.TextRenderer> {
final net.minecraft.network.chat.Component text;
int color = ColorUtil.DEFAULT_TEXT;
public Text(
DynamicSize width,
DynamicSize height,
Value width,
Value height,
net.minecraft.network.chat.Component text
) {

View file

@ -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.ScrollerRenderer;
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.Value;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
@ -14,8 +14,8 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRenderer> extends Component<R> {
protected Component<?> child;
public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRenderer> extends LayoutComponent<R> {
protected LayoutComponent<?> child;
protected final RS scrollerRenderer;
protected int dist;
@ -24,23 +24,23 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
protected int travel;
protected int topOffset;
public VerticalScroll(DynamicSize width, DynamicSize height, RS scrollerRenderer) {
public VerticalScroll(Value width, Value height, RS scrollerRenderer) {
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);
this.scrollerRenderer = scrollerRenderer;
}
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(Component<?> c) {
return create(DynamicSize.relative(1), DynamicSize.relative(1), c);
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(LayoutComponent<?> c) {
return create(Value.relative(1), Value.relative(1), c);
}
public static VerticalScroll<NullRenderer, VanillaScrollerRenderer> create(
DynamicSize width,
DynamicSize height,
Component<?> c
Value width,
Value height,
LayoutComponent<?> c
) {
VerticalScroll<NullRenderer, VanillaScrollerRenderer> res = new VerticalScroll<>(
width,
@ -52,7 +52,7 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
return res;
}
public void setChild(Component<?> c) {
public void setChild(LayoutComponent<?> c) {
this.child = c;
}

View file

@ -4,14 +4,14 @@ 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.DynamicSize;
import org.betterx.ui.layout.values.Value;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> implements RelativeContainerEventHandler {
public VerticalStack(DynamicSize width, DynamicSize height) {
public VerticalStack(Value width, Value height) {
super(width, height);
}
@ -19,7 +19,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
protected int updateContainerWidth(int containerWidth) {
int myWidth = width.calculateOrFill(containerWidth);
components.stream().forEach(c -> c.width.calculateOrFill(myWidth));
for (Component<?> c : components) {
for (LayoutComponent<?> c : components) {
c.updateContainerWidth(c.width.calculatedSize());
}
return myWidth;
@ -33,7 +33,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
int freeHeight = Math.max(0, myHeight - fixedHeight);
fillHeight(myHeight, freeHeight);
for (Component<?> c : components) {
for (LayoutComponent<?> c : components) {
c.updateContainerHeight(c.height.calculatedSize());
}
@ -45,7 +45,7 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
super.setRelativeBounds(left, top);
int offset = 0;
for (Component<?> c : components) {
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;
@ -67,16 +67,26 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
return (int) (fixedHeight / (1 - percentage));
}
public static VerticalStack centered(Component<?> c) {
return new VerticalStack(DynamicSize.relative(1), DynamicSize.relative(1)).addFiller().add(c).addFiller();
public static VerticalStack centered(LayoutComponent<?> c) {
return new VerticalStack(Value.relative(1), Value.relative(1)).addFiller().add(c).addFiller();
}
public static VerticalStack bottom(Component<?> c) {
return new VerticalStack(DynamicSize.relative(1), DynamicSize.relative(1)).add(c).addFiller();
public static VerticalStack bottom(LayoutComponent<?> c) {
return new VerticalStack(Value.relative(1), Value.relative(1)).add(c).addFiller();
}
protected VerticalStack addEmpty(DynamicSize size) {
this.components.add(new Empty(DynamicSize.fixed(0), size));
protected VerticalStack addEmpty(Value size) {
this.components.add(new Empty(Value.fixed(0), size));
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());
}
}

View file

@ -1,4 +1,11 @@
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

@ -4,33 +4,33 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class DynamicSize {
public class Value {
private SizeType sizeType;
private int calculatedSize;
public DynamicSize(SizeType sizeType) {
public Value(SizeType sizeType) {
this.sizeType = sizeType;
this.calculatedSize = 0;
}
public static DynamicSize fixed(int size) {
return new DynamicSize(new SizeType.Fixed(size));
public static Value fixed(int size) {
return new Value(new SizeType.Fixed(size));
}
public static DynamicSize relative(double percentage) {
return new DynamicSize(new SizeType.Relative(percentage));
public static Value relative(double percentage) {
return new Value(new SizeType.Relative(percentage));
}
public static DynamicSize fill() {
return new DynamicSize(SizeType.FILL);
public static Value fill() {
return new Value(SizeType.FILL);
}
public static DynamicSize fit() {
return new DynamicSize(SizeType.FIT_CONTENT);
public static Value fit() {
return new Value(SizeType.FIT_CONTENT);
}
public static DynamicSize fitOrFill() {
return new DynamicSize(SizeType.FIT_CONTENT_OR_FILL);
public static Value fitOrFill() {
return new Value(SizeType.FIT_CONTENT_OR_FILL);
}
public int calculatedSize() {
@ -42,7 +42,7 @@ public class DynamicSize {
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) {
sizeType = fit.copyForSupplier(c);
}

View file

@ -1,10 +1,7 @@
package org.betterx.ui.vanilla;
import org.betterx.ui.layout.components.HorizontalStack;
import org.betterx.ui.layout.components.Panel;
import org.betterx.ui.layout.components.Text;
import org.betterx.ui.layout.components.VerticalStack;
import org.betterx.ui.layout.values.DynamicSize;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Value;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.gui.screens.Screen;
@ -49,7 +46,7 @@ public abstract class LayoutScreen extends Screen {
@Nullable
public final Screen parent;
protected abstract org.betterx.ui.layout.components.Component<?> initContent();
protected abstract LayoutComponent<?> initContent();
@Override
protected final void init() {
@ -61,18 +58,24 @@ public abstract class LayoutScreen extends Screen {
addRenderableWidget(main);
}
protected org.betterx.ui.layout.components.Component<?> addTitle(org.betterx.ui.layout.components.Component<?> content) {
VerticalStack rows = new VerticalStack(DynamicSize.fill(), DynamicSize.fill());
protected LayoutComponent<?> buildTitle() {
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);
rows.add(new Text(DynamicSize.fill(), DynamicSize.fit(), title).centerHorizontal());
rows.add(buildTitle());
rows.addSpacer(15);
rows.add(content);
if (bottomPadding > 0) rows.addSpacer(bottomPadding);
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.add(rows);
cols.addSpacer(sidePadding);

View file

@ -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;
}
}