View Javadoc

1   package fr.ove.openmath.jome.ctrlview.bidim;
2   
3   import java.awt.*;
4   import fr.ove.openmath.jome.ctrlview.bidim.DisplayLayout;
5   import fr.ove.openmath.jome.ctrlview.bidim.Display;
6   import fr.ove.openmath.jome.ctrlview.bidim.selection.events.SelectionEvent;
7   import fr.ove.openmath.jome.model.*;
8   
9   /***
10  * A layout manager that lays components of a function.
11  *
12  * @author © 1999 DIRAT Laurent
13  * @version 2.0 20/07/1999
14  */
15  public class LambdaExpLayout extends HorizontalLayout {
16      private boolean arrangeDisplay = true; // Au premier calcul, il faudra arranger les displays correctement
17      private Display enumeration = null;
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);
28          
29          // La fts associÈe au display
30          LambdaExpression fts = (LambdaExpression) this.displayToLay.getListener();
31          GraphicContext gc = this.displayToLay.getGraphicContext();
32          // Display temporaire pour manipulations
33          Display displayElems = null;
34          if (!fts.isJustFunction()) {
35              if (fts.getNbChildren() > 2) {
36                  // Alors il faut qu'on ajoute un display supplÈmentaire, qui contiendra les variables liÈes
37                  // du bind. Ce display aura un EnumerationLayout.
38                  enumeration = new BidimDisplay(gc);
39                  enumeration.addControlListener(fts);
40                  EnumerationLayout layout = new EnumerationLayout();
41                  layout.initDisplay(enumeration);
42                  enumeration.setLayout(layout);
43                  this.displayToLay.add(enumeration);
44              }
45              
46              // Le symbole de la flËche
47              SymbolDisplay arrow = new SymbolDisplay(gc, new ImageSymbol("RightArrow", this.displayToLay));
48              // Le display de la somme est le display d'un opÈrateur (on peut le considÈrer comme tel)
49              arrow.setIsSymbolOperatorDisplay(true);
50              this.displayToLay.add(arrow);
51              arrow.addControlListener(fts);
52          }
53          
54          // De part la mÈthode d'allocation des displays, si fts.isJustFunction() est vrai, alors display n'a
55          // pour le moment pas de fils.
56          // Si fts.getNbChildren() > 2, alors display contient, dans cet ordre [enumeration, arrow].
57          // Sinon, display contient seulement [arrow]
58          // Donc selon les cas, aprËs allocation complËte, display sera de la forme :
59          // [ftc, var1, var2,....] : il faut donc virer les var* (puisqu'en fait <=> fts.isJustFunction() == true)
60          // [arrow, fct, var1] : juste faire un shiftX pour que affichage soit de la forme [var1, arrow, fct]
61          // [enumeration, arrow, fct, var1, var2, ...] : il faut mettre les var* comme fils de enumeration
62          
63      }
64      
65      /***
66      * Checks the validity of the selection.
67      */
68      public void validateSelection() {
69      }
70      
71      /***
72      * Checks the validity of the deselection.
73      * @param display the display to deselect.
74      */
75      public void validateDeselection(Display display) {
76      }
77      
78      /***
79      * Computes the size of the display according to its children size (if any),
80      * and its different attributes.
81      * @return the size of the display.
82      */
83      public Dimension computeAttributes() {
84          updateLevel(displayToLay.getLevel());
85          LambdaExpression fts = (LambdaExpression) displayToLay.getListener();
86          
87          if (displayToLay.getComponentCount() > 3) {
88          //if (arrangeDisplay) {
89              if (!fts.isJustFunction()) {
90                  if (fts.getNbChildren() > 2) {
91                      // On enlËve tous les displays correspondant en fait aux variables, de displayToLay,
92                      // pour le mettre comme fils ? enumeration
93                      //Display enumeration = (Display) displayToLay.getComponent(0);
94                      Display d;
95                      for (int i = 3; i < displayToLay.getComponentCount(); ) {
96                          d = (Display) displayToLay.getComponent(i);
97                          // enumeration.add(d) appelle un displayToLay.remove(d).
98                          // remove(d), enlËve Ègalement d de la liste des listeners de l'objet (fts) qu'il Ècoutait.
99                          // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple dÈplacement de display. 
100                         d.setDoRemoveFromListListeners(false);
101                         enumeration.add(d);
102                         // On remet le comportement de suppression par dÈfault.
103                         d.setDoRemoveFromListListeners(true);
104                     }
105                 }
106             }
107             else {
108                 // On enlËve tous les displays correspondant en fait aux variables.
109                 for (int i = 1; i < displayToLay.getComponentCount(); )
110                     displayToLay.remove(i);
111             }
112             arrangeDisplay = false;
113         }        
114         
115         Dimension dim = super.computeAttributes();
116         
117         if ((!fts.isJustFunction()) && (fts.getNbChildren() == 2)) {
118             // en fait un truc du style lambda(sin(x), x), displayToLay est de a forme [arrow, sin(x), x]
119             // faut faire en sorte qsue ce soit affichÈ [x, arrow, sin(x)]
120             ((Display) displayToLay.getComponent(0)).setShiftX(((Display) displayToLay.getComponent(2)).getWidth());
121             ((Display) displayToLay.getComponent(2)).setShiftX(-dim.width);
122         }
123                 
124         return dim;
125     }
126     
127     /***
128     * The display needs to be rebuilt. We do this.
129     */
130     public void rebuildDisplay() {
131         // Il y a besoin de reconstruire le display, seulement lorsque nous avons un lambda expression avec
132         // une variable. Au dÈpart, display est de la forme [arrow, fct, var]. L'iconification modifie
133         // display de telle sorte qu'il devient [arrow, var, icon].
134         // Pour que cela colle avec le computeAttributes() il faut remettre dans l'ordre [arrox, icon, var]
135         LambdaExpression fts = (LambdaExpression) displayToLay.getListener();
136         if (!fts.isJustFunction() && (fts.getNbChildren() == 2)) {
137             Display variable = (Display) displayToLay.getComponent(1);
138             // On l'enlËve mais on ne veut pas l'enlever de la liste des listeners dont elle fait partie
139             variable.setDoRemoveFromListListeners(false);
140             displayToLay.remove(variable);
141             // On remet le comportement par dÈfaut
142             variable.setDoRemoveFromListListeners(true);
143             // On rajoute la variable ? la fin de display
144             displayToLay.add(variable);
145             
146             int count = displayToLay.getComponentCount();
147             for (int i = 0; i < count; i++)
148                 ((Display) displayToLay.getComponent(i)).setShiftX(0);
149         }
150             
151     
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 }