375 lines
13 KiB
Java
375 lines
13 KiB
Java
package me.rigamortis.seppuku.api.gui.hud.component;
|
|
|
|
import me.rigamortis.seppuku.Seppuku;
|
|
import me.rigamortis.seppuku.api.util.RenderUtil;
|
|
import me.rigamortis.seppuku.impl.gui.hud.GuiHudEditor;
|
|
import me.rigamortis.seppuku.impl.gui.hud.anchor.AnchorPoint;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.ScaledResolution;
|
|
import net.minecraft.util.math.MathHelper;
|
|
import org.lwjgl.input.Keyboard;
|
|
|
|
/**
|
|
* Author Seth
|
|
* 7/25/2019 @ 7:17 AM.
|
|
*/
|
|
public class DraggableHudComponent extends HudComponent {
|
|
|
|
private boolean rclicked;
|
|
private boolean snappable;
|
|
private boolean dragging;
|
|
private boolean locked;
|
|
private float deltaX;
|
|
private float deltaY;
|
|
|
|
private AnchorPoint anchorPoint;
|
|
|
|
private DraggableHudComponent glued;
|
|
private GlueSide glueSide;
|
|
private boolean parent;
|
|
|
|
private static final double ANCHOR_THRESHOLD = 80;
|
|
|
|
protected final Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
public DraggableHudComponent(String name) {
|
|
this.setName(name);
|
|
this.setVisible(false);
|
|
this.setSnappable(true);
|
|
this.setLocked(false);
|
|
this.setRclicked(false);
|
|
this.setX(Minecraft.getMinecraft().displayWidth / 2.0f);
|
|
this.setY(Minecraft.getMinecraft().displayHeight / 2.0f);
|
|
}
|
|
|
|
@Override
|
|
public void mouseClick(int mouseX, int mouseY, int button) {
|
|
if (this.isMouseInside(mouseX, mouseY)) {
|
|
if (button == 0) {
|
|
this.setDragging(true);
|
|
this.setDeltaX(mouseX - this.getX());
|
|
this.setDeltaY(mouseY - this.getY());
|
|
Seppuku.INSTANCE.getHudManager().moveToTop(this);
|
|
this.anchorPoint = null;
|
|
this.glued = null;
|
|
this.glueSide = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void render(int mouseX, int mouseY, float partialTicks) {
|
|
super.render(mouseX, mouseY, partialTicks);
|
|
|
|
boolean isHudEditor = Minecraft.getMinecraft().currentScreen instanceof GuiHudEditor;
|
|
|
|
if (this.isDragging()) {
|
|
this.setX(mouseX - this.getDeltaX());
|
|
this.setY(mouseY - this.getDeltaY());
|
|
this.clamp();
|
|
} else if (this.isMouseInside(mouseX, mouseY)) {
|
|
RenderUtil.drawRect(this.getX(), this.getY(), this.getX() + this.getW(), this.getY() + this.getH(), 0x45FFFFFF);
|
|
}
|
|
|
|
if (isHudEditor) {
|
|
RenderUtil.drawRect(this.getX(), this.getY(), this.getX() + this.getW(), this.getY() + this.getH(), 0x75101010);
|
|
if (this.isLocked()) {
|
|
RenderUtil.drawBorderedRect(this.getX() - 1, this.getY() - 1, this.getX() + this.getW() + 1, this.getY() + this.getH() + 1, 0.5f, 0x00000000, 0x75FFFFFF);
|
|
}
|
|
}
|
|
|
|
if (this.glued != null) {
|
|
if (this.glued.getAnchorPoint() == null) {
|
|
if (this.anchorPoint != null) {
|
|
this.anchorPoint = null;
|
|
}
|
|
} else {
|
|
this.anchorPoint = this.glued.getAnchorPoint();
|
|
}
|
|
}
|
|
|
|
if (this.anchorPoint == null && this.glued != null) {
|
|
this.setX(this.glued.getX());
|
|
if (this.glueSide != null) {
|
|
switch (this.glueSide) {
|
|
case TOP:
|
|
// math... am i right?
|
|
if (!isHudEditor && this.glued.getH() <= 0 && this.getH() <= 0) {
|
|
this.setY((this.glued.getY() - this.getEmptyH()) + this.glued.getEmptyH());
|
|
} else if (!isHudEditor && this.glued.getH() <= 0 && this.getH() > 0) {
|
|
this.setY((this.glued.getY() + this.glued.getEmptyH()) - this.getH());
|
|
} else if (!isHudEditor && this.glued.getH() > 0 && this.getH() <= 0) {
|
|
this.setY(this.glued.getY() - this.getEmptyH());
|
|
} else {
|
|
this.setY(this.glued.getY() - this.getH());
|
|
}
|
|
break;
|
|
case BOTTOM:
|
|
this.setY(this.glued.getY() + this.glued.getH());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!this.isDragging()) {
|
|
if (this.anchorPoint != null && this.glued != null) {
|
|
switch (this.anchorPoint.getPoint()) {
|
|
case TOP_LEFT:
|
|
this.setX(this.anchorPoint.getX());
|
|
break;
|
|
case BOTTOM_LEFT:
|
|
this.setX(this.anchorPoint.getX());
|
|
break;
|
|
case TOP_RIGHT:
|
|
this.setX(this.anchorPoint.getX() - this.getW());
|
|
break;
|
|
case BOTTOM_RIGHT:
|
|
this.setX(this.anchorPoint.getX() - this.getW());
|
|
break;
|
|
case TOP_CENTER:
|
|
this.setX(this.anchorPoint.getX() - (this.getW() / 2.0f));
|
|
break;
|
|
case BOTTOM_CENTER:
|
|
this.setX(this.anchorPoint.getX() - (this.getW() / 2.0f));
|
|
break;
|
|
}
|
|
if (this.glueSide != null) {
|
|
switch (this.glueSide) {
|
|
case TOP:
|
|
this.setY(this.glued.getY() - this.getH());
|
|
break;
|
|
case BOTTOM:
|
|
this.setY(this.glued.getY() + this.glued.getH());
|
|
break;
|
|
}
|
|
}
|
|
} else if (this.anchorPoint != null) {
|
|
switch (this.anchorPoint.getPoint()) {
|
|
case TOP_LEFT:
|
|
this.setX(this.anchorPoint.getX());
|
|
this.setY(this.anchorPoint.getY());
|
|
break;
|
|
case BOTTOM_LEFT:
|
|
this.setX(this.anchorPoint.getX());
|
|
this.setY(this.anchorPoint.getY() - this.getH());
|
|
break;
|
|
case TOP_RIGHT:
|
|
this.setX(this.anchorPoint.getX() - this.getW());
|
|
this.setY(this.anchorPoint.getY());
|
|
break;
|
|
case BOTTOM_RIGHT:
|
|
this.setX(this.anchorPoint.getX() - this.getW());
|
|
this.setY(this.anchorPoint.getY() - this.getH());
|
|
break;
|
|
case TOP_CENTER:
|
|
this.setX(this.anchorPoint.getX() - (this.getW() / 2.0f));
|
|
this.setY(this.anchorPoint.getY());
|
|
break;
|
|
case BOTTOM_CENTER:
|
|
this.setX(this.anchorPoint.getX() - (this.getW() / 2.0f));
|
|
this.setY(this.anchorPoint.getY() - this.getH());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.clamp();
|
|
}
|
|
|
|
@Override
|
|
public void mouseRelease(int mouseX, int mouseY, int button) {
|
|
super.mouseRelease(mouseX, mouseY, button);
|
|
|
|
if (button == 0) {
|
|
if (this.isDragging()) {
|
|
if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) || !this.isSnappable()) {
|
|
this.setDragging(false);
|
|
return;
|
|
}
|
|
|
|
this.anchorPoint = this.findClosest(mouseX, mouseY);
|
|
|
|
for (HudComponent component : Seppuku.INSTANCE.getHudManager().getComponentList()) {
|
|
if (component instanceof DraggableHudComponent) {
|
|
DraggableHudComponent draggable = (DraggableHudComponent) component;
|
|
if (draggable != this && draggable.isVisible() && draggable.isSnappable()) {
|
|
if (this.collidesWith(draggable)) {
|
|
if ((this.getY() + (this.getH() / 2.0f)) < (draggable.getY() + (draggable.getH() / 2.0f))) { // top
|
|
this.setY(draggable.getY() - this.getH());
|
|
this.glueSide = GlueSide.TOP;
|
|
this.glued = draggable;
|
|
draggable.setParent(true);
|
|
if (draggable.getAnchorPoint() != null) {
|
|
this.anchorPoint = draggable.getAnchorPoint();
|
|
}
|
|
} else if ((this.getY() + (this.getH() / 2.0f)) > (draggable.getY() + (draggable.getH() / 2.0f))) { // bottom
|
|
this.setY(draggable.getY() + draggable.getH());
|
|
this.glueSide = GlueSide.BOTTOM;
|
|
this.glued = draggable;
|
|
draggable.setParent(true);
|
|
if (draggable.getAnchorPoint() != null) {
|
|
this.anchorPoint = draggable.getAnchorPoint();
|
|
}
|
|
}
|
|
} else {
|
|
AnchorPoint draggableClosest = draggable.getAnchorPoint();
|
|
AnchorPoint myClosest = this.findClosest(mouseX, mouseY);
|
|
if (draggableClosest != null && myClosest != null) {
|
|
boolean sameAnchor = draggableClosest.getPoint().equals(myClosest.getPoint());
|
|
if (sameAnchor) {
|
|
this.anchorPoint = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.setDragging(false);
|
|
} else if (button == 2) {
|
|
if (this.isMouseInside(mouseX, mouseY)) {
|
|
this.setLocked(!this.isLocked());
|
|
this.setSnappable(!this.isSnappable());
|
|
}
|
|
} else if (button == 1) {
|
|
if (this.isMouseInside(mouseX, mouseY)) {
|
|
this.setRclicked(!this.isRclicked());
|
|
}
|
|
}
|
|
}
|
|
|
|
public AnchorPoint findClosest(float x, float y) {
|
|
AnchorPoint ret = null;
|
|
double max = ANCHOR_THRESHOLD;
|
|
for (AnchorPoint point : Seppuku.INSTANCE.getHudManager().getAnchorPoints()) {
|
|
final double deltaX = x - point.getX();
|
|
final double deltaY = y - point.getY();
|
|
|
|
final double dist = MathHelper.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
if (dist <= max) {
|
|
max = dist;
|
|
ret = point;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public AnchorPoint findClosest() {
|
|
return findClosest(this.getX(), this.getY());
|
|
}
|
|
|
|
public void clamp() {
|
|
final ScaledResolution sr = new ScaledResolution(Minecraft.getMinecraft());
|
|
|
|
/* off screen clamp bypass check */
|
|
if (this.isLocked()/*this.isVisible() && this.getAnchorPoint() == null*/) {
|
|
return;
|
|
/*if (this.getX() > sr.getScaledWidth() || this.getY() > sr.getScaledHeight()) { // off the screen
|
|
return;
|
|
}*/
|
|
}
|
|
|
|
if (this.getX() <= 0) {
|
|
this.setX(2);
|
|
}
|
|
|
|
if (this.getY() <= 0) {
|
|
this.setY(2);
|
|
}
|
|
|
|
if (this.getX() + this.getW() >= sr.getScaledWidth() - 2) {
|
|
this.setX(sr.getScaledWidth() - 2 - this.getW());
|
|
}
|
|
|
|
if (this.getY() + this.getH() >= sr.getScaledHeight() - 2) {
|
|
this.setY(sr.getScaledHeight() - 2 - this.getH());
|
|
}
|
|
}
|
|
|
|
public boolean isRclicked() {
|
|
return rclicked;
|
|
}
|
|
|
|
public void setRclicked(boolean rclicked) {
|
|
this.rclicked = rclicked;
|
|
}
|
|
|
|
public boolean isSnappable() {
|
|
return snappable;
|
|
}
|
|
|
|
public void setSnappable(boolean snappable) {
|
|
this.snappable = snappable;
|
|
}
|
|
|
|
public boolean isDragging() {
|
|
return dragging;
|
|
}
|
|
|
|
public void setDragging(boolean dragging) {
|
|
this.dragging = dragging;
|
|
}
|
|
|
|
public boolean isLocked() {
|
|
return locked;
|
|
}
|
|
|
|
public void setLocked(boolean locked) {
|
|
this.locked = locked;
|
|
}
|
|
|
|
public float getDeltaX() {
|
|
return deltaX;
|
|
}
|
|
|
|
public void setDeltaX(float deltaX) {
|
|
this.deltaX = deltaX;
|
|
}
|
|
|
|
public float getDeltaY() {
|
|
return deltaY;
|
|
}
|
|
|
|
public void setDeltaY(float deltaY) {
|
|
this.deltaY = deltaY;
|
|
}
|
|
|
|
public AnchorPoint getAnchorPoint() {
|
|
return anchorPoint;
|
|
}
|
|
|
|
public void setAnchorPoint(AnchorPoint anchorPoint) {
|
|
this.anchorPoint = anchorPoint;
|
|
}
|
|
|
|
public HudComponent getGlued() {
|
|
return glued;
|
|
}
|
|
|
|
public void setGlued(DraggableHudComponent glued) {
|
|
this.glued = glued;
|
|
}
|
|
|
|
public GlueSide getGlueSide() {
|
|
return glueSide;
|
|
}
|
|
|
|
public void setGlueSide(GlueSide glueSide) {
|
|
this.glueSide = glueSide;
|
|
}
|
|
|
|
public enum GlueSide {
|
|
TOP, BOTTOM
|
|
}
|
|
|
|
public boolean isParent() {
|
|
return parent;
|
|
}
|
|
|
|
public void setParent(boolean parent) {
|
|
this.parent = parent;
|
|
}
|
|
}
|