1
6 import java.awt.event.*;
7 import java.awt.*;
8 import javax.swing.*;
9 import java.awt.geom.*;
10
11
15 public class Anchor extends PointSym implements DragableSymbol {
16
17 private static final long serialVersionUID = Version.getSUID();
18
19
20
22
23 static int SMOOTH = -2;
24
25
27 static int ALL = -1;
28
29
30 static int GUIDE0 = 0;
31
32
33 static int GUIDE1 = 1;
34
35
36 static int GLOBAL = 0;
37
38
39 static int LOCAL = 1;
40
41
42 static int CONSISTANT = 2;
43
44
46 transient public Point2D[] guide = new Point2D[2];
47
48
51 transient public Point2D[] guidelocal = new Point2D[2];
52
53
57 transient int guidestate = LOCAL;
58
59
60
61 boolean kink=false;
62
63
65 public Arrow arrow = null;
66
67
69 public boolean arrowreverse = false;
70
71
74 int selmode;
75
76
78 private void readObject(java.io.ObjectInputStream stream)
79 throws java.io.IOException,java.lang.ClassNotFoundException {
80 stream.defaultReadObject();
81 guide = new Point2D[2];
82 guidelocal = new Point2D[2];
83 guidelocal[0] = new Point2D.Double();
84 guidelocal[1] = new Point2D.Double();
85 guide[0] = new Point2D.Double(stream.readDouble(),stream.readDouble());
86 guide[1] = new Point2D.Double(stream.readDouble(),stream.readDouble());
87 guidestate = GLOBAL;
88 }
89
90
91 private void writeObject(java.io.ObjectOutputStream stream)
92 throws java.io.IOException {
93 stream.defaultWriteObject();
94 guideUpdate();
95 stream.writeDouble(guide[0].getX());
96 stream.writeDouble(guide[0].getY());
97 stream.writeDouble(guide[1].getX());
98 stream.writeDouble(guide[1].getY());
99 }
100
101
104 public void alignmentChanged() {
105 guidestate = LOCAL;
106 }
107
108 Point2D.Double morphpos0 = null;
109 Point2D.Double morphpos1 = null;
110
111 public void prepareForSurveyUpdate(java.util.List segments) {
112
113
114 guideUpdate();
115 super.prepareForSurveyUpdate(segments);
116 if (morphsegment!=null) {
117 morphpos0 = new Point2D.Double();
118 morphsegment.map.btrans(guide[0],morphpos0);
119 morphpos1 = new Point2D.Double();
120 morphsegment.map.btrans(guide[1],morphpos1);
121 }
122 }
123
124
127 public void useSurveyUpdate() {
128
129
130
131 if (morphsegment!=null) {
132 Point2D.Double res = new Point2D.Double();
133 morphsegment.map.ftrans(morphpos0,res);
134 guide[0]=res;
135 morphpos0 = null;
136 res = new Point2D.Double();
137 morphsegment.map.ftrans(morphpos1,res);
138 guide[1] = res;
139 morphpos1 = null;
140 }
141
142 super.useSurveyUpdate();
143 guidestate = GLOBAL;
144
145
146
147
153 }
154
155
157 public void guideUpdate() {
158 if (guidestate==GLOBAL) {
159 try {
160 position.inverseTransform(guide[0],guidelocal[0]);
161 position.inverseTransform(guide[1],guidelocal[1]);
162 } catch (NoninvertibleTransformException ex) {
163 ErrorLog.log("Internal error in guideUpdate");
164 ErrorLog.exception(ex);
165 return;
166 }
167 }
168 else if (guidestate==LOCAL) {
169 position.transform(guidelocal[0],guide[0]);
170 position.transform(guidelocal[1],guide[1]);
171 }
172 guidestate=CONSISTANT;
173 }
174
175
178 public Anchor(Point2D where,View view,Object arg) {
179 super(where,view,arg);
180 guidelocal[0]= new Point2D.Double(0,0);
181 guidelocal[1]= new Point2D.Double(0,0);
182 guide[0]= (Point2D)position.getTranslation();
183 guide[1]= (Point2D)position.getTranslation();
184
185
186 guidestate = GLOBAL;
187 selmode = SMOOTH;
188 }
189
200
201 public int getLevel() {return(super.getLevel()+1);}
202
203 public void getPropertyEdit(Object[] edits,int slot,java.util.Set sub, Symbol parent) {
204 edits[slot] = anchorPropertyEdit();
205
206 super.getPropertyEdit(edits,slot-1,sub,parent);
207 }
208
209 transient JComboBox arrowfield;
210 transient JCheckBox reversebox;
211
212 java.awt.Container anchorPropertyEdit() {
213 JPanel res = new JPanel();
214 res.setName("Arrow");
215 res.setLayout(new BoxLayout(res,BoxLayout.Y_AXIS));
216
217 arrowfield = new JComboBox(Arrow.getAll(Arrow.class));
218 arrowfield.setSelectedItem(arrow);
219 res.add(arrowfield);
220 reversebox = new JCheckBox("Reverse",arrowreverse);
221 res.add(reversebox);
222
223 return(res);
224 }
225
226 public void acceptPropertyEdit() {
227 if (arrowfield!=null) {
228
229 arrow = (Arrow)arrowfield.getSelectedItem();
230 if (arrow==Arrow.none) arrow = null;
231 arrowreverse = reversebox.isSelected();
232
233 arrowfield = null;
234 reversebox = null;
235 }
236 super.acceptPropertyEdit();
237 }
238
239 public void abandonPropertyEdit() {
240 arrowfield = null;
241 reversebox = null;
242 super.abandonPropertyEdit();
243 }
244
245
248 public boolean selectProbe(Point2D where,View view){
249 double BOXSIZE = Size.handle.getSize(view.mapscale);
250 if (position.distance(where)<BOXSIZE/view.scale) {
251 selmode = ALL;
252 return(true);
253 }
254 guideUpdate();
255 if (guide[0].distance(where)<BOXSIZE/view.scale) {
256 selmode=GUIDE0;
257 return(true);
258 }
259 if (guide[1].distance(where)<BOXSIZE/view.scale) {
260 selmode=GUIDE1;
261 return(true);
262 }
263 return(false);
264 }
265
266
267 public void startDrag(int command,Point2D where,View view) {
268 if ((command&CompPane.SMOOTH)!=0) {
269 if (selmode== ALL && kink) {
270 selmode = SMOOTH;
271 kink = false;
272 }
273 else if (selmode>=0) kink = true;
274 }
275 dragpoint = where;
276 }
277
278
280 public void drag(int command,Point2D where,View view) {
281 showSelected(view);
282 if (selmode==SMOOTH) {
283 guide[1].setLocation(where.getX()-dragpoint.getX()+guide[1].getX(),
284 where.getY()-dragpoint.getY()+guide[1].getY());
285 guide[0].setLocation(2*position.getTranslateX()-guide[1].getX(),
286 2*position.getTranslateY()-guide[1].getY());
287 guidestate = GLOBAL;
288 }
289 else if (selmode==ALL) {
290 guidestate = LOCAL;
291 position.setLocation(position.getTranslateX()+(where.getX()-dragpoint.getX())/position.scale,
292 position.getTranslateY()+(where.getY()-dragpoint.getY())/position.scale);
293 }
294 else if (selmode>=GUIDE0) {
295 Point2D drager = guide[selmode-GUIDE0];
296 Point2D dragee = guide[1-(selmode-GUIDE0)];
297 double length1 = position.distance(dragee);
298 drager.setLocation(drager.getX()+where.getX()-dragpoint.getX(),
299 drager.getY()+where.getY()-dragpoint.getY());
300 double length0 = position.distance(drager);
301 if (!kink)
302 dragee.setLocation(position.getTranslateX()+length1*(position.getTranslateX()-drager.getX())/length0,
303 position.getTranslateY()+length1*(position.getTranslateY()-drager.getY())/length0);
304 guidestate = GLOBAL;
305 }
306 dragpoint = where;
307 showSelected(view);
308 }
309
310
314 public void endDrag(int comand,Point2D pos,View view){
315 position.notifyChange();
316 }
317
318
319
324 public void showSelected(View view) {
325 guideUpdate();
326
327 Point2D tpos = new Point2D.Double();
328 Point2D tguide = new Point2D.Double();
329
330 int BOXSIZE = (int)Size.handle.getSize(view.mapscale);
331
332 position.transformOrigin(view.trans,tpos);
333
334 view.draw.fillRect((int)tpos.getX()-BOXSIZE,(int)tpos.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
335
336 for (int i=0;i<2;i++) {
337 view.trans.transform(guide[i],tguide);
338
339 view.draw.drawLine((int)tpos.getX(),(int)tpos.getY(),(int)tguide.getX(),(int)tguide.getY());
340
341 if (selmode==i)
342 view.draw.fillOval((int)tguide.getX()-BOXSIZE,(int)tguide.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
343 else
344 view.draw.drawOval((int)tguide.getX()-BOXSIZE,(int)tguide.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
345 }
346 }
347
348
351 public void paint(View view) {
352 guideUpdate();
353 if (!view.visible.isMember(this)) return;
354 int BOXSIZE = (int)Size.handle.getSize(view.mapscale);
355 Point2D tpos = new Point2D.Double();
356 position.transformOrigin(view.trans,tpos);
357
358 view.draw.drawRect((int)tpos.getX()-BOXSIZE,(int)tpos.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
359 view.trans.transform(guide[0],tpos);
360 view.draw.drawOval((int)tpos.getX()-BOXSIZE,(int)tpos.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
361 view.trans.transform(guide[1],tpos);
362 view.draw.drawOval((int)tpos.getX()-BOXSIZE,(int)tpos.getY()-BOXSIZE,2*BOXSIZE,2*BOXSIZE);
363 }
364 }
365
366
367