1 /*
2 $Id: BidimDisplay.java 706 2005-03-21 16:20:16Z guest $
3 */
4
5
6 /*
7 Copyright (C) 2001-2002 Mainline Project (I3S - ESSI - CNRS -UNSA)
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 For further information on the GNU Lesser General Public License,
24 see: http://www.gnu.org/copyleft/lesser.html
25 For further information on this library, contact: mainline@essi.fr
26 */
27
28
29 package fr.ove.openmath.jome.ctrlview.bidim;
30
31 import java.awt.*;
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34
35 import fr.ove.openmath.jome.model.*;
36 import fr.ove.openmath.jome.model.events.*;
37
38 /***
39 * The bidimensional display of the elements of the formula.
40 *
41 * @author © 1999 DIRAT Laurent
42 * @version 2.0 01/07/1999
43 */
44
45 public class BidimDisplay extends Display{
46 /***
47 * The constructor.
48 * @param graphicContext the graphic context of the display.
49 */
50 public BidimDisplay(GraphicContext graphicContext) {
51 super(graphicContext);
52 if (getDisplayAllocator() == null)
53 setDisplayAllocator(new BidimDisplayAllocator());
54 }
55
56 /***
57 * Paints the display.
58 * @param g where we paint the display.
59 */
60 public void paint(Graphics g) {
61 Color old = g.getColor();
62 Rectangle bounds = getBounds();
63 GraphicContext gc = getGraphicContext();
64
65 if (isSelected())
66 g.setColor(gc.getSelectionColor());
67 else
68 g.setColor(gc.getBackgroundColor());
69
70 g.fillRect(0, 0, bounds.width, bounds.height);
71
72 g.setColor(gc.getForegroundColor());
73
74 if (weDrawBounds())
75 g.drawRect(0, 0, bounds.width -1, bounds.height - 1);
76
77 /*
78 // on trace la baseline
79 g.setColor(Color.red);
80 g.drawLine(0, getAscent(), bounds.width, getAscent());
81 */
82
83 g.setColor(old);
84 super.paint(g);
85 }
86
87 // *****************************************************
88 // ImplÈmentation de l'interface ModelListenerController
89
90 /***
91 * Consumes (i.e. treats) the event received from the model.
92 * @param modelEvent the event to consume.
93 */
94 public void consumeModelEvent(ModelEvent modelEvent) {
95 FormulaTreeStructure fts = null;
96 int action = modelEvent.getAction();
97 switch (action) {
98 case ModelEvent.ADD :
99 // On ajoute un dispay.
100 // On rÈcupËre le FTS dont on doit ajouter, et par l? mÍme, crÈer le display
101 // qui lui est associÈ.
102 fts = (FormulaTreeStructure) modelEvent.getArgument();
103 Display newDisplay = buildDisplay(fts.getRank());
104
105 if (fts.isIcon()) {
106 SubstitutedDisplayManager iconLM = (SubstitutedDisplayManager) newDisplay.getLayout();
107 // On se trouve dans un cas particulier o?, ajouter le display de l'icone
108 // entraÓne des modifications sur le display qui le contient (i.e. l'instance courante).
109 // Il faut Èliminer tous les displays dont les fts sont iconifiÈes.
110 FormulaTreeStructure iconifiedFts = null;
111 Display iconifiedDisplay = null;
112 int nbIconified = ((Icon) fts).getNbIconified();
113 for (int i = 0; i < nbIconified; i++) {
114 // Prend une fts iconifiÈe
115 iconifiedFts = ((Icon) fts).getIconified(i);
116 // On recherche le display qui lui est associÈ
117 int count = getComponentCount();
118 for (int j = 0; j < count; j++) {
119 iconifiedDisplay = (Display) getComponent(j);
120 if (iconifiedDisplay.isDisplay(iconifiedFts))
121 break;
122 }
123
124 if (iconifiedDisplay != null) {
125 // On en garde une trace en l'ajoutant dans le LM.
126 // Utile pour la dÈsiconification.
127 iconLM.addSubstitutedDisplay(iconifiedDisplay);
128 // On l'enlËve du pËre, mais on ne veut pas qu'il soit supprimÈ
129 // de la liste des listeners qu'il Ècoute
130 iconifiedDisplay.setDoRemoveFromListListeners(false);
131 remove(iconifiedDisplay);
132 iconifiedDisplay = null;
133 }
134 }
135
136 // On reconstruit le father pour que l'ordre des displays qui le composent
137 // corresponde ? l'odre des fts dont ils sont les displays.
138 ((DisplayLayout) getLayout()).rebuildDisplay();
139 }
140
141 break;
142
143 case ModelEvent.UPDATE :
144 Container container = this;
145
146 //container.invalidate();
147
148 while (container.getParent() != null)
149 container = container.getParent();
150
151 container.validate();
152 break;
153
154 case ModelEvent.REBUILD :
155 //System.out.println("ModelEvent.REBUILD : on rebuild le display");
156 // Dans un premier temps, on regarde si la reconstruction du display n'a pas
157 // ÈtÈ demandÈe lors d'une dÈsiconification. Donc, on parcourt la liste des
158 // displays contenus dans l'instance courante pour vÈrifier si chacun est
159 // associÈ ? un ÈlÈment de la FTS. Si tel est le cas, on peut demander la
160 // reconstruction du display. Sinon, on est dans le cas de la dÈsiconification,
161 // et donc il faut rajouter dans la liste des displays de l'instance courante
162 // tous les displays qui ont ÈtÈ prÈalablement iconifiÈs.
163
164 FormulaTreeStructure theFts = (FormulaTreeStructure) getListener();
165 FormulaTreeStructure theFtsChild = null;
166 Display theFtsChildDisplay = null;
167 int nbDisplay = getComponentCount();
168 // On parcourt la liste des displays.
169 for (int i = 0; i < nbDisplay; i++) {
170 theFtsChildDisplay = (Display) getComponent(i);
171 theFtsChild = (FormulaTreeStructure) theFtsChildDisplay.getListener();
172 // Si theFtsChild est une icone et qu'elle n'appartient ? la liste des fils de son pËre
173 // (Áa veut donc dire qu'on l'a supprimÈe lors d'une dÈsiconification), on dÈsiconifie
174 if (theFtsChild.isIcon() && !theFts.hasChild(theFtsChild)) {
175 Display displaySubstituted;
176 SubstitutedDisplayManager theIconLM = (SubstitutedDisplayManager) theFtsChildDisplay.getLayout();
177 // Tous les displays qui Ètaient iconifÈs sont rajoutÈs ? l'instance courante.
178 for (int j = 0; j < theIconLM.getNbSubstitutedDisplay(); j++) {
179 displaySubstituted = theIconLM.getSubstitutedDisplay(j);
180 add(displaySubstituted);
181 // Lors de l'iconification, quand on supprime le display iconifiÈ, on ne veut
182 // pas qu'il soit enlevÈ de la liste des listeners qu'il Ècoute.
183 // Par contre, quand on revient l?, on se remet dans l'Ètat par dÈfaut qui est
184 // que l'on veut les supprimer de la liste des listeners.
185 displaySubstituted.setDoRemoveFromListListeners(true);
186 }
187 // On enlËve le display de l'icon
188 remove(theFtsChildDisplay);
189 // On rÈajuste le nombre de displays contenus dans l'instance courante.
190 nbDisplay = getComponentCount();
191 // Idem pour l'index. Puisqu'on a enlevÈ un display, si on ne dÈcrÈmente
192 // pas i, on va en sauter 1.
193 i--;
194 }
195 }
196
197 // On regarde si tous les ÈlÈments de la fts ont des displays associÈs.
198 // Sinon, il faut leur en construire un.
199 int count = theFts.getNbChildren();
200 boolean buildDisplay = true;
201 for (int i = 0; i < count; i++) {
202 buildDisplay = true;
203 theFtsChild = (FormulaTreeStructure) theFts.getChild(i);
204 for (int j = 0; j < nbDisplay; j++) {
205 theFtsChildDisplay = (Display) getComponent(j);
206 if (theFtsChildDisplay.isDisplay(theFtsChild)) {
207 buildDisplay = false;
208 break;
209 }
210 }
211 if (buildDisplay) {
212 buildDisplay(theFtsChild.getRank());
213 }
214 }
215
216 // Maintenant on peut reconstruire le display, en fait le bon rÈagencement des
217 // displays contenus dans l'instance.
218 ((DisplayLayout) getLayout()).rebuildDisplay();
219 break;
220
221 case ModelEvent.CREATE :
222 buildDisplay();
223 invalidate();
224 setComputeAttributes(true);
225 validate();
226 repaint();
227 break;
228
229 case ModelEvent.CLEAR :
230 removeAll();
231 }
232 }
233
234 // *** Fin de l'interface ModelListenerController ***
235 // **************************************************
236 }