]> git.somenet.org - irc/pjirc-ng.git/blob - src/main/java/irc/gui/pixx/PixxHorizontalScrollBar.java
GITOLITE.txt
[irc/pjirc-ng.git] / src / main / java / irc / gui / pixx / PixxHorizontalScrollBar.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 horizontal pixx scroll bar.\r
44  */\r
45 public class PixxHorizontalScrollBar 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 PixxHorizontalScrollBar(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 x = pos;\r
157 \r
158                 Color c[] = getColors(invert);\r
159 \r
160                 g.setColor(c[0]);\r
161                 /*\r
162                  * for(int i=0;i<w-5;i++) g.drawLine(i+3,y-1,i+3,y-1-i);\r
163                  * \r
164                  * g.setColor(c[1]); g.drawLine(0,y-1,w-2,y-w+1); g.setColor(c[2]);\r
165                  * g.drawLine(1,y-1,w-2,y-w+2); g.setColor(c[4]);\r
166                  * g.drawLine(2,y-1,w-2,y-w+3);\r
167                  * \r
168                  * g.setColor(c[1]); g.drawLine(w-1,y-1,w-1,y-w); g.setColor(c[4]);\r
169                  * g.drawLine(w-2,y-1,w-2,y+3-w);\r
170                  */\r
171                 for (int i = 0; i < h - 5; i++)\r
172                         // g.drawLine(i+3,y-1,i+3,y-1-i);\r
173                         g.drawLine(x - 1, i + 3, x - 1 - i, i + 3);\r
174 \r
175                 g.setColor(c[1]);\r
176                 // g.drawLine(0,y-1,w-2,y-w+1);\r
177                 g.drawLine(x - 1, 0, x - h + 1, h - 2);\r
178                 g.setColor(c[2]);\r
179                 // g.drawLine(1,y-1,w-2,y-w+2);\r
180                 g.drawLine(x - 1, 1, x - h + 2, h - 2);\r
181                 g.setColor(c[4]);\r
182                 // g.drawLine(2,y-1,w-2,y-w+3);\r
183                 g.drawLine(x - 1, 2, x - h + 3, h - 2);\r
184 \r
185                 g.setColor(c[1]);\r
186                 // g.drawLine(w-1,y-1,w-1,y-w);\r
187                 g.drawLine(x - 1, h - 1, x - h, h - 1);\r
188                 g.setColor(c[4]);\r
189                 // g.drawLine(w-2,y-1,w-2,y+3-w);\r
190                 g.drawLine(x - 1, h - 2, x + 3 - h, h - 2);\r
191         }\r
192 \r
193         private void drawB(Graphics g, int pos, boolean invert) {\r
194                 // int w=getSize().width;\r
195                 int h = getSize().height;\r
196                 int x = pos;\r
197 \r
198                 Color c[] = getColors(invert);\r
199 \r
200                 /*\r
201                  * g.setColor(c[0]); for(int i=0;i<w-5;i++)\r
202                  * g.drawLine(w-1-i-3,y,w-1-i-3,y+i);\r
203                  * \r
204                  * g.setColor(c[1]); g.drawLine(0,y+w-1,w-1,y); g.setColor(c[2]);\r
205                  * g.drawLine(1,y+w-3,w-2,y); g.setColor(c[4]); g.drawLine(1,y+w-4,w-3,y);\r
206                  * \r
207                  * g.setColor(c[3]); g.drawLine(0,y,0,y+w-2); g.setColor(c[4]);\r
208                  * g.drawLine(1,y,1,y+w-4);\r
209                  */\r
210 \r
211                 g.setColor(c[0]);\r
212                 for (int i = 0; i < h - 5; i++)\r
213                         g.drawLine(x, h - 1 - i - 3, x + i, h - 1 - i - 3);\r
214 \r
215                 g.setColor(c[1]);\r
216                 // g.drawLine(0,y+w-1,w-1,y);\r
217                 g.drawLine(x + h - 1, 0, x, h - 1);\r
218                 g.setColor(c[2]);\r
219                 // g.drawLine(1,y+w-3,w-2,y);\r
220                 g.drawLine(x + h - 3, 1, x, h - 2);\r
221                 g.setColor(c[4]);\r
222                 // g.drawLine(1,y+w-4,w-3,y);\r
223                 g.drawLine(x + h - 4, 1, x, h - 3);\r
224 \r
225                 g.setColor(c[3]);\r
226                 // g.drawLine(0,y,0,y+w-2);\r
227                 g.drawLine(x, 0, x + h - 2, 0);\r
228                 g.setColor(c[4]);\r
229                 // g.drawLine(1,y,1,y+w-4);\r
230                 g.drawLine(x, 1, x + h - 4, 1);\r
231 \r
232         }\r
233 \r
234         private void drawInside(Graphics g, int pos, int lng, boolean invert) {\r
235                 // int w=getSize().width;\r
236                 int h = getSize().height;\r
237                 Color c[] = getColors(invert);\r
238                 int x = pos;\r
239 \r
240                 /*\r
241                  * g.setColor(c[3]); g.drawLine(0,y,0,y+lng-1); g.setColor(c[4]);\r
242                  * g.drawLine(1,y,1,y+lng-1); g.drawLine(w-2,y,w-2,y+lng-1);\r
243                  * g.setColor(c[1]); g.drawLine(w-1,y,w-1,y+lng-1); g.setColor(c[0]);\r
244                  * g.fillRect(2,y,w-4,lng);\r
245                  */\r
246                 g.setColor(c[3]);\r
247                 g.drawLine(x, 0, x + lng - 1, 0);\r
248                 g.setColor(c[4]);\r
249                 g.drawLine(x, 1, x + lng - 1, 1);\r
250                 g.drawLine(x, h - 2, x + lng - 1, h - 2);\r
251                 g.setColor(c[1]);\r
252                 g.drawLine(x, h - 1, x + lng - 1, h - 1);\r
253                 g.setColor(c[0]);\r
254                 g.fillRect(x, 2, lng, h - 4);\r
255         }\r
256 \r
257         @Override\r
258         public Dimension getPreferredSize() {\r
259                 return new Dimension(100, 16);\r
260         }\r
261 \r
262         @Override\r
263         public void paint(Graphics g) {\r
264                 update(g);\r
265         }\r
266 \r
267         private int getMargin() {\r
268                 return _arrow + getSize().height;\r
269         }\r
270 \r
271         private int getCursorLong() {\r
272                 int h = getSize().width;\r
273                 int margin = getMargin();\r
274                 if (_min == _max)\r
275                         return h - 2 * margin;\r
276                 double iSee = (h - 2 * margin) * _view;\r
277 \r
278                 int cursorLong = (int) ((iSee / (_max - _min + 1)) * (h - 2 * margin));\r
279                 if (cursorLong > (h - 2 * margin) / 3)\r
280                         cursorLong = (h - 2 * margin) / 3;\r
281                 return cursorLong;\r
282         }\r
283 \r
284         private int getPos() {\r
285                 int h = getSize().width;\r
286                 int lng = h;\r
287 \r
288                 int margin = getMargin();\r
289                 int cursorLong = getCursorLong();\r
290                 return (int) ((_val * (lng - margin - cursorLong) + (_max - _val) * margin) / (_max) - margin);\r
291         }\r
292 \r
293         @Override\r
294         public void update(Graphics g) {\r
295                 int w = getSize().width;\r
296                 int h = getSize().height;\r
297                 int margin = getMargin();\r
298                 int cursorLong = getCursorLong();\r
299 \r
300                 Image buffer;\r
301                 Graphics gra;\r
302                 try {\r
303                         buffer = createImage(w, h);\r
304                         gra = buffer.getGraphics();\r
305                 } catch (Throwable e) {\r
306                         return;\r
307                 }\r
308 \r
309                 gra.setColor(getColor(COLOR_BACK));\r
310                 gra.fillRect(0, 0, w, h);\r
311 \r
312                 // fleche de gauche\r
313                 drawInside(gra, 2, _arrow - 2, _mouseDownUp);\r
314                 drawB(gra, margin - h, _mouseDownUp);\r
315 \r
316                 Color c[] = getColors(_mouseDownUp);\r
317                 gra.setColor(c[3]);\r
318                 // gra.drawLine(1,0,w-2,0);\r
319                 gra.drawLine(0, 1, 0, h - 2);\r
320                 // gra.drawLine(0,0,0,1);\r
321                 gra.drawLine(0, 0, 1, 0);\r
322                 gra.setColor(c[4]);\r
323                 // gra.drawLine(1,1,w-2,1);\r
324                 gra.drawLine(1, 1, 1, h - 2);\r
325                 gra.setColor(c[1]);\r
326                 // gra.drawLine(w-1,0,w-1,1);\r
327                 gra.drawLine(0, h - 1, 1, h - 1);\r
328 \r
329                 gra.setColor(c[4]);\r
330                 // gra.drawLine(w/2,4,w/4+1,4+w/4-1);\r
331                 gra.drawLine(4, h / 2, 4 + h / 4 - 1, h / 4 + 1);\r
332                 // gra.drawLine(w/2,4,3*w/4-1,4+w/4-1);\r
333                 gra.drawLine(4, h / 2, 4 + h / 4 - 1, 3 * h / 4 - 1);\r
334 \r
335                 // fleche de droite\r
336                 drawInside(gra, w - _arrow, _arrow - 2, _mouseDownDown);\r
337                 drawA(gra, w - margin + h, _mouseDownDown);\r
338 \r
339                 c = getColors(_mouseDownDown);\r
340                 gra.setColor(c[3]);\r
341                 // gra.drawLine(0,h-2,0,h-1);\r
342                 gra.drawLine(w - 2, 0, w - 1, 0);\r
343                 gra.setColor(c[1]);\r
344                 // gra.drawLine(w-1,h-2,w-1,h-1);\r
345                 gra.drawLine(w - 2, h - 1, w - 1, h - 1);\r
346                 // gra.drawLine(1,h-1,w-2,h-1);\r
347                 gra.drawLine(w - 1, 1, w - 1, h - 2);\r
348                 gra.setColor(c[4]);\r
349                 // gra.drawLine(1,h-2,w-2,h-2);\r
350                 gra.drawLine(w - 2, 1, w - 2, h - 2);\r
351 \r
352                 gra.setColor(c[4]);\r
353                 // gra.drawLine(w/2,h-5,w/4+1,h-5-w/4+1);\r
354                 gra.drawLine(w - 5, h / 2, w - 5 - h / 4 + 1, h / 4 + 1);\r
355                 // gra.drawLine(w/2,h-5,3*w/4-1,h-5-w/4+1);\r
356                 gra.drawLine(w - 5, h / 2, w - 5 - h / 4 + 1, 3 * h / 4 - 1);\r
357 \r
358                 // curseur\r
359                 int pos = getPos() + margin;\r
360                 drawInside(gra, pos, cursorLong, _mouseDown);\r
361                 drawA(gra, pos, _mouseDown);\r
362                 drawB(gra, pos + cursorLong, _mouseDown);\r
363 \r
364                 g.drawImage(buffer, 0, 0, this);\r
365         }\r
366 \r
367         /**\r
368          * Set minimum position.\r
369          * \r
370          * @param v\r
371          *          new minimum position.\r
372          */\r
373         @Override\r
374         public void setMinimum(int v) {\r
375                 _min = v;\r
376                 if (_min > _max)\r
377                         _min = _max;\r
378                 if (_val < _min)\r
379                         updateValue(_min);\r
380                 repaint();\r
381         }\r
382 \r
383         /**\r
384          * Set maximum position.\r
385          * \r
386          * @param v\r
387          *          new maximum position.\r
388          */\r
389         @Override\r
390         public void setMaximum(int v) {\r
391                 _max = v;\r
392                 if (_max < _min)\r
393                         _max = _min;\r
394                 if (_val > _max)\r
395                         updateValue(_max);\r
396                 repaint();\r
397         }\r
398 \r
399         /**\r
400          * Set value.\r
401          * \r
402          * @param v\r
403          *          new value.\r
404          */\r
405         @Override\r
406         public void setValue(int v) {\r
407                 _val = v;\r
408                 if (_val < _min)\r
409                         _val = _min;\r
410                 if (_val > _max)\r
411                         _val = _max;\r
412                 repaint();\r
413         }\r
414 \r
415         /**\r
416          * Get current value.\r
417          * \r
418          * @return value.\r
419          */\r
420         @Override\r
421         public int getValue() {\r
422                 return (int) (_val + 0.5);\r
423         }\r
424 \r
425         private boolean inCursor(int x, int y) {\r
426                 // int w=getSize().width;\r
427                 int h = getSize().height;\r
428                 int l = getCursorLong();\r
429                 x -= getMargin();\r
430                 x -= getPos();\r
431 \r
432                 return (x + y >= -1) && (y + x - l - h <= -1);\r
433         }\r
434 \r
435         private boolean inSubArrow(int x, int y) {\r
436                 x -= getMargin();\r
437                 return (x + y <= -1);\r
438         }\r
439 \r
440         private boolean inAddArrow(int x, int y) {\r
441                 int w = getSize().width;\r
442                 int h = getSize().height;\r
443                 return (y + x - w + getMargin() - h >= -1);\r
444         }\r
445 \r
446         private double getValue(int x, int y) {\r
447                 int w = getSize().width;\r
448                 int lng = w;\r
449                 int margin = getMargin();\r
450 \r
451                 lng -= margin * 2 + getCursorLong();\r
452 \r
453                 int px = x - margin - _base;\r
454                 return (_max - _min) * px / lng + _min;\r
455         }\r
456 \r
457         private void updateValue(double v) {\r
458                 int oldVal = getValue();\r
459                 _val = v;\r
460                 if (_val < _min)\r
461                         _val = _min;\r
462                 if (_val > _max)\r
463                         _val = _max;\r
464                 repaint();\r
465                 if (getValue() != oldVal) {\r
466                         _listeners.sendEventAsync("valueChanged", this);\r
467                 }\r
468         }\r
469 \r
470         @Override\r
471         public void mouseClicked(MouseEvent e) {\r
472         }\r
473 \r
474         @Override\r
475         public void mouseEntered(MouseEvent e) {\r
476         }\r
477 \r
478         @Override\r
479         public void mouseExited(MouseEvent e) {\r
480         }\r
481 \r
482         private void beginRepeat(MouseEvent e) {\r
483                 _repeatEvent = e;\r
484                 _repeatThread = new Thread(this, "Scrolling thread");\r
485                 _repeatThread.start();\r
486         }\r
487 \r
488         private void endRepeat() {\r
489                 if (_repeatThread != null) {\r
490                         try {\r
491                                 _repeatThread.interrupt();\r
492                         } catch (Exception ex) {\r
493                         }\r
494                         try {\r
495                                 _repeatThread.join(1000);\r
496                         } catch (Exception ex) {\r
497                         }\r
498                         _repeatThread = null;\r
499                 }\r
500         }\r
501 \r
502         @Override\r
503         public void mousePressed(MouseEvent e) {\r
504                 if (inCursor(e.getX(), e.getY())) {\r
505                         _base = e.getX() - getMargin() - getPos();\r
506                         _mouseDown = true;\r
507                         repaint();\r
508                         return;\r
509                 } else if (inSubArrow(e.getX(), e.getY())) {\r
510                         _mouseDownUp = true;\r
511                         updateValue(_val - 1);\r
512                         repaint();\r
513                 } else if (inAddArrow(e.getX(), e.getY())) {\r
514                         _mouseDownDown = true;\r
515                         updateValue(_val + 1);\r
516                         repaint();\r
517                 } else if (getValue(e.getX(), e.getY()) < _val) {\r
518                         updateValue(_val - 10);\r
519                         repaint();\r
520                 } else if (getValue(e.getX(), e.getY()) > _val) {\r
521                         updateValue(_val + 10);\r
522                         repaint();\r
523                 }\r
524                 if (_repeatThread == null)\r
525                         beginRepeat(e);\r
526         }\r
527 \r
528         @Override\r
529         public void mouseReleased(MouseEvent e) {\r
530                 endRepeat();\r
531                 _mouseDown = false;\r
532                 _mouseDownUp = false;\r
533                 _mouseDownDown = false;\r
534                 repaint();\r
535         }\r
536 \r
537         @Override\r
538         public void mouseDragged(MouseEvent e) {\r
539                 mouseMoved(e);\r
540         }\r
541 \r
542         @Override\r
543         public void mouseMoved(MouseEvent e) {\r
544                 _repeatEvent = e;\r
545                 if (_mouseDown) {\r
546                         updateValue(getValue(e.getX(), e.getY()));\r
547                 }\r
548         }\r
549 }\r