Refactored BCLib Package Structure
This commit is contained in:
parent
c658a24750
commit
f6d5f85ec1
206 changed files with 974 additions and 945 deletions
|
@ -7,9 +7,9 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.model.*;
|
||||
|
||||
import org.betterx.bclib.api.ModIntegrationAPI;
|
||||
import org.betterx.bclib.api.PostInitAPI;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.v2.ModIntegrationAPI;
|
||||
import org.betterx.bclib.api.v2.PostInitAPI;
|
||||
import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.client.models.CustomModelBakery;
|
||||
import org.betterx.bclib.client.presets.WorldPresetsUI;
|
||||
import org.betterx.bclib.registry.BaseBlockEntityRenders;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.betterx.bclib.interfaces.TriConsumer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
class GridCell extends GridCellDefinition {
|
||||
public final float height;
|
||||
Function<GridTransform, Object> componentPlacer;
|
||||
TriConsumer<PoseStack, GridTransform, Object> customRender;
|
||||
|
||||
GridCell(double width,
|
||||
double height,
|
||||
GridLayout.GridValueType widthType,
|
||||
Function<GridTransform, Object> componentPlacer,
|
||||
TriConsumer<PoseStack, GridTransform, Object> customRender) {
|
||||
super(width, widthType);
|
||||
this.height = (float) height;
|
||||
this.componentPlacer = componentPlacer;
|
||||
this.customRender = customRender;
|
||||
}
|
||||
|
||||
protected GridElement buildElementAt(int left, int top, int width, final List<GridElement> collector) {
|
||||
return new GridElement(left, top, width, (int) this.height, componentPlacer, customRender);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.components.Checkbox;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
class SignalingCheckBox extends Checkbox {
|
||||
private final Consumer<Boolean> onChange;
|
||||
|
||||
public SignalingCheckBox(int left,
|
||||
int top,
|
||||
int width,
|
||||
int height,
|
||||
Component component,
|
||||
boolean checked,
|
||||
Consumer<Boolean> onChange) {
|
||||
super(left, top, width, height, component, checked);
|
||||
this.onChange = onChange;
|
||||
if (onChange != null)
|
||||
onChange.accept(checked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPress() {
|
||||
super.onPress();
|
||||
if (onChange != null)
|
||||
onChange.accept(this.selected());
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridCheckboxCell extends GridCell implements GridWidgetWithEnabledState {
|
||||
private boolean checked;
|
||||
private Checkbox lastCheckbox;
|
||||
private boolean enabled;
|
||||
private final float alpha;
|
||||
|
||||
GridCheckboxCell(Component text,
|
||||
boolean checked,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height) {
|
||||
this(text, checked, alpha, width, widthType, height, null);
|
||||
}
|
||||
|
||||
GridCheckboxCell(Component text,
|
||||
boolean checked,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height,
|
||||
Consumer<Boolean> onChange) {
|
||||
super(width, height, widthType, null, null);
|
||||
lastCheckbox = null;
|
||||
enabled = true;
|
||||
this.alpha = alpha;
|
||||
this.componentPlacer = (transform) -> {
|
||||
Checkbox cb = new SignalingCheckBox(transform.left, transform.top, transform.width, transform.height,
|
||||
text,
|
||||
checked,
|
||||
(state) -> {
|
||||
this.checked = state;
|
||||
if (onChange != null) onChange.accept(state);
|
||||
}
|
||||
);
|
||||
cb.setAlpha(alpha);
|
||||
lastCheckbox = cb;
|
||||
setEnabled(enabled);
|
||||
return cb;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public boolean isChecked() {
|
||||
return checked;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
if (lastCheckbox != null) {
|
||||
lastCheckbox.active = enabled;
|
||||
lastCheckbox.setAlpha(enabled ? alpha : (alpha * 0.5f));
|
||||
}
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridColumn extends GridContainer {
|
||||
GridColumn(double width) {
|
||||
super(width);
|
||||
}
|
||||
|
||||
GridColumn(double width, GridLayout.GridValueType widthType) {
|
||||
super(width, widthType);
|
||||
}
|
||||
|
||||
public GridRow addRow() {
|
||||
return addRow(GridLayout.VerticalAlignment.TOP);
|
||||
}
|
||||
|
||||
public GridRow addRow(GridLayout.VerticalAlignment align) {
|
||||
GridRow row = new GridRow(1.0,
|
||||
widthType == GridLayout.GridValueType.INHERIT
|
||||
? GridLayout.GridValueType.INHERIT
|
||||
: GridLayout.GridValueType.PERCENTAGE,
|
||||
align);
|
||||
this.cells.add(row);
|
||||
return row;
|
||||
}
|
||||
|
||||
|
||||
public void addSpacerRow() {
|
||||
this.addSpacerRow(4);
|
||||
}
|
||||
|
||||
public void addSpacerRow(int height) {
|
||||
GridCell cell = new GridCell(1.0, height, GridLayout.GridValueType.PERCENTAGE, null, null);
|
||||
this.cells.add(cell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculateWidth(final int parentWidth) {
|
||||
if (widthType == GridLayout.GridValueType.INHERIT) {
|
||||
return cells.stream()
|
||||
.filter(row -> row.widthType == GridLayout.GridValueType.INHERIT)
|
||||
.map(row -> row.buildElement(0, 0, 1, 0, 0, null).width)
|
||||
.reduce(0, (p, c) -> Math.max(p, c));
|
||||
|
||||
} else {
|
||||
return super.calculateWidth(parentWidth);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected GridElement buildElementAt(int left, int inTop, int width, final List<GridElement> collector) {
|
||||
int height = 0;
|
||||
int top = inTop;
|
||||
|
||||
if (widthType == GridLayout.GridValueType.INHERIT) {
|
||||
width = calculateWidth(width);
|
||||
}
|
||||
|
||||
for (GridCellDefinition row : cells) {
|
||||
GridElement element = row.buildElement(width, 0, 1, left, top, collector);
|
||||
top += element.height;
|
||||
height += element.height;
|
||||
}
|
||||
|
||||
return new GridElement(left, inTop, width, height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout.GridValueType;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class GridCustomRenderCell extends GridCell {
|
||||
protected GridCustomRenderCell(double width, GridValueType widthType, double height) {
|
||||
super(width, height, widthType, null, null);
|
||||
this.customRender = this::onRender;
|
||||
}
|
||||
|
||||
public abstract void onRender(PoseStack poseStack, GridTransform transform, Object context);
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
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;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridImageCell extends GridCell {
|
||||
GridImageCell(ResourceLocation location,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height,
|
||||
float alpha,
|
||||
int uvLeft,
|
||||
int uvTop,
|
||||
int uvWidth,
|
||||
int uvHeight,
|
||||
int resourceWidth,
|
||||
int resourceHeight) {
|
||||
super(width, height, widthType, null, (poseStack, transform, context) -> {
|
||||
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(poseStack,
|
||||
transform.left,
|
||||
transform.top,
|
||||
transform.width,
|
||||
transform.height,
|
||||
uvLeft,
|
||||
uvTop,
|
||||
uvWidth,
|
||||
uvHeight,
|
||||
resourceWidth,
|
||||
resourceHeight);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.components.AbstractWidget;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout.GridValueType;
|
||||
import org.betterx.bclib.interfaces.TriConsumer;
|
||||
import org.betterx.bclib.util.Pair;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
abstract class GridCellDefinition {
|
||||
public final float width;
|
||||
public final GridLayout.GridValueType widthType;
|
||||
|
||||
public GridCellDefinition(double width, GridLayout.GridValueType widthType) {
|
||||
this.width = (float) width;
|
||||
this.widthType = widthType;
|
||||
}
|
||||
|
||||
public int calculateWidth(final int parentWidth) {
|
||||
if (widthType == GridLayout.GridValueType.CONSTANT) {
|
||||
return (int) this.width;
|
||||
} else if (widthType == GridValueType.PERCENTAGE) {
|
||||
return (int) (this.width * parentWidth);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
final GridElement buildElement(final int parentWidth,
|
||||
final int autoWidth,
|
||||
final float autoWidthSum,
|
||||
int left,
|
||||
final int top,
|
||||
final List<GridElement> collector) {
|
||||
final int width = widthType == GridValueType.FILL
|
||||
? (int) ((this.width / autoWidthSum) * autoWidth)
|
||||
: calculateWidth(parentWidth);
|
||||
|
||||
final GridElement el = buildElementAt(left, top, width, collector);
|
||||
if (collector != null) {
|
||||
collector.add(el);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
abstract protected GridElement buildElementAt(int left, int top, int width, final List<GridElement> collector);
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
class GridElement extends GridTransform {
|
||||
final Function<GridTransform, Object> componentPlacer;
|
||||
final TriConsumer<PoseStack, GridTransform, Object> customRender;
|
||||
Object renderContext;
|
||||
|
||||
GridElement(int left,
|
||||
int top,
|
||||
int width,
|
||||
int height,
|
||||
Function<GridTransform, Object> componentPlacer,
|
||||
TriConsumer<PoseStack, GridTransform, Object> customRender) {
|
||||
super(left, top, width, height);
|
||||
this.componentPlacer = componentPlacer;
|
||||
this.customRender = customRender;
|
||||
}
|
||||
|
||||
GridElement(int left, int top, int width, int height) {
|
||||
this(left, top, width, height, null, null);
|
||||
}
|
||||
|
||||
GridTransform transformWithPadding(int leftPadding, int topPadding) {
|
||||
return new GridTransform(left + leftPadding, top + topPadding, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
abstract class GridContainer extends GridCellDefinition {
|
||||
protected List<GridCellDefinition> cells;
|
||||
|
||||
public GridContainer(double width) {
|
||||
this(width, GridLayout.GridValueType.CONSTANT);
|
||||
}
|
||||
|
||||
GridContainer(double width, GridLayout.GridValueType widthType) {
|
||||
super(width, widthType);
|
||||
cells = new LinkedList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridLayout extends GridColumn {
|
||||
public static final int COLOR_WHITE = 0xFFFFFFFF;
|
||||
public static final int COLOR_RED = 0xFFDB1F48;
|
||||
public static final int COLOR_CYAN = 0xFF01949A;
|
||||
public static final int COLOR_GREEN = 0xFF00FF00;
|
||||
public static final int COLOR_DARK_GREEN = 0xFF007F00;
|
||||
public static final int COLOR_YELLOW = 0xFFFAD02C;
|
||||
public static final int COLOR_BLUE = 0xFF0000FF;
|
||||
public static final int COLOR_GRAY = 0xFF7F7F7F;
|
||||
|
||||
public final GridScreen screen;
|
||||
public final int screenHeight;
|
||||
public final int sidePadding;
|
||||
public final int initialTopPadding;
|
||||
public final boolean centerVertically;
|
||||
private int height;
|
||||
private int topPadding;
|
||||
|
||||
private List<GridElement> elements;
|
||||
|
||||
public GridLayout(GridScreen screen) {
|
||||
this(screen, 0, true);
|
||||
}
|
||||
|
||||
public GridLayout(GridScreen screen, int topPadding, boolean centerVertically) {
|
||||
this(screen, topPadding, 20, centerVertically);
|
||||
}
|
||||
|
||||
public GridLayout(GridScreen screen, int topPadding, int sidePadding, boolean centerVertically) {
|
||||
super(screen.width - 2 * sidePadding, GridValueType.CONSTANT);
|
||||
this.screen = screen;
|
||||
this.screenHeight = screen.height;
|
||||
height = 0;
|
||||
this.topPadding = topPadding;
|
||||
this.sidePadding = sidePadding;
|
||||
this.initialTopPadding = topPadding;
|
||||
this.centerVertically = centerVertically;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getTopPadding() {
|
||||
return topPadding;
|
||||
}
|
||||
|
||||
void buildLayout() {
|
||||
elements = new LinkedList<>();
|
||||
GridElement el = this.buildElement((int) this.width, 0, 1, 0, 0, elements);
|
||||
this.height = el.height;
|
||||
if (centerVertically && el.height + initialTopPadding < screenHeight) {
|
||||
topPadding = (screenHeight - el.height) >> 1;
|
||||
} else {
|
||||
topPadding = initialTopPadding;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<Pair<AbstractWidget, Integer>> movableWidgets = new LinkedList<>();
|
||||
|
||||
public void finalizeLayout() {
|
||||
buildLayout();
|
||||
|
||||
elements
|
||||
.stream()
|
||||
.filter(element -> element.componentPlacer != null)
|
||||
.forEach(element -> {
|
||||
final GridTransform transform = element.transformWithPadding(sidePadding, topPadding);
|
||||
final Object context = element.componentPlacer.apply(transform);
|
||||
if (element.customRender != null) {
|
||||
element.renderContext = context;
|
||||
} else if (context instanceof AbstractWidget) {
|
||||
final AbstractWidget widget = (AbstractWidget) context;
|
||||
movableWidgets.add(new Pair(widget, widget.y));
|
||||
screen.addRenderableWidget(widget);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void render(PoseStack poseStack) {
|
||||
if (elements == null) return;
|
||||
elements
|
||||
.stream()
|
||||
.filter(element -> element.customRender != null)
|
||||
.forEach(element -> element.customRender.accept(poseStack,
|
||||
element.transformWithPadding(sidePadding, topPadding),
|
||||
element.renderContext));
|
||||
}
|
||||
|
||||
|
||||
public enum VerticalAlignment {
|
||||
TOP, CENTER, BOTTOM
|
||||
}
|
||||
|
||||
public enum Alignment {
|
||||
LEFT, CENTER, RIGHT
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines how a measurement value is interpreted
|
||||
*/
|
||||
public enum GridValueType {
|
||||
/**
|
||||
* The value is a constant pixel size
|
||||
*/
|
||||
CONSTANT,
|
||||
/**
|
||||
* The Value is relative to the parent size
|
||||
*/
|
||||
PERCENTAGE,
|
||||
/**
|
||||
* The value will be set to fill up the remaining space (i.e. when this is applied to a width of a row element,
|
||||
* a {@link #FILL}-type may be used to right align (FILL - CONSTANT) or center (FILL - CONSTANT - FILL) elements.
|
||||
*/
|
||||
FILL,
|
||||
/**
|
||||
* Calculate size based on child-elements
|
||||
*/
|
||||
INHERIT
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.MultiLineLabel;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridMessageCell extends GridCell {
|
||||
private final Font font;
|
||||
private Component text;
|
||||
private MultiLineLabel lastLabel;
|
||||
private GridTransform lastTransform;
|
||||
|
||||
GridMessageCell(double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
Font font,
|
||||
Component text) {
|
||||
this(width, widthType, contentAlignment, font, text, GridLayout.COLOR_WHITE);
|
||||
}
|
||||
|
||||
GridMessageCell(double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
Font font,
|
||||
Component text,
|
||||
int color) {
|
||||
super(width, -1, widthType, null, null);
|
||||
this.font = font;
|
||||
this.text = text;
|
||||
|
||||
customRender = (poseStack, transform, context) -> {
|
||||
//MultiLineLabel label = (MultiLineLabel) context;
|
||||
if (contentAlignment == GridLayout.Alignment.CENTER) {
|
||||
lastLabel.renderCentered(poseStack,
|
||||
transform.width / 2 + transform.left,
|
||||
transform.top,
|
||||
font.lineHeight,
|
||||
color);
|
||||
} else if (contentAlignment == GridLayout.Alignment.LEFT) {
|
||||
lastLabel.renderLeftAligned(poseStack, transform.left, transform.top, font.lineHeight, color);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setText(Component text) {
|
||||
this.text = text;
|
||||
if (lastTransform != null) {
|
||||
create(lastTransform);
|
||||
}
|
||||
}
|
||||
|
||||
private MultiLineLabel getLabel(GridTransform transform) {
|
||||
return lastLabel;
|
||||
}
|
||||
|
||||
protected void create(GridTransform transform) {
|
||||
this.lastTransform = transform;
|
||||
this.lastLabel = MultiLineLabel.create(font, text, transform.width);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GridElement buildElementAt(int left, int top, int width, List<GridElement> collector) {
|
||||
create(new GridTransform(left, top, width, 0));
|
||||
int promptLines = this.lastLabel.getLineCount() + 1;
|
||||
int height = promptLines * 9;
|
||||
|
||||
return new GridElement(left, top, width, height, this::getLabel, customRender);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,407 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.Button.OnPress;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridRow extends GridContainer {
|
||||
public final GridLayout.VerticalAlignment alignment;
|
||||
|
||||
GridRow(double width) {
|
||||
this(width, GridLayout.VerticalAlignment.TOP);
|
||||
}
|
||||
|
||||
GridRow(double width, GridLayout.GridValueType widthType) {
|
||||
this(width, widthType, GridLayout.VerticalAlignment.CENTER);
|
||||
}
|
||||
|
||||
GridRow(double width, GridLayout.VerticalAlignment alignment) {
|
||||
super(width);
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
GridRow(double width, GridLayout.GridValueType widthType, GridLayout.VerticalAlignment alignment) {
|
||||
super(width, widthType);
|
||||
this.alignment = alignment;
|
||||
}
|
||||
|
||||
public GridColumn addColumn(double width, GridLayout.GridValueType widthType) {
|
||||
GridColumn cell = new GridColumn(width, widthType);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridCell addComponent(double height, Function<GridTransform, Object> componentPlacer) {
|
||||
return addComponent(1.0, GridLayout.GridValueType.PERCENTAGE, height, componentPlacer);
|
||||
}
|
||||
|
||||
public GridCell addComponent(double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height,
|
||||
Function<GridTransform, Object> componentPlacer) {
|
||||
GridCell cell = new GridCell(width, height, widthType, componentPlacer, null);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
public GridCell addButton(Component text, double height, OnPress onPress) {
|
||||
return addButton(text, 1.0, GridLayout.GridValueType.PERCENTAGE, height, onPress);
|
||||
}
|
||||
|
||||
public GridCell addButton(Component text, float alpha, double height, OnPress onPress) {
|
||||
return addButton(text, alpha, 1.0, GridLayout.GridValueType.PERCENTAGE, height, onPress);
|
||||
}
|
||||
|
||||
public GridCell addButton(Component text, double height, Font font, OnPress onPress) {
|
||||
return addButton(text, 1.0f, height, font, onPress);
|
||||
}
|
||||
|
||||
public GridCell addButton(Component text, float alpha, double height, Font font, OnPress onPress) {
|
||||
final int width = font.width(text.getVisualOrderText()) + 24;
|
||||
return addButton(text, alpha, width, GridLayout.GridValueType.CONSTANT, height, onPress);
|
||||
}
|
||||
|
||||
public GridCell addButton(Component text,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height,
|
||||
OnPress onPress) {
|
||||
return addButton(text, 1.0f, width, widthType, height, onPress);
|
||||
}
|
||||
|
||||
public GridCell addButton(Component text,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
double height,
|
||||
OnPress onPress) {
|
||||
GridCell cell = new GridCell(width, height, widthType, (transform) -> {
|
||||
Button customButton = new Button(transform.left,
|
||||
transform.top,
|
||||
transform.width,
|
||||
transform.height,
|
||||
text,
|
||||
onPress);
|
||||
customButton.setAlpha(alpha);
|
||||
return customButton;
|
||||
}, null);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, Font font, Consumer<Boolean> onChange) {
|
||||
final int width = font.width(text.getVisualOrderText()) + 24 + 2 * 12;
|
||||
return addCheckbox(text, checked, width, widthType, onChange);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, double width,
|
||||
GridLayout.GridValueType widthType, Consumer<Boolean> onChange) {
|
||||
|
||||
GridCheckboxCell cell = new GridCheckboxCell(text, checked, 1.0f, width, widthType, 20, onChange);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, int height) {
|
||||
return addCheckbox(text, checked, 1.0f, height);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, float alpha, int height) {
|
||||
return addCheckbox(text, checked, alpha, 1.0, GridLayout.GridValueType.PERCENTAGE, height);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, int height, Font font) {
|
||||
return addCheckbox(text, checked, 1.0f, height, font);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text, boolean checked, float alpha, int height, Font font) {
|
||||
final int width = font.width(text.getVisualOrderText()) + 24 + 2 * 12;
|
||||
return addCheckbox(text, checked, alpha, width, GridLayout.GridValueType.CONSTANT, height);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text,
|
||||
boolean checked,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height) {
|
||||
return addCheckbox(text, checked, 1.0f, width, widthType, height);
|
||||
}
|
||||
|
||||
public GridCheckboxCell addCheckbox(Component text,
|
||||
boolean checked,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height) {
|
||||
GridCheckboxCell cell = new GridCheckboxCell(text, checked, alpha, width, widthType, height);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridCustomRenderCell addCustomRender(GridCustomRenderCell cell) {
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location, int width, int height) {
|
||||
return addImage(location, 1.0f, width, height);
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location, float alpha, int width, int height) {
|
||||
return addImage(location,
|
||||
alpha,
|
||||
width,
|
||||
GridLayout.GridValueType.CONSTANT,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
int resourceWidth,
|
||||
int resourceHeight) {
|
||||
return addImage(location, 1.0f, width, widthType, height, resourceWidth, resourceHeight);
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
int resourceWidth,
|
||||
int resourceHeight) {
|
||||
return addImage(location,
|
||||
alpha,
|
||||
width,
|
||||
widthType,
|
||||
height,
|
||||
0,
|
||||
0,
|
||||
resourceWidth,
|
||||
resourceWidth,
|
||||
resourceWidth,
|
||||
resourceHeight);
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
int uvLeft,
|
||||
int uvTop,
|
||||
int uvWidth,
|
||||
int uvHeight,
|
||||
int resourceWidth,
|
||||
int resourceHeight) {
|
||||
return addImage(location,
|
||||
1.0f,
|
||||
width,
|
||||
widthType,
|
||||
height,
|
||||
uvLeft,
|
||||
uvTop,
|
||||
uvWidth,
|
||||
uvHeight,
|
||||
resourceWidth,
|
||||
resourceHeight);
|
||||
}
|
||||
|
||||
public GridCell addImage(ResourceLocation location,
|
||||
float alpha,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
int uvLeft,
|
||||
int uvTop,
|
||||
int uvWidth,
|
||||
int uvHeight,
|
||||
int resourceWidth,
|
||||
int resourceHeight) {
|
||||
GridCell cell = new GridImageCell(location,
|
||||
width,
|
||||
widthType,
|
||||
height,
|
||||
alpha,
|
||||
uvLeft,
|
||||
uvTop,
|
||||
uvWidth,
|
||||
uvHeight,
|
||||
resourceWidth,
|
||||
resourceHeight);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
public GridColumn addFiller() {
|
||||
return addFiller(1);
|
||||
}
|
||||
|
||||
public GridColumn addFiller(float portion) {
|
||||
GridColumn cell = new GridColumn(portion, GridLayout.GridValueType.FILL);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public void addSpacer() {
|
||||
addSpacer(12);
|
||||
}
|
||||
|
||||
public void addSpacer(int width) {
|
||||
GridCell cell = new GridCell(width, 0, GridLayout.GridValueType.CONSTANT, null, null);
|
||||
this.cells.add(cell);
|
||||
}
|
||||
|
||||
|
||||
public GridMessageCell addMessage(Component text, Font font, GridLayout.Alignment contentAlignment) {
|
||||
return addMessage(text, font, GridLayout.COLOR_WHITE, contentAlignment);
|
||||
}
|
||||
|
||||
public GridMessageCell addMessage(Component text, Font font, int color, GridLayout.Alignment contentAlignment) {
|
||||
return addMessage(text, 1.0, GridLayout.GridValueType.PERCENTAGE, font, color, contentAlignment);
|
||||
}
|
||||
|
||||
public GridMessageCell addMessage(Component text,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
Font font,
|
||||
GridLayout.Alignment contentAlignment) {
|
||||
return addMessage(text, width, widthType, font, GridLayout.COLOR_WHITE, contentAlignment);
|
||||
}
|
||||
|
||||
public GridMessageCell addMessage(Component text,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
Font font,
|
||||
int color,
|
||||
GridLayout.Alignment contentAlignment) {
|
||||
GridMessageCell cell = new GridMessageCell(width, widthType, contentAlignment, font, text, color);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
public GridStringCell addString(Component text, GridScreen parent) {
|
||||
return this.addString(text, GridLayout.COLOR_WHITE, parent);
|
||||
}
|
||||
|
||||
|
||||
public GridStringCell addString(Component text, int color, GridScreen parent) {
|
||||
final int width = parent.getWidth(text);
|
||||
return this.addString(text,
|
||||
width,
|
||||
GridLayout.GridValueType.CONSTANT,
|
||||
color,
|
||||
GridLayout.Alignment.CENTER,
|
||||
parent);
|
||||
}
|
||||
|
||||
public GridStringCell addString(Component text, GridLayout.Alignment contentAlignment, GridScreen parent) {
|
||||
return this.addString(text, GridLayout.COLOR_WHITE, contentAlignment, parent);
|
||||
}
|
||||
|
||||
public GridStringCell addString(Component text,
|
||||
int color,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
GridScreen parent) {
|
||||
return this.addString(text, 1.0, GridLayout.GridValueType.PERCENTAGE, color, contentAlignment, parent);
|
||||
}
|
||||
|
||||
public GridStringCell addString(Component text,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
GridScreen parent) {
|
||||
return addString(text, width, widthType, GridLayout.COLOR_WHITE, contentAlignment, parent);
|
||||
}
|
||||
|
||||
public GridStringCell addString(Component text,
|
||||
double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int color,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
GridScreen parent) {
|
||||
GridStringCell cell = new GridStringCell(width,
|
||||
widthType,
|
||||
parent.getFont().lineHeight,
|
||||
contentAlignment,
|
||||
parent,
|
||||
text,
|
||||
color);
|
||||
this.cells.add(cell);
|
||||
return cell;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GridElement buildElementAt(int inLeft, int top, int width, final List<GridElement> collector) {
|
||||
int height = 0;
|
||||
int left = inLeft;
|
||||
if (widthType == GridLayout.GridValueType.INHERIT) {
|
||||
final int originalWidth = width;
|
||||
width = cells.stream()
|
||||
.filter(row -> row.widthType == GridLayout.GridValueType.CONSTANT || row.widthType == GridLayout.GridValueType.INHERIT)
|
||||
.map(row -> row.buildElement(0, 0, 1, 0, 0, null).width)
|
||||
.reduce(0, (p, c) -> p + c);
|
||||
}
|
||||
|
||||
final int inheritedWidth = width;
|
||||
final int fixedWidth = cells.stream()
|
||||
.filter(col -> col.widthType != GridLayout.GridValueType.FILL)
|
||||
.map(col -> col.calculateWidth(inheritedWidth))
|
||||
.reduce(0, (p, c) -> p + c);
|
||||
final float autoWidthSum = cells.stream()
|
||||
.filter(col -> col.widthType == GridLayout.GridValueType.FILL)
|
||||
.map(col -> col.width)
|
||||
.reduce(0.0f, (p, c) -> p + c);
|
||||
final int autoWidth = width - fixedWidth;
|
||||
|
||||
if (alignment == GridLayout.VerticalAlignment.TOP) {
|
||||
for (GridCellDefinition col : cells) {
|
||||
GridElement element = col.buildElement(width, autoWidth, autoWidthSum, left, top, collector);
|
||||
left += element.width;
|
||||
height = Math.max(height, element.height);
|
||||
}
|
||||
} else {
|
||||
//first iteration will collect heights, second one will transform top position for alignment
|
||||
Map<GridCellDefinition, GridElement> cache = new HashMap<>();
|
||||
for (GridCellDefinition col : cells) {
|
||||
GridElement element = col.buildElement(width, autoWidth, autoWidthSum, left, top, null);
|
||||
left += element.width;
|
||||
height = Math.max(height, element.height);
|
||||
cache.put(col, element);
|
||||
}
|
||||
|
||||
left = inLeft;
|
||||
for (GridCellDefinition col : cells) {
|
||||
GridElement element = cache.get(col);
|
||||
final int topOffset = (alignment == GridLayout.VerticalAlignment.BOTTOM)
|
||||
? (height - element.height)
|
||||
: (height - element.height) >> 1;
|
||||
element = col.buildElement(width, autoWidth, autoWidthSum, left, top + topOffset, collector);
|
||||
left += element.width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new GridElement(inLeft, top, width, height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.client.gui.components.Widget;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.client.gui.narration.NarratableEntry;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.*;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public abstract class GridScreen extends Screen {
|
||||
protected GridLayout grid = null;
|
||||
public final int topPadding;
|
||||
public final int sidePadding;
|
||||
public final boolean centerVertically;
|
||||
@Nullable
|
||||
public final Screen parent;
|
||||
|
||||
protected int scrollPos = 0;
|
||||
|
||||
public GridScreen(Component title) {
|
||||
this(null, title);
|
||||
}
|
||||
|
||||
public GridScreen(@Nullable Screen parent, Component title) {
|
||||
this(parent, title, 0, true);
|
||||
}
|
||||
|
||||
public GridScreen(Component title, int topPadding, boolean centerVertically) {
|
||||
this(null, title, topPadding, 20, centerVertically);
|
||||
}
|
||||
|
||||
public GridScreen(@Nullable Screen parent, Component title, int topPadding, boolean centerVertically) {
|
||||
this(parent, title, topPadding, 20, centerVertically);
|
||||
}
|
||||
|
||||
public GridScreen(Component title, int topPadding, int sidePadding, boolean centerVertically) {
|
||||
this(null, title, topPadding, sidePadding, centerVertically);
|
||||
}
|
||||
|
||||
public GridScreen(@Nullable Screen parent,
|
||||
Component title,
|
||||
int topPadding,
|
||||
int sidePadding,
|
||||
boolean centerVertically) {
|
||||
super(title);
|
||||
|
||||
this.parent = parent;
|
||||
this.topPadding = topPadding;
|
||||
this.sidePadding = sidePadding;
|
||||
this.centerVertically = centerVertically;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
this.minecraft.setScreen(parent);
|
||||
}
|
||||
|
||||
public Font getFont() {
|
||||
return this.font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends GuiEventListener & Widget & NarratableEntry> T addRenderableWidget(T guiEventListener) {
|
||||
return super.addRenderableWidget(guiEventListener);
|
||||
}
|
||||
|
||||
protected void addTitle() {
|
||||
grid.addRow().addString(this.title, GridLayout.Alignment.CENTER, this);
|
||||
grid.addSpacerRow(15);
|
||||
}
|
||||
|
||||
final protected void init() {
|
||||
super.init();
|
||||
this.grid = new GridLayout(this, this.topPadding, this.sidePadding, this.centerVertically);
|
||||
|
||||
addTitle();
|
||||
|
||||
initLayout();
|
||||
grid.finalizeLayout();
|
||||
}
|
||||
|
||||
protected abstract void initLayout();
|
||||
|
||||
protected void renderScreen(PoseStack poseStack, int i, int j, float f) {
|
||||
super.render(poseStack, i, j, f);
|
||||
}
|
||||
|
||||
public void render(PoseStack poseStack, int i, int j, float f) {
|
||||
this.renderDirtBackground(i);
|
||||
renderGrid(poseStack);
|
||||
super.render(poseStack, i, j, f);
|
||||
}
|
||||
|
||||
protected void renderGrid(PoseStack poseStack) {
|
||||
if (grid != null) {
|
||||
if (isScrollable()) {
|
||||
for (var item : grid.movableWidgets) {
|
||||
item.first.y = item.second + scrollPos;
|
||||
}
|
||||
|
||||
renderScroll(poseStack);
|
||||
|
||||
poseStack.pushPose();
|
||||
poseStack.translate(0, scrollPos, 0);
|
||||
grid.render(poseStack);
|
||||
poseStack.popPose();
|
||||
} else {
|
||||
grid.render(poseStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getWidth(Component text, Font font) {
|
||||
return font.width(text.getVisualOrderText());
|
||||
}
|
||||
|
||||
public int getWidth(Component text) {
|
||||
return getWidth(text, getFont());
|
||||
}
|
||||
|
||||
public void setScrollPos(int sp) {
|
||||
scrollPos = Math.max(getMaxScrollPos(), Math.min(0, sp));
|
||||
}
|
||||
|
||||
public int getScrollPos() {
|
||||
return scrollPos;
|
||||
}
|
||||
|
||||
public int getScrollHeight() {
|
||||
if (grid != null) return grid.getHeight() + topPadding;
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getMaxScrollPos() {
|
||||
return height - (getScrollHeight() + topPadding);
|
||||
}
|
||||
|
||||
public boolean isScrollable() {
|
||||
return height < getScrollHeight();
|
||||
}
|
||||
|
||||
public boolean isMouseOverScroller(double x, double y) {
|
||||
return y >= 0 && y <= height && x >= width - SCROLLER_WIDTH && x <= width;
|
||||
}
|
||||
|
||||
private boolean scrolling = false;
|
||||
|
||||
protected void updateScrollingState(double x, double y, int i) {
|
||||
this.scrolling = i == 0 && x >= width - SCROLLER_WIDTH && x < width;
|
||||
}
|
||||
|
||||
private static final int SCROLLER_WIDTH = 6;
|
||||
|
||||
private void renderScroll(PoseStack poseStack) {
|
||||
final int y1 = height;
|
||||
final int y0 = 0;
|
||||
final int yd = y1 - y0;
|
||||
final int maxPosition = getScrollHeight() + topPadding;
|
||||
|
||||
final int x0 = width - SCROLLER_WIDTH;
|
||||
final int x1 = width;
|
||||
|
||||
Tesselator tesselator = Tesselator.getInstance();
|
||||
BufferBuilder bufferBuilder = tesselator.getBuilder();
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader);
|
||||
int widgetHeight = (int) ((float) (yd * yd) / (float) maxPosition);
|
||||
widgetHeight = Mth.clamp(widgetHeight, 32, yd - 8);
|
||||
float relPos = (float) this.getScrollPos() / this.getMaxScrollPos();
|
||||
int top = (int) (relPos * (yd - widgetHeight)) + y0;
|
||||
if (top < y0) {
|
||||
top = y0;
|
||||
}
|
||||
|
||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR);
|
||||
|
||||
//scroller background
|
||||
bufferBuilder.vertex(x0, y1, 0.0D).color(0, 0, 0, 255).endVertex();
|
||||
bufferBuilder.vertex(x1, y1, 0.0D).color(0, 0, 0, 255).endVertex();
|
||||
bufferBuilder.vertex(x1, y0, 0.0D).color(0, 0, 0, 255).endVertex();
|
||||
bufferBuilder.vertex(x0, y0, 0.0D).color(0, 0, 0, 255).endVertex();
|
||||
|
||||
//scroll widget shadow
|
||||
bufferBuilder.vertex(x0, top + widgetHeight, 0.0D).color(128, 128, 128, 255).endVertex();
|
||||
bufferBuilder.vertex(x1, top + widgetHeight, 0.0D).color(128, 128, 128, 255).endVertex();
|
||||
bufferBuilder.vertex(x1, top, 0.0D).color(128, 128, 128, 255).endVertex();
|
||||
bufferBuilder.vertex(x0, top, 0.0D).color(128, 128, 128, 255).endVertex();
|
||||
|
||||
//scroll widget
|
||||
bufferBuilder.vertex(x0, top + widgetHeight - 1, 0.0D)
|
||||
.color(192, 192, 192, 255)
|
||||
.endVertex();
|
||||
bufferBuilder.vertex(x1 - 1, top + widgetHeight - 1, 0.0D)
|
||||
.color(192, 192, 192, 255)
|
||||
.endVertex();
|
||||
bufferBuilder.vertex(x1 - 1, top, 0.0D).color(192, 192, 192, 255).endVertex();
|
||||
bufferBuilder.vertex(x0, top, 0.0D).color(192, 192, 192, 255).endVertex();
|
||||
tesselator.end();
|
||||
}
|
||||
|
||||
public boolean mouseClicked(double x, double y, int i) {
|
||||
this.updateScrollingState(x, y, i);
|
||||
if (this.scrolling) {
|
||||
return true;
|
||||
} else {
|
||||
return super.mouseClicked(x, y, i);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseDragged(double xAbs, double yAbs, int i, double dX, double dY) {
|
||||
if (super.mouseDragged(xAbs, yAbs, i, dX, dY)) {
|
||||
return true;
|
||||
} else if (i == 0 && this.scrolling) {
|
||||
if (yAbs < 0) {
|
||||
this.setScrollPos(0);
|
||||
} else if (yAbs > height) {
|
||||
this.setScrollPos(this.getMaxScrollPos());
|
||||
} else {
|
||||
this.setScrollPos((int) (this.getScrollPos() - dY * 2));
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(double d, double e, double f) {
|
||||
if (isScrollable()) {
|
||||
setScrollPos((int) (scrollPos + f * 10));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean keyPressed(int keyCode, int j, int k) {
|
||||
if (super.keyPressed(keyCode, j, k)) {
|
||||
return true;
|
||||
} else if (keyCode == 264) {
|
||||
this.mouseScrolled(0, -1.0f, 0);
|
||||
return true;
|
||||
} else if (keyCode == 265) {
|
||||
this.mouseScrolled(0, 1.0, 0);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridStringCell extends GridCell {
|
||||
private Component text;
|
||||
|
||||
GridStringCell(double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
GridScreen parent,
|
||||
Component text) {
|
||||
this(width, widthType, height, contentAlignment, parent, text, GridLayout.COLOR_WHITE);
|
||||
|
||||
}
|
||||
|
||||
GridStringCell(double width,
|
||||
GridLayout.GridValueType widthType,
|
||||
int height,
|
||||
GridLayout.Alignment contentAlignment,
|
||||
GridScreen parent,
|
||||
Component text,
|
||||
int color) {
|
||||
super(width, height, widthType, null, null);
|
||||
this.text = text;
|
||||
this.customRender = (poseStack, transform, context) -> {
|
||||
if (contentAlignment == GridLayout.Alignment.CENTER) {
|
||||
GuiComponent.drawCenteredString(poseStack,
|
||||
parent.getFont(),
|
||||
this.text,
|
||||
transform.width / 2 + transform.left,
|
||||
transform.top,
|
||||
color);
|
||||
} else if (contentAlignment == GridLayout.Alignment.LEFT) {
|
||||
GuiComponent.drawString(poseStack, parent.getFont(), this.text, transform.left, transform.top, color);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setText(Component newText) {
|
||||
this.text = newText;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class GridTransform {
|
||||
public final int left;
|
||||
public final int top;
|
||||
public final int width;
|
||||
public final int height;
|
||||
|
||||
GridTransform(int left, int top, int width, int height) {
|
||||
this.left = left;
|
||||
this.top = top;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + "left=" + left + ", top=" + top + ", width=" + width + ", height=" + height + '}';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.betterx.bclib.client.gui.gridlayout;
|
||||
|
||||
public interface GridWidgetWithEnabledState {
|
||||
boolean isEnabled();
|
||||
void setEnabled(boolean enabled);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package org.betterx.bclib.client.gui.modmenu;
|
||||
|
||||
import org.betterx.bclib.integration.modmenu.ModMenuIntegration;
|
||||
|
||||
@Deprecated()
|
||||
public class EntryPoint extends ModMenuIntegration {
|
||||
public static final Object entrypointObject = createEntrypoint(new EntryPoint());
|
||||
|
||||
public EntryPoint() {
|
||||
super(MainScreen::new);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package org.betterx.bclib.client.gui.modmenu;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import org.betterx.bclib.client.gui.gridlayout.*;
|
||||
import org.betterx.bclib.config.ConfigKeeper;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.config.NamedPathConfig;
|
||||
import org.betterx.bclib.config.NamedPathConfig.ConfigTokenDescription;
|
||||
import org.betterx.bclib.config.NamedPathConfig.DependendConfigToken;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MainScreen extends GridScreen {
|
||||
|
||||
public MainScreen(@Nullable Screen parent) {
|
||||
super(parent, Component.translatable("title.bclib.modmenu.main"), 10, false);
|
||||
}
|
||||
|
||||
protected <T> Component getComponent(NamedPathConfig config, ConfigTokenDescription<T> option, String type) {
|
||||
return Component.translatable(type + ".config." + config.configID + option.getPath());
|
||||
}
|
||||
|
||||
Map<GridWidgetWithEnabledState, Supplier<Boolean>> dependentWidgets = new HashMap<>();
|
||||
|
||||
protected void updateEnabledState() {
|
||||
dependentWidgets.forEach((cb, supl) -> cb.setEnabled(supl.get()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T> void addRow(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<T> option) {
|
||||
if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(option.token.type)) {
|
||||
addCheckbox(grid, config, (ConfigTokenDescription<Boolean>) option);
|
||||
}
|
||||
|
||||
grid.addSpacerRow(2);
|
||||
}
|
||||
|
||||
|
||||
protected void addCheckbox(GridColumn grid, NamedPathConfig config, ConfigTokenDescription<Boolean> option) {
|
||||
if (option.topPadding > 0) {
|
||||
grid.addSpacerRow(option.topPadding);
|
||||
}
|
||||
GridRow row = grid.addRow();
|
||||
if (option.leftPadding > 0) {
|
||||
row.addSpacer(option.leftPadding);
|
||||
}
|
||||
GridCheckboxCell cb = row.addCheckbox(getComponent(config, option, "title"),
|
||||
config.getRaw(option.token),
|
||||
font,
|
||||
(state) -> {
|
||||
config.set(option.token, state);
|
||||
updateEnabledState();
|
||||
});
|
||||
|
||||
if (option.token instanceof DependendConfigToken) {
|
||||
dependentWidgets.put(cb, () -> option.token.dependenciesTrue(config));
|
||||
cb.setEnabled(option.token.dependenciesTrue(config));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
Configs.GENERATOR_CONFIG.getAllOptions()
|
||||
.stream()
|
||||
.filter(o -> !o.hidden)
|
||||
.forEach(o -> addRow(grid, Configs.GENERATOR_CONFIG, o));
|
||||
grid.addSpacerRow(12);
|
||||
Configs.MAIN_CONFIG.getAllOptions()
|
||||
.stream()
|
||||
.filter(o -> !o.hidden)
|
||||
.forEach(o -> addRow(grid, Configs.MAIN_CONFIG, o));
|
||||
grid.addSpacerRow(12);
|
||||
Configs.CLIENT_CONFIG.getAllOptions()
|
||||
.stream()
|
||||
.filter(o -> !o.hidden)
|
||||
.forEach(o -> addRow(grid, Configs.CLIENT_CONFIG, o));
|
||||
|
||||
grid.addSpacerRow(15);
|
||||
GridRow row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_DONE, BUTTON_HEIGHT, font, (button) -> {
|
||||
Configs.CLIENT_CONFIG.saveChanges();
|
||||
Configs.GENERATOR_CONFIG.saveChanges();
|
||||
Configs.MAIN_CONFIG.saveChanges();
|
||||
onClose();
|
||||
});
|
||||
grid.addSpacerRow(10);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public interface AtomicProgressListener {
|
||||
void incAtomic(int maxProgress);
|
||||
void resetAtomic();
|
||||
void stop();
|
||||
void progressStage(Component component);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridScreen;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
abstract class BCLibScreen extends GridScreen {
|
||||
static final ResourceLocation BCLIB_LOGO_LOCATION = new ResourceLocation(BCLib.MOD_ID, "icon.png");
|
||||
|
||||
public BCLibScreen(Component title) {
|
||||
super(title);
|
||||
}
|
||||
|
||||
public BCLibScreen(@Nullable Screen parent, Component title) {
|
||||
super(parent, title);
|
||||
}
|
||||
|
||||
public BCLibScreen(Component title, int topPadding, boolean centerVertically) {
|
||||
super(title, topPadding, 20, centerVertically);
|
||||
}
|
||||
|
||||
public BCLibScreen(@Nullable Screen parent, Component title, int topPadding, boolean centerVertically) {
|
||||
super(parent, title, topPadding, centerVertically);
|
||||
}
|
||||
|
||||
public BCLibScreen(Component title, int topPadding, int sidePadding, boolean centerVertically) {
|
||||
super(title, topPadding, sidePadding, centerVertically);
|
||||
}
|
||||
|
||||
public BCLibScreen(@Nullable Screen parent,
|
||||
Component title,
|
||||
int topPadding,
|
||||
int sidePadding,
|
||||
boolean centerVertically) {
|
||||
super(parent, title, topPadding, sidePadding, centerVertically);
|
||||
}
|
||||
|
||||
|
||||
protected void addTitle() {
|
||||
GridRow row = grid.addRow(GridLayout.VerticalAlignment.CENTER);
|
||||
row.addFiller();
|
||||
row.addImage(BCLIB_LOGO_LOCATION, 24, GridLayout.GridValueType.CONSTANT, 24, 512, 512);
|
||||
row.addSpacer(4);
|
||||
row.addString(this.title, this);
|
||||
row.addFiller();
|
||||
grid.addSpacerRow(15);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ConfirmFixScreen extends BCLibScreen {
|
||||
protected final ConfirmFixScreen.Listener listener;
|
||||
private final Component description;
|
||||
protected int id;
|
||||
|
||||
public ConfirmFixScreen(@Nullable Screen parent, ConfirmFixScreen.Listener listener) {
|
||||
super(parent, Component.translatable("bclib.datafixer.backupWarning.title"));
|
||||
this.listener = listener;
|
||||
|
||||
this.description = Component.translatable("bclib.datafixer.backupWarning.message");
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
|
||||
grid.addSpacerRow();
|
||||
|
||||
GridRow row = grid.addRow();
|
||||
GridCheckboxCell backup = row.addCheckbox(Component.translatable("bclib.datafixer.backupWarning.backup"),
|
||||
true,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
|
||||
grid.addSpacerRow(10);
|
||||
|
||||
row = grid.addRow();
|
||||
GridCheckboxCell fix = row.addCheckbox(Component.translatable("bclib.datafixer.backupWarning.fix"),
|
||||
true,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
|
||||
grid.addSpacerRow(20);
|
||||
|
||||
row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_CANCEL, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
onClose();
|
||||
});
|
||||
row.addSpacer();
|
||||
row.addButton(CommonComponents.GUI_PROCEED, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
this.listener.proceed(backup.isChecked(), fix.isChecked());
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed(boolean createBackup, boolean applyPatches);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ConfirmRestartScreen extends BCLibScreen {
|
||||
private final Component description;
|
||||
private final ConfirmRestartScreen.Listener listener;
|
||||
|
||||
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener) {
|
||||
this(listener, null);
|
||||
}
|
||||
|
||||
public ConfirmRestartScreen(ConfirmRestartScreen.Listener listener, Component message) {
|
||||
super(Component.translatable("title.bclib.confirmrestart"));
|
||||
|
||||
this.description = message == null ? Component.translatable("message.bclib.confirmrestart") : message;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
|
||||
|
||||
grid.addSpacerRow();
|
||||
|
||||
GridRow row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_PROCEED, BUTTON_HEIGHT, font, (button) -> {
|
||||
listener.proceed();
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridColumn;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class LevelFixErrorScreen extends BCLibScreen {
|
||||
private final String[] errors;
|
||||
final Listener onContinue;
|
||||
|
||||
public LevelFixErrorScreen(Screen parent, String[] errors, Listener onContinue) {
|
||||
super(parent, Component.translatable("title.bclib.datafixer.error"), 10, true);
|
||||
this.errors = errors;
|
||||
this.onContinue = onContinue;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
grid.addSpacerRow();
|
||||
grid.addRow()
|
||||
.addMessage(Component.translatable("message.bclib.datafixer.error"), font, GridLayout.Alignment.CENTER);
|
||||
grid.addSpacerRow(8);
|
||||
|
||||
GridRow row = grid.addRow();
|
||||
row.addSpacer(10);
|
||||
GridColumn col = row.addColumn(300, GridLayout.GridValueType.CONSTANT);
|
||||
for (String error : errors) {
|
||||
Component dash = Component.literal("-");
|
||||
row = col.addRow();
|
||||
row.addString(dash, this);
|
||||
|
||||
row.addSpacer(4);
|
||||
row.addString(Component.literal(error), this);
|
||||
}
|
||||
|
||||
grid.addSpacerRow(8);
|
||||
row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(Component.translatable("title.bclib.datafixer.error.continue"), 0.5f, 20, font, (n) -> {
|
||||
onClose();
|
||||
onContinue.doContinue(true);
|
||||
});
|
||||
row.addSpacer();
|
||||
row.addButton(CommonComponents.GUI_CANCEL, 20, font, (n) -> {
|
||||
this.minecraft.setScreen(null);
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void doContinue(boolean markFixed);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,256 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.loader.api.metadata.ModEnvironment;
|
||||
|
||||
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridColumn;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridScreen;
|
||||
import org.betterx.bclib.util.ModUtil;
|
||||
import org.betterx.bclib.util.PathUtil;
|
||||
import org.betterx.bclib.util.Triple;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ModListScreen extends BCLibScreen {
|
||||
|
||||
private final List<ModUtil.ModInfo> mods;
|
||||
private final HelloClient.IServerModMap serverInfo;
|
||||
private final Component description;
|
||||
private final Component buttonTitle;
|
||||
|
||||
private static List<ModUtil.ModInfo> extractModList(Map<String, ModUtil.ModInfo> mods) {
|
||||
List<ModUtil.ModInfo> list = new LinkedList<ModUtil.ModInfo>();
|
||||
ModUtil.getMods().forEach((id, info) -> list.add(info));
|
||||
return list;
|
||||
}
|
||||
|
||||
public ModListScreen(Screen parent,
|
||||
Component title,
|
||||
Component description,
|
||||
Map<String, ModUtil.ModInfo> mods,
|
||||
HelloClient.IServerModMap serverInfo) {
|
||||
this(parent, title, description, CommonComponents.GUI_BACK, mods, serverInfo);
|
||||
}
|
||||
|
||||
public ModListScreen(Screen parent,
|
||||
Component title,
|
||||
Component description,
|
||||
List<ModUtil.ModInfo> mods,
|
||||
HelloClient.IServerModMap serverInfo) {
|
||||
this(parent, title, description, CommonComponents.GUI_BACK, mods, serverInfo);
|
||||
}
|
||||
|
||||
public ModListScreen(Screen parent,
|
||||
Component title,
|
||||
Component description,
|
||||
Component button,
|
||||
Map<String, ModUtil.ModInfo> mods,
|
||||
HelloClient.IServerModMap serverInfo) {
|
||||
this(parent, title, description, button, extractModList(mods), serverInfo);
|
||||
}
|
||||
|
||||
public ModListScreen(Screen parent,
|
||||
Component title,
|
||||
Component description,
|
||||
Component button,
|
||||
List<ModUtil.ModInfo> mods,
|
||||
HelloClient.IServerModMap serverInfo) {
|
||||
super(parent, title, 10, true);
|
||||
this.mods = mods;
|
||||
this.serverInfo = serverInfo;
|
||||
this.description = description;
|
||||
this.buttonTitle = button;
|
||||
}
|
||||
|
||||
public static List<String> localMissing(HelloClient.IServerModMap serverInfo) {
|
||||
return serverInfo.keySet()
|
||||
.stream()
|
||||
.filter(modid -> !ModUtil.getMods()
|
||||
.keySet()
|
||||
.stream()
|
||||
.filter(mod -> mod.equals(modid))
|
||||
.findFirst()
|
||||
.isPresent()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static List<String> serverMissing(HelloClient.IServerModMap serverInfo) {
|
||||
return ModUtil.getMods().entrySet()
|
||||
.stream()
|
||||
.filter(entry -> entry.getValue().metadata.getEnvironment() != ModEnvironment.CLIENT)
|
||||
.map(entry -> entry.getKey())
|
||||
.filter(modid -> !serverInfo.keySet()
|
||||
.stream()
|
||||
.filter(mod -> mod.equals(modid))
|
||||
.findFirst()
|
||||
.isPresent()).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public static void addModDesc(GridColumn grid,
|
||||
java.util.List<ModUtil.ModInfo> mods,
|
||||
HelloClient.IServerModMap serverInfo,
|
||||
GridScreen parent) {
|
||||
final int STATE_OK = 6;
|
||||
final int STATE_SERVER_MISSING_CLIENT_MOD = 5;
|
||||
final int STATE_MISSING_NOT_OFFERED = 4;
|
||||
final int STATE_VERSION_CLIENT_ONLY = 7;
|
||||
final int STATE_VERSION_NOT_OFFERED = 3;
|
||||
final int STATE_VERSION = 2;
|
||||
final int STATE_SERVER_MISSING = 1;
|
||||
final int STATE_MISSING = 0;
|
||||
|
||||
|
||||
List<Triple<String, Integer, String>> items = new LinkedList<>();
|
||||
if (serverInfo != null) {
|
||||
serverInfo.keySet()
|
||||
.stream()
|
||||
.filter(modid -> !mods.stream()
|
||||
.filter(mod -> mod.metadata.getId().equals(modid))
|
||||
.findFirst()
|
||||
.isPresent())
|
||||
.forEach(modid -> {
|
||||
HelloClient.OfferedModInfo nfo = serverInfo.get(modid);
|
||||
String stateString = nfo.version();
|
||||
if (nfo.size() > 0) {
|
||||
stateString = "Version: " + stateString + ", Size: " + PathUtil.humanReadableFileSize(nfo.size());
|
||||
}
|
||||
if (nfo.canDownload()) {
|
||||
stateString += ", offered by server";
|
||||
}
|
||||
|
||||
items.add(new Triple<>(modid,
|
||||
nfo.canDownload() ? STATE_MISSING : STATE_MISSING_NOT_OFFERED,
|
||||
stateString));
|
||||
});
|
||||
}
|
||||
|
||||
mods.forEach(mod -> {
|
||||
String serverVersion = null;
|
||||
int serverSize = 0;
|
||||
int state = STATE_OK;
|
||||
if (serverInfo != null) {
|
||||
final String modID = mod.metadata.getId();
|
||||
|
||||
|
||||
HelloClient.OfferedModInfo data = serverInfo.get(modID);
|
||||
if (data != null) {
|
||||
final String modVer = data.version();
|
||||
final int size = data.size();
|
||||
if (!modVer.equals(mod.getVersion())) {
|
||||
if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT)
|
||||
state = STATE_VERSION_CLIENT_ONLY;
|
||||
else
|
||||
state = data.canDownload() ? STATE_VERSION : STATE_VERSION_NOT_OFFERED;
|
||||
serverVersion = modVer;
|
||||
serverSize = size;
|
||||
}
|
||||
} else if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT) {
|
||||
state = STATE_SERVER_MISSING_CLIENT_MOD;
|
||||
} else {
|
||||
state = STATE_SERVER_MISSING;
|
||||
}
|
||||
}
|
||||
|
||||
String stateString = mod.metadata.getVersion().toString();
|
||||
if (serverVersion != null) {
|
||||
stateString = "Client: " + stateString;
|
||||
stateString += ", Server: " + serverVersion;
|
||||
if (serverSize > 0) {
|
||||
stateString += ", Size: " + PathUtil.humanReadableFileSize(serverSize);
|
||||
}
|
||||
}
|
||||
if (mod.metadata.getEnvironment() == ModEnvironment.CLIENT) {
|
||||
stateString += ", client-only";
|
||||
} else if (mod.metadata.getEnvironment() == ModEnvironment.SERVER) {
|
||||
stateString += ", server-only";
|
||||
}
|
||||
items.add(new Triple<>(mod.metadata.getName(), state, stateString));
|
||||
});
|
||||
|
||||
items.stream()
|
||||
.sorted(Comparator.comparing(a -> a.second + a.first.toLowerCase(Locale.ROOT)))
|
||||
.forEach(t -> {
|
||||
final String name = t.first;
|
||||
final int state = t.second;
|
||||
final String stateString = t.third;
|
||||
|
||||
int color = GridLayout.COLOR_RED;
|
||||
final String typeText;
|
||||
if (state == STATE_VERSION || state == STATE_VERSION_NOT_OFFERED || state == STATE_VERSION_CLIENT_ONLY) {
|
||||
typeText = "[VERSION]";
|
||||
if (state == STATE_VERSION_NOT_OFFERED) {
|
||||
color = GridLayout.COLOR_YELLOW;
|
||||
} else if (state == STATE_VERSION_CLIENT_ONLY) {
|
||||
color = GridLayout.COLOR_DARK_GREEN;
|
||||
}
|
||||
} else if (state == STATE_MISSING || state == STATE_MISSING_NOT_OFFERED) {
|
||||
typeText = "[MISSING]";
|
||||
if (state == STATE_MISSING_NOT_OFFERED) {
|
||||
color = GridLayout.COLOR_YELLOW;
|
||||
}
|
||||
} else if (state == STATE_SERVER_MISSING || state == STATE_SERVER_MISSING_CLIENT_MOD) {
|
||||
if (state == STATE_SERVER_MISSING_CLIENT_MOD) {
|
||||
color = GridLayout.COLOR_CYAN;
|
||||
typeText = "[OK]";
|
||||
} else {
|
||||
typeText = "[NOT ON SERVER]";
|
||||
}
|
||||
} else {
|
||||
color = GridLayout.COLOR_DARK_GREEN;
|
||||
typeText = "[OK]";
|
||||
}
|
||||
Component dash = Component.literal("-");
|
||||
Component typeTextComponent = Component.literal(typeText);
|
||||
GridRow row = grid.addRow();
|
||||
|
||||
row.addString(dash, parent);
|
||||
|
||||
row.addSpacer(4);
|
||||
row.addString(Component.literal(name), parent);
|
||||
|
||||
row.addSpacer(4);
|
||||
row.addString(typeTextComponent, color, parent);
|
||||
|
||||
if (!stateString.isEmpty()) {
|
||||
row = grid.addRow();
|
||||
row.addSpacer(4 + parent.getWidth(dash));
|
||||
row.addString(Component.literal(stateString), GridLayout.COLOR_GRAY, parent);
|
||||
}
|
||||
|
||||
grid.addSpacerRow();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
if (description != null) {
|
||||
grid.addSpacerRow();
|
||||
grid.addRow().addMessage(description, font, GridLayout.Alignment.CENTER);
|
||||
grid.addSpacerRow(8);
|
||||
}
|
||||
|
||||
GridRow row = grid.addRow();
|
||||
row.addSpacer(10);
|
||||
GridColumn col = row.addColumn(200, GridLayout.GridValueType.CONSTANT);
|
||||
addModDesc(col, mods, serverInfo, this);
|
||||
|
||||
grid.addSpacerRow(8);
|
||||
row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(buttonTitle, 20, font, (n) -> {
|
||||
onClose();
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.GuiComponent;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.ProgressListener;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.client.gui.gridlayout.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class ProgressLogoRender extends GridCustomRenderCell {
|
||||
public static final int SIZE = 64;
|
||||
public static final int LOGO_SIZE = 512;
|
||||
public static final int PIXELATED_SIZE = 512;
|
||||
float percentage = 0;
|
||||
double time = 0;
|
||||
|
||||
protected ProgressLogoRender() {
|
||||
super(SIZE, GridLayout.GridValueType.CONSTANT, SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRender(PoseStack poseStack, GridTransform transform, Object context) {
|
||||
time += 0.03;
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0f);
|
||||
|
||||
final int yBarLocal = (int) (transform.height * percentage);
|
||||
final int yBar = transform.top + yBarLocal;
|
||||
|
||||
final float fScale = (float) (0.3 * ((Math.sin(time) + 1.0) * 0.5) + 0.7);
|
||||
int height = (int) (transform.height * fScale);
|
||||
int width = (int) (transform.width * fScale);
|
||||
width -= ((transform.width - width) % 2);
|
||||
height -= ((transform.height - height) % 2);
|
||||
|
||||
final int yOffset = (transform.height - height) / 2;
|
||||
final int xOffset = (transform.width - width) / 2;
|
||||
|
||||
|
||||
final int yBarImage = Math.max(0, Math.min(height, yBarLocal - yOffset));
|
||||
final float relativeY = ((float) yBarImage / height);
|
||||
|
||||
if (yBarImage > 0) {
|
||||
final int uvTopLogo = (int) (relativeY * LOGO_SIZE);
|
||||
RenderSystem.setShaderTexture(0, BCLibScreen.BCLIB_LOGO_LOCATION);
|
||||
GuiComponent.blit(poseStack,
|
||||
xOffset + transform.left,
|
||||
yOffset + transform.top,
|
||||
width,
|
||||
yBarImage,
|
||||
0, 0, LOGO_SIZE, uvTopLogo,
|
||||
LOGO_SIZE, LOGO_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
if (yBarImage < height) {
|
||||
final int uvTopPixelated = (int) (relativeY * PIXELATED_SIZE);
|
||||
RenderSystem.setShaderTexture(0, ProgressScreen.BCLIB_LOGO_PIXELATED_LOCATION);
|
||||
GuiComponent.blit(poseStack,
|
||||
xOffset + transform.left,
|
||||
yOffset + transform.top + yBarImage,
|
||||
width,
|
||||
height - yBarImage,
|
||||
0, uvTopPixelated, PIXELATED_SIZE, PIXELATED_SIZE - uvTopPixelated,
|
||||
PIXELATED_SIZE, PIXELATED_SIZE
|
||||
);
|
||||
}
|
||||
|
||||
if (percentage > 0 && percentage < 1.0) {
|
||||
GuiComponent.fill(poseStack,
|
||||
transform.left,
|
||||
yBar,
|
||||
transform.left + transform.width,
|
||||
yBar + 1,
|
||||
0x3FFFFFFF
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgressScreen extends GridScreen implements ProgressListener, AtomicProgressListener {
|
||||
|
||||
static final ResourceLocation BCLIB_LOGO_PIXELATED_LOCATION = new ResourceLocation(BCLib.MOD_ID,
|
||||
"iconpixelated.png");
|
||||
|
||||
public ProgressScreen(@Nullable Screen parent, Component title, Component description) {
|
||||
super(parent, title, 20, true);
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
Component description;
|
||||
private Component stageComponent;
|
||||
private GridMessageCell stage;
|
||||
private GridStringCell progress;
|
||||
private ProgressLogoRender progressImage;
|
||||
private int currentProgress = 0;
|
||||
private AtomicInteger atomicCounter;
|
||||
|
||||
@Override
|
||||
public void incAtomic(int maxProgress) {
|
||||
if (atomicCounter != null) {
|
||||
progressStagePercentage((100 * atomicCounter.incrementAndGet()) / maxProgress);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAtomic() {
|
||||
progressStagePercentage(0);
|
||||
atomicCounter = new AtomicInteger(0);
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Component getProgressComponent() {
|
||||
return getProgressComponent(currentProgress);
|
||||
}
|
||||
|
||||
private Component getProgressComponent(int pg) {
|
||||
return Component.translatable("title.bclib.progress").append(": " + pg + "%");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
grid.addSpacerRow();
|
||||
|
||||
GridRow row = grid.addRow(GridLayout.VerticalAlignment.CENTER);
|
||||
row.addFiller();
|
||||
progressImage = new ProgressLogoRender();
|
||||
progressImage.percentage = currentProgress / 100.0f;
|
||||
row.addCustomRender(progressImage);
|
||||
row.addSpacer();
|
||||
|
||||
int textWidth = Math.max(getWidth(description), getWidth(getProgressComponent(100)));
|
||||
GridColumn textCol = row.addColumn(0, GridLayout.GridValueType.INHERIT);
|
||||
textCol.addRow().addString(description, this);
|
||||
textCol.addSpacerRow();
|
||||
progress = textCol.addRow()
|
||||
.addString(getProgressComponent(), GridLayout.COLOR_GRAY, GridLayout.Alignment.LEFT, this);
|
||||
|
||||
row.addFiller();
|
||||
|
||||
grid.addSpacerRow(20);
|
||||
row = grid.addRow();
|
||||
stage = row.addMessage(stageComponent != null ? stageComponent : Component.literal(""),
|
||||
font,
|
||||
GridLayout.Alignment.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progressStartNoAbort(Component text) {
|
||||
this.progressStage(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progressStart(Component text) {
|
||||
this.progressStage(text);
|
||||
this.progressStagePercentage(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progressStage(Component text) {
|
||||
stageComponent = text;
|
||||
if (stage != null) stage.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void progressStagePercentage(int progress) {
|
||||
if (progress != currentProgress) {
|
||||
currentProgress = progress;
|
||||
if (progressImage != null) progressImage.percentage = currentProgress / 100.0f;
|
||||
if (this.progress != null) this.progress.setText(getProgressComponent());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.HelloClient;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
import org.betterx.bclib.util.ModUtil;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class SyncFilesScreen extends BCLibScreen {
|
||||
private final Component description;
|
||||
private final SyncFilesScreen.Listener listener;
|
||||
private final boolean hasConfigFiles;
|
||||
private final boolean hasFiles;
|
||||
private final boolean hasMods;
|
||||
private final boolean shouldDelete;
|
||||
private final HelloClient.IServerModMap serverInfo;
|
||||
|
||||
public SyncFilesScreen(int modFiles,
|
||||
int configFiles,
|
||||
int singleFiles,
|
||||
int folderFiles,
|
||||
int deleteFiles,
|
||||
HelloClient.IServerModMap serverInfo,
|
||||
Listener listener) {
|
||||
super(Component.translatable("title.bclib.syncfiles"));
|
||||
|
||||
this.serverInfo = serverInfo;
|
||||
this.description = Component.translatable("message.bclib.syncfiles");
|
||||
this.listener = listener;
|
||||
|
||||
this.hasConfigFiles = configFiles > 0;
|
||||
this.hasFiles = singleFiles + folderFiles > 0;
|
||||
this.hasMods = modFiles > 0;
|
||||
this.shouldDelete = deleteFiles > 0;
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addRow()
|
||||
.addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
|
||||
|
||||
grid.addSpacerRow(10);
|
||||
|
||||
GridRow row;
|
||||
|
||||
|
||||
final GridCheckboxCell mods;
|
||||
row = grid.addRow();
|
||||
mods = row.addCheckbox(Component.translatable("message.bclib.syncfiles.mods"),
|
||||
hasMods,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
mods.setEnabled(hasMods);
|
||||
|
||||
row.addSpacer();
|
||||
row.addButton(Component.translatable("title.bclib.syncfiles.modInfo"), 20, font, (button) -> {
|
||||
ModListScreen scr = new ModListScreen(
|
||||
this,
|
||||
Component.translatable("title.bclib.syncfiles.modlist"),
|
||||
Component.translatable("message.bclib.syncfiles.modlist"),
|
||||
ModUtil.getMods(),
|
||||
serverInfo
|
||||
);
|
||||
Minecraft.getInstance().setScreen(scr);
|
||||
});
|
||||
|
||||
grid.addSpacerRow();
|
||||
|
||||
|
||||
final GridCheckboxCell configs;
|
||||
row = grid.addRow();
|
||||
configs = row.addCheckbox(Component.translatable("message.bclib.syncfiles.configs"),
|
||||
hasConfigFiles,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
configs.setEnabled(hasConfigFiles);
|
||||
|
||||
grid.addSpacerRow();
|
||||
|
||||
row = grid.addRow();
|
||||
|
||||
final GridCheckboxCell folder;
|
||||
folder = row.addCheckbox(Component.translatable("message.bclib.syncfiles.folders"),
|
||||
hasFiles,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
folder.setEnabled(hasFiles);
|
||||
row.addSpacer();
|
||||
|
||||
GridCheckboxCell delete;
|
||||
delete = row.addCheckbox(Component.translatable("message.bclib.syncfiles.delete"),
|
||||
shouldDelete,
|
||||
BUTTON_HEIGHT,
|
||||
this.font);
|
||||
delete.setEnabled(shouldDelete);
|
||||
|
||||
|
||||
grid.addSpacerRow(30);
|
||||
row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_NO, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
listener.proceed(false, false, false, false);
|
||||
});
|
||||
row.addSpacer();
|
||||
row.addButton(CommonComponents.GUI_YES, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
listener.proceed(
|
||||
mods.isChecked(),
|
||||
configs.isChecked(),
|
||||
folder.isChecked(),
|
||||
delete.isChecked()
|
||||
);
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed(boolean downloadMods, boolean downloadConfigs, boolean downloadFiles, boolean removeFiles);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridRow;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class WarnBCLibVersionMismatch extends BCLibScreen {
|
||||
private final Component description;
|
||||
private final Listener listener;
|
||||
|
||||
public WarnBCLibVersionMismatch(Listener listener) {
|
||||
super(Component.translatable("title.bclib.bclibmissmatch"));
|
||||
|
||||
this.description = Component.translatable("message.bclib.bclibmissmatch");
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
protected void initLayout() {
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
|
||||
grid.addRow().addMessage(this.description, this.font, GridLayout.Alignment.CENTER);
|
||||
grid.addSpacerRow(20);
|
||||
GridRow row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_NO, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
listener.proceed(false);
|
||||
});
|
||||
row.addSpacer();
|
||||
row.addButton(CommonComponents.GUI_YES, BUTTON_HEIGHT, this.font, (button) -> {
|
||||
listener.proceed(true);
|
||||
});
|
||||
row.addFiller();
|
||||
}
|
||||
|
||||
public boolean shouldCloseOnEsc() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public interface Listener {
|
||||
void proceed(boolean download);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package org.betterx.bclib.client.gui.screens;
|
||||
|
||||
import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen;
|
||||
import net.minecraft.client.gui.screens.worldselection.WorldCreationContext;
|
||||
import net.minecraft.network.chat.CommonComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.dimension.BuiltinDimensionTypes;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.generator.BCLBiomeSource;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridCheckboxCell;
|
||||
import org.betterx.bclib.client.gui.gridlayout.GridLayout;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class WorldSetupScreen extends BCLibScreen {
|
||||
private final WorldCreationContext context;
|
||||
private final CreateWorldScreen createWorldScreen;
|
||||
|
||||
public WorldSetupScreen(@Nullable CreateWorldScreen parent, WorldCreationContext context) {
|
||||
super(parent, Component.translatable("title.screen.bclib.worldgen.main"), 10, false);
|
||||
this.context = context;
|
||||
this.createWorldScreen = parent;
|
||||
}
|
||||
|
||||
|
||||
private GridCheckboxCell bclibEnd;
|
||||
private GridCheckboxCell bclibNether;
|
||||
GridCheckboxCell endLegacy;
|
||||
GridCheckboxCell netherLegacy;
|
||||
|
||||
@Override
|
||||
protected void initLayout() {
|
||||
final int netherVersion = LevelGenUtil.getBiomeVersionForGenerator(context
|
||||
.worldGenSettings()
|
||||
.dimensions()
|
||||
.getOrCreateHolderOrThrow(
|
||||
LevelStem.NETHER)
|
||||
.value()
|
||||
.generator());
|
||||
final int endVersion = LevelGenUtil.getBiomeVersionForGenerator(context
|
||||
.worldGenSettings()
|
||||
.dimensions()
|
||||
.getOrCreateHolderOrThrow(
|
||||
LevelStem.END)
|
||||
.value()
|
||||
.generator());
|
||||
|
||||
final int BUTTON_HEIGHT = 20;
|
||||
grid.addSpacerRow(20);
|
||||
|
||||
var row = grid.addRow();
|
||||
var colNether = row.addColumn(0.5, GridLayout.GridValueType.PERCENTAGE);
|
||||
var colEnd = row.addColumn(0.5, GridLayout.GridValueType.PERCENTAGE);
|
||||
|
||||
row = colNether.addRow();
|
||||
row.addString(Component.translatable("title.bclib.the_nether"), GridLayout.Alignment.CENTER, this);
|
||||
colNether.addSpacerRow(15);
|
||||
|
||||
var mainSettingsRow = colNether.addRow();
|
||||
mainSettingsRow.addSpacer(16);
|
||||
row = colNether.addRow();
|
||||
row.addSpacer(32);
|
||||
netherLegacy = row.addCheckbox(Component.translatable("title.screen.bclib.worldgen.legacy_square"),
|
||||
endVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE,
|
||||
1.0,
|
||||
GridLayout.GridValueType.PERCENTAGE,
|
||||
(state) -> {
|
||||
});
|
||||
bclibNether = mainSettingsRow.addCheckbox(Component.translatable(
|
||||
"title.screen.bclib.worldgen.custom_biome_source"),
|
||||
netherVersion != BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA,
|
||||
1.0,
|
||||
GridLayout.GridValueType.PERCENTAGE,
|
||||
(state) -> {
|
||||
netherLegacy.setEnabled(state);
|
||||
});
|
||||
|
||||
|
||||
row = colEnd.addRow(GridLayout.VerticalAlignment.CENTER);
|
||||
row.addString(Component.translatable("title.bclib.the_end"), GridLayout.Alignment.CENTER, this);
|
||||
colEnd.addSpacerRow(15);
|
||||
|
||||
mainSettingsRow = colEnd.addRow();
|
||||
mainSettingsRow.addSpacer(16);
|
||||
row = colEnd.addRow();
|
||||
row.addSpacer(32);
|
||||
|
||||
endLegacy = row.addCheckbox(Component.translatable("title.screen.bclib.worldgen.legacy_square"),
|
||||
endVersion == BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE,
|
||||
1.0,
|
||||
GridLayout.GridValueType.PERCENTAGE,
|
||||
(state) -> {
|
||||
});
|
||||
|
||||
bclibEnd = mainSettingsRow.addCheckbox(Component.translatable(
|
||||
"title.screen.bclib.worldgen.custom_biome_source"),
|
||||
endVersion != BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA,
|
||||
1.0,
|
||||
GridLayout.GridValueType.PERCENTAGE,
|
||||
(state) -> {
|
||||
endLegacy.setEnabled(state);
|
||||
});
|
||||
|
||||
grid.addSpacerRow(15);
|
||||
row = grid.addRow();
|
||||
row.addFiller();
|
||||
row.addButton(CommonComponents.GUI_DONE, BUTTON_HEIGHT, font, (button) -> {
|
||||
updateSettings();
|
||||
onClose();
|
||||
});
|
||||
grid.addSpacerRow(10);
|
||||
}
|
||||
|
||||
private void updateSettings() {
|
||||
int endVersion = BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
|
||||
if (bclibEnd.isChecked()) {
|
||||
if (endLegacy.isChecked()) endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
|
||||
else endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_HEX;
|
||||
} else {
|
||||
endVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
|
||||
}
|
||||
|
||||
int netherVersion = BCLBiomeSource.DEFAULT_BIOME_SOURCE_VERSION;
|
||||
if (bclibNether.isChecked()) {
|
||||
if (netherLegacy.isChecked()) netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_SQUARE;
|
||||
else netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_HEX;
|
||||
} else {
|
||||
netherVersion = BCLBiomeSource.BIOME_SOURCE_VERSION_VANILLA;
|
||||
}
|
||||
|
||||
BCLib.LOGGER.info("Custom World Versions: end=" + endVersion + ", nether=" + netherVersion);
|
||||
updateConfiguration(LevelStem.END, BuiltinDimensionTypes.END, endVersion);
|
||||
updateConfiguration(LevelStem.NETHER, BuiltinDimensionTypes.NETHER, netherVersion);
|
||||
}
|
||||
|
||||
|
||||
private void updateConfiguration(
|
||||
ResourceKey<LevelStem> dimensionKey,
|
||||
ResourceKey<DimensionType> dimensionTypeKey,
|
||||
int biomeSourceVersion
|
||||
) {
|
||||
createWorldScreen.worldGenSettingsComponent.updateSettings(
|
||||
(registryAccess, worldGenSettings) -> LevelGenUtil.replaceGenerator(
|
||||
dimensionKey,
|
||||
dimensionTypeKey,
|
||||
biomeSourceVersion,
|
||||
registryAccess,
|
||||
worldGenSettings
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import org.betterx.bclib.api.ModIntegrationAPI;
|
||||
import org.betterx.bclib.api.v2.ModIntegrationAPI;
|
||||
import org.betterx.bclib.client.render.EmissiveTextureInfo;
|
||||
import org.betterx.bclib.interfaces.BlockModelProvider;
|
||||
import org.betterx.bclib.interfaces.ItemModelProvider;
|
||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.world.level.levelgen.presets.WorldPreset;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.gui.screens.WorldSetupScreen;
|
||||
import org.betterx.bclib.client.gui.screens.WorldSetupScreen;
|
||||
import org.betterx.bclib.presets.worldgen.BCLWorldPresets;
|
||||
|
||||
import java.util.Optional;
|
||||
|
|
|
@ -12,8 +12,8 @@ import net.minecraft.world.level.biome.Biome;
|
|||
import net.minecraft.world.level.material.FogType;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import org.betterx.bclib.api.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.util.BackgroundInfo;
|
||||
import org.betterx.bclib.util.MHelper;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue