aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/gregtech/api/gui/widgets')
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java82
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiCoverTabLine.java179
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiFakeItemButton.java162
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiIcon.java157
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiIconButton.java114
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiIconCheckButton.java43
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiIntegerTextBox.java73
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java24
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java27
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiTab.java174
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiTabLine.java274
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiTooltip.java121
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_GuiTooltipManager.java80
-rw-r--r--src/main/java/gregtech/api/gui/widgets/GT_LockedWhileActiveButton.java90
14 files changed, 1600 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java b/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java
new file mode 100644
index 0000000000..883ffb4079
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_CoverTickRateButton.java
@@ -0,0 +1,82 @@
+package gregtech.api.gui.widgets;
+
+import static gregtech.api.gui.modularui.GT_UITextures.OVERLAY_BUTTON_HOURGLASS;
+import static gregtech.common.covers.CoverInfo.MAX_TICK_RATE_ADDITION;
+
+import java.util.List;
+
+import net.minecraft.util.StatCollector;
+
+import org.jetbrains.annotations.NotNull;
+
+import com.google.common.collect.ImmutableList;
+import com.gtnewhorizons.modularui.api.drawable.UITexture;
+import com.gtnewhorizons.modularui.api.widget.IWidgetBuilder;
+import com.gtnewhorizons.modularui.api.widget.Widget;
+import com.gtnewhorizons.modularui.common.widget.ButtonWidget;
+import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
+
+import gregtech.api.gui.modularui.GT_UITextures;
+import gregtech.common.covers.CoverInfo;
+
+public class GT_CoverTickRateButton extends ButtonWidget {
+
+ private static final UITexture BACKGROUND = GT_UITextures.BUTTON_COVER_NORMAL.getSubArea(0, 0, 1, 0.5f);
+
+ private final CoverInfo coverInfo;
+ private int clientTickRate;
+ private int tickRateAddition;
+
+ public GT_CoverTickRateButton(@NotNull CoverInfo coverInfo, @NotNull IWidgetBuilder<?> builder) {
+ this.coverInfo = coverInfo;
+ this.clientTickRate = coverInfo.getTickRate();
+ this.tickRateAddition = coverInfo.getTickRateAddition();
+
+ super.setBackground(BACKGROUND, OVERLAY_BUTTON_HOURGLASS);
+ super.setOnClick(this::onClick);
+ super.dynamicTooltip(this::dynamicTooltip);
+ super.attachSyncer(
+ new FakeSyncWidget.IntegerSyncer(this.coverInfo::getTickRate, integer -> clientTickRate = integer),
+ builder,
+ (widget, aInt) -> notifyTooltipChange())
+ .attachSyncer(
+ new FakeSyncWidget.IntegerSyncer(
+ this.coverInfo::getTickRateAddition,
+ integer -> tickRateAddition = integer),
+ builder);
+
+ }
+
+ private void onClick(@NotNull ClickData clickData, @NotNull Widget widget) {
+ final int iterations = clickData.ctrl ? 5 : 1;
+ final boolean isDecreasing = clickData.mouseButton == 1;
+
+ // Do five operations at once if Ctrl is held down. Since the actual increase granted by each invocation can be
+ // different on each call, just call the method several times rather than trying to do a bunch of weird math.
+ for (int i = 0; i < iterations; i++) {
+ coverInfo.adjustTickRateMultiplier(isDecreasing);
+ }
+ }
+
+ private List<String> dynamicTooltip() {
+ final String boundsNotification;
+
+ if (tickRateAddition == 0) {
+ boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.minimum");
+ } else if (tickRateAddition >= MAX_TICK_RATE_ADDITION - 1) {
+ // Clamping can make tickRateAddition approach but never actually equal MAX_ADDITION, so we need this
+ // adjustment.
+ boundsNotification = StatCollector.translateToLocal("gt.cover.info.button.bounds_notification.maximum");
+ } else {
+ boundsNotification = "";
+ }
+
+ return ImmutableList.of(
+ StatCollector.translateToLocalFormatted(
+ "gt.cover.info.button.tick_rate.1",
+ new CoverInfo.ClientTickRateFormatter(clientTickRate),
+ boundsNotification),
+ StatCollector.translateToLocal("gt.cover.info.button.tick_rate.2"),
+ StatCollector.translateToLocal("gt.cover.info.button.tick_rate.3"));
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiCoverTabLine.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiCoverTabLine.java
new file mode 100644
index 0000000000..6f4eb0e2c2
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiCoverTabLine.java
@@ -0,0 +1,179 @@
+package gregtech.api.gui.widgets;
+
+import java.awt.Rectangle;
+import java.util.List;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.StatCollector;
+import net.minecraftforge.common.util.ForgeDirection;
+
+import org.lwjgl.opengl.GL11;
+
+import codechicken.nei.api.API;
+import codechicken.nei.api.INEIGuiAdapter;
+import gregtech.api.enums.GT_Values;
+import gregtech.api.gui.GT_GUIContainerMetaTile_Machine;
+import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
+import gregtech.api.net.GT_Packet_GtTileEntityGuiRequest;
+import gregtech.common.GT_Proxy;
+
+/**
+ * Let's you access a GregTech IGregTechTileEntity's covers as tabs on the GUI's sides
+ */
+public class GT_GuiCoverTabLine extends GT_GuiTabLine {
+
+ // Names of the block a cover could be on
+ private static final String[] SIDES = new String[] { "GT5U.interface.coverTabs.down", "GT5U.interface.coverTabs.up",
+ "GT5U.interface.coverTabs.north", "GT5U.interface.coverTabs.south", "GT5U.interface.coverTabs.west",
+ "GT5U.interface.coverTabs.east" };
+
+ // Not sure if there's a point in JIT translation but that's what this is
+ private final String[] translatedSides;
+ private final IGregTechTileEntity tile;
+ private final int colorization;
+
+ /**
+ * Let's you access an IGregTechTileEntity's covers as tabs on the GUI's sides
+ *
+ * @param gui GT_ITabRenderer gui which this tab line attaches to
+ * @param tabLineLeft left position of the tab line in relation to the gui
+ * @param tabLineTop top position of the tab line in relation to the gui
+ * @param tabHeight height of a tab
+ * @param tabWidth width of a tab
+ * @param tabSpacing pixels between each tab
+ * @param xDir whether to extend the line horizontally to the right (NORMAL), the left (INVERSE) or not at
+ * all (NONE)
+ * @param yDir whether to extend the line vertically down (NORMAL), up (INVERSE) or not at all (NONE)
+ * @param displayMode whether to display on the left side of the GT_ITabRenderer (NORMAL), on it's right side
+ * (INVERSE) or not at all (NONE)
+ * @param tabBackground the set of textures used to draw this tab line's tab backgrounds
+ * @param tile The IGregTechTileEntity the covers of which we are accessing
+ * @param colorization The colorization of the GUI we are adding tabs to
+ */
+ public GT_GuiCoverTabLine(GT_GUIContainerMetaTile_Machine gui, int tabLineLeft, int tabLineTop, int tabHeight,
+ int tabWidth, int tabSpacing, DisplayStyle xDir, DisplayStyle yDir, DisplayStyle displayMode,
+ GT_GuiTabIconSet tabBackground, IGregTechTileEntity tile, int colorization) {
+ super(gui, 6, tabLineLeft, tabLineTop, tabHeight, tabWidth, tabSpacing, xDir, yDir, displayMode, tabBackground);
+ this.tile = tile;
+ this.colorization = colorization;
+ this.translatedSides = new String[6];
+ setupTabs();
+ }
+
+ /**
+ * Add a tab for each existing cover on this IGregTechTileEntity at creation time
+ */
+ private void setupTabs() {
+ for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
+ final ItemStack cover = tile.getCoverItemAtSide(side);
+ if (cover != null) {
+ addCoverToTabs(side, cover);
+ }
+ }
+ }
+
+ @Override
+ protected void drawBackground(float parTicks, int mouseX, int mouseY) {
+ // Apply this tile's coloration to draw the background
+ GL11.glColor3ub(
+ (byte) ((colorization >> 16) & 0xFF),
+ (byte) ((colorization >> 8) & 0xFF),
+ (byte) (colorization & 0xFF));
+ super.drawBackground(parTicks, mouseX, mouseY);
+ }
+
+ @Override
+ protected void tabClicked(int tabId, int mouseButton) {
+ if (mouseButton == 0 && mTabs[tabId].enabled) {
+ GT_Values.NW.sendToServer(
+ new GT_Packet_GtTileEntityGuiRequest(
+ this.tile.getXCoord(),
+ this.tile.getYCoord(),
+ this.tile.getZCoord(),
+ tabId + GT_Proxy.GUI_ID_COVER_SIDE_BASE,
+ this.tile.getWorld().provider.dimensionId,
+ Minecraft.getMinecraft().thePlayer.getEntityId(),
+ 0));
+ }
+ }
+
+ /**
+ * Add the cover on this side of the IGregTechTileEntity to the tabs
+ *
+ * @param side side to apply the cover to
+ * @param cover cover to add
+ */
+ private void addCoverToTabs(ForgeDirection side, ItemStack cover) {
+ final boolean enabled = this.tile.getCoverBehaviorAtSideNew(side)
+ .hasCoverGUI();
+ final int ordinalSide = side.ordinal();
+ this.setTab(ordinalSide, cover, null, getTooltipForCoverTab(side, cover, enabled));
+ this.setTabEnabled(ordinalSide, enabled);
+ }
+
+ /**
+ * Decorate the cover's tooltips according to the side it's on and on whether the tab is enabled or not
+ *
+ * @param side side
+ * @param cover cover which tooltip to decorate
+ * @param enabled if the tab is enabled
+ * @return This cover tab's tooltip
+ */
+ private String[] getTooltipForCoverTab(ForgeDirection side, ItemStack cover, boolean enabled) {
+ final List<String> tooltip = cover.getTooltip(Minecraft.getMinecraft().thePlayer, true);
+ tooltip.set(
+ 0,
+ (enabled ? EnumChatFormatting.UNDERLINE : EnumChatFormatting.DARK_GRAY) + getSideDescription(side)
+ + (enabled ? EnumChatFormatting.RESET + ": " : ": " + EnumChatFormatting.RESET)
+ + tooltip.get(0));
+ return tooltip.toArray(new String[0]);
+ }
+
+ /**
+ * Get the translated name for a side of the IGregTechTileEntity
+ *
+ * @param side side of the entity
+ * @return translated name for a side of the IGregTechTileEntity
+ */
+ private String getSideDescription(ForgeDirection side) {
+ final int ordinalSide = side.ordinal();
+ if (ordinalSide < SIDES.length) {
+ if (this.translatedSides[ordinalSide] == null) {
+ this.translatedSides[ordinalSide] = StatCollector.translateToLocal(SIDES[ordinalSide]);
+ }
+ return this.translatedSides[ordinalSide];
+ }
+ return null;
+ }
+
+ /**
+ * Hide any NEI slots that would intersect with a cover tab
+ */
+ static class CoverTabLineNEIHandler extends INEIGuiAdapter {
+
+ @Override
+ public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
+ final Rectangle neiSlotArea = new Rectangle(x, y, w, h);
+ if (gui instanceof GT_GUIContainerMetaTile_Machine) {
+ final GT_GuiTabLine tabLine = ((GT_GUIContainerMetaTile_Machine) gui).coverTabs;
+ if (!tabLine.visible) {
+ return false;
+ }
+ for (int i = 0; i < tabLine.mTabs.length; i++) {
+ if (tabLine.mTabs[i] != null && tabLine.mTabs[i].getBounds()
+ .intersects(neiSlotArea)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ static {
+ API.registerNEIGuiHandler(new CoverTabLineNEIHandler());
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiFakeItemButton.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiFakeItemButton.java
new file mode 100644
index 0000000000..9f4287a65b
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiFakeItemButton.java
@@ -0,0 +1,162 @@
+package gregtech.api.gui.widgets;
+
+import java.awt.Rectangle;
+import java.util.List;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL12;
+
+import codechicken.lib.gui.GuiDraw;
+import gregtech.api.interfaces.IGuiScreen;
+import gregtech.api.util.GT_UtilityClient;
+
+public class GT_GuiFakeItemButton implements IGuiScreen.IGuiElement {
+
+ private GT_GuiIcon bgIcon;
+ private ItemStack item;
+ private final IGuiScreen gui;
+ private int xPosition, yPosition;
+ private List<String> itemTooltips;
+ private final GT_GuiTooltip tooltip = new GT_GuiTooltip(null) {
+
+ @Override
+ public List<String> getToolTipText() {
+ return itemTooltips;
+ }
+
+ @Override
+ public boolean isDelayed() {
+ return false;
+ }
+
+ @Override
+ public Rectangle getBounds() {
+ return GT_GuiFakeItemButton.this.getBounds();
+ }
+ };
+ private final Rectangle rectangle;
+ private boolean mimicSlot;
+
+ public GT_GuiFakeItemButton(IGuiScreen gui, int x, int y, GT_GuiIcon bgIcon) {
+ this.gui = gui;
+ this.bgIcon = bgIcon;
+ item = null;
+ rectangle = new Rectangle(x, y, 18, 18);
+ gui.addElement(this);
+ }
+
+ public GT_GuiFakeItemButton setItem(ItemStack i) {
+ item = i;
+ if (getMimicSlot()) updateTooltip();
+ return this;
+ }
+
+ private void updateTooltip() {
+ itemTooltips = item == null ? null : GT_UtilityClient.getTooltip(item, true);
+ }
+
+ public ItemStack getItem() {
+ return item;
+ }
+
+ public GT_GuiFakeItemButton setMimicSlot(boolean mimicSlot) {
+ if (mimicSlot != this.mimicSlot) {
+ if (mimicSlot) {
+ updateTooltip();
+ gui.addToolTip(tooltip);
+ } else {
+ gui.removeToolTip(tooltip);
+ }
+ this.mimicSlot = mimicSlot;
+ }
+ return this;
+ }
+
+ public boolean getMimicSlot() {
+ return mimicSlot;
+ }
+
+ public GT_GuiIcon getBgIcon() {
+ return bgIcon;
+ }
+
+ public GT_GuiFakeItemButton setBgIcon(GT_GuiIcon bgIcon) {
+ this.bgIcon = bgIcon;
+ return this;
+ }
+
+ @Override
+ public void onInit() {
+ xPosition = rectangle.x + gui.getGuiLeft();
+ yPosition = rectangle.y + gui.getGuiTop();
+ }
+
+ @Override
+ public void onRemoved() {
+ if (mimicSlot) gui.removeToolTip(tooltip);
+ }
+
+ @Override
+ public void draw(int mouseX, int mouseY, float parTicks) {
+ GL11.glColor4f(1, 1, 1, 1);
+ GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ if (bgIcon != null) {
+ GT_GuiIcon.render(bgIcon, xPosition - 1, yPosition - 1, 18, 18, 0, true);
+ }
+
+ if (item != null) {
+ if (item.getItem() instanceof ItemBlock) {
+ GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
+ GL11.glEnable(GL12.GL_RESCALE_NORMAL);
+ }
+ gui.getItemRenderer()
+ .renderItemAndEffectIntoGUI(
+ gui.getFontRenderer(),
+ Minecraft.getMinecraft()
+ .getTextureManager(),
+ item,
+ xPosition,
+ yPosition);
+
+ if (item.getItem() instanceof ItemBlock) GL11.glPopAttrib();
+ }
+
+ if (getMimicSlot()) if (getBounds().contains(mouseX - gui.getGuiLeft(), mouseY - gui.getGuiTop())) {
+ GL11.glDisable(GL11.GL_LIGHTING);
+ GL11.glDisable(GL11.GL_DEPTH_TEST);
+ GL11.glColorMask(true, true, true, false);
+ GuiDraw.drawGradientRect(xPosition, yPosition, 16, 16, 0x80ffffff, 0x80ffffff);
+ GL11.glColorMask(true, true, true, true);
+ // no glEnable, state will be recovered by glPopAttrib
+ }
+
+ GL11.glPopAttrib();
+ }
+
+ public Rectangle getBounds() {
+ return rectangle;
+ }
+
+ public void setX(int x) {
+ rectangle.x = x;
+ }
+
+ public void setY(int y) {
+ rectangle.y = y;
+ }
+
+ public void setWidth(int width) {
+ rectangle.width = width;
+ }
+
+ public void setHeight(int height) {
+ rectangle.height = height;
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiIcon.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiIcon.java
new file mode 100644
index 0000000000..66ab27356e
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiIcon.java
@@ -0,0 +1,157 @@
+package gregtech.api.gui.widgets;
+
+import static gregtech.api.enums.Mods.GregTech;
+
+import java.util.Arrays;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.util.ResourceLocation;
+
+import gregtech.api.interfaces.IGuiIcon;
+
+public enum GT_GuiIcon implements IGuiIcon {
+
+ BUTTON_NORMAL(0, 0, 0),
+ BUTTON_DOWN(0, 32, 0),
+ BUTTON_HIGHLIGHT(0, 32 * 2, 0),
+ BUTTON_HIGHLIGHT_DOWN(0, 32 * 3, 0),
+ BUTTON_DISABLED(0, 32 * 4, 0),
+
+ DISABLE(0, 0, 32),
+ REDSTONE_OFF(0, 32, 32),
+ REDSTONE_ON(0, 32 * 2, 32),
+ CHECKMARK(0, 32 * 3, 32),
+ CROSS(0, 32 * 4, 32),
+ WHITELIST(0, 32 * 5, 32),
+ BLACKLIST(0, 32 * 6, 32),
+ PROGRESS(0, 32 * 7, 32),
+
+ EXPORT(0, 0, 32 * 2),
+ IMPORT(0, 32, 32 * 2),
+ ALLOW_INPUT(0, 32 * 2, 32 * 2),
+ BLOCK_INPUT(0, 32 * 3, 32 * 2),
+ GREEN_ARROW_UP(0, 32 * 4, 32 * 2),
+ GREEN_ARROW_DOWN(0, 32 * 5, 32 * 2),
+ CYCLIC(0, 32 * 6, 32 * 2),
+
+ AND_GATE(0, 0, 32 * 3),
+ NAND_GATE(0, 32, 32 * 3),
+ OR_GATE(0, 32 * 2, 32 * 3),
+ NOR_GATE(0, 32 * 3, 32 * 3),
+ ANALOG_MODE(0, 32 * 4, 32 * 3),
+
+ SLOT_DARKGRAY(1, 176, 0, 18, 18),
+ SLOT_GRAY(1, 176, 18, 18, 18),
+
+ TAB_NORMAL(2, 0, 0, 18, 20),
+ TAB_HIGHLIGHT(2, 18, 0, 18, 20),
+ TAB_DISABLED(2, 18 * 2, 0, 18, 20),
+ TAB_NORMAL_BRONZE(2, 0, 20, 18, 20),
+ TAB_HIGHLIGHT_BRONZE(2, 18, 20, 18, 20),
+ TAB_DISABLED_BRONZE(2, 18 * 2, 20, 18, 20),
+ TAB_NORMAL_STEEL(2, 0, 2 * 20, 18, 20),
+ TAB_HIGHLIGHT_STEEL(2, 18, 2 * 20, 18, 20),
+ TAB_DISABLED_STEEL(2, 18 * 2, 2 * 20, 18, 20),
+ TAB_NORMAL_BRICK(2, 0, 3 * 20, 18, 20),
+ TAB_HIGHLIGHT_BRICK(2, 18, 3 * 20, 18, 20),
+ TAB_DISABLED_BRICK(2, 18 * 2, 3 * 20, 18, 20),
+ TAB_INFO_GRAY(2, 220, 0, 18, 20),
+ TAB_INFO_BLUE(2, 220 + 18, 0, 18, 20),;
+
+ private static final int T_SIZE = 256;
+ private static ResourceLocation[] TEXTURES = { new ResourceLocation(GregTech.ID, "textures/gui/GuiButtons.png"),
+ new ResourceLocation(GregTech.ID, "textures/gui/GuiCover.png"),
+ new ResourceLocation(GregTech.ID, "textures/gui/GuiTabs.png"), };
+
+ public final int x, y, width, height;
+ public final IGuiIcon overlay;
+ private final int texID;
+
+ GT_GuiIcon(int texID, int x, int y, int width, int height, IGuiIcon overlay) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.overlay = overlay;
+ this.texID = texID;
+ }
+
+ GT_GuiIcon(int texID, int x, int y) {
+ this(texID, x, y, 32, 32, null);
+ }
+
+ GT_GuiIcon(int texID, int x, int y, int width, int height) {
+ this(texID, x, y, width, height, null);
+ }
+
+ public static void render(IGuiIcon icon, double x, double y, double width, double height, double zLevel,
+ boolean doDraw) {
+ render(icon, x, y, width, height, zLevel, doDraw, false);
+ }
+
+ public static void render(IGuiIcon icon, double x, double y, double width, double height, double zLevel,
+ boolean doDraw, boolean flipHoritontally) {
+ Tessellator tess = Tessellator.instance;
+ if (doDraw) {
+ Minecraft.getMinecraft().renderEngine.bindTexture(TEXTURES[icon.getTexId()]);
+ tess.startDrawingQuads();
+ }
+ double minU = (double) (icon.getX() + (flipHoritontally ? icon.getWidth() : 0)) / T_SIZE;
+ double maxU = (double) (icon.getX() + (flipHoritontally ? 0 : icon.getWidth())) / T_SIZE;
+ double minV = (double) icon.getY() / T_SIZE;
+ double maxV = (double) (icon.getY() + icon.getHeight()) / T_SIZE;
+ tess.addVertexWithUV(x, y + height, zLevel, minU, maxV);
+ tess.addVertexWithUV(x + width, y + height, zLevel, maxU, maxV);
+ tess.addVertexWithUV(x + width, y + 0, zLevel, maxU, minV);
+ tess.addVertexWithUV(x, y + 0, zLevel, minU, minV);
+
+ if (icon.getOverlay() != null) render(icon.getOverlay(), x, y, width, height, zLevel, false);
+
+ if (doDraw) tess.draw();
+ }
+
+ /**
+ * This is intended to enable addon mods to register additional textures. They can then add to this enum using
+ * EnumHelper.addEnum or by creating their enum that implements IGuiIcon (still requires adding a texture here)
+ *
+ * @param location location of the texture to add
+ */
+ public static void addTextures(ResourceLocation... location) {
+ if (location == null || location.length == 0) return;
+
+ int startIndex = TEXTURES.length;
+ TEXTURES = Arrays.copyOf(TEXTURES, location.length);
+ System.arraycopy(location, 0, TEXTURES, startIndex, location.length);
+ }
+
+ @Override
+ public int getX() {
+ return this.x;
+ }
+
+ @Override
+ public int getY() {
+ return this.y;
+ }
+
+ @Override
+ public int getWidth() {
+ return this.width;
+ }
+
+ @Override
+ public int getHeight() {
+ return this.height;
+ }
+
+ @Override
+ public int getTexId() {
+ return this.texID;
+ }
+
+ @Override
+ public IGuiIcon getOverlay() {
+ return this.overlay;
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiIconButton.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiIconButton.java
new file mode 100644
index 0000000000..d4bfe31404
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiIconButton.java
@@ -0,0 +1,114 @@
+package gregtech.api.gui.widgets;
+
+import java.awt.Rectangle;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiButton;
+
+import org.lwjgl.opengl.GL11;
+
+import gregtech.api.interfaces.IGuiScreen;
+
+public class GT_GuiIconButton extends GuiButton implements IGuiScreen.IGuiElement {
+
+ public static final int DEFAULT_WIDTH = 16;
+ public static final int DEFAULT_HEIGHT = 16;
+
+ protected GT_GuiIcon icon;
+ private final int x0;
+ private final int y0;
+ protected final IGuiScreen gui;
+
+ private GT_GuiTooltip tooltip;
+
+ public GT_GuiIconButton(IGuiScreen gui, int id, int x, int y, GT_GuiIcon icon) {
+ super(id, x, y, DEFAULT_WIDTH, DEFAULT_HEIGHT, "");
+ this.gui = gui;
+ this.icon = icon;
+ this.x0 = x;
+ this.y0 = y;
+ gui.addElement(this);
+ }
+
+ @Override
+ public void onInit() {
+ if (tooltip != null) gui.addToolTip(tooltip);
+ xPosition = x0 + gui.getGuiLeft();
+ yPosition = y0 + gui.getGuiTop();
+ }
+
+ @Override
+ public void draw(int mouseX, int mouseY, float parTicks) {
+ drawButton(Minecraft.getMinecraft(), mouseX, mouseY);
+ }
+
+ @Override
+ public void drawButton(Minecraft mc, int mouseX, int mouseY) {
+ if (this.tooltip != null) this.tooltip.enabled = true;
+
+ if (this.visible) {
+ // moused over
+ this.field_146123_n = mouseX >= this.xPosition && mouseY >= this.yPosition
+ && mouseX < this.xPosition + width
+ && mouseY < this.yPosition + height;
+
+ mouseDragged(mc, mouseX, mouseY);
+
+ GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ int x = xPosition;
+ int y = yPosition;
+ if (!this.field_146123_n) {
+ // GL11.glColor4f(200F/255F, 210F/255F, 1, 1);
+ } else GL11.glColor4f(1, 1, 1, 1);
+
+ GT_GuiIcon.render(getButtonTexture(this.field_146123_n), x, y, width, height, 0, true);
+
+ GL11.glColor4f(1, 1, 1, 1);
+ if (icon != null) {
+ GT_GuiIcon.render(icon, x, y, width, height, 0, true);
+ }
+
+ GL11.glPopAttrib();
+ }
+ }
+
+ @Override
+ public void mouseReleased(int mouseX, int mouseY) {
+ this.gui.clearSelectedButton();
+ if (mousePressed(Minecraft.getMinecraft(), mouseX, mouseY)) this.gui.buttonClicked(this);
+ }
+
+ public GT_GuiIcon getButtonTexture(boolean mouseOver) {
+ if (!enabled) return GT_GuiIcon.BUTTON_DISABLED;
+ if (this.equals(this.gui.getSelectedButton()))
+ return mouseOver ? GT_GuiIcon.BUTTON_HIGHLIGHT_DOWN : GT_GuiIcon.BUTTON_DOWN;
+
+ return mouseOver ? GT_GuiIcon.BUTTON_HIGHLIGHT : GT_GuiIcon.BUTTON_NORMAL;
+ }
+
+ public GT_GuiIcon getIcon() {
+ return icon;
+ }
+
+ public GT_GuiIconButton setIcon(GT_GuiIcon icon) {
+ this.icon = icon;
+ return this;
+ }
+
+ public GT_GuiTooltip getTooltip() {
+ return tooltip;
+ }
+
+ public GT_GuiIconButton setTooltipText(String... text) {
+ if (tooltip == null) tooltip = new GT_GuiTooltip(getBounds(), text);
+ else tooltip.setToolTipText(text);
+ return this;
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle(x0, y0, width, height);
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiIconCheckButton.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiIconCheckButton.java
new file mode 100644
index 0000000000..5b5007fef3
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiIconCheckButton.java
@@ -0,0 +1,43 @@
+package gregtech.api.gui.widgets;
+
+import gregtech.api.interfaces.IGuiScreen;
+
+public class GT_GuiIconCheckButton extends GT_GuiIconButton {
+
+ private final GT_GuiIcon checkedIcon;
+ private final GT_GuiIcon normalIcon;
+ private final String checkedTooltip;
+ private final String normalTooltip;
+ private boolean checked = false;
+
+ public GT_GuiIconCheckButton(IGuiScreen gui, int id, int x, int y, GT_GuiIcon checkedIcon, GT_GuiIcon normalIcon) {
+ this(gui, id, x, y, checkedIcon, normalIcon, null, null);
+ }
+
+ public GT_GuiIconCheckButton(IGuiScreen gui, int id, int x, int y, GT_GuiIcon checkedIcon, GT_GuiIcon normalIcon,
+ String checkedTooltip, String normalTooltip) {
+ super(gui, id, x, y, normalIcon);
+ this.checkedIcon = checkedIcon;
+ this.normalIcon = normalIcon;
+ this.checkedTooltip = checkedTooltip;
+ this.normalTooltip = normalTooltip;
+ }
+
+ @Override
+ public GT_GuiIcon getButtonTexture(boolean mouseOver) {
+ if (!enabled) return GT_GuiIcon.BUTTON_DISABLED;
+ if (this.equals(super.gui.getSelectedButton()))
+ return mouseOver ? GT_GuiIcon.BUTTON_HIGHLIGHT_DOWN : GT_GuiIcon.BUTTON_DOWN;
+ return mouseOver ? GT_GuiIcon.BUTTON_HIGHLIGHT : GT_GuiIcon.BUTTON_NORMAL;
+ }
+
+ public boolean isChecked() {
+ return checked;
+ }
+
+ public void setChecked(boolean checked) {
+ super.setIcon(checked ? checkedIcon : normalIcon);
+ super.setTooltipText(checked ? checkedTooltip : normalTooltip);
+ this.checked = checked;
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiIntegerTextBox.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiIntegerTextBox.java
new file mode 100644
index 0000000000..2d3c7374bd
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiIntegerTextBox.java
@@ -0,0 +1,73 @@
+package gregtech.api.gui.widgets;
+
+import java.awt.Rectangle;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.GuiTextField;
+
+import gregtech.api.interfaces.IGuiScreen;
+
+public class GT_GuiIntegerTextBox extends GuiTextField implements IGuiScreen.IGuiElement {
+
+ private final int x0, y0;
+ private final IGuiScreen gui;
+ public final int id;
+ private boolean enabled;
+
+ public GT_GuiIntegerTextBox(IGuiScreen gui, int id, int x, int y, int width, int height) {
+ super(Minecraft.getMinecraft().fontRenderer, x, y, width, height);
+ super.setText("");
+ this.id = id;
+ x0 = x;
+ y0 = y;
+ this.gui = gui;
+ enabled = true;
+ gui.addElement(this);
+ }
+
+ @Override
+ public void onInit() {
+ xPosition = x0 + gui.getGuiLeft();
+ yPosition = y0 + gui.getGuiTop();
+ }
+
+ @Override
+ public void draw(int mouseX, int mouseY, float parTicks) {
+ super.drawTextBox();
+ }
+
+ public Rectangle getBounds() {
+ return new Rectangle(x0, y0, width, height);
+ }
+
+ public boolean validChar(char c, int key) {
+ return Character.isDigit(c);
+ }
+
+ @Override
+ public boolean textboxKeyTyped(char c, int key) {
+ if (validChar(c, key) || c == 1
+ || c == 3
+ || c == 22
+ || c == 24
+ || key == 14
+ || key == 199
+ || key == 203
+ || key == 205
+ || key == 207
+ || key == 211) {
+ return super.textboxKeyTyped(c, key);
+ }
+ return false;
+ }
+
+ @Override
+ public void setEnabled(boolean p_146184_1_) {
+ super.setEnabled(p_146184_1_);
+ enabled = p_146184_1_;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java
new file mode 100644
index 0000000000..015c8c7697
--- /dev/null
+++ b/src/main/java/gregtech/api/gui/widgets/GT_GuiSlotTooltip.java
@@ -0,0 +1,24 @@
+package gregtech.api.gui.widgets;
+
+import java.awt.Rectangle;
+
+import net.minecraft.inventory.Slot;
+
+import gregtech.api.util.GT_TooltipDataCache.TooltipData;
+
+public class GT_GuiSlotTooltip extends GT_GuiTooltip {
+
+ private final Slot slot;
+
+ public GT_GuiSlotTooltip(Slot slot, TooltipData data) {
+ super(new Rectangle(slot.xDisplayPosition - 1, slot.yDisplayPosition - 1, 18, 18), data);
+ this.slot = slot;
+ }
+
+ @Override
+ protected void onTick() {
+ super.onTick();
+ // If disabled by super, stay disabled.
+ this.enabled = this.enabled && this.slot.getStack() == null;
+ }
+}
diff --git a/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java b/src/main/java/gregtech/api/gui/widgets/GT_GuiSmartTooltip.java
new file mode 100644
index 0000000000..ffae5c30e6
--- /dev/null
+++ b/