    001    package net.minecraft.client.gui;
    002
    003    import cpw.mods.fml.common.Side;
    004    import cpw.mods.fml.common.asm.SideOnly;
    005    import java.util.List;
    006    import net.minecraft.client.Minecraft;
    007    import net.minecraft.client.renderer.Tessellator;
    008    import org.lwjgl.input.Mouse;
    009    import org.lwjgl.opengl.GL11;
    010
    011    @SideOnly(Side.CLIENT)
    012    public abstract class GuiSlot
    013    {
    014        private final Minecraft mc;
    015
    016        /**
    017         * The width of the GuiScreen. Affects the container rendering, but not the overlays.
    018         */
    019        private int width;
    020
    021        /**
    022         * The height of the GuiScreen. Affects the container rendering, but not the overlays or the scrolling.
    023         */
    024        private int height;
    025
    026        /** The top of the slot container. Affects the overlays and scrolling. */
    027        protected int top;
    028
    029        /** The bottom of the slot container. Affects the overlays and scrolling. */
    030        protected int bottom;
    031        private int right;
    032        private int left;
    033
    034        /** The height of a slot. */
    035        protected final int slotHeight;
    036
    037        /** button id of the button used to scroll up */
    038        private int scrollUpButtonID;
    039
    040        /** the buttonID of the button used to scroll down */
    041        private int scrollDownButtonID;
    042
    043        /** X axis position of the mouse */
    044        protected int mouseX;
    045
    046        /** Y axis position of the mouse */
    047        protected int mouseY;
    048
    049        /** where the mouse was in the window when you first clicked to scroll */
    050        private float initialClickY = -2.0F;
    051
    052        /**
    053         * what to multiply the amount you moved your mouse by(used for slowing down scrolling when over the items and no on
    054         * scroll bar)
    055         */
    056        private float scrollMultiplier;
    057
    058        /** how far down this slot has been scrolled */
    059        private float amountScrolled;
    060
    061        /** the element in the list that was selected */
    062        private int selectedElement = -1;
    063
    064        /** the time when this button was last clicked. */
    065        private long lastClicked = 0L;
    066
    067        /** true if a selected element in this gui will show an outline box */
    068        private boolean showSelectionBox = true;
    069        private boolean field_77243_s;
    070        private int field_77242_t;
    071
    072        public String BACKGROUND_IMAGE = "/gui/background.png";
    073
    074        public GuiSlot(Minecraft par1Minecraft, int par2, int par3, int par4, int par5, int par6)
    075        {
    076            this.mc = par1Minecraft;
    077            this.width = par2;
    078            this.height = par3;
    079            this.top = par4;
    080            this.bottom = par5;
    081            this.slotHeight = par6;
    082            this.left = 0;
    083            this.right = par2;
    084        }
    085
    086        public void func_77207_a(int par1, int par2, int par3, int par4)
    087        {
    088            this.width = par1;
    089            this.height = par2;
    090            this.top = par3;
    091            this.bottom = par4;
    092            this.left = 0;
    093            this.right = par1;
    094        }
    095
    096        public void setShowSelectionBox(boolean par1)
    097        {
    098            this.showSelectionBox = par1;
    099        }
    100
    101        protected void func_77223_a(boolean par1, int par2)
    102        {
    103            this.field_77243_s = par1;
    104            this.field_77242_t = par2;
    105
    106            if (!par1)
    107            {
    108                this.field_77242_t = 0;
    109            }
    110        }
    111
    112        /**
    113         * Gets the size of the current slot list.
    114         */
    115        protected abstract int getSize();
    116
    117        /**
    118         * the element in the slot that was clicked, boolean for wether it was double clicked or not
    119         */
    120        protected abstract void elementClicked(int var1, boolean var2);
    121
    122        /**
    123         * returns true if the element passed in is currently selected
    124         */
    125        protected abstract boolean isSelected(int var1);
    126
    127        /**
    128         * return the height of the content being scrolled
    129         */
    130        protected int getContentHeight()
    131        {
    132            return this.getSize() * this.slotHeight + this.field_77242_t;
    133        }
    134
    135        protected abstract void drawBackground();
    136
    137        protected abstract void drawSlot(int var1, int var2, int var3, int var4, Tessellator var5);
    138
    139        protected void func_77222_a(int par1, int par2, Tessellator par3Tessellator) {}
    140
    141        protected void func_77224_a(int par1, int par2) {}
    142
    143        protected void func_77215_b(int par1, int par2) {}
    144
    145        public int func_77210_c(int par1, int par2)
    146        {
    147            int var3 = this.width / 2 - 110;
    148            int var4 = this.width / 2 + 110;
    149            int var5 = par2 - this.top - this.field_77242_t + (int)this.amountScrolled - 4;
    150            int var6 = var5 / this.slotHeight;
    151            return par1 >= var3 && par1 <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
    152        }
    153
    154        /**
    155         * Registers the IDs that can be used for the scrollbar's buttons.
    156         */
    157        public void registerScrollButtons(List par1List, int par2, int par3)
    158        {
    159            this.scrollUpButtonID = par2;
    160            this.scrollDownButtonID = par3;
    161        }
    162
    163        /**
    164         * stop the thing from scrolling out of bounds
    165         */
    166        private void bindAmountScrolled()
    167        {
    168            int var1 = this.func_77209_d();
    169
    170            if (var1 < 0)
    171            {
    172                var1 /= 2;
    173            }
    174
    175            if (this.amountScrolled < 0.0F)
    176            {
    177                this.amountScrolled = 0.0F;
    178            }
    179
    180            if (this.amountScrolled > (float)var1)
    181            {
    182                this.amountScrolled = (float)var1;
    183            }
    184        }
    185
    186        public int func_77209_d()
    187        {
    188            return this.getContentHeight() - (this.bottom - this.top - 4);
    189        }
    190
    191        public void func_77208_b(int par1)
    192        {
    193            this.amountScrolled += (float)par1;
    194            this.bindAmountScrolled();
    195            this.initialClickY = -2.0F;
    196        }
    197
    198        public void actionPerformed(GuiButton par1GuiButton)
    199        {
    200            if (par1GuiButton.enabled)
    201            {
    202                if (par1GuiButton.id == this.scrollUpButtonID)
    203                {
    204                    this.amountScrolled -= (float)(this.slotHeight * 2 / 3);
    205                    this.initialClickY = -2.0F;
    206                    this.bindAmountScrolled();
    207                }
    208                else if (par1GuiButton.id == this.scrollDownButtonID)
    209                {
    210                    this.amountScrolled += (float)(this.slotHeight * 2 / 3);
    211                    this.initialClickY = -2.0F;
    212                    this.bindAmountScrolled();
    213                }
    214            }
    215        }
    216
    217        /**
    218         * draws the slot to the screen, pass in mouse's current x and y and partial ticks
    219         */
    220        public void drawScreen(int par1, int par2, float par3)
    221        {
    222            this.mouseX = par1;
    223            this.mouseY = par2;
    224            this.drawBackground();
    225            int var4 = this.getSize();
    226            int var5 = this.getScrollBarX();
    227            int var6 = var5 + 6;
    228            int var9;
    229            int var10;
    230            int var11;
    231            int var13;
    232            int var19;
    233
    234            if (Mouse.isButtonDown(0))
    235            {
    236                if (this.initialClickY == -1.0F)
    237                {
    238                    boolean var7 = true;
    239
    240                    if (par2 >= this.top && par2 <= this.bottom)
    241                    {
    242                        int var8 = this.width / 2 - 110;
    243                        var9 = this.width / 2 + 110;
    244                        var10 = par2 - this.top - this.field_77242_t + (int)this.amountScrolled - 4;
    245                        var11 = var10 / this.slotHeight;
    246
    247                        if (par1 >= var8 && par1 <= var9 && var11 >= 0 && var10 >= 0 && var11 < var4)
    248                        {
    249                            boolean var12 = var11 == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L;
    250                            this.elementClicked(var11, var12);
    251                            this.selectedElement = var11;
    252                            this.lastClicked = Minecraft.getSystemTime();
    253                        }
    254                        else if (par1 >= var8 && par1 <= var9 && var10 < 0)
    255                        {
    256                            this.func_77224_a(par1 - var8, par2 - this.top + (int)this.amountScrolled - 4);
    257                            var7 = false;
    258                        }
    259
    260                        if (par1 >= var5 && par1 <= var6)
    261                        {
    262                            this.scrollMultiplier = -1.0F;
    263                            var19 = this.func_77209_d();
    264
    265                            if (var19 < 1)
    266                            {
    267                                var19 = 1;
    268                            }
    269
    270                            var13 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / (float)this.getContentHeight());
    271
    272                            if (var13 < 32)
    273                            {
    274                                var13 = 32;
    275                            }
    276
    277                            if (var13 > this.bottom - this.top - 8)
    278                            {
    279                                var13 = this.bottom - this.top - 8;
    280                            }
    281
    282                            this.scrollMultiplier /= (float)(this.bottom - this.top - var13) / (float)var19;
    283                        }
    284                        else
    285                        {
    286                            this.scrollMultiplier = 1.0F;
    287                        }
    288
    289                        if (var7)
    290                        {
    291                            this.initialClickY = (float)par2;
    292                        }
    293                        else
    294                        {
    295                            this.initialClickY = -2.0F;
    296                        }
    297                    }
    298                    else
    299                    {
    300                        this.initialClickY = -2.0F;
    301                    }
    302                }
    303                else if (this.initialClickY >= 0.0F)
    304                {
    305                    this.amountScrolled -= ((float)par2 - this.initialClickY) * this.scrollMultiplier;
    306                    this.initialClickY = (float)par2;
    307                }
    308            }
    309            else
    310            {
    311                while (!this.mc.gameSettings.field_85185_A && Mouse.next())
    312                {
    313                    int var16 = Mouse.getEventDWheel();
    314
    315                    if (var16 != 0)
    316                    {
    317                        if (var16 > 0)
    318                        {
    319                            var16 = -1;
    320                        }
    321                        else if (var16 < 0)
    322                        {
    323                            var16 = 1;
    324                        }
    325
    326                        this.amountScrolled += (float)(var16 * this.slotHeight / 2);
    327                    }
    328                }
    329
    330                this.initialClickY = -1.0F;
    331            }
    332
    333            this.bindAmountScrolled();
    334            GL11.glDisable(GL11.GL_LIGHTING);
    335            GL11.glDisable(GL11.GL_FOG);
    336            Tessellator var18 = Tessellator.instance;
    337            drawContainerBackground(var18);
    338            var9 = this.width / 2 - 92 - 16;
    339            var10 = this.top + 4 - (int)this.amountScrolled;
    340
    341            if (this.field_77243_s)
    342            {
    343                this.func_77222_a(var9, var10, var18);
    344            }
    345
    346            int var14;
    347
    348            for (var11 = 0; var11 < var4; ++var11)
    349            {
    350                var19 = var10 + var11 * this.slotHeight + this.field_77242_t;
    351                var13 = this.slotHeight - 4;
    352
    353                if (var19 <= this.bottom && var19 + var13 >= this.top)
    354                {
    355                    if (this.showSelectionBox && this.isSelected(var11))
    356                    {
    357                        var14 = this.width / 2 - 110;
    358                        int var15 = this.width / 2 + 110;
    359                        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    360                        GL11.glDisable(GL11.GL_TEXTURE_2D);
    361                        var18.startDrawingQuads();
    362                        var18.setColorOpaque_I(8421504);
    363                        var18.addVertexWithUV((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
    364                        var18.addVertexWithUV((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
    365                        var18.addVertexWithUV((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
    366                        var18.addVertexWithUV((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
    367                        var18.setColorOpaque_I(0);
    368                        var18.addVertexWithUV((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
    369                        var18.addVertexWithUV((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
    370                        var18.addVertexWithUV((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
    371                        var18.addVertexWithUV((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
    372                        var18.draw();
    373                        GL11.glEnable(GL11.GL_TEXTURE_2D);
    374                    }
    375
    376                    this.drawSlot(var11, var9, var19, var13, var18);
    377                }
    378            }
    379
    380            GL11.glDisable(GL11.GL_DEPTH_TEST);
    381            byte var20 = 4;
    382            this.overlayBackground(0, this.top, 255, 255);
    383            this.overlayBackground(this.bottom, this.height, 255, 255);
    384            GL11.glEnable(GL11.GL_BLEND);
    385            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    386            GL11.glDisable(GL11.GL_ALPHA_TEST);
    387            GL11.glShadeModel(GL11.GL_SMOOTH);
    388            GL11.glDisable(GL11.GL_TEXTURE_2D);
    389            var18.startDrawingQuads();
    390            var18.setColorRGBA_I(0, 0);
    391            var18.addVertexWithUV((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
    392            var18.addVertexWithUV((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
    393            var18.setColorRGBA_I(0, 255);
    394            var18.addVertexWithUV((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
    395            var18.addVertexWithUV((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
    396            var18.draw();
    397            var18.startDrawingQuads();
    398            var18.setColorRGBA_I(0, 255);
    399            var18.addVertexWithUV((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
    400            var18.addVertexWithUV((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
    401            var18.setColorRGBA_I(0, 0);
    402            var18.addVertexWithUV((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
    403            var18.addVertexWithUV((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
    404            var18.draw();
    405            var19 = this.func_77209_d();
    406
    407            if (var19 > 0)
    408            {
    409                var13 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight();
    410
    411                if (var13 < 32)
    412                {
    413                    var13 = 32;
    414                }
    415
    416                if (var13 > this.bottom - this.top - 8)
    417                {
    418                    var13 = this.bottom - this.top - 8;
    419                }
    420
    421                var14 = (int)this.amountScrolled * (this.bottom - this.top - var13) / var19 + this.top;
    422
    423                if (var14 < this.top)
    424                {
    425                    var14 = this.top;
    426                }
    427
    428                var18.startDrawingQuads();
    429                var18.setColorRGBA_I(0, 255);
    430                var18.addVertexWithUV((double)var5, (double)this.bottom, 0.0D, 0.0D, 1.0D);
    431                var18.addVertexWithUV((double)var6, (double)this.bottom, 0.0D, 1.0D, 1.0D);
    432                var18.addVertexWithUV((double)var6, (double)this.top, 0.0D, 1.0D, 0.0D);
    433                var18.addVertexWithUV((double)var5, (double)this.top, 0.0D, 0.0D, 0.0D);
    434                var18.draw();
    435                var18.startDrawingQuads();
    436                var18.setColorRGBA_I(8421504, 255);
    437                var18.addVertexWithUV((double)var5, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
    438                var18.addVertexWithUV((double)var6, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
    439                var18.addVertexWithUV((double)var6, (double)var14, 0.0D, 1.0D, 0.0D);
    440                var18.addVertexWithUV((double)var5, (double)var14, 0.0D, 0.0D, 0.0D);
    441                var18.draw();
    442                var18.startDrawingQuads();
    443                var18.setColorRGBA_I(12632256, 255);
    444                var18.addVertexWithUV((double)var5, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
    445                var18.addVertexWithUV((double)(var6 - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
    446                var18.addVertexWithUV((double)(var6 - 1), (double)var14, 0.0D, 1.0D, 0.0D);
    447                var18.addVertexWithUV((double)var5, (double)var14, 0.0D, 0.0D, 0.0D);
    448                var18.draw();
    449            }
    450
    451            this.func_77215_b(par1, par2);
    452            GL11.glEnable(GL11.GL_TEXTURE_2D);
    453            GL11.glShadeModel(GL11.GL_FLAT);
    454            GL11.glEnable(GL11.GL_ALPHA_TEST);
    455            GL11.glDisable(GL11.GL_BLEND);
    456        }
    457
    458        protected int getScrollBarX()
    459        {
    460            return this.width / 2 + 124;
    461        }
    462
    463        /**
    464         * Overlays the background to hide scrolled items
    465         */
    466        protected void overlayBackground(int par1, int par2, int par3, int par4)
    467        {
    468            Tessellator var5 = Tessellator.instance;
    469            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.mc.renderEngine.getTexture(BACKGROUND_IMAGE));
    470            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    471            float var6 = 32.0F;
    472            var5.startDrawingQuads();
    473            var5.setColorRGBA_I(4210752, par4);
    474            var5.addVertexWithUV(0.0D, (double)par2, 0.0D, 0.0D, (double)((float)par2 / var6));
    475            var5.addVertexWithUV((double)this.width, (double)par2, 0.0D, (double)((float)this.width / var6), (double)((float)par2 / var6));
    476            var5.setColorRGBA_I(4210752, par3);
    477            var5.addVertexWithUV((double)this.width, (double)par1, 0.0D, (double)((float)this.width / var6), (double)((float)par1 / var6));
    478            var5.addVertexWithUV(0.0D, (double)par1, 0.0D, 0.0D, (double)((float)par1 / var6));
    479            var5.draw();
    480        }
    481
    482        protected void drawContainerBackground(Tessellator tess)
    483        {
    484            GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(BACKGROUND_IMAGE));
    485            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
    486            float height = 32.0F;
    487            tess.startDrawingQuads();
    488            tess.setColorOpaque_I(2105376);
    489            tess.addVertexWithUV((double)left,  (double)bottom, 0.0D, (double)(left  / height), (double)((bottom + (int)amountScrolled) / height));
    490            tess.addVertexWithUV((double)right, (double)bottom, 0.0D, (double)(right / height), (double)((bottom + (int)amountScrolled) / height));
    491            tess.addVertexWithUV((double)right, (double)top,    0.0D, (double)(right / height), (double)((top    + (int)amountScrolled) / height));
    492            tess.addVertexWithUV((double)left,  (double)top,    0.0D, (double)(left  / height), (double)((top    + (int)amountScrolled) / height));
    493            tess.draw();
    494        }
    495    }