Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/xerox/VTM/engine/VirtualSpaceManager.java


1   /*   FILE: VirtualSpaceManager.java
2    *   DATE OF CREATION:   Jul 11 2000
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Wed Jul 23 15:25:29 2003 by Emmanuel Pietriga (emmanuel@w3.org, emmanuel@claribole.net)
5    *   Copyright (c) Xerox Corporation, XRCE/Contextual Computing, 2002. All Rights Reserved
6    *
7    * This library is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU Lesser General Public
9    * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   * 
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * For full terms see the file COPYING.
18   */
19  
20  package com.xerox.VTM.engine;
21  
22  import java.util.Vector;
23  import java.util.Hashtable;
24  import java.util.Enumeration;
25  import java.awt.Color;
26  import java.awt.Font;
27  import java.awt.Point;
28  import javax.swing.*;
29  import com.xerox.VTM.engine.*;
30  import com.xerox.VTM.glyphs.*;
31  import net.claribole.zvtm.glyphs.CGlyph;
32  import net.claribole.zvtm.engine.Location;
33  // import EDU.Washington.grad.gjb.cassowary.*;
34  
35  /**
36   * Virtual space manager - VTM root class - virtual space management (camera, glyphs,...) is done here - primary interface to application. This is the main class to instantiate.
37   * @author Emmanuel Pietriga
38   **/
39  
40  public class VirtualSpaceManager implements java.awt.event.AWTEventListener {
41  
42      static Font mainFont=new Font("Dialog",0,10);
43  
44      public static Font getMainFont(){return mainFont;}
45  
46      public void setMainFont(Font f){
47    mainFont=f;
48    for (Enumeration e=allViews.elements();e.hasMoreElements();){((View)e.nextElement()).updateFont();}
49    Object g;
50    for (Enumeration e=allGlyphs.elements();e.hasMoreElements();){
51        g=e.nextElement();
52        if (g instanceof VText){((VText)g).invalidate();}
53    }
54    repaintNow();
55      }
56  
57      /**select only mouse sensitive and visible glyphs*/
58      public static short VIS_AND_SENS_GLYPHS=0;
59      /**select only visible glyphs*/ 
60      public static short VISIBLE_GLYPHS=1;
61      /**select only mouse sensitive glyphs*/
62      public static short SENSITIVE_GLYPHS=2;
63      /**select all glyphs in the region*/
64      public static short ALL_GLYPHS=3;     
65  
66      /**print exceptions*/
67      boolean debug=false;
68  
69      /**next glyph will have ID...*/
70      private long nextID;
71      /**next camera will have ID...*/
72      private int nextcID;
73      /**next cursor will have ID...*/
74      private int nextmID;
75  
76      /**key is glyph ID (Long)*/
77      protected Hashtable allGlyphs;
78      /**key is camera ID  (Integer)*/
79      protected Hashtable allCameras;
80      /**key is space name (String)*/
81      protected Hashtable allVirtualSpaces;
82      /**key is view name  (String)*/
83      protected Hashtable allViews;
84  
85      /**current view*/
86      public View activeView;
87  
88      /**default policy for view repainting - true means all views are repainted even if ((not active) or (mouse not inside the view)) - false means only the active view and the view in which the mouse is currently located (if different) are repainted - default is true*/
89      boolean generalRepaintPolicy=true;
90  
91      /**enables detection of multiple full fills in one view repaint - default value assigned to new views  - STILL VERY BUGGY - ONLY SUPPORTS VRectangle and VCircle for now*/
92      boolean defaultMultiFill=false;
93  
94      /**value under which a VText is drawn as a point instead of a text (considered too small to be read). Default is 0.5 - if you raise this value, text that was still displayed as a string will be displayed as a segment and inversely - of course, displaying a line instead of applying affine transformations to strings is faster*/
95      float textAsLineCoef=0.5f;
96  
97      /**sync mouse cursor and mouse glyph*/
98      public boolean mouseSync;
99  
100     /**Animation Manager*/
101     public AnimManager animator;
102 
103     /**allow negative camera altitudes (zoom beyond the standard size=magnification)*/
104     protected int zoomFloor=0;
105 
106     /**Constraint Manager*/
107 //     public ConstraintManager constMgr;
108 
109     Color selectColor=Color.yellow;
110     Color mouseInsideColor=Color.white;
111 
112     /**
113      * Only for use with stand-alone Java applications (use other constructor with applet=true if running inside a JApplet)
114      */
115     public VirtualSpaceManager(){
116   if (debug){System.out.println("Debug mode ON");}
117   nextID=1;
118   nextcID=1;
119   nextmID=1;
120   allGlyphs=new Hashtable();
121   allCameras=new Hashtable();
122   allVirtualSpaces=new Hashtable();
123   allViews=new Hashtable();
124   animator=new AnimManager(this);  //started only when a view is created
125 //   constMgr=new ConstraintManager(this);
126   mouseSync=true;
127   java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(this,java.awt.AWTEvent.WINDOW_EVENT_MASK);
128     }
129 
130     /**
131      * Set applet to true if you are calling ZVTM from inside an Applet
132      */
133     public VirtualSpaceManager(boolean applet){
134   if (debug){System.out.println("Debug mode ON");}
135   nextID=1;
136   nextcID=1;
137   nextmID=1;
138   allGlyphs=new Hashtable();
139   allCameras=new Hashtable();
140   allVirtualSpaces=new Hashtable();
141   allViews=new Hashtable();
142   animator=new AnimManager(this);  //started only when a view is created
143 //   constMgr=new ConstraintManager(this);
144   mouseSync=true;
145   if (!applet){java.awt.Toolkit.getDefaultToolkit().addAWTEventListener(this,java.awt.AWTEvent.WINDOW_EVENT_MASK);}
146     }
147 
148     /**set debug mode ON or OFF*/
149     public void setDebug(boolean b){
150   debug=b;
151     }
152 
153     /**get debug mode state (ON or OFF)*/
154     public boolean debugModeON(){return debug;}
155 
156     /**set policy for view repainting - true means all views are repainted even if ((not active) or (mouse not inside the view)) - policy is forwarded to all existing views (no matter its current policy) and will be applied to future ones (but it can be changed for each single view)*/
157     public void setRepaintPolicy(boolean b){
158   if (b!=generalRepaintPolicy){
159       generalRepaintPolicy=b;
160       for (Enumeration e=allViews.elements();e.hasMoreElements();){
161     ((View)e.nextElement()).setRepaintPolicy(generalRepaintPolicy);
162       }
163   }
164     }
165 
166     /**get general policy for view repainting (this is the current default policy, but this does not guarantee that all views comply with it since the policy may be changed for each single view)*/
167     public boolean getRepaintPolicy(){return generalRepaintPolicy;}
168 
169     /**enable/disable detection of multiple full fills in one view repaint - default value assigned to new views - default is false */
170     public void setDefaultMultiFills(boolean b){
171   defaultMultiFill=b;
172     }
173 
174     /**get state of detection of multiple full fills in one view repaint - default value assigned to new views */
175     public boolean getDefaultMultiFills(){
176   return defaultMultiFill;
177     }
178 
179     /**
180      * set a zoom-in limit/maximum magnification  (like a floor the camera cannot go through)<br>
181      * value 0 means that, at maximum magnification, the size of observed glyphs corresponds to their <i>real</i> size (e.g. if a circle has a declared radius of 50 in the virtual space, then its radius at max magnification is 50)<br>
182      * if the floor is set to a negative value, you will be able to zoom in further (meaning that you will be able to magnify objects beyond their declared size)<br>
183      * Note: there is no limit for zoom out (no so-called ceiling)
184      *@param a the altitude of the floor - the default value is 0 (put a negative value if you want to be able to magnify objects beyond their normal size) 
185      */
186     public void setZoomLimit(int a){
187   zoomFloor=a;
188     }
189 
190     /**
191      * get the zoom-in limit/maximum magnification  (like a floor the camera cannot go through)<br>
192      * default value 0 means that, at maximum magnification, the size of observed glyphs corresponds to their <i>real</i> size (e.g. if a circle has a declared radius of 50 in the virtual space, then its radius at max magnification is 50)<br>
193      * if the floor is set to a negative value, you will be able to zoom in further (meaning that you will be able to magnify objects beyond their declared size)<br>
194      * Note: there is no limit for zoom out (no so-called ceiling)
195      */
196     public int getZoomLimit(){
197   return zoomFloor;
198     }
199 
200     /**true -&gt; sync mouse cursor and mouse glyph*/
201     public void setMouseSync(boolean b){
202   mouseSync=b;
203   activeView.mouse.setSync(mouseSync);
204     }
205 
206     /**set border color of selected glyphs (not propagated to existing glyphs)*/
207     public void setSelectedGlyphColor(Color c){
208   selectColor=c;
209     }
210     
211     /**set border color of glyphs overlapped by mouse (not propagated to existing glyphs)*/
212     public void setMouseInsideGlyphColor(Color c){
213   mouseInsideColor=c;
214     }
215 
216     /**add glyph g to virtual space whose name is vs*/
217     public Glyph addGlyph(Glyph g,String vs){
218   if (g!=null){
219       if (allVirtualSpaces.containsKey(vs)){
220     VirtualSpace tvs=(VirtualSpace)allVirtualSpaces.get(vs);
221     tvs.addGlyph(g);
222     g.setID(new Long(nextID++));
223     g.setVSM(this);
224     g.setSelectedColor(this.selectColor);
225     g.setMouseInsideColor(this.mouseInsideColor);
226     allGlyphs.put(g.getID(),g);
227     repaintNow();
228     return g;
229       }
230       else {System.err.println("ZVTM Error:VirtualSpaceManager:addGlyph:unknown virtual space: "+vs);return null;}
231   }
232   else {System.err.println("ZVTM Error:VirtualSpaceManager:addGlyph:attempting to add a null Glyph in space: "+vs);return null;}
233     }
234 
235     /**add composite glyph c to virtual space whose name is vs*/
236     public CGlyph addCGlyph(CGlyph c,String vs){
237   if (c!=null){
238       if (allVirtualSpaces.containsKey(vs)){
239     c.setID(new Long(nextID++));
240     c.setVSM(this);
241     allGlyphs.put(c.getID(),c);
242     return c;
243       }
244       else {System.err.println("Error:VirtualSpaceManager:addCGlyph:unknown virtual space: "+vs);return null;}
245   }
246   else {System.err.println("Error:VirtualSpaceManager:addCGlyph:attempting to add a null composite glyph in space: "+vs);return null;}
247     }
248 
249     /**get glyph with ID id*/
250     public Glyph getGlyph(Long id){
251   return (Glyph)(allGlyphs.get(id));
252     }
253 
254     /** returns a vector of glyphs whose hotspot is in region delimited by rectangle (x1,y1,x2,y2) in virtual space vs (returns null if empty). Coordinates of the mouse cursor in virtual space are available in instance variables vx and vy of class VCursor. The selection rectangle can be drawn on screen by using ViewPanel.setDrawRect(true) (e.g. call when mouse button is pressed)/ViewPanel.setDrawRect(false) (e.g. call when mouse button is released)
255      *@param x1 x coord of first point
256      *@param y1 y coord of first point
257      *@param x2 x coord of opposite point
258      *@param y2 y coord of opposite point
259      *@param vsn name of virtual space
260      *@param wg which glyphs in the region should be returned (among VIS_AND_SENS_GLYPHS (default), VISIBLE_GLYPHS, SENSIBLE_GLYPHS, ALL_GLYPHS)
261      */
262     public Vector getGlyphsInRegion(long x1,long y1,long x2,long y2,String vsn,int wg){
263   Vector res=new Vector();
264   VirtualSpace vs=getVirtualSpace(vsn);
265   long minX=Math.min(x1,x2);
266   long minY=Math.min(y1,y2);
267   long maxX=Math.max(x1,x2);
268   long maxY=Math.max(y1,y2);
269   if (vs!=null){
270       Vector allG=vs.getAllGlyphs();
271       Glyph g;
272       for (int i=0;i<allG.size();i++){
273     g=(Glyph)allG.elementAt(i);
274     if ((g.vx>=minX) && (g.vy>=minY) && (g.vx<=maxX) && (g.vy<=maxY)){
275         if ((wg==VIS_AND_SENS_GLYPHS) && g.isSensitive() && g.isVisible()){res.add(g);}
276         else if ((wg==VISIBLE_GLYPHS) && g.isVisible()){res.add(g);}
277         else if ((wg==SENSITIVE_GLYPHS) && g.isSensitive()){res.add(g);}
278         else if (wg==ALL_GLYPHS){res.add(g);}
279     }
280       }
281   }
282   if (res.isEmpty()){res=null;}
283   return res;
284     }
285 
286     /**destroy all glyphs in space whose name is spaceName*/
287     public void destroyGlyphsInSpace(String spaceName){
288   VirtualSpace vs=getVirtualSpace(spaceName);
289   Glyph g;
290   Vector entClone=(Vector)vs.getAllGlyphs().clone();
291   for (Enumeration e=entClone.elements();e.hasMoreElements();){
292       g=(Glyph)(e.nextElement());
293       vs.destroyGlyph(g);
294       allGlyphs.remove(g);
295   }
296   repaintNow();
297     }
298 
299     /**add camera to space whose name is vs
300      *@param vs owning virtual space 
301      */
302     public Camera addCamera(String vs){
303   VirtualSpace tvs=(VirtualSpace)allVirtualSpaces.get(vs);
304   Camera c=tvs.createCamera();
305   c.setID(new Integer(nextcID++));
306   allCameras.put(c.getID(),c);
307   return c;
308     }
309 
310     /**
311      *add camera to space whose name is vs
312      *@param vs owning virtual space
313      *@param lazy true if this is to be a lazy camera (false otherwise)
314      */
315     public Camera addCamera(String vs,boolean lazy){
316   VirtualSpace tvs=(VirtualSpace)allVirtualSpaces.get(vs);
317   Camera c=tvs.createCamera();
318   c.setLaziness(lazy);
319   c.setID(new Integer(nextcID++));
320   allCameras.put(c.getID(),c);
321   return c;
322     }
323 
324     /**get camera whose ID is id*/
325     public Camera getCamera(Integer id){
326   return (Camera)(allCameras.get(id));
327     }
328 
329     /**get active camera*/
330     public Camera getActiveCamera(){
331   return activeView.getActiveCamera();
332     }
333 
334     /**create a new view - old method
335      *@param c vector of cameras superimposed in this view
336      *@param name view name
337      *@param w width of window in pixels
338      *@param h height of window in pixels
339      *@param bar true -&gt; add a status bar to this view (below main panel)
340      *@param visible should the view be made visible automatically or not
341      */
342     public View addView(Vector c,String name,int w,int h,boolean bar,boolean visible){
343   EView tvi=new EView(c,name,w,h,bar,visible,this);
344   tvi.mouse.setID(new Long(nextmID++));
345   allViews.put(name,tvi);
346   tvi.setRepaintPolicy(generalRepaintPolicy);
347   if (!animator.started){animator.start();} //start animator only when a view is created
348   return tvi;
349     }
350 
351     /**create a new accelerated view - old method
352      *@param c vector of cameras superimposed in this view
353      *@param name view name
354      *@param w width of window in pixels
355      *@param h height of window in pixels
356      *@param bar true -&gt; add a status bar to this view (below main panel)
357      *@param visible should the view be made visible automatically or not
358      */
359     public View addAccView(Vector c,String name,int w,int h,boolean bar,boolean visible){
360   AccEView tvi=new AccEView(c,name,w,h,bar,visible,this);
361   tvi.mouse.setID(new Long(nextmID++));
362   allViews.put(name,tvi);
363   tvi.setRepaintPolicy(generalRepaintPolicy);
364   if (!animator.started){animator.start();} //start animator only when a view is created
365   return tvi;
366     }
367 
368     /**create a new view - old method
369      *@param c vector of cameras superimposed in this view
370      *@param name view name
371      *@param w width of window in pixels
372      *@param h height of window in pixels
373      *@param bar true -&gt; add a status bar to this view (below main panel)
374      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
375      *@param visible should the view be made visible automatically or not
376      */
377     public View addView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb){
378   EView tvi=new EView(c,name,w,h,bar,visible,this,mnb);
379   tvi.mouse.setID(new Long(nextmID++));
380   allViews.put(name,tvi);
381   tvi.setRepaintPolicy(generalRepaintPolicy);
382   if (!animator.started){animator.start();} //start animator only when a view is created
383   return tvi;
384     }
385 
386     /**create a new accelerated view - old method
387      *@param c vector of cameras superimposed in this view
388      *@param name view name
389      *@param w width of window in pixels
390      *@param h height of window in pixels
391      *@param bar true -&gt; add a status bar to this view (below main panel)
392      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
393      *@param visible should the view be made visible automatically or not
394      */
395     public View addAccView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb){
396   AccEView tvi=new AccEView(c,name,w,h,bar,visible,this,mnb);
397   tvi.mouse.setID(new Long(nextmID++));
398   allViews.put(name,tvi);
399   tvi.setRepaintPolicy(generalRepaintPolicy);
400   if (!animator.started){animator.start();} //start animator only when a view is created
401   return tvi;
402     }
403 
404     /**create a new external view
405      *@param c vector of cameras superimposed in this view
406      *@param name view name
407      *@param w width of window in pixels
408      *@param h height of window in pixels
409      *@param bar true -&gt; add a status bar to this view (below main panel)
410      *@param visible should the view be made visible automatically or not
411      */
412     public EView addExternalView(Vector c,String name,int w,int h,boolean bar,boolean visible){
413   EView tvi=new EView(c,name,w,h,bar,visible,this);
414   tvi.mouse.setID(new Long(nextmID++));
415   allViews.put(name,tvi);
416   tvi.setRepaintPolicy(generalRepaintPolicy);
417   if (!animator.started){animator.start();} //start animator only when a view is created
418   return tvi;
419     }
420 
421     /**create a new external accelerated view
422      *@param c vector of cameras superimposed in this view
423      *@param name view name
424      *@param w width of window in pixels
425      *@param h height of window in pixels
426      *@param bar true -&gt; add a status bar to this view (below main panel)
427      *@param visible should the view be made visible automatically or not
428      */
429     public AccEView addExternalAccView(Vector c,String name,int w,int h,boolean bar,boolean visible){
430   AccEView tvi=new AccEView(c,name,w,h,bar,visible,this);
431   tvi.mouse.setID(new Long(nextmID++));
432   allViews.put(name,tvi);
433   tvi.setRepaintPolicy(generalRepaintPolicy);
434   if (!animator.started){animator.start();} //start animator only when a view is created
435   return tvi;
436     }
437 
438     /**create a new external view
439      *@param c vector of cameras superimposed in this view
440      *@param name view name
441      *@param w width of window in pixels
442      *@param h height of window in pixels
443      *@param bar true -&gt; add a status bar to this view (below main panel)
444      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
445      *@param visible should the view be made visible automatically or not
446      */
447     public EView addExternalView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb){
448   EView tvi=new EView(c,name,w,h,bar,visible,this,mnb);
449   tvi.mouse.setID(new Long(nextmID++));
450   allViews.put(name,tvi);
451   tvi.setRepaintPolicy(generalRepaintPolicy);
452   if (!animator.started){animator.start();} //start animator only when a view is created
453   return tvi;
454     }
455 
456     /**create a new external accelerated view
457      *@param c vector of cameras superimposed in this view
458      *@param name view name
459      *@param w width of window in pixels
460      *@param h height of window in pixels
461      *@param bar true -&gt; add a status bar to this view (below main panel)
462      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
463      *@param visible should the view be made visible automatically or not
464      */
465     public AccEView addExternalAccView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb){
466   AccEView tvi=new AccEView(c,name,w,h,bar,visible,this,mnb);
467   tvi.mouse.setID(new Long(nextmID++));
468   allViews.put(name,tvi);
469   tvi.setRepaintPolicy(generalRepaintPolicy);
470   if (!animator.started){animator.start();} //start animator only when a view is created
471   return tvi;
472     }
473 
474     /**create a new internal view
475      *@param c vector of cameras superimposed in this view
476      *@param name view name
477      *@param w width of window in pixels
478      *@param h height of window in pixels
479      *@param bar true -&gt; add a status bar to this view (below main panel)
480      *@param visible should the view be made visible automatically or not
481      *@param desktop parent desktop pane
482      *@param layer layer number in the JDesktopPane (ivc) - put 1 if you don't care
483      */
484     public IView addInternalView(Vector c,String name,int w,int h,boolean bar,boolean visible,IViewContainer ivc,Integer layer){
485   IView tvi=new IView(c,name,w,h,bar,visible,this,ivc,layer);
486   tvi.mouse.setID(new Long(nextmID++));
487   allViews.put(name,tvi);
488   tvi.setRepaintPolicy(generalRepaintPolicy);
489   if (!animator.started){animator.start();} //start animator only when a view is created
490   return tvi;
491     }
492 
493     /**create a new internal accelerated view
494      *@param c vector of cameras superimposed in this view
495      *@param name view name
496      *@param w width of window in pixels
497      *@param h height of window in pixels
498      *@param bar true -&gt; add a status bar to this view (below main panel)
499      *@param visible should the view be made visible automatically or not
500      *@param desktop parent desktop pane
501      *@param layer layer number in the JDesktopPane (ivc) - put 1 if you don't care
502      */
503     public AccIView addInternalAccView(Vector c,String name,int w,int h,boolean bar,boolean visible,IViewContainer ivc,Integer layer){
504   AccIView tvi=new AccIView(c,name,w,h,bar,visible,this,ivc,layer);
505   tvi.mouse.setID(new Long(nextmID++));
506   allViews.put(name,tvi);
507   tvi.setRepaintPolicy(generalRepaintPolicy);
508   if (!animator.started){animator.start();} //start animator only when a view is created
509   return tvi;
510     }
511 
512     /**create a new internal view
513      *@param c vector of cameras superimposed in this view
514      *@param name view name
515      *@param w width of window in pixels
516      *@param h height of window in pixels
517      *@param bar true -&gt; add a status bar to this view (below main panel)
518      *@param desktop parent desktop pane
519      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
520      *@param visible should the view be made visible automatically or not
521      *@param layer layer number in the JDesktopPane (ivc) - put 1 if you don't care
522      */
523     public IView addInternalView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb,IViewContainer ivc,Integer layer){
524   IView tvi=new IView(c,name,w,h,bar,visible,this,ivc,mnb,layer);
525   tvi.mouse.setID(new Long(nextmID++));
526   allViews.put(name,tvi);
527   tvi.setRepaintPolicy(generalRepaintPolicy);
528   if (!animator.started){animator.start();} //start animator only when a view is created
529   return tvi;
530     }
531 
532     /**create a new internal accelerated view
533      *@param c vector of cameras superimposed in this view
534      *@param name view name
535      *@param w width of window in pixels
536      *@param h height of window in pixels
537      *@param bar true -&gt; add a status bar to this view (below main panel)
538      *@param desktop parent desktop pane
539      *@param mnb a menu bar, already configured with actionListeners already attached to items (it is just added to the view)
540      *@param visible should the view be made visible automatically or not
541      *@param layer layer number in the JDesktopPane (ivc) - put 1 if you don't care
542      */
543     public AccIView addInternalAccView(Vector c,String name,int w,int h,boolean bar,boolean visible,JMenuBar mnb,IViewContainer ivc,Integer layer){
544   AccIView tvi=new AccIView(c,name,w,h,bar,visible,this,ivc,mnb,layer);
545   tvi.mouse.setID(new Long(nextmID++));
546   allViews.put(name,tvi);
547   tvi.setRepaintPolicy(generalRepaintPolicy);
548   if (!animator.started){animator.start();} //start animator only when a view is created
549   return tvi;
550     }
551 
552     /**create a JFrame container for IViews - required parameter in IView constructor
553      *@param name title of the JFrame
554      *@param w width of the main JFrame (0 for max width and height)
555      *@param h height of the main JFrame (0 for max width and height)
556      */
557     public IViewContainer createIViewContainer(String name,int w,int h){
558   IViewContainer ivc;
559   if ((w==0) && (h==0)){ivc=new IViewContainer(name);}
560   else{ivc=new IViewContainer(name,w,h);}
561   return ivc;
562     }
563 
564     /**create a new applet view
565      *@param c vector of cameras superimposed in this view
566      *@param name view name
567      *@param w width of window in pixels
568      *@param h height of window in pixels
569      */
570     public JPanel addAppletView(Vector c,String name,int w,int h){
571   AppletView tvi=new AppletView(c,name,w,h,this);
572   tvi.mouse.setID(new Long(nextmID++));
573   allViews.put(name,tvi);
574   tvi.setRepaintPolicy(generalRepaintPolicy);
575   if (!animator.started){animator.start();} //start animator only when a view is created
576   return tvi.panel;
577     }
578 
579     /**get view whose name is n*/
580     public View getView(String n){
581   return (View)(allViews.get(n));
582     }
583 
584     /**destroy a view - used internally - not available to programmer, who should call the method directly on the view itself*/
585     protected void destroyView(String viewName){
586   allViews.remove(viewName);
587   if (allViews.isEmpty()){animator.stop();}  //if there are no more views, stop AnimatorManager
588     }
589 
590     /**call this if you want to repaint all views at once
591      * in some cases it is not possible to detect graphical changes, like when a glyph is selected so repaint has to be done manually (unless you are willing to wait for another event to trigger repaint, like mouse moving)
592      */
593     public void repaintNow(){
594   for (Enumeration e=allViews.elements();e.hasMoreElements();){
595       ((View)(e.nextElement())).repaintNow();
596   }
597     }
598 
599     /**create a new virtual space with name n*/
600     public VirtualSpace addVirtualSpace(String n){
601   VirtualSpace tvs=new VirtualSpace(n);
602   tvs.setManager(this);
603   allVirtualSpaces.put(n,tvs);
604   return tvs;
605     }
606 
607     /**destroy a virtual space*/
608     public void destroyVirtualSpace(String n){
609   if (allVirtualSpaces.containsKey(n)){
610       VirtualSpace vs=(VirtualSpace)(allVirtualSpaces.get(n));
611       vs.destroy();
612       allVirtualSpaces.remove(n);
613   }
614     }
615 
616     /**get virtual space whose name is n*/
617     public VirtualSpace getVirtualSpace(String n){
618   return (VirtualSpace)(allVirtualSpaces.get(n));
619     }
620 
621     /**get active virtual space*/
622     public VirtualSpace getActiveSpace(){
623   return activeView.getActiveCamera().getOwningSpace();
624     }
625 
626     /**set active view*/
627     public void setActiveView(View v){
628   activeView=v;
629     }
630 
631     /**get active view*/
632     public View getActiveView(){
633   return activeView;
634     }
635 
636     /**stick glyph whose ID is id to mouse (to drag it) - glyph is automatically made unsensitive to mouse events*/
637     public void stickToMouse(Long id){
638   stickToMouse(getGlyph(id));
639     }
640 
641     /**stick glyph g to mouse (to drag it) - glyph is automatically made unsensitive to mouse events*/
642     public void stickToMouse(Glyph g){
643   activeView.mouse.stick(g);
644     }
645 
646     /**unstick ONLY LAST glyph sticked to mouse - glyph is automatically made sensitive to mouse events - you can get the number of glyphs sticked to the mouse by calling VCursor.getStickedGlyphsNumber()*/
647     public void unstickFromMouse(){
648   activeView.mouse.unstick();
649     }
650     
651     /**stick glyph whose ID is id1 to glyph whose ID is id2 (behaves like a one-way constraint)*/
652     public void stickToGlyph(Long id1,Long id2){
653   stickToGlyph(getGlyph(id1),getGlyph(id2));
654     }
655 
656     /**stick glyph g1 to glyph g2 (behaves like a one-way constraint)*/
657     public void stickToGlyph(Glyph g1,Glyph g2){
658   g2.stick(g1);
659     }
660 
661     /**unstick glyph whose ID is id1 from glyph whose ID is id2*/
662     public void unstickFromGlyph(Long id1,Long id2){
663   getGlyph(id2).unstick(getGlyph(id1));
664     }
665 
666     /**unstick glyph g1 from glyph g2*/
667     public void unstickFromGlyph(Glyph g1,Glyph g2){
668   g2.unstick(g1);
669     }
670 
671     /**unstick all glyphs sticked to g*/
672     public void unstickAllGlyphs(Glyph g){
673   Vector v=g.getStickedGlyphs();
674   for (int i=v.size()-1;i>=0;i--){
675       g.unstick((Glyph)v.elementAt(i));
676   }
677     }
678 
679     /**translates and (un)zooms a camera in order to see everything visible in the associated virtual space
680      *@param c Camera to be moved
681      *@param d duration of the animation in ms
682      *@return the final camera location
683      */
684     public Location getGlobalView(Camera c,int d){
685   View v=null;
686   try {
687       v=c.getOwningView();
688       if (v!=null){
689     long[] wnes=findFarmostGlyphCoords(c.parentSpace);  //wnes=west north east south
690     long dx=(wnes[2]+wnes[0])/2;  //new coords where camera should go
691     long dy=(wnes[1]+wnes[3])/2;
692     long[] regBounds=v.getVisibleRegion(c);
693     long[] trRegBounds={regBounds[0]+dx-c.posx,regBounds[3]+dy-c.posy};  //region that will be visible after translation, but before zoom/unzoom  (need to compute zoom) ; we only take left and down because we only need horizontal and vertical ratios, which are equals for left and right, up and down
694     float currentAlt=c.getAltitude()+c.getFocal();
695     float ratio=0;
696     //compute the mult factor for altitude to see all stuff on X
697     if (trRegBounds[0]!=0){ratio=(dx-wnes[0])/((float)(dx-trRegBounds[0]));}
698     //same for Y ; take the max of both
699     if (trRegBounds[1]!=0){
700         float tmpRatio=(dy-wnes[3])/((float)(dy-trRegBounds[1]));
701         if (tmpRatio>ratio){ratio=tmpRatio;}
702     }
703     float newAlt=currentAlt*Math.abs(ratio);
704     float dAlt=newAlt-currentAlt;
705     Vector prms=new Vector();
706     prms.add(new Float(dAlt));prms.add(new LongPoint(dx-c.posx,dy-c.posy));
707     animator.createCameraAnimation(d,AnimManager.CA_ALT_TRANS_SIG,prms,c.getID());
708     return new Location(dx,dy,newAlt);
709       }
710       else return null;
711   }
712   catch (NullPointerException e){
713       System.err.println("Error:VirtualSpaceManager:getGlobalView: ");
714       System.err.println("Camera c="+c);
715       System.err.println("View v="+v);
716       if (debug){e.printStackTrace();}
717       else {System.err.println(e);}
718       return null;
719   }
720     }
721 
722     /**returns the leftmost xpos, upmost ypos, rightmost xpos, downmost ypos visible in virtual space s*/
723     public static long[] findFarmostGlyphCoords(VirtualSpace s){
724   if (s!=null){
725       long[] res=new long[4];
726       Vector v=s.getVisibleGlyphs();
727       if (!v.isEmpty()){
728     Glyph g=(Glyph)v.firstElement();//init result with first glyph found
729     long size=(long)g.getSize();
730     res[0]=g.vx-size;
731     res[1]=g.vy+size;
732     res[2]=g.vx+size;
733     res[3]=g.vy-size;
734     long tmp;
735     for (int i=1;i<v.size();i++){
736         g=(Glyph)v.elementAt(i);
737         size=(long)g.getSize();
738         tmp=g.vx-size; if (tmp<res[0]){res[0]=tmp;}
739         tmp=g.vy+size; if (tmp>res[1]){res[1]=tmp;}
740         tmp=g.vx+size; if (tmp>res[2]){res[2]=tmp;}
741         tmp=g.vy-size; if (tmp<res[3]){res[3]=tmp;}
742     }
743     return res;
744       }
745       else {res[0]=0;res[1]=0;res[2]=0;res[3]=0;return res;}
746   }
747   else return null;
748     }
749 
750     /**translates and (un)zooms a camera in order to focus on glyph g
751      *@param g Glyph of interest
752      *@param c Camera to be moved
753      *@param d duration of the animation in ms
754      *@return the final camera location
755      */
756     public Location centerOnGlyph(Glyph g,Camera c,int d){
757   View v=null;
758   try {
759       v=c.getOwningView();
760       if (v!=null){
761     long dx;
762     long dy;
763     if (g instanceof VText){
764         VText t=(VText)g;
765         LongPoint p=t.getBounds(c.getIndex());
766         if (t.getTextAnchor()==VText.TEXT_ANCHOR_START){
767       dx=g.vx+p.x/2-c.posx;
768       dy=g.vy+p.y/2-c.posy;
769         }
770         else if (t.getTextAnchor()==VText.TEXT_ANCHOR_MIDDLE){
771       dx=g.vx-c.posx;
772       dy=g.vy-c.posy;
773         }
774         else {
775       dx=g.vx-p.x/2-c.posx;
776       dy=g.vy-p.y/2-c.posy;
777         }
778     }
779     else if (g instanceof VPath){
780         VPath p=(VPath)g;
781         dx=p.realHotSpot.x-c.posx;
782         dy=p.realHotSpot.y-c.posy;
783     }
784     else {
785         dx=g.vx-c.posx;
786         dy=g.vy-c.posy;
787     }
788     long[] regBounds=v.getVisibleRegion(c);
789     long[] trRegBounds={regBounds[0]+dx,regBounds[3]+dy};  //region that will be visible after translation, but before zoom/unzoom  (need to compute zoom) ; we only take left and down because ratios are equals for left and right, up and down
790     float currentAlt=c.getAltitude()+c.getFocal();
791     float ratio=0;
792     //compute the mult factor for altitude to see glyph g entirely
793     if (trRegBounds[0]!=0){ratio=(g.getSize())/((float)(g.vx-trRegBounds[0]));}
794     //same for Y ; take the max of both
795     if (trRegBounds[1]!=0){
796         float tmpRatio=(g.getSize())/((float)(g.vy-trRegBounds[1]));
797         if (tmpRatio>ratio){ratio=tmpRatio;}
798     }
799     float newAlt=currentAlt*Math.abs(ratio);
800     float dAlt=newAlt-currentAlt;
801     //       animator.createCameraAnimation(d,2,new LongPoint(dx,dy),c.getID());
802     //       animator.createCameraAnimation(d,5,new Float(dAlt),c.getID());
803     Vector prms=new Vector();
804     prms.add(new Float(dAlt));prms.add(new LongPoint(dx,dy));
805     animator.createCameraAnimation(d,AnimManager.CA_ALT_TRANS_SIG,prms,c.getID());
806     return new Location(g.vx,g.vy,newAlt);
807       }
808       else return null;
809   }
810   catch (NullPointerException e){
811       System.err.println("Error:VirtualSpaceManager:centerOnGlyph: ");
812       System.err.println("Glyph g="+g);
813       System.err.println("Camera c="+c);
814       System.err.println("View v="+v);
815       if (debug){e.printStackTrace();}
816       else {System.err.println(e);}
817       return null;
818   }
819     }
820 
821     /**translates and (un)zooms a camera in order to focus on a specific rectangular region
822      *@param c Camera to be moved
823      *@param d duration of the animation in ms
824      *@param x1 coordinate of the region's west bound (in virtual space)
825      *@param y1 coordinate of the region's north bound (in virtual space)
826      *@param x2 coordinate of the region's east bound (in virtual space)
827      *@param y2 coordinate of the region's south bound (in virtual space)
828      *@return the final camera location
829      */
830     public Location centerOnRegion(Camera c,int d,long x1,long y1,long x2,long y2){
831   View v=null;
832   try {
833       v=c.getOwningView();
834       if (v!=null){
835     long[] wnes={x1,y1,x2,y2};  //wnes=west north east south
836     long dx=(wnes[2]+wnes[0])/2;  //new coords where camera should go
837     long dy=(wnes[1]+wnes[3])/2;
838     long[] regBounds=v.getVisibleRegion(c);
839     long[] trRegBounds={regBounds[0]+dx-c.posx,regBounds[3]+dy-c.posy};  //region that will be visible after translation, but before zoom/unzoom  (need to compute zoom) ; we only take left and down because we only need horizontal and vertical ratios, which are equals for left and right, up and down
840     float currentAlt=c.getAltitude()+c.getFocal();
841     float ratio=0;
842     //compute the mult factor for altitude to see all stuff on X
843     if (trRegBounds[0]!=0){ratio=(dx-wnes[0])/((float)(dx-trRegBounds[0]));}
844     //same for Y ; take the max of both
845     if (trRegBounds[1]!=0){
846         float tmpRatio=(dy-wnes[3])/((float)(dy-trRegBounds[1]));
847         if (tmpRatio>ratio){ratio=tmpRatio;}
848     }
849     float newAlt=currentAlt*Math.abs(ratio);
850     float dAlt=newAlt-currentAlt;
851     Vector prms=new Vector();
852     prms.add(new Float(dAlt));prms.add(new LongPoint(dx-c.posx,dy-c.posy));
853     animator.createCameraAnimation(d,AnimManager.CA_ALT_TRANS_SIG,prms,c.getID());
854     return new Location(dx,dy,newAlt);
855       }
856       else return null;
857   }
858   catch (NullPointerException e){
859       System.err.println("Error:VirtualSpaceManager:centerOnRegion: ");
860       System.err.println("Camera c="+c);
861       System.err.println("View v="+v);
862       if (debug){e.printStackTrace();}
863       else {System.err.println(e);}
864       return null;
865   }
866     }
867 
868     /**set the value under which a VText is drawn as a point instead of a text (considered too small to be read). Default is 0.5 (it is compared to the product of the font size by the projection value) - if you raise this value, more text that was still displayed as a string will be displayed as a segment and inversely - of course, displaying a line instead of applying affine transformations to strings is faster*/
869     public void setTextDisplayedAsSegCoef(float f){
870   textAsLineCoef=f;
871     }
872 
873     /**set the value under which a VText is drawn as a point instead of a text (considered too small to be read). Default is 0.5 (it is compared to the product of the font size by the projection value)*/
874     public float getTextDisplayedAsSegCoef(){
875   return textAsLineCoef;
876     }
877 
878 //     /**create a vector linking two glyphs - a vector is a helper that can be used in constraints (constrainable dimensions are size, position and orientation) - use with caution: vectors introduce non-linear relations in contraints that are processed outside of the solver, thus limiting the support for cycles in the constraint graph
879 //      *@param ID1 ID of glyph1 (tail)
880 //      *@param ID2 ID of glyph 2 (head)
881 //      */
882 //     public Long createHVector(Long ID1,Long ID2){return constMgr.createVect(ID1,ID2);}
883 
884 //     /**remove a helper (like vector)
885 //      *@param hID ID of helper
886 //      */
887 //     public void removeHelper(Long hID){constMgr.removeHelper(hID);}
888 
889 
890 //     /**get all constraints involving a glyph
891 //      *@param gID ID of glyph
892 //      *returns a vector of Long (IDs of constraints)
893 //      */
894 //     public Vector getConstraints(Long gID){return constMgr.getConstraints(gID);}
895 
896 //     /**destroy a constraint
897 //      *@param cID ID of constraint
898 //      */
899 //     public void removeConstraint(Long cID){constMgr.removeConstraint(cID);}
900 
901 //     /**activate an existing constraint
902 //      *@param cID ID of constraint
903 //      */
904 //     public void activateConstraint(Long cID){constMgr.activateConstraint(cID);}
905 
906 //     /**deactivate an existing constraint
907 //      *@param cID ID of constraint
908 //      */
909 //     public void deactivateConstraint(Long cID){constMgr.deactivateConstraint(cID);}
910 
911 //     /**create a constraint that links a size to a size
912 //      *@param id1 first glyph or helper ID
913 //      *@param id2 second glyph or helper ID
914 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
915 //      */
916 //     public Long createCnstrntSizeSize(Long id1,Long id2,String exp){
917 //   Vector glyphs=new Vector();glyphs.add(id1);glyphs.add(id2);
918 //   Vector attrs=new Vector();attrs.add("sz");attrs.add("sz");
919 //   return constMgr.createConstraint(glyphs,attrs,exp);
920 //     }
921 
922 //     /**create a constraint that links an orientation to an orientation
923 //      *@param id1 first glyph or helper ID
924 //      *@param id2 second glyph or helper ID
925 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
926 //      */
927 //     public Long createCnstrntOrientOrient(Long id1,Long id2,String exp){
928 //   Vector glyphs=new Vector();glyphs.add(id1);glyphs.add(id2);
929 //   Vector attrs=new Vector();attrs.add("or");attrs.add("or");
930 //   return constMgr.createConstraint(glyphs,attrs,exp);
931 //     }
932 
933 //     /**create a constraint that links a size to an orientation
934 //      *@param id1 first glyph or helper ID
935 //      *@param id2 second glyph or helper ID
936 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
937 //      */
938 //     public Long createCnstrntSizeOrient(Long id1,Long id2,String exp){
939 //   Vector glyphs=new Vector();glyphs.add(id1);glyphs.add(id2);
940 //   Vector attrs=new Vector();attrs.add("sz");attrs.add("or");
941 //   return constMgr.createConstraint(glyphs,attrs,exp);
942 //     }
943 
944 //     /**create a constraint that links a position to a position
945 //      *@param id1 first glyph or helper ID
946 //      *@param id2 second glyph or helper ID
947 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
948 //      *@param pos1 integer describing which one of x,y is involved (1=x, 2=y, 3=both)
949 //      *@param pos2 integer describing which one of x,y is involved (1=x, 2=y, 3=both)
950 //      */
951 //     public Long createCnstrntPosPos(Long id1,Long id2,String exp,int pos1,int pos2){
952 //   Vector glyphs=new Vector();
953 //   Vector attrs=new Vector();
954 //   if ((pos1>0) && (pos1<4) && (pos2>0) && (pos2<4)){
955 //       switch (pos1){
956 //       case 1:{glyphs.add(id1);attrs.add("x");break;}
957 //       case 2:{glyphs.add(id1);attrs.add("y");break;}
958 //       case 3:{glyphs.add(id1);attrs.add("x");glyphs.add(id1);attrs.add("y");break;}
959 //       }
960 //       switch (pos2){
961 //       case 1:{glyphs.add(id2);attrs.add("x");break;}
962 //       case 2:{glyphs.add(id2);attrs.add("y");break;}
963 //       case 3:{glyphs.add(id2);attrs.add("x");glyphs.add(id2);attrs.add("y");break;}
964 //       }
965 //       return constMgr.createConstraint(glyphs,attrs,exp);
966 //   }
967 //   else return null;
968 //     }
969 
970 //     /**create a constraint that links a position to a size
971 //      *@param id1 first glyph or helper ID
972 //      *@param id2 second glyph or helper ID
973 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
974 //      *@param pos1 integer describing which one of x,y is involved (1=x, 2=y, 3=both)
975 //      */
976 //     public Long createCnstrntPosSize(Long id1,Long id2,String exp,int pos1){
977 //   Vector glyphs=new Vector();
978 //   Vector attrs=new Vector();
979 //   if ((pos1>0) && (pos1<4)){
980 //       switch (pos1){
981 //       case 1:{glyphs.add(id1);attrs.add("x");break;}
982 //       case 2:{glyphs.add(id1);attrs.add("y");break;}
983 //       case 3:{glyphs.add(id1);attrs.add("x");glyphs.add(id1);attrs.add("y");break;}
984 //       }
985 //       glyphs.add(id2);attrs.add("sz");
986 //       return constMgr.createConstraint(glyphs,attrs,exp);
987 //   }
988 //   else return null;
989 //     }
990 
991 //     /**create a constraint that links a position to an orientation
992 //      *@param id1 first glyph or helper ID
993 //      *@param id2 second glyph or helper ID
994 //      *@param exp math expression of the constraint (for syntax refer to top of this page)
995 //      *@param pos1 integer describing which one of x,y is involved (1=x, 2=y, 3=both)
996 //      */
997 //     public Long createCnstrntPosOrient(Long id1,Long id2,String exp,int pos1){
998 //   Vector glyphs=new Vector();
999 //   Vector attrs=new Vector();
1000//   if ((pos1>0) && (pos1<4)){
1001//       switch (pos1){
1002//       case 1:{glyphs.add(id1);attrs.add("x");break;}
1003//       case 2:{glyphs.add(id1);attrs.add("y");break;}
1004//       case 3:{glyphs.add(id1);attrs.add("x");glyphs.add(id1);attrs.add("y");break;}
1005//       }
1006//       glyphs.add(id2);attrs.add("or");
1007//       return constMgr.createConstraint(glyphs,attrs,exp);
1008//   }
1009//   else return null;
1010//     }
1011
1012//     /**create a constraint that links a position to a color
1013//      *@param id1 first glyph or helper ID
1014//      *@param id2 second glyph or helper ID
1015//      *@param exp math expression of the constraint (for syntax refer to top of this page)
1016//      *@param pos1 integer describing which one of x,y is involved (1=x, 2=y, 3=both)
1017//      *@param pos2 integer describing which one of h,s,v is involved ()
1018//      */
1019//     public Long createCnstrntPosCol(Long id1,Long id2,String exp,int pos1,int col2){
1020//   Vector glyphs=new Vector();
1021//   Vector attrs=new Vector();
1022//   if ((pos1>0) && (pos1<4) && (col2>0) && (col2<8)){
1023//       switch (pos1){
1024//       case 1:{glyphs.add(id1);attrs.add("x");break;}
1025//       case 2:{glyphs.add(id1);attrs.add("y");break;}
1026//       case 3:{glyphs.add(id1);attrs.add("x");glyphs.add(id1);attrs.add("y");break;}
1027//       }
1028//       switch (col2){
1029//       case 1:{glyphs.add(id2);attrs.add("v");break;}
1030//       case 2:{glyphs.add(id2);attrs.add("s");break;}
1031//       case 3:{glyphs.add(id2);glyphs.add(id2);attrs.add("s");attrs.add("v");break;}
1032//       case 4:{glyphs.add(id2);attrs.add("h");break;}
1033//       case 5:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("v");break;}
1034//       case 6:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");break;}
1035//       case 7:{glyphs.add(id2);glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");attrs.add("v");break;}
1036//       }
1037//       return constMgr.createConstraint(glyphs,attrs,exp);
1038//   }
1039//   else return null;
1040//     }
1041
1042//     /**create a constraint that links a size to a color
1043//      *@param id1 first glyph or helper ID
1044//      *@param id2 second glyph or helper ID
1045//      *@param exp math expression of the constraint (for syntax refer to top of this page)
1046//      *@param col2 integer describing which one of h,s,v is involved ()
1047//      */
1048//     public Long createCnstrntSizeCol(Long id1,Long id2,String exp,int col2){
1049//   Vector glyphs=new Vector();
1050//   Vector attrs=new Vector();
1051//   if ((col2>0) && (col2<8)){
1052//       glyphs.add(id1);attrs.add("sz");
1053//       switch (col2){
1054//       case 1:{glyphs.add(id2);attrs.add("v");break;}
1055//       case 2:{glyphs.add(id2);attrs.add("s");break;}
1056//       case 3:{glyphs.add(id2);glyphs.add(id2);attrs.add("s");attrs.add("v");break;}
1057//       case 4:{glyphs.add(id2);attrs.add("h");break;}
1058//       case 5:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("v");break;}
1059//       case 6:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");break;}
1060//       case 7:{glyphs.add(id2);glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");attrs.add("v");break;}
1061//       }
1062//       return constMgr.createConstraint(glyphs,attrs,exp);
1063//   }
1064//   else return null;
1065//     }
1066
1067//     /**create a constraint that links an orientation to a color
1068//      *@param id1 first glyph or helper ID
1069//      *@param id2 second glyph or helper ID
1070//      *@param exp math expression of the constraint (for syntax refer to top of this page)
1071//      *@param col2 integer describing which one of h,s,v is involved ()
1072//      */
1073//     public Long createCnstrntOrientCol(Long id1,Long id2,String exp,int col2){
1074//   Vector glyphs=new Vector();
1075//   Vector attrs=new Vector();
1076//   if ((col2>0) && (col2<8)){
1077//       glyphs.add(id1);attrs.add("or");
1078//       switch (col2){
1079//       case 1:{glyphs.add(id2);attrs.add("v");break;}
1080//       case 2:{glyphs.add(id2);attrs.add("s");break;}
1081//       case 3:{glyphs.add(id2);glyphs.add(id2);attrs.add("s");attrs.add("v");break;}
1082//       case 4:{glyphs.add(id2);attrs.add("h");break;}
1083//       case 5:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("v");break;}
1084//       case 6:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");break;}
1085//       case 7:{glyphs.add(id2);glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");attrs.add("v");break;}
1086//       }
1087//       return constMgr.createConstraint(glyphs,attrs,exp);
1088//   }
1089//   else return null;
1090//     }
1091
1092//     /**create a constraint that links an orientation to a color
1093//      *@param id1 first glyph or helper ID
1094//      *@param id2 second glyph or helper ID
1095//      *@param exp math expression of the constraint (for syntax refer to top of this page)
1096//      *@param col2 integer describing which one of h,s,v is involved ()
1097//      */
1098//     public Long createCnstrntColCol(Long id1,Long id2,String exp,int col1,int col2){
1099//   Vector glyphs=new Vector();
1100//   Vector attrs=new Vector();
1101//   if ((col1>0) && (col1<8) && (col2>0) && (col2<8)){
1102//       switch (col1){
1103//       case 1:{glyphs.add(id1);attrs.add("v");break;}
1104//       case 2:{glyphs.add(id1);attrs.add("s");break;}
1105//       case 3:{glyphs.add(id1);glyphs.add(id1);attrs.add("s");attrs.add("v");break;}
1106//       case 4:{glyphs.add(id1);attrs.add("h");break;}
1107//       case 5:{glyphs.add(id1);glyphs.add(id1);attrs.add("h");attrs.add("v");break;}
1108//       case 6:{glyphs.add(id1);glyphs.add(id1);attrs.add("h");attrs.add("s");break;}
1109//       case 7:{glyphs.add(id1);glyphs.add(id1);glyphs.add(id1);attrs.add("h");attrs.add("s");attrs.add("v");break;}
1110//       }
1111//       switch (col2){
1112//       case 1:{glyphs.add(id2);attrs.add("v");break;}
1113//       case 2:{glyphs.add(id2);attrs.add("s");break;}
1114//       case 3:{glyphs.add(id2);glyphs.add(id2);attrs.add("s");attrs.add("v");break;}
1115//       case 4:{glyphs.add(id2);attrs.add("h");break;}
1116//       case 5:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("v");break;}
1117//       case 6:{glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");break;}
1118//       case 7:{glyphs.add(id2);glyphs.add(id2);glyphs.add(id2);attrs.add("h");attrs.add("s");attrs.add("v");break;}
1119//       }
1120//       return constMgr.createConstraint(glyphs,attrs,exp);
1121//   }
1122//   else return null;
1123//     }
1124
1125//     /**create a complex constraint
1126//      *@param v1 vector of Long IDs of glyphs to be linked
1127//      *@param v2 vector of attributes to be linked
1128//      *@param exp math expression of the constraint (for syntax refer to top of this page)
1129//      */
1130//     public Long createComplexCnstrnt(Vector v1,Vector v2,String exp){
1131//   Vector glyphs=v1;
1132//   Vector attrs=v2;
1133//   return constMgr.createConstraint(glyphs,attrs,exp);
1134//     }
1135
1136//     /**create a compound constraint
1137//      *@param v1 vector of Long IDs of constraints to be compound
1138//      */
1139//     public Long createCompoundCnstrnt(Vector v1){
1140//   return constMgr.createCompoundConstraint(v1);
1141//     }
1142
1143//     /**create stay constraint(s)
1144//      *@param v1 vector of IDs of glyph
1145//      *@param v2 vector of Strings in x,y,or,sz,h,s,v
1146//      */
1147//     public void createStayCnstrnt(Vector v1,Vector v2){
1148//   constMgr.addStay(v1,v2);
1149//     }
1150
1151//     /**remove stay constraint(s)
1152//      *@param v1 vector of IDs of glyph
1153//      *@param v2 vector of Strings in x,y,or,sz,h,s,v
1154//      */
1155//     public void removeStayCnstrnt(Vector v1,Vector v2){
1156//   constMgr.removeStay(v1,v2);
1157//     }
1158
1159    //should not be used by applications - public because accessed by Glyphs themselves when made unsensitive
1160    public void removeGlyphFromUnderMouseLists(Glyph g){
1161  VirtualSpace vs=null;
1162  try {
1163      for (Enumeration e=allVirtualSpaces.elements();e.hasMoreElements();){
1164    vs=(VirtualSpace)e.nextElement();
1165    if (vs.getAllGlyphs().contains(g)){break;}
1166      }
1167      for (Enumeration e=vs.getCameraList().elements();e.hasMoreElements();){
1168    ((View)((Camera)e.nextElement()).getOwningView()).mouse.removeGlyphFromList(g);
1169      }
1170  }
1171  catch (NullPointerException ex){}
1172    }
1173    
1174    Object activeJFrame=null;
1175    
1176    public void eventDispatched(java.awt.AWTEvent e){
1177  if (e.getID()==java.awt.event.WindowEvent.WINDOW_ACTIVATED){activeJFrame=e.getSource();}
1178    }
1179
1180}
1181
1182
1183