1
mirror of https://github.com/Shiewk/Widgets.git synced 2026-04-28 11:34:17 +02:00

Rework widget positioning

This commit is contained in:
Shy
2025-11-20 19:33:12 +01:00
parent 4b27e15e0c
commit ceb507078c
8 changed files with 279 additions and 164 deletions
@@ -0,0 +1,61 @@
package de.shiewk.widgets;
import org.joml.Vector2i;
public enum Anchor {
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
CENTER_LEFT,
CENTER,
CENTER_RIGHT,
BOTTOM_LEFT,
BOTTOM_CENTER,
BOTTOM_RIGHT;
public int getAlignStartPosX(int scaledScreenWidth){
return switch (this){
case TOP_LEFT, CENTER_LEFT, BOTTOM_LEFT -> 0;
case TOP_CENTER, CENTER, BOTTOM_CENTER -> scaledScreenWidth / 2;
case TOP_RIGHT, CENTER_RIGHT, BOTTOM_RIGHT -> scaledScreenWidth;
};
}
public int getAlignStartPosY(int scaledScreenHeight){
return switch (this){
case TOP_LEFT, TOP_CENTER, TOP_RIGHT -> 0;
case CENTER_LEFT, CENTER, CENTER_RIGHT -> scaledScreenHeight / 2;
case BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT -> scaledScreenHeight;
};
}
public Vector2i getTopLeft(int scaledScreenWidth, int scaledScreenHeight){
return new Vector2i(
// X component
switch (this){
case TOP_LEFT, CENTER_LEFT, BOTTOM_LEFT -> 0;
case TOP_CENTER, CENTER, BOTTOM_CENTER -> scaledScreenWidth / 3;
case TOP_RIGHT, CENTER_RIGHT, BOTTOM_RIGHT -> (int) (scaledScreenWidth / 3d * 2d);
},
// Y component
switch (this){
case TOP_LEFT, TOP_CENTER, TOP_RIGHT -> 0;
case CENTER_LEFT, CENTER, CENTER_RIGHT -> scaledScreenHeight / 3;
case BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT -> (int) (scaledScreenHeight / 3d * 2d);
}
);
}
public static Anchor getAnchor(int scaledScreenWidth, int scaledScreenHeight, int posX, int posY){
for (Anchor anchor : values()) {
Vector2i topLeft = anchor.getTopLeft(scaledScreenWidth, scaledScreenHeight);
if (
topLeft.x <= posX && topLeft.x + scaledScreenWidth / 3 >= posX &&
topLeft.y <= posY && topLeft.y + scaledScreenHeight / 3 >= posY
){
return anchor;
}
}
return Anchor.TOP_LEFT;
}
}
@@ -1,9 +0,0 @@
package de.shiewk.widgets;
public interface Dimensionable {
int width();
int height();
double getX(int mx);
double getY(int my);
float getScaleFactor();
}
+20 -8
View File
@@ -1,6 +1,5 @@
package de.shiewk.widgets;
import de.shiewk.widgets.utils.WidgetUtils;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
@@ -9,7 +8,7 @@ import net.minecraft.util.Identifier;
import java.util.List;
import java.util.Objects;
public abstract class ModWidget implements Dimensionable {
public abstract class ModWidget {
private final Identifier id;
private final WidgetSettings settings;
@@ -37,14 +36,27 @@ public abstract class ModWidget implements Dimensionable {
public abstract Text getDescription();
public abstract void onSettingsChanged(WidgetSettings settings);
@Override
public double getX(int mx) {
return (int) WidgetUtils.translateToScreen(settings.posX, mx);
public int getX(int scaledScreenWidth){
return settings.anchor.getAlignStartPosX(scaledScreenWidth) + settings.offsetX;
}
@Override
public double getY(int my) {
return (int) WidgetUtils.translateToScreen(settings.posY, my);
public int getY(int scaledScreenHeight){
return settings.anchor.getAlignStartPosY(scaledScreenHeight) + settings.offsetY;
}
public abstract int width();
public abstract int height();
public float scaledWidth() {
return width() * getScaleFactor();
}
public float scaledHeight() {
return height() * getScaleFactor();
}
public void move(int dx, int dy) {
settings.offsetX += dx;
settings.offsetY += dy;
}
}
@@ -2,31 +2,40 @@ package de.shiewk.widgets;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import de.shiewk.widgets.client.WidgetManager;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import java.util.List;
import java.util.Objects;
import static de.shiewk.widgets.WidgetsMod.LOGGER;
import static de.shiewk.widgets.utils.WidgetUtils.translateToWidgetSettingsValue;
import static de.shiewk.widgets.client.WidgetManager.gson;
public class WidgetSettings {
public double posX = 0; // posx * 100 = screen width
public double posY = 0; // posy * 100 = screen height
public Anchor anchor = Anchor.TOP_LEFT;
public int offsetX = 0;
public int offsetY = 0;
private boolean enabled = false;
private final ObjectArrayList<WidgetSettingOption> customSettings;
private WidgetSettings(JsonObject data, List<WidgetSettingOption> settings){
customSettings = new ObjectArrayList<>(settings);
if (data != null){
final JsonElement enabled = data.get("enabled");
this.enabled = enabled.isJsonPrimitive() && enabled.getAsJsonPrimitive().isBoolean() && enabled.getAsBoolean();
final JsonElement x = data.get("x");
this.posX = x.isJsonPrimitive() ? x.getAsJsonPrimitive().isNumber() ? x.getAsDouble() : 0 : 0;
final JsonElement y = data.get("y");
this.posY = y.isJsonPrimitive() ? y.getAsJsonPrimitive().isNumber() ? y.getAsDouble() : 0 : 0;
try {
this.enabled = Objects.requireNonNullElse(gson.fromJson(data.get("enabled"), Boolean.class), false);
this.anchor = gson.fromJson(data.get("anchor"), Anchor.class);
this.offsetX = Objects.requireNonNullElse(gson.fromJson(data.get("ox"), Integer.class), 0);
this.offsetY = Objects.requireNonNullElse(gson.fromJson(data.get("oy"), Integer.class), 0);
} catch (JsonSyntaxException | NullPointerException e) {
LOGGER.info("Failed to load widget positioning:", e);
} finally {
if (anchor == null){
anchor = Anchor.TOP_LEFT;
}
}
final JsonElement s = data.get("settings");
if (s != null && s.isJsonObject()){
final JsonObject savedSettings = s.getAsJsonObject();
@@ -52,11 +61,10 @@ public class WidgetSettings {
return new WidgetSettings(data, customSettings);
}
public void setPosX(double v, int widgetWidth, int maxWidth) {
posX = MathHelper.clamp(v, 0, 100 - translateToWidgetSettingsValue(widgetWidth, maxWidth));
}
public void setPosY(double v, int widgetHeight, int maxHeight) {
posY = MathHelper.clamp(v, 0, 100 - translateToWidgetSettingsValue(widgetHeight, maxHeight));
public void setPos(Anchor anchor, int offsetX, int offsetY){
this.anchor = anchor;
this.offsetX = offsetX;
this.offsetY = offsetY;
}
public boolean isEnabled(){
@@ -78,14 +86,17 @@ public class WidgetSettings {
public final JsonObject saveState(){
JsonObject object = new JsonObject();
object.addProperty("x", posX);
object.addProperty("y", posY);
object.addProperty("enabled", enabled);
object.add("anchor", gson.toJsonTree(this.anchor));
object.add("enabled", gson.toJsonTree(this.enabled));
object.add("ox", gson.toJsonTree(this.offsetX));
object.add("oy", gson.toJsonTree(this.offsetY));
JsonObject customSettings = new JsonObject();
for (WidgetSettingOption customSetting : this.customSettings) {
customSettings.add(customSetting.getId(), customSetting.saveState());
}
object.add("settings", customSettings);
return object;
}
@@ -46,8 +46,8 @@ public class WidgetManager {
enabled.remove(widget);
}
static Function<Identifier, File> saveFileFactory = id -> new File(MinecraftClient.getInstance().runDirectory.getPath() + "/config/widgets/" + id.getNamespace() + "/" + id.getPath() + ".json");;
private static final Gson gson = new Gson();
static Function<Identifier, File> saveFileFactory = id -> new File(MinecraftClient.getInstance().runDirectory.getPath() + "/config/widgets/" + id.getNamespace() + "/" + id.getPath() + ".json");
public static final Gson gson = new Gson();
public static void saveWidgets(List<ModWidget> widgets) {
for (ModWidget widget : widgets) {
@@ -1,7 +1,6 @@
package de.shiewk.widgets.client;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetSettings;
import de.shiewk.widgets.WidgetsMod;
import de.shiewk.widgets.client.screen.EditWidgetPositionsScreen;
import de.shiewk.widgets.client.screen.WidgetConfigScreen;
@@ -18,8 +17,6 @@ import net.minecraft.util.Util;
import net.minecraft.util.profiler.Profiler;
import net.minecraft.util.profiler.Profilers;
import static de.shiewk.widgets.utils.WidgetUtils.translateToScreen;
public class WidgetRenderer implements ClientTickEvents.StartTick, ClientLifecycleEvents.ClientStarted {
public static final Identifier LAYER_ID = Identifier.of(WidgetsMod.MOD_ID, "widgets-hud-layer");
@@ -46,13 +43,12 @@ public class WidgetRenderer implements ClientTickEvents.StartTick, ClientLifecyc
for (int i = 0, enabledSize = enabled.size(); i < enabledSize; i++) {
final ModWidget widget = enabled.get(i);
profiler.push(widget.getId().toString());
final WidgetSettings settings = widget.getSettings();
widget.render(
drawContext,
timeNano,
textRenderer,
(int) Math.round(Math.min(translateToScreen(settings.posX, windowWidth), windowWidth - (widget.width() * widget.getScaleFactor()))),
(int) Math.round(Math.min(translateToScreen(settings.posY, windowHeight), windowHeight - (widget.height() * widget.getScaleFactor())))
widget.getX(windowWidth),
widget.getY(windowHeight)
);
profiler.pop();
}
@@ -1,10 +1,9 @@
package de.shiewk.widgets.client.screen;
import de.shiewk.widgets.Dimensionable;
import de.shiewk.widgets.Anchor;
import de.shiewk.widgets.ModWidget;
import de.shiewk.widgets.WidgetSettings;
import de.shiewk.widgets.client.WidgetManager;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.client.gui.Click;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
@@ -12,38 +11,16 @@ import net.minecraft.client.gui.tooltip.Tooltip;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector2i;
import java.awt.*;
import java.util.function.Consumer;
import static de.shiewk.widgets.utils.WidgetUtils.translateToScreen;
import static de.shiewk.widgets.utils.WidgetUtils.translateToWidgetSettingsValue;
public class EditWidgetPositionsScreen extends AnimatedScreen {
private record Alignment(int x, int y, int width, int height) implements Dimensionable {
@Override
public double getX(int mx) {
return x;
}
@Override
public double getY(int my) {
return y;
}
@Override
public float getScaleFactor() {
return 1f;
}
}
private final Screen parent;
private final Consumer<ModWidget> onEdit;
private boolean alignX = true;
private boolean alignY = true;
public EditWidgetPositionsScreen(Screen parent, Consumer<ModWidget> onEdit) {
super(Text.translatable("widgets.ui.editPositions"), parent, 500);
this.parent = parent;
@@ -58,85 +35,46 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
private record AlignResult(double result, boolean isEnd){}
private @Nullable AlignResult alignX(double x, int width, ModWidget widget){
double endX = x + width;
int factor = alignX ? 2 : 0;
for (Dimensionable rect : this.getAlignments(widget)) {
if (rect == widget) continue;
final int rectWidth = rect.width();
final double nwx = Math.min(rect.getX(this.width), this.width - rectWidth);
final double nww = rectWidth * rect.getScaleFactor();
if (endX < nwx + factor && endX > nwx - factor){
return new AlignResult(nwx - width, true);
} else if (x < nwx + factor && x > nwx - factor){
return new AlignResult(nwx, false);
} else if (endX < nwx+nww + factor && endX > nwx + nww - factor){
return new AlignResult(nwx + nww - width, true);
} else if (x < nwx+nww + factor && x > nwx + nww - factor){
return new AlignResult(nwx + nww, false);
}
}
return null;
}
private Iterable<? extends Dimensionable> getAlignments(Dimensionable rel) {
ObjectArrayList<Dimensionable> alignments = new ObjectArrayList<>();
for (ModWidget widget : WidgetManager.getEnabledWidgets()) {
alignments.add(widget);
}
alignments.add(new Alignment(2, 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(this.width / 2, this.height / 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(2, this.height / 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment(this.width / 2, 2, this.width / 2 - 2, this.height / 2 - 2));
alignments.add(new Alignment((int) ((float) this.width / 2 - (rel.width() * rel.getScaleFactor()) / 2), (int) ((float) this.height / 2 - (rel.height() * rel.getScaleFactor()) / 2), (int) (rel.width() * rel.getScaleFactor()), (int) (rel.height() * rel.getScaleFactor())));
return alignments;
}
private @Nullable AlignResult alignY(double y, int height, ModWidget widget){
double endY = y + height;
int factor = alignY ? 2 : 0;
for (Dimensionable rect : this.getAlignments(widget)) {
if (rect == widget) continue;
final int rectHeight = rect.height();
final double nwy = Math.min(rect.getY(this.height), this.height - rectHeight);
final double nwh = rectHeight * rect.getScaleFactor();
if (endY < nwy + factor && endY > nwy - factor){
return new AlignResult(nwy - height, true);
} else if (y < nwy + factor && y > nwy - factor){
return new AlignResult(nwy, false);
} else if (endY < nwy+nwh + factor && endY > nwy + nwh - factor){
return new AlignResult(nwy + nwh - height, true);
} else if (y < nwy+nwh + factor && y > nwy + nwh - factor){
return new AlignResult(nwy + nwh, false);
}
}
return null;
}
private static final int SELECT_COLOR = Color.GREEN.getRGB(), ALIGN_COLOR = Color.ORANGE.getRGB(), ALIGN_DISABLED_COLOR = Color.GRAY.getRGB();
private ModWidget selectedWidget = null;
private ModWidget hoveredWidget = null;
private int focusedExtraX = 0;
private int focusedExtraY = 0;
private boolean align = true;
private int scaledWindowWidth = 1920;
private int scaledWindowHeight = 1080;
@Override
public void renderScreenContents(DrawContext context, int mouseX, int mouseY, float delta) {
assert client != null;
this.scaledWindowWidth = context.getScaledWindowWidth();
this.scaledWindowHeight = context.getScaledWindowHeight();
long mt = Util.getMeasuringTimeNano();
renderAnchorArea(context, mouseX, mouseY);
for (ModWidget widget : WidgetManager.getEnabledWidgets()) {
final WidgetSettings settings = widget.getSettings();
final int ww = (int) (widget.width() * widget.getScaleFactor());
double wx = Math.min(translateToScreen(settings.posX, this.width), this.width - ww);
int wx = Math.min(widget.getX(scaledWindowWidth), this.width - ww);
final int wh = (int) (widget.height() * widget.getScaleFactor());
double wy = Math.min(translateToScreen(settings.posY, this.height), this.height - wh);
int wy = Math.min(widget.getY(scaledWindowHeight), this.height - wh);
if (selectedWidget == widget){
final AlignResult alignedX = alignX(wx, ww, widget);
AlignResult alignedX = alignX(widget);
if (alignedX != null){
context.drawVerticalLine((int) (!alignedX.isEnd() ? alignedX.result() : alignedX.result() + ww), 0, this.height, alignX ? ALIGN_COLOR : ALIGN_DISABLED_COLOR);
wx = alignedX.result();
context.drawVerticalLine(
(int) Math.round(alignedX.result),
0,
scaledWindowHeight,
align ? ALIGN_COLOR : ALIGN_DISABLED_COLOR
);
}
final AlignResult alignedY = alignY(wy, wh, widget);
AlignResult alignedY = alignY(widget);
if (alignedY != null){
context.drawHorizontalLine(0, this.width, (int) (!alignedY.isEnd() ? alignedY.result() : alignedY.result() + wh), alignY ? ALIGN_COLOR : ALIGN_DISABLED_COLOR);
wy = alignedY.result();
context.drawHorizontalLine(
0,
scaledWindowWidth,
(int) Math.round(alignedY.result),
align ? ALIGN_COLOR : ALIGN_DISABLED_COLOR
);
}
}
if (hoveredWidget == null || hoveredWidget == widget){
@@ -149,23 +87,96 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
}
}
if (selectedWidget == null ? hoveredWidget == widget : selectedWidget == widget){
context.drawStrokedRectangle((int) Math.round(wx-1), (int) Math.round(wy-1), ww+2, wh+2, SELECT_COLOR);
context.drawStrokedRectangle((int) Math.round(wx), (int) Math.round(wy), ww, wh, SELECT_COLOR);
context.drawStrokedRectangle(wx-1,wy-1, ww+2, wh+2, SELECT_COLOR);
context.drawStrokedRectangle(wx, wy, ww, wh, SELECT_COLOR);
}
widget.render(context, Util.getMeasuringTimeNano(), textRenderer, (int) Math.round(wx), (int) Math.round(wy));
widget.render(context, mt, textRenderer, wx, wy);
}
}
private boolean canAlign(int val1, int val2){
return ((val2 - val1) * (val2 - val1)) < 9;
}
private AlignResult alignX(ModWidget widget) {
// Align with other widgets
for (ModWidget other : WidgetManager.getEnabledWidgets()) {
if (other == widget) continue;
if (canAlign(widget.getX(scaledWindowWidth), other.getX(scaledWindowWidth))){
return new AlignResult(other.getX(scaledWindowWidth), false);
} else if (canAlign(widget.getX(scaledWindowWidth) + (int) widget.scaledWidth(), other.getX(scaledWindowWidth) + (int) other.scaledWidth())) {
return new AlignResult(other.getX(scaledWindowWidth) + other.scaledWidth(), true);
} else if (canAlign(widget.getX(scaledWindowWidth), other.getX(scaledWindowWidth) + (int) other.scaledWidth())){
return new AlignResult(other.getX(scaledWindowWidth) + other.scaledWidth(), false);
} else if (canAlign(widget.getX(scaledWindowWidth) + (int) widget.scaledWidth(), other.getX(scaledWindowWidth))){
return new AlignResult(other.getX(scaledWindowWidth), true);
}
}
return null;
}
private AlignResult alignY(ModWidget widget) {
// Align with other widgets
for (ModWidget other : WidgetManager.getEnabledWidgets()) {
if (other == widget) continue;
if (canAlign(widget.getY(scaledWindowHeight), other.getY(scaledWindowHeight))){
return new AlignResult(other.getY(scaledWindowHeight), false);
} else if (canAlign(widget.getY(scaledWindowHeight) + (int) widget.scaledHeight(), other.getY(scaledWindowHeight) + (int) other.scaledHeight())) {
return new AlignResult(other.getY(scaledWindowHeight) + other.scaledHeight(), true);
} else if (canAlign(widget.getY(scaledWindowHeight), other.getY(scaledWindowHeight) + (int) other.scaledHeight())){
return new AlignResult(other.getY(scaledWindowHeight) + other.scaledHeight(), false);
} else if (canAlign(widget.getY(scaledWindowHeight) + (int) widget.scaledHeight(), other.getY(scaledWindowHeight))){
return new AlignResult(other.getY(scaledWindowHeight), true);
}
}
return null;
}
private void renderAnchorArea(DrawContext context, int mouseX, int mouseY) {
Anchor anchor = Anchor.getAnchor(
scaledWindowWidth,
scaledWindowHeight,
mouseX,
mouseY
);
Vector2i topLeft = anchor.getTopLeft(scaledWindowWidth, scaledWindowHeight);
context.fill(
topLeft.x,
topLeft.y,
topLeft.x + scaledWindowWidth / 3,
topLeft.y + scaledWindowHeight / 3,
0x08ffffff
);
}
@Override
public boolean mouseReleased(Click click) {
if (click.button() == 0 && selectedWidget != null){
final AlignResult alignedX = alignX(translateToScreen(selectedWidget.getSettings().posX, this.width), (int) (selectedWidget.width() * selectedWidget.getScaleFactor()), selectedWidget);
if (alignedX != null){
selectedWidget.getSettings().setPosX(translateToWidgetSettingsValue(alignedX.result(), this.width), (int) (selectedWidget.width() * selectedWidget.getScaleFactor()), this.width);
}
final AlignResult alignedY = alignY(translateToScreen(selectedWidget.getSettings().posY, this.height), (int) (selectedWidget.height() * selectedWidget.getScaleFactor()), selectedWidget);
if (alignedY != null){
selectedWidget.getSettings().setPosY(translateToWidgetSettingsValue(alignedY.result(), this.height), (int) (selectedWidget.height() * selectedWidget.getScaleFactor()), this.height);
if (align){
AlignResult alignedX = alignX(selectedWidget);
if (alignedX != null){
double diff = Math.round(alignedX.result - selectedWidget.getX(scaledWindowWidth));
if (alignedX.isEnd){
diff -= selectedWidget.scaledWidth();
}
selectedWidget.move((int) diff, 0);
}
AlignResult alignedY = alignY(selectedWidget);
if (alignedY != null){
double diff = Math.round(alignedY.result - selectedWidget.getY(scaledWindowHeight));
if (alignedY.isEnd){
diff -= selectedWidget.scaledHeight();
}
selectedWidget.move(0, (int) diff);
}
}
onEdit.accept(selectedWidget);
selectedWidget = null;
@@ -177,6 +188,8 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
public boolean mouseClicked(Click click, boolean doubled) {
if (click.button() == 0 && hoveredWidget != null){
selectedWidget = hoveredWidget;
focusedExtraX = (int) (click.x() - hoveredWidget.getX(scaledWindowWidth));
focusedExtraY = (int) (click.y() - hoveredWidget.getY(scaledWindowHeight));
}
return super.mouseClicked(click, doubled);
}
@@ -189,15 +202,35 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
if (widget != null){
final WidgetSettings settings = widget.getSettings();
final int ww = (int) (widget.width() * widget.getScaleFactor());
final int wx = (int) Math.min(translateToScreen(settings.posX, this.width), this.width - ww);
int wx = Math.min(widget.getX(scaledWindowWidth), this.width - ww);
final int wh = (int) (widget.height() * widget.getScaleFactor());
final int wy = (int) Math.min(translateToScreen(settings.posY, this.height), this.height - wh);
int wy = Math.min(widget.getY(scaledWindowHeight), this.height - wh);
if (click.x() <= wx + ww + deltaX && click.x() >= wx + deltaX){
if (click.y() <= wy + wh + deltaY && click.y() >= wy + deltaY){
double newPosX = settings.posX + translateToWidgetSettingsValue(deltaX, this.width);
double newPosY = settings.posY + translateToWidgetSettingsValue(deltaY, this.height);
settings.setPosX(newPosX, ww, this.width);
settings.setPosY(newPosY, wh, this.height);
Anchor anchor = Anchor.getAnchor(scaledWindowWidth, scaledWindowHeight, (int) click.x(), (int) click.y());
int newOffX = (int) (click.x() - anchor.getAlignStartPosX(scaledWindowWidth)) - focusedExtraX;
int newOffY = (int) (click.y() - anchor.getAlignStartPosY(scaledWindowHeight)) - focusedExtraY;
// Ensure the thing does not go out of bounds
settings.setPos(anchor, newOffX, newOffY);
if (widget.getX(scaledWindowWidth) + ww > scaledWindowWidth){
newOffX -= widget.getX(scaledWindowWidth) - scaledWindowWidth + ww;
settings.setPos(anchor, newOffX, newOffY);
}
if (widget.getX(scaledWindowWidth) < 0){
newOffX -= widget.getX(scaledWindowWidth);
settings.setPos(anchor, newOffX, newOffY);
}
if (widget.getY(scaledWindowHeight) + wh > scaledWindowHeight){
newOffY -= widget.getY(scaledWindowHeight) - scaledWindowHeight + wh;
settings.setPos(anchor, newOffX, newOffY);
}
if (widget.getY(scaledWindowHeight) < 0){
newOffY -= widget.getY(scaledWindowHeight);
settings.setPos(anchor, newOffX, newOffY);
}
return true;
}
}
@@ -209,10 +242,29 @@ public class EditWidgetPositionsScreen extends AnimatedScreen {
@Override
protected void init() {
super.init();
this.addDrawableChild(new ButtonWidget.Builder(Text.translatable("widgets.ui.editPositions.snap", alignX ? Text.translatable("gui.yes") : Text.translatable("gui.no")), button -> {
alignX = !alignX;
alignY = !alignY;
button.setMessage(Text.translatable("widgets.ui.editPositions.snap", alignX ? Text.translatable("gui.yes") : Text.translatable("gui.no")));
}).position(this.width / 2 - 75, this.height / 2 - 10).tooltip(Tooltip.of(Text.translatable("widgets.ui.editPositions.snap.help"))).build());
this.addDrawableChild(
new ButtonWidget.Builder(
Text.translatable(
"widgets.ui.editPositions.snap",
align ?
Text.translatable("gui.yes") :
Text.translatable("gui.no")
), button -> {
align = !align;
button.setMessage(
Text.translatable(
"widgets.ui.editPositions.snap",
align ?
Text.translatable("gui.yes")
: Text.translatable("gui.no")
)
);
}).position(
this.width / 2 - 75,
this.height / 2 - 10
).tooltip(
Tooltip.of(Text.translatable("widgets.ui.editPositions.snap.help"))
).build()
);
}
}
@@ -9,14 +9,6 @@ public class WidgetUtils {
public static final BooleanSupplier TRUE_SUPPLIER = () -> true;
public static double translateToWidgetSettingsValue(double value, int max){
return (value / max) * 100;
}
public static double translateToScreen(double value, int max){
return value / 100d * max;
}
public static double computeEasing(double x) {
return 1d - Math.pow(1d - x, 3.5d);
}