From 877489c46980b05c99e617a9c182d1e73f1f8128 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 15 Jul 2022 15:47:56 +0200 Subject: [PATCH] Image Component --- .../bclib/client/gui/modmenu/TestScreen.java | 11 +- .../ui/layout/components/AbstractStack.java | 10 +- .../AbstractVanillaComponentRenderer.java | 11 +- .../ui/layout/components/Component.java | 19 ++- .../components/CustomRenderComponent.java | 48 ++++++++ .../betterx/ui/layout/components/Image.java | 115 ++++++++++++++++++ .../betterx/ui/layout/components/Panel.java | 4 +- .../betterx/ui/layout/components/Text.java | 9 +- .../ui/layout/components/VerticalScroll.java | 44 ++++--- .../components/render/ComponentRenderer.java | 9 +- .../components/render/NullRenderer.java | 11 +- .../components/render/TextProvider.java | 4 + .../org/betterx/ui/layout/values/Size.java | 4 + 13 files changed, 263 insertions(+), 36 deletions(-) create mode 100644 src/main/java/org/betterx/ui/layout/components/CustomRenderComponent.java create mode 100644 src/main/java/org/betterx/ui/layout/components/Image.java create mode 100644 src/main/java/org/betterx/ui/layout/values/Size.java 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 3886a492..4cbd4292 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 @@ -1,7 +1,9 @@ package org.betterx.bclib.client.gui.modmenu; +import org.betterx.bclib.BCLib; import org.betterx.ui.layout.components.*; import org.betterx.ui.layout.values.DynamicSize; +import org.betterx.ui.layout.values.Size; import org.betterx.ui.vanilla.LayoutScreen; import net.minecraft.client.gui.screens.Screen; @@ -36,6 +38,13 @@ public class TestScreen extends LayoutScreen { ).centerHorizontal() ); rows.addSpacer(16); + rows.add(new Image( + DynamicSize.fixed(24), DynamicSize.fixed(24), + BCLib.makeID("icon.png"), + new Size(512, 512) + ).centerHorizontal() + ); + rows.addSpacer(16); rows.add(new Range<>( DynamicSize.fill(), DynamicSize.fit(), Component.literal("Integer"), @@ -72,7 +81,7 @@ public class TestScreen extends LayoutScreen { } )); rows.add(cb1); - rows.addSpacer(32); + rows.addSpacer(16); rows.add(new Button( DynamicSize.fit(), DynamicSize.fit(), Component.literal("test"), diff --git a/src/main/java/org/betterx/ui/layout/components/AbstractStack.java b/src/main/java/org/betterx/ui/layout/components/AbstractStack.java index d8892136..f6267262 100644 --- a/src/main/java/org/betterx/ui/layout/components/AbstractStack.java +++ b/src/main/java/org/betterx/ui/layout/components/AbstractStack.java @@ -46,15 +46,15 @@ public abstract class AbstractStack c : components) { - c.render(poseStack, x, y, a, renderBounds, clipRect); + c.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect); } } diff --git a/src/main/java/org/betterx/ui/layout/components/AbstractVanillaComponentRenderer.java b/src/main/java/org/betterx/ui/layout/components/AbstractVanillaComponentRenderer.java index 25adbaf7..822798b2 100644 --- a/src/main/java/org/betterx/ui/layout/components/AbstractVanillaComponentRenderer.java +++ b/src/main/java/org/betterx/ui/layout/components/AbstractVanillaComponentRenderer.java @@ -19,13 +19,20 @@ public class AbstractVanillaComponentRenderer implements Componen ); } - public void render(PoseStack poseStack, int x, int y, float a, Rectangle parentBounds, Rectangle clipRect) { + public void render( + PoseStack poseStack, + int mouseX, + int mouseY, + float deltaTicks, + Rectangle parentBounds, + Rectangle clipRect + ) { Rectangle r = relativeBounds.movedBy(parentBounds.left, parentBounds.top); Rectangle clip = r.intersect(clipRect); poseStack.pushPose(); poseStack.translate(relativeBounds.left, relativeBounds.top, 0); if (r.overlaps(clip)) { - renderInBounds(poseStack, x - relativeBounds.left, y - relativeBounds.top, a, r, clip); + renderInBounds(poseStack, mouseX - relativeBounds.left, mouseY - relativeBounds.top, deltaTicks, r, clip); } poseStack.popPose(); } protected void renderInBounds( PoseStack poseStack, - int x, - int y, - float a, + int mouseX, + int mouseY, + float deltaTicks, Rectangle renderBounds, Rectangle clipRect ) { if (renderer != null) { setClippingRect(clipRect); - renderer.renderInBounds(poseStack, x, y, a, renderBounds, clipRect); + renderer.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect); setClippingRect(null); } } diff --git a/src/main/java/org/betterx/ui/layout/components/CustomRenderComponent.java b/src/main/java/org/betterx/ui/layout/components/CustomRenderComponent.java new file mode 100644 index 00000000..d191b54d --- /dev/null +++ b/src/main/java/org/betterx/ui/layout/components/CustomRenderComponent.java @@ -0,0 +1,48 @@ +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 com.mojang.blaze3d.vertex.PoseStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public abstract class CustomRenderComponent> extends Component> { + public CustomRenderComponent( + DynamicSize width, + DynamicSize height + ) { + super(width, height, new CustomRenderRenderer<>()); + renderer.linkedComponent = (C) this; + } + + protected abstract void customRender( + PoseStack stack, + int x, + int y, + float deltaTicks, + Rectangle bounds, + Rectangle clipRect + ); + + protected static class CustomRenderRenderer> implements ComponentRenderer { + C linkedComponent; + + @Override + public void renderInBounds( + PoseStack stack, + int mouseX, + int mouseY, + float deltaTicks, + Rectangle bounds, + Rectangle clipRect + ) { + if (linkedComponent != null) { + linkedComponent.customRender(stack, mouseX, mouseY, deltaTicks, bounds, clipRect); + } + } + } +} diff --git a/src/main/java/org/betterx/ui/layout/components/Image.java b/src/main/java/org/betterx/ui/layout/components/Image.java new file mode 100644 index 00000000..bf84b3f8 --- /dev/null +++ b/src/main/java/org/betterx/ui/layout/components/Image.java @@ -0,0 +1,115 @@ +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 com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.resources.ResourceLocation; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class Image extends CustomRenderComponent { + protected Rectangle uvRect; + public final ResourceLocation location; + protected float alpha; + protected Size resourceSize; + + public Image(DynamicSize width, DynamicSize height, ResourceLocation location) { + this(width, height, location, new Size(16, 16)); + } + + public Image(DynamicSize width, DynamicSize height, ResourceLocation location, Size resourceSize) { + super(width, height); + this.location = location; + this.uvRect = new Rectangle(0, 0, resourceSize.width(), resourceSize.height()); + this.resourceSize = resourceSize; + this.alpha = 1f; + } + + + public Image setAlpha(float a) { + alpha = a; + return this; + } + + public float getAlpha() { + return alpha; + } + + + public Image setUvRect(int left, int top, int width, int height) { + uvRect = new Rectangle(left, top, width, height); + return this; + } + + public Rectangle getUvRect() { + return uvRect; + } + + public Image setResourceSize(int width, int height) { + resourceSize = new Size(width, height); + return this; + } + + public Size getResourceSize() { + return resourceSize; + } + + @Override + public int getContentWidth() { + return resourceSize.width(); + } + + @Override + public int getContentHeight() { + return resourceSize.height(); + } + + + @Override + protected void customRender( + PoseStack stack, + int mouseX, + int mouseY, + float deltaTicks, + Rectangle bounds, + Rectangle clipRect + ) { + renderImage(stack, bounds, location, uvRect, resourceSize, alpha); + } + + protected static void renderImage( + PoseStack stack, + Rectangle bounds, + ResourceLocation location, + Rectangle uvRect, + Size size, + float alpha + ) { + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderTexture(0, location); + RenderSystem.enableBlend(); + RenderSystem.blendFunc( + GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA + ); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, alpha); + GuiComponent.blit( + stack, + 0, 0, bounds.width, bounds.height, + uvRect.left, + uvRect.top, + uvRect.width, + uvRect.height, + size.width(), + size.height() + ); + } +} diff --git a/src/main/java/org/betterx/ui/layout/components/Panel.java b/src/main/java/org/betterx/ui/layout/components/Panel.java index 049d1243..c8dd99ba 100644 --- a/src/main/java/org/betterx/ui/layout/components/Panel.java +++ b/src/main/java/org/betterx/ui/layout/components/Panel.java @@ -94,9 +94,9 @@ public class Panel implements ComponentWithBounds, RelativeContainerEventHandler } @Override - public void render(PoseStack poseStack, int x, int y, float a) { + public void render(PoseStack poseStack, int mouseX, int mouseY, float deltaTicks) { if (child != null) { - child.render(poseStack, x - bounds.left, y - bounds.top, a, bounds, bounds); + child.render(poseStack, mouseX - bounds.left, mouseY - bounds.top, deltaTicks, bounds, bounds); } } // @Override diff --git a/src/main/java/org/betterx/ui/layout/components/Text.java b/src/main/java/org/betterx/ui/layout/components/Text.java index 748b0855..5f84898c 100644 --- a/src/main/java/org/betterx/ui/layout/components/Text.java +++ b/src/main/java/org/betterx/ui/layout/components/Text.java @@ -54,7 +54,14 @@ public class Text extends Component { } @Override - public void renderInBounds(PoseStack stack, int x, int y, float a, Rectangle bounds, Rectangle clipRect) { + public void renderInBounds( + PoseStack stack, + int mouseX, + int mouseY, + float deltaTicks, + Rectangle bounds, + Rectangle clipRect + ) { if (linkedComponent != null) { int left = bounds.width - getWidth(linkedComponent.text); if (linkedComponent.hAlign == Alignment.MIN) left = 0; 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 651c628b..51d051fe 100644 --- a/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java +++ b/src/main/java/org/betterx/ui/layout/components/VerticalScroll.java @@ -3,6 +3,7 @@ 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.Alignment; import org.betterx.ui.layout.values.DynamicSize; import org.betterx.ui.layout.values.Rectangle; import org.betterx.ui.vanilla.VanillaScrollerRenderer; @@ -59,7 +60,7 @@ public class VerticalScroll 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 = relativeBounds.height - child.height.calculatedSize(); + if (child.vAlign == Alignment.MIN) childLeft = 0; + else if (child.vAlign == Alignment.CENTER) childLeft /= 2; + + child.setRelativeBounds(childLeft, childTop); + } updateScrollViewMetrics(); } @@ -100,13 +117,13 @@ public class VerticalScroll