Back to index

wims  3.65+svn20090927
Display.java
Go to the documentation of this file.
00001 /*
00002 $Id: Display.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 java.awt.event.*;
00033 import java.util.*;
00034 import fr.ove.openmath.jome.model.*;
00035 import fr.ove.openmath.jome.model.events.*;
00036 import fr.ove.openmath.jome.behaviour.*;
00037 import fr.ove.openmath.jome.ctrlview.events.*;
00038 import fr.ove.openmath.jome.ctrlview.bidim.*;
00039 import fr.ove.openmath.jome.ctrlview.bidim.selection.*;
00040 import fr.ove.openmath.jome.ctrlview.bidim.selection.events.*;
00041 
00048 public abstract class Display extends Container implements Displayable, Colorizable, Selectable, Iconifiable, ModelListenerController {
00053     private int ascent;
00054 
00059     private int descent;
00060 
00064     private int shiftX = 0;
00065 
00069     private int shiftY = 0;
00070 
00074     protected boolean isSelected = false;
00075     
00080     private int level = 0;
00081     
00085     private boolean updateLevel = true;
00086     
00090     private boolean weDrawBounds = false;
00091     
00095     private GraphicContext graphicContext;
00096     
00100     private boolean computeAttributes = true;
00101     
00105     private int rank = 0;
00106     
00110     private static SelectionEventListener selectionManager = null;
00111     
00115     private ControlListener listener;
00116     
00120     protected boolean dragNDrop;
00121     
00127     private boolean isSymbolOperatorDisplay = false;
00128     
00137     private boolean doRemoveFromListListeners = true;
00138     
00139     
00144     private static DisplayAllocator displayAllocator = null;
00145     
00150     public Display(GraphicContext graphicContext) {
00151         super();
00152         
00153         this.graphicContext = new GraphicContext(graphicContext);
00154         setFont(graphicContext.getFont());
00155         setForeground(graphicContext.getForegroundColor());
00156         setBackground(graphicContext.getBackgroundColor());
00157         
00158         addMouseListener( 
00159             new MouseAdapter() {
00160                 public void mousePressed(MouseEvent e) {
00161                     SelectionEvent selEvt = new SelectionEvent(Display.this);
00162                     if (e.isControlDown()) {
00163                         if (!isSelected) {
00164                             DisplayLayout displayLayout = (DisplayLayout) getLayout();
00165                             
00166                             if (displayLayout instanceof OneFormulaLayout) {
00167                                 Display formulaDisplay = (Display) getComponent(0);
00168                                 if (formulaDisplay.isSelected())
00169                                     displayLayout.deselectDisplay();
00170                                 else {
00171                                     displayLayout.selectDisplay();
00172                                     setCursor(new Cursor(Cursor.HAND_CURSOR));
00173                                 }
00174                             }
00175                             else {
00176                                 displayLayout.selectDisplay();
00177                                 setCursor(new Cursor(Cursor.HAND_CURSOR));
00178                             }
00179 
00180                             repaint();
00181                         }
00182                         else {
00183                             ((DisplayLayout) getLayout()).deselectDisplay();
00184                             setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
00185 
00186                             repaint();
00187                         }
00188                     }
00189                     else if (e.isShiftDown())
00190                         iconify();
00191                     else if (e.isAltDown())
00192                         uniconify();
00193                 }
00194                 
00195                 public void mouseEntered(MouseEvent e) {
00196                     if (isSelected) 
00197                         setCursor(new Cursor(Cursor.HAND_CURSOR));
00198                     else
00199                         setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
00200                 }
00201             
00202                 public void mouseReleased(MouseEvent e) {
00203                     int mouseX = e.getX();
00204                     
00205                     if (dragNDrop) {
00206                         moveSelectedDisplays(mouseX);
00207                         dragNDrop = false;
00208                         repaint();
00209                     }
00210                 }
00211 
00212             }
00213         );
00214         
00215         addMouseMotionListener(
00216             new MouseMotionAdapter() {
00217                 public void mouseDragged(MouseEvent e) {
00218                     if (isSelected) {
00219                         dragNDrop = true;
00220                         setCursor(new Cursor(Cursor.MOVE_CURSOR));
00221                     }
00222                 }
00223                 
00224                 public void mouseMoved(MouseEvent e) {
00225                     if (isSelected) 
00226                         setCursor(new Cursor(Cursor.HAND_CURSOR));
00227                     else
00228                         setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
00229                 }
00230             }
00231         );
00232        }
00233        
00234        
00235        
00236     // *******************
00237     // Display information
00238     // *******************
00239     
00240     
00245     public boolean isDisplay(FormulaTreeStructure fts) {
00246         // On recupère la liste de tous les listeners de fts
00247         Vector listeners = fts.getListeners();
00248         
00249         return listeners.contains(this);
00250     }
00251     
00252        
00253     // ***************************************
00254     // About the display as one of an operator
00255     // ***************************************
00256     
00262     public void setIsSymbolOperatorDisplay(boolean isSymbolOperatorDisplay) {
00263         this.isSymbolOperatorDisplay = isSymbolOperatorDisplay;
00264     }
00265     
00270     public boolean isSymbolOperatorDisplay() {
00271         return isSymbolOperatorDisplay;
00272     }
00273     
00274     
00275     // *************************
00276     // The bounds of the display
00277     // *************************
00278     
00282     public void drawBounds() {
00283         weDrawBounds = true;
00284     }
00285     
00289     public void dontDrawBounds() {
00290         weDrawBounds = false;
00291     }
00292     
00298     public boolean weDrawBounds() {
00299         return weDrawBounds;
00300     }
00301     
00302     // ************************
00303     // The level of the display
00304     // ************************
00305     
00310     public void setLevel(int level) {
00311         this.level = level;
00312     }
00313     
00317     public int getLevel() {
00318         return level;
00319     }
00320 
00324     public void incLevel() {
00325         level++;
00326     }
00327     
00331     public void decLevel() {
00332         level--;
00333     }
00334     
00340     public void setUpdateLevel(boolean updateLevel) {
00341         this.updateLevel = updateLevel;
00342         if (updateLevel) {
00343             int count = getComponentCount();
00344             for (int i = 0; i < count; i++)
00345                 ((Display) getComponent(i)).setUpdateLevel(updateLevel);
00346         }
00347     }
00348     
00353     public boolean getUpdateLevel() {
00354         return updateLevel;
00355     }
00356     
00361     public void updateAncestorsLevel() {
00362         Container parent = getParent();
00363         while (parent instanceof Display) {
00364             ((Display) parent).setUpdateLevel(true);
00365             parent = parent.getParent();
00366         }
00367     }
00368     
00373     public void updateChildrenLevel() {
00374         Display childDisplay;
00375         int count = getComponentCount();
00376         for (int i = 0; i < count; i++) {
00377             childDisplay = (Display) getComponent(i);
00378             childDisplay.setUpdateLevel(true);
00379             childDisplay.updateChildrenLevel();
00380         }
00381     }
00382     
00383     
00384     // ************************************
00385     // The management of display attributes 
00386     // ************************************
00387     
00388     
00394     public void setComputeAttributes(boolean computeAttributes) {
00395         this.computeAttributes = computeAttributes;
00396     }
00397 
00402     public boolean getComputeAttributes() {
00403         return computeAttributes;
00404     }
00405     
00410     public void computeAncestorsAttributes() {
00411         computeAttributes = true;
00412         Container parent = getParent();
00413         while (parent instanceof Display) {
00414             ((Display) parent).setComputeAttributes(true);
00415             parent = parent.getParent();
00416         }
00417     }
00418     
00423     public void computeChildrenAttributes() {
00424         computeAttributes = true;
00425         int count = getComponentCount();
00426         for (int i = 0; i < count; i++)
00427             ((Display) getComponent(i)).computeChildrenAttributes();
00428     }
00429     
00430     
00431     // ***********************
00432     // The rank of the display
00433     // ***********************
00434     
00435     
00440     public void setRank(int rank) {
00441         this.rank = rank;
00442     }
00443     
00447     public int getRank() {
00448         return rank;
00449     }
00450     
00454     public void adjustRank() {
00455         int count = getComponentCount();
00456         for (int i = 0; i < count; i++)
00457             ((Display) getComponent(i)).setRank(i);
00458     }
00459     
00460     // *********************
00461     // Display manipulations
00462     // *********************
00463     
00469     public void removeAllDisplays() {
00470         Display display;
00471         int count = getComponentCount();
00472         for (int i = 0; i < count; ) {
00473             display = (Display) getComponent(i);
00474             // Si c'est le display d'un opérateur, alors on l'enlève de la liste et en plus, on l'enlève
00475             // de la liste des listeners de la fts qu'il écoutait.
00476             // Le remove surchargé.
00477             // si ce n'est pas le cas, on ne fait que le supprimer des fils de l'instance.
00478             if (display.isSymbolOperatorDisplay)
00479                 //remove(display);
00480                 remove(i);
00481             else
00482                 //super.remove(display);
00483                 super.remove(i);
00484                 
00485             count--;
00486         }
00487     }
00488     
00492     public void scaleDisplay() {
00493         setTheFont(graphicContext.scaleFont(level));
00494         setComputeAttributes(true);
00495         
00496         int count = getComponentCount();
00497         for (int i = 0; i < count; i++)
00498             ((Display) getComponent(i)).scaleDisplay();
00499         
00500         // On regarde si le display de l'instance est le display d'une icone.
00501         // Si tel est le cas, il faut que l'on scale les displays iconifiés.
00502         FormulaTreeStructure fts = (FormulaTreeStructure) getListener();
00503         if ((fts != null) && fts.isIcon()) {
00504             SubstitutedDisplayManager layout = (SubstitutedDisplayManager) getLayout();
00505             count = layout.getNbSubstitutedDisplay();
00506             for (int i = 0; i < count; i++)
00507                 layout.getSubstitutedDisplay(i).scaleDisplay();
00508         }
00509     }
00510     
00511     
00516     public void moveSelectedDisplays(int mouseX) {
00517         SelectionEvent selectionEvent = new SelectionEvent(this);
00518 
00519         // On récupère la taille de la sélection.
00520         Integer selectionSize = null;
00521         selectionEvent.setAction(SelectionEvent.GET_SELECTION_SIZE, selectionSize);
00522         fireSelectionEvent(selectionEvent);
00523         selectionSize = (Integer) selectionEvent.getArgument();
00524         // Si différente de 0, on peut faire du drag'n drop de qque chose.
00525         if (selectionSize.intValue() != 0) {
00526             // On récupère la sélection entière.
00527             Vector selection = null;
00528             selectionEvent.setAction(SelectionEvent.GET_SELECTION, selection);
00529             fireSelectionEvent(selectionEvent);
00530             selection = (Vector) selectionEvent.getArgument();
00531             Display display = (Display) selection.elementAt(0);
00532             // On récupère le fts associé au display.
00533             FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
00534             // On récupère l'opérateur dont les display sont les opérandes.
00535             fts = (FormulaTreeStructure) fts.getFather();
00536             // On fonction du type de cet opérateur, on permet ou pas le drag'n
00537             // drop.
00538             if (!fts.getAreOperandsMovable())
00539                 return;  // Pour ces opérateur là, on ne permet pas le drag'n drop.
00540 
00541             // Il faut maintenant savoir où on va dropper la sélection.
00542             // On récupère le display de l'opérateur, et on cherche cette position
00543             display = (Display) display.getParent();
00544             
00545             // On ajuste la position de la souris pour qu'on soit en coordonnée relative
00546             // dans le repère de display.
00547             // ATTENTION : l'instance courante est celle qui a reçu le mouseDragged. Elle
00548             // a reçu également le mouseReleased. Ce qui fait que le mouseX est une coordonnée
00549             // relative à l'instance. Donc, pour ramener notre coordonnée relativement à display
00550             // il faut rajouter la coordonnée de l'instance.
00551             Display tmp = this;
00552             while (tmp != display) {
00553                 mouseX += tmp.getX();
00554                 tmp = (Display) tmp.getParent();
00555             }
00556             
00557             // On regarde si la position de la souris ainsi calculée est toujours contenue
00558             // dans le display. Si ce n'est pas le cas, on se trouve dans un cas particulier.
00559             int insertionPosition;
00560             if (mouseX <= 0) {
00561                 // On a droppé à gauche de display, on insère donc au début de celui-ci
00562                 // Cela revient à dropper sur le premier display de la liste.
00563                 tmp = (Display) display.getComponentAt(1, display.getAscent());
00564                 insertionPosition = tmp.computeInsertionPosition(1);
00565             }
00566             else if (mouseX >= display.getWidth()) {
00567                 // On a droppé à droite de display, on insère donc à la fin de celui-ci
00568                 // Cela revient dropper sur le dernier display de la liste.
00569                 tmp = (Display) display.getComponentAt(display.getWidth() - 1, display.getAscent());
00570                 insertionPosition = tmp.computeInsertionPosition(display.getWidth() - 1 - tmp.getX());
00571             }
00572             else {
00573                 // On a droppé qque part dans display. On récupère ce display.
00574                 tmp = (Display) display.getComponentAt(mouseX, display.getAscent());
00575                 insertionPosition = tmp.computeInsertionPosition(mouseX - tmp.getX());
00576             }
00577             
00578             // On créé la liste des opérandes à permuter
00579             Vector operands = new Vector();
00580             for (Enumeration e = selection.elements(); e.hasMoreElements(); ) {
00581                 tmp = (Display) e.nextElement();
00582                 // Si l'on n'a pas affaire à un display d'operateur, alors on ajoute l'operande
00583                 // dans la liste.
00584                 if (!tmp.isSymbolOperatorDisplay()) {
00585                     tmp.deselect();
00586                     operands.addElement(tmp.getListener());
00587                 }
00588             }
00589             
00590             // On fait la permutation
00591             // Faut-il rajouter l'événement pour rester dans la philosophie ???
00592             fts.moveOperands(operands, insertionPosition);
00593             
00594             // On purge la liste de sélection
00595             selectionEvent.setAction(SelectionEvent.PURGE, null);
00596             fireSelectionEvent(selectionEvent);
00597         }
00598     }
00599 
00604     public int computeInsertionPosition(int mouseX) {
00605         int insertionPosition;
00606         
00607         // On regarde la position de la souris.
00608         // Si elle est inférieure à la moitié de la largeur de l'instance, alors
00609         // la position d'insertion est la position de l'opérande dont l'instance est
00610         // le display. Sinon, la position d'insertion est la position de l'opérande 
00611         // dont l'instance est le display + 1.
00612         if (mouseX <= (getWidth() / 2))
00613             insertionPosition = ((FormulaTreeStructure) listener).getRank();
00614         else
00615             insertionPosition = ((FormulaTreeStructure) listener).getRank() + 1;
00616             // Pas de pb de test pour savoir si on n'est pas sur le dernier opérande
00617             // puisqu'on est obligé dans ce cas de retourner le nbre réel + 1 pour dire
00618             // effectivement que l'on insère à la dernière position.
00619 
00620         // On retourne la position d'insertion calculée.
00621         return insertionPosition;
00622     }
00623     
00624     // ******************
00625     // Display allocation
00626     // ******************
00627     
00632     public void setDisplayAllocator(DisplayAllocator displayAllocator) {
00633         this.displayAllocator = displayAllocator;
00634     }
00635     
00640     public DisplayAllocator getDisplayAllocator() {
00641         return displayAllocator;
00642     }
00643     
00651     public void buildDisplay() {
00652         Display childDisplay;
00653         FormulaTreeStructure fts, ftsChild;
00654         int count;
00655         
00656         // On récupère l'élément de la FTS donc l'instance est le display.
00657         fts = (FormulaTreeStructure) getListener();
00658         if (fts != null) { // Bon malgrè le prérequis, on fait le test quand même
00659             count = fts.getNbChildren();
00660             
00661             // On parcourre la liste des fils de la fts, pour leur associer le display qui va bien
00662             for (int i = 0; i < count; i++) {
00663                 ftsChild = (FormulaTreeStructure) fts.getChild(i);
00664                 // Allocation du display
00665                 childDisplay = displayAllocator.allocateDisplay(graphicContext, ftsChild);
00666                 // Chacun écoute l'autre
00667                 //childDisplay.addControlListener(ftsChild);
00668                 //ftsChild.addModelListener(childDisplay);
00669                 // On ajoute le nouveau display comme fils à l'instance
00670                 add(childDisplay);
00671                 // On descend dans la fts pour poursuivre la construction des display
00672                 childDisplay.buildDisplay();
00673             }
00674         }
00675     }
00676     
00690     public Display buildDisplay(int indexFts) {
00691         Display childDisplay = null;
00692         FormulaTreeStructure fts, ftsChild;
00693         int count;
00694         
00695         // On récupère l'élément de la FTS donc l'instance est le display.
00696         fts = (FormulaTreeStructure) getListener();
00697         if (fts != null) {
00698             count = fts.getNbChildren();
00699             if ((indexFts >= 0) && (indexFts < count)) {
00700                 ftsChild = (FormulaTreeStructure) fts.getChild(indexFts);
00701                 // Allocation du display
00702                 childDisplay = displayAllocator.allocateDisplay(graphicContext, ftsChild);
00703                 // Le display que l'on ajoute est au même niveau que celui du père
00704                 // (rappel: niveau = nb de fois que la réduction de taille doit être appliquée,
00705                 // par exemple pour les exposants.) C'est le layout manager qui s'occupe de
00706                 // faire la réduction si nécessaire.
00707                 childDisplay.setLevel(getLevel());
00708                 // Chacun écoute l'autre
00709                 childDisplay.addControlListener(ftsChild);
00710                 ftsChild.addModelListener(childDisplay);
00711                 // On ajoute le nouveau display comme fils à l'instance
00712                 add(childDisplay);
00713                 // On descend dans la fts pour poursuivre la construction des display
00714                 childDisplay.buildDisplay();
00715             }
00716         }
00717         
00718         return childDisplay;
00719     }
00720     
00721     // ############################
00722     // ### Méthodes surchargées ###
00723     // ############################
00724     
00730     public void add(Display display) {
00731         super.add(display, display);
00732         display.setRank(getComponentCount() - 1);
00733     }
00734     
00739     public void remove(int index) {
00740         try {
00741             Display display = (Display) getComponent(index);
00742             
00743             if (display.doRemoveFromListListeners())
00744                 // On enlève maintenant le display supprimé de la liste des listeners de la fts
00745                 // qu'il écoutait
00746                 display.removeFromListListeners();
00747             
00748             // On enlève le display de la liste
00749             super.remove(index);
00750             
00751             // On réajuste maintenant le rank des fils de l'instance
00752             adjustRank();
00753         }
00754         catch (ArrayIndexOutOfBoundsException e) {
00755             System.out.println("Trying to remove display with a wrong index");
00756             e.printStackTrace();
00757         }
00758     }
00759     
00778     public void removeAll() {
00779         /*
00780         for (int i = 0; i < getComponentCount(); i++)
00781             remove(i);
00782         */
00783         for (int i = 0; i < getComponentCount(); )
00784             remove(i);
00785             
00786         computeAncestorsAttributes();
00787     }
00788     
00795     protected void setDoRemoveFromListListeners(boolean doRemoveFromListListeners) {
00796         this.doRemoveFromListListeners = doRemoveFromListListeners;
00797     }
00798     
00803     protected boolean doRemoveFromListListeners() {
00804         return doRemoveFromListListeners;
00805     }
00806     
00813     protected void removeFromListListeners(boolean doRemoveFromListListeners) {
00814         int count = getComponentCount();
00815         for (int i = 0; i < count; i++)
00816             ((Display) getComponent(i)).doRemoveFromListListeners = doRemoveFromListListeners;
00817     }
00818     
00823     private void removeFromListListeners() {
00824         // On récupère la fts associée au display enlevé et on lui enlève display
00825         // de la liste de ses listeners. 
00826         FormulaTreeStructure fts = (FormulaTreeStructure) getListener();
00827         fts.removeModelListener(this);
00828         removeControlListener(fts);
00829         
00830         // Il faut maintenant que l'on fasse la même chose avec les displays fils
00831         int count = getComponentCount();
00832         for (int i = 0; i < count; i++)
00833             ((Display) getComponent(i)).removeFromListListeners();
00834     }
00835     
00836         
00837     
00842     public void setFont(Font font) {
00843         setTheFont(font);
00844         
00845         graphicContext.setFont(font);
00846         
00847         int count = getComponentCount();
00848         // On parcourre tous les displays fils et ont leur affecte la nouvelle font.
00849         for (int i = 0; i < count; i++)
00850             ((Display) getComponent(i)).setFont(font);
00851             
00852         // On calcule la taille de la nouvelle font utilisée en fonction du niveau
00853         // du display.
00854         scaleDisplay();
00855             
00856         // On indique au layout manager que la taille du display (container) n'est plus
00857         // valide.
00858         invalidate();
00859         
00860         // On regarde si le display de l'instance est le display d'une icone.
00861         // Si tel est le cas, il faut que l'on mette la nouvelle font aux displays iconifiés.
00862         FormulaTreeStructure fts = (FormulaTreeStructure) getListener();
00863         if ((fts != null) && fts.isIcon()) {
00864             SubstitutedDisplayManager layout = (SubstitutedDisplayManager) getLayout();
00865             count = layout.getNbSubstitutedDisplay();
00866             for (int i = 0; i < count; i++)
00867                 layout.getSubstitutedDisplay(i).setFont(font);
00868         }
00869     }
00870     
00871     protected void setTheFont(Font font) {
00872         super.setFont(font);
00873     }
00874     
00879     public void substitute(String name) {
00880         SelectionEvent selectionEvent = new SelectionEvent(this);
00881 
00882         // On récupère la taille de la sélection.
00883         Integer selectionSize = null;
00884         selectionEvent.setAction(SelectionEvent.GET_SELECTION_SIZE, selectionSize);
00885         fireSelectionEvent(selectionEvent);
00886         selectionSize = (Integer) selectionEvent.getArgument();
00887         // Si différent de 0, il y a qque chose à substituer.
00888         if (selectionSize.intValue() != 0) {
00889             // On récupère la sélection entière.
00890             Vector selection = null;
00891             selectionEvent.setAction(SelectionEvent.GET_SELECTION, selection);
00892             fireSelectionEvent(selectionEvent);
00893             selection = (Vector) selectionEvent.getArgument();
00894             // On créé la liste des éléments à iconifier. (on enlève les displays
00895             // d'opérateurs parasites, et aux displays qui restent, on récupère
00896             // la fts dont ils sont le display).
00897             Display display;
00898             FormulaTreeStructure fts;
00899             Vector toIconify = new Vector();
00900             for (int i = 0; i < selectionSize.intValue(); i++) {
00901                 display = (Display) selection.elementAt(i);
00902                 if (!display.isSymbolOperatorDisplay()) {
00903                     // On désélectionne le display
00904                     display.deselect();
00905                     // On récupère le fts associé au display.
00906                     fts = (FormulaTreeStructure) display.getListener();
00907                     // On l'ajoute à la liste des fts à iconifier
00908                     toIconify.addElement(fts);
00909                 }
00910             }
00911             // On purge la sélection
00912             selectionEvent.setAction(SelectionEvent.PURGE, null);
00913             fireSelectionEvent(selectionEvent);
00914             
00915             // On rajoute comme premier élément à toIconify le nom de la substitution
00916             toIconify.insertElementAt(name, 0);
00917             
00918             // On envoie l'événement au modèle pour lui dire qu'il faut faire la substitution
00919             ControlEvent controlEvent = new ControlEvent(this);
00920             controlEvent.setAction(ControlEvent.SUBSTITUTE, toIconify);
00921             fireControlEvent(controlEvent);
00922         }
00923     }
00924     
00925     
00926     // #################################################
00927     // ### Implémentation des différentes interfaces ###
00928     // #################################################
00929     
00930     // *************************************************
00931     // *** Implémentation de l'interface Displayable ***
00932     
00937     public void setAscent(int ascent) {
00938         this.ascent = ascent;
00939     }
00940 
00945     public int getAscent() {
00946         return ascent;
00947     }
00948 
00953     public void setDescent(int descent) {
00954         this.descent = descent;
00955     }
00956 
00961     public int getDescent() {
00962         return descent;
00963     }
00964     
00969     public void setShiftX(int shiftX) {
00970         this.shiftX = shiftX;
00971     }
00972 
00977     public int getShiftX() {
00978         return shiftX;
00979     }
00980 
00985     public void setShiftY(int shiftY) {
00986         this.shiftY = shiftY;
00987     }
00988 
00993     public int getShiftY() {
00994         return shiftY;
00995     }
00996     
01004     public void setAttributes(int ascent, int descent, int shiftX, int shiftY) {
01005         this.ascent = ascent;
01006         this.descent = descent;
01007         this.shiftX = shiftX;
01008         this.shiftY = shiftY;
01009     }
01010         
01015     public void setGraphicContext(GraphicContext graphicContext) {
01016         this.graphicContext = graphicContext;
01017     }
01018     
01022     public GraphicContext getGraphicContext() {
01023         return graphicContext;
01024     }
01025     
01026     // *** Fin de l'interface Displayable ***
01027     // **************************************
01028     
01029     // *************************************************
01030     // *** Implémentation de l'interface Localisable ***
01031     
01036     public void setX(int x) {
01037         setLocation(x, getLocation().y);
01038     }
01039     
01043     public int getX() {
01044         return getLocation().x;
01045     }
01046     
01051     public void setY(int y) {
01052         setLocation(getLocation().x, y);
01053     }
01054     
01058     public int getY() {
01059         return getLocation().y;
01060     }
01061     
01062     // *** Fin de l'interface Localisable ***
01063     // **************************************
01064     
01065     // *********************************************
01066     // *** Implémentation de l'interface Sizable ***
01067     
01072     public void setWidth(int width) {
01073         setSize(width, getSize().height);
01074     }
01075     
01079     public int getWidth() {
01080         return getSize().width;
01081     }
01082     
01087     public void setHeight(int height) {
01088         setSize(getSize().width, height);
01089     }
01090     
01094     public int getHeight() {
01095         return getSize().height;
01096     }
01097     
01098     // *** Fin de l'interface sizable ***
01099     // **********************************
01100     
01101     
01102     // ****************************************
01103     // Implémentation de l'interface Selectable
01104     
01108     public void select() {
01109         if (!isSelected) {
01110             isSelected = true;
01111             int count = getComponentCount();
01112             for (int i = 0; i < count; i++)
01113                 ((Display) getComponent(i)).select();
01114         }
01115     }
01116     
01120     public void deselect() {
01121         if (isSelected) {
01122             isSelected = false;
01123             int count = getComponentCount();
01124             for (int i = 0; i < count; i++)
01125                 ((Display) getComponent(i)).deselect();
01126         }
01127     }
01128     
01132     public void setSelected() {
01133         isSelected = true;
01134     }
01135 
01139     public void setNotSelected() {
01140         isSelected = false;
01141     }
01142     
01148     public boolean isSelected() {
01149         return isSelected;
01150     }
01151     
01156     public boolean gotSelectedElements() {
01157         if (isSelected)
01158             return true;
01159             
01160         int count = getComponentCount();
01161         for (int i = 0; i < count; i++)
01162             if (((Display) getComponent(i)).gotSelectedElements())
01163                 return true;
01164         
01165         return false;
01166     }
01167     
01168     // *** Fin de l'interface Selectable ***
01169     // *************************************
01170     
01171     // *****************************************
01172     // Implémentation de l'interface Colorisable
01173     
01178     public void setForegroundColor(Color foregroundColor) {
01179         graphicContext.setForegroundColor(foregroundColor);
01180     }
01181  
01185     public Color getForegroundColor() {
01186         return graphicContext.getForegroundColor();
01187     }
01188     
01193     public void setBackgroundColor(Color backgroundColor) {
01194         graphicContext.setBackgroundColor(backgroundColor);
01195     }
01196     
01200     public Color getBackgroundColor() {
01201         return graphicContext.getBackgroundColor();
01202     }
01203     
01208     public void setSelectionColor(Color selectionColor) {
01209         graphicContext.setSelectionColor(selectionColor);
01210     }
01211 
01215     public Color getSelectionColor() {
01216         return graphicContext.getSelectionColor();
01217     }
01218     
01219     // *** Fin de l'interface Colorisable ***
01220     // **************************************
01221     
01222     // *****************************************
01223     // Implémentation de l'interface Iconifiable
01224     
01225     // Même si en fait ce n'est pas un display que l'on va iconifier, on implémente l'interface
01226     // iconifiable, parce que c'est à partir de là que le processus d'iconification va être lancé,
01227     // notamment en parcourant la liste de tous les display sélectionnés, potentiellement iconifiables.
01228     
01234     public void setIconName(String iconName) {
01235         // on ne fait rien, ce n'est pas un display que l'on va iconifier.
01236     }
01237 
01244     public String getIconName() {
01245         return null; // ce n'est pas un display que l'on va iconifier.
01246     }
01247     
01251     public boolean isIcon() {
01252         return false; // ce n'est pas un display que l'on va iconifier.
01253     }
01254     
01258     public void iconify() {
01259         SelectionEvent selectionEvent = new SelectionEvent(this);
01260 
01261         // On récupère la taille de la sélection.
01262         Integer selectionSize = null;
01263         selectionEvent.setAction(SelectionEvent.GET_SELECTION_SIZE, selectionSize);
01264         fireSelectionEvent(selectionEvent);
01265         selectionSize = (Integer) selectionEvent.getArgument();
01266         // Si différente de 0, il y a qque chose à iconifier.
01267         if (selectionSize.intValue() != 0) {
01268             // On récupère la sélection entière.
01269             Vector selection = null;
01270             selectionEvent.setAction(SelectionEvent.GET_SELECTION, selection);
01271             fireSelectionEvent(selectionEvent);
01272             selection = (Vector) selectionEvent.getArgument();
01273             // On créé la liste des éléments à iconifier. (on enlève les displays
01274             // d'opérateurs parasites, et aux displays qui restent, on récupère
01275             // la fts dont ils sont le display).
01276             Display display;
01277             FormulaTreeStructure fts;
01278             Vector toIconify = new Vector();
01279             for (int i = 0; i < selectionSize.intValue(); i++) {
01280                 display = (Display) selection.elementAt(i);
01281                 if (!display.isSymbolOperatorDisplay()) {
01282                     // On désélectionne le display
01283                     display.deselect();
01284                     // On récupère le fts associé au display.
01285                     fts = (FormulaTreeStructure) display.getListener();
01286                     // On l'ajoute à la liste des fts à iconifier
01287                     toIconify.addElement(fts);
01288                 }
01289             }
01290             // On purge la sélection
01291             selectionEvent.setAction(SelectionEvent.PURGE, null);
01292             fireSelectionEvent(selectionEvent);
01293             // On envoie l'événement au modèle pour lui dire qu'il faut iconifier
01294             ControlEvent controlEvent = new ControlEvent(this);
01295             controlEvent.setAction(ControlEvent.ICONIFY, toIconify);
01296             fireControlEvent(controlEvent);
01297         }
01298     }
01299 
01303     public void uniconify() {
01304         SelectionEvent selectionEvent = new SelectionEvent(this);
01305         // On récupère la taille de la sélection.
01306         Integer selectionSize = null;
01307         selectionEvent.setAction(SelectionEvent.GET_SELECTION_SIZE, selectionSize);
01308         fireSelectionEvent(selectionEvent);
01309         selectionSize = (Integer) selectionEvent.getArgument();
01310         // Si différente de 0, il y a éventuellement qque chose à désiconifier.
01311         if (selectionSize.intValue() != 0) {
01312             // On récupère la sélection entière.
01313             Vector selection = null;
01314             selectionEvent.setAction(SelectionEvent.GET_SELECTION, selection);
01315             fireSelectionEvent(selectionEvent);
01316             selection = (Vector) selectionEvent.getArgument();
01317             selectionEvent.setAction(SelectionEvent.PURGE, null);
01318             fireSelectionEvent(selectionEvent);
01319             // On parcourt la liste de sélection, et si l'on a affaire à une icone
01320             // on la désiconifie.
01321             Display display = null;
01322             FormulaTreeStructure fts = null;
01323             for (int i = 0; i < selectionSize.intValue(); i++) {
01324                 display = (Display) selection.elementAt(i);
01325                 // On désélectionne le display.
01326                 display.deselect();
01327                 // On récupère le fts associé au display.
01328                 fts = (FormulaTreeStructure) display.getListener();
01329                 if (fts.isIcon()) {
01330                     display.computeAncestorsAttributes();
01331                     // On envoie un événement pour dire au modèle qu'il doit
01332                     // déisconifier fts.
01333                     ControlEvent controlEvent = new ControlEvent(this);
01334                     controlEvent.setAction(ControlEvent.UNICONIFY, fts);
01335                     fireControlEvent(controlEvent);
01336                 }
01337             }
01338         }
01339     }
01340     
01346     public void uniconifyAll() {
01347         ControlEvent controlEvent = new ControlEvent(this);
01348         controlEvent.setAction(ControlEvent.UNICONIFY_ALL, null);
01349         fireControlEvent(controlEvent);
01350     }
01351     
01357     public void setIsIconifiable(boolean isIconifiable) {
01358         // Ce n'est pas un display que l'on va iconifier
01359     }
01360     
01365     public boolean isIconifiable() {
01366         // Ce n'est pas un display que l'on va iconifier
01367         return false;
01368     }
01369     
01370     // *** Fin de l'interface Iconifiable ***
01371     // **************************************
01372     
01373     
01374     // *****************************************************
01375     // Implémentation de l'interface ModelListenerController
01376     
01381     public void addControlListener(ControlListener controlListener) {
01382         listener = controlListener;
01383     }
01384 
01388     public void removeAllControlListener() {
01389         listener = null;
01390     }
01391     
01396     public void removeControlListener(ControlListener controlListener) {
01397         listener  = null;
01398     }
01399     
01404     public void fireControlEvent(ControlEvent controlEvent) {
01405         listener.consumeControlEvent(controlEvent);
01406     }
01407     
01411     public ControlListener getListener() {
01412         return listener;
01413     }
01414 
01415     // *** Fin de l'interface ModelListenerController ***
01416     // **************************************************
01417     
01418     
01419     // Selection management.
01420     
01425     public void addSelectionEventListener(SelectionEventListener selectionEventListener) {
01426         selectionManager = selectionEventListener;
01427     }
01428     
01433     public void removeSelectionEventListener(SelectionEventListener selectionEventListener) {
01434         if (selectionEventListener == selectionManager)
01435             selectionManager = null;
01436     }
01437     
01442     public void fireSelectionEvent(SelectionEvent selectionEvent) {
01443         selectionManager.consumeSelectionEvent(selectionEvent);
01444     }
01445     
01446     
01447     
01452     public void ToString() {
01453         System.out.println(super.toString());
01454         System.out.println("\t x = " + getX() + " y = " + getY());
01455         System.out.println("\t ascent = " + ascent + " descent = " + descent);
01456         System.out.println("\t width = " + getWidth() + " height = " + getHeight());
01457     }
01458     
01459     public void whoAmI() {
01460         System.out.println("I am a " + getClass().getName() + " with the " + getLayout().getClass().getName()  + " manager");
01461         System.out.println("My level is " + level);
01462         System.out.println("My children are :");
01463         for (int i = 0; i < getComponentCount(); i++)
01464             ((Display) getComponent(i)).whoAmI();
01465     }
01466 }