001 package net.minecraft.src; 002 003 import cpw.mods.fml.common.Side; 004 import cpw.mods.fml.common.asm.SideOnly; 005 import java.io.ByteArrayOutputStream; 006 import java.io.DataOutputStream; 007 import org.lwjgl.input.Keyboard; 008 import org.lwjgl.opengl.GL11; 009 010 @SideOnly(Side.CLIENT) 011 public class GuiScreenBook extends GuiScreen 012 { 013 /** The player editing the book */ 014 private final EntityPlayer editingPlayer; 015 private final ItemStack itemstackBook; 016 017 /** Whether the book is signed or can still be edited */ 018 private final boolean bookIsUnsigned; 019 private boolean bookModified; 020 private boolean editingTitle; 021 022 /** Update ticks since the gui was opened */ 023 private int updateCount; 024 private int bookImageWidth = 192; 025 private int bookImageHeight = 192; 026 private int bookTotalPages = 1; 027 private int currPage; 028 private NBTTagList bookPages; 029 private String bookTitle = ""; 030 private GuiButtonNextPage buttonNextPage; 031 private GuiButtonNextPage buttonPreviousPage; 032 private GuiButton buttonDone; 033 034 /** The GuiButton to sign this book. */ 035 private GuiButton buttonSign; 036 private GuiButton buttonFinalize; 037 private GuiButton buttonCancel; 038 039 public GuiScreenBook(EntityPlayer par1EntityPlayer, ItemStack par2ItemStack, boolean par3) 040 { 041 this.editingPlayer = par1EntityPlayer; 042 this.itemstackBook = par2ItemStack; 043 this.bookIsUnsigned = par3; 044 045 if (par2ItemStack.hasTagCompound()) 046 { 047 NBTTagCompound var4 = par2ItemStack.getTagCompound(); 048 this.bookPages = var4.getTagList("pages"); 049 050 if (this.bookPages != null) 051 { 052 this.bookPages = (NBTTagList)this.bookPages.copy(); 053 this.bookTotalPages = this.bookPages.tagCount(); 054 055 if (this.bookTotalPages < 1) 056 { 057 this.bookTotalPages = 1; 058 } 059 } 060 } 061 062 if (this.bookPages == null && par3) 063 { 064 this.bookPages = new NBTTagList("pages"); 065 this.bookPages.appendTag(new NBTTagString("1", "")); 066 this.bookTotalPages = 1; 067 } 068 } 069 070 /** 071 * Called from the main game loop to update the screen. 072 */ 073 public void updateScreen() 074 { 075 super.updateScreen(); 076 ++this.updateCount; 077 } 078 079 /** 080 * Adds the buttons (and other controls) to the screen in question. 081 */ 082 public void initGui() 083 { 084 this.controlList.clear(); 085 Keyboard.enableRepeatEvents(true); 086 087 if (this.bookIsUnsigned) 088 { 089 this.controlList.add(this.buttonSign = new GuiButton(3, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.signButton"))); 090 this.controlList.add(this.buttonDone = new GuiButton(0, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.done"))); 091 this.controlList.add(this.buttonFinalize = new GuiButton(5, this.width / 2 - 100, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("book.finalizeButton"))); 092 this.controlList.add(this.buttonCancel = new GuiButton(4, this.width / 2 + 2, 4 + this.bookImageHeight, 98, 20, StatCollector.translateToLocal("gui.cancel"))); 093 } 094 else 095 { 096 this.controlList.add(this.buttonDone = new GuiButton(0, this.width / 2 - 100, 4 + this.bookImageHeight, 200, 20, StatCollector.translateToLocal("gui.done"))); 097 } 098 099 int var1 = (this.width - this.bookImageWidth) / 2; 100 byte var2 = 2; 101 this.controlList.add(this.buttonNextPage = new GuiButtonNextPage(1, var1 + 120, var2 + 154, true)); 102 this.controlList.add(this.buttonPreviousPage = new GuiButtonNextPage(2, var1 + 38, var2 + 154, false)); 103 this.updateButtons(); 104 } 105 106 /** 107 * Called when the screen is unloaded. Used to disable keyboard repeat events 108 */ 109 public void onGuiClosed() 110 { 111 Keyboard.enableRepeatEvents(false); 112 } 113 114 private void updateButtons() 115 { 116 this.buttonNextPage.drawButton = !this.editingTitle && (this.currPage < this.bookTotalPages - 1 || this.bookIsUnsigned); 117 this.buttonPreviousPage.drawButton = !this.editingTitle && this.currPage > 0; 118 this.buttonDone.drawButton = !this.bookIsUnsigned || !this.editingTitle; 119 120 if (this.bookIsUnsigned) 121 { 122 this.buttonSign.drawButton = !this.editingTitle; 123 this.buttonCancel.drawButton = this.editingTitle; 124 this.buttonFinalize.drawButton = this.editingTitle; 125 this.buttonFinalize.enabled = this.bookTitle.trim().length() > 0; 126 } 127 } 128 129 private void sendBookToServer(boolean par1) 130 { 131 if (this.bookIsUnsigned && this.bookModified) 132 { 133 if (this.bookPages != null) 134 { 135 while (this.bookPages.tagCount() > 1) 136 { 137 NBTTagString var2 = (NBTTagString)this.bookPages.tagAt(this.bookPages.tagCount() - 1); 138 139 if (var2.data != null && var2.data.length() != 0) 140 { 141 break; 142 } 143 144 this.bookPages.removeTag(this.bookPages.tagCount() - 1); 145 } 146 147 if (this.itemstackBook.hasTagCompound()) 148 { 149 NBTTagCompound var7 = this.itemstackBook.getTagCompound(); 150 var7.setTag("pages", this.bookPages); 151 } 152 else 153 { 154 this.itemstackBook.setTagInfo("pages", this.bookPages); 155 } 156 157 String var8 = "MC|BEdit"; 158 159 if (par1) 160 { 161 var8 = "MC|BSign"; 162 this.itemstackBook.setTagInfo("author", new NBTTagString("author", this.editingPlayer.username)); 163 this.itemstackBook.setTagInfo("title", new NBTTagString("title", this.bookTitle.trim())); 164 this.itemstackBook.itemID = Item.writtenBook.shiftedIndex; 165 } 166 167 ByteArrayOutputStream var3 = new ByteArrayOutputStream(); 168 DataOutputStream var4 = new DataOutputStream(var3); 169 170 try 171 { 172 Packet.writeItemStack(this.itemstackBook, var4); 173 this.mc.getSendQueue().addToSendQueue(new Packet250CustomPayload(var8, var3.toByteArray())); 174 } 175 catch (Exception var6) 176 { 177 var6.printStackTrace(); 178 } 179 } 180 } 181 } 182 183 /** 184 * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e). 185 */ 186 protected void actionPerformed(GuiButton par1GuiButton) 187 { 188 if (par1GuiButton.enabled) 189 { 190 if (par1GuiButton.id == 0) 191 { 192 this.mc.displayGuiScreen((GuiScreen)null); 193 this.sendBookToServer(false); 194 } 195 else if (par1GuiButton.id == 3 && this.bookIsUnsigned) 196 { 197 this.editingTitle = true; 198 } 199 else if (par1GuiButton.id == 1) 200 { 201 if (this.currPage < this.bookTotalPages - 1) 202 { 203 ++this.currPage; 204 } 205 else if (this.bookIsUnsigned) 206 { 207 this.addNewPage(); 208 209 if (this.currPage < this.bookTotalPages - 1) 210 { 211 ++this.currPage; 212 } 213 } 214 } 215 else if (par1GuiButton.id == 2) 216 { 217 if (this.currPage > 0) 218 { 219 --this.currPage; 220 } 221 } 222 else if (par1GuiButton.id == 5 && this.editingTitle) 223 { 224 this.sendBookToServer(true); 225 this.mc.displayGuiScreen((GuiScreen)null); 226 } 227 else if (par1GuiButton.id == 4 && this.editingTitle) 228 { 229 this.editingTitle = false; 230 } 231 232 this.updateButtons(); 233 } 234 } 235 236 private void addNewPage() 237 { 238 if (this.bookPages != null && this.bookPages.tagCount() < 50) 239 { 240 this.bookPages.appendTag(new NBTTagString("" + (this.bookTotalPages + 1), "")); 241 ++this.bookTotalPages; 242 this.bookModified = true; 243 } 244 } 245 246 /** 247 * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e). 248 */ 249 protected void keyTyped(char par1, int par2) 250 { 251 super.keyTyped(par1, par2); 252 253 if (this.bookIsUnsigned) 254 { 255 if (this.editingTitle) 256 { 257 this.func_74162_c(par1, par2); 258 } 259 else 260 { 261 this.keyTypedInBook(par1, par2); 262 } 263 } 264 } 265 266 /** 267 * Processes keystrokes when editing the text of a book 268 */ 269 private void keyTypedInBook(char par1, int par2) 270 { 271 switch (par1) 272 { 273 case 22: 274 this.func_74160_b(GuiScreen.getClipboardString()); 275 return; 276 default: 277 switch (par2) 278 { 279 case 14: 280 String var3 = this.func_74158_i(); 281 282 if (var3.length() > 0) 283 { 284 this.func_74159_a(var3.substring(0, var3.length() - 1)); 285 } 286 287 return; 288 case 28: 289 this.func_74160_b("\n"); 290 return; 291 default: 292 if (ChatAllowedCharacters.isAllowedCharacter(par1)) 293 { 294 this.func_74160_b(Character.toString(par1)); 295 } 296 } 297 } 298 } 299 300 private void func_74162_c(char par1, int par2) 301 { 302 switch (par2) 303 { 304 case 14: 305 if (this.bookTitle.length() > 0) 306 { 307 this.bookTitle = this.bookTitle.substring(0, this.bookTitle.length() - 1); 308 this.updateButtons(); 309 } 310 311 return; 312 case 28: 313 if (this.bookTitle.length() > 0) 314 { 315 this.sendBookToServer(true); 316 this.mc.displayGuiScreen((GuiScreen)null); 317 } 318 319 return; 320 default: 321 if (this.bookTitle.length() < 16 && ChatAllowedCharacters.isAllowedCharacter(par1)) 322 { 323 this.bookTitle = this.bookTitle + Character.toString(par1); 324 this.updateButtons(); 325 this.bookModified = true; 326 } 327 } 328 } 329 330 private String func_74158_i() 331 { 332 if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) 333 { 334 NBTTagString var1 = (NBTTagString)this.bookPages.tagAt(this.currPage); 335 return var1.toString(); 336 } 337 else 338 { 339 return ""; 340 } 341 } 342 343 private void func_74159_a(String par1Str) 344 { 345 if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) 346 { 347 NBTTagString var2 = (NBTTagString)this.bookPages.tagAt(this.currPage); 348 var2.data = par1Str; 349 this.bookModified = true; 350 } 351 } 352 353 private void func_74160_b(String par1Str) 354 { 355 String var2 = this.func_74158_i(); 356 String var3 = var2 + par1Str; 357 int var4 = this.fontRenderer.splitStringWidth(var3 + "\u00a70_", 118); 358 359 if (var4 <= 118 && var3.length() < 256) 360 { 361 this.func_74159_a(var3); 362 } 363 } 364 365 /** 366 * Draws the screen and all the components in it. 367 */ 368 public void drawScreen(int par1, int par2, float par3) 369 { 370 int var4 = this.mc.renderEngine.getTexture("/gui/book.png"); 371 GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 372 this.mc.renderEngine.bindTexture(var4); 373 int var5 = (this.width - this.bookImageWidth) / 2; 374 byte var6 = 2; 375 this.drawTexturedModalRect(var5, var6, 0, 0, this.bookImageWidth, this.bookImageHeight); 376 String var7; 377 String var8; 378 int var9; 379 380 if (this.editingTitle) 381 { 382 var7 = this.bookTitle; 383 384 if (this.bookIsUnsigned) 385 { 386 if (this.updateCount / 6 % 2 == 0) 387 { 388 var7 = var7 + "\u00a70_"; 389 } 390 else 391 { 392 var7 = var7 + "\u00a77_"; 393 } 394 } 395 396 var8 = StatCollector.translateToLocal("book.editTitle"); 397 var9 = this.fontRenderer.getStringWidth(var8); 398 this.fontRenderer.drawString(var8, var5 + 36 + (116 - var9) / 2, var6 + 16 + 16, 0); 399 int var10 = this.fontRenderer.getStringWidth(var7); 400 this.fontRenderer.drawString(var7, var5 + 36 + (116 - var10) / 2, var6 + 48, 0); 401 String var11 = String.format(StatCollector.translateToLocal("book.byAuthor"), new Object[] {this.editingPlayer.username}); 402 int var12 = this.fontRenderer.getStringWidth(var11); 403 this.fontRenderer.drawString("\u00a78" + var11, var5 + 36 + (116 - var12) / 2, var6 + 48 + 10, 0); 404 String var13 = StatCollector.translateToLocal("book.finalizeWarning"); 405 this.fontRenderer.drawSplitString(var13, var5 + 36, var6 + 80, 116, 0); 406 } 407 else 408 { 409 var7 = String.format(StatCollector.translateToLocal("book.pageIndicator"), new Object[] {Integer.valueOf(this.currPage + 1), Integer.valueOf(this.bookTotalPages)}); 410 var8 = ""; 411 412 if (this.bookPages != null && this.currPage >= 0 && this.currPage < this.bookPages.tagCount()) 413 { 414 NBTTagString var14 = (NBTTagString)this.bookPages.tagAt(this.currPage); 415 var8 = var14.toString(); 416 } 417 418 if (this.bookIsUnsigned) 419 { 420 if (this.fontRenderer.getBidiFlag()) 421 { 422 var8 = var8 + "_"; 423 } 424 else if (this.updateCount / 6 % 2 == 0) 425 { 426 var8 = var8 + "\u00a70_"; 427 } 428 else 429 { 430 var8 = var8 + "\u00a77_"; 431 } 432 } 433 434 var9 = this.fontRenderer.getStringWidth(var7); 435 this.fontRenderer.drawString(var7, var5 - var9 + this.bookImageWidth - 44, var6 + 16, 0); 436 this.fontRenderer.drawSplitString(var8, var5 + 36, var6 + 16 + 16, 116, 0); 437 } 438 439 super.drawScreen(par1, par2, par3); 440 } 441 }