1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package fr.ove.openmath.jome.ctrlview.bidim;
30
31 import java.awt.*;
32 import fr.ove.openmath.jome.ctrlview.bidim.Display;
33 import fr.ove.openmath.jome.ctrlview.bidim.DisplayLayout;
34 import fr.ove.openmath.jome.ctrlview.bidim.HorizontalLayout;
35 import fr.ove.openmath.jome.ctrlview.bidim.selection.events.SelectionEvent;
36 import fr.ove.openmath.jome.model.*;
37
38 /***
39 * A layout manager that lays components to place them as the different elements like the operator
40 * sum does.<BR>
41 * The different elements are contained in the display in the following order :
42 * <UL>
43 * <LI>the symbol of the operator.</LI>
44 * <LI>the expression.</LI>
45 * <LI>the lower bound.</LI>
46 * <LI>the upper bound.</LI>
47 *</UL>
48 *
49 * Bounds are optional elements.
50 *
51 * @author © 1999 DIRAT Laurent
52 * @version 2.0 16/12/1999
53 */
54 public class UnderOverLayout extends HorizontalLayout{
55 /***
56 * According to the operator, the layout manager has to add some components (e.g. brackets, ...)
57 * or has to perform some "re-oganisation" before rendering.<BR>
58 * As soon as the layout manager is set to the display, this mehtod MUST be called with the display laid out
59 * as parameter. This method serves as well as a registering method. So all sub-classes of the instance MUST
60 * call super.initDisplay(displayToLay).
61 * @param displayToLay the display laid by the instance
62 */
63 public void initDisplay(Display displayToLay) {
64 super.initDisplay(displayToLay);
65 }
66
67 /***
68 * Updates the level of the display that is layed out.<BR>
69 * @param level the level put to the display
70 */
71 public void updateLevel(int level) {
72 Display tmp;
73
74 if (displayToLay.getUpdateLevel()) {
75 displayToLay.updateChildrenLevel();
76
77
78 displayToLay.setLevel(level);
79 displayToLay.setUpdateLevel(false);
80
81
82 tmp = (Display) displayToLay.getComponent(0);
83 ((DisplayLayout) tmp.getLayout()).updateLevel(level);
84 tmp.setUpdateLevel(false);
85
86 int count = displayToLay.getComponentCount();
87
88 if (count > 1) {
89
90 tmp = (Display) displayToLay.getComponent(1);
91 ((DisplayLayout) tmp.getLayout()).updateLevel(level+1);
92 tmp.setUpdateLevel(false);
93
94 if (count > 2) {
95
96 tmp = (Display) displayToLay.getComponent(2);
97 ((DisplayLayout) tmp.getLayout()).updateLevel(level+1);
98 tmp.setUpdateLevel(false);
99 }
100 }
101 }
102 }
103
104 /***
105 * Checks the validity of the selection.
106 * @param display the display to select.
107 */
108 public void validateSelection() {
109 Display symbol = (Display) displayToLay.getComponent(0);
110 Display expression = (Display) displayToLay.getComponent(1);
111
112 int count = displayToLay.getComponentCount();
113
114
115 if (symbol.isSelected())
116 displayToLay.select();
117 else if (count > 2) {
118 Display lower = (Display) displayToLay.getComponent(2);
119 Display upper;
120
121 if (lower.gotSelectedElements()) {
122 if (expression.gotSelectedElements())
123 displayToLay.select();
124 else if (count > 3) {
125 upper = (Display) displayToLay.getComponent(3);
126 if (upper.gotSelectedElements())
127 displayToLay.select();
128 }
129 }
130 else if (count > 3) {
131 upper = (Display) displayToLay.getComponent(3);
132 if (upper.gotSelectedElements()) {
133 if (expression.gotSelectedElements())
134 displayToLay.select();
135 }
136 }
137 }
138
139
140
141 if (displayToLay.isSelected()) {
142 SelectionEvent selEvt = new SelectionEvent(displayToLay);
143
144 selEvt.setAction(SelectionEvent.PURGE, null);
145 displayToLay.fireSelectionEvent(selEvt);
146
147 selEvt.setAction(SelectionEvent.ADD, displayToLay);
148 displayToLay.fireSelectionEvent(selEvt);
149 }
150
151
152
153 Display display = displayToLay;
154 if (display.getParent() instanceof Display) {
155 display = (Display) display.getParent();
156
157 FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
158 if (fts.getFather() != null)
159 ((DisplayLayout) display.getLayout()).validateSelection();
160 }
161
162
163 display.repaint();
164 }
165
166 /***
167 * Checks the validity of the deselection.
168 * @param display the display to deselect.
169 */
170 public void validateDeselection(Display display) {
171 Display father = displayToLay;
172 SelectionEvent selEvt = new SelectionEvent(father);
173
174 if (father.isSelected()) {
175 father.setNotSelected();
176
177 selEvt.setAction(SelectionEvent.REMOVE, father);
178 father.fireSelectionEvent(selEvt);
179
180 Display expression = (Display) father.getComponent(1);
181 int count = father.getComponentCount();
182 if (display != expression) {
183
184
185 selEvt.setAction(SelectionEvent.ADD, expression);
186 father.fireSelectionEvent(selEvt);
187 }
188
189 ((Display) father.getComponent(0)).setNotSelected();
190 if (count > 2) {
191 ((Display) father.getComponent(2)).deselect();
192 if (count > 3)
193 ((Display) father.getComponent(3)).deselect();
194 }
195
196
197 if (father.getParent() instanceof Display) {
198 father = (Display) father.getParent();
199 FormulaTreeStructure fts = (FormulaTreeStructure) father.getListener();
200 if (fts.getFather() != null)
201 ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
202 }
203
204
205
206 validateSelection();
207
208
209 father.repaint();
210 }
211 }
212
213 /***
214 * Computes the size of the display according to its children size (if any),
215 * and its different attributes.
216 * @return the size of the display.
217 */
218 public Dimension computeAttributes() {
219 int ascent = 0;
220 int descent = 0;
221
222 updateLevel(displayToLay.getLevel());
223
224 int width = 0;
225 int height = 0;
226
227 Display symbol, lower, upper;
228 int gap = 2;
229
230
231 symbol = (Display) displayToLay.getComponent(0);
232 symbol.setSize(symbol.getPreferredSize());
233
234
235 int width1 = symbol.getWidth();
236
237 int count = displayToLay.getComponentCount();
238 if (count > 1) {
239
240 lower = (Display) displayToLay.getComponent(1);
241 lower.setSize(lower.getPreferredSize());
242 lower.setShiftY(symbol.getDescent() + lower.getAscent() + gap);
243
244 width1 = Math.max(lower.getWidth(), width1);
245
246 if (count > 2 ) {
247
248 upper = (Display) displayToLay.getComponent(2);
249 upper.setSize(upper.getPreferredSize());
250
251 width1 = Math.max(upper.getWidth(), width1);
252
253 upper.setShiftX(-(lower.getWidth() + upper.getWidth()) / 2);
254 upper.setShiftY(-(symbol.getAscent() + upper.getDescent() + gap));
255
256 ascent = symbol.getAscent() + upper.getHeight() + gap;
257 }
258 else {
259 ascent = symbol.getAscent();
260 }
261
262 symbol.setShiftX((width1 - symbol.getWidth()) / 2);
263
264 lower.setShiftX(-(symbol.getWidth() + lower.getWidth())/2);
265
266 descent = symbol.getDescent() + lower.getHeight() + gap;
267 }
268 else {
269 ascent = symbol.getAscent();
270 descent = symbol.getDescent();
271 }
272
273 displayToLay.setAscent(ascent);
274 displayToLay.setDescent(descent);
275
276 width += width1 + 4*gap;
277
278 height += ascent + descent;
279 displayToLay.setSize(width , height);
280
281 displayToLay.setComputeAttributes(false);
282 return new Dimension(width, height);
283 }
284
285 /***
286 * The display needs to be rebuilt. We do this.
287 */
288 public void rebuildDisplay() {
289
290
291
292
293
294 displayToLay.computeAncestorsAttributes();
295 }
296
297 }