source: trunk/hiptop/cognet++/org/twodot/cognet/ChatHistory.java@ 210

Last change on this file since 210 was 210, checked in by Nicholas Riley, 18 years ago

cognet++: Brian Swetland et al.'s generic proxied hiptop chat client.
Requires cognetd to function.

File size: 7.9 KB
Line 
1/*
2 * cognet chat app
3 *
4 * Copyright 2003, Brian Swetland <swetland@frotz.net>
5 * See LICENSE for redistribution terms
6 *
7 * Derived from:
8 *
9 * @(#)ChatHistory.java 1.0 01/03/23
10 *
11 * Copyright 2000 by Danger Research, Inc.
12 * 165 University Avenue, Palo Alto, CA 94301
13 * All rights reserved.
14 * See SAMPLE_CODE_LICENSE for redistribution terms.
15 *
16 */
17
18package org.twodot.cognet;
19
20import danger.ui.*;
21import danger.util.LineBreaker;
22import java.util.Enumeration;
23
24public class ChatHistory extends View
25{
26 public
27 ChatHistory(int inSizeLimit, Engine e)
28 {
29 Rect r;
30
31 mPlainFont = Font.findSystemFont();
32 mBoldFont = Font.findSystemFont();
33
34 mAscent = mBoldFont.getAscent() + mBoldFont.getDescent();
35 mLineHeight = mAscent + kLeading - 2;
36
37 mLimit = inSizeLimit;
38
39 setSize(20, 10);
40 engine = e;
41
42 tag_bitmap = engine.app.bm_tag;
43 tag_width = tag_bitmap.getWidth();
44 tag_height = tag_bitmap.getHeight();
45 tag_font = Font.findFont("Bort7");
46 }
47
48 Bitmap tag_bitmap;
49 int tag_width, tag_height;
50 Font tag_font;
51
52
53 public void
54 paint(Pen inPen)
55 {
56
57 Rect r = getBounds();
58 int i, x, y;
59 ChatLine index = mBottomDisplayLine;
60
61 //* Clear the area
62 if(mCurrentSelection != 0){
63 inPen.setColor(Color.GRAY10);
64 } else {
65 inPen.setColor(Color.WHITE);
66 }
67 inPen.fillRect(r);
68
69 inPen.setColor(Color.BLACK);
70
71 x = r.left;
72 y = mLineHeight * (mNumDisplayLines - 1);
73 y += mAscent;
74 y += r.top;
75
76 SmileyEngine smiley = new SmileyEngine(mPlainFont);
77 inPen.setFont(mPlainFont);
78 //* Draw the individual lines
79 while ((y > r.top) && (null != index)) {
80// if (engine.app.doSmileys)
81 smiley.drawString(x,y,index.mText, inPen);
82// else
83// inPen.drawText(x, y, index.mText);
84
85 y -= mLineHeight;
86 index = index.mPrev;
87 }
88
89 y = 0;
90 x = r.right - tag_width;
91
92
93 inPen.setColor(Color.BLACK);
94
95 Enumeration enum = engine.alerts.keys();
96 while (enum.hasMoreElements()) {
97 inPen.setFont(tag_font);
98 inPen.drawBitmap(x, y, tag_bitmap);
99 inPen.drawText(x + 3, y + 9, ((Character) enum.nextElement()).toString());
100 y += tag_height;
101 }
102 }
103
104 public void
105 setSize(int inWidth, int inHeight)
106 {
107 Rect r;
108
109 super.setSize(inWidth, inHeight);
110
111 mPlainLineBreaker = new LineBreaker("", mPlainFont, inWidth - 8, 0);
112 mBoldLineBreaker = new LineBreaker("", mBoldFont, inWidth - 8, 0);
113
114 r = getBounds();
115 r.inset(kBorder);
116
117 mNumDisplayLines = r.getHeight() / mLineHeight;
118 }
119
120 public void
121 AddChannel(String inText) {
122 AddLines(inText, 0);
123 }
124
125 public void
126 AddSent(String inText) {
127 AddLines(inText, 3);
128 }
129
130 public void
131 AddPrivate(String inText) {
132 AddLines(inText, 1);
133 }
134
135 public void
136 AddServer(String inText) {
137 AddLines(inText, 2);
138 }
139
140
141 void AddLines(String inText, int glyph) {
142 if (engine.app.doSmileys)
143 AddLinesIcon(inText, glyph);
144 else
145 AddLinesPlain(inText, glyph);
146 }
147
148 private void AddLinesPlain(String inText, int glyph)
149 {
150 int firstChar = 0, lastChar = 0;
151 boolean firstLine = true;
152 LineBreaker lineBreaker;
153
154 //* If we're scrolled up then we need to mark this line as the first
155 //* incoming line that we missed;
156 if (0 == mCurrentSelection)
157 mFirstMissed = false;
158
159 //* Pick the right line breaker depending on the font
160 lineBreaker = mPlainLineBreaker;
161
162 lineBreaker.setText(inText);
163
164 while (lastChar < inText.length())
165 {
166 String s;
167 ChatLine line;
168
169 lastChar = lineBreaker.nextLineBreak(firstChar);
170
171 s = inText.substring(firstChar, lastChar);
172 line = new ChatLine(s, glyph, firstLine, mFirstMissed);
173 AddLine(line, glyph);
174
175 firstLine = false;
176 mFirstMissed = false;
177
178 firstChar = lastChar;
179 }
180
181 TrimForLength();
182 }
183
184
185 private void AddLinesIcon(String inText, int glyph)
186 {
187 int firstChar = 0, lastChar = 0;
188 boolean firstLine = true;
189 //LineBreaker lineBreaker;
190 SmileyEngine smileyEngine;
191
192 //* If we're scrolled up then we need to mark this line as the first
193 //* incoming line that we missed;
194 if (0 == mCurrentSelection)
195 mFirstMissed = false;
196
197 //* Pick the right line breaker depending on the font
198 //lineBreaker = mPlainLineBreaker;
199
200 //lineBreaker.setText(inText);
201 if (inText.startsWith("<::::>")) {
202 // server flag
203 inText = SmileyEngine.ICON_FLAG + inText.substring(6);
204 }
205 if (inText.startsWith("<*>")) {
206 // cognet++ message
207 inText = SmileyEngine.ICON_COG + inText.substring(3);
208 }
209 if (inText.startsWith("* ")) {
210 // action flag
211 inText = SmileyEngine.ICON_BULLET + inText.substring(1);
212 }
213 if (inText.startsWith("<-> ")) {
214 // info flag
215 inText = SmileyEngine.ICON_INFO + inText.substring(3);
216 }
217
218 smileyEngine = new SmileyEngine(mPlainFont, inText);
219 String strLine;
220
221
222 while ((strLine = smileyEngine.getNext(getWidth() - 8)) != null)
223 {
224 String s;
225 ChatLine line;
226
227 line = new ChatLine(strLine, glyph, firstLine, mFirstMissed);
228 AddLine(line, glyph);
229
230 firstLine = false;
231 mFirstMissed = false;
232
233 }
234
235 TrimForLength();
236 }
237
238 public void
239 AddLine(ChatLine inLine, int glyph)
240 {
241 Rect r = getBounds();
242 int numLines;
243 ChatLine line;
244 boolean atBottom = false;
245
246 if (mBottomDisplayLine == mTail)
247 atBottom = true;
248
249 mNumLines++;
250 mTextSize += inLine.mText.length();
251
252 r.inset(kBorder);
253 numLines = r.getHeight() / mLineHeight;
254
255 if (null == mHead)
256 {
257 mHead = inLine;
258 mBottomDisplayLine = inLine;
259 mTail = inLine;
260
261 return;
262 }
263
264 mTail.mNext = inLine;
265 inLine.mPrev = mTail;
266 mTail = inLine;
267
268 if (atBottom /* || output */)
269 {
270 mCurrentSelection = 0;
271 mBottomDisplayLine = mTail;
272 }
273 else
274 {
275 mCurrentSelection++;
276 }
277 }
278
279 void
280 TrimForLength()
281 {
282 while (mTextSize > mLimit)
283 {
284 if (mNumDisplayLines >= (mNumLines - mCurrentSelection))
285 {
286 mCurrentSelection--;
287 mBottomDisplayLine = mBottomDisplayLine.mNext;
288 }
289
290 mTextSize -= mHead.mText.length();
291
292 mHead.mNext.mPrev = null;
293 mHead = mHead.mNext;
294
295 mNumLines--;
296 }
297 }
298
299 void
300 ScrollUp()
301 {
302 if ((mNumLines - mCurrentSelection) <= mNumDisplayLines)
303 return;
304
305 mCurrentSelection++;
306 mBottomDisplayLine = mBottomDisplayLine.mPrev;
307
308 mFirstMissed = true;
309 }
310
311 void
312 ScrollDown()
313 {
314 if (mCurrentSelection == 0)
315 return;
316
317 mCurrentSelection--;
318 mBottomDisplayLine = mBottomDisplayLine.mNext;
319
320 if (0 == mCurrentSelection)
321 mFirstMissed = false;
322 }
323
324 public void
325 Clear() {
326 mTextSize = 0;
327 mNumLines = 0;
328 mCurrentSelection = 0;
329 mHead = null;
330 mTail = null;
331 mBottomDisplayLine = null;
332 mFirstMissed = false;
333 }
334
335 void setPlainFont(Font f) {
336 Clear();
337 mPlainFont = f;
338 mAscent = mPlainFont.getAscent() + mPlainFont.getDescent();
339 mLineHeight = mAscent + kLeading - 2;
340 mNumDisplayLines = getHeight() / mLineHeight;
341 }
342
343 void setEmoticons(boolean onOff) {
344 Clear();
345 engine.app.doSmileys = onOff;
346 }
347
348 private int mLimit;
349 private int mTextSize;
350 private int mNumDisplayLines;
351
352 private int mNumLines;
353 private int mCurrentSelection;
354
355 private int mAscent;
356 private int mLineHeight;
357
358 private ChatLine mHead;
359 private ChatLine mBottomDisplayLine;
360 private ChatLine mTail;
361
362 private Font mPlainFont;
363 private Font mBoldFont;
364
365 private LineBreaker mPlainLineBreaker;
366 private LineBreaker mBoldLineBreaker;
367
368 private boolean mFirstMissed;
369
370 static final int kBorder = 2;
371 static final int kLeading = 2;
372 Engine engine;
373}
374
375class ChatLine
376{
377 public
378 ChatLine(String inText, int glyph, boolean inFirstLine, boolean inFirstMissed)
379 {
380 mText = inText;
381 mGlyph = glyph;
382 mFirstLine = inFirstLine;
383 mFirstMissed = inFirstMissed;
384 }
385
386 String mText;
387 int mGlyph;
388 boolean mFirstLine;
389 boolean mFirstMissed;
390
391 ChatLine mPrev;
392 ChatLine mNext;
393}
Note: See TracBrowser for help on using the repository browser.