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 }