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 (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 }