001    package cpw.mods.fml.client;
002    
003    import java.util.List;
004    
005    import net.minecraft.client.Minecraft;
006    import net.minecraft.client.gui.GuiButton;
007    import net.minecraft.client.renderer.Tessellator;
008    
009    import org.lwjgl.input.Mouse;
010    import org.lwjgl.opengl.GL11;
011    
012    public abstract class GuiScrollingList
013    {
014        private final Minecraft client;
015        protected final int listWidth;
016        protected final int listHeight;
017        protected final int top;
018        protected final int bottom;
019        private final int right;
020        protected final int left;
021        protected final int slotHeight;
022        private int scrollUpActionId;
023        private int scrollDownActionId;
024        protected int mouseX;
025        protected int mouseY;
026        private float initialMouseClickY = -2.0F;
027        private float scrollFactor;
028        private float scrollDistance;
029        private int selectedIndex = -1;
030        private long lastClickTime = 0L;
031        private boolean field_25123_p = true;
032        private boolean field_27262_q;
033        private int field_27261_r;
034    
035        public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight)
036        {
037            this.client = client;
038            this.listWidth = width;
039            this.listHeight = height;
040            this.top = top;
041            this.bottom = bottom;
042            this.slotHeight = entryHeight;
043            this.left = left;
044            this.right = width + this.left;
045        }
046    
047        public void func_27258_a(boolean p_27258_1_)
048        {
049            this.field_25123_p = p_27258_1_;
050        }
051    
052        protected void func_27259_a(boolean p_27259_1_, int p_27259_2_)
053        {
054            this.field_27262_q = p_27259_1_;
055            this.field_27261_r = p_27259_2_;
056    
057            if (!p_27259_1_)
058            {
059                this.field_27261_r = 0;
060            }
061        }
062    
063        protected abstract int getSize();
064    
065        protected abstract void elementClicked(int index, boolean doubleClick);
066    
067        protected abstract boolean isSelected(int index);
068    
069        protected int getContentHeight()
070        {
071            return this.getSize() * this.slotHeight + this.field_27261_r;
072        }
073    
074        protected abstract void drawBackground();
075    
076        protected abstract void drawSlot(int var1, int var2, int var3, int var4, Tessellator var5);
077    
078        protected void func_27260_a(int p_27260_1_, int p_27260_2_, Tessellator p_27260_3_) {}
079    
080        protected void func_27255_a(int p_27255_1_, int p_27255_2_) {}
081    
082        protected void func_27257_b(int p_27257_1_, int p_27257_2_) {}
083    
084        public int func_27256_c(int p_27256_1_, int p_27256_2_)
085    
086        {
087            int var3 = this.left + 1;
088            int var4 = this.left + this.listWidth - 7;
089            int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
090            int var6 = var5 / this.slotHeight;
091            return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1;
092        }
093    
094        public void registerScrollButtons(List p_22240_1_, int p_22240_2_, int p_22240_3_)
095        {
096            this.scrollUpActionId = p_22240_2_;
097            this.scrollDownActionId = p_22240_3_;
098        }
099    
100        private void applyScrollLimits()
101        {
102            int var1 = this.getContentHeight() - (this.bottom - this.top - 4);
103    
104            if (var1 < 0)
105            {
106                var1 /= 2;
107            }
108    
109            if (this.scrollDistance < 0.0F)
110            {
111                this.scrollDistance = 0.0F;
112            }
113    
114            if (this.scrollDistance > (float)var1)
115            {
116                this.scrollDistance = (float)var1;
117            }
118        }
119    
120        public void actionPerformed(GuiButton button)
121        {
122            if (button.enabled)
123            {
124                if (button.id == this.scrollUpActionId)
125                {
126                    this.scrollDistance -= (float)(this.slotHeight * 2 / 3);
127                    this.initialMouseClickY = -2.0F;
128                    this.applyScrollLimits();
129                }
130                else if (button.id == this.scrollDownActionId)
131                {
132                    this.scrollDistance += (float)(this.slotHeight * 2 / 3);
133                    this.initialMouseClickY = -2.0F;
134                    this.applyScrollLimits();
135                }
136            }
137        }
138    
139        public void drawScreen(int mouseX, int mouseY, float p_22243_3_)
140        {
141            this.mouseX = mouseX;
142            this.mouseY = mouseY;
143            this.drawBackground();
144            int listLength = this.getSize();
145            int scrollBarXStart = this.left + this.listWidth - 6;
146            int scrollBarXEnd = scrollBarXStart + 6;
147            int boxLeft = this.left;
148            int boxRight = scrollBarXStart-1;
149            int var10;
150            int var11;
151            int var13;
152            int var19;
153    
154            if (Mouse.isButtonDown(0))
155            {
156                if (this.initialMouseClickY == -1.0F)
157                {
158                    boolean var7 = true;
159    
160                    if (mouseY >= this.top && mouseY <= this.bottom)
161                    {
162                        var10 = mouseY - this.top - this.field_27261_r + (int)this.scrollDistance - 4;
163                        var11 = var10 / this.slotHeight;
164    
165                        if (mouseX >= boxLeft && mouseX <= boxRight && var11 >= 0 && var10 >= 0 && var11 < listLength)
166                        {
167                            boolean var12 = var11 == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L;
168                            this.elementClicked(var11, var12);
169                            this.selectedIndex = var11;
170                            this.lastClickTime = System.currentTimeMillis();
171                        }
172                        else if (mouseX >= boxLeft && mouseX <= boxRight && var10 < 0)
173                        {
174                            this.func_27255_a(mouseX - boxLeft, mouseY - this.top + (int)this.scrollDistance - 4);
175                            var7 = false;
176                        }
177    
178                        if (mouseX >= scrollBarXStart && mouseX <= scrollBarXEnd)
179                        {
180                            this.scrollFactor = -1.0F;
181                            var19 = this.getContentHeight() - (this.bottom - this.top - 4);
182    
183                            if (var19 < 1)
184                            {
185                                var19 = 1;
186                            }
187    
188                            var13 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / (float)this.getContentHeight());
189    
190                            if (var13 < 32)
191                            {
192                                var13 = 32;
193                            }
194    
195                            if (var13 > this.bottom - this.top - 8)
196                            {
197                                var13 = this.bottom - this.top - 8;
198                            }
199    
200                            this.scrollFactor /= (float)(this.bottom - this.top - var13) / (float)var19;
201                        }
202                        else
203                        {
204                            this.scrollFactor = 1.0F;
205                        }
206    
207                        if (var7)
208                        {
209                            this.initialMouseClickY = (float)mouseY;
210                        }
211                        else
212                        {
213                            this.initialMouseClickY = -2.0F;
214                        }
215                    }
216                    else
217                    {
218                        this.initialMouseClickY = -2.0F;
219                    }
220                }
221                else if (this.initialMouseClickY >= 0.0F)
222                {
223                    this.scrollDistance -= ((float)mouseY - this.initialMouseClickY) * this.scrollFactor;
224                    this.initialMouseClickY = (float)mouseY;
225                }
226            }
227            else
228            {
229                while (Mouse.next())
230                {
231                    int var16 = Mouse.getEventDWheel();
232    
233                    if (var16 != 0)
234                    {
235                        if (var16 > 0)
236                        {
237                            var16 = -1;
238                        }
239                        else if (var16 < 0)
240                        {
241                            var16 = 1;
242                        }
243    
244                        this.scrollDistance += (float)(var16 * this.slotHeight / 2);
245                    }
246                }
247    
248                this.initialMouseClickY = -1.0F;
249            }
250    
251            this.applyScrollLimits();
252            GL11.glDisable(GL11.GL_LIGHTING);
253            GL11.glDisable(GL11.GL_FOG);
254            Tessellator var18 = Tessellator.instance;
255            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.renderEngine.getTexture("/gui/background.png"));
256            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
257            float var17 = 32.0F;
258            var18.startDrawingQuads();
259            var18.setColorOpaque_I(2105376);
260            var18.addVertexWithUV((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
261            var18.addVertexWithUV((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17));
262            var18.addVertexWithUV((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
263            var18.addVertexWithUV((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17));
264            var18.draw();
265    //        boxRight = this.listWidth / 2 - 92 - 16;
266            var10 = this.top + 4 - (int)this.scrollDistance;
267    
268            if (this.field_27262_q)
269            {
270                this.func_27260_a(boxRight, var10, var18);
271            }
272    
273            int var14;
274    
275            for (var11 = 0; var11 < listLength; ++var11)
276            {
277                var19 = var10 + var11 * this.slotHeight + this.field_27261_r;
278                var13 = this.slotHeight - 4;
279    
280                if (var19 <= this.bottom && var19 + var13 >= this.top)
281                {
282                    if (this.field_25123_p && this.isSelected(var11))
283                    {
284                        var14 = boxLeft;
285                        int var15 = boxRight;
286                        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
287                        GL11.glDisable(GL11.GL_TEXTURE_2D);
288                        var18.startDrawingQuads();
289                        var18.setColorOpaque_I(8421504);
290                        var18.addVertexWithUV((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D);
291                        var18.addVertexWithUV((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D);
292                        var18.addVertexWithUV((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D);
293                        var18.addVertexWithUV((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D);
294                        var18.setColorOpaque_I(0);
295                        var18.addVertexWithUV((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D);
296                        var18.addVertexWithUV((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D);
297                        var18.addVertexWithUV((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D);
298                        var18.addVertexWithUV((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D);
299                        var18.draw();
300                        GL11.glEnable(GL11.GL_TEXTURE_2D);
301                    }
302    
303                    this.drawSlot(var11, boxRight, var19, var13, var18);
304                }
305            }
306    
307            GL11.glDisable(GL11.GL_DEPTH_TEST);
308            byte var20 = 4;
309            this.overlayBackground(0, this.top, 255, 255);
310            this.overlayBackground(this.bottom, this.listHeight, 255, 255);
311            GL11.glEnable(GL11.GL_BLEND);
312            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
313            GL11.glDisable(GL11.GL_ALPHA_TEST);
314            GL11.glShadeModel(GL11.GL_SMOOTH);
315            GL11.glDisable(GL11.GL_TEXTURE_2D);
316            var18.startDrawingQuads();
317            var18.setColorRGBA_I(0, 0);
318            var18.addVertexWithUV((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D);
319            var18.addVertexWithUV((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D);
320            var18.setColorRGBA_I(0, 255);
321            var18.addVertexWithUV((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D);
322            var18.addVertexWithUV((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D);
323            var18.draw();
324            var18.startDrawingQuads();
325            var18.setColorRGBA_I(0, 255);
326            var18.addVertexWithUV((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D);
327            var18.addVertexWithUV((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D);
328            var18.setColorRGBA_I(0, 0);
329            var18.addVertexWithUV((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D);
330            var18.addVertexWithUV((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D);
331            var18.draw();
332            var19 = this.getContentHeight() - (this.bottom - this.top - 4);
333    
334            if (var19 > 0)
335            {
336                var13 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight();
337    
338                if (var13 < 32)
339                {
340                    var13 = 32;
341                }
342    
343                if (var13 > this.bottom - this.top - 8)
344                {
345                    var13 = this.bottom - this.top - 8;
346                }
347    
348                var14 = (int)this.scrollDistance * (this.bottom - this.top - var13) / var19 + this.top;
349    
350                if (var14 < this.top)
351                {
352                    var14 = this.top;
353                }
354    
355                var18.startDrawingQuads();
356                var18.setColorRGBA_I(0, 255);
357                var18.addVertexWithUV((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D);
358                var18.addVertexWithUV((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D);
359                var18.addVertexWithUV((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D);
360                var18.addVertexWithUV((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D);
361                var18.draw();
362                var18.startDrawingQuads();
363                var18.setColorRGBA_I(8421504, 255);
364                var18.addVertexWithUV((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D);
365                var18.addVertexWithUV((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D);
366                var18.addVertexWithUV((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D);
367                var18.addVertexWithUV((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
368                var18.draw();
369                var18.startDrawingQuads();
370                var18.setColorRGBA_I(12632256, 255);
371                var18.addVertexWithUV((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D);
372                var18.addVertexWithUV((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D);
373                var18.addVertexWithUV((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D);
374                var18.addVertexWithUV((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D);
375                var18.draw();
376            }
377    
378            this.func_27257_b(mouseX, mouseY);
379            GL11.glEnable(GL11.GL_TEXTURE_2D);
380            GL11.glShadeModel(GL11.GL_FLAT);
381            GL11.glEnable(GL11.GL_ALPHA_TEST);
382            GL11.glDisable(GL11.GL_BLEND);
383        }
384    
385        private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_)
386        {
387            Tessellator var5 = Tessellator.instance;
388            GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.client.renderEngine.getTexture("/gui/background.png"));
389            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
390            float var6 = 32.0F;
391            var5.startDrawingQuads();
392            var5.setColorRGBA_I(4210752, p_22239_4_);
393            var5.addVertexWithUV(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6));
394            var5.addVertexWithUV((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6));
395            var5.setColorRGBA_I(4210752, p_22239_3_);
396            var5.addVertexWithUV((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6));
397            var5.addVertexWithUV(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6));
398            var5.draw();
399        }
400    }