Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / raster / beans / canvas / layers / StraightLine.java @ 19354

History | View | Annotate | Download (9.64 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.BasicStroke;
22
import java.awt.Color;
23
import java.awt.Cursor;
24
import java.awt.Graphics;
25
import java.awt.Graphics2D;
26
import java.awt.Point;
27
import java.awt.Stroke;
28
import java.awt.event.MouseEvent;
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
                 * Informa de si el punto pasado por par?metro cae dentro del cuadro o no
121
                 * @param p Punto a comprobar
122
                 * @return true si el punto est? dentro y false si no lo est?
123
                 */
124
                public boolean isInside(Point p) {
125
                        if (p.getX() < (valueToPixelX(x) - (width >> 1)))
126
                                return false;
127
                        if (p.getX() > (valueToPixelX(x) + (width >> 1)))
128
                                return false;
129
                        if (p.getY() < (valueToPixelY(y) - (width >> 1)))
130
                                return false;
131
                        if (p.getY() > (valueToPixelY(y) + (width >> 1)))
132
                                return false;
133
                        return true;
134
                }
135
                
136
                /**
137
                 * Asigna el color del cuadrado
138
                 * @param c Color
139
                 */
140
                public void setColor(Color c) {
141
                        this.color = c;
142
                }
143
                
144
                private int valueToPixelX(double value) {
145
                        return (int) Math.round(canvas.getCanvasMinX() + border + ((canvas.getCanvasMaxX() - canvas.getCanvasMinX() - (border * 2)) * value));
146
                }
147

    
148
                private double pixelToValueX(int pixel) {
149
                        return ((double) (pixel - canvas.getCanvasMinX() - border) / (double) (canvas.getCanvasMaxX() - canvas.getCanvasMinX() - (border * 2)));
150
                }
151

    
152
                private int valueToPixelY(double value) {
153
                        value = 1.0D - value;
154
                        return (int) Math.round(canvas.getCanvasMinY() + border + ((canvas.getCanvasMaxY() - canvas.getCanvasMinY() - (border * 2)) * value));
155
                }
156

    
157
                private double pixelToValueY(int pixel) {
158
                        return (1.0D - ((double) (pixel - canvas.getCanvasMinY() - border) / (double) (canvas.getCanvasMaxY() - canvas.getCanvasMinY() - (border * 2))));
159
                }
160
        }
161
        
162
        /**
163
         * Lista de cuadrados que intersectan con la recta
164
         */
165
        private ArrayList listSquare       = new ArrayList();
166
        private int       pointDragged = -1;
167
        
168
        /**
169
         * Constructor. Asigna el color
170
         * @param c
171
         */
172
        public StraightLine(Color c) {
173
                setColor(c);
174
                listSquare.add(new Square(0.0D, 0.0D));
175
                listSquare.add(new Square(1.0D, 1.0D));
176
        }
177
        
178
        /*
179
         * (non-Javadoc)
180
         * @see org.gvsig.raster.beans.canvas.DrawableElement#firstDrawActions()
181
         */
182
        public void firstDrawActions() {
183
        }
184
        
185
        /**
186
         * Dibujado de las l?neas y cuadros sobre el canvas
187
         */
188
        public void paint(Graphics g) {
189
                g.setColor(color);
190

    
191
                // Dibujamos una l?nea desde un punto hasta el siguiente
192
                Square square = null;
193
                Square lastSquare = null;
194
                
195
                for (int i = 0; i < listSquare.size(); i++) {
196
                        lastSquare = square;
197
                        square = ((Square) listSquare.get(i));
198
                        square.setColor(color);
199
                        if ((pointDragged != i) && canvas.isMouse())
200
                                square.paint(g);
201

    
202
                        if (lastSquare != null)
203
                                g.drawLine(lastSquare.getPixelX(), lastSquare.getPixelY(), square.getPixelX(), square.getPixelY());
204
                }
205
        }
206

    
207
        /**
208
         * Asigna el objeto JComponent donde se pintan los elementos. Inicializa los puntos
209
         * de inicio y fin de l?nea y asigna los listener
210
         * @param canvas
211
         */
212
        public void setCanvas(GCanvas canvas) {
213
                super.setCanvas(canvas);
214
        }
215
        
216
        /**
217
         * Inserta un elemento (cuadrado) en el array entre los dos cuadrados entre los que se
218
         * encuentre el valor de su X, as? siempre est?n ordenados en el array por valor de X. 
219
         * @param element
220
         * @return Devuelve la posici?n del elemento insertado, en caso de no poder insertarse
221
         *         devolver? -1
222
         */
223
        private int insert(Square element) {
224
                for (int i = 0; i < (listSquare.size() - 1); i++) {
225
                        double sqX = ((Square) listSquare.get(i)).getX();
226
                        double sqNextX = ((Square) listSquare.get(i + 1)).getX();
227
                        if (element.getX() >= sqX && element.getX() <= sqNextX) {
228
                                listSquare.add(i + 1, element);
229
                                return i + 1;
230
                        }
231
                }
232
                return -1;
233
        }
234
        
235
        /**
236
         * Se captura el punto a arrastrar, en caso de que no coincida con un punto,
237
         * se inserta
238
         */
239
        public boolean mousePressed(MouseEvent e) {
240
                for (int i = 0; i < listSquare.size(); i++) {
241
                        if (((Square) listSquare.get(i)).isInside(e.getPoint())) {
242
                                if ((e.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0) {
243
                                        if ((i == 0) || ((i + 1) == listSquare.size()))
244
                                                continue;
245
                                        pointDragged = -1;
246
                                        listSquare.remove(i);
247
                                        canvas.repaint();
248
                                        return false;
249
                                }
250
                                if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
251
                                        pointDragged = i;
252
                                        this.mouseDragged(e);
253
                                        return false;
254
                                }
255
                        }
256
                }
257

    
258
                if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == 0)
259
                        return true;
260
                // En caso de que nadie lo este tratando, osea, un cursor normal
261
                if (canvas.getCursor().getType() == Cursor.DEFAULT_CURSOR) {
262
                        pointDragged = insert(new Square(e.getX(), e.getY()));
263
                        this.mouseDragged(e);
264
                        return false;
265
                }
266
                return true;
267
        }
268

    
269
        /**
270
         * Inicializamos el punto arrastrado a un valor fuera del array
271
         */
272
        public boolean mouseReleased(MouseEvent e) {
273
                pointDragged = -1;
274
                canvas.repaint();
275
                return true;
276
        }
277

    
278
        /**
279
         * Cuando se ha pinchado un punto y se arrastra se define aqu? su comportamiento.
280
         */
281
        public boolean mouseDragged(MouseEvent e) {
282
                if (pointDragged >= 0) {
283
                        canvas.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
284
                        int minX = canvas.getCanvasMinX();
285
                        int minY = canvas.getCanvasMinY();
286
                        int maxX = canvas.getCanvasMaxX();
287
                        int maxY = canvas.getCanvasMaxY();
288

    
289
                        // Controlamos que no se salga de los l?mites
290
                        int x = Math.min(Math.max(e.getX(), minX), maxX);
291
                        int y = Math.min(Math.max(e.getY(), minY), maxY);
292
                        Square point = ((Square) listSquare.get(pointDragged));
293

    
294
                        try {
295
                                // El primer punto no se desplaza en X
296
                                if (pointDragged == 0) {
297
                                        point.setPosition(minX, y);
298
                                        return false;
299
                                }
300
                                // El ?ltimo punto no se desplaza en X
301
                                if (pointDragged == (listSquare.size() - 1)) {
302
                                        point.setPosition(maxX, y);
303
                                        return false;
304
                                }
305

    
306
                                // Puntos centrales
307
                                point.setPosition(x, y);
308

    
309
                                // Arrastra a los de abajo si la X es menor que los inferiores
310
                                for (int i = 0; i < pointDragged; i++) {
311
                                        Square lowPoint = ((Square) listSquare.get(i));
312
                                        if (lowPoint.getPixelX() >= x) {
313
                                                lowPoint.setPosition(x, lowPoint.getPixelY());
314
                                                for (int j = i + 1; listSquare.get(j) != point;) {
315
                                                        listSquare.remove(j);
316
                                                        pointDragged--;
317
                                                }
318
                                                break;
319
                                        }
320
                                }
321

    
322
                                // Arrastra a los de arriba si la X es mayor que los superiores
323
                                for (int i = listSquare.size() - 1; i > pointDragged; i--) {
324
                                        Square upperPoint = ((Square) listSquare.get(i));
325
                                        if (upperPoint.getPixelX() <= x) {
326
                                                upperPoint.setPosition(x, upperPoint.getPixelY());
327
                                                for (int j = i - 1; listSquare.get(j) != point;) {
328
                                                        listSquare.remove(j);
329
                                                        j--;
330
                                                }
331
                                                break;
332
                                        }
333
                                }
334
                        } finally {
335
                                // Siempre repintamos
336
                                canvas.repaint();
337
                        }
338
                        return false;
339
                }
340
                return true;
341
        }
342

    
343
        /*
344
         * (non-Javadoc)
345
         * @see org.gvsig.raster.beans.canvas.DrawableElement#mouseMoved(java.awt.event.MouseEvent)
346
         */
347
        public boolean mouseMoved(MouseEvent e) {
348
                for (int i = 0; i < listSquare.size(); i++) {
349
                        if (((Square)listSquare.get(i)).isInside(e.getPoint())) {
350
                                canvas.setCursor(new Cursor(Cursor.MOVE_CURSOR));
351
                                return false;
352
                        }
353
                }
354
                return true;
355
        }
356
}