001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import org.lwjgl.opengl.GL11; 006 007 @SideOnly(Side.CLIENT) 008 public class GuiTextField extends Gui 009 { 010 /** 011 * Have the font renderer from GuiScreen to render the textbox text into the screen. 012 */ 013 private final FontRenderer fontRenderer; 014 private final int xPos; 015 private final int yPos; 016 017 /** The width of this text field. */ 018 private final int width; 019 private final int height; 020 021 /** Have the current text beign edited on the textbox. */ 022 private String text = ""; 023 private int maxStringLength = 32; 024 private int cursorCounter; 025 private boolean enableBackgroundDrawing = true; 026 027 /** 028 * if true the textbox can lose focus by clicking elsewhere on the screen 029 */ 030 private boolean canLoseFocus = true; 031 032 /** 033 * If this value is true along isEnabled, keyTyped will process the keys. 034 */ 035 private boolean isFocused = false; 036 037 /** 038 * If this value is true along isFocused, keyTyped will process the keys. 039 */ 040 private boolean isEnabled = true; 041 private int field_73816_n = 0; 042 private int cursorPosition = 0; 043 044 /** other selection position, maybe the same as the cursor */ 045 private int selectionEnd = 0; 046 private int enabledColor = 14737632; 047 private int disabledColor = 7368816; 048 private boolean field_73823_s = true; 049 050 public GuiTextField(FontRenderer par1FontRenderer, int par2, int par3, int par4, int par5) 051 { 052 this.fontRenderer = par1FontRenderer; 053 this.xPos = par2; 054 this.yPos = par3; 055 this.width = par4; 056 this.height = par5; 057 } 058 059 /** 060 * Increments the cursor counter 061 */ 062 public void updateCursorCounter() 063 { 064 ++this.cursorCounter; 065 } 066 067 /** 068 * Sets the text of the textbox. 069 */ 070 public void setText(String par1Str) 071 { 072 if (par1Str.length() > this.maxStringLength) 073 { 074 this.text = par1Str.substring(0, this.maxStringLength); 075 } 076 else 077 { 078 this.text = par1Str; 079 } 080 081 this.setCursorPositionEnd(); 082 } 083 084 /** 085 * Returns the text beign edited on the textbox. 086 */ 087 public String getText() 088 { 089 return this.text; 090 } 091 092 /** 093 * @return returns the text between the cursor and selectionEnd 094 */ 095 public String getSelectedtext() 096 { 097 int var1 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd; 098 int var2 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition; 099 return this.text.substring(var1, var2); 100 } 101 102 /** 103 * replaces selected text, or inserts text at the position on the cursor 104 */ 105 public void writeText(String par1Str) 106 { 107 String var2 = ""; 108 String var3 = ChatAllowedCharacters.filerAllowedCharacters(par1Str); 109 int var4 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd; 110 int var5 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition; 111 int var6 = this.maxStringLength - this.text.length() - (var4 - this.selectionEnd); 112 boolean var7 = false; 113 114 if (this.text.length() > 0) 115 { 116 var2 = var2 + this.text.substring(0, var4); 117 } 118 119 int var8; 120 121 if (var6 < var3.length()) 122 { 123 var2 = var2 + var3.substring(0, var6); 124 var8 = var6; 125 } 126 else 127 { 128 var2 = var2 + var3; 129 var8 = var3.length(); 130 } 131 132 if (this.text.length() > 0 && var5 < this.text.length()) 133 { 134 var2 = var2 + this.text.substring(var5); 135 } 136 137 this.text = var2; 138 this.func_73784_d(var4 - this.selectionEnd + var8); 139 } 140 141 public void func_73779_a(int par1) 142 { 143 if (this.text.length() != 0) 144 { 145 if (this.selectionEnd != this.cursorPosition) 146 { 147 this.writeText(""); 148 } 149 else 150 { 151 this.deleteFromCursor(this.getNthWordFromCursor(par1) - this.cursorPosition); 152 } 153 } 154 } 155 156 /** 157 * delete the selected text, otherwsie deletes characters from either side of the cursor. params: delete num 158 */ 159 public void deleteFromCursor(int par1) 160 { 161 if (this.text.length() != 0) 162 { 163 if (this.selectionEnd != this.cursorPosition) 164 { 165 this.writeText(""); 166 } 167 else 168 { 169 boolean var2 = par1 < 0; 170 int var3 = var2 ? this.cursorPosition + par1 : this.cursorPosition; 171 int var4 = var2 ? this.cursorPosition : this.cursorPosition + par1; 172 String var5 = ""; 173 174 if (var3 >= 0) 175 { 176 var5 = this.text.substring(0, var3); 177 } 178 179 if (var4 < this.text.length()) 180 { 181 var5 = var5 + this.text.substring(var4); 182 } 183 184 this.text = var5; 185 186 if (var2) 187 { 188 this.func_73784_d(par1); 189 } 190 } 191 } 192 } 193 194 /** 195 * see @getNthNextWordFromPos() params: N, position 196 */ 197 public int getNthWordFromCursor(int par1) 198 { 199 return this.getNthWordFromPos(par1, this.getCursorPosition()); 200 } 201 202 /** 203 * gets the position of the nth word. N may be negative, then it looks backwards. params: N, position 204 */ 205 public int getNthWordFromPos(int par1, int par2) 206 { 207 return this.func_73798_a(par1, this.getCursorPosition(), true); 208 } 209 210 public int func_73798_a(int par1, int par2, boolean par3) 211 { 212 int var4 = par2; 213 boolean var5 = par1 < 0; 214 int var6 = Math.abs(par1); 215 216 for (int var7 = 0; var7 < var6; ++var7) 217 { 218 if (var5) 219 { 220 while (par3 && var4 > 0 && this.text.charAt(var4 - 1) == 32) 221 { 222 --var4; 223 } 224 225 while (var4 > 0 && this.text.charAt(var4 - 1) != 32) 226 { 227 --var4; 228 } 229 } 230 else 231 { 232 int var8 = this.text.length(); 233 var4 = this.text.indexOf(32, var4); 234 235 if (var4 == -1) 236 { 237 var4 = var8; 238 } 239 else 240 { 241 while (par3 && var4 < var8 && this.text.charAt(var4) == 32) 242 { 243 ++var4; 244 } 245 } 246 } 247 } 248 249 return var4; 250 } 251 252 public void func_73784_d(int par1) 253 { 254 this.setCursorPosition(this.selectionEnd + par1); 255 } 256 257 /** 258 * sets the position of the cursor to the provided index 259 */ 260 public void setCursorPosition(int par1) 261 { 262 this.cursorPosition = par1; 263 int var2 = this.text.length(); 264 265 if (this.cursorPosition < 0) 266 { 267 this.cursorPosition = 0; 268 } 269 270 if (this.cursorPosition > var2) 271 { 272 this.cursorPosition = var2; 273 } 274 275 this.func_73800_i(this.cursorPosition); 276 } 277 278 /** 279 * sets the cursors position to the beginning 280 */ 281 public void setCursorPositionZero() 282 { 283 this.setCursorPosition(0); 284 } 285 286 /** 287 * sets the cursors position to after the text 288 */ 289 public void setCursorPositionEnd() 290 { 291 this.setCursorPosition(this.text.length()); 292 } 293 294 /** 295 * Call this method from you GuiScreen to process the keys into textbox. 296 */ 297 public boolean textboxKeyTyped(char par1, int par2) 298 { 299 if (this.isEnabled && this.isFocused) 300 { 301 switch (par1) 302 { 303 case 1: 304 this.setCursorPositionEnd(); 305 this.func_73800_i(0); 306 return true; 307 case 3: 308 GuiScreen.setClipboardString(this.getSelectedtext()); 309 return true; 310 case 22: 311 this.writeText(GuiScreen.getClipboardString()); 312 return true; 313 case 24: 314 GuiScreen.setClipboardString(this.getSelectedtext()); 315 this.writeText(""); 316 return true; 317 default: 318 switch (par2) 319 { 320 case 14: 321 if (GuiScreen.isCtrlKeyDown()) 322 { 323 this.func_73779_a(-1); 324 } 325 else 326 { 327 this.deleteFromCursor(-1); 328 } 329 330 return true; 331 case 199: 332 if (GuiScreen.isShiftKeyDown()) 333 { 334 this.func_73800_i(0); 335 } 336 else 337 { 338 this.setCursorPositionZero(); 339 } 340 341 return true; 342 case 203: 343 if (GuiScreen.isShiftKeyDown()) 344 { 345 if (GuiScreen.isCtrlKeyDown()) 346 { 347 this.func_73800_i(this.getNthWordFromPos(-1, this.getSelectionEnd())); 348 } 349 else 350 { 351 this.func_73800_i(this.getSelectionEnd() - 1); 352 } 353 } 354 else if (GuiScreen.isCtrlKeyDown()) 355 { 356 this.setCursorPosition(this.getNthWordFromCursor(-1)); 357 } 358 else 359 { 360 this.func_73784_d(-1); 361 } 362 363 return true; 364 case 205: 365 if (GuiScreen.isShiftKeyDown()) 366 { 367 if (GuiScreen.isCtrlKeyDown()) 368 { 369 this.func_73800_i(this.getNthWordFromPos(1, this.getSelectionEnd())); 370 } 371 else 372 { 373 this.func_73800_i(this.getSelectionEnd() + 1); 374 } 375 } 376 else if (GuiScreen.isCtrlKeyDown()) 377 { 378 this.setCursorPosition(this.getNthWordFromCursor(1)); 379 } 380 else 381 { 382 this.func_73784_d(1); 383 } 384 385 return true; 386 case 207: 387 if (GuiScreen.isShiftKeyDown()) 388 { 389 this.func_73800_i(this.text.length()); 390 } 391 else 392 { 393 this.setCursorPositionEnd(); 394 } 395 396 return true; 397 case 211: 398 if (GuiScreen.isCtrlKeyDown()) 399 { 400 this.func_73779_a(1); 401 } 402 else 403 { 404 this.deleteFromCursor(1); 405 } 406 407 return true; 408 default: 409 if (ChatAllowedCharacters.isAllowedCharacter(par1)) 410 { 411 this.writeText(Character.toString(par1)); 412 return true; 413 } 414 else 415 { 416 return false; 417 } 418 } 419 } 420 } 421 else 422 { 423 return false; 424 } 425 } 426 427 /** 428 * Args: x, y, buttonClicked 429 */ 430 public void mouseClicked(int par1, int par2, int par3) 431 { 432 boolean var4 = par1 >= this.xPos && par1 < this.xPos + this.width && par2 >= this.yPos && par2 < this.yPos + this.height; 433 434 if (this.canLoseFocus) 435 { 436 this.setFocused(this.isEnabled && var4); 437 } 438 439 if (this.isFocused && par3 == 0) 440 { 441 int var5 = par1 - this.xPos; 442 443 if (this.enableBackgroundDrawing) 444 { 445 var5 -= 4; 446 } 447 448 String var6 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), this.getWidth()); 449 this.setCursorPosition(this.fontRenderer.trimStringToWidth(var6, var5).length() + this.field_73816_n); 450 } 451 } 452 453 /** 454 * Draws the textbox 455 */ 456 public void drawTextBox() 457 { 458 if (this.func_73778_q()) 459 { 460 if (this.getEnableBackgroundDrawing()) 461 { 462 drawRect(this.xPos - 1, this.yPos - 1, this.xPos + this.width + 1, this.yPos + this.height + 1, -6250336); 463 drawRect(this.xPos, this.yPos, this.xPos + this.width, this.yPos + this.height, -16777216); 464 } 465 466 int var1 = this.isEnabled ? this.enabledColor : this.disabledColor; 467 int var2 = this.cursorPosition - this.field_73816_n; 468 int var3 = this.selectionEnd - this.field_73816_n; 469 String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), this.getWidth()); 470 boolean var5 = var2 >= 0 && var2 <= var4.length(); 471 boolean var6 = this.isFocused && this.cursorCounter / 6 % 2 == 0 && var5; 472 int var7 = this.enableBackgroundDrawing ? this.xPos + 4 : this.xPos; 473 int var8 = this.enableBackgroundDrawing ? this.yPos + (this.height - 8) / 2 : this.yPos; 474 int var9 = var7; 475 476 if (var3 > var4.length()) 477 { 478 var3 = var4.length(); 479 } 480 481 if (var4.length() > 0) 482 { 483 String var10 = var5 ? var4.substring(0, var2) : var4; 484 var9 = this.fontRenderer.drawStringWithShadow(var10, var7, var8, var1); 485 } 486 487 boolean var13 = this.cursorPosition < this.text.length() || this.text.length() >= this.getMaxStringLength(); 488 int var11 = var9; 489 490 if (!var5) 491 { 492 var11 = var2 > 0 ? var7 + this.width : var7; 493 } 494 else if (var13) 495 { 496 var11 = var9 - 1; 497 --var9; 498 } 499 500 if (var4.length() > 0 && var5 && var2 < var4.length()) 501 { 502 this.fontRenderer.drawStringWithShadow(var4.substring(var2), var9, var8, var1); 503 } 504 505 if (var6) 506 { 507 if (var13) 508 { 509 Gui.drawRect(var11, var8 - 1, var11 + 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT, -3092272); 510 } 511 else 512 { 513 this.fontRenderer.drawStringWithShadow("_", var11, var8, var1); 514 } 515 } 516 517 if (var3 != var2) 518 { 519 int var12 = var7 + this.fontRenderer.getStringWidth(var4.substring(0, var3)); 520 this.drawCursorVertical(var11, var8 - 1, var12 - 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT); 521 } 522 } 523 } 524 525 /** 526 * draws the vertical line cursor in the textbox 527 */ 528 private void drawCursorVertical(int par1, int par2, int par3, int par4) 529 { 530 int var5; 531 532 if (par1 < par3) 533 { 534 var5 = par1; 535 par1 = par3; 536 par3 = var5; 537 } 538 539 if (par2 < par4) 540 { 541 var5 = par2; 542 par2 = par4; 543 par4 = var5; 544 } 545 546 Tessellator var6 = Tessellator.instance; 547 GL11.glColor4f(0.0F, 0.0F, 255.0F, 255.0F); 548 GL11.glDisable(GL11.GL_TEXTURE_2D); 549 GL11.glEnable(GL11.GL_COLOR_LOGIC_OP); 550 GL11.glLogicOp(GL11.GL_OR_REVERSE); 551 var6.startDrawingQuads(); 552 var6.addVertex((double)par1, (double)par4, 0.0D); 553 var6.addVertex((double)par3, (double)par4, 0.0D); 554 var6.addVertex((double)par3, (double)par2, 0.0D); 555 var6.addVertex((double)par1, (double)par2, 0.0D); 556 var6.draw(); 557 GL11.glDisable(GL11.GL_COLOR_LOGIC_OP); 558 GL11.glEnable(GL11.GL_TEXTURE_2D); 559 } 560 561 public void setMaxStringLength(int par1) 562 { 563 this.maxStringLength = par1; 564 565 if (this.text.length() > par1) 566 { 567 this.text = this.text.substring(0, par1); 568 } 569 } 570 571 /** 572 * returns the maximum number of character that can be contained in this textbox 573 */ 574 public int getMaxStringLength() 575 { 576 return this.maxStringLength; 577 } 578 579 /** 580 * returns the current position of the cursor 581 */ 582 public int getCursorPosition() 583 { 584 return this.cursorPosition; 585 } 586 587 /** 588 * get enable drawing background and outline 589 */ 590 public boolean getEnableBackgroundDrawing() 591 { 592 return this.enableBackgroundDrawing; 593 } 594 595 /** 596 * enable drawing background and outline 597 */ 598 public void setEnableBackgroundDrawing(boolean par1) 599 { 600 this.enableBackgroundDrawing = par1; 601 } 602 603 public void func_73794_g(int par1) 604 { 605 this.enabledColor = par1; 606 } 607 608 /** 609 * setter for the focused field 610 */ 611 public void setFocused(boolean par1) 612 { 613 if (par1 && !this.isFocused) 614 { 615 this.cursorCounter = 0; 616 } 617 618 this.isFocused = par1; 619 } 620 621 /** 622 * getter for the focused field 623 */ 624 public boolean isFocused() 625 { 626 return this.isFocused; 627 } 628 629 /** 630 * the side of the selection that is not the cursor, maye be the same as the cursor 631 */ 632 public int getSelectionEnd() 633 { 634 return this.selectionEnd; 635 } 636 637 /** 638 * returns the width of the textbox depending on if the the box is enabled 639 */ 640 public int getWidth() 641 { 642 return this.getEnableBackgroundDrawing() ? this.width - 8 : this.width; 643 } 644 645 public void func_73800_i(int par1) 646 { 647 int var2 = this.text.length(); 648 649 if (par1 > var2) 650 { 651 par1 = var2; 652 } 653 654 if (par1 < 0) 655 { 656 par1 = 0; 657 } 658 659 this.selectionEnd = par1; 660 661 if (this.fontRenderer != null) 662 { 663 if (this.field_73816_n > var2) 664 { 665 this.field_73816_n = var2; 666 } 667 668 int var3 = this.getWidth(); 669 String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), var3); 670 int var5 = var4.length() + this.field_73816_n; 671 672 if (par1 == this.field_73816_n) 673 { 674 this.field_73816_n -= this.fontRenderer.trimStringToWidth(this.text, var3, true).length(); 675 } 676 677 if (par1 > var5) 678 { 679 this.field_73816_n += par1 - var5; 680 } 681 else if (par1 <= this.field_73816_n) 682 { 683 this.field_73816_n -= this.field_73816_n - par1; 684 } 685 686 if (this.field_73816_n < 0) 687 { 688 this.field_73816_n = 0; 689 } 690 691 if (this.field_73816_n > var2) 692 { 693 this.field_73816_n = var2; 694 } 695 } 696 } 697 698 /** 699 * if true the textbox can lose focus by clicking elsewhere on the screen 700 */ 701 public void setCanLoseFocus(boolean par1) 702 { 703 this.canLoseFocus = par1; 704 } 705 706 public boolean func_73778_q() 707 { 708 return this.field_73823_s; 709 } 710 711 public void func_73790_e(boolean par1) 712 { 713 this.field_73823_s = par1; 714 } 715 }