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