42 import android.text.style.RelativeSizeSpan; |
42 import android.text.style.RelativeSizeSpan; |
43 import android.text.style.StyleSpan; |
43 import android.text.style.StyleSpan; |
44 import android.util.Log; |
44 import android.util.Log; |
45 |
45 |
46 public class MessageLog { |
46 public class MessageLog { |
47 private static final int BACKLOG_LINES = 200; |
47 private static final int BACKLOG_LINES = 200; |
48 |
|
49 private static final int INFO_COLOR = Color.GRAY; |
|
50 private static final int PLAYERINFO_COLOR = Color.GREEN; |
|
51 private static final int CHAT_COLOR = Color.GREEN; |
|
52 private static final int MECHAT_COLOR = Color.CYAN; |
|
53 private static final int WARN_COLOR = Color.RED; |
|
54 private static final int ERROR_COLOR = Color.RED; |
|
55 |
|
56 private final Context context; |
|
57 private List<Listener> observers = new LinkedList<Listener>(); |
|
58 private List<CharSequence> log = new LinkedList<CharSequence>(); |
|
59 |
|
60 public MessageLog(Context context) { |
|
61 this.context = context; |
|
62 } |
|
63 |
|
64 private Spanned makeLogTime() { |
|
65 String time = DateFormat.getTimeFormat(context).format(new Date()); |
|
66 return withColor("[" + time + "] ", INFO_COLOR); |
|
67 } |
|
68 |
|
69 private static Spanned span(CharSequence s, Object o) { |
|
70 Spannable spannable = new SpannableString(s); |
|
71 spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); |
|
72 return spannable; |
|
73 } |
|
74 |
|
75 private static Spanned withColor(CharSequence s, int color) { |
|
76 return span(s, new ForegroundColorSpan(color)); |
|
77 } |
|
78 |
|
79 private static Spanned bold(CharSequence s) { |
|
80 return span(s, new StyleSpan(Typeface.BOLD)); |
|
81 } |
|
82 |
|
83 private void append(CharSequence msg) { |
|
84 SpannableStringBuilder ssb = new SpannableStringBuilder(); |
|
85 ssb.append(makeLogTime()).append(msg); |
|
86 appendRaw(ssb); |
|
87 } |
|
88 |
|
89 private void appendRaw(CharSequence msg) { |
|
90 if(log.size() > BACKLOG_LINES) { |
|
91 log.remove(0); |
|
92 for(Listener o : observers) { |
|
93 o.lineRemoved(); |
|
94 } |
|
95 } |
|
96 log.add(msg); |
|
97 for(Listener o : observers) { |
|
98 o.lineAdded(msg); |
|
99 } |
|
100 } |
|
101 |
|
102 void appendPlayerJoin(String playername) { |
|
103 append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR)); |
|
104 } |
|
105 |
|
106 void appendPlayerLeave(String playername, String partMsg) { |
|
107 String msg = "***"; |
|
108 if(partMsg != null) { |
|
109 msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg); |
|
110 } else { |
|
111 msg += context.getResources().getString(R.string.log_player_leave, playername); |
|
112 } |
|
113 append(withColor(msg, INFO_COLOR)); |
|
114 } |
|
115 |
|
116 void appendChat(String playerName, String msg) { |
|
117 if(msg.startsWith("/me ")) { |
|
118 append(withColor("*"+playerName+" "+msg.substring(4), MECHAT_COLOR)); |
|
119 } else { |
|
120 Spanned name = bold(playerName+": "); |
|
121 Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR); |
|
122 append(fullMessage); |
|
123 } |
|
124 } |
|
125 |
|
126 void appendMessage(int type, String msg) { |
|
127 switch(type) { |
|
128 case Frontlib.NETCONN_MSG_TYPE_ERROR: |
|
129 append(withColor("***"+msg, ERROR_COLOR)); |
|
130 break; |
|
131 case Frontlib.NETCONN_MSG_TYPE_WARNING: |
|
132 append(withColor("***"+msg, WARN_COLOR)); |
|
133 break; |
|
134 case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO: |
|
135 append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR)); |
|
136 break; |
|
137 case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: |
|
138 appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f))); |
|
139 break; |
|
140 default: |
|
141 Log.e("MessageLog", "Unknown messagetype "+type); |
|
142 } |
|
143 } |
|
144 |
|
145 void clear() { |
|
146 for(Listener o : observers) { |
|
147 o.clear(); |
|
148 } |
|
149 log.clear(); |
|
150 } |
|
151 |
|
152 public void addListener(Listener o) { |
|
153 observers.add(o); |
|
154 } |
|
155 |
|
156 public void removeListener(Listener o) { |
|
157 observers.remove(o); |
|
158 } |
|
159 |
|
160 public static interface Listener { |
|
161 void lineAdded(CharSequence text); |
|
162 void lineRemoved(); |
|
163 void clear(); |
|
164 } |
|
165 |
48 |
166 public Collection<CharSequence> getLog() { |
49 private static final int INFO_COLOR = Color.GRAY; |
167 return Collections.unmodifiableList(log); |
50 private static final int PLAYERINFO_COLOR = Color.GREEN; |
168 } |
51 private static final int CHAT_COLOR = Color.GREEN; |
|
52 private static final int MECHAT_COLOR = Color.CYAN; |
|
53 private static final int WARN_COLOR = Color.RED; |
|
54 private static final int ERROR_COLOR = Color.RED; |
|
55 |
|
56 private final Context context; |
|
57 private List<Listener> observers = new LinkedList<Listener>(); |
|
58 private List<CharSequence> log = new LinkedList<CharSequence>(); |
|
59 |
|
60 public MessageLog(Context context) { |
|
61 this.context = context; |
|
62 } |
|
63 |
|
64 private Spanned makeLogTime() { |
|
65 String time = DateFormat.getTimeFormat(context).format(new Date()); |
|
66 return withColor("[" + time + "] ", INFO_COLOR); |
|
67 } |
|
68 |
|
69 private static Spanned span(CharSequence s, Object o) { |
|
70 Spannable spannable = new SpannableString(s); |
|
71 spannable.setSpan(o, 0, s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); |
|
72 return spannable; |
|
73 } |
|
74 |
|
75 private static Spanned withColor(CharSequence s, int color) { |
|
76 return span(s, new ForegroundColorSpan(color)); |
|
77 } |
|
78 |
|
79 private static Spanned bold(CharSequence s) { |
|
80 return span(s, new StyleSpan(Typeface.BOLD)); |
|
81 } |
|
82 |
|
83 private void append(CharSequence msg) { |
|
84 SpannableStringBuilder ssb = new SpannableStringBuilder(); |
|
85 ssb.append(makeLogTime()).append(msg); |
|
86 appendRaw(ssb); |
|
87 } |
|
88 |
|
89 private void appendRaw(CharSequence msg) { |
|
90 if(log.size() > BACKLOG_LINES) { |
|
91 log.remove(0); |
|
92 for(Listener o : observers) { |
|
93 o.lineRemoved(); |
|
94 } |
|
95 } |
|
96 log.add(msg); |
|
97 for(Listener o : observers) { |
|
98 o.lineAdded(msg); |
|
99 } |
|
100 } |
|
101 |
|
102 void appendPlayerJoin(String playername) { |
|
103 append(withColor("***" + context.getResources().getString(R.string.log_player_join, playername), INFO_COLOR)); |
|
104 } |
|
105 |
|
106 void appendPlayerLeave(String playername, String partMsg) { |
|
107 String msg = "***"; |
|
108 if(partMsg != null) { |
|
109 msg += context.getResources().getString(R.string.log_player_leave_with_msg, playername, partMsg); |
|
110 } else { |
|
111 msg += context.getResources().getString(R.string.log_player_leave, playername); |
|
112 } |
|
113 append(withColor(msg, INFO_COLOR)); |
|
114 } |
|
115 |
|
116 void appendChat(String playerName, String msg) { |
|
117 if(msg.startsWith("/me ")) { |
|
118 append(withColor("*"+playerName+" "+msg.substring(4), MECHAT_COLOR)); |
|
119 } else { |
|
120 Spanned name = bold(playerName+": "); |
|
121 Spanned fullMessage = withColor(TextUtils.concat(name, msg), CHAT_COLOR); |
|
122 append(fullMessage); |
|
123 } |
|
124 } |
|
125 |
|
126 void appendMessage(int type, String msg) { |
|
127 switch(type) { |
|
128 case Frontlib.NETCONN_MSG_TYPE_ERROR: |
|
129 append(withColor("***"+msg, ERROR_COLOR)); |
|
130 break; |
|
131 case Frontlib.NETCONN_MSG_TYPE_WARNING: |
|
132 append(withColor("***"+msg, WARN_COLOR)); |
|
133 break; |
|
134 case Frontlib.NETCONN_MSG_TYPE_PLAYERINFO: |
|
135 append(withColor(msg.replace("\n", " "), PLAYERINFO_COLOR)); |
|
136 break; |
|
137 case Frontlib.NETCONN_MSG_TYPE_SERVERMESSAGE: |
|
138 appendRaw(span(TextUtils.concat("\n", Html.fromHtml(msg), "\n"), new RelativeSizeSpan(1.5f))); |
|
139 break; |
|
140 default: |
|
141 Log.e("MessageLog", "Unknown messagetype "+type); |
|
142 } |
|
143 } |
|
144 |
|
145 void clear() { |
|
146 for(Listener o : observers) { |
|
147 o.clear(); |
|
148 } |
|
149 log.clear(); |
|
150 } |
|
151 |
|
152 public void addListener(Listener o) { |
|
153 observers.add(o); |
|
154 } |
|
155 |
|
156 public void removeListener(Listener o) { |
|
157 observers.remove(o); |
|
158 } |
|
159 |
|
160 public static interface Listener { |
|
161 void lineAdded(CharSequence text); |
|
162 void lineRemoved(); |
|
163 void clear(); |
|
164 } |
|
165 |
|
166 public Collection<CharSequence> getLog() { |
|
167 return Collections.unmodifiableList(log); |
|
168 } |
169 } |
169 } |