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