001package cpw.mods.fml.client;
002
003import java.util.List;
004
005import net.minecraft.client.Minecraft;
006import net.minecraft.client.gui.GuiButton;
007import net.minecraft.client.renderer.Tessellator;
008
009import org.lwjgl.input.Mouse;
010import org.lwjgl.opengl.GL11;
011
012public 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}