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 import fr.ove.utils.FontInfo;
8
9 /***
10 * A layout manager that lays the display of the nth-root.
11 *
12 * @author © 1999 DIRAT Laurent
13 * @version 2.0 22/07/1999
14 */
15 public class RootLayout extends HorizontalLayout {
16 /***
17 * According to the operator, the layout manager has to add some components (e.g. brackets, ...)
18 * or has to perform some "re-oganisation" before rendering.<BR>
19 * As soon as the layout manager is set to the display, this mehtod MUST be called with the display laid out
20 * as parameter. This method serves as well as a registering method. So all sub-classes of the instance MUST
21 * call super.initDisplay(displayToLay).
22 * @param displayToLay the display laid by the instance
23 */
24 public void initDisplay(Display displayToLay) {
25 super.initDisplay(displayToLay);
26
27 FormulaTreeStructure fts = (FormulaTreeStructure) this.displayToLay.getListener();
28
29
30 SymbolDisplay tick = new SymbolDisplay(this.displayToLay.getGraphicContext(), new SqrtTick());
31
32 tick.setIsSymbolOperatorDisplay(true);
33 this.displayToLay.add(tick);
34
35
36
37
38
39
40
41
42
43 tick.addControlListener(fts);
44
45
46 SymbolDisplay bar = new SymbolDisplay(this.displayToLay.getGraphicContext(), new Bar());
47
48 bar.setIsSymbolOperatorDisplay(true);
49 this.displayToLay.add(bar);
50
51
52
53 bar.addControlListener(fts);
54
55 this.displayToLay.computeAncestorsAttributes();
56 }
57
58 /***
59 * Updates the level of the display that is layed out.<BR>
60 * @param level the level put to the display
61 */
62 public void updateLevel(int level) {
63 Display tmp;
64
65
66 if (displayToLay.getUpdateLevel()) {
67
68 displayToLay.setLevel(level);
69 displayToLay.setUpdateLevel(false);
70
71 int i = 0;
72 int count = displayToLay.getComponentCount();
73
74
75
76
77 if (count == 4) {
78
79
80 if (((Display) displayToLay.getComponent(0)).isSymbolOperatorDisplay()) {
81 tmp = (Display) displayToLay.getComponent(3);
82
83
84
85 displayToLay.removeFromListListeners(false);
86
87 displayToLay.add(tmp, tmp, 0);
88
89
90
91 displayToLay.removeFromListListeners(true);
92
93 displayToLay.adjustRank();
94 }
95
96
97 tmp = (Display) displayToLay.getComponent(0);
98 ((DisplayLayout) tmp.getLayout()).updateLevel(level+1);
99 tmp.setUpdateLevel(false);
100
101
102
103 i++;
104 }
105
106
107
108 for (; i < count; i++) {
109 tmp = (Display) displayToLay.getComponent(i);
110 ((DisplayLayout) tmp.getLayout()).updateLevel(level);
111 tmp.setUpdateLevel(false);
112 }
113 }
114 }
115
116 /***
117 * Checks the validity of the selection.
118 */
119 public void validateSelection() {
120 SelectionEvent selEvt = new SelectionEvent(displayToLay);
121
122
123
124
125 Display tick, bar;
126 int count = displayToLay.getComponentCount();
127 if (count == 4) {
128 tick = (Display) displayToLay.getComponent(1);
129 bar = (Display) displayToLay.getComponent(2);
130 }
131 else {
132 tick = (Display) displayToLay.getComponent(0);
133 bar = (Display) displayToLay.getComponent(1);
134 }
135
136 if (tick.isSelected() || bar.isSelected()) {
137
138 displayToLay.select();
139
140 selEvt.setAction(SelectionEvent.PURGE, null);
141 displayToLay.fireSelectionEvent(selEvt);
142
143 selEvt.setAction(SelectionEvent.ADD, displayToLay);
144 displayToLay.fireSelectionEvent(selEvt);
145 }
146 else {
147 if (count == 4) {
148 Display nthRoot = (Display) displayToLay.getComponent(0);
149 Display arg = (Display) displayToLay.getComponent(3);
150 if (nthRoot.gotSelectedElements() && arg.gotSelectedElements()) {
151
152 displayToLay.select();
153
154 selEvt.setAction(SelectionEvent.PURGE, null);
155 displayToLay.fireSelectionEvent(selEvt);
156
157 selEvt.setAction(SelectionEvent.ADD, displayToLay);
158 displayToLay.fireSelectionEvent(selEvt);
159 }
160 }
161 }
162
163
164
165 Display display = displayToLay;
166 if (display.getParent() instanceof Display) {
167 display = (Display) display.getParent();
168 FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
169 if (fts.getFather() != null)
170 ((DisplayLayout) display.getLayout()).validateSelection();
171 }
172
173
174 display.repaint();
175 }
176
177 /***
178 * Checks the validity of the deselection.
179 * @param display the display to deselect.
180 */
181 public void validateDeselection(Display display) {
182 Display father = displayToLay;
183 SelectionEvent selEvt = new SelectionEvent(father);
184
185 if (father.isSelected()) {
186 father.setNotSelected();
187
188 selEvt.setAction(SelectionEvent.REMOVE, father);
189 father.fireSelectionEvent(selEvt);
190
191 Display tick, bar, arg;
192 Display nthRoot = null;
193
194 if (father.getComponentCount() == 4) {
195 nthRoot = (Display) father.getComponent(0);
196 tick = (Display) father.getComponent(1);
197 bar = (Display) father.getComponent(2);
198 arg = (Display) father.getComponent(3);
199 }
200 else {
201 tick = (Display) father.getComponent(0);
202 bar = (Display) father.getComponent(1);
203 arg = (Display) father.getComponent(2);
204 }
205
206 if ((display == tick) || (display == bar)) {
207
208 tick.setNotSelected();
209 bar.setNotSelected();
210
211
212 selEvt.setAction(SelectionEvent.ADD, arg);
213 father.fireSelectionEvent(selEvt);
214
215 if (nthRoot != null)
216 nthRoot.deselect();
217 }
218 else if (display == arg) {
219 tick.setNotSelected();
220 bar.setNotSelected();
221
222 if (nthRoot != null) {
223 selEvt.setAction(SelectionEvent.ADD, nthRoot);
224 father.fireSelectionEvent(selEvt);
225 }
226 }
227 else {
228 tick.setNotSelected();
229 bar.setNotSelected();
230 selEvt.setAction(SelectionEvent.ADD, arg);
231 father.fireSelectionEvent(selEvt);
232 }
233
234
235
236 if (father.getParent() instanceof Display) {
237 father = (Display) father.getParent();
238 FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
239 if (fts.getFather() != null)
240 ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
241 }
242
243
244
245
246 validateSelection();
247
248
249 father.repaint();
250 }
251
252 }
253
254 /***
255 * Computes the size of the display according to its children size (if any),
256 * and its different attributes.
257 * @return the size of the display.
258 */
259 public Dimension computeAttributes() {
260 updateLevel(displayToLay.getLevel());
261
262 int width = 0;
263 int height = 0;
264
265 int thickness = FontInfo.getLineThickness(displayToLay, displayToLay.getFont());
266
267 Display arg;
268 SymbolDisplay barDisplay, tickDisplay;
269 Bar bar;
270 SqrtTick tick;
271
272 int count = displayToLay.getComponentCount();
273
274 if (count == 4) {
275 tickDisplay = (SymbolDisplay) displayToLay.getComponent(1);
276 barDisplay = (SymbolDisplay) displayToLay.getComponent(2);
277 arg = (Display) displayToLay.getComponent(3);
278 }
279 else {
280 tickDisplay = (SymbolDisplay) displayToLay.getComponent(0);
281 barDisplay = (SymbolDisplay) displayToLay.getComponent(1);
282 arg = (Display) displayToLay.getComponent(2);
283 }
284
285
286 arg.invalidate();
287 arg.setComputeAttributes(true);
288 ((DisplayLayout) arg.getLayout()).computeAttributes();
289 arg.setSize(arg.getPreferredSize());
290
291
292 bar = (Bar) barDisplay.getSymbol();
293 bar.setHeight(thickness);
294 bar.setWidth(arg.getWidth() + 4);
295 barDisplay.invalidate();
296 barDisplay.setComputeAttributes(true);
297 barDisplay.setSize(barDisplay.getPreferredSize());
298
299
300
301 barDisplay.setShiftY(-arg.getAscent() - barDisplay.getDescent() );
302
303
304 arg.setShiftX(-bar.getWidth());
305
306
307 tick = (SqrtTick) tickDisplay.getSymbol();
308 tick.setThickness(thickness);
309 tick.setHeight(arg.getHeight() + thickness);
310 tick.setWidth(displayToLay.getFontMetrics(displayToLay.getFont()).stringWidth("A"));
311 tick.setAscent(arg.getAscent() + thickness);
312 tick.setDescent(arg.getDescent());
313 tickDisplay.invalidate();
314 tickDisplay.setComputeAttributes(true);
315 tickDisplay.setSize(tickDisplay.getPreferredSize());
316
317 int ascent;
318
319 if (count == 4) {
320
321
322 Display nthRoot = (Display) displayToLay.getComponent(0);
323 nthRoot.setSize(nthRoot.getPreferredSize());
324
325
326
327 nthRoot.setShiftY(-(int) Math.round(0.42f * (float) tickDisplay.getAscent()) - nthRoot.getDescent());
328 tickDisplay.setShiftX(-tickDisplay.getWidth() / 2);
329
330 width += nthRoot.getWidth() + (tickDisplay.getWidth()/2) + barDisplay.getWidth();
331 ascent = Math.max(nthRoot.getAscent() - nthRoot.getShiftY(), tickDisplay.getAscent());
332 }
333 else {
334 width += tickDisplay.getWidth() + barDisplay.getWidth();
335 ascent = tickDisplay.getAscent();
336 }
337
338 height += ascent + arg.getDescent();
339
340 displayToLay.setSize(width, height);
341 displayToLay.setAscent(ascent);
342 displayToLay.setDescent(arg.getDescent());
343
344 displayToLay.setComputeAttributes(false);
345
346 return new Dimension(width, height);
347 }
348
349
350 /***
351 * The display needs to be rebuilt. We do this.
352 */
353 public void rebuildDisplay() {
354
355
356 displayToLay.computeAncestorsAttributes();
357 }
358 }