package org.pokenet.client.ui.frames; import java.util.ArrayList; import java.util.List; import mdes.slick.sui.Button; import mdes.slick.sui.Container; import mdes.slick.sui.Label; import mdes.slick.sui.event.ActionEvent; import mdes.slick.sui.event.ActionListener; import mdes.slick.sui.skin.simple.SimpleArrowButton; import org.newdawn.slick.Color; import org.pokenet.client.GameClient; /** * The widget where the chat is actually displayed * @author ZombieBear * */ @SuppressWarnings("deprecation") class ChatWidget extends Container{ private int m_scrollIndex = 0; private int m_maxLines; private Button m_up, m_down; private Color m_foreColor; private List<String> m_contents = new ArrayList<String>(); private List<Label> m_shownChat = new ArrayList<Label>(); private List<String> m_wrappedText = new ArrayList<String>(); /** * Default Constructor */ public ChatWidget(){ m_up = new SimpleArrowButton(SimpleArrowButton.FACE_UP); m_down = new SimpleArrowButton(SimpleArrowButton.FACE_DOWN); m_up.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { scroll(-1); } }); m_down.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { scroll(1); } }); } /** * Adds the contents to be used for display * @param text */ public void setContents(List<String> text) { m_contents = text; wrap(); if (m_wrappedText.size() - m_maxLines >= 0) m_scrollIndex = m_wrappedText.size() - m_maxLines - 1; else m_scrollIndex = -1; scroll(1); } /** * Scrolls after adding a line * @param line */ public void addLine() { wrap(); if (m_down.isVisible() && m_down.isEnabled()) scroll(0); else { if (m_wrappedText.size() - m_maxLines >= 0) m_scrollIndex = m_wrappedText.size() - m_maxLines - 1; else m_scrollIndex = -1; scroll(1); } } /** * Handles scrolling and text display * @param indexMod */ public void scroll(int indexMod){ // Remove previous lines for (Label l : m_shownChat) { try { l.setText(""); remove(l); l = null; } catch (Exception e) {} } m_shownChat.clear(); // Sets the scrolling index m_scrollIndex += indexMod; //Handles availability of scroll buttons if (m_scrollIndex == 0) m_up.setEnabled(false); else m_up.setEnabled(true); if (m_scrollIndex + m_maxLines >= m_wrappedText.size()) m_down.setEnabled(false); else m_down.setEnabled(true); if (m_wrappedText.size() < m_maxLines){ m_up.setVisible(false); m_down.setVisible(false); } else { m_up.setVisible(true); m_down.setVisible(true); } // Add new lines int y = 0; for (int i = 0; i < m_maxLines; i++){ m_shownChat.add(new Label()); m_shownChat.get(i).setFont(GameClient.getFontSmall()); m_shownChat.get(i).setForeground(m_foreColor); m_shownChat.get(i).setLocation(0, y); try { // Make system messages red if (m_wrappedText.get(m_scrollIndex + i).charAt(0) == '*'){ m_shownChat.get(i).setForeground(Color.red); m_wrappedText.set(m_scrollIndex + i, m_wrappedText.get(m_scrollIndex + i).substring(1)); } // Make announcements yellow if (m_wrappedText.get(m_scrollIndex + i).charAt(0) == '%'){ m_shownChat.get(i).setForeground(Color.yellow); m_wrappedText.set(m_scrollIndex + i, m_wrappedText.get(m_scrollIndex + i).substring(1)); } // Highlight chat when named. if (m_wrappedText.get(m_scrollIndex + i).charAt(0) == '!'){ m_shownChat.get(i).setForeground(Color.green); m_wrappedText.set(m_scrollIndex + i, m_wrappedText.get(m_scrollIndex + i).substring(1)); } m_shownChat.get(i).setText(m_wrappedText.get(m_scrollIndex + i)); } catch (Exception e) {} m_shownChat.get(i).pack(); add(m_shownChat.get(i)); y += GameClient.getFontSmall().getHeight("X"); } } /** * Sets the foreground color * @param c */ public void setForeColor(Color c) { m_foreColor = c; scroll(0); } /** * Lays out the scrolling buttons */ public void layoutScrollButtons(){ int buttonWidth = 16; m_up.setEnabled(false); m_up.setSize(buttonWidth, buttonWidth); m_up.setLocation(getWidth() - buttonWidth, 0); m_down.setSize(buttonWidth, buttonWidth); m_down.setLocation(getWidth() - buttonWidth, getHeight() - buttonWidth); add(m_up); add(m_down); if (m_wrappedText.size() < m_maxLines){ m_up.setVisible(false); m_down.setVisible(false); } else { m_up.setVisible(true); m_down.setVisible(true); } } /** * Returns a List<String> with the wrapped text for the chat labels. * @return a List<String> with the wrapped text for the chat labels. */ public void wrap(){ m_wrappedText.clear(); if (m_contents.size() != 0) { for (int i = 0; i < m_contents.size(); i++) { try{ if (GameClient.getFontSmall().getWidth(m_contents.get(i)) <= getWidth()){ m_wrappedText.add(m_contents.get(i)); } else { String loopLine = new String(); ArrayList<String> loopList = new ArrayList<String>(); loopLine = m_contents.get(i); loopList.add(m_contents.get(i)); char messageType = '\u0000'; if (loopLine.charAt(0) == '*') messageType = '*'; else if (loopLine.charAt(0) == '%') messageType = '%'; else if (loopLine.charAt(0) == '!' || (!loopLine.contains( '<' + GameClient.getInstance().getOurPlayer() .getUsername() + '>') && loopLine .contains(GameClient.getInstance().getOurPlayer() .getUsername()))) messageType = '!'; while (GameClient.getFontSmall().getWidth(loopLine) > getWidth()){ int linesToDrop = 1; while (GameClient.getFontSmall().getWidth(loopList.get( loopList.size() - 1)) > getWidth()){ loopList.add(loopLine.substring(0, loopLine.length() - linesToDrop)); linesToDrop++; } if (linesToDrop == 1) m_wrappedText.add(loopList.get(loopList.size() - 1)); else m_wrappedText.add(messageType + loopList.get(loopList.size() - 1)); loopLine = loopLine.substring(loopList.get( loopList.size() - 1).length()); loopList.add(loopLine); } m_wrappedText.add(messageType + loopLine); } } catch (IndexOutOfBoundsException e) {} catch (Exception e) {e.printStackTrace();} } } } @Override public void setSize(float width, float height){ super.setSize(width, height); m_maxLines = (int)(getHeight() / GameClient.getFontSmall().getHeight("X")); wrap(); layoutScrollButtons(); scroll(0); } }