[Feature] Container and Tabs Components

This commit is contained in:
Frank 2022-07-20 00:40:16 +02:00
parent 200385c73e
commit d19123c949
22 changed files with 1125 additions and 301 deletions

View file

@ -61,7 +61,8 @@ public class MainScreen extends LayoutScreenWithIcon {
Checkbox cb = row.addCheckbox(
Value.fit(), Value.fit(),
getComponent(config, option, "title"),
config.getRaw(option.token),
config.getRaw(option.token)
).onChange(
(caller, state) -> {
config.set(option.token, state);
updateEnabledState();
@ -104,7 +105,7 @@ public class MainScreen extends LayoutScreenWithIcon {
VerticalStack grid = new VerticalStack(Value.fill(), Value.fill()).setDebugName("main grid");
grid.addScrollable(content);
grid.addSpacer(8);
grid.addButton(Value.fit(), Value.fit(), CommonComponents.GUI_DONE, (button) -> {
grid.addButton(Value.fit(), Value.fit(), CommonComponents.GUI_DONE).onPress((button) -> {
Configs.CLIENT_CONFIG.saveChanges();
Configs.GENERATOR_CONFIG.saveChanges();
Configs.MAIN_CONFIG.saveChanges();

View file

@ -25,6 +25,21 @@ public class TestScreen extends LayoutScreen {
@Override
protected LayoutComponent<?, ?> initContent() {
VerticalStack page1 = new VerticalStack(Value.fill(), Value.fit());
page1.addText(Value.fit(), Value.fit(), Component.literal("Page 1")).alignLeft().centerVertical();
page1.addButton(Value.fit(), Value.fit(), Component.literal("A")).onPress((bt) -> System.out.println("A"))
.centerHorizontal();
VerticalStack page2 = new VerticalStack(Value.fill(), Value.fit());
page2.addText(Value.fit(), Value.fit(), Component.literal("Page 2")).alignRight().centerVertical();
page1.addButton(Value.fit(), Value.fit(), Component.literal("B")).onPress((bt) -> System.out.println("B"))
.centerHorizontal();
Container c = new Container(Value.fill(), Value.fixed(40));
c.addChild(new Button(Value.fit(), Value.fit(), Component.literal("Containerd")).onPress(bt -> {
System.out.println("Containerd");
}).centerHorizontal().centerVertical());
c.setBackgroundColor(0x77000000);
VerticalStack rows = new VerticalStack(Value.fit(), Value.fitOrFill());
rows.addFiller();
@ -39,6 +54,8 @@ public class TestScreen extends LayoutScreen {
).centerHorizontal()
);
rows.addHorizontalSeparator(16).alignTop();
rows.add(new Tabs(Value.fixed(300), Value.fit()).addPage(Component.literal("PAGE 1"), page1)
.addPage(Component.literal("PAGE 2"), page2));
rows.add(new Input(Value.fitOrFill(), Value.fit(), Component.literal("Input"), "0xff00ff"));
rows.add(new ColorSwatch(Value.fit(), Value.fit(), ColorUtil.LIGHT_PURPLE).centerHorizontal());
rows.add(new ColorPicker(
@ -53,6 +70,16 @@ public class TestScreen extends LayoutScreen {
).centerHorizontal().setColor(ColorUtil.BLUE)
);
rows.addHLine(Value.fixed(32), Value.fixed(16));
rows.add(c);
rows.addCheckbox(
Value.fitOrFill(),
Value.fit(),
Component.literal("Hide"),
false
).onChange(
(cb, state) -> c.setVisible(!state)
);
rows.addSpacer(16);
rows.add(new Image(
Value.fixed(24), Value.fixed(24),
BCLib.makeID("icon.png"),
@ -70,7 +97,8 @@ public class TestScreen extends LayoutScreen {
rows.add(new Range<>(
Value.fill(), Value.fit(),
Component.literal("Integer"),
10, 90, 20,
10, 90, 20
).onChange(
(slider, value) -> {
System.out.println(value);
}
@ -79,7 +107,8 @@ public class TestScreen extends LayoutScreen {
rows.add(new Range<>(
Value.fill(), Value.fit(),
Component.literal("Float"),
10f, 90f, 20f,
10f, 90f, 20f
).onChange(
(slider, value) -> {
System.out.println(value);
}
@ -88,7 +117,8 @@ public class TestScreen extends LayoutScreen {
Checkbox cb1 = new Checkbox(
Value.fit(), Value.fit(),
Component.literal("Some Sub-State"),
false, true,
false, true
).onChange(
(checkbox, value) -> {
System.out.println(value);
}
@ -96,7 +126,8 @@ public class TestScreen extends LayoutScreen {
rows.add(new Checkbox(
Value.fit(), Value.fit(),
Component.literal("Some Selectable State"),
false, true,
false, true
).onChange(
(checkbox, value) -> {
System.out.println(value);
cb1.setEnabled(value);
@ -106,7 +137,8 @@ public class TestScreen extends LayoutScreen {
rows.addSpacer(16);
rows.add(new Button(
Value.fit(), Value.fit(),
Component.literal("test"),
Component.literal("test")
).onPress(
(bt) -> {
System.out.println("clicked test");
}
@ -115,7 +147,8 @@ public class TestScreen extends LayoutScreen {
rows.addSpacer(8);
rows.add(new Button(
Value.fit(), Value.fit(),
Component.literal("Hello World"),
Component.literal("Hello World")
).onPress(
(bt) -> {
System.out.println("clicked hello");
}

View file

@ -1,8 +1,6 @@
package org.betterx.bclib.integration.modmenu;
import org.betterx.bclib.client.gui.modmenu.TestScreen;
import net.minecraft.network.chat.Component;
import org.betterx.bclib.client.gui.modmenu.MainScreen;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
@ -28,8 +26,8 @@ public class ModMenuEntryPoint implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return (parent) -> new TestScreen(parent, Component.literal("Hello Test"));
//return (parent) -> new MainScreen(parent);
//return (parent) -> new TestScreen(parent, Component.literal("Hello Test"));
return (parent) -> new MainScreen(parent);
}

View file

@ -0,0 +1,87 @@
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

@ -6,7 +6,6 @@ import org.betterx.ui.layout.components.render.NullRenderer;
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.Slider;
import org.betterx.ui.vanilla.VanillaScrollerRenderer;
import com.mojang.blaze3d.vertex.PoseStack;
@ -64,25 +63,6 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
}
}
public T add(LayoutComponent<?, ?> c) {
this.components.add(c);
return (T) this;
}
protected abstract T addEmpty(Value size);
public T addSpacer(int size) {
return addEmpty(Value.fixed(size));
}
public T addSpacer(float percentage) {
return addEmpty(Value.relative(percentage));
}
public T addFiller() {
return addEmpty(Value.fill());
}
@Override
public List<? extends GuiEventListener> children() {
return components;
@ -118,44 +98,65 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
focused = guiEventListener;
}
public boolean isEmpty() {
return components.isEmpty();
}
public Image addIcon(ResourceLocation location, Size resourceSize) {
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;
}
public Image addImage(Value width, Value height, ResourceLocation location, Size resourceSize) {
protected 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(
protected Checkbox addCheckbox(
Value width, Value height, Component component,
boolean selected,
Checkbox.SelectionChanged onSelectionChange
boolean selected
) {
Checkbox c = new Checkbox(width, height, component, selected, true, onSelectionChange);
Checkbox c = new Checkbox(width, height, component, selected, true);
add(c);
return c;
}
public Button addButton(
protected Button addButton(
Value width, Value height,
Component component,
net.minecraft.client.gui.components.Button.OnPress onPress
Component component
) {
Button b = new Button(width, height, component, onPress);
Button b = new Button(width, height, component);
add(b);
return b;
}
public VerticalScroll<NullRenderer, VanillaScrollerRenderer> addScrollable(LayoutComponent<?, ?> content) {
protected VerticalScroll<NullRenderer, VanillaScrollerRenderer> addScrollable(LayoutComponent<?, ?> content) {
return addScrollable(Value.fill(), Value.fill(), content);
}
public VerticalScroll<NullRenderer, VanillaScrollerRenderer> addScrollable(
protected VerticalScroll<NullRenderer, VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
@ -165,52 +166,49 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
return s;
}
public Text addText(Value width, Value height, net.minecraft.network.chat.Component text) {
protected Text addText(Value width, Value height, net.minecraft.network.chat.Component text) {
Text t = new Text(width, height, text);
add(t);
return t;
}
public MultiLineText addMultilineText(Value width, Value height, net.minecraft.network.chat.Component text) {
protected MultiLineText addMultilineText(Value width, Value height, net.minecraft.network.chat.Component text) {
MultiLineText t = new MultiLineText(width, height, text);
add(t);
return t;
}
public Range<Integer> addRange(
protected Range<Integer> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
int minValue, int maxValue, int initialValue,
Slider.SliderValueChanged<Integer> onChange
int minValue, int maxValue, int initialValue
) {
Range<Integer> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue, onChange);
Range<Integer> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
public Range<Float> addRange(
protected Range<Float> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
float minValue, float maxValue, float initialValue,
Slider.SliderValueChanged<Float> onChange
float minValue, float maxValue, float initialValue
) {
Range<Float> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue, onChange);
Range<Float> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
public Range<Double> addRange(
protected Range<Double> addRange(
Value width, Value height,
net.minecraft.network.chat.Component titleOrNull,
double minValue, double maxValue, double initialValue,
Slider.SliderValueChanged<Double> onChange
double minValue, double maxValue, double initialValue
) {
Range<Double> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue, onChange);
Range<Double> r = new Range<>(width, height, titleOrNull, minValue, maxValue, initialValue);
add(r);
return r;
}
public Input addInput(
protected Input addInput(
Value width, Value height, net.minecraft.network.chat.Component titleOrNull, String initialValue
) {
Input i = new Input(width, height, titleOrNull, initialValue);
@ -218,13 +216,13 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
return i;
}
public ColorSwatch addColorSwatch(Value width, Value height, int color) {
protected ColorSwatch addColorSwatch(Value width, Value height, int color) {
ColorSwatch c = new ColorSwatch(width, height, color);
add(c);
return c;
}
public ColorPicker addColorPicker(
protected ColorPicker addColorPicker(
Value width,
Value height,
net.minecraft.network.chat.Component titleOrNull,
@ -235,32 +233,39 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
return c;
}
public HLine addHorizontalSeparator(int height) {
protected HLine addHorizontalSeparator(int height) {
return addHLine(Value.relative(1.0 / 1.618033988749894), Value.fixed(height));
}
public HLine addHorizontalLine(int height) {
protected HLine addHorizontalLine(int height) {
return addHLine(Value.fill(), Value.fixed(height));
}
public HLine addHLine(Value width, Value height) {
protected HLine addHLine(Value width, Value height) {
HLine l = new HLine(width, height);
add(l);
return l;
}
public VLine addVerticalSeparator(int width) {
protected VLine addVerticalSeparator(int width) {
return addVLine(Value.fixed(width), Value.relative(1.0 / 1.618033988749894));
}
public VLine addVerticalLine(int width) {
protected VLine addVerticalLine(int width) {
return addVLine(Value.fixed(width), Value.fill());
}
public VLine addVLine(Value width, Value height) {
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;
}
}

View file

@ -0,0 +1,83 @@
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

@ -3,40 +3,68 @@ 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> {
final net.minecraft.client.gui.components.Button.OnPress onPress;
net.minecraft.client.gui.components.Button.OnTooltip onTooltip;
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,
net.minecraft.client.gui.components.Button.OnPress onPress
net.minecraft.network.chat.Component component
) {
super(width, height, new ButtonRenderer(), component);
this.onPress = onPress;
this.onTooltip = net.minecraft.client.gui.components.Button.NO_TOOLTIP;
this.onPress = NO_ACTION;
this.onTooltip = NO_TOOLTIP;
}
public Button setOnToolTip(net.minecraft.client.gui.components.Button.OnTooltip onTooltip) {
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 new net.minecraft.client.gui.components.Button(
0,
0,
relativeBounds.width,
relativeBounds.height,
component,
onPress,
onTooltip
(bt) -> onPress.onPress(self),
(bt, stack, x, y) -> onTooltip.onTooltip(self, stack, x, y)
);
}
public boolean isGlowing() {
return glow;
}
}

View file

@ -10,36 +10,44 @@ 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(net.minecraft.client.gui.components.Checkbox checkBox, boolean selected);
void now(Checkbox checkBox, boolean selected);
}
private final boolean selected;
private final boolean showLabel;
private final SelectionChanged onSelectionChange;
private SelectionChanged onSelectionChange;
public Checkbox(
Value width,
Value height,
Component component,
boolean selected, boolean showLabel,
SelectionChanged onSelectionChange
boolean selected, boolean showLabel
) {
super(width, height, new CheckboxRenderer(), component);
onSelectionChange = IGNORE_CHANGE;
this.selected = selected;
this.showLabel = showLabel;
this.onSelectionChange = onSelectionChange;
}
public boolean selected() {
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,
@ -50,11 +58,11 @@ public class Checkbox extends AbstractVanillaComponent<net.minecraft.client.gui.
@Override
public void onPress() {
super.onPress();
onSelectionChange.now(this, this.selected());
onSelectionChange.now(self, this.selected());
}
};
onSelectionChange.now(cb, cb.selected());
onSelectionChange.now(this, cb.selected());
return cb;
}
}

View file

@ -5,7 +5,11 @@ import org.betterx.ui.layout.values.Value;
import net.minecraft.network.chat.Component;
public class ColorPicker extends HorizontalStack {
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ColorPicker extends AbstractHorizontalStack<ColorPicker> {
ColorSwatch swatch;
Input input;
@ -29,14 +33,4 @@ public class ColorPicker extends HorizontalStack {
swatch.setBorderColor(ColorUtil.RED);
}
}
@Override
public int getContentWidth() {
return swatch.getContentWidth() + input.getContentWidth();
}
@Override
public int getContentHeight() {
return Math.max(swatch.getContentHeight(), input.getContentHeight());
}
}

View file

@ -8,6 +8,10 @@ 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;

View file

@ -0,0 +1,248 @@
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);
}
}
}
private final List<LayoutComponent<?, ?>> children = new LinkedList<>();
boolean dragging = false;
GuiEventListener focused = null;
boolean visible = true;
int padding = 0;
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(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) {
this.padding = padding;
return this;
}
public int getPadding() {
return padding;
}
@Override
public int getContentWidth() {
return children.stream().map(LayoutComponent::getContentWidth).reduce(0, Math::max) + 2 * padding;
}
@Override
public int getContentHeight() {
return children.stream().map(LayoutComponent::getContentHeight).reduce(0, Math::max) + 2 * padding;
}
@Override
public Rectangle getInputBounds() {
return relativeBounds;
}
@Override
public List<? extends GuiEventListener> children() {
return children;
}
@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.width.calculateOrFill(myWidth - 2 * padding);
child.updateContainerWidth(child.width.calculatedSize());
}
return myWidth;
}
@Override
protected int updateContainerHeight(int containerHeight) {
int myHeight = height.calculateOrFill(containerHeight);
for (var child : children) {
child.height.calculateOrFill(myHeight - 2 * padding);
child.updateContainerHeight(child.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.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 - 2 * padding) - child.width.calculatedSize();
if (child.hAlign == Alignment.MIN) childLeft = 0;
else if (child.hAlign == Alignment.CENTER) childLeft /= 2;
int childTop = (relativeBounds.height - 2 * padding) - child.height.calculatedSize();
if (child.vAlign == Alignment.MIN) childTop = 0;
else if (child.vAlign == Alignment.CENTER) childTop /= 2;
child.setRelativeBounds(padding + childLeft, padding + childTop);
}
}
@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) {
for (var child : children) {
return child.isMouseOver(x, y);
}
}
return relativeBounds.contains(x, y);
}
}

View file

@ -8,6 +8,10 @@ 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;

View file

@ -1,71 +1,22 @@
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.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.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack> implements RelativeContainerEventHandler {
public class HorizontalStack extends AbstractHorizontalStack<HorizontalStack> {
public HorizontalStack(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.hAlign == Alignment.MIN) delta = 0;
else if (c.hAlign == 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);
}
public static HorizontalStack centered(LayoutComponent<?, ?> c) {
return new HorizontalStack(Value.fill(), Value.fill()).addFiller().add(c).addFiller();
@ -80,14 +31,170 @@ public class HorizontalStack extends AbstractStack<NullRenderer, HorizontalStack
return this;
}
public VerticalStack addColumn(Value width, Value height) {
VerticalStack stack = new VerticalStack(width, height);
add(stack);
return stack;
@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 addColumn(Value.fit(), Value.fit());
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<NullRenderer, 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<NullRenderer, VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
) {
return super.addScrollable(width, height, content);
}
}

View file

@ -99,73 +99,4 @@ public class Panel implements ComponentWithBounds, RelativeContainerEventHandler
child.render(poseStack, mouseX - bounds.left, mouseY - bounds.top, deltaTicks, bounds, bounds);
}
}
// @Override
// public void mouseMoved(double x, double y) {
// if (child != null)
// child.mouseMoved(x - bounds.left, y - bounds.top);
// }
//
// @Override
// public boolean mouseClicked(double x, double y, int button) {
// if (child != null)
// return child.mouseClicked(x - bounds.left, y - bounds.top, button);
// return false;
// }
//
// @Override
// public boolean mouseReleased(double x, double y, int button) {
// if (child != null)
// return child.mouseReleased(x - bounds.left, y - bounds.top, button);
// return false;
// }
//
// @Override
// public boolean mouseDragged(double x, double y, int button, double x2, double y2) {
// if (child != null)
// return child.mouseDragged(x - bounds.left, y - bounds.top, button, x2 - bounds.left, y2 - bounds.top);
// return false;
// }
//
// @Override
// public boolean mouseScrolled(double x, double y, double f) {
// if (child != null)
// return child.mouseScrolled(x - bounds.left, y - bounds.top, f);
// return false;
// }
//
// @Override
// public boolean keyPressed(int i, int j, int k) {
// if (child != null)
// return child.keyPressed(i, j, k);
// return false;
// }
//
// @Override
// public boolean keyReleased(int i, int j, int k) {
// if (child != null)
// return child.keyReleased(i, j, k);
// return false;
// }
//
// @Override
// public boolean charTyped(char c, int i) {
// if (child != null)
// return child.charTyped(c, i);
// return false;
// }
//
// @Override
// public boolean changeFocus(boolean bl) {
// if (child != null)
// return child.changeFocus(bl);
// return false;
// }
//
// @Override
// public boolean isMouseOver(double x, double y) {
// if (child != null)
// return child.isMouseOver(x, y);
// return false;
// }
}

View file

@ -11,7 +11,12 @@ import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>, Range<N>> {
private final Slider.SliderValueChanged<N> onChange;
@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;
@ -22,11 +27,11 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
Component component,
N minValue,
N maxValue,
N initialValue,
Slider.SliderValueChanged<N> onChange
N initialValue
) {
super(width, height, new RangeRenderer<>(), component);
this.onChange = onChange;
this.onChange = (a, b) -> {
};
this.minValue = minValue;
this.maxValue = maxValue;
this.initialValue = initialValue;
@ -37,14 +42,19 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
Value height,
N minValue,
N maxValue,
N initialValue,
Slider.SliderValueChanged<N> onChange
N initialValue
) {
this(width, height, null, minValue, maxValue, initialValue, onChange);
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,
@ -54,7 +64,7 @@ public class Range<N extends Number> extends AbstractVanillaComponent<Slider<N>,
minValue,
maxValue,
initialValue,
onChange
(s, v) -> onChange.now(self, v)
);
}

View file

@ -0,0 +1,133 @@
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> {
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;
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;
}
});
buttons.add(b);
buttonList.add(b);
return this;
}
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 int getPadding() {
return content.getPadding();
}
@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
void setRelativeBounds(int left, int top) {
super.setRelativeBounds(left, top);
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

@ -8,6 +8,10 @@ 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;

View file

@ -109,13 +109,13 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
int width = relativeBounds.width;
boolean willNeedScrollBar = child.height.calculatedSize() > relativeBounds.height;
if (willNeedScrollBar) width -= scrollerWidth();
int childTop = width - child.width.calculatedSize();
if (child.hAlign == Alignment.MIN) childTop = 0;
else if (child.hAlign == Alignment.CENTER) childTop /= 2;
int childLeft = width - child.width.calculatedSize();
if (child.hAlign == Alignment.MIN) childLeft = 0;
else if (child.hAlign == Alignment.CENTER) childLeft /= 2;
int childLeft = relativeBounds.height - child.height.calculatedSize();
if (child.vAlign == Alignment.MIN) childLeft = 0;
else if (child.vAlign == 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);
}
@ -265,21 +265,25 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
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;
}

View file

@ -1,72 +1,23 @@
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.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.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> implements RelativeContainerEventHandler {
public class VerticalStack extends AbstractVerticalStack<VerticalStack> {
public VerticalStack(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));
}
public static VerticalStack centered(LayoutComponent<?, ?> c) {
return new VerticalStack(Value.relative(1), Value.relative(1)).addFiller().add(c).addFiller();
}
@ -75,18 +26,187 @@ public class VerticalStack extends AbstractStack<NullRenderer, VerticalStack> im
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 addRow(Value width, Value height) {
HorizontalStack stack = new HorizontalStack(width, height);
add(stack);
return stack;
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 addRow(Value.fit(), Value.fit());
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<NullRenderer, 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<NullRenderer, VanillaScrollerRenderer> addScrollable(
Value width,
Value height,
LayoutComponent<?, ?> content
) {
return super.addScrollable(width, height, content);
}
}

View file

@ -21,7 +21,7 @@ public interface RelativeContainerEventHandler extends ContainerEventHandler {
default boolean mouseClicked(double d, double e, int i) {
if (getFocused() != null) {
getFocused().mouseClicked(d, e, i);
//getFocused().mouseClicked(d, e, i);
}
Rectangle r = getInputBounds();
return ContainerEventHandler.super.mouseClicked(d - r.left, e - r.top, i);

View file

@ -1,11 +1,30 @@
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.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class ButtonRenderer extends AbstractVanillaComponentRenderer<net.minecraft.client.gui.components.Button, Button> {
@Override
public void renderInBounds(
PoseStack poseStack,
int mouseX,
int mouseY,
float deltaTicks,
Rectangle bounds,
Rectangle clipRect
) {
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, bounds, clipRect);
if (getLinkedComponent() != null && getLinkedComponent().isGlowing()) {
RenderHelper.outline(poseStack, 0, 0, bounds.width, bounds.height, ColorUtil.RED);
}
}
}

View file

@ -1,5 +1,6 @@
package org.betterx.ui.vanilla;
import org.betterx.ui.ColorUtil;
import org.betterx.ui.layout.components.*;
import org.betterx.ui.layout.values.Value;
@ -59,7 +60,9 @@ public abstract class LayoutScreen extends Screen {
}
protected LayoutComponent<?, ?> buildTitle() {
var text = new Text(Value.fill(), Value.fit(), title).centerHorizontal().setDebugName("title");
var text = new Text(Value.fit(), Value.fit(), title).centerHorizontal()
.setColor(ColorUtil.WHITE)
.setDebugName("title");
return text;
}