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