View Javadoc

1   package org.catacomb.graph.gui;
2   
3   import org.catacomb.be.Position;
4   import org.catacomb.datalish.Box;
5   import org.catacomb.interlish.interact.ClickListener;
6   import org.catacomb.interlish.structure.ModeSettable;
7   import org.catacomb.report.E;
8   
9   
10  import java.awt.Graphics;
11  import java.awt.Graphics2D;
12  import java.awt.RenderingHints;
13  
14  import java.awt.Color;
15  
16  public class WorldCanvas extends BaseCanvas implements ModeSettable {
17  
18      static final long serialVersionUID = 1001;
19  
20  
21      public static final String PAN = "pan";
22      public static final String ZOOM = "zoom";
23      public static final String BOX = "box";
24      public static final String ROLL = "roll";
25      public static final String TURN = "turn";
26      public static final String MULTI = "all";
27  
28      public static final String ZOOMIN = "zoomIn";
29      public static final String ZOOMOUT = "zoomOut";
30  
31  
32      protected WorldTransform wt;
33      protected Painter painter;
34      protected PaintInstructor paintInstructor;
35      protected Mouse mouse;
36  
37  
38      private BoxSelectionHandler boxSelectionHandler;
39      private PanHandler panHandler;
40      private TurnZoomHandler turnZoomHandler;
41      private ClickZoomHandler clickZoomHandler;
42      private RollHandler rollHandler;
43      private TurntableHandler turntableHandler;
44  
45      private MouseHandler[] handlers;
46  
47      private boolean antialias = false;
48      private boolean tooltips = false;
49  
50      Box reframeBox;
51  
52      private boolean userAntialias;
53  
54  
55      public WorldCanvas(int w, int h) {
56          this(w, h, true);
57      }
58  
59  
60      public WorldCanvas(int w, int h, boolean interactive) {
61          super(w, h);
62  
63  
64          mouse = new Mouse(this, interactive);
65  
66  
67          wt = new WorldTransform();
68          wt.setWidth(w);
69          wt.setHeight(h);
70  
71          painter = new Painter(wt);
72  
73          addWorldHandlers();
74  
75          setMouseMode("pan");
76      }
77  
78  
79      public boolean isAntialiasing() {
80          return antialias;
81      }
82  
83      public void setAntialias(boolean b) {
84          userAntialias = b;
85          antialias = b;
86          repaint();
87      }
88  
89      public void restoreAA() {
90          setAntialias(userAntialias);
91      }
92  
93  
94      public void setMode(String dom, String mod) {
95  
96          if (dom.equals("antialias")) {
97              antialias = (mod.equals("true"));
98  
99          } else if (dom.equals("mouse")) {
100             setMouseMode(mod);
101 
102         } else {
103             E.error("unrecognized mode " + dom);
104         }
105         repaint();
106     }
107 
108 
109 
110     public void setMode(String dom, boolean b) {
111         if (dom.equals("antialias")) {
112             antialias = b;
113 
114         } else if (dom.equals("labels")) {
115             tooltips = b;
116 
117         } else if (dom.equals("showAll")) {
118             reframe();
119 
120         } else {
121             E.error("unrecognized mode " + dom);
122         }
123         repaint();
124     }
125 
126 
127     public void syncSize() {
128         wt.setWidth(getWidth());
129         wt.setHeight(getHeight());
130     }
131 
132 
133     public void reluctantReframe() {
134         if (reframeBox == null) {
135             reframe();
136         } else if (paintInstructor != null) {
137             Box box = paintInstructor.getLimitBox();
138             if (box != null && box.differentFrom(reframeBox, 0.15)) {
139                 frameToBox(box);
140             }
141         }
142     }
143 
144 
145     public void reframe() {
146         if (paintInstructor == null) {
147             E.shortWarning("no paint instructor?");
148         } else {
149             Box box = paintInstructor.getLimitBox();
150             frameToBox(box);
151         }
152     }
153 
154 
155     protected void frameToBox(Box box) {
156         if (box == null) {
157             E.warning("no limit box returned from " + paintInstructor.getClass().getName());
158 
159 
160         } else if (box.hasData()) {
161             reframeBox = box.makeCopy();
162             box.pad();
163             painter.reframe(box);
164             repaint();
165 
166         } else {
167             // ok? - mesage? TODO
168         }
169 
170     }
171 
172 
173 
174     public boolean showTooltips() {
175         return tooltips;
176     }
177 
178 
179     public void setMode(int imode) {
180         E.missing();
181     }
182 
183 
184     public void addRangeListener(RangeListener rl) {
185         wt.addRangeListener(rl);
186     }
187 
188 
189 
190     public Painter getPainter() {
191         return painter;
192     }
193 
194 
195     WorldTransform getWorldTransform() {
196         return wt;
197     }
198 
199 
200     public void prependHandler(MouseHandler mhandler) {
201         mouse.prependHandler(mhandler);
202     }
203 
204 
205     public void setClickListener(ClickListener cl) {
206         mouse.setClickListener(cl);
207     }
208 
209     public void setRotationListener(RotationListener rl) {
210         wt.setRotationListener(rl);
211     }
212 
213 
214 
215     public void addWorldHandlers() {
216         panHandler = new PanHandler();
217         addHandler(panHandler);
218 
219         clickZoomHandler = new ClickZoomHandler();
220         addHandler(clickZoomHandler);
221 
222         boxSelectionHandler = new BoxSelectionHandler();
223         addHandler(boxSelectionHandler);
224 
225         turnZoomHandler = new TurnZoomHandler();
226         addHandler(turnZoomHandler);
227 
228         // TODO - only if 3d?
229         rollHandler = new RollHandler();
230         addHandler(rollHandler);
231 
232         turntableHandler = new TurntableHandler();
233         addHandler(turntableHandler);
234 
235 
236         MouseHandler[] ha = { panHandler, clickZoomHandler, boxSelectionHandler,
237                               turnZoomHandler, rollHandler, turntableHandler
238                             };
239         handlers = ha;
240     }
241 
242 
243 
244     public void setMouseMode(String s) {
245         for (int i = 0; i < handlers.length; i++) {
246             handlers[i].deactivate();
247         }
248 
249         if (s == null) {
250             E.error("null mouse mode ");
251 
252         } else if (s.equals(MULTI)) {
253             for (int i = 0; i < handlers.length; i++) {
254                 handlers[i].activate();
255             }
256 
257         } else if (s.equals(PAN)) {
258             panHandler.simpleActivate();
259 
260         } else if (s.equals(ZOOM)) {
261             clickZoomHandler.activateInOut();
262 
263         } else if (s.equals(BOX)) {
264             boxSelectionHandler.simpleActivate();
265 
266         } else if (s.equals(ROLL)) {
267             rollHandler.simpleActivate();
268 
269         } else if (s.equals(TURN)) {
270             turntableHandler.simpleActivate();
271 
272         } else if (s.equals(ZOOMIN)) {
273             clickZoomHandler.activateIn();
274 
275         } else if (s.equals(ZOOMOUT)) {
276             clickZoomHandler.activateOut();
277 
278         } else {
279             E.error("unhandled mouse mode " + s);
280         }
281     }
282 
283 
284     public void setXRange(double[] lh) {
285         setXRange(lh[0], lh[1]);
286     }
287 
288 
289     public void setYRange(double[] lh) {
290         setYRange(lh[0], lh[1]);
291     }
292 
293 
294 
295     public void ensureCovers(double[] xr, double[] yr) {
296         wt.ensureCovers(xr[0], yr[0], xr[1], yr[1]);
297         wt.notifyRangeChange();
298     }
299 
300 
301     public void setXRange(double low, double high) {
302         wt.setXRange(low, high);
303         wt.notifyRangeChange();
304     }
305 
306 
307     public void setYRange(double low, double high) {
308         wt.setYRange(low, high);
309         wt.notifyRangeChange();
310     }
311 
312 
313     public void setFixedAspectRatio(double ar) {
314         wt.setFixedAspectRatio(ar);
315     }
316 
317 
318     public double[] getXRange() {
319         return wt.getXRange();
320     }
321 
322 
323     public double[] getYRange() {
324         return wt.getYRange();
325     }
326 
327 
328     public void viewAction(String s) {
329         if (s.equals("frame")) {
330             reframe();
331         }
332     }
333 
334 
335 
336     public void addHandler(MouseHandler mh) {
337         mouse.addHandler(mh);
338     }
339 
340 
341     public void fixRanges() {
342         wt.fixRanges();
343     }
344 
345 
346 
347     public void setPaintInstructor(PaintInstructor pi) {
348         paintInstructor = pi;
349     }
350 
351 
352     public void paintComponent(Graphics g0) {
353         wt.setWidth(getWidth());
354         wt.setHeight(getHeight());
355 
356         g0.setColor(getDataBackground());
357         g0.fillRect(0, 0, getWidth(), getHeight());
358         Graphics2D g = (Graphics2D)g0;
359 
360 
361         painter.setGraphics(g);
362 
363         prePaint(g);
364 
365         paint2D(g);
366 
367         postPaint(g);
368 
369         mouse.echoPaint(g);
370 
371     }
372 
373 
374     public void prePaint(Graphics2D g) {
375 
376     }
377 
378     public void postPaint(Graphics2D g) {
379 
380     }
381 
382 
383     public void applyAAPreference(Graphics2D g) {
384         if (antialias) {
385             g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
386         } else {
387             g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
388         }
389 
390     }
391 
392 
393     public void paint2D(Graphics2D g) {
394 
395         E.info("pw oainting ");
396 
397         if (paintInstructor != null) {
398 
399             applyAAPreference(g);
400 
401             paintInstructor.instruct(painter);
402         }
403 
404     }
405 
406 
407 
408     void boxSelected(int x0, int y0, int x1, int y1) {
409         wt.setCanvasSize(getWidth(), getHeight());
410         wt.boxSelected(x0, y0, x1, y1);
411         repaint();
412     }
413 
414     void initializeZoom(int xc, int yc) {
415         wt.initializeZoom(xc, yc);
416     }
417 
418     void dragZoom(double fx, double fy, int xc, int yc) {
419         antialias = false;
420         wt.dragZoom(fx, fy, xc, yc);
421     }
422 
423 
424     void zoom(double fac, int xc, int yc) {
425         wt.zoom(fac, xc, yc);
426         repaint();
427     }
428 
429 
430     void zoom(double xfac, double yfac, int xc, int yc) {
431         wt.zoom(xfac, yfac, xc, yc);
432         repaint();
433     }
434 
435 
436     void trialPan(int xfrom, int yfrom, int xto, int yto) {
437         antialias = false;
438         wt.trialPan(xfrom, yfrom, xto, yto);
439         repaint();
440     }
441 
442 
443     void permanentPan(int xfrom, int yfrom, int xto, int yto) {
444         wt.permanentPan(xfrom, yfrom, xto, yto);
445         repaint();
446     }
447 
448 
449     void dragRollRotate(int px, int py) {
450         antialias = false;
451         wt.dragRollRotate(px, py);
452         repaint();
453     }
454 
455     void dragZRotate(int px, int py) {
456         antialias = false;
457         wt.dragZRotate(px, py);
458         repaint();
459     }
460 
461     public void turn(double d) {
462         wt.initializeRotation(getWidth() / 2, getHeight() / 2);
463         wt.zRotate(d / 180. * Math.PI);
464         repaint();
465     }
466 
467     void initializeRotation(int px, int py) {
468         wt.initializeRotation(px, py);
469     }
470 
471 
472     void initializeRotation(double x, double y, double z) {
473         wt.initializeRotationLocal(x, y, z);
474     }
475 
476 
477     public void setColorRange(double cmin, double cmax) {
478         painter.setColorRange(cmin, cmax);
479     }
480 
481     public void setColorTable(Color[] ac) {
482         painter.setColorTable(ac);
483     }
484 
485 
486     public int[] getIntPosition(Position pos) {
487         return wt.getIntPosition(pos.getX(), pos.getY());
488     }
489 
490 
491     public double[][] getProjectionMatrix() {
492         return wt.getProjectionMatrix();
493     }
494 
495     public void setRollCenter(double x, double y, double z) {
496         rollHandler.setRollCenter(x, y, z);
497     }
498 
499 
500     public double[] get2Center() {
501         return wt.get2Center();
502     }
503 
504     public double[] get3Center() {
505         return wt.get3Center();
506     }
507 
508 
509 
510     // first four elements should be top row of matrix;
511     public double[] getFourMatrix() {
512         double[][] pm = wt.getProjectionMatrix();
513 
514 //	   double[] cen = wt.get3Center();
515 
516         double[] cen2 = wt.get2Center();
517 
518         double[] ret = new double[16];
519 
520         double sf = 3. * wt.getScale();
521 
522         for (int i = 0; i < 3; i++) {
523             for (int j = 0; j < 3; j++) {
524                 ret[4 * i + j] = sf * pm[i][j];
525             }
526             ret[4 * i + 3] = cen2[i];
527         }
528         ret[15] = 1.;
529         return ret;
530     }
531 
532 
533     public void setFourMatrix(double[] fm) {
534         double[][] pm = new double[3][3];
535         double[] cen = new double[3];
536 
537         for (int i = 0; i < 3; i++) {
538             for (int j = 0; j < 3; j++) {
539                 pm[i][j]= fm[4 * i + j];
540             }
541             cen[i] = fm[4 * i + 3];
542         }
543 
544         double m3xx, m3xy, m3xz, m3yx, m3yy, m3yz, m3zx, m3zy, m3zz;
545         m3xx = pm[0][0];
546         m3xy = pm[0][1];
547         m3xz = pm[0][2];
548         m3yx = pm[1][0];
549         m3yy = pm[1][1];
550         m3yz = pm[1][2];
551         m3zx = pm[2][0];
552         m3zy = pm[2][1];
553         m3zz = pm[2][2];
554 
555         double det = (m3xx * (m3yy * m3zz - m3zy * m3yz) -
556                       m3xy * (m3yx * m3zz - m3zx * m3yz) +
557                       m3xz * (m3yx * m3zy - m3zx * m3yy));
558 
559         double rdet = Math.pow(det, 1./3.);
560         for (int i = 0; i < 3; i++) {
561             for (int j = 0; j < 3; j++) {
562                 pm[i][j] /= rdet;
563             }
564         }
565 
566         double[] c0 = {0., 0., 0.};
567 
568         for (int i = 0; i < 3; i++) {
569             cen[i] /= rdet;
570         }
571 
572         wt.setProjectionMatrix(pm);
573         wt.set3Center(c0);
574         wt.set2Center(cen);
575 
576         wt.setScale(0.3 * rdet); // ADHOC
577 
578         repaint();
579 
580     }
581 }