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