]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/gui/pixx/PixxNickList.java
Pjirc 2.2.1 as available on the net, reformatted and made it compile.
[irc/pjirc-ng.git] / src / main / java / irc / gui / pixx / PixxNickList.java
1 /*****************************************************/
2 /*          This java file is a part of the          */
3 /*                                                   */
4 /*           -  Plouf's Java IRC Client  -           */
5 /*                                                   */
6 /*   Copyright (C)  2002 - 2004 Philippe Detournay   */
7 /*                                                   */
8 /*         All contacts : theplouf@yahoo.com         */
9 /*                                                   */
10 /*  PJIRC is free software; you can redistribute     */
11 /*  it and/or modify it under the terms of the GNU   */
12 /*  General Public License as published by the       */
13 /*  Free Software Foundation; version 2 or later of  */
14 /*  the License.                                     */
15 /*                                                   */
16 /*  PJIRC is distributed in the hope that it will    */
17 /*  be useful, but WITHOUT ANY WARRANTY; without     */
18 /*  even the implied warranty of MERCHANTABILITY or  */
19 /*  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   */
20 /*  General Public License for more details.         */
21 /*                                                   */
22 /*  You should have received a copy of the GNU       */
23 /*  General Public License along with PJIRC; if      */
24 /*  not, write to the Free Software Foundation,      */
25 /*  Inc., 59 Temple Place, Suite 330, Boston,        */
26 /*  MA  02111-1307  USA                              */
27 /*                                                   */
28 /*****************************************************/
29
30 package irc.gui.pixx;
31
32 import irc.ListenerGroup;
33
34 import java.awt.Color;
35 import java.awt.Dimension;
36 import java.awt.Font;
37 import java.awt.FontMetrics;
38 import java.awt.Graphics;
39 import java.awt.Image;
40 import java.awt.event.MouseEvent;
41 import java.awt.event.MouseListener;
42 import java.awt.event.MouseMotionListener;
43 import java.util.Vector;
44
45 /**
46  * The pixx nick list display.
47  */
48 public class PixxNickList extends PixxPanel implements MouseListener, MouseMotionListener {
49         private Vector _nicks;
50         private Image _buffer;
51         private Font _font;
52         private int _base;
53         private int _selected;
54         private int _overindex;
55         private int _overX;
56         private int _toScroll;
57         private Object _scrollLock = new Object();
58         private ListenerGroup _listeners;
59         private char[] _prefixes;
60         private boolean _leftAlign;
61
62         /**
63          * Create a new PixxNickList.
64          * 
65          * @param config
66          *          global irc configuration.
67          * @param prefixes
68          *          known nick prefixes.
69          */
70         public PixxNickList(PixxConfiguration config, char[] prefixes) {
71                 super(config);
72                 _prefixes = prefixes;
73                 _toScroll = 0;
74                 _selected = -1;
75                 _overindex = -1;
76                 _listeners = new ListenerGroup();
77                 addMouseListener(this);
78                 addMouseMotionListener(this);
79                 _base = 0;
80                 _nicks = new Vector();
81                 _font = new Font("", 0, 12);
82                 _leftAlign = _pixxConfiguration.getB("leftnickalign");
83         }
84
85         @Override
86         public void release() {
87                 dispose();
88                 removeMouseListener(this);
89                 removeMouseMotionListener(this);
90                 super.release();
91         }
92
93         /**
94          * Add listener.
95          * 
96          * @param lis
97          *          listener to add.
98          */
99         public void addPixxNickListListener(PixxNickListListener lis) {
100                 _listeners.addListener(lis);
101         }
102
103         /**
104          * Remove listener.
105          * 
106          * @param lis
107          *          listener to remove.
108          */
109         public void removePixxNickListListener(PixxNickListListener lis) {
110                 _listeners.removeListener(lis);
111         }
112
113         @Override
114         public Dimension getPreferredSize() {
115                 return new Dimension(_pixxConfiguration.getI("nicklistwidth"), 16);
116         }
117
118         /**
119          * Clear any off-screen ressources. The next display might be slower.
120          */
121         public void dispose() {
122                 reinit();
123         }
124
125         private void reinit() {
126                 synchronized (_scrollLock) {
127                         _toScroll = 0;
128                         _buffer = null;
129                 }
130         }
131
132         private void scroll(int v) {
133                 synchronized (_scrollLock) {
134                         _toScroll += v;
135                         _base += v;
136                 }
137         }
138
139         private int getScrollValue() {
140                 synchronized (_scrollLock) {
141                         int ans = _toScroll;
142                         _toScroll = 0;
143                         return ans;
144                 }
145         }
146
147         /**
148          * Set first displayed nick.
149          * 
150          * @param b
151          *          first displayed nick index.
152          */
153         public void setBase(int b) {
154                 scroll(b - _base);
155                 repaint();
156         }
157
158         /**
159          * Get first displayed nick.
160          * 
161          * @return first dispalyed nick index.
162          */
163         public int getBase() {
164                 return _base;
165         }
166
167         /**
168          * Get amount of nicks in the list.
169          * 
170          * @return nick list size.
171          */
172         public int getNickCount() {
173                 return _nicks.size();
174         }
175
176         /**
177          * Add a nick in the list.
178          * 
179          * @param nick
180          *          nickname to add.
181          */
182         public void add(String nick) {
183                 _nicks.insertElementAt(nick, _nicks.size());
184                 reinit();
185                 repaint();
186         }
187
188         /**
189          * Remove the given nick name from the list.
190          * 
191          * @param nick
192          *          nick name to remove.
193          */
194         public void remove(String nick) {
195                 for (int i = 0; i < _nicks.size(); i++) {
196                         String s = (String) _nicks.elementAt(i);
197                         if (s.equals(nick)) {
198                                 _nicks.removeElementAt(i);
199                                 break;
200                         }
201                 }
202                 reinit();
203                 repaint();
204         }
205
206         /**
207          * Change all the nicks in the list.
208          * 
209          * @param nicks
210          *          new nick array.
211          */
212         public void set(String[] nicks) {
213                 _nicks = new Vector();
214                 for (int i = 0; i < nicks.length; i++)
215                         _nicks.insertElementAt(nicks[i], _nicks.size());
216                 reinit();
217                 repaint();
218         }
219
220         /**
221          * Remove all the nicks from the list.
222          */
223         @Override
224         public void removeAll() {
225                 _nicks = new Vector();
226                 // _buffer=null;
227                 reinit();
228                 repaint();
229         }
230
231         @Override
232         public void paint(Graphics g) {
233                 update(g);
234         }
235
236         private Color findColor(String info) {
237                 return _pixxConfiguration.getIRCConfiguration().getASLColor(info, getColor(COLOR_MALE), getColor(COLOR_FEMEALE),
238                                 getColor(COLOR_UNDEF));
239         }
240
241         private void update(Graphics gra, int ytop, int height) {
242                 int w = getSize().width;
243                 // int h=getSize().height;
244                 int fh = _font.getSize();
245
246                 gra.setColor(getColor(COLOR_BACK));
247                 gra.fillRect(0, ytop, w, height);
248                 gra.setColor(getColor(COLOR_BLACK));
249                 gra.drawLine(w - 1, ytop, w - 1, ytop + height - 1);
250
251                 gra.setFont(_font);
252
253                 int y = 8;
254                 FontMetrics fm = gra.getFontMetrics();
255
256                 int i = _base;
257                 while (y + fh + 5 < ytop) {
258                         y += fh + 6;
259                         i++;
260                 }
261                 if (i > 0) {
262                         y -= fh + 6;
263                         i--;
264                 }
265                 while ((i < _nicks.size()) && (y <= ytop + height)) {
266                         String nick = (String) _nicks.elementAt(i);
267                         String info = "";
268                         int pos = nick.indexOf(":");
269                         Color back = getColor(COLOR_FRONT);
270                         if (pos != -1) {
271                                 info = nick.substring(pos + 1);
272                                 nick = nick.substring(0, pos);
273                                 back = findColor(info);
274                         }
275                         if (_selected == i)
276                                 back = getColor(COLOR_SELECTED);
277
278                         char prefix = 0;
279                         for (int ci = 0; ci < _prefixes.length; ci++)
280                                 if ((nick.length() > 0) && (nick.charAt(0) == _prefixes[ci]))
281                                         prefix = _prefixes[ci];
282                         if (prefix > 0)
283                                 nick = nick.substring(1);
284
285                         int sw = fm.stringWidth(nick);
286
287                         gra.setColor(back);
288                         gra.fillRect(20, y - 1, w - 28, fh + 2);
289                         gra.setColor(getColor(COLOR_WHITE));
290                         gra.drawRect(20, y - 1, w - 28, fh + 2);
291
292                         gra.setColor(getColor(COLOR_WHITE));
293                         gra.setClip(20, y - 1, w - 28, fh + 2);
294                         int px = w - sw - 12;
295                         if (px < 22)
296                                 px = 22;
297
298                         if (_leftAlign)
299                                 px = 22;
300
301                         gra.drawString(nick, px, y + fh - 1);
302                         gra.setClip(0, 0, getSize().width, getSize().height);
303
304                         if (prefix > 0) {
305                                 if (prefix == '@')
306                                         gra.setColor(getColor(COLOR_OP));
307                                 else if (prefix == '+')
308                                         gra.setColor(getColor(COLOR_VOICE));
309                                 else if (prefix == '%')
310                                         gra.setColor(getColor(COLOR_SEMIOP));
311                                 else
312                                         gra.setColor(getColor(COLOR_FRONT));
313                                 gra.fillRect(20 - fh - 6, y - 1, fh + 2, fh + 2);
314                                 gra.setColor(getColor(COLOR_WHITE));
315                                 gra.drawRect(20 - fh - 6, y - 1, fh + 2, fh + 2);
316
317                                 gra.setColor(getColor(COLOR_WHITE));
318                                 sw = fm.stringWidth("" + prefix);
319                                 int tx = 20 - fh - 6 + (fh + 2 - sw) / 2 + 1;
320                                 int ty = y + fh - 1;
321                                 if (prefix == '@') {
322                                         tx--;
323                                         ty--;
324                                 }
325                                 gra.drawString("" + prefix, tx, ty);
326                         }
327
328                         y += fh + 6;
329                         i++;
330                 }
331         }
332
333         @Override
334         public void update(Graphics g) {
335                 int w = getSize().width;
336                 int h = getSize().height;
337                 int fh = _font.getSize();
338
339                 if (_buffer != null) {
340                         if ((_buffer.getWidth(this) != w) || (_buffer.getHeight(this) != h))
341                                 _buffer = null;
342                 }
343
344                 if (_buffer == null) {
345                         Graphics gra;
346                         try {
347                                 _buffer = createImage(w, h);
348                                 gra = _buffer.getGraphics();
349                                 update(gra, 0, h);
350                         } catch (Throwable e) {
351                                 return;
352                         }
353                 } else {
354                         int scr = getScrollValue();
355                         if (scr != 0) {
356                                 Graphics gra = _buffer.getGraphics();
357                                 int dy = -(fh + 6) * scr;
358                                 if (dy < 0) {
359                                         gra.copyArea(0, -dy, w, h + dy, 0, dy);
360                                         update(gra, h + dy, -dy);
361                                 } else {
362                                         gra.copyArea(0, 0, w, h - dy, 0, dy);
363                                         update(gra, 0, dy);
364                                 }
365                         }
366                 }
367
368                 if (_buffer != null)
369                         g.drawImage(_buffer, 0, 0, this);
370                 if ((_overindex != -1) && _pixxConfiguration.getIRCConfiguration().getB("style:floatingasl")) {
371                         int x = _overX;
372                         int y = 8 + (_overindex - _base) * (fh + 6) + 2;
373                         if (y + fh + 5 >= h)
374                                 y = h - fh - 5;
375                         String info = getInfo(_overindex);
376                         String text = _pixxConfiguration.getIRCConfiguration().formatASL(info);
377                         if (text.length() > 0) {
378                                 int tw = g.getFontMetrics().stringWidth(text);
379                                 if (x + tw + 5 >= w)
380                                         x = w - tw - 5;
381                                 if (x < 0)
382                                         x = 0;
383                                 g.setColor(getAlphaColor(findColor(info),
384                                                 _pixxConfiguration.getIRCConfiguration().getI("style:floatingaslalpha")));
385                                 g.fillRect(x, y, tw + 4, fh + 4);
386                                 g.setColor(getColor(COLOR_WHITE));
387                                 g.drawRect(x, y, tw + 4, fh + 4);
388                                 g.drawString(text, x + 2, y + fh);
389                         }
390                 }
391         }
392
393         private Color getAlphaColor(Color c, int alpha) {
394                 try {
395                         return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
396                 } catch (Throwable ex) {
397                         return c;
398                 }
399         }
400
401         private int getIndex(int x, int y) {
402                 int fh = _font.getSize();
403                 // increase y value so that it won't reach negative value. neg y is a
404                 // problem since / rounds to 0, not to lower : -0.5 will lead to 0, not
405                 // to -1.
406                 y += fh + 6;
407                 y -= 8;
408                 y /= fh + 6;
409                 y--;
410                 y += _base;
411                 if (y < 0)
412                         y = -1;
413                 if (y >= _nicks.size())
414                         y = -1;
415                 return y;
416         }
417
418         @Override
419         public void mouseClicked(MouseEvent e) {
420         }
421
422         @Override
423         public void mouseEntered(MouseEvent e) {
424         }
425
426         @Override
427         public void mouseExited(MouseEvent e) {
428                 if (_overindex != -1) {
429                         _overindex = -1;
430                         repaint();
431                 }
432         }
433
434         @Override
435         public void mousePressed(MouseEvent e) {
436                 int index = getIndex(e.getX(), e.getY());
437                 _selected = index;
438                 reinit();
439                 repaint();
440                 if (_selected != -1)
441                         _listeners.sendEventAsync("eventOccured", getNick(_selected), e);
442         }
443
444         @Override
445         public void mouseReleased(MouseEvent e) {
446         }
447
448         @Override
449         public void mouseDragged(MouseEvent e) {
450                 mouseMoved(e);
451         }
452
453         private String getUnprefixedNick(String nick) {
454                 if (nick.length() == 0)
455                         return nick;
456                 for (int i = 0; i < _prefixes.length; i++)
457                         if (nick.charAt(0) == _prefixes[i])
458                                 return nick.substring(1);
459                 return nick;
460         }
461
462         private String getNick(int index) {
463                 if (index == -1)
464                         return "";
465                 String nick = (String) _nicks.elementAt(index);
466                 nick = getUnprefixedNick(nick);
467                 int pos = nick.indexOf(":");
468                 if (pos != -1) {
469                         nick = nick.substring(0, pos);
470                 }
471                 return nick;
472         }
473
474         private String getInfo(int index) {
475                 if (index == -1)
476                         return "";
477                 String nick = (String) _nicks.elementAt(index);
478                 nick = getUnprefixedNick(nick);
479                 int pos = nick.indexOf(":");
480                 String info = "";
481                 if (pos != -1) {
482                         info = nick.substring(pos + 1);
483                 }
484                 return info;
485         }
486
487         @Override
488         public void mouseMoved(MouseEvent e) {
489                 if (!_pixxConfiguration.getIRCConfiguration().getASLMaster())
490                         return;
491                 int index = getIndex(e.getX(), e.getY());
492                 if (index == _overindex)
493                         return;
494                 _overindex = index;
495                 _overX = e.getX();
496                 repaint();
497                 if (index != -1)
498                         _listeners.sendEventAsync("ASLEventOccured", getNick(index), getInfo(index));
499         }
500 }