View Javadoc

1   package fr.ove.openmath.jome.ctrlview.bidim;
2   
3   import java.awt.*;
4   import fr.ove.openmath.jome.ctrlview.bidim.*;
5   import fr.ove.openmath.jome.ctrlview.bidim.selection.events.SelectionEvent;
6   import fr.ove.openmath.jome.model.*;
7   
8   /***
9   * A layout manager that lays components for the denominator of a differentiation.
10  *
11  * @author © 1999 DIRAT Laurent
12  * @version 2.0 15/10/1999
13  */
14  public class DifferentiationLayout extends HorizontalLayout {
15      private boolean arrangeDisplay = true; // Au premier calcul, il faudra arranger les displays correctement
16      private Display fracDisplay = null;
17      
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          Differentiation diff = (Differentiation) this.displayToLay.getListener();
30          diff.computeOrder();
31          
32          // Allocation d'un display, qui va correspondre ? la partie fraction de la reprÈsentation
33          fracDisplay = new BidimDisplay(displayToLay.getGraphicContext());
34          // On met un listener ? fracDisplay
35          // En fait, il n'y en a pas besoin, dans le sens o? il n'y a pas spÈcifiquement de fts qui
36          // Ècoute le comportement de ce display. NÈanmoins, il s'avËre nÈcessaire qu'il en ait
37          // un, par exemple lors de l'iconification, car c'est le display qui reÁoit la demande
38          // d'iconification qui envoie l'ÈvÈnement correspondant ? la FTS. Or si ce display n'a pas
39          // d'Ècouteur, alors pb. Par cohÈrence, l'Ècouteur du display d'opÈrateur, est le fts qui
40          // reprÈsente cette opÈration. Par contre, la fts en question, n'Ècoute pas le display
41          // d'opÈrateur.
42          fracDisplay.addControlListener(diff);
43          // On lui met dont un FractionLayout
44          FractionLayout layout = new FractionLayout();
45          layout.initDisplay(fracDisplay);
46          fracDisplay.setLayout(layout);
47          // On l'ajoute comme fils ? display
48          this.displayToLay.add(fracDisplay);
49      }
50      
51      /***
52      * Checks the validity of the selection.
53      */
54      public void validateSelection() {
55          SelectionEvent selEvt = new SelectionEvent(displayToLay);
56  
57          Display derivator = (Display) displayToLay.getComponent(0);
58          Display func = (Display) displayToLay.getComponent(1);
59          // Si le display de ce qui est la partie fraction de la dÈrivÈe (derivator) est sÈlectionnÈe,
60          // alors on sÈlectionne tout.
61          // Si la function et dÈrivator ont qque chose de sÈlectionnÈ, alors on sÈlectionne tout.
62          if (derivator.isSelected() || (func.gotSelectedElements() && derivator.gotSelectedElements())) {
63              displayToLay.select();
64              // On purge la liste des ÈlÈments sÈlectionnÈs.
65              selEvt.setAction(SelectionEvent.PURGE, null);
66              displayToLay.fireSelectionEvent(selEvt);
67              // On y ajoute l'instance dans la liste des sÈlectionnÈs
68              selEvt.setAction(SelectionEvent.ADD, displayToLay);
69              displayToLay.fireSelectionEvent(selEvt);
70          }
71          
72          // On a vÈrifiÈ la validitÈ de la sÈlection de l'opÈrateur. On doit maitenant
73          // la contrÙler au niveau supÈrieur, au niveau du pËre.
74          Display display = displayToLay;
75          if (displayToLay.getParent() instanceof Display) {
76              display = (Display) displayToLay.getParent();
77              //if (!(display.getListener() instanceof Formula))
78              FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
79              if (fts.getFather() != null)
80                  ((DisplayLayout) display.getLayout()).validateSelection();
81          }
82  
83          // On met ? jour l'affichage.
84          display.repaint();
85      }
86      
87      /***
88      * Checks the validity of the deselection.
89      * @param display the display to deselect.
90      */
91      public void validateDeselection(Display display) {
92          // father est le display de l'opÈrateur unaire.
93          Display father = displayToLay;
94          Display tmp;
95          SelectionEvent selEvt = new SelectionEvent(father);
96          
97          // Si l'opÈrateur en entier est sÈlectionnÈ, il faut le dÈsÈlectionner
98          if (father.isSelected()) {
99              father.deselect();
100             // On enlËve le display pËre de la liste des display sÈlectionnÈs.
101             selEvt.setAction(SelectionEvent.REMOVE, father);
102             father.fireSelectionEvent(selEvt);
103             
104             // Si display est l'opÈrateur (on vient de dÈselectionner l'opÈrateur), alors
105             // on ajoute l'opÈrande dans la liste des sÈlectionnÈs.
106             if (display == displayToLay.getComponent(0)) {
107                 ((Display) displayToLay.getComponent(1)).select();
108                 selEvt.setAction(SelectionEvent.ADD, (Display) displayToLay.getComponent(1));
109                 father.fireSelectionEvent(selEvt);
110             }                
111             
112             // Comme pour la sÈlection, on contrÙle la validitÈ de la dÈsÈlection.
113             if (father.getParent() instanceof Display) {
114                 father = (Display) father.getParent();
115                 //((DisplayLayout) father.getLayout()).validateDeselection((Display) display.getParent());
116                 if (!(father.getListener() instanceof Formula))
117                     ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
118             }
119             
120             // HÈ oui, on contrÙle la validitÈ de la sÈlection... dans une dÈsÈlection.
121             // Toujours le mÍme pb, est-ce que le nouvel Ètat de la sÈlection (aprËs
122             // dÈsÈlection donc) est syntaxiquement cohÈrent ?
123             validateSelection();
124             
125             // On met ? jour l'affichage.
126             father.repaint();
127         }        
128     }
129         
130     
131     /***
132     * Computes the size of the display according to its children size (if any),
133     * and its different attributes.
134     * @return the size of the display.
135     */
136     public Dimension computeAttributes() {
137         VarDiffLayout varDiffLayout;
138         updateLevel(displayToLay.getLevel());
139         
140         //if (arrangeDisplay) {
141         if (displayToLay.getComponentCount() > 3) {
142             // Dans l'ordre, displayToLay contient [fracDisplay, numFrac, fct, var1, var2, ...]
143             // Il faut mettre numFrac, comme fils de fracDisplay (qui ? ce stade ne contient que le display
144             // de la barre de fraction.
145             // Il faut creer un display avec comme layout DenominatorDiffLayout, et y ajouter tous les vari.
146             // Ensuite, ajouter ce display ? fracDisplay.
147             // On obtient donc displayToLay = [fracDisplay, fct]
148             // avec fracDisplay = [barDisplay, numFrac, [var1, var2, ...]]
149             // Le display de chacun des vari est en fait le display d'un slot. On remplace le SlotLayout, par
150             // un VarDiffLayout, pour que le "d" (ou le delta) soit rajoutÈ devant.
151             
152             Display d;
153             d = (Display) displayToLay.getComponent(1);
154             // fracDisplay.add(d) appelle un displayToLay.remove(d).
155             // remove(d), enlËve Ègalement d de la liste des listeners de l'objet (fts) qu'il Ècoutait.
156             // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple dÈplacement de display. 
157             d.setDoRemoveFromListListeners(false);
158             fracDisplay.add(d);
159             d.setDoRemoveFromListListeners(true);
160             //displayToLay contient [fracDisplay, fct, var1, var2, ...]
161             int count = displayToLay.getComponentCount();
162             Differentiation diff = (Differentiation) displayToLay.getListener();
163             if (count == 3) {
164                 // Ca veut dire que l'on a une dÈrivÈe du premier ordre : [fracDisplay, fct, var1]
165                 // On a juste ? mettre le display de var1 dans fracDisplay
166                 d = (Display) displayToLay.getComponent(2);
167                 // On modifie le layout, qui doit Ítre un slotLayout, par un VarDiffLayout.
168                 varDiffLayout = new VarDiffLayout(diff.isPartial());
169                 varDiffLayout.initDisplay(d);
170                 d.setLayout(varDiffLayout);
171                 // fracDisplay.add(d) appelle un displayToLay.remove(d).
172                 // remove(d), enlËve Ègalement d de la liste des listeners de l'objet (fts) qu'il Ècoutait.
173                 // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple dÈplacement de display. 
174                 d.setDoRemoveFromListListeners(false);
175                 fracDisplay.add(d);
176                 d.setDoRemoveFromListListeners(true);
177             }
178             else {
179                 // Ca veut dire que l'on a une dÈrivÈe d' ordre > 1 : [fracDisplay, fct, var1, var2, ...]
180                 // Il faut crÈer un display pour le dÈnominateur
181                 Display den = new BidimDisplay(displayToLay.getGraphicContext());
182                 // On met un listener ? den
183                 // En fait, il n'y en a pas besoin, dans le sens o? il n'y a pas spÈcifiquement de fts qui
184                 // Ècoute le comportement de ce display. NÈanmoins, il s'avËre nÈcessaire qu'il en ait
185                 // un, par exemple lors de l'iconification, car c'est le display qui reÁoit la demande
186                 // d'iconification qui envoie l'ÈvÈnement correspondant ? la FTS. Or si ce display n'a pas
187                 // d'Ècouteur, alors pb. Par cohÈrence, l'Ècouteur du display d'opÈrateur, est le fts qui
188                 // reprÈsente cette opÈration. Par contre, la fts en question, n'Ècoute pas le display
189                 // d'opÈrateur.
190                 den.addControlListener(diff);
191                 
192                 DenominatorDiffLayout denLayout = new DenominatorDiffLayout();
193                 denLayout.initDisplay(den);
194                 den.setLayout(denLayout);
195                 
196                 for (int i = 2; i < displayToLay.getComponentCount(); ) {
197                     d = (Display) displayToLay.getComponent(i);
198                     // On modifie le layout, qui doit Ítre un slotLayout, par un VarDiffLayout.
199                     varDiffLayout = new VarDiffLayout(diff.isPartial());
200                     varDiffLayout.initDisplay(d);
201                     d.setLayout(varDiffLayout);
202                     // den.add(d) appelle un displayToLay.remove(d).
203                     // remove(d), enlËve Ègalement d de la liste des listeners de l'objet (fts) qu'il Ècoutait.
204                     // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple dÈplacement de display. 
205                     d.setDoRemoveFromListListeners(false);
206                     den.add(d);
207                     // On remet le comportement de suppression par dÈfault.
208                     d.setDoRemoveFromListListeners(true);
209                 }
210                 // On ajoute maintenant le dÈnominateur dans fracDisplay
211                 fracDisplay.add(den);
212             }
213         }        
214         
215         // On a donc displayToLay = [fracDisplay, fct]
216         // avec fracDisplay = [barDisplay, numFrac, [var1, var2, ...]]
217         ((Display) displayToLay.getComponent(1)).setShiftX(5);
218         Dimension dim = super.computeAttributes();
219         
220         return new Dimension(dim.width + 5, dim.height);
221     }
222     
223     /***
224     * The display needs to be rebuilt. We do this.
225     */
226     public void rebuildDisplay() {
227         // La taille des displays est probablement diffÈrente de ceux qui Ètaient
228         // prÈcÈdemment. On demande alors le recalcul des display ancÍtres.
229         displayToLay.computeAncestorsAttributes();
230     }
231 
232 }