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