]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/gui/pixx/PixxVerticalScrollBar.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 / PixxVerticalScrollBar.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 - 2004 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.ListenerGroup;\r
33 \r
34 import java.awt.Color;\r
35 import java.awt.Dimension;\r
36 import java.awt.Graphics;\r
37 import java.awt.Image;\r
38 import java.awt.event.MouseEvent;\r
39 import java.awt.event.MouseListener;\r
40 import java.awt.event.MouseMotionListener;\r
41 \r
42 /**\r
43  * The vertical pixx scroll bar.\r
44  */\r
45 public class PixxVerticalScrollBar extends PixxPanel implements PixxScrollBar, MouseListener, MouseMotionListener,\r
46                 Runnable {\r
47         private double _min;\r
48         private double _max;\r
49         private double _val;\r
50         private boolean _mouseDown;\r
51         private boolean _mouseDownUp;\r
52         private boolean _mouseDownDown;\r
53         private int _base;\r
54 \r
55         private final int _arrow = 10;\r
56         private double _view;\r
57 \r
58         private MouseEvent _repeatEvent;\r
59         private int _repeatEventCount;\r
60         private Thread _repeatThread;\r
61 \r
62         private ListenerGroup _listeners;\r
63 \r
64         /**\r
65          * Create a new PixxVerticalScrollBar.\r
66          * \r
67          * @param config\r
68          *          global irc configuration.\r
69          * @param min\r
70          *          minimum value.\r
71          * @param max\r
72          *          maximum value.\r
73          * @param view\r
74          *          width of the display.\r
75          */\r
76         public PixxVerticalScrollBar(PixxConfiguration config, int min, int max, double view) {\r
77                 super(config);\r
78                 _mouseDown = false;\r
79                 _view = view;\r
80                 _listeners = new ListenerGroup();\r
81                 setMinimum(min);\r
82                 setMaximum(max);\r
83                 setValue(min);\r
84                 addMouseListener(this);\r
85                 addMouseMotionListener(this);\r
86         }\r
87 \r
88         @Override\r
89         public void run() {\r
90                 boolean terminated = false;\r
91                 _repeatEventCount = 0;\r
92                 while (!terminated) {\r
93                         try {\r
94                                 if (_repeatEventCount++ == 0)\r
95                                         Thread.sleep(500);\r
96                                 else\r
97                                         Thread.sleep(50);\r
98                                 mousePressed(_repeatEvent);\r
99                         } catch (InterruptedException ex) {\r
100                                 terminated = true;\r
101                         }\r
102                 }\r
103         }\r
104 \r
105         @Override\r
106         public void release() {\r
107                 removeMouseListener(this);\r
108                 removeMouseMotionListener(this);\r
109                 super.release();\r
110         }\r
111 \r
112         /**\r
113          * Add a listener.\r
114          * \r
115          * @param lis\r
116          *          listener to add.\r
117          */\r
118         @Override\r
119         public void addPixxScrollBarListener(PixxScrollBarListener lis) {\r
120                 _listeners.addListener(lis);\r
121         }\r
122 \r
123         /**\r
124          * Remove a listener.\r
125          * \r
126          * @param lis\r
127          *          listener to remove.\r
128          */\r
129         @Override\r
130         public void removePixxScrollBarListener(PixxScrollBarListener lis) {\r
131                 _listeners.removeListener(lis);\r
132         }\r
133 \r
134         private Color[] getColors(boolean invert) {\r
135                 Color[] c = new Color[5];\r
136                 if (!invert) {\r
137                         c[0] = getColor(COLOR_FRONT);\r
138                         c[1] = getColor(COLOR_BLACK);\r
139                         c[2] = getColor(COLOR_GRAY);\r
140                         c[3] = getColor(COLOR_LIGHT_GRAY);\r
141                         c[4] = getColor(COLOR_WHITE);\r
142                 } else {\r
143                         c[0] = getColor(COLOR_SELECTED);\r
144                         c[1] = getColor(COLOR_BLACK);\r
145                         c[2] = getColor(COLOR_GRAY);\r
146                         c[3] = getColor(COLOR_LIGHT_GRAY);\r
147                         c[4] = getColor(COLOR_WHITE);\r
148                 }\r
149 \r
150                 return c;\r
151         }\r
152 \r
153         private void drawA(Graphics g, int pos, boolean invert) {\r
154                 int w = getSize().width;\r
155                 // int h=getSize().height;\r
156                 int y = pos;\r
157 \r
158                 Color c[] = getColors(invert);\r
159 \r
160                 g.setColor(c[0]);\r
161                 for (int i = 0; i < w - 5; i++)\r
162                         g.drawLine(i + 3, y - 1, i + 3, y - 1 - i);\r
163 \r
164                 g.setColor(c[1]);\r
165                 g.drawLine(0, y - 1, w - 2, y - w + 1);\r
166                 g.setColor(c[2]);\r
167                 g.drawLine(1, y - 1, w - 2, y - w + 2);\r
168                 g.setColor(c[4]);\r
169                 g.drawLine(2, y - 1, w - 2, y - w + 3);\r
170 \r
171                 g.setColor(c[1]);\r
172                 g.drawLine(w - 1, y - 1, w - 1, y - w);\r
173                 g.setColor(c[4]);\r
174                 g.drawLine(w - 2, y - 1, w - 2, y + 3 - w);\r
175 \r
176         }\r
177 \r
178         private void drawB(Graphics g, int pos, boolean invert) {\r
179                 int w = getSize().width;\r
180                 // int h=getSize().height;\r
181                 int y = pos;\r
182 \r
183                 Color c[] = getColors(invert);\r
184 \r
185                 g.setColor(c[0]);\r
186                 for (int i = 0; i < w - 5; i++)\r
187                         g.drawLine(w - 1 - i - 3, y, w - 1 - i - 3, y + i);\r
188 \r
189                 g.setColor(c[1]);\r
190                 g.drawLine(0, y + w - 1, w - 1, y);\r
191                 g.setColor(c[2]);\r
192                 g.drawLine(1, y + w - 3, w - 2, y);\r
193                 g.setColor(c[4]);\r
194                 g.drawLine(1, y + w - 4, w - 3, y);\r
195 \r
196                 g.setColor(c[3]);\r
197                 g.drawLine(0, y, 0, y + w - 2);\r
198                 g.setColor(c[4]);\r
199                 g.drawLine(1, y, 1, y + w - 4);\r
200 \r
201         }\r
202 \r
203         private void drawInside(Graphics g, int pos, int lng, boolean invert) {\r
204                 int w = getSize().width;\r
205                 // int h=getSize().height;\r
206                 Color c[] = getColors(invert);\r
207                 int y = pos;\r
208 \r
209                 g.setColor(c[3]);\r
210                 g.drawLine(0, y, 0, y + lng - 1);\r
211                 g.setColor(c[4]);\r
212                 g.drawLine(1, y, 1, y + lng - 1);\r
213                 g.drawLine(w - 2, y, w - 2, y + lng - 1);\r
214                 g.setColor(c[1]);\r
215                 g.drawLine(w - 1, y, w - 1, y + lng - 1);\r
216                 g.setColor(c[0]);\r
217                 g.fillRect(2, y, w - 4, lng);\r
218         }\r
219 \r
220         @Override\r
221         public Dimension getPreferredSize() {\r
222                 return new Dimension(16, 100);\r
223         }\r
224 \r
225         @Override\r
226         public void paint(Graphics g) {\r
227                 update(g);\r
228         }\r
229 \r
230         private int getMargin() {\r
231                 return _arrow + getSize().width;\r
232         }\r
233 \r
234         private int getCursorLong() {\r
235                 int h = getSize().height;\r
236                 int margin = getMargin();\r
237                 if (_min == _max)\r
238                         return h - 2 * margin;\r
239                 double iSee = (h - 2 * margin) * _view;\r
240 \r
241                 int cursorLong = (int) ((iSee / (_max - _min + 1)) * (h - 2 * margin));\r
242                 if (cursorLong > (h - 2 * margin) / 3)\r
243                         cursorLong = (h - 2 * margin) / 3;\r
244                 return cursorLong;\r
245         }\r
246 \r
247         private int getPos() {\r
248                 int h = getSize().height;\r
249                 int lng = h;\r
250 \r
251                 int margin = getMargin();\r
252                 int cursorLong = getCursorLong();\r
253                 return (int) ((_val * (lng - margin - cursorLong) + (_max - _val) * margin) / (_max) - margin);\r
254         }\r
255 \r
256         @Override\r
257         public void update(Graphics g) {\r
258                 int w = getSize().width;\r
259                 int h = getSize().height;\r
260                 int margin = getMargin();\r
261                 int cursorLong = getCursorLong();\r
262 \r
263                 Image buffer;\r
264                 Graphics gra;\r
265                 try {\r
266                         buffer = createImage(w, h);\r
267                         gra = buffer.getGraphics();\r
268                 } catch (Throwable e) {\r
269                         return;\r
270                 }\r
271 \r
272                 gra.setColor(getColor(COLOR_BACK));\r
273                 gra.fillRect(0, 0, w, h);\r
274 \r
275                 // fleche du haut\r
276                 drawInside(gra, 2, _arrow - 2, _mouseDownUp);\r
277                 drawB(gra, margin - w, _mouseDownUp);\r
278 \r
279                 Color c[] = getColors(_mouseDownUp);\r
280                 gra.setColor(c[3]);\r
281                 gra.drawLine(1, 0, w - 2, 0);\r
282                 gra.drawLine(0, 0, 0, 1);\r
283                 gra.setColor(c[4]);\r
284                 gra.drawLine(1, 1, w - 2, 1);\r
285                 gra.setColor(c[1]);\r
286                 gra.drawLine(w - 1, 0, w - 1, 1);\r
287 \r
288                 gra.setColor(c[4]);\r
289                 gra.drawLine(w / 2, 4, w / 4 + 1, 4 + w / 4 - 1);\r
290                 gra.drawLine(w / 2, 4, 3 * w / 4 - 1, 4 + w / 4 - 1);\r
291 \r
292                 // fleche du bas\r
293                 drawInside(gra, h - _arrow, _arrow - 2, _mouseDownDown);\r
294                 drawA(gra, h - margin + w, _mouseDownDown);\r
295 \r
296                 c = getColors(_mouseDownDown);\r
297                 gra.setColor(c[3]);\r
298                 gra.drawLine(0, h - 2, 0, h - 1);\r
299                 gra.setColor(c[1]);\r
300                 gra.drawLine(w - 1, h - 2, w - 1, h - 1);\r
301                 gra.drawLine(1, h - 1, w - 2, h - 1);\r
302                 gra.setColor(c[4]);\r
303                 gra.drawLine(1, h - 2, w - 2, h - 2);\r
304 \r
305                 gra.setColor(c[4]);\r
306                 gra.drawLine(w / 2, h - 5, w / 4 + 1, h - 5 - w / 4 + 1);\r
307                 gra.drawLine(w / 2, h - 5, 3 * w / 4 - 1, h - 5 - w / 4 + 1);\r
308 \r
309                 // curseur\r
310                 int pos = getPos() + margin;\r
311                 drawInside(gra, pos, cursorLong, _mouseDown);\r
312                 drawA(gra, pos, _mouseDown);\r
313                 drawB(gra, pos + cursorLong, _mouseDown);\r
314 \r
315                 g.drawImage(buffer, 0, 0, this);\r
316         }\r
317 \r
318         /**\r
319          * Set minimum position.\r
320          * \r
321          * @param v\r
322          *          new minimum position.\r
323          */\r
324         @Override\r
325         public void setMinimum(int v) {\r
326                 _min = v;\r
327                 if (_min > _max)\r
328                         _min = _max;\r
329                 if (_val < _min)\r
330                         updateValue(_min);\r
331                 repaint();\r
332         }\r
333 \r
334         /**\r
335          * Set maximum position.\r
336          * \r
337          * @param v\r
338          *          new maximum position.\r
339          */\r
340         @Override\r
341         public void setMaximum(int v) {\r
342                 _max = v;\r
343                 if (_max < _min)\r
344                         _max = _min;\r
345                 if (_val > _max)\r
346                         updateValue(_max);\r
347                 repaint();\r
348         }\r
349 \r
350         /**\r
351          * Set value.\r
352          * \r
353          * @param v\r
354          *          new value.\r
355          */\r
356         @Override\r
357         public void setValue(int v) {\r
358                 _val = v;\r
359                 if (_val < _min)\r
360                         _val = _min;\r
361                 if (_val > _max)\r
362                         _val = _max;\r
363                 repaint();\r
364         }\r
365 \r
366         /**\r
367          * Get current value.\r
368          * \r
369          * @return value.\r
370          */\r
371         @Override\r
372         public int getValue() {\r
373                 return (int) (_val + 0.5);\r
374         }\r
375 \r
376         private boolean inCursor(int x, int y) {\r
377                 int w = getSize().width;\r
378                 // int h=getSize().height;\r
379                 int l = getCursorLong();\r
380                 y -= getMargin();\r
381                 y -= getPos();\r
382 \r
383                 return (x + y >= -1) && (y + x - l - w <= -1);\r
384         }\r
385 \r
386         private boolean inSubArrow(int x, int y) {\r
387                 y -= getMargin();\r
388                 return (x + y <= -1);\r
389         }\r
390 \r
391         private boolean inAddArrow(int x, int y) {\r
392                 int w = getSize().width;\r
393                 int h = getSize().height;\r
394                 return (y + x - h + getMargin() - w >= -1);\r
395         }\r
396 \r
397         private double getValue(int x, int y) {\r
398                 // int w=getSize().width;\r
399                 int h = getSize().height;\r
400                 // int lrg=w;\r
401                 int lng = h;\r
402                 int margin = getMargin();\r
403 \r
404                 lng -= margin * 2 + getCursorLong();\r
405 \r
406                 int py = y - margin - _base;\r
407 \r
408                 return (_max - _min) * py / lng + _min;\r
409         }\r
410 \r
411         private void updateValue(double v) {\r
412                 int oldVal = getValue();\r
413                 _val = v;\r
414                 if (_val < _min)\r
415                         _val = _min;\r
416                 if (_val > _max)\r
417                         _val = _max;\r
418                 repaint();\r
419                 if (getValue() != oldVal) {\r
420                         _listeners.sendEventAsync("valueChanged", this);\r
421                 }\r
422         }\r
423 \r
424         @Override\r
425         public void mouseClicked(MouseEvent e) {\r
426         }\r
427 \r
428         @Override\r
429         public void mouseEntered(MouseEvent e) {\r
430         }\r
431 \r
432         @Override\r
433         public void mouseExited(MouseEvent e) {\r
434         }\r
435 \r
436         private void beginRepeat(MouseEvent e) {\r
437                 _repeatEvent = e;\r
438                 _repeatThread = new Thread(this, "Scrolling thread");\r
439                 _repeatThread.start();\r
440         }\r
441 \r
442         private void endRepeat() {\r
443                 if (_repeatThread != null) {\r
444                         try {\r
445                                 _repeatThread.interrupt();\r
446                         } catch (Exception ex) {\r
447                         }\r
448                         try {\r
449                                 _repeatThread.join(1000);\r
450                         } catch (Exception ex) {\r
451                         }\r
452                         _repeatThread = null;\r
453                 }\r
454         }\r
455 \r
456         @Override\r
457         public void mousePressed(MouseEvent e) {\r
458                 if (inCursor(e.getX(), e.getY())) {\r
459                         _base = e.getY() - getMargin() - getPos();\r
460                         _mouseDown = true;\r
461                         repaint();\r
462                         return;\r
463                 } else if (inSubArrow(e.getX(), e.getY())) {\r
464                         _mouseDownUp = true;\r
465                         updateValue(_val - 1);\r
466                         repaint();\r
467                 } else if (inAddArrow(e.getX(), e.getY())) {\r
468                         _mouseDownDown = true;\r
469                         updateValue(_val + 1);\r
470                         repaint();\r
471                 } else if (getValue(e.getX(), e.getY()) < _val) {\r
472                         updateValue(_val - 10);\r
473                         repaint();\r
474                 } else if (getValue(e.getX(), e.getY()) > _val) {\r
475                         updateValue(_val + 10);\r
476                         repaint();\r
477                 }\r
478                 if (_repeatThread == null)\r
479                         beginRepeat(e);\r
480         }\r
481 \r
482         @Override\r
483         public void mouseReleased(MouseEvent e) {\r
484                 endRepeat();\r
485                 _mouseDown = false;\r
486                 _mouseDownUp = false;\r
487                 _mouseDownDown = false;\r
488                 repaint();\r
489         }\r
490 \r
491         @Override\r
492         public void mouseDragged(MouseEvent e) {\r
493                 mouseMoved(e);\r
494         }\r
495 \r
496         @Override\r
497         public void mouseMoved(MouseEvent e) {\r
498                 _repeatEvent = e;\r
499                 if (_mouseDown) {\r
500                         updateValue(getValue(e.getX(), e.getY()));\r
501                 }\r
502         }\r
503 }\r