View Javadoc

1   package fr.ove.openmath.jome.ctrlview.bidim;
2   
3   import java.awt.*;
4   import java.util.*;
5   import fr.ove.openmath.jome.ctrlview.bidim.Display;
6   import fr.ove.openmath.jome.ctrlview.bidim.DisplayLayout;
7   import fr.ove.openmath.jome.ctrlview.bidim.selection.events.SelectionEvent;
8   import fr.ove.openmath.jome.model.*;
9   import fr.ove.utils.FontInfo;
10  
11  /***
12  * Temporaire
13  *
14  * @author © 1999 DIRAT Laurent
15  * @version 2.0 06/09/1999
16  */
17  public class IntervalLayout extends EnclosingLayout {
18      /***
19      * According to the operator, the layout manager has to add some components (e.g. brackets, ...)
20      * or has to perform some "re-oganisation" before rendering.<BR>
21      * As soon as the layout manager is set to the display, this mehtod MUST be called with the display laid out
22      * as parameter. This method serves as well as a registering method. So all sub-classes of the instance MUST
23      * call super.initDisplay(displayToLay).
24      * @param displayToLay the display laid by the instance
25      */
26      public void initDisplay(Display displayToLay) {
27          super.initDisplay(displayToLay);  // Par cet appel, on ajoute dans displayToLay les crochets
28          // On va maintenant y rajouter un display, dans lequel on va mettre les displays correspondants
29          // aux bornes de l'intervalle, display ? qui on va affecter un SeparatorOperatorLayout, qui va se charger
30          // d'afficher entre chacun des ÈlÈments une virgule (un sÈparateur)
31          Display boundsDisplay = new BidimDisplay(displayToLay.getGraphicContext());
32          // On met un listener ? boundsDisplay
33          // En fait, il n'y en a pas besoin, dans le sens o? il n'y a pas spÈcifiquement de fts qui
34          // Ècoute le comportement de ce display. NÈanmoins, il s'avËre nÈcessaire qu'il en ait
35          // un, par exemple lors de l'iconification, car c'est le display qui reÁoit la demande
36          // d'iconification qui envoie l'ÈvÈnement correspondant ? la FTS. Or si ce display n'a pas
37          // d'Ècouteur, alors pb. Par cohÈrence, l'Ècouteur du display d'opÈrateur, est le fts qui
38          // reprÈsente cette opÈration. Par contre, la fts en question, n'Ècoute pas le display
39          // d'opÈrateur.
40          boundsDisplay.addControlListener((FormulaTreeStructure) displayToLay.getListener());
41          
42          SeparatorOperatorLayout layout = new SeparatorOperatorLayout();
43          layout.initDisplay(boundsDisplay);
44          boundsDisplay.setLayout(layout);
45          
46          // On l'ajoute comme fils ? display
47          this.displayToLay.add(boundsDisplay);
48      }
49      
50      /***
51      * Returns the opening
52      */
53      public SymbolDisplay createOpening() {
54          // On rÈcupËre le fts associÈ (listener) au display.
55          KaryOperator fts = (KaryOperator) displayToLay.getListener();
56          
57          SymbolDisplay bracket = new SymbolDisplay(displayToLay.getGraphicContext(), 
58                                                    new SquaredBracketSymbol(fts.getTheOperator(), displayToLay));            
59          // Le display de l'accolade est le display d'un opÈrateur (on peut le considÈrer comme tel)
60          bracket.setIsSymbolOperatorDisplay(true);
61          
62          return bracket;
63      }
64      
65      /***
66      * Returns the closing
67      */
68      public SymbolDisplay createClosing() {
69          // On rÈcupËre le fts associÈ (listener) au display.
70          KaryOperator fts = (KaryOperator) displayToLay.getListener();
71          
72          SymbolDisplay bracket = new SymbolDisplay(displayToLay.getGraphicContext(), 
73                                                    new SquaredBracketSymbol(fts.getEnding(), displayToLay));            
74          // Le display de l'accolade est le display d'un opÈrateur (on peut le considÈrer comme tel)
75          bracket.setIsSymbolOperatorDisplay(true);
76          
77          return bracket;
78      }    
79      
80      /***
81      * Computes the size of the display according to its children size (if any),
82      * and its different attributes.
83      * @return the size of the display.
84      */
85      public Dimension computeAttributes() {
86          Display display = null;
87          
88          if (displayToLay.getComponentCount() > 3) {
89              Display boundsDisplay = (Display) displayToLay.getComponent(2);
90              Display d;
91              for (int i = 3; i < displayToLay.getComponentCount(); ) {
92                  d = (Display) displayToLay.getComponent(i);
93                  // elementsDisplay.add(d) appelle un displayToLay.remove(d).
94                  // remove(d), enlËve Ègalement d de la liste des listeners de l'objet (fts) qu'il Ècoutait.
95                  // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple dÈplacement de display. 
96                  d.setDoRemoveFromListListeners(false);
97                  boundsDisplay.add(d);
98                  // On remet le comportement de suppression par dÈfault.
99                  d.setDoRemoveFromListListeners(true);
100             }
101         }
102         
103         SymbolDisplay leftBracket = (SymbolDisplay) displayToLay.getComponent(0);
104         SquaredBracketSymbol leftSymbol = (SquaredBracketSymbol) leftBracket.getSymbol();
105         SymbolDisplay rightBracket = (SymbolDisplay) displayToLay.getComponent(1);
106         SquaredBracketSymbol rightSymbol = (SquaredBracketSymbol) rightBracket.getSymbol();
107         
108         // On met la hauteur ? 0, pour que dans tous les cas, le super.computeAttributes() ne soit pas
109         // biaisÈe par une Èventuelle nouvelle taille des ÈlÈments qui composent la liste.
110         // Comme c'est plus loin qu'on leur fixe la taille....
111         leftSymbol.setHeight(0);
112         rightSymbol.setHeight(0);
113         
114         Dimension dim = super.computeAttributes();
115         
116         // Par contre, par rapport ? comment est calculÈe la taille des accolades, dim comprend
117         // dÈj? la taille des accolades
118         int ascent = displayToLay.getAscent();
119         int descent = displayToLay.getDescent();
120         int height =  displayToLay.getHeight();
121         int thickness = FontInfo.getLineThickness(displayToLay, displayToLay.getFont());
122         
123         leftSymbol.setAscent(ascent);
124         leftSymbol.setDescent(descent);
125         leftSymbol.setHeight(height);
126         leftSymbol.setThickness(thickness);
127         leftBracket.setComputeAttributes(true);
128         leftBracket.invalidate();
129         leftBracket.setSize(leftBracket.getPreferredSize());
130 
131         rightSymbol.setAscent(ascent);
132         rightSymbol.setDescent(descent);
133         rightSymbol.setHeight(height);
134         rightSymbol.setThickness(thickness);
135         rightBracket.setComputeAttributes(true);
136         rightBracket.invalidate();
137         rightBracket.setSize(rightBracket.getPreferredSize());
138         
139         // Cette taille l? correspond au dÈcalage qu'il faut appliquer ? la derniËre accolade
140         rightBracket.setShiftX(dim.width - 2*rightBracket.getWidth());
141         // Mais il faut l'enlever au premier terme de la liste qui doit Ítre contre la premiËre
142         // accolade (because HonrizontalLayout)
143         ((Display) displayToLay.getComponent(2)).setShiftX(-rightBracket.getShiftX() - rightBracket.getWidth());
144         
145         return dim;
146     }
147     
148     /***
149     * The display needs to be rebuilt. We do this.
150     */
151     public void rebuildDisplay() {
152         // La taille des displays est probablement diffÈrente de ceux qui Ètaient
153         // prÈcÈdemment. On demande alors le recalcul des display ancÍtres.
154         displayToLay.computeAncestorsAttributes();
155     }
156    
157 }