Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / beans / canvas / layers / StraightLine.java @ 19361

History | View | Annotate | Download (10.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.beans.canvas.layers;
20

    
21
import java.awt.Color;
22
import java.awt.Cursor;
23
import java.awt.Graphics;
24
import java.awt.Image;
25
import java.awt.Point;
26
import java.awt.Toolkit;
27
import java.awt.event.MouseEvent;
28
import java.awt.image.MemoryImageSource;
29
import java.util.ArrayList;
30

    
31
import org.gvsig.raster.beans.canvas.DrawableElement;
32
import org.gvsig.raster.beans.canvas.GCanvas;
33
/**
34
 * Representa una linea recta con puntos de arrastre para la ecualizaci?n de
35
 * un histograma y realce lineales y dencity slicing.
36
 *
37
 * 14-oct-2007
38
 * @author Nacho Brodin (nachobrodin@gmail.com)
39
 */
40
public class StraightLine extends DrawableElement {
41

    
42
        /**
43
         * Representa un punto seleccionado sobre el canvas. Este es
44
         * dibujado como un peque?o cuadrado.
45
         *
46
         * 14-oct-2007
47
         * @author Nacho Brodin (nachobrodin@gmail.com)
48
         */
49
        class Square {
50
                private double x      = 0.0D;
51
                private double y      = 0.0D;
52
                private int    width  = 6;
53
                private Color  color  = Color.WHITE;
54
                private int    border = 2;
55

    
56
                /**
57
                 * Constructor. Calcula las esquinas del cuadrado
58
                 * @param p
59
                 */
60
                public Square(double x, double y) {
61
                        setPosition(x, y);
62
                }
63

    
64
                /**
65
                 * Constructor. Calcula las esquinas del cuadrado
66
                 * @param p
67
                 */
68
                public Square(int x, int y) {
69
                        setPosition(x, y);
70
                }
71
                
72
                /**
73
                 * Asigna una nueva posici?n al punto
74
                 * @param x
75
                 */
76
                public void setPosition(double x, double y) {
77
                        this.x = x;
78
                        this.y = y;
79

    
80
                        if (this.x > 1.0D) this.x = 1.0D;
81
                        if (this.x < 0.0D) this.x = 0.0D;
82
                        if (this.y > 1.0D) this.y = 1.0D;
83
                        if (this.y < 0.0D) this.y = 0.0D;
84
                }
85
                
86
                /**
87
                 * Asigna una nueva posici?n al punto
88
                 * @param x
89
                 */
90
                public void setPosition(int x, int y) {
91
                        setPosition(pixelToValueX(x), pixelToValueY(y));
92
                }
93
                
94
                public int getPixelX() {
95
                        return valueToPixelX(x);
96
                }
97

    
98
                public int getPixelY() {
99
                        return valueToPixelY(y);
100
                }
101
                
102
                public double getX() {
103
                        return x;
104
                }
105
                
106
                public double getY() {
107
                        return y;
108
                }
109
                
110
                /**
111
                 * Dibuja el cuadrado
112
                 * @param g
113
                 */
114
                protected void paint(Graphics g) {
115
                        g.setColor(color);
116
                        g.drawRect((int) valueToPixelX(x) - (width >> 1), (int) valueToPixelY(y) - (width >> 1), (int) width, (int)width);
117
                }
118

    
119
                /**
120
                 * Dibuja el cursor del raton
121
                 * @param g
122
                 */
123
                protected void paintCursor(Graphics g) {
124
                        g.setColor(Color.white);
125
                        g.drawLine(valueToPixelX(x) - 6, valueToPixelY(y), valueToPixelX(x) + 6, valueToPixelY(y));
126
                        g.drawLine(valueToPixelX(x), valueToPixelY(y) - 6, valueToPixelX(x), valueToPixelY(y) + 6);
127
                }
128
                
129
                /**
130
                 * Informa de si el punto pasado por par?metro cae dentro del cuadro o no
131
                 * @param p Punto a comprobar
132
                 * @return true si el punto est? dentro y false si no lo est?
133
                 */
134
                public boolean isInside(Point p) {
135
                        if (p.getX() < (valueToPixelX(x) - (width >> 1)))
136
                                return false;
137
                        if (p.getX() > (valueToPixelX(x) + (width >> 1)))
138
                                return false;
139
                        if (p.getY() < (valueToPixelY(y) - (width >> 1)))
140
                                return false;
141
                        if (p.getY() > (valueToPixelY(y) + (width >> 1)))
142
                                return false;
143
                        return true;
144
                }
145
                
146
                /**
147
                 * Asigna el color del cuadrado
148
                 * @param c Color
149
                 */
150
                public void setColor(Color c) {
151
                        this.color = c;
152
                }
153
                
154
                private int valueToPixelX(double value) {
155
                        return (int) Math.round(canvas.getCanvasMinX() + border + ((canvas.getCanvasMaxX() - canvas.getCanvasMinX() - (border * 2)) * value));
156
                }
157

    
158
                private double pixelToValueX(int pixel) {
159
                        return ((double) (pixel - canvas.getCanvasMinX() - border) / (double) (canvas.getCanvasMaxX() - canvas.getCanvasMinX() - (border * 2)));
160
                }
161

    
162
                private int valueToPixelY(double value) {
163
                        value = 1.0D - value;
164
                        return (int) Math.round(canvas.getCanvasMinY() + border + ((canvas.getCanvasMaxY() - canvas.getCanvasMinY() - (border * 2)) * value));
165
                }
166

    
167
                private double pixelToValueY(int pixel) {
168
                        return (1.0D - ((double) (pixel - canvas.getCanvasMinY() - border) / (double) (canvas.getCanvasMaxY() - canvas.getCanvasMinY() - (border * 2))));
169
                }
170
        }
171
        
172
        /**
173
         * Lista de cuadrados que intersectan con la recta
174
         */
175
        private ArrayList listSquare        = new ArrayList();
176
        private int       pointDragged      = -1;
177
        Cursor            transparentCursor = null;
178
        
179
        /**
180
         * Constructor. Asigna el color
181
         * @param c
182
         */
183
        public StraightLine(Color c) {
184
                int[] pixels = new int[16 * 16];
185
                Image image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(16, 16, pixels, 0, 16));
186
                transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(0, 0), "invisibleCursor");
187
                
188
                setColor(c);
189
                listSquare.add(new Square(0.0D, 0.0D));
190
                listSquare.add(new Square(1.0D, 1.0D));
191
        }
192
        
193
        /*
194
         * (non-Javadoc)
195
         * @see org.gvsig.raster.beans.canvas.DrawableElement#firstDrawActions()
196
         */
197
        public void firstDrawActions() {
198
        }
199
        
200
        /**
201
         * Dibujado de las l?neas y cuadros sobre el canvas
202
         */
203
        public void paint(Graphics g) {
204
                g.setColor(color);
205

    
206
                // Dibujamos una l?nea desde un punto hasta el siguiente
207
                Square square = null;
208
                Square lastSquare = null;
209
                for (int i = 0; i < listSquare.size(); i++) {
210
                        lastSquare = square;
211
                        square = ((Square) listSquare.get(i));
212
                        if (lastSquare != null)
213
                                g.drawLine(lastSquare.getPixelX(), lastSquare.getPixelY(), square.getPixelX(), square.getPixelY());
214
                }
215

    
216
                // Dibujamos los cuadrados de los puntos
217
                for (int i = 0; i < listSquare.size(); i++) {
218
                        square = ((Square) listSquare.get(i));
219
                        square.setColor(color);
220
                        if (pointDragged != i)
221
                                square.paint(g);
222
                        else
223
                                square.paintCursor(g);
224
                }
225
        }
226

    
227
        /**
228
         * Asigna el objeto JComponent donde se pintan los elementos. Inicializa los puntos
229
         * de inicio y fin de l?nea y asigna los listener
230
         * @param canvas
231
         */
232
        public void setCanvas(GCanvas canvas) {
233
                super.setCanvas(canvas);
234
        }
235
        
236
        /**
237
         * Inserta un elemento (cuadrado) en el array entre los dos cuadrados entre los que se
238
         * encuentre el valor de su X, as? siempre est?n ordenados en el array por valor de X. 
239
         * @param element
240
         * @return Devuelve la posici?n del elemento insertado, en caso de no poder insertarse
241
         *         devolver? -1
242
         */
243
        private int insert(Square element) {
244
                for (int i = 0; i < (listSquare.size() - 1); i++) {
245
                        double sqX = ((Square) listSquare.get(i)).getX();
246
                        double sqNextX = ((Square) listSquare.get(i + 1)).getX();
247
                        if (element.getX() >= sqX && element.getX() <= sqNextX) {
248
                                listSquare.add(i + 1, element);
249
                                return i + 1;
250
                        }
251
                }
252
                return -1;
253
        }
254
        
255
        /**
256
         * Se captura el punto a arrastrar, en caso de que no coincida con un punto,
257
         * se inserta
258
         */
259
        public boolean mousePressed(MouseEvent e) {
260
                for (int i = 0; i < listSquare.size(); i++) {
261
                        if (((Square) listSquare.get(i)).isInside(e.getPoint())) {
262
                                if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0) {
263
                                        if ((i == 0) || ((i + 1) == listSquare.size()))
264
                                                continue;
265
                                        pointDragged = -1;
266
                                        listSquare.remove(i);
267
                                        canvas.repaint();
268
                                        return false;
269
                                }
270
                                if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
271
                                        pointDragged = i;
272
                                        this.mouseDragged(e);
273
                                        return false;
274
                                }
275
                        }
276
                }
277

    
278
                if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
279
                        return true;
280
                // En caso de que nadie lo este tratando, osea, un cursor normal
281
                if (canvas.getCursor().getType() == Cursor.DEFAULT_CURSOR) {
282
                        pointDragged = insert(new Square(e.getX(), e.getY()));
283
                        this.mouseDragged(e);
284
                        return false;
285
                }
286
                return true;
287
        }
288

    
289
        /**
290
         * Inicializamos el punto arrastrado a un valor fuera del array
291
         */
292
        public boolean mouseReleased(MouseEvent e) {
293
                pointDragged = -1;
294
                canvas.repaint();
295
                canvas.callDataChanged("line", this);
296
                return true;
297
        }
298

    
299
        /**
300
         * Cuando se ha pinchado un punto y se arrastra se define aqu? su comportamiento.
301
         */
302
        public boolean mouseDragged(MouseEvent e) {
303
                if (pointDragged >= 0) {
304
                        canvas.setCursor(transparentCursor);
305
                        int minX = canvas.getCanvasMinX();
306
                        int minY = canvas.getCanvasMinY();
307
                        int maxX = canvas.getCanvasMaxX();
308
                        int maxY = canvas.getCanvasMaxY();
309

    
310
                        // Controlamos que no se salga de los l?mites
311
                        int x = Math.min(Math.max(e.getX(), minX), maxX);
312
                        int y = Math.min(Math.max(e.getY(), minY), maxY);
313
                        Square point = ((Square) listSquare.get(pointDragged));
314

    
315
                        try {
316
                                // El primer punto no se desplaza en X
317
                                if (pointDragged == 0) {
318
                                        point.setPosition(minX, y);
319
                                        return false;
320
                                }
321
                                // El ?ltimo punto no se desplaza en X
322
                                if (pointDragged == (listSquare.size() - 1)) {
323
                                        point.setPosition(maxX, y);
324
                                        return false;
325
                                }
326

    
327
                                // Puntos centrales
328
                                point.setPosition(x, y);
329

    
330
                                // Arrastra a los de abajo si la X es menor que los inferiores
331
                                for (int i = 0; i < pointDragged; i++) {
332
                                        Square lowPoint = ((Square) listSquare.get(i));
333
                                        if (lowPoint.getPixelX() >= x) {
334
                                                lowPoint.setPosition(x, lowPoint.getPixelY());
335
                                                for (int j = i + 1; listSquare.get(j) != point;) {
336
                                                        listSquare.remove(j);
337
                                                        pointDragged--;
338
                                                }
339
                                                break;
340
                                        }
341
                                }
342

    
343
                                // Arrastra a los de arriba si la X es mayor que los superiores
344
                                for (int i = listSquare.size() - 1; i > pointDragged; i--) {
345
                                        Square upperPoint = ((Square) listSquare.get(i));
346
                                        if (upperPoint.getPixelX() <= x) {
347
                                                upperPoint.setPosition(x, upperPoint.getPixelY());
348
                                                for (int j = i - 1; listSquare.get(j) != point;) {
349
                                                        listSquare.remove(j);
350
                                                        j--;
351
                                                }
352
                                                break;
353
                                        }
354
                                }
355
                        } finally {
356
                                // Siempre repintamos
357
                                canvas.repaint();
358
                                canvas.callDataDragged("line", this);
359
                        }
360
                        return false;
361
                }
362
                return true;
363
        }
364

    
365
        /*
366
         * (non-Javadoc)
367
         * @see org.gvsig.raster.beans.canvas.DrawableElement#mouseMoved(java.awt.event.MouseEvent)
368
         */
369
        public boolean mouseMoved(MouseEvent e) {
370
                for (int i = 0; i < listSquare.size(); i++) {
371
                        if (((Square)listSquare.get(i)).isInside(e.getPoint())) {
372
                                canvas.setCursor(new Cursor(Cursor.MOVE_CURSOR));
373
                                return false;
374
                        }
375
                }
376
                return true;
377
        }
378
}