001 package net.minecraft.client.gui; 002 003 import cpw.mods.fml.relauncher.Side; 004 import cpw.mods.fml.relauncher.SideOnly; 005 import java.net.URI; 006 import java.util.ArrayList; 007 import java.util.Iterator; 008 import java.util.List; 009 import net.minecraft.network.packet.Packet203AutoComplete; 010 import org.lwjgl.input.Keyboard; 011 import org.lwjgl.input.Mouse; 012 013 @SideOnly(Side.CLIENT) 014 public class GuiChat extends GuiScreen 015 { 016 private String field_73898_b = ""; 017 018 /** 019 * keeps position of which chat message you will select when you press up, (does not increase for duplicated 020 * messages sent immediately after each other) 021 */ 022 private int sentHistoryCursor = -1; 023 private boolean field_73897_d = false; 024 private boolean field_73905_m = false; 025 private int field_73903_n = 0; 026 private List field_73904_o = new ArrayList(); 027 028 /** used to pass around the URI to various dialogues and to the host os */ 029 private URI clickedURI = null; 030 031 /** Chat entry field */ 032 protected GuiTextField inputField; 033 034 /** 035 * is the text that appears when you press the chat key and the input box appears pre-filled 036 */ 037 private String defaultInputFieldText = ""; 038 039 public GuiChat() {} 040 041 public GuiChat(String par1Str) 042 { 043 this.defaultInputFieldText = par1Str; 044 } 045 046 /** 047 * Adds the buttons (and other controls) to the screen in question. 048 */ 049 public void initGui() 050 { 051 Keyboard.enableRepeatEvents(true); 052 this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); 053 this.inputField = new GuiTextField(this.fontRenderer, 4, this.height - 12, this.width - 4, 12); 054 this.inputField.setMaxStringLength(100); 055 this.inputField.setEnableBackgroundDrawing(false); 056 this.inputField.setFocused(true); 057 this.inputField.setText(this.defaultInputFieldText); 058 this.inputField.setCanLoseFocus(false); 059 } 060 061 /** 062 * Called when the screen is unloaded. Used to disable keyboard repeat events 063 */ 064 public void onGuiClosed() 065 { 066 Keyboard.enableRepeatEvents(false); 067 this.mc.ingameGUI.getChatGUI().resetScroll(); 068 } 069 070 /** 071 * Called from the main game loop to update the screen. 072 */ 073 public void updateScreen() 074 { 075 this.inputField.updateCursorCounter(); 076 } 077 078 /** 079 * Fired when a key is typed. This is the equivalent of KeyListener.keyTyped(KeyEvent e). 080 */ 081 protected void keyTyped(char par1, int par2) 082 { 083 this.field_73905_m = false; 084 085 if (par2 == 15) 086 { 087 this.completePlayerName(); 088 } 089 else 090 { 091 this.field_73897_d = false; 092 } 093 094 if (par2 == 1) 095 { 096 this.mc.displayGuiScreen((GuiScreen)null); 097 } 098 else if (par2 == 28) 099 { 100 String var3 = this.inputField.getText().trim(); 101 102 if (var3.length() > 0) 103 { 104 this.mc.ingameGUI.getChatGUI().addToSentMessages(var3); 105 106 if (!this.mc.handleClientCommand(var3)) 107 { 108 this.mc.thePlayer.sendChatMessage(var3); 109 } 110 } 111 112 this.mc.displayGuiScreen((GuiScreen)null); 113 } 114 else if (par2 == 200) 115 { 116 this.getSentHistory(-1); 117 } 118 else if (par2 == 208) 119 { 120 this.getSentHistory(1); 121 } 122 else if (par2 == 201) 123 { 124 this.mc.ingameGUI.getChatGUI().scroll(19); 125 } 126 else if (par2 == 209) 127 { 128 this.mc.ingameGUI.getChatGUI().scroll(-19); 129 } 130 else 131 { 132 this.inputField.textboxKeyTyped(par1, par2); 133 } 134 } 135 136 /** 137 * Handles mouse input. 138 */ 139 public void handleMouseInput() 140 { 141 super.handleMouseInput(); 142 int var1 = Mouse.getEventDWheel(); 143 144 if (var1 != 0) 145 { 146 if (var1 > 1) 147 { 148 var1 = 1; 149 } 150 151 if (var1 < -1) 152 { 153 var1 = -1; 154 } 155 156 if (!isShiftKeyDown()) 157 { 158 var1 *= 7; 159 } 160 161 this.mc.ingameGUI.getChatGUI().scroll(var1); 162 } 163 } 164 165 /** 166 * Called when the mouse is clicked. 167 */ 168 protected void mouseClicked(int par1, int par2, int par3) 169 { 170 if (par3 == 0 && this.mc.gameSettings.chatLinks) 171 { 172 ChatClickData var4 = this.mc.ingameGUI.getChatGUI().func_73766_a(Mouse.getX(), Mouse.getY()); 173 174 if (var4 != null) 175 { 176 URI var5 = var4.getURI(); 177 178 if (var5 != null) 179 { 180 if (this.mc.gameSettings.chatLinksPrompt) 181 { 182 this.clickedURI = var5; 183 this.mc.displayGuiScreen(new GuiConfirmOpenLink(this, var4.getClickedUrl(), 0)); 184 } 185 else 186 { 187 this.func_73896_a(var5); 188 } 189 190 return; 191 } 192 } 193 } 194 195 this.inputField.mouseClicked(par1, par2, par3); 196 super.mouseClicked(par1, par2, par3); 197 } 198 199 public void confirmClicked(boolean par1, int par2) 200 { 201 if (par2 == 0) 202 { 203 if (par1) 204 { 205 this.func_73896_a(this.clickedURI); 206 } 207 208 this.clickedURI = null; 209 this.mc.displayGuiScreen(this); 210 } 211 } 212 213 private void func_73896_a(URI par1URI) 214 { 215 try 216 { 217 Class var2 = Class.forName("java.awt.Desktop"); 218 Object var3 = var2.getMethod("getDesktop", new Class[0]).invoke((Object)null, new Object[0]); 219 var2.getMethod("browse", new Class[] {URI.class}).invoke(var3, new Object[] {par1URI}); 220 } 221 catch (Throwable var4) 222 { 223 var4.printStackTrace(); 224 } 225 } 226 227 /** 228 * Autocompletes player name 229 */ 230 public void completePlayerName() 231 { 232 String var3; 233 234 if (this.field_73897_d) 235 { 236 this.inputField.deleteFromCursor(this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition()); 237 238 if (this.field_73903_n >= this.field_73904_o.size()) 239 { 240 this.field_73903_n = 0; 241 } 242 } 243 else 244 { 245 int var1 = this.inputField.func_73798_a(-1, this.inputField.getCursorPosition(), false); 246 this.field_73904_o.clear(); 247 this.field_73903_n = 0; 248 String var2 = this.inputField.getText().substring(var1).toLowerCase(); 249 var3 = this.inputField.getText().substring(0, this.inputField.getCursorPosition()); 250 this.func_73893_a(var3, var2); 251 252 if (this.field_73904_o.isEmpty()) 253 { 254 return; 255 } 256 257 this.field_73897_d = true; 258 this.inputField.deleteFromCursor(var1 - this.inputField.getCursorPosition()); 259 } 260 261 if (this.field_73904_o.size() > 1) 262 { 263 StringBuilder var4 = new StringBuilder(); 264 265 for (Iterator var5 = this.field_73904_o.iterator(); var5.hasNext(); var4.append(var3)) 266 { 267 var3 = (String)var5.next(); 268 269 if (var4.length() > 0) 270 { 271 var4.append(", "); 272 } 273 } 274 275 this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(var4.toString(), 1); 276 } 277 278 this.inputField.writeText((String)this.field_73904_o.get(this.field_73903_n++)); 279 } 280 281 private void func_73893_a(String par1Str, String par2Str) 282 { 283 if (par1Str.length() >= 1) 284 { 285 this.mc.thePlayer.sendQueue.addToSendQueue(new Packet203AutoComplete(par1Str)); 286 this.field_73905_m = true; 287 } 288 } 289 290 /** 291 * input is relative and is applied directly to the sentHistoryCursor so -1 is the previous message, 1 is the next 292 * message from the current cursor position 293 */ 294 public void getSentHistory(int par1) 295 { 296 int var2 = this.sentHistoryCursor + par1; 297 int var3 = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); 298 299 if (var2 < 0) 300 { 301 var2 = 0; 302 } 303 304 if (var2 > var3) 305 { 306 var2 = var3; 307 } 308 309 if (var2 != this.sentHistoryCursor) 310 { 311 if (var2 == var3) 312 { 313 this.sentHistoryCursor = var3; 314 this.inputField.setText(this.field_73898_b); 315 } 316 else 317 { 318 if (this.sentHistoryCursor == var3) 319 { 320 this.field_73898_b = this.inputField.getText(); 321 } 322 323 this.inputField.setText((String)this.mc.ingameGUI.getChatGUI().getSentMessages().get(var2)); 324 this.sentHistoryCursor = var2; 325 } 326 } 327 } 328 329 /** 330 * Draws the screen and all the components in it. 331 */ 332 public void drawScreen(int par1, int par2, float par3) 333 { 334 drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); 335 this.inputField.drawTextBox(); 336 super.drawScreen(par1, par2, par3); 337 } 338 339 public void func_73894_a(String[] par1ArrayOfStr) 340 { 341 if (this.field_73905_m) 342 { 343 this.field_73904_o.clear(); 344 String[] var2 = par1ArrayOfStr; 345 int var3 = par1ArrayOfStr.length; 346 347 for (int var4 = 0; var4 < var3; ++var4) 348 { 349 String var5 = var2[var4]; 350 351 if (var5.length() > 0) 352 { 353 this.field_73904_o.add(var5); 354 } 355 } 356 357 if (this.field_73904_o.size() > 0) 358 { 359 this.field_73897_d = true; 360 this.completePlayerName(); 361 } 362 } 363 } 364 365 /** 366 * Returns true if this GUI should pause the game when it is displayed in single-player 367 */ 368 public boolean doesGuiPauseGame() 369 { 370 return false; 371 } 372 }