diff --git a/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java b/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java index 48e1b225..f3092de5 100644 --- a/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java +++ b/src/main/java/org/betterx/bclib/client/gui/modmenu/TestScreen.java @@ -2,8 +2,8 @@ package org.betterx.bclib.client.gui.modmenu; import org.betterx.ui.layout.components.*; import org.betterx.ui.layout.values.DynamicSize; +import org.betterx.ui.vanilla.LayoutScreen; -import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; @@ -11,23 +11,28 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @Environment(EnvType.CLIENT) -public class TestScreen extends Screen { +public class TestScreen extends LayoutScreen { public TestScreen(Component component) { super(component); } - Panel main; + public TestScreen(Screen parent, Component component) { + super(parent, component); + } @Override - protected void init() { - super.init(); - main = new Panel(this.width, this.height); - VerticalStack rows = new VerticalStack(DynamicSize.fit(), DynamicSize.relative(1)); + protected org.betterx.ui.layout.components.Component initContent() { + VerticalStack rows = new VerticalStack(DynamicSize.fit(), DynamicSize.fitOrFill()); rows.addFiller(); rows.add(new Text( DynamicSize.fitOrFill(), DynamicSize.fit(), Component.literal("Some Text") + ).alignRight() + ); + rows.add(new Text( + DynamicSize.fitOrFill(), DynamicSize.fit(), + Component.literal("Some other, longer Text") ).centerHorizontal() ); rows.addSpacer(16); @@ -67,7 +72,7 @@ public class TestScreen extends Screen { } )); rows.add(cb1); - rows.addSpacer(16); + rows.addSpacer(32); rows.add(new Button( DynamicSize.fit(), DynamicSize.fit(), Component.literal("test"), @@ -90,15 +95,7 @@ public class TestScreen extends Screen { ).centerHorizontal() ); rows.addFiller(); - main.setChild(HorizontalStack.centered(rows)); - main.calculateLayout(); - addRenderableWidget(main); - } - - @Override - public void render(PoseStack poseStack, int i, int j, float f) { - renderDirtBackground(i); - super.render(poseStack, i, j, f); + return HorizontalStack.centered(VerticalScroll.create(DynamicSize.fit(), DynamicSize.relative(1), rows)); } } diff --git a/src/main/java/org/betterx/bclib/integration/modmenu/ModMenuEntryPoint.java b/src/main/java/org/betterx/bclib/integration/modmenu/ModMenuEntryPoint.java index 01ec9c0f..2e2bbeb8 100644 --- a/src/main/java/org/betterx/bclib/integration/modmenu/ModMenuEntryPoint.java +++ b/src/main/java/org/betterx/bclib/integration/modmenu/ModMenuEntryPoint.java @@ -28,7 +28,7 @@ public class ModMenuEntryPoint implements ModMenuApi { @Override public ConfigScreenFactory getModConfigScreenFactory() { - return (parent) -> new TestScreen(Component.literal("Hello Test")); + return (parent) -> new TestScreen(parent, Component.literal("Hello Test")); //return (parent) -> new MainScreen(parent); } diff --git a/src/main/java/org/betterx/ui/layout/components/Component.java b/src/main/java/org/betterx/ui/layout/components/Component.java index b6080415..eaf0f814 100644 --- a/src/main/java/org/betterx/ui/layout/components/Component.java +++ b/src/main/java/org/betterx/ui/layout/components/Component.java @@ -5,7 +5,9 @@ import org.betterx.ui.layout.values.Alignment; import org.betterx.ui.layout.values.DynamicSize; import org.betterx.ui.layout.values.Rectangle; +import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.events.GuiEventListener; import net.fabricmc.api.EnvType; @@ -65,6 +67,21 @@ public abstract class Component implements Componen return height.calculatedSize(); } + protected final void setClippingRect(Rectangle clippingRect) { + if (clippingRect == null) { + RenderSystem.disableScissor(); + return; + } + final double uiScale = Minecraft.getInstance().getWindow().getGuiScale(); + final int windowHeight = Minecraft.getInstance().getWindow().getHeight(); + RenderSystem.enableScissor( + (int) (clippingRect.left * uiScale), + (int) (windowHeight - clippingRect.bottom() * uiScale), + (int) (clippingRect.width * uiScale), + (int) (clippingRect.height * uiScale) + ); + } + public void render(PoseStack poseStack, int x, int y, float a, Rectangle parentBounds, Rectangle clipRect) { Rectangle r = relativeBounds.movedBy(parentBounds.left, parentBounds.top); Rectangle clip = r.intersect(clipRect); @@ -85,7 +102,9 @@ public abstract class Component implements Componen Rectangle clipRect ) { if (renderer != null) { + setClippingRect(clipRect); renderer.renderInBounds(poseStack, x, y, a, renderBounds, clipRect); + setClippingRect(null); } } diff --git a/src/main/java/org/betterx/ui/layout/components/HorizontalStack.java b/src/main/java/org/betterx/ui/layout/components/HorizontalStack.java index e49bfaf8..df2368fe 100644 --- a/src/main/java/org/betterx/ui/layout/components/HorizontalStack.java +++ b/src/main/java/org/betterx/ui/layout/components/HorizontalStack.java @@ -68,11 +68,11 @@ public class HorizontalStack extends AbstractStack c) { - return new HorizontalStack(DynamicSize.relative(1), DynamicSize.relative(1)).addFiller().add(c).addFiller(); + return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).addFiller().add(c).addFiller(); } public static HorizontalStack bottom(Component c) { - return new HorizontalStack(DynamicSize.relative(1), DynamicSize.relative(1)).add(c).addFiller(); + return new HorizontalStack(DynamicSize.fill(), DynamicSize.fill()).add(c).addFiller(); } protected HorizontalStack addEmpty(DynamicSize size) { diff --git a/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java b/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java index 9a844c81..651c628b 100644 --- a/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java +++ b/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java @@ -1,9 +1,11 @@ package org.betterx.ui.layout.components; 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.DynamicSize; import org.betterx.ui.layout.values.Rectangle; +import org.betterx.ui.vanilla.VanillaScrollerRenderer; import com.mojang.blaze3d.vertex.PoseStack; @@ -30,6 +32,25 @@ public class VerticalScroll create(Component c) { + return create(DynamicSize.relative(1), DynamicSize.relative(1), c); + } + + public static VerticalScroll create( + DynamicSize width, + DynamicSize height, + Component c + ) { + VerticalScroll res = new VerticalScroll<>( + width, + height, + VanillaScrollerRenderer.DEFAULT, + null + ); + res.setChild(c); + return res; + } + public void setChild(Component c) { this.child = c; } @@ -38,7 +59,7 @@ public class VerticalScroll addTitle(org.betterx.ui.layout.components.Component content) { VerticalStack rows = new VerticalStack(DynamicSize.relative(1), DynamicSize.relative(1)); - //rows.add(this.title, GridLayout.Alignment.CENTER, this); + rows.add(new Text(DynamicSize.fill(), DynamicSize.fit(), title).centerHorizontal()); rows.addSpacer(15); rows.add(content); return rows; } + protected void renderBackground(PoseStack poseStack, int i, int j, float f) { + renderDirtBackground(i); + } @Override public void render(PoseStack poseStack, int i, int j, float f) { - renderDirtBackground(i); + renderBackground(poseStack, i, j, f); super.render(poseStack, i, j, f); } diff --git a/src/main/java/org/betterx/ui/vanilla/VanillaScrollerRenderer.java b/src/main/java/org/betterx/ui/vanilla/VanillaScrollerRenderer.java new file mode 100644 index 00000000..2c6edcab --- /dev/null +++ b/src/main/java/org/betterx/ui/vanilla/VanillaScrollerRenderer.java @@ -0,0 +1,54 @@ +package org.betterx.ui.vanilla; + +import org.betterx.ui.layout.components.render.ScrollerRenderer; +import org.betterx.ui.layout.values.Rectangle; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.BufferBuilder; +import com.mojang.blaze3d.vertex.DefaultVertexFormat; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexFormat; +import net.minecraft.client.renderer.GameRenderer; + +public class VanillaScrollerRenderer implements ScrollerRenderer { + public static final VanillaScrollerRenderer DEFAULT = new VanillaScrollerRenderer(); + + @Override + public void renderScrollBar(Rectangle b, int pickerOffset, int pickerSize) { + b = this.getScrollerBounds(b); + Rectangle p = this.getPickerBounds(b, pickerOffset, pickerSize); + + + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder bufferBuilder = tesselator.getBuilder(); + RenderSystem.disableTexture(); + RenderSystem.setShader(GameRenderer::getPositionColorShader); + + + bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR); + + //scroller background + bufferBuilder.vertex(b.left, b.bottom(), 0.0D).color(0, 0, 0, 255).endVertex(); + bufferBuilder.vertex(b.right(), b.bottom(), 0.0D).color(0, 0, 0, 255).endVertex(); + bufferBuilder.vertex(b.right(), b.top, 0.0D).color(0, 0, 0, 255).endVertex(); + bufferBuilder.vertex(b.left, b.top, 0.0D).color(0, 0, 0, 255).endVertex(); + + //scroll widget shadow + bufferBuilder.vertex(p.left, p.bottom(), 0.0D).color(128, 128, 128, 255).endVertex(); + bufferBuilder.vertex(p.right(), p.bottom(), 0.0D).color(128, 128, 128, 255).endVertex(); + bufferBuilder.vertex(p.right(), p.top, 0.0D).color(128, 128, 128, 255).endVertex(); + bufferBuilder.vertex(p.left, p.top, 0.0D).color(128, 128, 128, 255).endVertex(); + + //scroll widget + bufferBuilder.vertex(p.left, p.bottom() - 1, 0.0D) + .color(192, 192, 192, 255) + .endVertex(); + bufferBuilder.vertex(p.right() - 1, p.bottom() - 1, 0.0D) + .color(192, 192, 192, 255) + .endVertex(); + bufferBuilder.vertex(p.right() - 1, p.top, 0.0D).color(192, 192, 192, 255).endVertex(); + bufferBuilder.vertex(p.left, p.top, 0.0D).color(192, 192, 192, 255).endVertex(); + + tesselator.end(); + } +}