]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/gui/pixx/PixxTaskBar.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 / PixxTaskBar.java
1 /*****************************************************/\r
2 /*          This java file is a part of the          */\r
3 /*                                                   */\r
4 /*           -  Plouf's Java IRC Client  -           */\r
5 /*                                                   */\r
6 /*   Copyright (C)  2002 - 2005 Philippe Detournay   */\r
7 /*                                                   */\r
8 /*         All contacts : theplouf@yahoo.com         */\r
9 /*                                                   */\r
10 /*  PJIRC is free software; you can redistribute     */\r
11 /*  it and/or modify it under the terms of the GNU   */\r
12 /*  General Public License as published by the       */\r
13 /*  Free Software Foundation; version 2 or later of  */\r
14 /*  the License.                                     */\r
15 /*                                                   */\r
16 /*  PJIRC is distributed in the hope that it will    */\r
17 /*  be useful, but WITHOUT ANY WARRANTY; without     */\r
18 /*  even the implied warranty of MERCHANTABILITY or  */\r
19 /*  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   */\r
20 /*  General Public License for more details.         */\r
21 /*                                                   */\r
22 /*  You should have received a copy of the GNU       */\r
23 /*  General Public License along with PJIRC; if      */\r
24 /*  not, write to the Free Software Foundation,      */\r
25 /*  Inc., 59 Temple Place, Suite 330, Boston,        */\r
26 /*  MA  02111-1307  USA                              */\r
27 /*                                                   */\r
28 /*****************************************************/\r
29 \r
30 package irc.gui.pixx;\r
31 \r
32 import irc.EventDispatcher;\r
33 import irc.ListenerGroup;\r
34 \r
35 import java.awt.Color;\r
36 import java.awt.Cursor;\r
37 import java.awt.Dimension;\r
38 import java.awt.Font;\r
39 import java.awt.Graphics;\r
40 import java.awt.Image;\r
41 import java.awt.event.InputEvent;\r
42 import java.awt.event.MouseEvent;\r
43 import java.awt.event.MouseListener;\r
44 import java.awt.event.MouseMotionListener;\r
45 import java.util.Enumeration;\r
46 import java.util.Vector;\r
47 \r
48 /**\r
49  * TaskBarItem.\r
50  */\r
51 class TaskBarItem {\r
52         /**\r
53          * Create a new TaskBarItem\r
54          * \r
55          * @param src\r
56          *          source.\r
57          * @param arow\r
58          *          row.\r
59          * @param abring\r
60          *          if should be brang.\r
61          */\r
62         public TaskBarItem(BaseAWTSource src, int arow, boolean abring) {\r
63                 source = src;\r
64                 eventWaiting = false;\r
65                 row = arow;\r
66                 bring = abring;\r
67                 visible = true;\r
68         }\r
69 \r
70         /**\r
71          * Source.\r
72          */\r
73         public BaseAWTSource source;\r
74         /**\r
75          * Row.\r
76          */\r
77         public int row;\r
78         /**\r
79          * True if some event is waiting.\r
80          */\r
81         public boolean eventWaiting;\r
82         /**\r
83          * True if source must be brang.\r
84          */\r
85         public boolean bring;\r
86         /**\r
87          * Source z-order.\r
88          */\r
89         public int zorder;\r
90         /**\r
91          * True if source is visible in the taskbar.\r
92          */\r
93         public boolean visible;\r
94 }\r
95 \r
96 /**\r
97  * The task bar.\r
98  */\r
99 public class PixxTaskBar extends PixxPanel implements MouseListener, MouseMotionListener, BaseAWTSourceListener {\r
100         private final ListenerGroup _listeners;\r
101 \r
102         private TaskBarItem _active;\r
103         private TaskBarItem _pressed;\r
104         private final Vector _items;\r
105 \r
106         private final int[] _itemCount;\r
107         private final int[] _visibleItemCount;\r
108         private final Font _font;\r
109         private Image _buffer;\r
110         private int _iwidth;\r
111         private int _ileft;\r
112         private int _zorder;\r
113         private boolean _handCursor;\r
114         private int _overX;\r
115         private int _overY;\r
116         private final int _maxWidth;\r
117 \r
118         /**\r
119          * Create a new PixxTaskBar.\r
120          * \r
121          * @param config\r
122          *          global irc configuration.\r
123          */\r
124         public PixxTaskBar(PixxConfiguration config) {\r
125                 super(config);\r
126                 _font = new Font("", 0, 12);\r
127                 _listeners = new ListenerGroup();\r
128                 _active = null;\r
129                 _pressed = null;\r
130                 _items = new Vector();\r
131                 _itemCount = new int[2];\r
132                 _visibleItemCount = new int[2];\r
133                 _itemCount[0] = 0;\r
134                 _itemCount[1] = 0;\r
135                 _visibleItemCount[0] = 0;\r
136                 _visibleItemCount[1] = 0;\r
137                 _ileft = 60;\r
138                 _zorder = 0;\r
139                 _handCursor = false;\r
140                 _overX = -1;\r
141                 _overY = -1;\r
142                 computeWidth();\r
143 \r
144                 addMouseListener(this);\r
145                 addMouseMotionListener(this);\r
146                 _maxWidth = config.getI("taskbaritemwidth");\r
147         }\r
148 \r
149         @Override\r
150         public void release() {\r
151                 _buffer = null;\r
152                 removeMouseMotionListener(this);\r
153                 removeMouseListener(this);\r
154                 super.release();\r
155         }\r
156 \r
157         /**\r
158          * Add a listener.\r
159          * \r
160          * @param lis\r
161          *          listener to add.\r
162          */\r
163         public void addPixxTaskBarListener(PixxTaskBarListener lis) {\r
164                 _listeners.addListener(lis);\r
165         }\r
166 \r
167         /**\r
168          * Remove a listener.\r
169          * \r
170          * @param lis\r
171          *          listener to remove.\r
172          */\r
173         public void removePixxTaskBarListener(PixxTaskBarListener lis) {\r
174                 _listeners.removeListener(lis);\r
175         }\r
176 \r
177         private TaskBarItem findItem(BaseAWTSource source) {\r
178                 if (source == null)\r
179                         return null;\r
180                 for (int i = 0; i < _items.size(); i++)\r
181                         if (((TaskBarItem) _items.elementAt(i)).source == source)\r
182                                 return (TaskBarItem) _items.elementAt(i);\r
183                 return null;\r
184         }\r
185 \r
186         private void removeFromVector(Vector v, Object o) {\r
187                 for (int i = 0; i < v.size(); i++)\r
188                         if (v.elementAt(i) == o)\r
189                                 v.removeElementAt(i);\r
190         }\r
191 \r
192         private synchronized void enter(BaseAWTSource source, int row, boolean bring) {\r
193                 TaskBarItem item = new TaskBarItem(source, row, bring);\r
194                 source.addBaseAWTSourceListener(this);\r
195                 _items.insertElementAt(item, _items.size());\r
196                 _itemCount[row]++;\r
197                 _visibleItemCount[row]++;\r
198                 _listeners.sendEvent("AWTSourceAdded", this, source);\r
199                 if (bring)\r
200                         activate(source);\r
201                 _buffer = null;\r
202                 repaint();\r
203         }\r
204 \r
205         private synchronized void leave(BaseAWTSource source, int row) {\r
206                 TaskBarItem item = findItem(source);\r
207                 source.removeBaseAWTSourceListener(this);\r
208                 _itemCount[row]--;\r
209                 _visibleItemCount[row]--;\r
210                 boolean change = getActive() == source;\r
211                 removeFromVector(_items, item);\r
212                 if (change)\r
213                         activate(null);\r
214                 _listeners.sendEvent("AWTSourceRemoved", this, source);\r
215                 _buffer = null;\r
216                 repaint();\r
217         }\r
218 \r
219         /**\r
220          * Get icons count in this task bar.\r
221          * \r
222          * @return icons count.\r
223          */\r
224         public int getCount() {\r
225                 return _itemCount[0] + _itemCount[1];\r
226         }\r
227 \r
228         /**\r
229          * Add a new channel in the taskbar.\r
230          * \r
231          * @param chan\r
232          *          channel to add.\r
233          * @param bring\r
234          *          true if this new channel must be made the active awt source.\r
235          */\r
236         public void addChannel(AWTChannel chan, boolean bring) {\r
237                 enter(chan, 0, bring);\r
238         }\r
239 \r
240         /**\r
241          * Remove the given channel from the taskbar.\r
242          * \r
243          * @param chan\r
244          *          channel to remove.\r
245          */\r
246         public void removeChannel(AWTChannel chan) {\r
247                 leave(chan, 0);\r
248         }\r
249 \r
250         /**\r
251          * Add a new status in the taskbar.\r
252          * \r
253          * @param status\r
254          *          status to add.\r
255          * @param bring\r
256          *          true if this new status must be made the active awt source.\r
257          */\r
258         public void addStatus(AWTStatus status, boolean bring) {\r
259                 enter(status, 1, bring);\r
260         }\r
261 \r
262         /**\r
263          * Remove the given status from the taskbar.\r
264          * \r
265          * @param status\r
266          *          status to remove.\r
267          */\r
268         public void removeStatus(AWTStatus status) {\r
269                 leave(status, 1);\r
270         }\r
271 \r
272         /**\r
273          * Add a new default source in the taskbar.\r
274          * \r
275          * @param source\r
276          *          default source to add.\r
277          * @param bring\r
278          *          true if this new default source must be made the active awt\r
279          *          source.\r
280          */\r
281         public void addDefaultSource(AWTDefaultSource source, boolean bring) {\r
282                 enter(source, 1, bring);\r
283         }\r
284 \r
285         /**\r
286          * Remove the given default source from the taskbar.\r
287          * \r
288          * @param source\r
289          *          default sourceto remove.\r
290          */\r
291         public void removeDefaultSource(AWTDefaultSource source) {\r
292                 leave(source, 1);\r
293         }\r
294 \r
295         /**\r
296          * Add a new query in the taskbar.\r
297          * \r
298          * @param query\r
299          *          query to add.\r
300          * @param bring\r
301          *          true if this new query must be made the active awt source.\r
302          */\r
303         public void addQuery(AWTQuery query, boolean bring) {\r
304                 enter(query, 1, bring);\r
305         }\r
306 \r
307         /**\r
308          * Remove the given query from the taskbar.\r
309          * \r
310          * @param query\r
311          *          query to remove.\r
312          */\r
313         public void removeQuery(AWTQuery query) {\r
314                 leave(query, 1);\r
315         }\r
316 \r
317         /**\r
318          * Add a new chanlist in the taskbar.\r
319          * \r
320          * @param chanlist\r
321          *          chanlist to add.\r
322          * @param bring\r
323          *          true if this new chanlist must be made the active awt source.\r
324          */\r
325         public void addChanList(AWTChanList chanlist, boolean bring) {\r
326                 enter(chanlist, 1, bring);\r
327         }\r
328 \r
329         /**\r
330          * Remove the given chanlist from the taskbar.\r
331          * \r
332          * @param chanlist\r
333          *          chanlist to remove.\r
334          */\r
335         public void removeChanList(AWTChanList chanlist) {\r
336                 leave(chanlist, 1);\r
337         }\r
338 \r
339         /**\r
340          * Add a new dcc chat in the taskbar.\r
341          * \r
342          * @param chat\r
343          *          dcc chat to add.\r
344          * @param bring\r
345          *          true if this new dcc chat must be made the active awt source.\r
346          */\r
347         public void addDCCChat(AWTDCCChat chat, boolean bring) {\r
348                 enter(chat, 1, bring);\r
349         }\r
350 \r
351         /**\r
352          * Remove the given dcc chat from the taskbar.\r
353          * \r
354          * @param chat\r
355          *          dcc chat to remove.\r
356          */\r
357         public void removeDCCChat(AWTDCCChat chat) {\r
358                 leave(chat, 1);\r
359         }\r
360 \r
361         private BaseAWTSource findFirst() {\r
362                 TaskBarItem first = null;\r
363                 int maxz = -1;\r
364                 for (int i = 0; i < _items.size(); i++) {\r
365                         TaskBarItem item = (TaskBarItem) _items.elementAt(i);\r
366                         if (item.zorder > maxz) {\r
367                                 maxz = item.zorder;\r
368                                 first = item;\r
369                         }\r
370                 }\r
371                 if (first == null)\r
372                         return null;\r
373                 return first.source;\r
374         }\r
375 \r
376         /**\r
377          * Get all sources sorted by their z-order.\r
378          * \r
379          * @return z-ordered sources.\r
380          */\r
381         public BaseAWTSource[] getZOrderedSources() {\r
382                 TaskBarItem[] items = new TaskBarItem[_items.size()];\r
383                 for (int i = 0; i < items.length; i++)\r
384                         items[i] = (TaskBarItem) _items.elementAt(i);\r
385 \r
386                 for (int i = 0; i < items.length - 1; i++) {\r
387                         TaskBarItem item = items[i];\r
388                         int max = item.zorder;\r
389                         int maxIndex = i;\r
390                         for (int j = i + 1; j < items.length; j++) {\r
391                                 item = items[j];\r
392                                 if (item.zorder > max) {\r
393                                         max = item.zorder;\r
394                                         maxIndex = j;\r
395                                 }\r
396                         }\r
397                         TaskBarItem tmp = items[i];\r
398                         items[i] = items[maxIndex];\r
399                         items[maxIndex] = tmp;\r
400                 }\r
401 \r
402                 BaseAWTSource[] ans = new BaseAWTSource[items.length];\r
403                 for (int i = 0; i < ans.length; i++)\r
404                         ans[i] = items[i].source;\r
405                 return ans;\r
406         }\r
407 \r
408         /**\r
409          * Make the given source visible in the taskbar.\r
410          * \r
411          * @param source\r
412          *          the source that should be visible.\r
413          */\r
414         public void show(BaseAWTSource source) {\r
415                 if (source == null)\r
416                         return;\r
417                 TaskBarItem item = findItem(source);\r
418                 if (item.visible)\r
419                         return;\r
420 \r
421                 item.visible = true;\r
422                 _visibleItemCount[item.row]++;\r
423 \r
424                 _buffer = null;\r
425                 repaint();\r
426         }\r
427 \r
428         /**\r
429          * Make the given source invisible in the taskbar.\r
430          * \r
431          * @param source\r
432          *          the source that should be invisible.\r
433          */\r
434         public void hide(BaseAWTSource source) {\r
435                 if (source == null)\r
436                         return;\r
437                 TaskBarItem item = findItem(source);\r
438                 if (!item.visible)\r
439                         return;\r
440 \r
441                 item.visible = false;\r
442                 _visibleItemCount[item.row]--;\r
443 \r
444                 _buffer = null;\r
445                 repaint();\r
446         }\r
447 \r
448         /**\r
449          * Activate the given source.\r
450          * \r
451          * @param source\r
452          *          the source to activate.\r
453          */\r
454         public void activate(BaseAWTSource source) {\r
455                 if (source == null)\r
456                         source = findFirst();\r
457                 if (source == null)\r
458                         return;\r
459                 TaskBarItem item = findItem(source);\r
460                 if (item == _active)\r
461                         return;\r
462                 if (!item.visible)\r
463                         return;\r
464                 if (_active != null)\r
465                         _listeners.sendEvent("AWTSourceDesactivated", this, _active.source);\r
466 \r
467                 _active = item;\r
468                 if (_active != null) {\r
469                         _active.zorder = _zorder++;\r
470                         _active.eventWaiting = false;\r
471                         _listeners.sendEvent("AWTSourceActivated", this, _active.source);\r
472                 } else {\r
473                         _listeners.sendEvent("AWTSourceActivated", this, null);\r
474                 }\r
475                 source.requestFocus();\r
476                 _buffer = null;\r
477                 repaint();\r
478         }\r
479 \r
480         /**\r
481          * Get the current active source.\r
482          * \r
483          * @return active source, or null if there is no active source.\r
484          */\r
485         public BaseAWTSource getActive() {\r
486                 if (_active == null)\r
487                         return null;\r
488                 return _active.source;\r
489         }\r
490 \r
491         @Override\r
492         public void paint(Graphics g) {\r
493                 update(g);\r
494         }\r
495 \r
496         @Override\r
497         public Dimension getPreferredSize() {\r
498                 return new Dimension(16, 2 * getItemHeight() + 16);\r
499         }\r
500 \r
501         private int getItemWidth() {\r
502                 return _iwidth;\r
503                 // return 100;\r
504         }\r
505 \r
506         private int getItemHeight() {\r
507                 return _font.getSize() + 4;\r
508         }\r
509 \r
510         private synchronized void computeWidth() {\r
511                 int w = getSize().width - 63;\r
512                 int n = Math.max(_visibleItemCount[0], _visibleItemCount[1]);\r
513 \r
514                 w -= 9 * n;\r
515                 if (n != 0)\r
516                         _iwidth = Math.min(_maxWidth, w / n);\r
517                 else\r
518                         _iwidth = _maxWidth;\r
519         }\r
520 \r
521         private int getX(int col) {\r
522                 return col * (getItemWidth() + 9) + _ileft;\r
523         }\r
524 \r
525         private int getCol(int x) {\r
526                 return (x - _ileft) / (9 + getItemWidth());\r
527         }\r
528 \r
529         private int getY(int row) {\r
530                 return 4 + (getItemHeight() + 8) * row;\r
531         }\r
532 \r
533         private int getRow(int y) {\r
534                 return (y - 4) / (8 + getItemHeight());\r
535         }\r
536 \r
537         private void drawItem(Graphics g, int col, int row, Color c, String s) {\r
538                 int x = getX(col);\r
539                 int y = getY(row);\r
540                 int w = getItemWidth();\r
541                 int h = getItemHeight();\r
542                 g.setClip(x + 1, y + 1, w - 1, h - 1);\r
543                 g.setColor(c);\r
544                 g.fillRect(x, y, w, h);\r
545                 g.setColor(getColor(COLOR_BLACK));\r
546                 g.drawRect(x, y, w, h);\r
547                 g.setColor(getColor(COLOR_WHITE));\r
548                 g.drawRect(x + 1, y + 1, w - 2, h - 2);\r
549                 y += h;\r
550                 int strw = g.getFontMetrics().stringWidth(s);\r
551                 y -= (h - _font.getSize()) / 2;\r
552                 g.drawString(s, x + (w - strw) / 2, y - 1);\r
553                 g.setClip(0, 0, getSize().width, getSize().height);\r
554         }\r
555 \r
556         private void drawItem(Graphics g, TaskBarItem item, int col) {\r
557                 int row = item.row;\r
558                 Color c = getColor(COLOR_FRONT);\r
559                 if ((item == _active) || (item == _pressed))\r
560                         c = getColor(COLOR_SELECTED);\r
561                 if ((item != _active) && (item.eventWaiting))\r
562                         c = getColor(COLOR_EVENT);\r
563                 drawItem(g, col++, row, c, item.source.getShortTitle());\r
564         }\r
565 \r
566         @Override\r
567         public void update(Graphics ug) {\r
568                 // int col=0;\r
569                 int w = getSize().width;\r
570                 int h = getSize().height;\r
571 \r
572                 if (_buffer != null) {\r
573                         if ((_buffer.getWidth(this) != w) || (_buffer.getHeight(this) != h))\r
574                                 _buffer = null;\r
575                 }\r
576 \r
577                 if (_buffer == null) {\r
578                         Graphics g;\r
579                         try {\r
580                                 _buffer = createImage(w, h);\r
581                                 g = _buffer.getGraphics();\r
582                         } catch (Throwable e) {\r
583                                 return;\r
584                         }\r
585 \r
586                         g.setFont(new Font("", Font.PLAIN, 12));\r
587                         int sw = Math.max(g.getFontMetrics().stringWidth(getText(PixxTextProvider.GUI_PRIVATE)), g.getFontMetrics()\r
588                                         .stringWidth(getText(PixxTextProvider.GUI_PUBLIC)));\r
589                         _ileft = 25 + sw;\r
590                         computeWidth();\r
591 \r
592                         // g.setColor(new Color(0x084079));\r
593                         g.setColor(getColor(COLOR_BACK));\r
594                         g.fillRect(0, 0, w, h);\r
595                         int col0 = 0;\r
596                         int col1 = 0;\r
597                         Enumeration el = _items.elements();\r
598                         while (el.hasMoreElements()) {\r
599                                 TaskBarItem item = (TaskBarItem) el.nextElement();\r
600                                 if (item.visible) {\r
601                                         if (item.row == 0)\r
602                                                 drawItem(g, item, col0++);\r
603                                         else\r
604                                                 drawItem(g, item, col1++);\r
605                                 }\r
606 \r
607                         }\r
608 \r
609                         // g.setColor(new Color(0x336699));\r
610                         g.setColor(getColor(COLOR_FRONT));\r
611                         g.fillRect(4, 5, sw + 2, h - 9);\r
612 \r
613                         for (int y = 3; y < h / 4; y++) {\r
614                                 g.drawLine(sw + 3 + y, y + 3, sw + 3 + y, h / 2 + 2 - y);\r
615                                 g.drawLine(sw + 3 + y, h - 3 - y, sw + 3 + y, h / 2 - 1 + y);\r
616                         }\r
617 \r
618                         // g.setColor(Color.black);\r
619                         g.setColor(getColor(COLOR_BLACK));\r
620                         g.drawLine(4, h / 2 - 1, w - 1, h / 2 - 1);\r
621                         g.drawLine(4, h / 2 + 1, w - 1, h / 2 + 1);\r
622                         // g.setColor(Color.white);\r
623                         g.setColor(getColor(COLOR_WHITE));\r
624                         g.drawLine(4, h / 2, w - 1, h / 2);\r
625 \r
626                         int y = getY(0) + getItemHeight();\r
627                         y -= (getItemHeight() - _font.getSize()) / 2;\r
628 \r
629                         g.drawString(getText(PixxTextProvider.GUI_PUBLIC), 8, y + 1);\r
630 \r
631                         y = getY(1) + getItemHeight();\r
632                         y -= (getItemHeight() - _font.getSize()) / 2;\r
633 \r
634                         g.drawString(getText(PixxTextProvider.GUI_PRIVATE), 8, y - 4);\r
635 \r
636                         // g.setColor(Color.black);\r
637                         g.setColor(getColor(COLOR_BLACK));\r
638                         g.drawLine(4, 5, 4, h - 5);\r
639 \r
640                         g.drawLine(4, 5, sw + 6, 5);\r
641                         g.drawLine(4, h - 5, sw + 6, h - 5);\r
642 \r
643                         g.drawLine(sw + 6, 5, sw + 3 + h / 4, h / 4 + 2);\r
644                         g.drawLine(sw + 3 + h / 4, h / 4 + 2, sw + 6, h / 2 - 1);\r
645 \r
646                         g.drawLine(sw + 6, h - 5, sw + 3 + h / 4, h - 1 - h / 4 - 1);\r
647                         g.drawLine(sw + 3 + h / 4, h - h / 4 - 2, sw + 6, h - 3 - h / 2 + 4);\r
648 \r
649                         // g.setColor(Color.white);\r
650                         g.setColor(getColor(COLOR_WHITE));\r
651                         g.drawLine(5, 6, 5, h - 6);\r
652 \r
653                         g.drawLine(5, 6, sw + 5, 6);\r
654                         g.drawLine(5, h - 6, sw + 5, h - 6);\r
655 \r
656                         g.drawLine(sw + 6, 6, sw + 2 + h / 4, h / 4 + 2);\r
657                         g.drawLine(sw + 2 + h / 4, h / 4 + 2, sw + 5, h / 2 - 1);\r
658 \r
659                         g.drawLine(sw + 6, h - 6, sw + 2 + h / 4, h - 1 - h / 4 - 1);\r
660                         g.drawLine(sw + 2 + h / 4, h - 2 - h / 4, sw + 5, h - 1 - h / 2 + 2);\r
661 \r
662                 }\r
663 \r
664                 if (_buffer != null)\r
665                         ug.drawImage(_buffer, 0, 0, this);\r
666                 TaskBarItem item = getItemAt(_overX, _overY);\r
667                 if (item != null) {\r
668                         String text = item.source.getShortTitle();\r
669                         int tw = ug.getFontMetrics().stringWidth(text);\r
670                         int x = getX(getCol(_overX)) + (getItemWidth() - tw) / 2 - 2;\r
671                         int y = getY(getRow(_overY)) - (getItemHeight() - _font.getSize()) / 2 - 1;\r
672 \r
673                         int fh = getItemHeight();\r
674                         if (text.length() > 0) {\r
675                                 if (tw >= getItemWidth()) {\r
676 \r
677                                         if (x + tw + 5 >= w)\r
678                                                 x = w - tw - 5;\r
679                                         if (x < 0)\r
680                                                 x = 0;\r
681                                         ug.setColor(getAlphaColor(getColor(COLOR_FRONT), 200));\r
682                                         ug.fillRect(x, y, tw + 4, fh + 4);\r
683                                         ug.setColor(getColor(COLOR_WHITE));\r
684                                         ug.drawRect(x, y, tw + 4, fh + 4);\r
685                                         ug.drawString(text, x + 2, y + fh);\r
686                                 }\r
687                         }\r
688                 }\r
689         }\r
690 \r
691         private Color getAlphaColor(Color c, int alpha) {\r
692                 try {\r
693                         return new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);\r
694                 } catch (Throwable ex) {\r
695                         return c;\r
696                 }\r
697         }\r
698 \r
699         private TaskBarItem getItemAt(int x, int y) {\r
700                 int row = getRow(y);\r
701                 int col = getCol(x);\r
702 \r
703                 x -= getX(col);\r
704                 y -= getY(row);\r
705                 if ((x >= getItemWidth()) || (y >= getItemHeight()))\r
706                         return null;\r
707                 if ((x < 0) || (y < 0))\r
708                         return null;\r
709 \r
710                 int currentcol = 0;\r
711                 Enumeration el = _items.elements();\r
712                 while (el.hasMoreElements()) {\r
713                         TaskBarItem item = (TaskBarItem) el.nextElement();\r
714                         if (item.visible) {\r
715                                 if (item.row == row) {\r
716                                         if (currentcol == col)\r
717                                                 return item;\r
718                                         currentcol++;\r
719                                 }\r
720                         }\r
721                 }\r
722                 return null;\r
723         }\r
724 \r
725         @Override\r
726         public void mouseMoved(MouseEvent e) {\r
727                 TaskBarItem item = getItemAt(e.getX(), e.getY());\r
728                 if (item != null) {\r
729                         if (!_handCursor) {\r
730                                 setCursor(new Cursor(Cursor.HAND_CURSOR));\r
731                                 _handCursor = true;\r
732                         }\r
733                 } else {\r
734                         if (_handCursor) {\r
735                                 setCursor(new Cursor(Cursor.DEFAULT_CURSOR));\r
736                                 _handCursor = false;\r
737                         }\r
738                 }\r
739                 TaskBarItem oldItem = getItemAt(_overX, _overY);\r
740                 if (oldItem != item) {\r
741                         _overX = e.getX();\r
742                         _overY = e.getY();\r
743                         repaint();\r
744                 }\r
745         }\r
746 \r
747         @Override\r
748         public void mouseDragged(MouseEvent e) {\r
749                 mouseMoved(e);\r
750         }\r
751 \r
752         @Override\r
753         public void mouseClicked(MouseEvent e) {\r
754         }\r
755 \r
756         @Override\r
757         public void mouseEntered(MouseEvent e) {\r
758         }\r
759 \r
760         @Override\r
761         public void mouseExited(MouseEvent e) {\r
762                 mouseMoved(e);\r
763         }\r
764 \r
765         @Override\r
766         public void mousePressed(MouseEvent e) {\r
767                 TaskBarItem np = getItemAt(e.getX(), e.getY());\r
768                 _pressed = np;\r
769                 _buffer = null;\r
770                 repaint();\r
771                 if (_pressed != null)\r
772                         _listeners.sendEventAsync("eventOccured", this, _pressed.source, e);\r
773         }\r
774 \r
775         @Override\r
776         public void mouseReleased(MouseEvent e) {\r
777                 _pressed = null;\r
778                 TaskBarItem src = getItemAt(e.getX(), e.getY());\r
779                 try {\r
780                         if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0)\r
781                                 if (src != null)\r
782                                         EventDispatcher.dispatchEventAsyncAndWaitEx(this, "activate", new Object[] { src.source });\r
783                 } catch (InterruptedException ex) {\r
784                 } catch (Throwable ex) {\r
785                 }\r
786 \r
787                 _buffer = null;\r
788                 repaint();\r
789         }\r
790 \r
791         @Override\r
792         public void titleChanged(BaseAWTSource source) {\r
793                 _buffer = null;\r
794                 repaint();\r
795         }\r
796 \r
797         @Override\r
798         public void eventOccured(BaseAWTSource source) {\r
799                 TaskBarItem item = findItem(source);\r
800                 if (item == null)\r
801                         return;\r
802                 if (item == _active)\r
803                         return;\r
804                 item.eventWaiting = true;\r
805                 _buffer = null;\r
806                 repaint();\r
807         }\r
808 \r
809 }\r