Improved WorldSetupScreen
This commit is contained in:
parent
461dcd9a8a
commit
799018222c
12 changed files with 264 additions and 12 deletions
|
@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
public abstract class BCLibLayoutScreen extends LayoutScreenWithIcon {
|
||||
static final ResourceLocation BCLIB_LOGO_LOCATION = new ResourceLocation(BCLib.MOD_ID, "icon.png");
|
||||
static final ResourceLocation BCLIB_LOGO_WHITE_LOCATION = new ResourceLocation(BCLib.MOD_ID, "icon_bright.png");
|
||||
|
||||
public BCLibLayoutScreen(
|
||||
Component component
|
||||
|
|
|
@ -7,11 +7,15 @@ import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
|
|||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
import org.betterx.bclib.registry.PresetsRegistry;
|
||||
import org.betterx.ui.layout.components.*;
|
||||
import org.betterx.ui.layout.components.render.RenderHelper;
|
||||
import org.betterx.ui.layout.values.Rectangle;
|
||||
import org.betterx.ui.layout.values.Size;
|
||||
import org.betterx.ui.vanilla.LayoutScreen;
|
||||
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldGenSettingsComponentAccessor;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldCreationContext;
|
||||
import net.minecraft.core.Holder;
|
||||
|
@ -292,6 +296,10 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
return cols;
|
||||
}
|
||||
|
||||
Button netherButton, endButton;
|
||||
VerticalScroll<?> scroller;
|
||||
HorizontalStack title;
|
||||
|
||||
@Override
|
||||
protected LayoutComponent<?, ?> initContent() {
|
||||
BCLEndBiomeSourceConfig endConfig = BCLEndBiomeSourceConfig.VANILLA;
|
||||
|
@ -317,12 +325,19 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
|
||||
Tabs main = new Tabs(fill(), fill()).setPadding(8, 0, 0, 0);
|
||||
main.addPage(Component.translatable("title.bclib.the_nether"), VerticalScroll.create(netherPage));
|
||||
main.addPage(Component.translatable("title.bclib.the_end"), VerticalScroll.create(endPage));
|
||||
main.addSpacer(8);
|
||||
main.addPage(Component.translatable("title.bclib.the_end"), scroller = VerticalScroll.create(endPage));
|
||||
netherButton = main.getButton(0);
|
||||
endButton = main.getButton(1);
|
||||
|
||||
HorizontalStack title = new HorizontalStack(fit(), fit()).setDebugName("title bar");
|
||||
title.addIcon(BCLibLayoutScreen.BCLIB_LOGO_LOCATION, Size.of(512)).setDebugName("icon");
|
||||
title = new HorizontalStack(fit(), fit()).setDebugName("title bar").alignBottom();
|
||||
title.addImage(fixed(22), fixed(22), BCLibLayoutScreen.BCLIB_LOGO_WHITE_LOCATION, Size.of(256))
|
||||
.setDebugName("icon");
|
||||
title.addSpacer(4);
|
||||
title.add(super.buildTitle());
|
||||
VerticalStack logos = title.addColumn(fit(), fit());
|
||||
logos.addImage(fixed(178 / 3), fixed(40 / 3), WelcomeScreen.BETTERX_LOCATION, Size.of(178, 40));
|
||||
logos.add(super.buildTitle());
|
||||
logos.addSpacer(2);
|
||||
|
||||
main.addFiller();
|
||||
main.addComponent(title);
|
||||
|
@ -336,6 +351,118 @@ public class WorldSetupScreen extends LayoutScreen {
|
|||
onClose();
|
||||
}).alignRight();
|
||||
|
||||
main.onPageChange((tabs, idx) -> {
|
||||
targetT = 1 - idx;
|
||||
});
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderBackground(PoseStack poseStack, int i, int j, float f) {
|
||||
GuiComponent.fill(poseStack, 0, 0, width, height, 0xBD343444);
|
||||
}
|
||||
|
||||
record IconState(int left, int top, int size) {
|
||||
//easing curves from https://easings.net/de
|
||||
static double easeInOutQuint(double t) {
|
||||
return t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2;
|
||||
}
|
||||
|
||||
static double easeOutBounce(double x) {
|
||||
final double n1 = 7.5625;
|
||||
final double d1 = 2.75;
|
||||
|
||||
if (x < 1 / d1) {
|
||||
return n1 * x * x;
|
||||
} else if (x < 2 / d1) {
|
||||
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
||||
} else if (x < 2.5 / d1) {
|
||||
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
||||
} else {
|
||||
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
||||
}
|
||||
}
|
||||
|
||||
static int lerp(double t, int x0, int x1) {
|
||||
return (int) ((1 - t) * x0 + t * x1);
|
||||
}
|
||||
}
|
||||
|
||||
IconState netherOff, netherOn, endOff, endOn;
|
||||
double iconT = 0.5;
|
||||
double targetT = 1;
|
||||
|
||||
@Override
|
||||
public void render(PoseStack poseStack, int i, int j, float f) {
|
||||
super.render(poseStack, i, j, f);
|
||||
final double SPEED = 0.05;
|
||||
if (targetT < iconT && iconT > 0) iconT = Math.max(0, iconT - f * SPEED);
|
||||
else if (targetT > iconT && iconT < 1) iconT = Math.min(1, iconT + f * SPEED);
|
||||
|
||||
final double t;
|
||||
if (iconT > 0 && iconT < 1) {
|
||||
if (targetT > iconT) {
|
||||
t = IconState.easeOutBounce(iconT);
|
||||
} else {
|
||||
t = 1 - IconState.easeOutBounce(1 - iconT);
|
||||
}
|
||||
} else t = iconT;
|
||||
|
||||
if (endButton != null) {
|
||||
if (endOff == null) {
|
||||
endOff = new IconState(
|
||||
endButton.getScreenBounds().right() - 12,
|
||||
endButton.getScreenBounds().top - 7,
|
||||
16
|
||||
);
|
||||
endOn = new IconState(
|
||||
(title.getScreenBounds().left - endButton.getScreenBounds().right()) / 2
|
||||
+ endButton.getScreenBounds().right()
|
||||
- 14,
|
||||
scroller.getScreenBounds().top - 16,
|
||||
32
|
||||
);
|
||||
}
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(
|
||||
IconState.lerp(t, endOn.left, endOff.left),
|
||||
IconState.lerp(t, endOn.top, endOff.top),
|
||||
0
|
||||
);
|
||||
int size = IconState.lerp(t, endOn.size, endOff.size);
|
||||
RenderHelper.renderImage(
|
||||
poseStack, size, size,
|
||||
WelcomeScreen.ICON_BETTEREND,
|
||||
new Rectangle(0, 0, 32, 32),
|
||||
Size.of(32), 1
|
||||
);
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
||||
if (netherButton != null) {
|
||||
if (netherOff == null) {
|
||||
netherOff = new IconState(
|
||||
netherButton.getScreenBounds().right() - 12,
|
||||
netherButton.getScreenBounds().top - 7,
|
||||
16
|
||||
);
|
||||
netherOn = endOn;
|
||||
}
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(
|
||||
IconState.lerp(t, netherOff.left, netherOn.left),
|
||||
IconState.lerp(t, netherOff.top, netherOn.top),
|
||||
0
|
||||
);
|
||||
int size = IconState.lerp(t, netherOff.size, netherOn.size);
|
||||
RenderHelper.renderImage(
|
||||
poseStack, size, size,
|
||||
WelcomeScreen.ICON_BETTERNETHER,
|
||||
new Rectangle(0, 0, 32, 32),
|
||||
Size.of(32), 1
|
||||
);
|
||||
poseStack.popPose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class AbstractHorizontalStack<S extends AbstractHorizontalStack<S>> exten
|
|||
return myHeight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
void setRelativeBounds(int left, int top) {
|
||||
super.setRelativeBounds(left, top);
|
||||
|
|
|
@ -47,6 +47,15 @@ public abstract class AbstractStack<R extends ComponentRenderer, T extends Abstr
|
|||
.reduce(0, Integer::sum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreenBounds(int worldX, int worldY) {
|
||||
super.updateScreenBounds(worldX, worldY);
|
||||
for (LayoutComponent<?, ?> c : components) {
|
||||
c.updateScreenBounds(screenBounds.left, screenBounds.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void renderInBounds(
|
||||
PoseStack poseStack,
|
||||
|
|
|
@ -209,6 +209,14 @@ public class Container extends LayoutComponent<Container.ContainerRenderer, Cont
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreenBounds(int worldX, int worldY) {
|
||||
super.updateScreenBounds(worldX, worldY);
|
||||
for (LayoutComponent<?, ?> c : children) {
|
||||
c.updateScreenBounds(screenBounds.left, screenBounds.top);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(double d, double e) {
|
||||
if (visible)
|
||||
|
|
|
@ -20,6 +20,7 @@ public abstract class LayoutComponent<R extends ComponentRenderer, L extends Lay
|
|||
protected final Value height;
|
||||
protected String debugName;
|
||||
protected Rectangle relativeBounds;
|
||||
protected Rectangle screenBounds;
|
||||
protected Alignment vAlign = Alignment.MIN;
|
||||
protected Alignment hAlign = Alignment.MIN;
|
||||
|
||||
|
@ -33,6 +34,7 @@ public abstract class LayoutComponent<R extends ComponentRenderer, L extends Lay
|
|||
updateContainerWidth(relativeBounds.width);
|
||||
updateContainerHeight(relativeBounds.height);
|
||||
setRelativeBounds(relativeBounds.left, relativeBounds.top);
|
||||
updateScreenBounds(screenBounds.left, screenBounds.top);
|
||||
}
|
||||
|
||||
protected int updateContainerWidth(int containerWidth) {
|
||||
|
@ -48,6 +50,10 @@ public abstract class LayoutComponent<R extends ComponentRenderer, L extends Lay
|
|||
onBoundsChanged();
|
||||
}
|
||||
|
||||
public void updateScreenBounds(int worldX, int worldY) {
|
||||
screenBounds = relativeBounds.movedBy(worldX, worldY);
|
||||
}
|
||||
|
||||
protected void onBoundsChanged() {
|
||||
}
|
||||
|
||||
|
@ -55,6 +61,10 @@ public abstract class LayoutComponent<R extends ComponentRenderer, L extends Lay
|
|||
return relativeBounds;
|
||||
}
|
||||
|
||||
public Rectangle getScreenBounds() {
|
||||
return screenBounds;
|
||||
}
|
||||
|
||||
public abstract int getContentWidth();
|
||||
public abstract int getContentHeight();
|
||||
|
||||
|
@ -83,9 +93,9 @@ public abstract class LayoutComponent<R extends ComponentRenderer, L extends Lay
|
|||
final int windowHeight = Minecraft.getInstance().getWindow().getHeight();
|
||||
RenderSystem.enableScissor(
|
||||
(int) (clippingRect.left * uiScale),
|
||||
(int) (windowHeight - (clippingRect.bottom() + 1) * uiScale),
|
||||
(int) (windowHeight - (clippingRect.bottom()) * uiScale),
|
||||
(int) (clippingRect.width * uiScale),
|
||||
(int) ((clippingRect.height + 1) * uiScale)
|
||||
(int) ((clippingRect.height) * uiScale)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -96,8 +96,8 @@ public class MultiLineText extends LayoutComponent<MultiLineText.MultiLineTextRe
|
|||
}
|
||||
|
||||
@Override
|
||||
void setRelativeBounds(int left, int top) {
|
||||
super.setRelativeBounds(left, top);
|
||||
protected void onBoundsChanged() {
|
||||
super.onBoundsChanged();
|
||||
multiLineLabel = createVanillaComponent();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ public class Panel implements ComponentWithBounds, RelativeContainerEventHandler
|
|||
child.updateContainerWidth(bounds.width);
|
||||
child.updateContainerHeight(bounds.height);
|
||||
child.setRelativeBounds(0, 0);
|
||||
child.updateScreenBounds(bounds.left, bounds.top);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,11 @@ import java.util.List;
|
|||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class Tabs extends AbstractVerticalStack<Tabs> {
|
||||
@FunctionalInterface
|
||||
public interface OnPageChange {
|
||||
void now(Tabs tabs, int pageIndex);
|
||||
}
|
||||
|
||||
private final HorizontalStack buttons;
|
||||
private final Container content;
|
||||
|
||||
|
@ -20,6 +25,8 @@ public class Tabs extends AbstractVerticalStack<Tabs> {
|
|||
|
||||
private int initialPage = 0;
|
||||
|
||||
private OnPageChange onPageChange;
|
||||
|
||||
|
||||
public Tabs(Value width, Value height) {
|
||||
super(width, height);
|
||||
|
@ -45,9 +52,16 @@ public class Tabs extends AbstractVerticalStack<Tabs> {
|
|||
for (Container cc : pageList) {
|
||||
cc.setVisible(cc == c);
|
||||
}
|
||||
|
||||
for (Button bb : buttonList) {
|
||||
bb.glow = bb == b;
|
||||
}
|
||||
|
||||
if (onPageChange != null) {
|
||||
for (int i = 0; i < buttonList.size(); i++) {
|
||||
if (buttonList.get(i).glow) onPageChange.now(this, i);
|
||||
}
|
||||
}
|
||||
});
|
||||
buttons.add(b);
|
||||
buttonList.add(b);
|
||||
|
@ -56,6 +70,15 @@ public class Tabs extends AbstractVerticalStack<Tabs> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Tabs onPageChange(OnPageChange e) {
|
||||
this.onPageChange = e;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button getButton(int idx) {
|
||||
return buttonList.get(idx);
|
||||
}
|
||||
|
||||
public Tabs setBackgroundColor(int color) {
|
||||
content.setBackgroundColor(color);
|
||||
return this;
|
||||
|
@ -108,9 +131,10 @@ public class Tabs extends AbstractVerticalStack<Tabs> {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
void setRelativeBounds(int left, int top) {
|
||||
super.setRelativeBounds(left, top);
|
||||
protected void onBoundsChanged() {
|
||||
super.onBoundsChanged();
|
||||
selectPage(initialPage);
|
||||
}
|
||||
|
||||
|
|
|
@ -132,6 +132,12 @@ public class VerticalScroll<RS extends ScrollerRenderer> extends LayoutComponent
|
|||
updateScrollViewMetrics();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateScreenBounds(int worldX, int worldY) {
|
||||
super.updateScreenBounds(worldX, worldY);
|
||||
child.updateScreenBounds(screenBounds.left, screenBounds.top);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderInBounds(
|
||||
PoseStack poseStack,
|
||||
|
|
|
@ -6,12 +6,16 @@ import org.betterx.ui.layout.components.Button;
|
|||
import org.betterx.ui.layout.values.Rectangle;
|
||||
|
||||
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 ButtonRenderer extends AbstractVanillaComponentRenderer<net.minecraft.client.gui.components.Button, Button> {
|
||||
double deltaSum = 0;
|
||||
double deltaSum2 = .34;
|
||||
double deltaSum3 = .12;
|
||||
|
||||
@Override
|
||||
public void renderInBounds(
|
||||
|
@ -23,8 +27,70 @@ public class ButtonRenderer extends AbstractVanillaComponentRenderer<net.minecra
|
|||
Rectangle clipRect
|
||||
) {
|
||||
super.renderInBounds(poseStack, mouseX, mouseY, deltaTicks, bounds, clipRect);
|
||||
deltaSum += deltaTicks * 0.03;
|
||||
deltaSum2 += deltaTicks * 0.032;
|
||||
deltaSum3 += deltaTicks * 0.028;
|
||||
if (getLinkedComponent() != null && getLinkedComponent().isGlowing()) {
|
||||
RenderHelper.outline(poseStack, 0, 0, bounds.width, bounds.height, ColorUtil.RED);
|
||||
RenderHelper.outline(poseStack, 0, 0, bounds.width, bounds.height, ColorUtil.YELLOW);
|
||||
int len = 2 * bounds.width + 2 * bounds.height;
|
||||
|
||||
deltaSum = deltaSum - (int) deltaSum;
|
||||
int pos = (int) (len * deltaSum);
|
||||
|
||||
drawMoving(poseStack, bounds, pos);
|
||||
drawMoving(poseStack, bounds, pos + 2);
|
||||
drawMoving(poseStack, bounds, pos + 3);
|
||||
drawMoving(poseStack, bounds, pos + 4);
|
||||
drawMoving(poseStack, bounds, pos + 5);
|
||||
drawMoving(poseStack, bounds, pos + 7);
|
||||
|
||||
|
||||
deltaSum2 = deltaSum2 - (int) deltaSum2;
|
||||
pos = (int) (len * deltaSum2);
|
||||
|
||||
drawMoving(poseStack, bounds, pos + len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 2 + len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 3 + len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 4 + len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 5 + len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 7 + len / 3);
|
||||
|
||||
|
||||
deltaSum3 = deltaSum3 - (int) deltaSum3;
|
||||
pos = (int) (len * deltaSum3);
|
||||
|
||||
drawMoving(poseStack, bounds, pos + 2 * len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 2 + 2 * len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 3 + 2 * len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 4 + 2 * len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 5 + 2 * len / 3);
|
||||
drawMoving(poseStack, bounds, pos + 7 + 2 * len / 3);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawMoving(PoseStack poseStack, Rectangle bounds, int pos) {
|
||||
int bh = bounds.width + bounds.height;
|
||||
pos = pos % (2 * bh);
|
||||
int x, y;
|
||||
/**
|
||||
* pos <= w : x=pos, y=0
|
||||
* pos > w && pos<=w+h : x=w, y=pos-w
|
||||
* pos >w+h && pos<=2w+h : x=2w +h - pos, y=h
|
||||
* pos>2w+h : x=0, y=2w+2h-pos
|
||||
*/
|
||||
if (pos <= bounds.width) {
|
||||
x = pos;
|
||||
y = 0;
|
||||
} else if (pos <= bh) {
|
||||
x = bounds.width - 1;
|
||||
y = pos - bounds.width;
|
||||
} else if (pos <= bh + bounds.width) {
|
||||
x = bh + bounds.width - pos;
|
||||
y = bounds.height - 1;
|
||||
} else {
|
||||
x = 0;
|
||||
y = 2 * bh - pos;
|
||||
}
|
||||
GuiComponent.fill(poseStack, x, y, x + 1, y + 1, ColorUtil.BLACK);
|
||||
}
|
||||
}
|
||||
|
|
BIN
src/main/resources/assets/bclib/icon_bright.png
Normal file
BIN
src/main/resources/assets/bclib/icon_bright.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
Add table
Add a link
Reference in a new issue