diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorButton.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorButton.java deleted file mode 100644 index cdcf96db..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorButton.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.voxelmodpack.hdskins.gui; - -import static net.minecraft.client.renderer.GlStateManager.color; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.resources.I18n; - -/** - * Color picker button control, spawns a color picker when clicked. Code - * originally by Adam Mummery-Smith. - */ -public class GuiColorButton extends GuiButton { - - private Minecraft mc; - private int color = 0x000000; - private GuiColorPicker picker; - private boolean pickerClicked = false; - - public GuiColorButton(Minecraft minecraft, int id, int xPosition, int yPosition, int controlWidth, int controlHeight, int color, String name) { - super(id, xPosition, yPosition, controlWidth, controlHeight, I18n.format(name)); - this.mc = minecraft; - this.color = color; - } - - public int getColor() { - return this.color; - } - - @Override - public void drawButton(Minecraft mc, int mouseX, int mouseY) { - boolean mouseOver = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; - int borderColor = mouseOver || this.picker != null ? 0xFFFFFFFF : 0xFFA0A0A0; - - drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, borderColor); - - color(1.0F, 1.0F, 1.0F, 1.0F); - - drawRect(this.xPosition + 1, this.yPosition + 1, this.xPosition + this.width - 1, this.yPosition + this.height - 1, 0xFF000000 | this.color); - - this.mouseDragged(mc, mouseX, mouseY); - - if (this.displayString != null && this.displayString.length() > 0) { - int x = this.xPosition + this.width + 8; - int y = this.yPosition + (this.height - 8) / 2; - this.drawString(mc.fontRendererObj, this.displayString, x, y, this.enabled ? 0xFFFFFFFF : 0xFFA0A0A0); - } - } - - public void drawPicker(Minecraft minecraft, int mouseX, int mouseY) { - if (this.picker != null) { - this.picker.drawButton(minecraft, mouseX, mouseY); - - } - } - - public void closePicker(boolean getColor) { - if (getColor) - this.color = this.picker.getColor(); - this.picker = null; - this.pickerClicked = false; - } - - @Override - public void mouseReleased(int mouseX, int mouseY) { - if (this.pickerClicked && this.picker != null) { - this.picker.mouseReleased(mouseX, mouseY); - this.pickerClicked = false; - } - } - - @Override - public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { - boolean pressed = super.mousePressed(minecraft, mouseX, mouseY); - - if (this.picker == null) { - if (pressed) { - int xPos = Math.min(this.xPosition + this.width, mc.currentScreen.width - 233); - int yPos = Math.min(this.yPosition, mc.currentScreen.height - 175); - - this.picker = new GuiColorPicker(minecraft, 1, xPos, yPos, 0xFFFFFF & this.color, "Choose color"); - this.pickerClicked = false; - } - - return pressed; - } - - this.pickerClicked = this.picker.mousePressed(minecraft, mouseX, mouseY); - - if (pressed && !this.pickerClicked) { - this.closePicker(true); - } - - return this.pickerClicked; - } - - public boolean keyTyped(char keyChar, int keyCode) { - return (this.picker != null) ? this.picker.textBoxKeyTyped(keyChar, keyCode) : false; - } - -} \ No newline at end of file diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorPicker.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorPicker.java deleted file mode 100644 index 68ab8d1a..00000000 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiColorPicker.java +++ /dev/null @@ -1,311 +0,0 @@ -package com.voxelmodpack.hdskins.gui; - -import static net.minecraft.client.renderer.GlStateManager.*; -import static org.lwjgl.opengl.GL11.*; - -import java.awt.Color; -import java.awt.Rectangle; - -import org.apache.logging.log4j.core.helpers.Integers; -import org.lwjgl.input.Keyboard; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.gui.GuiTextField; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.GlStateManager.LogicOp; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.util.ResourceLocation; - -/** - * Color picker flyout control, for use with the designable GUI properties - * window. Code originally by Adam Mummery-Smith. - */ -public class GuiColorPicker extends GuiButton { - - public static final ResourceLocation COLORPICKER_PICKER = new ResourceLocation("hdskins", - "textures/gui/picker.png"); - - /** Indices into the HSB array. */ - private static final int H = 0, S = 1, B = 2; - - /** HSB values from Color.RGBtoHSB. */ - private float[] hsb; - - /** Original and altered RGB values. */ - private int rgb; - - /** Text boxes for manual entry. */ - private GuiTextField txtRed, txtGreen, txtBlue; - - // /** OK and cancel buttons. */ - // private GuiControl btnOk, btnCancel; - - /** Flags to track whether dragging a slider. */ - private boolean draggingHS, draggingB; - - /** Slider rectangles. */ - private Rectangle rectHSArea, rectBArea; - - /** Set when the user clicks ok or cancel. */ - // private DialogResult result = DialogResult.None; - - private FontRenderer fontRenderer; - - private Minecraft mc; - - public GuiColorPicker(Minecraft minecraft, int controlId, int xPos, int yPos, int initialColor, String displayText) { - super(controlId, xPos, yPos, displayText); - this.mc = minecraft; - Color color = new Color(initialColor); - this.hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); - - this.fontRenderer = minecraft.fontRendererObj; - this.txtRed = new GuiTextField(0, this.fontRenderer, this.xPosition + 163, this.yPosition + 10, 32, 16); - this.txtGreen = new GuiTextField(0, this.fontRenderer, this.xPosition + 163, this.yPosition + 30, 32, 16); - this.txtBlue = new GuiTextField(0, this.fontRenderer, this.xPosition + 163, this.yPosition + 50, 32, 16); - - this.txtRed.setMaxStringLength(3); - this.txtGreen.setMaxStringLength(3); - this.txtBlue.setMaxStringLength(3); - - this.rectHSArea = new Rectangle(this.xPosition + 10, this.yPosition + 10, 128, 128); - this.rectBArea = new Rectangle(this.xPosition + 143, this.yPosition + 10, 15, 128); - - // this.btnOk = - // new GuiControl(minecraft, 0, this.xPosition + 9, this.yPosition + - // 145, 55, 20, - // I18n.format("config.picker.ok")); - // this.btnCancel = - // new GuiControl(minecraft, 1, this.xPosition + 70, this.yPosition + - // 145, 65, 20, - // I18n.format("config.picker.cancel")); - - this.updateColor(); - } - - // public DialogResult getDialogResult() { - // return this.result; - // } - - public int getColor() { - int rgb = (0xFFFFFF & Color.HSBtoRGB(this.hsb[H], this.hsb[S], this.hsb[B])); - return rgb; - } - - protected void drawColorPicker(Minecraft minecraft, int mouseX, int mouseY) { - this.mouseDragged(minecraft, mouseX, mouseY); - - // Calculate coordinates for the selectors - int hPos = this.xPosition + 10 + (int) (128F * this.hsb[H]); - int sPos = this.yPosition + 10 + (128 - (int) (128F * this.hsb[S])); - int bPos = this.yPosition + 10 + (128 - (int) (128F * this.hsb[B])); - - // Calculate B color - int brightness = Color.HSBtoRGB(this.hsb[H], this.hsb[S], 1.0F) | 0xFF000000; - - // Draw backgrounds - // Background - drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, 0xAA000000); - // HS background - drawRect(this.xPosition + 9, this.yPosition + 9, this.xPosition + 139, this.yPosition + 139, 0xFFA0A0A0); - // B background - drawRect(this.xPosition + 142, this.yPosition + 9, this.xPosition + 159, this.yPosition + 139, 0xFFA0A0A0); - // Preview background - drawRect(this.xPosition + 162, this.yPosition + 105, this.xPosition + 196, this.yPosition + 139, 0xFFA0A0A0); - - // Draw color picker - this.mc.getTextureManager().bindTexture(GuiColorPicker.COLORPICKER_PICKER); - color(1.0F, 1.0F, 1.0F, 1.0F); - drawScaledCustomSizeModalRect(this.xPosition + 10, this.yPosition + 10, 0, 0, 256, 256, 138, 138, 256, 256); - this.drawCrossHair(hPos, sPos, 5, 1, 0xFF000000); - - // Draw brightness bar - this.drawGradientRect(this.xPosition + 143, this.yPosition + 10, this.xPosition + 158, this.yPosition + 138, brightness, 0xFF000000); - this.drawRotText(this.fontRenderer, "Luminosity", this.xPosition + 150, this.yPosition + 74, 0xFF000000, false); - drawRect(this.xPosition + 142, bPos - 1, this.xPosition + 159, bPos + 1, 0xFFFFFFFF); - - // Draw preview - drawRect(this.xPosition + 163, this.yPosition + 106, this.xPosition + 195, this.yPosition + 138, 0xFF000000 | this.rgb); - - // Draw text boxes - this.txtRed.drawTextBox(); - this.txtGreen.drawTextBox(); - this.txtBlue.drawTextBox(); - - // this.btnOk.drawButton(minecraft, mouseX, mouseY); - // this.btnCancel.drawButton(minecraft, mouseX, mouseY); - } - - private void drawCrossHair(int x, int y, int size, int width, int color) { - float alpha = (color >> 24 & 0xff) / 255F; - float red = (color >> 16 & 0xff) / 255F; - float green = (color >> 8 & 0xff) / 255F; - float blue = (color & 0xff) / 255F; - - GlStateManager.glLineWidth(mc.gameSettings.guiScale * width); - blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - enableBlend(); - disableTexture2D(); - disableLighting(); - color(red, green, blue, alpha); - enableColorLogic(); - colorLogicOp(LogicOp.OR_REVERSE); - - // Draw the frame - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer vb = tessellator.getBuffer(); - - vb.begin(GL_LINES, DefaultVertexFormats.POSITION); - vb.pos(x - size, y, 0).endVertex(); - vb.pos(x + size, y, 0).endVertex(); - tessellator.draw(); - - vb.begin(GL_LINES, DefaultVertexFormats.POSITION); - vb.pos(x, y - size, 0).endVertex(); - vb.pos(x, y + size, 0).endVertex(); - tessellator.draw(); - - disableColorLogic(); - enableTexture2D(); - } - - private void drawRotText(FontRenderer fontRenderer, String text, int xPosition, int yPosition, - int color, boolean colorOrOp) { - if (colorOrOp) { - enableColorLogic(); - colorLogicOp(GL_OR_REVERSE); - } - - int textWidth = fontRenderer.getStringWidth(text) / 2; - - pushMatrix(); - translate(xPosition, yPosition, 0); - rotate(-90, 0, 0, 1); - translate(-textWidth, -4, 0); - - fontRenderer.drawString(text, 0, 0, color); - - popMatrix(); - - if (colorOrOp) { - disableColorLogic(); - enableTexture2D(); - } - } - - public void updateCursorCounter() { - this.txtRed.updateCursorCounter(); - this.txtGreen.updateCursorCounter(); - this.txtBlue.updateCursorCounter(); - } - - protected void updateColor() { - this.rgb = (0xFFFFFF & Color.HSBtoRGB(this.hsb[H], this.hsb[S], this.hsb[B])); - this.txtRed.setText(String.valueOf((this.rgb >> 16) & 0xFF)); - this.txtGreen.setText(String.valueOf((this.rgb >> 8) & 0xFF)); - this.txtBlue.setText(String.valueOf(this.rgb & 0xFF)); - } - - protected void updateColorFromTextEntry() { - int currentRed = (this.rgb >> 16) & 0xFF; - int currentGreen = (this.rgb >> 8) & 0xFF; - int currentBlue = this.rgb & 0xFF; - - currentRed = (int) clamp(tryParseInt(this.txtRed.getText(), currentRed), 0, 255); - currentGreen = (int) clamp(tryParseInt(this.txtGreen.getText(), currentGreen), 0, 255); - currentBlue = (int) clamp(tryParseInt(this.txtBlue.getText(), currentBlue), 0, 255); - - this.hsb = Color.RGBtoHSB(currentRed, currentGreen, currentBlue, null); - this.updateColor(); - } - - @Override - protected void mouseDragged(Minecraft minecraft, int mouseX, int mouseY) { - super.mouseDragged(minecraft, mouseX, mouseY); - - if (this.draggingHS) { - this.hsb[H] = clamp(mouseX - this.xPosition - 10, 0, 128) / 128F; - this.hsb[S] = (128F - clamp(mouseY - this.yPosition - 10, 0, 128)) / 128F; - this.updateColor(); - } - - if (this.draggingB) { - this.hsb[B] = (128F - clamp(mouseY - this.yPosition - 10, 0, 128)) / 128F; - this.updateColor(); - } - - } - - @Override - public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { - if (super.mousePressed(minecraft, mouseX, mouseY)) { - - // if (this.btnOk.mousePressed(minecraft, mouseX, mouseY)) - // this.result = DialogResult.OK; - // - // if (this.btnCancel.mousePressed(minecraft, mouseX, mouseY)) - // this.result = DialogResult.Cancel; - - if (this.rectHSArea.contains(mouseX, mouseY)) - this.draggingHS = true; - - if (this.rectBArea.contains(mouseX, mouseY)) - this.draggingB = true; - - this.txtRed.mouseClicked(mouseX, mouseY, 0); - this.txtGreen.mouseClicked(mouseX, mouseY, 0); - this.txtBlue.mouseClicked(mouseX, mouseY, 0); - - return true; - } - - return false; - } - - @Override - public void mouseReleased(int mouseX, int mouseY) { - this.draggingHS = false; - this.draggingB = false; - } - - public boolean textBoxKeyTyped(char keyChar, int keyCode) { - this.txtRed.textboxKeyTyped(keyChar, keyCode); - this.txtGreen.textboxKeyTyped(keyChar, keyCode); - this.txtBlue.textboxKeyTyped(keyChar, keyCode); - this.updateColorFromTextEntry(); - - if (keyCode == Keyboard.KEY_TAB) { - if (this.txtRed.isFocused()) { - this.txtRed.setFocused(false); - this.txtGreen.setFocused(true); - this.txtBlue.setFocused(false); - } else if (this.txtGreen.isFocused()) { - this.txtRed.setFocused(false); - this.txtGreen.setFocused(false); - this.txtBlue.setFocused(true); - } else if (this.txtBlue.isFocused()) { - this.txtRed.setFocused(false); - this.txtGreen.setFocused(false); - this.txtBlue.setFocused(false); - } else { - this.txtRed.setFocused(true); - this.txtGreen.setFocused(false); - this.txtBlue.setFocused(false); - } - } - - return true; - } - - private static int tryParseInt(String text, int defaultValue) { - return "".equals(text) ? 0 : Integers.parseInt(text, defaultValue); - } - - private static float clamp(float value, float min, float max) { - return Math.min(Math.max(value, min), max); - } -} \ No newline at end of file diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiMetaHandler.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiMetaHandler.java index c240c30a..fcea0e73 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiMetaHandler.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/GuiMetaHandler.java @@ -25,6 +25,9 @@ import com.mumfrey.webprefs.WebPreferencesManager; import com.mumfrey.webprefs.interfaces.IWebPreferences; import com.voxelmodpack.hdskins.HDSkinManager; import com.voxelmodpack.hdskins.IMetaHandler; +import com.voxelmodpack.hdskins.gui.color.GuiColorButton; +import com.voxelmodpack.hdskins.gui.color.GuiColorButton.CloseListener; +import com.voxelmodpack.hdskins.gui.color.GuiControl; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; @@ -33,6 +36,7 @@ import net.minecraft.client.gui.GuiPageButtonList.GuiResponder; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiSlider; import net.minecraft.client.gui.GuiSlider.FormatHelper; +import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.resources.I18n; @@ -46,6 +50,7 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { protected int optionPosX; private EntityPlayerModel model; + private float updateCounter; public GuiMetaHandler(GuiScreen parent, EntityPlayerModel localPlayer) { this.parent = parent; @@ -80,6 +85,13 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { return Optional.absent(); } + @Override + public void setWorldAndResolution(Minecraft mc, int width, int height) { + super.setWorldAndResolution(mc, width, height); + ScaledResolution sr = new ScaledResolution(mc); + GuiControl.setScreenSizeAndScale(width, height, sr.getScaleFactor()); + } + @Override public void initGui() { super.initGui(); @@ -113,15 +125,14 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { if (keyCode == Keyboard.KEY_ESCAPE) { mc.displayGuiScreen(parent); } else { - super.keyTyped(typedChar, keyCode); + for (Opt opt : this.options) { + opt.keyTyped(typedChar, keyCode); + } } } - private float updateCounter; - @Override public void drawScreen(int mouseX, int mouseY, float partialTick) { - // this.lastPartialTick = this.updateCounter + partialTick; this.drawDefaultBackground(); int top = 30; @@ -139,11 +150,11 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { disableBlend(); ((GuiSkins) parent).disableClipping(); + this.drawCenteredString(this.fontRendererObj, "Skin Overrides", width / 2, 10, -1); super.drawScreen(mouseX, mouseY, partialTick); for (Opt opt : options) { opt.drawOption(mouseX, mouseY); } - this.drawCenteredString(this.fontRendererObj, "Skin Overrides", width / 2, 10, -1); } public void renderPlayerModel(Entity thePlayer, float xPosition, float yPosition, float scale, float mouseX, float mouseY, float partialTick) { @@ -178,9 +189,7 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { if (mouseX > width / 2) this.model.swingArm(); for (Opt opt : options) { - if (opt.mouseClicked(mouseX, mouseY)) - break; - + opt.mouseClicked(mouseX, mouseY); } } @@ -200,6 +209,15 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { } } + public void setControlsEnabled(boolean enabled) { + for (Opt opt : this.options) { + opt.setControlEnabled(enabled); + } + for (GuiButton guiButton : buttonList) { + guiButton.enabled = enabled; + } + } + public void push() { String data = new Gson().toJson(toMap()); @@ -257,6 +275,10 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { this.enabled.checked = enabled; } + public void setControlEnabled(boolean enabled) { + this.enabled.enabled = enabled; + } + public boolean isEnabled() { return this.enabled.checked; } @@ -269,18 +291,20 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { this.enabled.drawButton(mc, mouseX, mouseY); } - protected boolean mouseClicked(int mouseX, int mouseY) { + protected void mouseClicked(int mouseX, int mouseY) { if (this.enabled.mousePressed(mc, mouseX, mouseY)) { this.enabled.checked = !this.enabled.checked; - return true; } - return false; } protected void mouseReleased(int mouseX, int mouseY) { } + protected void keyTyped(char typedChar, int keyCode) { + + } + @Override public abstract String toString(); @@ -295,6 +319,12 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { super(name); } + @Override + public void setControlEnabled(boolean enabled) { + super.setControlEnabled(enabled); + this.chk.enabled = enabled; + } + @Override public void init() { super.init(); @@ -310,13 +340,11 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { } @Override - protected boolean mouseClicked(int mouseX, int mouseY) { - boolean clicked = super.mouseClicked(mouseX, mouseY); - if (!clicked && chk.mousePressed(mc, mouseX, mouseY)) { + protected void mouseClicked(int mouseX, int mouseY) { + super.mouseClicked(mouseX, mouseY); + if (chk.mousePressed(mc, mouseX, mouseY)) { chk.checked = !chk.checked; - return true; } - return clicked; } @Override @@ -344,6 +372,12 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { this.value = Optional.of(min); } + @Override + public void setControlEnabled(boolean enabled) { + super.setControlEnabled(enabled); + this.guiSlider.enabled = enabled; + } + @Override public void init() { super.init(); @@ -358,9 +392,9 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { } @Override - protected boolean mouseClicked(int mouseX, int mouseY) { - boolean clicked = super.mouseClicked(mouseX, mouseY); - return clicked || this.guiSlider.mousePressed(mc, mouseX, mouseY); + protected void mouseClicked(int mouseX, int mouseY) { + super.mouseClicked(mouseX, mouseY); + this.guiSlider.mousePressed(mc, mouseX, mouseY); } @Override @@ -412,6 +446,12 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { this.value = Optional.of(this.get()); } + @Override + public void setControlEnabled(boolean enabled) { + super.setControlEnabled(enabled); + this.button.enabled = enabled; + } + @Override protected void init() { super.init(); @@ -426,18 +466,16 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { } @Override - protected boolean mouseClicked(int mouseX, int mouseY) { - boolean clicked = super.mouseClicked(mouseX, mouseY); - if (!clicked && this.button.mousePressed(mc, mouseX, mouseY)) { + protected void mouseClicked(int mouseX, int mouseY) { + super.mouseClicked(mouseX, mouseY); + if (this.button.mousePressed(mc, mouseX, mouseY)) { this.index++; if (this.index >= this.options.size()) { this.index = 0; } this.value = Optional.of(get()); this.button.displayString = name + ": " + I18n.format(this.toString()); - return true; } - return clicked; } private E get() { @@ -458,7 +496,7 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { } - private class Col extends Opt { + private class Col extends Opt implements CloseListener { private GuiColorButton color; @@ -482,23 +520,29 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { @Override protected void init() { super.init(); - this.color = new GuiColorButton(mc, 0, optionPosX + 20, optionHeight, 20, 20, value.transform(colorConverter).or(-1), name); + this.color = new GuiColorButton(mc, 0, optionPosX + 20, optionHeight, 20, 20, value.get(), name, this); + } + + @Override + public void onClose() { + this.value = Optional.of(new Color(this.color.getColor())); + setControlsEnabled(true); } @Override protected void drawOption(int mouseX, int mouseY) { super.drawOption(mouseX, mouseY); this.color.drawButton(mc, mouseX, mouseY); + this.color.drawPicker(mc, mouseX, mouseY); + } @Override - protected boolean mouseClicked(int mouseX, int mouseY) { - boolean clicked = super.mouseClicked(mouseX, mouseY); - if (!clicked && this.color.mousePressed(mc, mouseX, mouseY)) { - this.value = Optional.of(new Color(this.color.getColor())); - return true; + protected void mouseClicked(int mouseX, int mouseY) { + super.mouseClicked(mouseX, mouseY); + if (this.color.mousePressed(mc, mouseX, mouseY)) { + setControlsEnabled(false); } - return clicked; } @Override @@ -506,9 +550,14 @@ public class GuiMetaHandler extends GuiScreen implements IMetaHandler { this.color.mouseReleased(mouseX, mouseY); } + @Override + protected void keyTyped(char typedChar, int keyCode) { + this.color.keyTyped(typedChar, keyCode); + } + @Override public String toString() { - return this.value.transform(Functions.toStringFunction()).orNull(); + return this.value.transform(colorConverter).transform(Functions.toStringFunction()).orNull(); } @Override diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java index c1d205d3..bfc61d6e 100644 --- a/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/RenderPlayerModel.java @@ -5,7 +5,6 @@ import static net.minecraft.client.renderer.GlStateManager.*; import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; -import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelPlayer; import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.client.renderer.entity.RenderManager; diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorButton.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorButton.java new file mode 100644 index 00000000..34a4e9f2 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorButton.java @@ -0,0 +1,133 @@ +package com.voxelmodpack.hdskins.gui.color; + +import static com.mumfrey.liteloader.gl.GL.glColor4f; + +import java.awt.Color; + +import net.minecraft.client.Minecraft; + +/** + * Colour picker button control, spawns a colour picker when clicked + * + * @author Adam Mummery-Smith + */ +public class GuiColorButton extends GuiControl { + /** + * Picker active colour + */ + private int colour = 0xFF000000; + + private Color lineColour; + + private GuiColorPicker picker; + + private boolean pickerClicked = false; + private CloseListener closeListener; + + public GuiColorButton(Minecraft minecraft, int id, int xPosition, int yPosition, int controlWidth, int controlHeight, Color lineColour, String name, CloseListener cl) { + super(minecraft, id, xPosition, yPosition, controlWidth, controlHeight, name); + this.lineColour = lineColour; + this.updateColour(lineColour); + this.closeListener = cl; + } + + /** + * @param lineColour2 + */ + public void updateColour(Color lineColour2) { + if (lineColour2 == this.lineColour) { + this.colour = lineColour2.getRGB(); + } + } + + public int getColor() { + return this.colour; + } + + @Override + public void drawControl(Minecraft minecraft, int mouseX, int mouseY) { + if (this.visible) { + + if (this.displayString != null && this.displayString.length() > 0) { + this.drawString(minecraft.fontRendererObj, this.displayString, this.xPosition + this.width + 8, this.yPosition + (this.height - 8) / 2, 0xFFFFFFFF); + } + boolean mouseOver = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; + int borderColour = mouseOver || this.picker != null ? 0xFFFFFFFF : 0xFFA0A0A0; + + drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, borderColour); + + int v = Math.min(Math.max((int) (((float) this.height / (float) this.width) * 1024F), 256), 1024); + + minecraft.getTextureManager().bindTexture(GuiColorPicker.COLOURPICKER_CHECKER); + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(this.xPosition + 1, this.yPosition + 1, this.xPosition + this.width - 1, this.yPosition + this.height - 1, 0, 0, 1024, v); + + drawRect(this.xPosition + 1, this.yPosition + 1, this.xPosition + this.width - 1, this.yPosition + this.height - 1, this.colour); + + this.mouseDragged(minecraft, mouseX, mouseY); + + } + } + + public void drawPicker(Minecraft minecraft, int mouseX, int mouseY) { + if (this.visible && this.picker != null) { + this.picker.drawButton(minecraft, mouseX, mouseY); + + if (this.picker.getDialogResult() == DialogResult.OK) { + this.closePicker(true); + } else if (this.picker.getDialogResult() == DialogResult.Cancel) { + this.closePicker(false); + } + } + } + + public void closePicker(boolean getColour) { + if (getColour) + this.colour = this.picker.getColour(); + this.picker = null; + this.pickerClicked = false; + if (this.closeListener != null) + this.closeListener.onClose(); + } + + @Override + public void mouseReleased(int mouseX, int mouseY) { + if (this.pickerClicked && this.picker != null) { + this.picker.mouseReleased(mouseX, mouseY); + this.pickerClicked = false; + } + } + + @Override + public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { + boolean pressed = super.mousePressed(minecraft, mouseX, mouseY); + + if (this.picker == null) { + if (pressed) { + int xPos = Math.min(this.xPosition + this.width, GuiControl.lastScreenWidth - 233); + int yPos = Math.min(this.yPosition, GuiControl.lastScreenHeight - 175); + + this.picker = new GuiColorPicker(minecraft, 1, xPos, yPos, this.colour, "Choose colour"); + this.pickerClicked = false; + } + + return pressed; + } + + this.pickerClicked = this.picker.mousePressed(minecraft, mouseX, mouseY); + + if (pressed && !this.pickerClicked) { + this.closePicker(true); + } + + return this.pickerClicked; + } + + public boolean keyTyped(char keyChar, int keyCode) { + return (this.picker != null) ? this.picker.textBoxKeyTyped(keyChar, keyCode) : false; + } + + public interface CloseListener { + void onClose(); + } +} \ No newline at end of file diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorPicker.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorPicker.java new file mode 100644 index 00000000..d4af94c9 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiColorPicker.java @@ -0,0 +1,323 @@ +package com.voxelmodpack.hdskins.gui.color; + +import static net.minecraft.client.renderer.GlStateManager.*; + +import java.awt.Color; +import java.awt.Rectangle; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiTextField; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.input.Keyboard; + +/** + * Colour picker flyout control, for use with the designable GUI properties + * window + * + * @author Adam Mummery-Smith + */ +public class GuiColorPicker extends GuiControl { + public static final ResourceLocation COLOURPICKER_CHECKER = new ResourceLocation("hdskins", "textures/gui/checker.png"); + public static final ResourceLocation COLOURPICKER_PICKER = new ResourceLocation("hdskins", "textures/gui/picker.png"); + + /** + * Indices into the hsb array + */ + private static final int H = 0, S = 1, B = 2; + + /** + * HSB values from Colour.RGBtoHSB, combined with opacity this is the + * authoritative version of the colour we are editing + */ + private float[] hsb; + + /** + * Original and altered RGB values + */ + private int rgb; + + /** + * Current opacity, stored as an offset byte in the usual position, eg. 0xFF + * << 24 + */ + private int opacity; + + /** + * Text boxes for manual entry + */ + private GuiTextField txtRed, txtGreen, txtBlue, txtAlpha; + + /** + * OK and cancel buttons + */ + private GuiControl btnOk, btnCancel; + + /** + * Flags to track whether dragging a slider + */ + private boolean draggingHS, draggingB, draggingA; + + /** + * Slider rects + */ + private Rectangle rectHSArea, rectBArea, rectAArea; + + /** + * Set when the user clicks ok or cancel + */ + private DialogResult result = DialogResult.None; + + private FontRenderer fontRenderer; + + public GuiColorPicker(Minecraft minecraft, int controlId, int xPos, int yPos, int initialColour, String displayText) { + super(minecraft, controlId, xPos, yPos, 231, 173, displayText); + + Color colour = new Color(initialColour); + this.hsb = Color.RGBtoHSB(colour.getRed(), colour.getGreen(), colour.getBlue(), null); + this.opacity = initialColour & 0xFF000000; + if (this.opacity == 0x01000000) + this.opacity = 0; + + this.fontRenderer = minecraft.fontRendererObj; + this.txtRed = new GuiTextField(0, this.fontRenderer, this.xPosition + 188, this.yPosition + 10, 32, 16); + this.txtGreen = new GuiTextField(1, this.fontRenderer, this.xPosition + 188, this.yPosition + 30, 32, 16); + this.txtBlue = new GuiTextField(2, this.fontRenderer, this.xPosition + 188, this.yPosition + 50, 32, 16); + this.txtAlpha = new GuiTextField(3, this.fontRenderer, this.xPosition + 188, this.yPosition + 70, 32, 16); + + this.txtRed.setMaxStringLength(3); + this.txtGreen.setMaxStringLength(3); + this.txtBlue.setMaxStringLength(3); + this.txtAlpha.setMaxStringLength(3); + + this.rectHSArea = new Rectangle(this.xPosition + 10, this.yPosition + 10, 128, 128); + this.rectBArea = new Rectangle(this.xPosition + 143, this.yPosition + 10, 15, 128); + this.rectAArea = new Rectangle(this.xPosition + 163, this.yPosition + 10, 15, 128); + + this.btnOk = new GuiControl(minecraft, 0, this.xPosition + 9, this.yPosition + 145, 55, 20, I18n.format("gui.ok")); + this.btnCancel = new GuiControl(minecraft, 1, this.xPosition + 70, this.yPosition + 145, 65, 20, I18n.format("gui.cancel")); + + this.updateColour(); + } + + public DialogResult getDialogResult() { + return this.result; + } + + public int getColour() { + int opacity = this.opacity == 0 ? 0x01000000 : this.opacity; + int rgb = opacity | (0xFFFFFF & Color.HSBtoRGB(this.hsb[H], this.hsb[S], this.hsb[B])); + return rgb; + } + + @Override + protected void drawControl(Minecraft minecraft, int mouseX, int mouseY) { + this.mouseDragged(minecraft, mouseX, mouseY); + + // Calculate coordinates for the selectors + int hPos = this.xPosition + 10 + (int) (128F * this.hsb[H]); + int sPos = this.yPosition + 10 + (128 - (int) (128F * this.hsb[S])); + int bPos = this.yPosition + 10 + (128 - (int) (128F * this.hsb[B])); + int aPos = this.yPosition + 10 + ((256 - ((this.opacity >> 24) & 0xFF)) / 2); + + // Calculate B colour + int brightness = Color.HSBtoRGB(this.hsb[H], this.hsb[S], 1.0F) | 0xFF000000; + + // Draw backgrounds + drawRect(this.xPosition, this.yPosition, this.xPosition + this.width, this.yPosition + this.height, 0xAA000000); // Background + drawRect(this.xPosition + 9, this.yPosition + 9, this.xPosition + 139, this.yPosition + 139, 0xFFA0A0A0); // HS + // background + drawRect(this.xPosition + 142, this.yPosition + 9, this.xPosition + 159, this.yPosition + 139, 0xFFA0A0A0); // B + // background + drawRect(this.xPosition + 162, this.yPosition + 9, this.xPosition + 179, this.yPosition + 139, 0xFFA0A0A0); // A + // background + drawRect(this.xPosition + 187, this.yPosition + 105, this.xPosition + 221, this.yPosition + 139, 0xFFA0A0A0); // Preview + // background + + // Draw colour picker + this.mc.getTextureManager().bindTexture(GuiColorPicker.COLOURPICKER_PICKER); + color(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(this.xPosition + 10, this.yPosition + 10, this.xPosition + 138, this.yPosition + 138, 0, 0, 256, 256); + this.drawCrossHair(hPos, sPos, 5, 1, 0xFF000000); + + // Draw brightness bar + this.drawGradientRect(this.xPosition + 143, this.yPosition + 10, this.xPosition + 158, this.yPosition + 138, brightness, 0xFF000000); + this.drawRotText(this.fontRenderer, "Luminosity", this.xPosition + 150, this.yPosition + 74, 0xFF000000, false); + drawRect(this.xPosition + 142, bPos - 1, this.xPosition + 159, bPos + 1, 0xFFFFFFFF); + + // Draw opacity bar + this.drawGradientRect(this.xPosition + 163, this.yPosition + 10, this.xPosition + 178, this.yPosition + 138, 0xFFFFFFFF, 0xFF000000); + this.drawRotText(this.fontRenderer, "Opacity", this.xPosition + 170, this.yPosition + 74, 0xFF000000, false); + drawRect(this.xPosition + 162, aPos - 1, this.xPosition + 179, aPos + 1, 0xFFFFFFFF); + + // Draw preview + this.mc.getTextureManager().bindTexture(GuiColorPicker.COLOURPICKER_CHECKER); + color(1.0F, 1.0F, 1.0F, 1.0F); + this.drawTexturedModalRect(this.xPosition + 188, this.yPosition + 106, this.xPosition + 220, this.yPosition + 138, 0, 0, 1024, 1024); + drawRect(this.xPosition + 188, this.yPosition + 106, this.xPosition + 220, this.yPosition + 138, this.rgb); + + // Draw text boxes + this.txtRed.drawTextBox(); + this.txtGreen.drawTextBox(); + this.txtBlue.drawTextBox(); + this.txtAlpha.drawTextBox(); + + this.btnOk.drawButton(minecraft, mouseX, mouseY); + this.btnCancel.drawButton(minecraft, mouseX, mouseY); + } + + public void updateCursorCounter() { + this.txtRed.updateCursorCounter(); + this.txtGreen.updateCursorCounter(); + this.txtBlue.updateCursorCounter(); + this.txtAlpha.updateCursorCounter(); + } + + protected void updateColour() { + this.rgb = this.opacity | (0xFFFFFF & Color.HSBtoRGB(this.hsb[H], this.hsb[S], this.hsb[B])); + this.txtRed.setText(String.valueOf((this.rgb >> 16) & 0xFF)); + this.txtGreen.setText(String.valueOf((this.rgb >> 8) & 0xFF)); + this.txtBlue.setText(String.valueOf(this.rgb & 0xFF)); + this.txtAlpha.setText(String.valueOf((this.opacity >> 24) & 0xFF)); + } + + protected void updateColourFromTextEntry() { + int currentRed = (this.rgb >> 16) & 0xFF; + int currentGreen = (this.rgb >> 8) & 0xFF; + int currentBlue = this.rgb & 0xFF; + int currentOpacity = (this.opacity >> 24) & 0xFF; + + currentRed = (int) clamp(this.tryParseInt(this.txtRed.getText(), currentRed), 0, 255); + currentGreen = (int) clamp(this.tryParseInt(this.txtGreen.getText(), currentGreen), 0, 255); + currentBlue = (int) clamp(this.tryParseInt(this.txtBlue.getText(), currentBlue), 0, 255); + currentOpacity = (int) clamp(this.tryParseInt(this.txtAlpha.getText(), currentOpacity), 0, 255); + + this.hsb = Color.RGBtoHSB(currentRed, currentGreen, currentBlue, null); + this.opacity = (currentOpacity << 24) & 0xFF000000; + this.updateColour(); + } + + protected int tryParseInt(String text, int defaultValue) { + try { + return Integer.parseInt(text); + } catch (Exception ex) { + return "".equals(text) ? 0 : defaultValue; + } + } + + /* + * (non-Javadoc) + * @see + * net.minecraft.src.GuiButton#mouseDragged(net.minecraft.src.Minecraft, + * int, int) + */ + @Override + protected void mouseDragged(Minecraft minecraft, int mouseX, int mouseY) { + super.mouseDragged(minecraft, mouseX, mouseY); + + if (this.draggingHS) { + this.hsb[H] = clamp(mouseX - this.xPosition - 10, 0, 128) / 128F; + this.hsb[S] = (128F - clamp(mouseY - this.yPosition - 10, 0, 128)) / 128F; + this.updateColour(); + } + + if (this.draggingB) { + this.hsb[B] = (128F - clamp(mouseY - this.yPosition - 10, 0, 128)) / 128F; + this.updateColour(); + } + + if (this.draggingA) { + this.opacity = (mouseY - this.yPosition < 11) ? 0xFF000000 : (((128 - (int) clamp(mouseY - this.yPosition - 10, 0, 128)) << 25) & 0xFF000000); + this.updateColour(); + } + } + + /* + * (non-Javadoc) + * @see + * net.minecraft.src.GuiButton#mousePressed(net.minecraft.src.Minecraft, + * int, int) + */ + @Override + public boolean mousePressed(Minecraft minecraft, int mouseX, int mouseY) { + if (super.mousePressed(minecraft, mouseX, mouseY)) { + + if (this.btnOk.mousePressed(minecraft, mouseX, mouseY)) + this.result = DialogResult.OK; + + if (this.btnCancel.mousePressed(minecraft, mouseX, mouseY)) + this.result = DialogResult.Cancel; + + if (this.rectHSArea.contains(mouseX, mouseY)) + this.draggingHS = true; + + if (this.rectBArea.contains(mouseX, mouseY)) + this.draggingB = true; + + if (this.rectAArea.contains(mouseX, mouseY)) + this.draggingA = true; + + this.txtRed.mouseClicked(mouseX, mouseY, 0); + this.txtGreen.mouseClicked(mouseX, mouseY, 0); + this.txtBlue.mouseClicked(mouseX, mouseY, 0); + this.txtAlpha.mouseClicked(mouseX, mouseY, 0); + + return true; + } else if (this.enabled) { + this.result = DialogResult.Cancel; + } + + return false; + } + + /* + * (non-Javadoc) + * @see net.minecraft.src.GuiButton#mouseReleased(int, int) + */ + @Override + public void mouseReleased(int mouseX, int mouseY) { + this.draggingHS = false; + this.draggingB = false; + this.draggingA = false; + } + + public boolean textBoxKeyTyped(char keyChar, int keyCode) { + this.txtRed.textboxKeyTyped(keyChar, keyCode); + this.txtGreen.textboxKeyTyped(keyChar, keyCode); + this.txtBlue.textboxKeyTyped(keyChar, keyCode); + this.txtAlpha.textboxKeyTyped(keyChar, keyCode); + this.updateColourFromTextEntry(); + + if (keyCode == Keyboard.KEY_TAB) { + if (this.txtRed.isFocused()) { + this.txtRed.setFocused(false); + this.txtGreen.setFocused(true); + this.txtBlue.setFocused(false); + this.txtAlpha.setFocused(false); + } else if (this.txtGreen.isFocused()) { + this.txtRed.setFocused(false); + this.txtGreen.setFocused(false); + this.txtBlue.setFocused(true); + this.txtAlpha.setFocused(false); + } else if (this.txtBlue.isFocused()) { + this.txtRed.setFocused(false); + this.txtGreen.setFocused(false); + this.txtBlue.setFocused(false); + this.txtAlpha.setFocused(true); + } else { + this.txtRed.setFocused(true); + this.txtGreen.setFocused(false); + this.txtBlue.setFocused(false); + this.txtAlpha.setFocused(false); + } + } + + return true; + } + + public static float clamp(float value, float min, float max) { + return Math.min(Math.max(value, min), max); + } +} \ No newline at end of file diff --git a/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiControl.java b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiControl.java new file mode 100644 index 00000000..85f2f0f0 --- /dev/null +++ b/src/hdskins/java/com/voxelmodpack/hdskins/gui/color/GuiControl.java @@ -0,0 +1,631 @@ +package com.voxelmodpack.hdskins.gui.color; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.VertexBuffer; +import static com.mumfrey.liteloader.gl.GL.*; + +/** + * GuiControlEx is the base class for additional controls. It includes some + * advanced drawing methods which are used by several derived classes + * + * @author Adam Mummery-Smith + */ +public class GuiControl extends GuiButton { + /** + * Used by some controls to indicate the manner in which they have handled a + * keypress + */ + public enum KeyHandledState { + /** + * The control did not handle the keypress + */ + None, + + /** + * The control handled the keypress and the container should do no + * further processing + */ + Handled, + + /** + * The control handled the keypress and the container should call + * actionPerformed + */ + ActionPerformed; + } + + public enum DialogResult { + /** + * No result (maybe the dialog was not closed yet?) + */ + None, + + /** + * Dialog result OK (user clicked OK or pressed RETURN) + */ + OK, + + /** + * Dialog result Cancel (user clicked Cancel or pressed ESCAPE) + */ + Cancel, + + Yes, + + No + } + + /** + * Set by parent screen to enable cursor flash etc + */ + public int updateCounter; + + /** + * Reference to the minecraft game instance + */ + protected Minecraft mc; + + /** + * Flag indicating whether an action was performed, to support GuiScreenEx's + * callback mechanism + */ + protected boolean actionPerformed; + + /** + * Flag tracking whether an item was double-clicked + */ + protected boolean doubleClicked; + + /** + * Scale factor which translates texture pixel coordinates to relative + * coordinates + */ + protected static float texMapScale = 0.00390625F; + + protected static float guiScaleFactor; + + protected static int lastScreenWidth; + protected static int lastScreenHeight; + + /** + * Override from GuiButton, handle this call and forward it to DrawControl + * for neatness + * + * @param minecraft Reference to the minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + @Override + public final void drawButton(Minecraft minecraft, int mouseX, int mouseY) { + this.drawControl(minecraft, mouseX, mouseY); + } + + /** + * Draw the control + * + * @param minecraft Reference to the minecraft game instance + * @param mouseX Mouse X coordinate + * @param mouseY Mouse Y coordinate + */ + protected void drawControl(Minecraft minecraft, int mouseX, int mouseY) { + super.drawButton(minecraft, mouseX, mouseY); + } + + /** + * Constructor, passes through to GuiButton constructor + * + * @param minecraft Minecraft game instance + * @param controlId Control's ID (used for actionPerformed) + * @param xPos Control X position (left) + * @param yPos Control Y position (top) + * @param controlWidth Control width + * @param controlHeight Control height + * @param displayText Control display text + */ + public GuiControl(Minecraft minecraft, int controlId, int xPos, int yPos, int controlWidth, int controlHeight, String displayText) { + super(controlId, xPos, yPos, controlWidth, controlHeight, displayText); + this.mc = minecraft; + } + + public GuiControl(Minecraft minecraft, int controlId, int xPos, int yPos, String displayText) { + super(controlId, xPos, yPos, displayText); + this.mc = minecraft; + } + + /** + * GuiControlEx returns true from mousePressed if the mouse was captured, + * NOT if an action was performed. Containers should call this function + * afterwards to determine whether an action was performed. + * + * @return True if actionPerformed should be dispatched + */ + public boolean isActionPerformed() { + return this.actionPerformed; + } + + /** + * Get whether an actionPerformed was a double-click event + * + * @return + */ + public boolean isDoubleClicked(boolean resetDoubleClicked) { + boolean result = this.doubleClicked; + if (resetDoubleClicked) + this.doubleClicked = false; + return result; + } + + /** + * Draws a line between two points with the specified width and colour + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param colour Line colour + */ + public static void drawLine(int x1, int y1, int x2, int y2, int width, int colour) { + drawArrow(x1, y1, x2, y2, 0, width, colour, false, 0); + } + + /** + * Draws an OpenGL line + * + * @param x1 Start x position + * @param y1 Start y position + * @param x2 End x position + * @param y2 End y position + * @param width Line width + * @param colour Line colour + */ + @SuppressWarnings("cast") + public static void drawNativeLine(float x1, float y1, float x2, float y2, float width, int colour) { + float f = (float) (colour >> 24 & 0xff) / 255F; + float f1 = (float) (colour >> 16 & 0xff) / 255F; + float f2 = (float) (colour >> 8 & 0xff) / 255F; + float f3 = (float) (colour & 0xff) / 255F; + + glEnableBlend(); + glDisableTexture2D(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(f1, f2, f3, f); + glLineWidth(width); + + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_LINES, VF_POSITION); + buf.pos(x1, y1, 0).endVertex(); + buf.pos(x2, y2, 0).endVertex(); + tessellator.draw(); + + glEnableTexture2D(); + glDisableBlend(); + } + + /** + * Draws an arrow between two points with the specified width and colour + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param arrowHeadSize Size of the arrow head + * @param colour Colour + */ + public static void drawArrow(int x1, int y1, int x2, int y2, int z, int width, int arrowHeadSize, int colour) { + drawArrow(x1, y1, x2, y2, z, width, colour, true, arrowHeadSize); + } + + /** + * Internal function for drawing lines and arrows + * + * @param x1 Origin x coordinate + * @param y1 Origin y coordinate + * @param x2 End x coordinate + * @param y2 End y coordinate + * @param width Line width in pixels + * @param colour Colour + * @param arrowHead True to draw an arrow, otherwise draws a line + * @param arrowHeadSize Size of the arrow head + */ + @SuppressWarnings("cast") + public static void drawArrow(int x1, int y1, int x2, int y2, int z, int width, int colour, boolean arrowHead, int arrowHeadSize) { + // Calculate the line length and angle defined by the specified points + int length = (int) Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2)); + float angle = (float) Math.toDegrees(Math.atan2(y2 - y1, x2 - x1)); + + // Local rotation + glPushMatrix(); + glTranslatef(x1, y1, 0.0f); + glRotatef(angle, 0.0f, 0.0f, 1.0f); + + // Calc coordinates for the line and arrow points + x1 = 0; + x2 = length - (arrowHead ? arrowHeadSize : 0); + y1 = (int) (width * -0.5); + y2 = y1 + width; + + // Calc colour components + float f = (float) (colour >> 24 & 0xff) / 255F; + float f1 = (float) (colour >> 16 & 0xff) / 255F; + float f2 = (float) (colour >> 8 & 0xff) / 255F; + float f3 = (float) (colour & 0xff) / 255F; + + glEnableBlend(); + glDisableTexture2D(); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(f1, f2, f3, f); + + // Draw the line + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION); + buf.pos(x1, y2, z).endVertex(); + buf.pos(x2, y2, z).endVertex(); + buf.pos(x2, y1, z).endVertex(); + buf.pos(x1, y1, z).endVertex(); + tessellator.draw(); + + // If an arrow then draw the arrow head + if (arrowHead && arrowHeadSize > 0) { + buf.begin(GL_TRIANGLES, VF_POSITION); + buf.pos(x2, 0 - arrowHeadSize / 2, z).endVertex(); + buf.pos(x2, arrowHeadSize / 2, z).endVertex(); + buf.pos(length, 0, z).endVertex(); + tessellator.draw(); + } + + glEnableTexture2D(); + glDisableBlend(); + + glPopMatrix(); + } + + /** + * Set the texmap scale factor + * + * @param textureSize + */ + @SuppressWarnings("cast") + public void setTexMapSize(int textureSize) { + texMapScale = 1F / (float) textureSize; + } + + /** + * Draws a textured rectangle at 90 degrees + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + @SuppressWarnings("cast") + public void drawTexturedModalRectRot(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION_TEX); + buf.pos(x2, y2, this.zLevel).tex((float) (u) * texMapScale, (float) (v2) * texMapScale).endVertex(); + buf.pos(x2, y, this.zLevel).tex((float) (u2) * texMapScale, (float) (v2) * texMapScale).endVertex(); + buf.pos(x, y, this.zLevel).tex((float) (u2) * texMapScale, (float) (v) * texMapScale).endVertex(); + buf.pos(x, y2, this.zLevel).tex((float) (u) * texMapScale, (float) (v) * texMapScale).endVertex(); + tessellator.draw(); + } + + /** + * Draws a textured rectangle at 90 degrees + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param width Width of texture to draw + * @param height Height of texture to draw + */ + @SuppressWarnings("cast") + public void drawTexturedModalRectRot(int x, int y, int u, int v, int width, int height) { + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION_TEX); + buf.pos(x + height, y + width, this.zLevel).tex((float) (u) * texMapScale, (float) (v + height) * texMapScale).endVertex(); + buf.pos(x + height, y, this.zLevel).tex((float) (u + width) * texMapScale, (float) (v + height) * texMapScale).endVertex(); + buf.pos(x, y, this.zLevel).tex((float) (u + width) * texMapScale, (float) (v) * texMapScale).endVertex(); + buf.pos(x, y + width, this.zLevel).tex((float) (u) * texMapScale, (float) (v) * texMapScale).endVertex(); + tessellator.draw(); + } + + /** + * Draws a tesselated rectangle where the texture is stretched horizontally + * but vertical scaling is achieved by splitting the texture in half and + * repeating the middle pixels + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalRectV(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + int tileSize = ((v2 - v) / 2); + int vMidTop = v + tileSize; + int vMidBtm = vMidTop + 1; + + this.drawTexturedModalRect(x, y, x2, y + tileSize, u, v, u2, vMidTop); + this.drawTexturedModalRect(x, y + tileSize, x2, y2 - tileSize + 1, u, vMidTop, u2, vMidBtm); + this.drawTexturedModalRect(x, y2 - tileSize + 1, x2, y2, u, vMidBtm, u2, v2); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * but horizontal scaling is achieved by splitting the texture in half and + * repeating the middle pixels + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalRectH(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + int tileSize = ((u2 - u) / 2); + int uMidLeft = u + tileSize; + int uMidRight = uMidLeft + 1; + + this.drawTexturedModalRect(x, y, x + tileSize, y2, u, v, uMidLeft, v2); + this.drawTexturedModalRect(x + tileSize, y, x2 - tileSize + 1, y2, uMidLeft, v, uMidRight, v2); + this.drawTexturedModalRect(x2 - tileSize + 1, y, x2, y2, uMidRight, v, u2, v2); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTessellatedModalBorderRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + this.drawTessellatedModalBorderRect(x, y, x2, y2, u, v, u2, v2, Math.min(((x2 - x) / 2) - 1, ((y2 - y) / 2) - 1)); + } + + /** + * Draws a tesselated rectangle where the texture is stretched vertically + * and horizontally but the middle pixels are repeated whilst the joining + * pixels are stretched. Bordersize specifies the portion of the texture + * which will remain unstretched. + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + * @param borderSize Number of pixels to leave unstretched, must be less + * than half of the width or height (whichever is smallest) + */ + public void drawTessellatedModalBorderRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2, int borderSize) { + int tileSize = Math.min(((u2 - u) / 2) - 1, ((v2 - v) / 2) - 1); + + int ul = u + tileSize, ur = u2 - tileSize, vt = v + tileSize, vb = v2 - tileSize; + int xl = x + borderSize, xr = x2 - borderSize, yt = y + borderSize, yb = y2 - borderSize; + + this.drawTexturedModalRect(x, y, xl, yt, u, v, ul, vt); + this.drawTexturedModalRect(xl, y, xr, yt, ul, v, ur, vt); + this.drawTexturedModalRect(xr, y, x2, yt, ur, v, u2, vt); + this.drawTexturedModalRect(x, yb, xl, y2, u, vb, ul, v2); + this.drawTexturedModalRect(xl, yb, xr, y2, ul, vb, ur, v2); + this.drawTexturedModalRect(xr, yb, x2, y2, ur, vb, u2, v2); + this.drawTexturedModalRect(x, yt, xl, yb, u, vt, ul, vb); + this.drawTexturedModalRect(xr, yt, x2, yb, ur, vt, u2, vb); + this.drawTexturedModalRect(xl, yt, xr, yb, ul, vt, ur, vb); + } + + /** + * Draw a string but cut it off if it's too long to fit in the specified + * width + * + * @param fontrenderer + * @param s + * @param x + * @param y + * @param width + * @param colour + */ + public static void drawStringWithEllipsis(FontRenderer fontrenderer, String s, int x, int y, int width, int colour) { + if (fontrenderer.getStringWidth(s) <= width) { + fontrenderer.drawStringWithShadow(s, x, y, colour); // func_175063_a + // drawStringWithShadow + } else if (width < 8) { + fontrenderer.drawStringWithShadow("..", x, y, colour); // func_175063_a + // drawStringWithShadow + } else { + String trimmedText = s; + + while (fontrenderer.getStringWidth(trimmedText) > width - 8 && trimmedText.length() > 0) + trimmedText = trimmedText.substring(0, trimmedText.length() - 1); + + fontrenderer.drawStringWithShadow(trimmedText + "...", x, y, colour); // func_175063_a + // drawStringWithShadow + } + } + + /** + * @param boundingBox + */ + @SuppressWarnings("cast") + protected void drawCrossHair(int x, int y, int size, int width, int colour) { + float alpha = (float) (colour >> 24 & 0xff) / 255F; + float red = (float) (colour >> 16 & 0xff) / 255F; + float green = (float) (colour >> 8 & 0xff) / 255F; + float blue = (float) (colour & 0xff) / 255F; + + glLineWidth(GuiControl.guiScaleFactor * width); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnableBlend(); + glDisableTexture2D(); + glDisableLighting(); + glColor4f(red, green, blue, alpha); + glEnableColorLogic(); + glLogicOp(GL_OR_REVERSE); + + // Draw the frame + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + + buf.begin(GL_LINES, VF_POSITION); + buf.pos(x - size, y, 0).endVertex(); + buf.pos(x + size, y, 0).endVertex(); + tessellator.draw(); + + buf.begin(GL_LINES, VF_POSITION); + buf.pos(x, y - size, 0).endVertex(); + buf.pos(x, y + size, 0).endVertex(); + tessellator.draw(); + + glDisableColorLogic(); + glEnableTexture2D(); + } + + protected void drawRotText(FontRenderer fontRenderer, String text, int xPosition, int yPosition, int colour, boolean colourOrOp) { + if (colourOrOp) { + glEnableColorLogic(); + glLogicOp(GL_OR_REVERSE); + } + + int textWidth = fontRenderer.getStringWidth(text) / 2; + + glPushMatrix(); + glTranslatef(xPosition, yPosition, 0); + glRotatef(-90, 0, 0, 1); + glTranslatef(-textWidth, -4, 0); + + fontRenderer.drawString(text, 0, 0, colour); + + glPopMatrix(); + + if (colourOrOp) { + glDisableColorLogic(); + glEnableTexture2D(); + } + } + + /** + * Draw a tooltip at the specified location and clip to screenWidth and + * screenHeight + * + * @param fontRenderer + * @param tooltipText + * @param mouseX + * @param mouseY + * @param screenWidth + * @param screenHeight + * @param colour + * @param backgroundColour + */ + protected void drawTooltip(FontRenderer fontRenderer, String tooltipText, int mouseX, int mouseY, int screenWidth, int screenHeight, int colour, int backgroundColour) { + int textSize = fontRenderer.getStringWidth(tooltipText); + mouseX = Math.max(0, Math.min(screenWidth - textSize - 6, mouseX - 6)); + mouseY = Math.max(0, Math.min(screenHeight - 16, mouseY - 18)); + + drawRect(mouseX, mouseY, mouseX + textSize + 6, mouseY + 16, backgroundColour); + this.drawString(fontRenderer, tooltipText, mouseX + 3, mouseY + 4, colour); + } + + /** + * Draws a textured rectangle with custom UV coordinates + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + @SuppressWarnings("cast") + public void drawTexturedModalRect(int x, int y, int x2, int y2, int u, int v, int u2, int v2) { + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION_TEX); + buf.pos(x, y2, this.zLevel).tex((float) (u) * texMapScale, (float) (v2) * texMapScale).endVertex(); + buf.pos(x2, y2, this.zLevel).tex((float) (u2) * texMapScale, (float) (v2) * texMapScale).endVertex(); + buf.pos(x2, y, this.zLevel).tex((float) (u2) * texMapScale, (float) (v) * texMapScale).endVertex(); + buf.pos(x, y, this.zLevel).tex((float) (u) * texMapScale, (float) (v) * texMapScale).endVertex(); + tessellator.draw(); + } + + /** + * Draws a textured rectangle with custom UV coordinates + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param x2 Right edge X coordinate + * @param y2 Bottom edge Y coordinate + * @param u U coordinate + * @param v V coordinate + * @param u2 Right edge U coordinate + * @param v2 Bottom edge V coordinate + */ + public void drawTexturedModalRectF(int x, int y, int x2, int y2, float u, float v, float u2, float v2) { + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION_TEX); + buf.pos(x, y2, this.zLevel).tex(u, v2).endVertex(); + buf.pos(x2, y2, this.zLevel).tex(u2, v2).endVertex(); + buf.pos(x2, y, this.zLevel).tex(u2, v).endVertex(); + buf.pos(x, y, this.zLevel).tex(u, v).endVertex(); + tessellator.draw(); + } + + /** + * Draws a textured rectangle with the specified texture map size + * + * @param x Left edge X coordinate + * @param y Top edge Y coordinate + * @param u Texture U coordinate + * @param v Texture V coordinate + * @param width Width + * @param height Height + * @param texMapScale Texture map scale for scaling UV coordinate + */ + @SuppressWarnings("cast") + public void drawTexturedModalRect(int x, int y, int u, int v, int width, int height, float texMapScale) { + Tessellator tessellator = Tessellator.getInstance(); + VertexBuffer buf = tessellator.getBuffer(); + buf.begin(GL_QUADS, VF_POSITION_TEX); + buf.pos(x + 0, y + height, this.zLevel).tex((float) (u + 0) * texMapScale, (float) (v + height) * texMapScale).endVertex(); + buf.pos(x + width, y + height, this.zLevel).tex((float) (u + width) * texMapScale, (float) (v + height) * texMapScale).endVertex(); + buf.pos(x + width, y + 0, this.zLevel).tex((float) (u + width) * texMapScale, (float) (v + 0) * texMapScale).endVertex(); + buf.pos(x + 0, y + 0, this.zLevel).tex((float) (u + 0) * texMapScale, (float) (v + 0) * texMapScale).endVertex(); + tessellator.draw(); + } + + public static void setScreenSizeAndScale(int width, int height, int scaleFactor) { + GuiControl.lastScreenWidth = width; + GuiControl.lastScreenHeight = height; + GuiControl.guiScaleFactor = scaleFactor; + } +} \ No newline at end of file diff --git a/src/hdskins/resources/assets/hdskins/lang/en_US.lang b/src/hdskins/resources/assets/hdskins/lang/en_US.lang index a40491d4..b5ccefa1 100644 --- a/src/hdskins/resources/assets/hdskins/lang/en_US.lang +++ b/src/hdskins/resources/assets/hdskins/lang/en_US.lang @@ -16,3 +16,5 @@ hdskins.upload=Uploading skin please wait... hdskins.local=Local Skin hdskins.server=Server Skin + +gui.ok=OK diff --git a/src/hdskins/resources/assets/hdskins/textures/gui/checker.png b/src/hdskins/resources/assets/hdskins/textures/gui/checker.png new file mode 100644 index 00000000..d7ca6a32 Binary files /dev/null and b/src/hdskins/resources/assets/hdskins/textures/gui/checker.png differ diff --git a/src/main/java/com/brohoof/minelittlepony/hdskins/gui/EntityPonyModel.java b/src/main/java/com/brohoof/minelittlepony/hdskins/gui/EntityPonyModel.java index 488b93b1..28240f7e 100644 --- a/src/main/java/com/brohoof/minelittlepony/hdskins/gui/EntityPonyModel.java +++ b/src/main/java/com/brohoof/minelittlepony/hdskins/gui/EntityPonyModel.java @@ -1,7 +1,6 @@ package com.brohoof.minelittlepony.hdskins.gui; import com.mojang.authlib.GameProfile; -import com.voxelmodpack.hdskins.IMetaHandler; import com.voxelmodpack.hdskins.gui.EntityPlayerModel; public class EntityPonyModel extends EntityPlayerModel {