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 }