Back to index

wims  3.65+svn20090927
BidimDisplay.java
Go to the documentation of this file.
00001 /*
00002 $Id: BidimDisplay.java,v 1.3 2003/02/18 11:48:46 sander Exp $
00003 */
00004 
00005 
00006 /*
00007 Copyright (C) 2001-2002 Mainline Project (I3S - ESSI - CNRS -UNSA)
00008 
00009 This library is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU Lesser General Public
00011 License as published by the Free Software Foundation; either
00012 version 2.1 of the License, or (at your option) any later version.
00013 
00014 This library is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public
00020 License along with this library; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023 For further information on the GNU Lesser General Public License,
00024 see: http://www.gnu.org/copyleft/lesser.html
00025 For further information on this library, contact: mainline@essi.fr
00026 */
00027 
00028 
00029 package fr.ove.openmath.jome.ctrlview.bidim;
00030 
00031 import java.awt.*;
00032 import fr.ove.openmath.jome.model.*;
00033 import fr.ove.openmath.jome.model.events.*;
00034 import fr.ove.openmath.jome.ctrlview.bidim.Display;
00035 import fr.ove.openmath.jome.ctrlview.bidim.BidimDisplayAllocator;
00036 
00044 public class BidimDisplay extends Display {
00049     public BidimDisplay(GraphicContext graphicContext) {
00050         super(graphicContext);
00051         if (getDisplayAllocator() == null)
00052             setDisplayAllocator(new BidimDisplayAllocator());
00053     }
00054     
00059     public void paint(Graphics g) {
00060         Color old = g.getColor();
00061         Rectangle bounds = getBounds();
00062         GraphicContext gc = getGraphicContext();
00063         
00064         if (isSelected())
00065             g.setColor(gc.getSelectionColor());
00066         else
00067             g.setColor(gc.getBackgroundColor());
00068             
00069         g.fillRect(0, 0, bounds.width, bounds.height);
00070         
00071         g.setColor(gc.getForegroundColor());
00072         
00073         if (weDrawBounds())
00074             g.drawRect(0, 0, bounds.width -1, bounds.height - 1);
00075         
00076         /*
00077         // on trace la baseline
00078         g.setColor(Color.red);
00079         g.drawLine(0, getAscent(), bounds.width, getAscent());
00080         */
00081                 
00082         g.setColor(old);
00083         super.paint(g);
00084     }
00085     
00086     // *****************************************************
00087     // Implémentation de l'interface ModelListenerController
00088     
00093     public void consumeModelEvent(ModelEvent modelEvent) {
00094         FormulaTreeStructure fts = null;
00095         int action = modelEvent.getAction();
00096         switch (action) {
00097             case ModelEvent.ADD :
00098                 // On ajoute un dispay.
00099                 // On récupère le FTS dont on doit ajouter, et par là même, créer le display
00100                 // qui lui est associé.
00101                 fts = (FormulaTreeStructure) modelEvent.getArgument();
00102                 Display newDisplay = buildDisplay(fts.getRank());
00103                 
00104                 if (fts.isIcon()) {
00105                     SubstitutedDisplayManager iconLM = (SubstitutedDisplayManager) newDisplay.getLayout();
00106                     // On se trouve dans un cas particulier où, ajouter le display de l'icone
00107                     // entraîne des modifications sur le display qui le contient (i.e. l'instance courante).
00108                     // Il faut éliminer tous les displays dont les fts sont iconifiées.
00109                     FormulaTreeStructure iconifiedFts = null;
00110                     Display iconifiedDisplay = null;
00111                     int nbIconified = ((Icon) fts).getNbIconified();
00112                     for (int i = 0; i < nbIconified; i++) {
00113                         // Prend une fts iconifiée
00114                         iconifiedFts = ((Icon) fts).getIconified(i);
00115                         // On recherche le display qui lui est associé
00116                         int count = getComponentCount();
00117                         for (int j = 0; j < count; j++) {
00118                             iconifiedDisplay = (Display) getComponent(j);
00119                             if (iconifiedDisplay.isDisplay(iconifiedFts))
00120                                 break;
00121                         }
00122                         
00123                         if (iconifiedDisplay != null) {
00124                             // On en garde une trace en l'ajoutant dans le LM.
00125                             // Utile pour la désiconification.
00126                             iconLM.addSubstitutedDisplay(iconifiedDisplay);
00127                             // On l'enlève du père, mais on ne veut pas qu'il soit supprimé
00128                             // de la liste des listeners qu'il écoute
00129                             iconifiedDisplay.setDoRemoveFromListListeners(false);
00130                             remove(iconifiedDisplay);
00131                             iconifiedDisplay = null;
00132                         }
00133                     }
00134                     
00135                     // On reconstruit le father pour que l'ordre des displays qui le composent
00136                     // corresponde à l'odre des fts dont ils sont les displays.
00137                     ((DisplayLayout) getLayout()).rebuildDisplay();
00138                 }
00139 
00140                 break;
00141                 
00142             case ModelEvent.UPDATE :
00143                 Container container = this;
00144                 
00145                 //container.invalidate();
00146                 
00147                 while (container.getParent() != null)
00148                     container = container.getParent();
00149                     
00150                 container.validate();
00151                 break;
00152                 
00153             case ModelEvent.REBUILD :
00154                 //System.out.println("ModelEvent.REBUILD : on rebuild le display");
00155                 // Dans un premier temps, on regarde si la reconstruction du display n'a pas
00156                 // été demandée lors d'une désiconification. Donc, on parcourt la liste des
00157                 // displays contenus dans l'instance courante pour vérifier si chacun est
00158                 // associé à un élément de la FTS. Si tel est le cas, on peut demander la 
00159                 // reconstruction du display. Sinon, on est dans le cas de la désiconification,
00160                 // et donc il faut rajouter dans la liste des displays de l'instance courante
00161                 // tous les displays qui ont été préalablement iconifiés.
00162                 
00163                 FormulaTreeStructure theFts = (FormulaTreeStructure) getListener();
00164                 FormulaTreeStructure theFtsChild = null;
00165                 Display theFtsChildDisplay = null;
00166                 int nbDisplay = getComponentCount();
00167                 // On parcourt la liste des displays.
00168                 for (int i = 0; i < nbDisplay; i++) {
00169                     theFtsChildDisplay = (Display) getComponent(i);
00170                     theFtsChild = (FormulaTreeStructure) theFtsChildDisplay.getListener();
00171                     // Si theFtsChild est une icone et qu'elle n'appartient à la liste des fils de son père
00172                     // (ça veut donc dire qu'on l'a supprimée lors d'une désiconification), on désiconifie
00173                     if (theFtsChild.isIcon() && !theFts.hasChild(theFtsChild)) {
00174                         Display displaySubstituted;
00175                         SubstitutedDisplayManager theIconLM = (SubstitutedDisplayManager) theFtsChildDisplay.getLayout();
00176                         // Tous les displays qui étaient iconifés sont rajoutés à l'instance courante.
00177                         for (int j = 0; j < theIconLM.getNbSubstitutedDisplay(); j++) {
00178                             displaySubstituted = theIconLM.getSubstitutedDisplay(j);
00179                             add(displaySubstituted);
00180                             // Lors de l'iconification, quand on supprime le display iconifié, on ne veut
00181                             // pas qu'il soit enlevé de la liste des listeners qu'il écoute.
00182                             // Par contre, quand on revient là, on se remet dans l'état par défaut qui est
00183                             // que l'on veut les supprimer de la liste des listeners.
00184                             displaySubstituted.setDoRemoveFromListListeners(true);
00185                         }
00186                         // On enlève le display de l'icon
00187                         remove(theFtsChildDisplay);
00188                         // On réajuste le nombre de displays contenus dans l'instance courante.
00189                         nbDisplay = getComponentCount();
00190                         // Idem pour l'index. Puisqu'on a enlevé un display, si on ne décrémente
00191                         // pas i, on va en sauter 1.
00192                         i--;
00193                     }
00194                 }
00195                 
00196                 // On regarde si tous les éléments de la fts ont des displays associés.
00197                 // Sinon, il faut leur en construire un.
00198                 int count = theFts.getNbChildren();
00199                 boolean buildDisplay = true;
00200                 for (int i = 0; i < count; i++) {
00201                     buildDisplay = true;
00202                     theFtsChild = (FormulaTreeStructure) theFts.getChild(i);
00203                     for (int j = 0; j < nbDisplay; j++) {
00204                         theFtsChildDisplay = (Display) getComponent(j);
00205                         if (theFtsChildDisplay.isDisplay(theFtsChild)) {
00206                             buildDisplay = false;
00207                             break;
00208                         }
00209                     }
00210                     if (buildDisplay) {
00211                         buildDisplay(theFtsChild.getRank());
00212                     }
00213                 }
00214                 
00215                 // Maintenant on peut reconstruire le display, en fait le bon réagencement des
00216                 // displays contenus dans l'instance.
00217                 ((DisplayLayout) getLayout()).rebuildDisplay();
00218                 break;
00219                 
00220              case ModelEvent.CREATE :
00221                 buildDisplay();
00222                 invalidate();
00223                 setComputeAttributes(true);
00224                 validate();
00225                 repaint();
00226                 break;
00227                 
00228              case ModelEvent.CLEAR :
00229                 removeAll();
00230         }
00231     }
00232     
00233     // *** Fin de l'interface ModelListenerController ***
00234     // **************************************************
00235     
00236 }