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 }