Package cofh.lib.gui

Source Code of cofh.lib.gui.GuiBase

package cofh.lib.gui;

import cofh.lib.audio.SoundBase;
import cofh.lib.gui.element.ElementBase;
import cofh.lib.gui.element.TabBase;
import cofh.lib.gui.slot.SlotFalseCopy;
import cofh.lib.render.RenderHelper;
import cofh.lib.util.helpers.StringHelper;
import cpw.mods.fml.client.FMLClientHandler;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.fluids.FluidStack;

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

/**
* Base class for a modular GUIs. Works with Elements {@link ElementBase} and Tabs {@link TabBase} which are both modular elements.
*
* @author King Lemming
*/
public abstract class GuiBase extends GuiContainer {

  public static final SoundHandler guiSoundManager = FMLClientHandler.instance().getClient().getSoundHandler();

  protected boolean drawTitle = true;
  protected boolean drawInventory = true;
  protected int mouseX = 0;
  protected int mouseY = 0;

  protected int lastIndex = -1;

  protected String name;
  protected ResourceLocation texture;

  public ArrayList<TabBase> tabs = new ArrayList<TabBase>();
  protected ArrayList<ElementBase> elements = new ArrayList<ElementBase>();

  protected List<String> tooltip = new LinkedList<String>();
  protected boolean tooltips = true;

  // protected boolean tooltips = !Loader.isModLoaded("NotEnoughItems");

  public static void playSound(String name, float volume, float pitch) {

    guiSoundManager.playSound(new SoundBase(name, volume, pitch));
  }

  public GuiBase(Container container) {

    super(container);
  }

  public GuiBase(Container container, ResourceLocation texture) {

    super(container);
    this.texture = texture;
  }

  @Override
  public void initGui() {

    super.initGui();
    tabs.clear();
    elements.clear();
  }

  @Override
  public void drawScreen(int x, int y, float partialTick) {

    updateElementInformation();

    super.drawScreen(x, y, partialTick);

    if (tooltips && mc.thePlayer.inventory.getItemStack() == null) {
      addTooltips(tooltip);
      drawTooltip(tooltip);
    }
    mouseX = x - guiLeft;
    mouseY = y - guiTop;

    updateElements();
  }

  @Override
  protected void drawGuiContainerForegroundLayer(int x, int y) {

    if (drawTitle) {
      fontRendererObj.drawString(StringHelper.localize(name), getCenteredOffset(StringHelper.localize(name)), 6, 0x404040);
    }
    if (drawInventory) {
      fontRendererObj.drawString(StatCollector.translateToLocal("container.inventory"), 8, ySize - 96 + 3, 0x404040);
    }
    drawElements(0, true);
    drawTabs(0, true);
  }

  @Override
  protected void drawGuiContainerBackgroundLayer(float partialTick, int x, int y) {

    GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    bindTexture(texture);
    drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);

    mouseX = x - guiLeft;
    mouseY = y - guiTop;

    GL11.glPushMatrix();
    GL11.glTranslatef(guiLeft, guiTop, 0.0F);
    drawElements(partialTick, false);
    drawTabs(partialTick, false);
    GL11.glPopMatrix();
  }

  @Override
  protected void keyTyped(char characterTyped, int keyPressed) {

    for (int i = elements.size(); i-- > 0;) {
      ElementBase c = elements.get(i);
      if (!c.isVisible() || !c.isEnabled()) {
        continue;
      }
      if (c.onKeyTyped(characterTyped, keyPressed)) {
        return;
      }
    }
    super.keyTyped(characterTyped, keyPressed);
  }

  @Override
  public void handleMouseInput() {

    int x = Mouse.getEventX() * width / mc.displayWidth;
    int y = height - Mouse.getEventY() * height / mc.displayHeight - 1;

    mouseX = x - guiLeft;
    mouseY = y - guiTop;

    int wheelMovement = Mouse.getEventDWheel();

    if (wheelMovement != 0) {
      for (int i = elements.size(); i-- > 0;) {
        ElementBase c = elements.get(i);
        if (!c.isVisible() || !c.isEnabled() || !c.intersectsWith(mouseX, mouseY)) {
          continue;
        }
        if (c.onMouseWheel(mouseX, mouseY, wheelMovement)) {
          return;
        }
      }
      TabBase tab = getTabAtPosition(mouseX, mouseY);

      if (tab != null && tab.onMouseWheel(mouseX, mouseY, wheelMovement)) {
        return;
      }
    }
    super.handleMouseInput();
  }

  @Override
  protected void mouseClicked(int mX, int mY, int mouseButton) {

    mX -= guiLeft;
    mY -= guiTop;

    for (int i = elements.size(); i-- > 0;) {
      ElementBase c = elements.get(i);
      if (!c.isVisible() || !c.isEnabled() || !c.intersectsWith(mX, mY)) {
        continue;
      }
      if (c.onMousePressed(mX, mY, mouseButton)) {
        return;
      }
    }
    TabBase tab = getTabAtPosition(mX, mY);
    if (tab != null && !tab.onMousePressed(mX, mY, mouseButton)) {
      for (int i = tabs.size(); i-- > 0;) {
        TabBase other = tabs.get(i);
        if (other != tab && other.open && other.side == tab.side) {
          other.toggleOpen();
        }
      }
      tab.toggleOpen();
      return;
    }
    mX += guiLeft;
    mY += guiTop;

    // TODO: Look into a better solution for this.
    if (tab != null) {
      xSize += tab.currentWidth;
    }
    super.mouseClicked(mX, mY, mouseButton);
    if (tab != null) {
      xSize -= tab.currentWidth;
    }
  }

  @Override
  protected void mouseMovedOrUp(int mX, int mY, int mouseButton) {

    mX -= guiLeft;
    mY -= guiTop;

    if (mouseButton >= 0 && mouseButton <= 2) { // 0:left, 1:right, 2: middle
      for (int i = elements.size(); i-- > 0;) {
        ElementBase c = elements.get(i);
        if (!c.isVisible() || !c.isEnabled()) { // no bounds checking on mouseUp events
          continue;
        }
        c.onMouseReleased(mX, mY);
      }
    }
    mX += guiLeft;
    mY += guiTop;

    super.mouseMovedOrUp(mX, mY, mouseButton);
  }

  @Override
  protected void mouseClickMove(int mX, int mY, int lastClick, long timeSinceClick) {

    Slot slot = getSlotAtPosition(mX, mY);
    ItemStack itemstack = this.mc.thePlayer.inventory.getItemStack();

    if (this.field_147007_t && slot != null && itemstack != null && slot instanceof SlotFalseCopy) {
      if (lastIndex != slot.slotNumber) {
        lastIndex = slot.slotNumber;
        this.handleMouseClick(slot, slot.slotNumber, 0, 0);
      }
    } else {
      lastIndex = -1;
      super.mouseClickMove(mX, mY, lastClick, timeSinceClick);
    }
  }

  public Slot getSlotAtPosition(int xCoord, int yCoord) {

    for (int k = 0; k < this.inventorySlots.inventorySlots.size(); ++k) {
      Slot slot = (Slot) this.inventorySlots.inventorySlots.get(k);

      if (this.isMouseOverSlot(slot, xCoord, yCoord)) {
        return slot;
      }
    }
    return null;
  }

  public boolean isMouseOverSlot(Slot theSlot, int xCoord, int yCoord) {

    return this.func_146978_c(theSlot.xDisplayPosition, theSlot.yDisplayPosition, 16, 16, xCoord, yCoord);
  }

  /**
   * Draws the elements for this GUI.
   */
  protected void drawElements(float partialTick, boolean foreground) {

    if (foreground) {
      for (int i = 0; i < elements.size(); i++) {
        ElementBase element = elements.get(i);
        if (element.isVisible()) {
          element.drawForeground(mouseX, mouseY);
        }
      }
    } else {
      for (int i = 0; i < elements.size(); i++) {
        ElementBase element = elements.get(i);
        if (element.isVisible()) {
          element.drawBackground(mouseX, mouseY, partialTick);
        }
      }
    }
  }

  /**
   * Draws the tabs for this GUI. Handles Tab open/close animation.
   */
  protected void drawTabs(float partialTick, boolean foreground) {

    if (foreground) {
      return; // TODO:
    }
    int yPosRight = 4;
    int yPosLeft = 4;

    for (int i = 0; i < tabs.size(); i++) {
      TabBase tab = tabs.get(i);
      tab.update();
      if (!tab.isVisible()) {
        continue;
      }
      // TODO: convert these over to foreground/background (maybe logic for top/bottom tabs?)
      if (tab.side == TabBase.LEFT) {
        tab.draw(0, yPosLeft);
        yPosLeft += tab.currentHeight;
      } else {
        tab.draw(xSize, yPosRight);
        yPosRight += tab.currentHeight;
      }
    }
  }

  /**
   * Called by NEI if installed
   */
  // @Override
  public List<String> handleTooltip(int mousex, int mousey, List<String> tooltip) {

    if (mc.thePlayer.inventory.getItemStack() == null) {
      addTooltips(tooltip);
    }
    return tooltip;
  }

  public void addTooltips(List<String> tooltip) {

    TabBase tab = getTabAtPosition(mouseX, mouseY);

    if (tab != null) {
      tab.addTooltip(tooltip);
    }
    ElementBase element = getElementAtPosition(mouseX, mouseY);

    if (element != null) {
      element.addTooltip(tooltip);
    }
  }

  /* ELEMENTS */
  public ElementBase addElement(ElementBase element) {

    elements.add(element);
    return element;
  }

  public TabBase addTab(TabBase tab) {

    int yOffset = 4;
    for (int i = 0; i < tabs.size(); i++) {
      if (tabs.get(i).side == tab.side && tabs.get(i).isVisible()) {
        yOffset += tabs.get(i).currentHeight;
      }
    }
    tab.setPosition(tab.side == TabBase.LEFT ? 0 : xSize, yOffset);
    tabs.add(tab);

    if (TabTracker.getOpenedLeftTab() != null && tab.getClass().equals(TabTracker.getOpenedLeftTab())) {
      tab.setFullyOpen();
    } else if (TabTracker.getOpenedRightTab() != null && tab.getClass().equals(TabTracker.getOpenedRightTab())) {
      tab.setFullyOpen();
    }
    return tab;
  }

  protected ElementBase getElementAtPosition(int mX, int mY) {

    for (int i = elements.size(); i-- > 0;) {
      ElementBase element = elements.get(i);
      if (element.intersectsWith(mX, mY)) {
        return element;
      }
    }
    return null;
  }

  protected TabBase getTabAtPosition(int mX, int mY) {

    int xShift = 0;
    int yShift = 4;

    for (int i = 0; i < tabs.size(); i++) {
      TabBase tab = tabs.get(i);
      if (!tab.isVisible() || tab.side == TabBase.RIGHT) {
        continue;
      }
      tab.currentShiftX = xShift;
      tab.currentShiftY = yShift;
      if (tab.intersectsWith(mX, mY, xShift, yShift)) {
        return tab;
      }
      yShift += tab.currentHeight;
    }

    xShift = xSize;
    yShift = 4;

    for (int i = 0; i < tabs.size(); i++) {
      TabBase tab = tabs.get(i);
      if (!tab.isVisible() || tab.side == TabBase.LEFT) {
        continue;
      }
      tab.currentShiftX = xShift;
      tab.currentShiftY = yShift;
      if (tab.intersectsWith(mX, mY, xShift, yShift)) {
        return tab;
      }
      yShift += tab.currentHeight;
    }
    return null;
  }

  protected final void updateElements() {

    for (int i = elements.size(); i-- > 0;) {
      ElementBase c = elements.get(i);
      if (c.isVisible() && c.isEnabled()) {
        c.update(mouseX, mouseY);
      }
    }
  }

  protected void updateElementInformation() {

  }

  public void handleElementButtonClick(String buttonName, int mouseButton) {

  }

  /* HELPERS */
  public void bindTexture(ResourceLocation texture) {

    mc.renderEngine.bindTexture(texture);
  }

  /**
   * Abstract method to retrieve icons by name from a registry. You must override this if you use any of the String methods below.
   */
  public IIcon getIcon(String name) {

    return null;
  }

  /**
   * Essentially a placeholder method for tabs to use should they need to draw a button.
   */
  public void drawButton(IIcon icon, int x, int y, int spriteSheet, int mode) {

    drawIcon(icon, x, y, spriteSheet);
  }

  public void drawButton(String iconName, int x, int y, int spriteSheet, int mode) {

    drawButton(getIcon(iconName), x, y, spriteSheet, mode);
  }

  /**
   * Simple method used to draw a fluid of arbitrary size.
   */
  public void drawFluid(int x, int y, FluidStack fluid, int width, int height) {

    if (fluid == null || fluid.getFluid() == null) {
      return;
    }
    RenderHelper.setBlockTextureSheet();
    RenderHelper.setColor3ub(fluid.getFluid().getColor(fluid));

    drawTiledTexture(x, y, fluid.getFluid().getIcon(fluid), width, height);
  }

  public void drawTiledTexture(int x, int y, IIcon icon, int width, int height) {

    int i = 0;
    int j = 0;

    int drawHeight = 0;
    int drawWidth = 0;

    for (i = 0; i < width; i += 16) {
      for (j = 0; j < height; j += 16) {
        drawWidth = Math.min(width - i, 16);
        drawHeight = Math.min(height - j, 16);
        drawScaledTexturedModelRectFromIcon(x + i, y + j, icon, drawWidth, drawHeight);
      }
    }
    GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F);
  }

  public void drawIcon(IIcon icon, int x, int y, int spriteSheet) {

    if (spriteSheet == 0) {
      RenderHelper.setBlockTextureSheet();
    } else {
      RenderHelper.setItemTextureSheet();
    }
    GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0F);
    drawTexturedModelRectFromIcon(x, y, icon, 16, 16);
  }

  public void drawIcon(String iconName, int x, int y, int spriteSheet) {

    drawIcon(getIcon(iconName), x, y, spriteSheet);
  }

  public void drawSizedModalRect(int x1, int y1, int x2, int y2, int color) {

    int temp;

    if (x1 < x2) {
      temp = x1;
      x1 = x2;
      x2 = temp;
    }
    if (y1 < y2) {
      temp = y1;
      y1 = y2;
      y2 = temp;
    }

    float a = (color >> 24 & 255) / 255.0F;
    float r = (color >> 16 & 255) / 255.0F;
    float g = (color >> 8 & 255) / 255.0F;
    float b = (color & 255) / 255.0F;
    Tessellator tessellator = Tessellator.instance;
    GL11.glEnable(GL11.GL_BLEND);
    GL11.glDisable(GL11.GL_TEXTURE_2D);
    GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    GL11.glColor4f(r, g, b, a);
    tessellator.startDrawingQuads();
    tessellator.addVertex(x1, y2, this.zLevel);
    tessellator.addVertex(x2, y2, this.zLevel);
    tessellator.addVertex(x2, y1, this.zLevel);
    tessellator.addVertex(x1, y1, this.zLevel);
    tessellator.draw();
    GL11.glEnable(GL11.GL_TEXTURE_2D);
    GL11.glDisable(GL11.GL_BLEND);
  }

  public void drawSizedTexturedModalRect(int x, int y, int u, int v, int width, int height, float texW, float texH) {

    float texU = 1 / texW;
    float texV = 1 / texH;
    Tessellator tessellator = Tessellator.instance;
    tessellator.startDrawingQuads();
    tessellator.addVertexWithUV(x + 0, y + height, this.zLevel, (u + 0) * texU, (v + height) * texV);
    tessellator.addVertexWithUV(x + width, y + height, this.zLevel, (u + width) * texU, (v + height) * texV);
    tessellator.addVertexWithUV(x + width, y + 0, this.zLevel, (u + width) * texU, (v + 0) * texV);
    tessellator.addVertexWithUV(x + 0, y + 0, this.zLevel, (u + 0) * texU, (v + 0) * texV);
    tessellator.draw();
  }

  public void drawScaledTexturedModelRectFromIcon(int x, int y, IIcon icon, int width, int height) {

    if (icon == null) {
      return;
    }
    double minU = icon.getMinU();
    double maxU = icon.getMaxU();
    double minV = icon.getMinV();
    double maxV = icon.getMaxV();

    Tessellator tessellator = Tessellator.instance;
    tessellator.startDrawingQuads();
    tessellator.addVertexWithUV(x + 0, y + height, this.zLevel, minU, minV + (maxV - minV) * height / 16F);
    tessellator.addVertexWithUV(x + width, y + height, this.zLevel, minU + (maxU - minU) * width / 16F, minV + (maxV - minV) * height / 16F);
    tessellator.addVertexWithUV(x + width, y + 0, this.zLevel, minU + (maxU - minU) * width / 16F, minV);
    tessellator.addVertexWithUV(x + 0, y + 0, this.zLevel, minU, minV);
    tessellator.draw();
  }

  public void drawTooltip(List<String> list) {

    drawTooltipHoveringText(list, mouseX + guiLeft, mouseY + guiTop, fontRendererObj);
    tooltip.clear();
  }

  @SuppressWarnings("rawtypes")
  protected void drawTooltipHoveringText(List list, int x, int y, FontRenderer font) {

    if (list == null || list.isEmpty()) {
      return;
    }
    GL11.glDisable(GL12.GL_RESCALE_NORMAL);
    GL11.glDisable(GL11.GL_LIGHTING);
    GL11.glDisable(GL11.GL_DEPTH_TEST);
    int k = 0;
    Iterator iterator = list.iterator();

    while (iterator.hasNext()) {
      String s = (String) iterator.next();
      int l = font.getStringWidth(s);

      if (l > k) {
        k = l;
      }
    }
    int i1 = x + 12;
    int j1 = y - 12;
    int k1 = 8;

    if (list.size() > 1) {
      k1 += 2 + (list.size() - 1) * 10;
    }
    if (i1 + k > this.width) {
      i1 -= 28 + k;
    }
    if (j1 + k1 + 6 > this.height) {
      j1 = this.height - k1 - 6;
    }
    this.zLevel = 300.0F;
    itemRender.zLevel = 300.0F;
    int l1 = -267386864;
    this.drawGradientRect(i1 - 3, j1 - 4, i1 + k + 3, j1 - 3, l1, l1);
    this.drawGradientRect(i1 - 3, j1 + k1 + 3, i1 + k + 3, j1 + k1 + 4, l1, l1);
    this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 + k1 + 3, l1, l1);
    this.drawGradientRect(i1 - 4, j1 - 3, i1 - 3, j1 + k1 + 3, l1, l1);
    this.drawGradientRect(i1 + k + 3, j1 - 3, i1 + k + 4, j1 + k1 + 3, l1, l1);
    int i2 = 1347420415;
    int j2 = (i2 & 16711422) >> 1 | i2 & -16777216;
    this.drawGradientRect(i1 - 3, j1 - 3 + 1, i1 - 3 + 1, j1 + k1 + 3 - 1, i2, j2);
    this.drawGradientRect(i1 + k + 2, j1 - 3 + 1, i1 + k + 3, j1 + k1 + 3 - 1, i2, j2);
    this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 - 3 + 1, i2, i2);
    this.drawGradientRect(i1 - 3, j1 + k1 + 2, i1 + k + 3, j1 + k1 + 3, j2, j2);

    for (int k2 = 0; k2 < list.size(); ++k2) {
      String s1 = (String) list.get(k2);
      font.drawStringWithShadow(s1, i1, j1, -1);

      if (k2 == 0) {
        j1 += 2;
      }
      j1 += 10;
    }
    this.zLevel = 0.0F;
    itemRender.zLevel = 0.0F;
    GL11.glEnable(GL11.GL_LIGHTING);
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glEnable(GL12.GL_RESCALE_NORMAL);
  }

  /**
   * Passthrough method for tab use.
   */
  public void mouseClicked(int mouseButton) {

    super.mouseClicked(guiLeft + mouseX, guiTop + mouseY, mouseButton);
  }

  public FontRenderer getFontRenderer() {

    return fontRendererObj;
  }

  protected int getCenteredOffset(String string) {

    return this.getCenteredOffset(string, xSize);
  }

  protected int getCenteredOffset(String string, int xWidth) {

    return (xWidth - fontRendererObj.getStringWidth(string)) / 2;
  }

  public int getGuiLeft() {

    return guiLeft;
  }

  public int getGuiTop() {

    return guiTop;
  }

  public int getMouseX() {

    return mouseX;
  }

  public int getMouseY() {

    return mouseY;
  }

  public void overlayRecipe() {

  }

}
TOP

Related Classes of cofh.lib.gui.GuiBase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.