Image Component
This commit is contained in:
parent
51da03f3c8
commit
877489c469
13 changed files with 263 additions and 36 deletions
|
@ -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"),
|
||||
|
|
|
@ -46,15 +46,15 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
|
|||
@Override
|
||||
protected void renderInBounds(
|
||||
PoseStack poseStack,
|
||||
int x,
|
||||
int y,
|
||||
float a,
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
float deltaTicks,
|
||||
Rectangle renderBounds,
|
||||
Rectangle clipRect
|
||||
) {
|
||||
super.renderInBounds(poseStack, x, y, a, renderBounds, clipRect);
|
||||
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||
for (Component<?> c : components) {
|
||||
c.render(poseStack, x, y, a, renderBounds, clipRect);
|
||||
c.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,13 +19,20 @@ public class AbstractVanillaComponentRenderer<C extends AbstractWidget, V extend
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderInBounds(PoseStack poseStack, int x, int y, float a, Rectangle bounds, Rectangle clipRect) {
|
||||
public void renderInBounds(
|
||||
PoseStack poseStack,
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
float deltaTicks,
|
||||
Rectangle bounds,
|
||||
Rectangle clipRect
|
||||
) {
|
||||
if (linkedComponent != null) {
|
||||
if (linkedComponent.vanillaComponent != null) {
|
||||
if (!linkedComponent.enabled) {
|
||||
linkedComponent.vanillaComponent.setAlpha(linkedComponent.alpha / 2);
|
||||
}
|
||||
linkedComponent.vanillaComponent.render(poseStack, x, y, a);
|
||||
linkedComponent.vanillaComponent.render(poseStack, mouseX, mouseY, deltaTicks);
|
||||
if (!linkedComponent.enabled) {
|
||||
linkedComponent.vanillaComponent.setAlpha(linkedComponent.alpha);
|
||||
}
|
||||
|
|
|
@ -82,28 +82,35 @@ public abstract class Component<R extends ComponentRenderer> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<C extends CustomRenderComponent<C>> extends Component<CustomRenderComponent.CustomRenderRenderer<C>> {
|
||||
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<C extends CustomRenderComponent<C>> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
115
src/main/java/org/betterx/ui/layout/components/Image.java
Normal file
115
src/main/java/org/betterx/ui/layout/components/Image.java
Normal file
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -54,7 +54,14 @@ public class Text extends Component<Text.TextRenderer> {
|
|||
}
|
||||
|
||||
@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;
|
||||
|
|
|
@ -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<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
protected int updateContainerWidth(int containerWidth) {
|
||||
int myWidth = width.calculateOrFill(containerWidth);
|
||||
if (child != null) {
|
||||
child.width.calculateOrFill(myWidth - (scrollerRenderer.scrollerPadding() + scrollerRenderer.scrollerWidth()));
|
||||
child.width.calculateOrFill(myWidth - scrollerWidth());
|
||||
child.updateContainerWidth(child.width.calculatedSize());
|
||||
}
|
||||
return myWidth;
|
||||
|
@ -75,9 +76,13 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
return myHeight;
|
||||
}
|
||||
|
||||
protected int scrollerWidth() {
|
||||
return scrollerRenderer.scrollerWidth() + scrollerRenderer.scrollerPadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getContentWidth() {
|
||||
return scrollerRenderer.scrollerWidth() + scrollerRenderer.scrollerPadding() + (child != null
|
||||
return scrollerWidth() + (child != null
|
||||
? child.getContentWidth()
|
||||
: 0);
|
||||
}
|
||||
|
@ -91,8 +96,20 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
void setRelativeBounds(int left, int top) {
|
||||
super.setRelativeBounds(left, top);
|
||||
|
||||
if (child != null)
|
||||
child.setRelativeBounds(0, 0);
|
||||
if (child != null) {
|
||||
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 = 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<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
@Override
|
||||
protected void renderInBounds(
|
||||
PoseStack poseStack,
|
||||
int x,
|
||||
int y,
|
||||
float a,
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
float deltaTicks,
|
||||
Rectangle renderBounds,
|
||||
Rectangle clipRect
|
||||
) {
|
||||
super.renderInBounds(poseStack, x, y, a, renderBounds, clipRect);
|
||||
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||
|
||||
if (showScrollBar()) {
|
||||
if (child != null) {
|
||||
|
@ -114,13 +131,8 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
poseStack.translate(0, scrollerOffset(), 0);
|
||||
setClippingRect(clipRect);
|
||||
child.render(
|
||||
poseStack, x, y, a,
|
||||
renderBounds.movedBy(
|
||||
0,
|
||||
scrollerOffset(),
|
||||
scrollerRenderer.scrollerWidth() + scrollerRenderer.scrollerPadding(),
|
||||
0
|
||||
),
|
||||
poseStack, mouseX, mouseY, deltaTicks,
|
||||
renderBounds.movedBy(0, scrollerOffset(), scrollerWidth(), 0),
|
||||
clipRect
|
||||
);
|
||||
setClippingRect(null);
|
||||
|
@ -129,7 +141,7 @@ public class VerticalScroll<R extends ComponentRenderer, RS extends ScrollerRend
|
|||
scrollerRenderer.renderScrollBar(renderBounds, saveScrollerY(), scrollerHeight);
|
||||
} else {
|
||||
if (child != null) {
|
||||
child.render(poseStack, x, y, a, renderBounds, clipRect);
|
||||
child.render(poseStack, mouseX, mouseY, deltaTicks, renderBounds, clipRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,5 +9,12 @@ import net.fabricmc.api.Environment;
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface ComponentRenderer {
|
||||
void renderInBounds(PoseStack stack, int x, int y, float a, Rectangle bounds, Rectangle clipRect);
|
||||
void renderInBounds(
|
||||
PoseStack stack,
|
||||
int mouseX,
|
||||
int mouseY,
|
||||
float deltaTicks,
|
||||
Rectangle bounds,
|
||||
Rectangle clipRect
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,14 @@ import net.fabricmc.api.Environment;
|
|||
@Environment(EnvType.CLIENT)
|
||||
public class NullRenderer implements ComponentRenderer {
|
||||
@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
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package org.betterx.ui.layout.components.render;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface TextProvider {
|
||||
default Font getFont() {
|
||||
return Minecraft.getInstance().font;
|
||||
|
|
4
src/main/java/org/betterx/ui/layout/values/Size.java
Normal file
4
src/main/java/org/betterx/ui/layout/values/Size.java
Normal file
|
@ -0,0 +1,4 @@
|
|||
package org.betterx.ui.layout.values;
|
||||
|
||||
public record Size(int width, int height) {
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue