1
6 import javax.swing.*;
7 import java.awt.*;
8 import java.awt.geom.*;
9 import java.util.*;
10 import java.awt.event.*;
11
12 public class CompPane extends JComponent implements Scaleable,MouseListener,MouseMotionListener{
13
14 public static int NEW = 1;
15 public static int SELECT = 2;
16 public static int SUBSELECT = 3;
17 public static int DELETE = 4;
18 public static int ADD = 5;
19 public static int HAND = 6;
20 public static int ZOOM = 7;
21
22 public static int MODES = 7;
23 public static int SMOOTH = 8;
24 public static int FLIP = 9;
25
26 public static int COPY = 10;
27 public static int PASTE = 11;
28
29 public static double margin = 0.2;
30
31 public static double screenscale = 0.0025;
32
33 public Comp contents;
34
35 public Selection sel = null;
36 public int selindex = 0;
37
38 Point2D dragpos = new Point2D.Double();
39 Set dragset = null;
40 int dragx = 0;
41 int dragy = 0;
42 int dragrx = 0;
43 int dragry = 0;
44 int dragwidth = 0;
45 int dragheight = 0;
46 boolean dragged;
47
48 int mode = 0;
49 int command = 0;
50
51 Class newtype = null;
52 Object newarg = null;
53
54
55
56
57 JScrollPane scrollpane;
58
59 View view = null;
60 ViewTransform viewtrans = new ViewTransform(ViewTransform.ABSOLUTE);
61
62 CompEditor editor;
63
64 Fill defaultfill = null;
65 Color defaultcolor = null;
66 LineType defaultlinetype = null;
67 Size defaultlinesize = null;
68 Color defaultlinecolor = null;
69
70 static Color[] selcolors = {Color.black,Color.red,Color.green,Color.blue};
71 static Color[] invcolors = {Color.white,Color.cyan,Color.magenta,Color.yellow};
72
73 public CompPane(CompEditor editor) {
74 this.editor = editor;
75
76
77 setSelection(0);
78
79 setOpaque(true);
80 setBackground(Color.white);
81 view = new View(this);
82
83 view.push(viewtrans);
84 view.observer = this;
85 addMouseListener(this);
86 addMouseMotionListener(this);
87 scrollpane = new JScrollPane(this,
88 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
89 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
90 defaultlinetype = LineType.lookup("Generic");
91 defaultlinesize = (Size)FileDefaultable.lookup(Size.class,Size.PIXEL);
92
93 defaultlinecolor = Color.black;
94 editor.frame.lastselected = editor;
95 }
96
97 public Selection setSelection(int index) {
98 selindex = index;
99 sel = editor.frame.carto.selections[index];
100 return(sel);
101 }
102
103 public void cleanup() {
104 contents = null;
105 dragpos=null;
106 dragset=null;
107 newtype=null;
108 newarg=null;
109 scrollpane=null;
110 view=null;
111 viewtrans=null;
112 editor=null;
113 defaultfill=null;
114 defaultcolor=null;
115 defaultlinetype=null;
116 defaultlinesize=null;
117 defaultlinecolor=null;
118 }
119
120 public void setLineType(LineType type,Size size,Color color) {
121 if (sel.setLineType(type,size,color))
122 repaint();
123
124 defaultlinetype = type;
125 defaultlinesize = size;
126 defaultlinecolor = color;
127 }
128
129 public void setFill(Fill newfill) {
130 if (sel.setFill(newfill))
131 repaint();
132
133 else defaultfill = newfill;
134 }
135
136 public void setFill(Color newfill) {
137 if (sel.setFill(newfill))
138 repaint();
139
140 else defaultcolor = newfill;
141 }
142
143 public JScrollPane getScrollPane() {
144 return(scrollpane);
145 }
146
147 Dimension size = new Dimension(500,500);
148
149 public Dimension getPreferredSize(){
150 return(size);
151 }
152
153 public Point2D getCenter() {
154 Rectangle viewrect = scrollpane.getViewport().getViewRect();
155 Point2D res = new Point2D.Double();
156 try {
157 viewtrans.inverseTransform(new Point2D.Double(viewrect.getX()+viewrect.getWidth()/2.0,
158 viewrect.getY()+viewrect.getHeight()/2.0),res);
159 } catch (java.awt.geom.NoninvertibleTransformException ex) {
160 ErrorLog.exception(ex);
161 }
162 return(res);
163 }
164
165 public void setScale(double newscale) {
166 Point2D center = getCenter();
167 viewtrans.setScale(newscale,center.getX(),center.getY());
168 adjustSize();
169 repaint();
170 }
171
172 public void setRotation(double newangle) {
173 Point2D center = getCenter();
174 viewtrans.setRotation(newangle,center.getX(),center.getY());
175 adjustSize();
176 repaint();
177 }
178
179 public void adjustSize(){
180
181 Rectangle2D bounds = contents.getBounds(viewtrans);
182 addMargin(bounds);
183 Rectangle viewrect = scrollpane.getViewport().getViewRect();
184
185 double xtrans = -bounds.getX();
186 double ytrans = -bounds.getY();
187
188 if (bounds.getWidth()<viewrect.getWidth()) {
189 size.width = (int)viewrect.getWidth();
190 xtrans += (viewrect.getWidth() - bounds.getWidth())/2.0;
191 }
192 else {
193 size.width = (int)bounds.getWidth();
194 viewrect.x -= (int)bounds.getX();
195 }
196
197 if (bounds.getHeight()<viewrect.getHeight()) {
198 size.height = (int)viewrect.getHeight();
199 ytrans += (viewrect.getHeight() - bounds.getHeight())/2.0;
200 }
201 else {
202 size.height = (int)bounds.getHeight();
203 viewrect.y -= (int)bounds.getY();
204 }
205
206 setSize(size);
207 viewtrans.preConcatenate(AffineTransform.getTranslateInstance(xtrans,ytrans));
208 view.pop();
209 view.push(viewtrans);
210 scrollpane.getViewport().setViewPosition(new Point(viewrect.x,viewrect.y));
211 }
212
213 public double center() {
214 Rectangle2D bounds;
215 if (contents.members.isEmpty()) bounds = new Rectangle2D.Double(0.0,0.0,
216 size.width,size.height);
217 else {
218 bounds = contents.getBounds(view.trans);
219 addMargin(bounds);
220 }
221 double scale;
222 if (size.width/bounds.getWidth()<size.height/bounds.getHeight())
223 scale=size.width/bounds.getWidth();
224 else
225 scale=size.height/bounds.getHeight();
226 viewtrans.setScale(scale,0.0,0.0);
227 bounds = contents.getBounds(viewtrans);
228 addMargin(bounds);
229 viewtrans.preConcatenate(AffineTransform.getTranslateInstance(
230 (size.width - bounds.getWidth() )/2.0-bounds.getX(),
231 (size.height- bounds.getHeight())/2.0-bounds.getY()));
232 view.pop();
233 view.push(viewtrans);
234 return(scale);
235 }
236
237 public void paintComponent(Graphics g) {
238 g.setColor(getBackground());
239 Rectangle clip = g.getClipBounds();
240 g.fillRect(clip.x,clip.y,clip.width,clip.height);
241
242 g.setColor(getForeground());
243 if (contents==null) {
244 Dimension dims = getSize();
245 g.drawLine(0,0,dims.width,dims.height);
246 } else {
247 view.draw = (Graphics2D)g;
248 view.mapscale = new MapScale(view.scale,Unit.pixel,(contents.survey?editor.frame.carto.mapunit:Unit.pixel));
249
250 view.mapscale.metersperpixel = screenscale;
251
252 view.showall = contents.showall;
253 if (contents.showall) view.visible = Layer.all;
254 else view.visible = contents.visible;
255
256 view.draw.setColor(Color.black);
257 view.stacking = contents.stack;
258
259
260 contents.paint(view);
261 contents.getSurvey().paint(view);
262
263 for (int i=0;i<4;i++) {
264 if (i!=selindex) {
265 view.draw.setColor(selcolors[i]);
266 editor.frame.carto.selections[i].show(view);
267 }
268 }
269
270 view.draw.setColor(selcolors[selindex]);
271 sel.show(view);
272
287 }
288 }
289
290 public void addMargin(Rectangle2D dim) {
291
292 dim.setRect(dim.getX()-dim.getWidth()*margin/2,
293 dim.getY()-dim.getHeight()*margin/2,
294 dim.getWidth()*(1+margin),
295 dim.getHeight()*(1+margin));
296 }
297
298 public void setMode(int mode) {
299 this.mode = mode;
300 }
301
302 Point2D getPos(MouseEvent e) {
303 Point2D pos = new Point2D.Double();
304 try {
305 viewtrans.inverseTransform(e.getPoint(),pos);
306 } catch (java.awt.geom.NoninvertibleTransformException ex) {
307 ErrorLog.exception(ex);
308 }
309 return(pos);
310 }
311
312 public void mouseClicked(MouseEvent e) {
313 }
314
315 public void mouseEntered(MouseEvent e) {
316 }
317
318 public void mouseExited(MouseEvent e) {
319 }
320
321 public void mousePressed(MouseEvent e) {
322 editor.frame.lastselected = editor;
323
324 editor.frame.dirty = true;
325
326 Point2D pos = getPos(e);
327 boolean shift = e.isShiftDown();
328 Symbol newselection = null;
329 boolean selecthit = false;
330
331 if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) {
332 sel.editProperties(contents,shift,pos,view,(mode&MODES)==SUBSELECT);
333 repaint();
334 return;
335 }
336
337 if ((mode&MODES)!=HAND) {
338 view.draw = (Graphics2D)getGraphics();
339 view.draw = (Graphics2D)view.draw.create();
340 view.draw.setXORMode(invcolors[selindex]);
341 }
342
343 if ((mode&MODES)==SELECT || (mode&MODES)==SUBSELECT)
344 selecthit = sel.select(contents,shift,pos,view,(mode&MODES)==SUBSELECT);
345
346 if ((mode&MODES)==NEW && newtype!=null) {
347 newselection = Symbol.getNew(newtype,pos,view,newarg);
348 if (newselection instanceof Curve) {
349 ((Curve)newselection).setFill(defaultcolor);
350 ((Curve)newselection).setLineType(defaultlinetype,defaultlinesize,defaultlinecolor,null);
351 }
352
353 contents.add(newselection,view);
354 sel.clearSelection();
355 sel.selection.add(newselection);
356 selecthit = true;
357 if (newselection instanceof Addable) {
358 mode=ADD;
359 editor.setMode(ADD);
360 }
361
362 }
363
364 if ((mode&MODES)==ADD) {
365
366 Addable addtarget = sel.getAddable();
367 if (addtarget!=null) {
368 selecthit = true;
369 newselection = Symbol.getNew(addtarget.addType(),pos,view,addtarget);
370 addtarget.add(newselection,sel.subselection,view);
371 sel.clearSubSelection();
372 sel.subselection.add(newselection);
373 }
374 }
375
376 dragrx = dragx = e.getX();
377 dragry = dragy = e.getY();
378 dragwidth = 0;
379 dragheight = 0;
380 dragged = false;
381 dragpos = pos;
382 if (selecthit)
383 sel.startDrag((mode&MODES)==SELECT);
384 else
385 sel.dragset = null;
386 }
387
388 public void mouseReleased(MouseEvent e) {
389 if (dragged && (mode&MODES)==ZOOM) {
390 Rectangle oldrect = scrollpane.getViewport().getViewRect();
391 scrollpane.getViewport().
392 setViewPosition(new Point((int)(dragrx+dragwidth/2-oldrect.getWidth()/2),
393 (int)(dragry+dragheight/2-oldrect.getHeight()/2)));
394
395
396
397
398
399 editor.scale.setValue(viewtrans.scale*oldrect.getWidth()/dragwidth);
400 editor.scale.repaint();
401 setScale(viewtrans.scale*oldrect.getWidth()/dragwidth);
402 return;
403 }
404 repaint();
405 if (!dragged) return;
406
407 if (!sel.endDrag(getPos(e),mode,view))
408 sel.selectRect(new Rectangle2D.Double(dragrx,dragry,dragwidth,dragheight),
409 contents,view,e.isShiftDown());
410 }
411
412 public void mouseDragged(MouseEvent e) {
413 if ((mode&MODES)==HAND) {
414 Point oldpos = scrollpane.getViewport().getViewPosition();
415 scrollpane.getViewport().setViewPosition(new Point((int)(oldpos.getX()-e.getX()+dragx),
416 (int)(oldpos.getY()-e.getY()+dragy)));
417 }
418 else if (!sel.drag(getPos(e),dragged,mode,dragpos,view)) {
419 if (dragged)
420 view.draw.drawRect(dragrx,dragry,dragwidth,dragheight);
421 if (e.getX()<dragx) {
422 dragrx = e.getX();
423 dragwidth = dragx - e.getX();
424 } else {
425 dragrx = dragx;
426 dragwidth = e.getX() - dragx;
427 }
428 if (e.getY()<dragy) {
429 dragry = e.getY();
430 dragheight = dragy - e.getY();
431 } else {
432 dragry = dragy;
433 dragheight = e.getY() - dragy;
434 }
435 view.draw.drawRect(dragrx,dragry,dragwidth,dragheight);
436 }
437 dragged = true;
438 }
439
440 public void mouseMoved(MouseEvent e) {
441 }
442 }
443