001/* 002 * Forge Mod Loader 003 * Copyright (c) 2012-2013 cpw. 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser Public License v2.1 006 * which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 008 * 009 * Contributors: 010 * cpw - implementation 011 */ 012 013package cpw.mods.fml.client; 014 015import java.util.List; 016 017import net.minecraft.client.Minecraft; 018import net.minecraft.client.gui.GuiButton; 019import net.minecraft.client.renderer.Tessellator; 020 021import org.lwjgl.input.Mouse; 022import org.lwjgl.opengl.GL11; 023 024public abstract class GuiScrollingList 025{ 026 private final Minecraft client; 027 protected final int listWidth; 028 protected final int listHeight; 029 protected final int top; 030 protected final int bottom; 031 private final int right; 032 protected final int left; 033 protected final int slotHeight; 034 private int scrollUpActionId; 035 private int scrollDownActionId; 036 protected int mouseX; 037 protected int mouseY; 038 private float initialMouseClickY = -2.0F; 039 private float scrollFactor; 040 private float scrollDistance; 041 private int selectedIndex = -1; 042 private long lastClickTime = 0L; 043 private boolean field_25123_p = true; 044 private boolean field_27262_q; 045 private int field_27261_r; 046 047 public GuiScrollingList(Minecraft client, int width, int height, int top, int bottom, int left, int entryHeight) 048 { 049 this.client = client; 050 this.listWidth = width; 051 this.listHeight = height; 052 this.top = top; 053 this.bottom = bottom; 054 this.slotHeight = entryHeight; 055 this.left = left; 056 this.right = width + this.left; 057 } 058 059 public void func_27258_a(boolean p_27258_1_) 060 { 061 this.field_25123_p = p_27258_1_; 062 } 063 064 protected void func_27259_a(boolean p_27259_1_, int p_27259_2_) 065 { 066 this.field_27262_q = p_27259_1_; 067 this.field_27261_r = p_27259_2_; 068 069 if (!p_27259_1_) 070 { 071 this.field_27261_r = 0; 072 } 073 } 074 075 protected abstract int getSize(); 076 077 protected abstract void elementClicked(int index, boolean doubleClick); 078 079 protected abstract boolean isSelected(int index); 080 081 protected int getContentHeight() 082 { 083 return this.getSize() * this.slotHeight + this.field_27261_r; 084 } 085 086 protected abstract void drawBackground(); 087 088 protected abstract void drawSlot(int var1, int var2, int var3, int var4, Tessellator var5); 089 090 protected void func_27260_a(int p_27260_1_, int p_27260_2_, Tessellator p_27260_3_) {} 091 092 protected void func_27255_a(int p_27255_1_, int p_27255_2_) {} 093 094 protected void func_27257_b(int p_27257_1_, int p_27257_2_) {} 095 096 public int func_27256_c(int p_27256_1_, int p_27256_2_) 097 098 { 099 int var3 = this.left + 1; 100 int var4 = this.left + this.listWidth - 7; 101 int var5 = p_27256_2_ - this.top - this.field_27261_r + (int)this.scrollDistance - 4; 102 int var6 = var5 / this.slotHeight; 103 return p_27256_1_ >= var3 && p_27256_1_ <= var4 && var6 >= 0 && var5 >= 0 && var6 < this.getSize() ? var6 : -1; 104 } 105 106 public void registerScrollButtons(List p_22240_1_, int p_22240_2_, int p_22240_3_) 107 { 108 this.scrollUpActionId = p_22240_2_; 109 this.scrollDownActionId = p_22240_3_; 110 } 111 112 private void applyScrollLimits() 113 { 114 int var1 = this.getContentHeight() - (this.bottom - this.top - 4); 115 116 if (var1 < 0) 117 { 118 var1 /= 2; 119 } 120 121 if (this.scrollDistance < 0.0F) 122 { 123 this.scrollDistance = 0.0F; 124 } 125 126 if (this.scrollDistance > (float)var1) 127 { 128 this.scrollDistance = (float)var1; 129 } 130 } 131 132 public void actionPerformed(GuiButton button) 133 { 134 if (button.enabled) 135 { 136 if (button.id == this.scrollUpActionId) 137 { 138 this.scrollDistance -= (float)(this.slotHeight * 2 / 3); 139 this.initialMouseClickY = -2.0F; 140 this.applyScrollLimits(); 141 } 142 else if (button.id == this.scrollDownActionId) 143 { 144 this.scrollDistance += (float)(this.slotHeight * 2 / 3); 145 this.initialMouseClickY = -2.0F; 146 this.applyScrollLimits(); 147 } 148 } 149 } 150 151 public void drawScreen(int mouseX, int mouseY, float p_22243_3_) 152 { 153 this.mouseX = mouseX; 154 this.mouseY = mouseY; 155 this.drawBackground(); 156 int listLength = this.getSize(); 157 int scrollBarXStart = this.left + this.listWidth - 6; 158 int scrollBarXEnd = scrollBarXStart + 6; 159 int boxLeft = this.left; 160 int boxRight = scrollBarXStart-1; 161 int var10; 162 int var11; 163 int var13; 164 int var19; 165 166 if (Mouse.isButtonDown(0)) 167 { 168 if (this.initialMouseClickY == -1.0F) 169 { 170 boolean var7 = true; 171 172 if (mouseY >= this.top && mouseY <= this.bottom) 173 { 174 var10 = mouseY - this.top - this.field_27261_r + (int)this.scrollDistance - 4; 175 var11 = var10 / this.slotHeight; 176 177 if (mouseX >= boxLeft && mouseX <= boxRight && var11 >= 0 && var10 >= 0 && var11 < listLength) 178 { 179 boolean var12 = var11 == this.selectedIndex && System.currentTimeMillis() - this.lastClickTime < 250L; 180 this.elementClicked(var11, var12); 181 this.selectedIndex = var11; 182 this.lastClickTime = System.currentTimeMillis(); 183 } 184 else if (mouseX >= boxLeft && mouseX <= boxRight && var10 < 0) 185 { 186 this.func_27255_a(mouseX - boxLeft, mouseY - this.top + (int)this.scrollDistance - 4); 187 var7 = false; 188 } 189 190 if (mouseX >= scrollBarXStart && mouseX <= scrollBarXEnd) 191 { 192 this.scrollFactor = -1.0F; 193 var19 = this.getContentHeight() - (this.bottom - this.top - 4); 194 195 if (var19 < 1) 196 { 197 var19 = 1; 198 } 199 200 var13 = (int)((float)((this.bottom - this.top) * (this.bottom - this.top)) / (float)this.getContentHeight()); 201 202 if (var13 < 32) 203 { 204 var13 = 32; 205 } 206 207 if (var13 > this.bottom - this.top - 8) 208 { 209 var13 = this.bottom - this.top - 8; 210 } 211 212 this.scrollFactor /= (float)(this.bottom - this.top - var13) / (float)var19; 213 } 214 else 215 { 216 this.scrollFactor = 1.0F; 217 } 218 219 if (var7) 220 { 221 this.initialMouseClickY = (float)mouseY; 222 } 223 else 224 { 225 this.initialMouseClickY = -2.0F; 226 } 227 } 228 else 229 { 230 this.initialMouseClickY = -2.0F; 231 } 232 } 233 else if (this.initialMouseClickY >= 0.0F) 234 { 235 this.scrollDistance -= ((float)mouseY - this.initialMouseClickY) * this.scrollFactor; 236 this.initialMouseClickY = (float)mouseY; 237 } 238 } 239 else 240 { 241 while (Mouse.next()) 242 { 243 int var16 = Mouse.getEventDWheel(); 244 245 if (var16 != 0) 246 { 247 if (var16 > 0) 248 { 249 var16 = -1; 250 } 251 else if (var16 < 0) 252 { 253 var16 = 1; 254 } 255 256 this.scrollDistance += (float)(var16 * this.slotHeight / 2); 257 } 258 } 259 260 this.initialMouseClickY = -1.0F; 261 } 262 263 this.applyScrollLimits(); 264 GL11.glDisable(GL11.GL_LIGHTING); 265 GL11.glDisable(GL11.GL_FOG); 266 Tessellator var18 = Tessellator.instance; 267 this.client.renderEngine.func_98187_b("/gui/background.png"); 268 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 269 float var17 = 32.0F; 270 var18.startDrawingQuads(); 271 var18.setColorOpaque_I(2105376); 272 var18.addVertexWithUV((double)this.left, (double)this.bottom, 0.0D, (double)((float)this.left / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17)); 273 var18.addVertexWithUV((double)this.right, (double)this.bottom, 0.0D, (double)((float)this.right / var17), (double)((float)(this.bottom + (int)this.scrollDistance) / var17)); 274 var18.addVertexWithUV((double)this.right, (double)this.top, 0.0D, (double)((float)this.right / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17)); 275 var18.addVertexWithUV((double)this.left, (double)this.top, 0.0D, (double)((float)this.left / var17), (double)((float)(this.top + (int)this.scrollDistance) / var17)); 276 var18.draw(); 277// boxRight = this.listWidth / 2 - 92 - 16; 278 var10 = this.top + 4 - (int)this.scrollDistance; 279 280 if (this.field_27262_q) 281 { 282 this.func_27260_a(boxRight, var10, var18); 283 } 284 285 int var14; 286 287 for (var11 = 0; var11 < listLength; ++var11) 288 { 289 var19 = var10 + var11 * this.slotHeight + this.field_27261_r; 290 var13 = this.slotHeight - 4; 291 292 if (var19 <= this.bottom && var19 + var13 >= this.top) 293 { 294 if (this.field_25123_p && this.isSelected(var11)) 295 { 296 var14 = boxLeft; 297 int var15 = boxRight; 298 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 299 GL11.glDisable(GL11.GL_TEXTURE_2D); 300 var18.startDrawingQuads(); 301 var18.setColorOpaque_I(8421504); 302 var18.addVertexWithUV((double)var14, (double)(var19 + var13 + 2), 0.0D, 0.0D, 1.0D); 303 var18.addVertexWithUV((double)var15, (double)(var19 + var13 + 2), 0.0D, 1.0D, 1.0D); 304 var18.addVertexWithUV((double)var15, (double)(var19 - 2), 0.0D, 1.0D, 0.0D); 305 var18.addVertexWithUV((double)var14, (double)(var19 - 2), 0.0D, 0.0D, 0.0D); 306 var18.setColorOpaque_I(0); 307 var18.addVertexWithUV((double)(var14 + 1), (double)(var19 + var13 + 1), 0.0D, 0.0D, 1.0D); 308 var18.addVertexWithUV((double)(var15 - 1), (double)(var19 + var13 + 1), 0.0D, 1.0D, 1.0D); 309 var18.addVertexWithUV((double)(var15 - 1), (double)(var19 - 1), 0.0D, 1.0D, 0.0D); 310 var18.addVertexWithUV((double)(var14 + 1), (double)(var19 - 1), 0.0D, 0.0D, 0.0D); 311 var18.draw(); 312 GL11.glEnable(GL11.GL_TEXTURE_2D); 313 } 314 315 this.drawSlot(var11, boxRight, var19, var13, var18); 316 } 317 } 318 319 GL11.glDisable(GL11.GL_DEPTH_TEST); 320 byte var20 = 4; 321 this.overlayBackground(0, this.top, 255, 255); 322 this.overlayBackground(this.bottom, this.listHeight, 255, 255); 323 GL11.glEnable(GL11.GL_BLEND); 324 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); 325 GL11.glDisable(GL11.GL_ALPHA_TEST); 326 GL11.glShadeModel(GL11.GL_SMOOTH); 327 GL11.glDisable(GL11.GL_TEXTURE_2D); 328 var18.startDrawingQuads(); 329 var18.setColorRGBA_I(0, 0); 330 var18.addVertexWithUV((double)this.left, (double)(this.top + var20), 0.0D, 0.0D, 1.0D); 331 var18.addVertexWithUV((double)this.right, (double)(this.top + var20), 0.0D, 1.0D, 1.0D); 332 var18.setColorRGBA_I(0, 255); 333 var18.addVertexWithUV((double)this.right, (double)this.top, 0.0D, 1.0D, 0.0D); 334 var18.addVertexWithUV((double)this.left, (double)this.top, 0.0D, 0.0D, 0.0D); 335 var18.draw(); 336 var18.startDrawingQuads(); 337 var18.setColorRGBA_I(0, 255); 338 var18.addVertexWithUV((double)this.left, (double)this.bottom, 0.0D, 0.0D, 1.0D); 339 var18.addVertexWithUV((double)this.right, (double)this.bottom, 0.0D, 1.0D, 1.0D); 340 var18.setColorRGBA_I(0, 0); 341 var18.addVertexWithUV((double)this.right, (double)(this.bottom - var20), 0.0D, 1.0D, 0.0D); 342 var18.addVertexWithUV((double)this.left, (double)(this.bottom - var20), 0.0D, 0.0D, 0.0D); 343 var18.draw(); 344 var19 = this.getContentHeight() - (this.bottom - this.top - 4); 345 346 if (var19 > 0) 347 { 348 var13 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight(); 349 350 if (var13 < 32) 351 { 352 var13 = 32; 353 } 354 355 if (var13 > this.bottom - this.top - 8) 356 { 357 var13 = this.bottom - this.top - 8; 358 } 359 360 var14 = (int)this.scrollDistance * (this.bottom - this.top - var13) / var19 + this.top; 361 362 if (var14 < this.top) 363 { 364 var14 = this.top; 365 } 366 367 var18.startDrawingQuads(); 368 var18.setColorRGBA_I(0, 255); 369 var18.addVertexWithUV((double)scrollBarXStart, (double)this.bottom, 0.0D, 0.0D, 1.0D); 370 var18.addVertexWithUV((double)scrollBarXEnd, (double)this.bottom, 0.0D, 1.0D, 1.0D); 371 var18.addVertexWithUV((double)scrollBarXEnd, (double)this.top, 0.0D, 1.0D, 0.0D); 372 var18.addVertexWithUV((double)scrollBarXStart, (double)this.top, 0.0D, 0.0D, 0.0D); 373 var18.draw(); 374 var18.startDrawingQuads(); 375 var18.setColorRGBA_I(8421504, 255); 376 var18.addVertexWithUV((double)scrollBarXStart, (double)(var14 + var13), 0.0D, 0.0D, 1.0D); 377 var18.addVertexWithUV((double)scrollBarXEnd, (double)(var14 + var13), 0.0D, 1.0D, 1.0D); 378 var18.addVertexWithUV((double)scrollBarXEnd, (double)var14, 0.0D, 1.0D, 0.0D); 379 var18.addVertexWithUV((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D); 380 var18.draw(); 381 var18.startDrawingQuads(); 382 var18.setColorRGBA_I(12632256, 255); 383 var18.addVertexWithUV((double)scrollBarXStart, (double)(var14 + var13 - 1), 0.0D, 0.0D, 1.0D); 384 var18.addVertexWithUV((double)(scrollBarXEnd - 1), (double)(var14 + var13 - 1), 0.0D, 1.0D, 1.0D); 385 var18.addVertexWithUV((double)(scrollBarXEnd - 1), (double)var14, 0.0D, 1.0D, 0.0D); 386 var18.addVertexWithUV((double)scrollBarXStart, (double)var14, 0.0D, 0.0D, 0.0D); 387 var18.draw(); 388 } 389 390 this.func_27257_b(mouseX, mouseY); 391 GL11.glEnable(GL11.GL_TEXTURE_2D); 392 GL11.glShadeModel(GL11.GL_FLAT); 393 GL11.glEnable(GL11.GL_ALPHA_TEST); 394 GL11.glDisable(GL11.GL_BLEND); 395 } 396 397 private void overlayBackground(int p_22239_1_, int p_22239_2_, int p_22239_3_, int p_22239_4_) 398 { 399 Tessellator var5 = Tessellator.instance; 400 this.client.renderEngine.func_98187_b("/gui/background.png"); 401 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 402 float var6 = 32.0F; 403 var5.startDrawingQuads(); 404 var5.setColorRGBA_I(4210752, p_22239_4_); 405 var5.addVertexWithUV(0.0D, (double)p_22239_2_, 0.0D, 0.0D, (double)((float)p_22239_2_ / var6)); 406 var5.addVertexWithUV((double)this.listWidth + 30, (double)p_22239_2_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_2_ / var6)); 407 var5.setColorRGBA_I(4210752, p_22239_3_); 408 var5.addVertexWithUV((double)this.listWidth + 30, (double)p_22239_1_, 0.0D, (double)((float)(this.listWidth + 30) / var6), (double)((float)p_22239_1_ / var6)); 409 var5.addVertexWithUV(0.0D, (double)p_22239_1_, 0.0D, 0.0D, (double)((float)p_22239_1_ / var6)); 410 var5.draw(); 411 } 412}