package de.hysky.skyblocker.config;
import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.utils.render.RenderHelper;
import it.unimi.dsi.fastutil.ints.IntIntMutablePair;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.util.math.MathHelper;
import java.awt.*;
import java.util.List;
/**
* A screen for configuring the positions of HUD widgets.
*
* This class takes care of rendering the widgets, dragging them, and resetting their positions.
* Create one subclass for each collection of HUD widgets that are displayed at the same time.
* (i.e. one for dwarven mines, one for the end, etc.) See an implementation for an example.
*/
public abstract class HudConfigScreen extends Screen {
private final Screen parent;
private final List widgets;
private Widget draggingWidget;
private double mouseClickRelativeX;
private double mouseClickRelativeY;
/**
* Creates a new HudConfigScreen with the passed title, parent, and widget
* @param title the title of the screen
* @param parent the parent screen
* @param widget the widget to configure
*/
public HudConfigScreen(Text title, Screen parent, Widget widget) {
this(title, parent, List.of(widget));
}
/**
* Creates a new HudConfigScreen with the passed title, parent, and widgets
* @param title the title of the screen
* @param parent the parent screen
* @param widgets the widgets to configure
*/
public HudConfigScreen(Text title, Screen parent, List widgets) {
super(title);
this.parent = parent;
this.widgets = widgets;
resetPos();
}
@Override
public final void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
renderWidget(context, widgets);
context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
}
/**
* Renders the widgets using the default {@link Widget#render(DrawContext, boolean)} method. Override to change the behavior.
* @param context the context to render in
* @param widgets the widgets to render
*/
protected void renderWidget(DrawContext context, List widgets) {
for (Widget widget : widgets) {
widget.render(context, SkyblockerConfigManager.get().general.tabHud.enableHudBackground);
}
}
@Override
public final boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
if (button == 0 && draggingWidget != null) {
draggingWidget.setX((int) MathHelper.clamp(mouseX - mouseClickRelativeX, 0, this.width - draggingWidget.getWidth()));
draggingWidget.setY((int) MathHelper.clamp(mouseY - mouseClickRelativeY, 0, this.height - draggingWidget.getHeight()));
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@Override
public final boolean mouseClicked(double mouseX, double mouseY, int button) {
if (button == 0) {
for (Widget widget : widgets) {
if (RenderHelper.pointIsInArea(mouseX, mouseY, widget.getX(), widget.getY(), widget.getX() + widget.getWidth(), widget.getY() + widget.getHeight())) {
draggingWidget = widget;
mouseClickRelativeX = mouseX - widget.getX();
mouseClickRelativeY = mouseY - widget.getY();
break;
}
}
} else if (button == 1) {
resetPos();
}
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public final boolean mouseReleased(double mouseX, double mouseY, int button) {
draggingWidget = null;
return super.mouseReleased(mouseX, mouseY, button);
}
/**
* Resets the positions of the widgets to the positions in the config. Override to change the behavior.
*/
protected void resetPos() {
List configPositions = getConfigPos(SkyblockerConfigManager.get());
if (configPositions.size() != widgets.size()) {
throw new IllegalStateException("The number of positions (" + configPositions.size() + ") does not match the number of widgets (" + widgets.size() + ")");
}
for (int i = 0; i < widgets.size(); i++) {
Widget widget = widgets.get(i);
IntIntMutablePair configPos = configPositions.get(i);
widget.setX(configPos.leftInt());
widget.setY(configPos.rightInt());
}
}
/**
* Returns the positions of the widgets in the config
* @param config the config to get the positions from
* @return the positions of the widgets
*/
protected abstract List getConfigPos(SkyblockerConfig config);
@Override
public final void close() {
SkyblockerConfig skyblockerConfig = SkyblockerConfigManager.get();
savePos(skyblockerConfig, widgets);
SkyblockerConfigManager.save();
client.setScreen(parent);
}
/**
* Saves the passed positions to the config.
*
* NOTE: The parent class will call {@link SkyblockerConfigManager#save()} right after this method
* @param configManager the config so you don't have to get it
* @param widgets the widgets to save
*/
protected abstract void savePos(SkyblockerConfig configManager, List widgets);
}