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