mirror of
https://github.com/KAMKEEL/CustomNPC-Plus.git
synced 2026-11-14 00:14:09 +00:00
172 lines
6.7 KiB
Java
172 lines
6.7 KiB
Java
package noppes.npcs.client.gui.util;
|
||||
|
|
|
|||
|
|
import net.minecraft.client.Minecraft;
|
|||
|
|
import net.minecraft.client.gui.FontRenderer;
|
|||
|
|
import net.minecraft.client.renderer.OpenGlHelper;
|
|||
|
|
import net.minecraft.util.ResourceLocation;
|
|||
|
|
import org.lwjgl.opengl.GL11;
|
|||
|
|
|
|||
|
|
public class GuiToggleButton extends GuiNpcButton {
|
|||
|
|
|
|||
|
|
// Fixed dimensions: 40x20 (even if other values are passed)
|
|||
|
|
private static final int FIXED_WIDTH = 40;
|
|||
|
|
private static final int FIXED_HEIGHT = 20;
|
|||
|
|
|
|||
|
|
private boolean toggled;
|
|||
|
|
// Animation progress: 0.0 = OFF (knob left), 1.0 = ON (knob right)
|
|||
|
|
private float animProgress;
|
|||
|
|
|
|||
|
|
// Optional off icon (if not set, the super class icon is used)
|
|||
|
|
private ResourceLocation textureOff = null;
|
|||
|
|
private int textureOffPosX = 0;
|
|||
|
|
private int textureOffPosY = 0;
|
|||
|
|
// Off icon always 16x16
|
|||
|
|
private static final int ICON_SIZE = 16;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Basic constructor. Uses the super class’s icon as the ON texture.
|
|||
|
|
* Note: The button is fixed at 40×20.
|
|||
|
|
*/
|
|||
|
|
public GuiToggleButton(int id, int x, int y, boolean initialState) {
|
|||
|
|
super(id, x, y, FIXED_WIDTH, FIXED_HEIGHT, "");
|
|||
|
|
this.toggled = initialState;
|
|||
|
|
this.animProgress = initialState ? 1.0f : 0.0f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Constructor with both an ON and OFF icon.
|
|||
|
|
* The ON icon is taken from the super class’s icon.
|
|||
|
|
*/
|
|||
|
|
public GuiToggleButton(int id, int x, int y, boolean initialState,
|
|||
|
|
ResourceLocation textureOn, ResourceLocation textureOff) {
|
|||
|
|
super(id, x, y, FIXED_WIDTH, FIXED_HEIGHT, "");
|
|||
|
|
this.setIconTexture(textureOn);
|
|||
|
|
this.toggled = initialState;
|
|||
|
|
this.animProgress = initialState ? 1.0f : 0.0f;
|
|||
|
|
this.textureOff = textureOff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Off icon setters
|
|||
|
|
public GuiToggleButton setTextureOff(ResourceLocation texture) {
|
|||
|
|
this.textureOff = texture;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public GuiToggleButton setTextureOffPos(int posX, int posY) {
|
|||
|
|
this.textureOffPosX = posX;
|
|||
|
|
this.textureOffPosY = posY;
|
|||
|
|
return this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Override
|
|||
|
|
public boolean mousePressed(Minecraft mc, int mouseX, int mouseY) {
|
|||
|
|
boolean pressed = super.mousePressed(mc, mouseX, mouseY);
|
|||
|
|
if (pressed) {
|
|||
|
|
toggled = !toggled;
|
|||
|
|
}
|
|||
|
|
return pressed;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@Override
|
|||
|
|
public void drawButton(Minecraft mc, int mouseX, int mouseY) {
|
|||
|
|
if (!this.visible)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
FontRenderer fontrenderer = mc.fontRenderer;
|
|||
|
|
// Bind vanilla button texture.
|
|||
|
|
mc.getTextureManager().bindTexture(buttonTextures);
|
|||
|
|
GL11.glColor4f(1F, 1F, 1F, 1F);
|
|||
|
|
|
|||
|
|
// Determine hover state (vanilla style)
|
|||
|
|
this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition &&
|
|||
|
|
mouseX < this.xPosition + FIXED_WIDTH && mouseY < this.yPosition + FIXED_HEIGHT;
|
|||
|
|
int k = this.getHoverState(this.field_146123_n);
|
|||
|
|
|
|||
|
|
GL11.glEnable(GL11.GL_BLEND);
|
|||
|
|
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
|
|||
|
|
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
|||
|
|
|
|||
|
|
// Update animation progress smoothly toward the target state.
|
|||
|
|
float target = toggled ? 1.0f : 0.0f;
|
|||
|
|
animProgress += (target - animProgress) * 0.2f;
|
|||
|
|
if (Math.abs(target - animProgress) < 0.01f)
|
|||
|
|
animProgress = target;
|
|||
|
|
|
|||
|
|
// Draw the two halves using the vanilla button drawing code.
|
|||
|
|
// Left half:
|
|||
|
|
GL11.glColor4f(1F, 1F, 1F, 1F);
|
|||
|
|
this.drawTexturedModalRect(this.xPosition, this.yPosition, 0, 46 + k * 20, FIXED_WIDTH / 2, FIXED_HEIGHT);
|
|||
|
|
// Right half:
|
|||
|
|
this.drawTexturedModalRect(this.xPosition + FIXED_WIDTH / 2, this.yPosition, 200 - FIXED_WIDTH / 2, 46 + k * 20, FIXED_WIDTH / 2, FIXED_HEIGHT);
|
|||
|
|
|
|||
|
|
// Determine which half is the non-head (static background) area.
|
|||
|
|
// When toggled ON, the knob (head) is on the right so non-head is the left half.
|
|||
|
|
// When toggled OFF, the knob is on the left so non-head is the right half.
|
|||
|
|
int nonHeadX, nonHeadWidth;
|
|||
|
|
if (animProgress > 0.5f) {
|
|||
|
|
// ON: knob on right, non-head = left half.
|
|||
|
|
nonHeadX = this.xPosition;
|
|||
|
|
nonHeadWidth = FIXED_WIDTH / 2;
|
|||
|
|
} else {
|
|||
|
|
// OFF: knob on left, non-head = right half.
|
|||
|
|
nonHeadX = this.xPosition + FIXED_WIDTH / 2;
|
|||
|
|
nonHeadWidth = FIXED_WIDTH / 2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Tint the non-head area darker.
|
|||
|
|
GL11.glColor4f(0.6f, 0.6f, 0.6f, 1.0F);
|
|||
|
|
// Redraw that half to simulate a darker tone.
|
|||
|
|
this.drawTexturedModalRect(nonHeadX, this.yPosition, 0, 46 + k * 20, nonHeadWidth, FIXED_HEIGHT);
|
|||
|
|
|
|||
|
|
// Now draw the knob ("head") that slides.
|
|||
|
|
// Knob width equals half of the button (20 pixels).
|
|||
|
|
int knobWidth = FIXED_WIDTH / 2;
|
|||
|
|
// The knob slides from xPosition (OFF) to xPosition + (FIXED_WIDTH - knobWidth) (ON).
|
|||
|
|
int knobX = this.xPosition + (int)((FIXED_WIDTH - knobWidth) * animProgress);
|
|||
|
|
int knobY = this.yPosition;
|
|||
|
|
|
|||
|
|
// Draw the knob with no tint.
|
|||
|
|
GL11.glColor4f(1F, 1F, 1F, 1F);
|
|||
|
|
this.drawTexturedModalRect(knobX, knobY, 0, 46 + k * 20, knobWidth / 2, FIXED_HEIGHT);
|
|||
|
|
this.drawTexturedModalRect(knobX + knobWidth / 2, knobY, 200 - knobWidth / 2, 46 + k * 20, knobWidth / 2, FIXED_HEIGHT);
|
|||
|
|
|
|||
|
|
// Draw the icon on the knob (always 16×16, centered on the knob).
|
|||
|
|
int iconX = knobX + (knobWidth - ICON_SIZE) / 2;
|
|||
|
|
int iconY = knobY + (FIXED_HEIGHT - ICON_SIZE) / 2;
|
|||
|
|
ResourceLocation iconTex;
|
|||
|
|
int texX, texY;
|
|||
|
|
// When ON, use the super class icon; when OFF, use textureOff if provided.
|
|||
|
|
if (toggled) {
|
|||
|
|
iconTex = this.iconTexture;
|
|||
|
|
texX = this.iconPosX;
|
|||
|
|
texY = this.iconPosY;
|
|||
|
|
} else {
|
|||
|
|
if (this.textureOff != null) {
|
|||
|
|
iconTex = this.textureOff;
|
|||
|
|
texX = this.textureOffPosX;
|
|||
|
|
texY = this.textureOffPosY;
|
|||
|
|
} else {
|
|||
|
|
iconTex = this.iconTexture;
|
|||
|
|
texX = this.iconPosX;
|
|||
|
|
texY = this.iconPosY;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (iconTex != null) {
|
|||
|
|
mc.getTextureManager().bindTexture(iconTex);
|
|||
|
|
GL11.glColor4f(1F, 1F, 1F, 1F);
|
|||
|
|
this.drawTexturedModalRect(iconX, iconY, texX, texY, ICON_SIZE, ICON_SIZE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Optionally, draw the centered display string (if needed).
|
|||
|
|
int textColor = 14737632;
|
|||
|
|
if (packedFGColour != 0) {
|
|||
|
|
textColor = packedFGColour;
|
|||
|
|
} else if (!this.enabled) {
|
|||
|
|
textColor = 10526880;
|
|||
|
|
} else if (this.field_146123_n) {
|
|||
|
|
textColor = 16777120;
|
|||
|
|
}
|
|||
|
|
this.drawCenteredString(fontrenderer, this.displayString, this.xPosition + FIXED_WIDTH / 2,
|
|||
|
|
this.yPosition + (FIXED_HEIGHT - 8) / 2, textColor);
|
|||
|
|
}
|
|||
|
|
}
|