Back to index

wims  3.65+svn20090927
EnclosingLayout.java
Go to the documentation of this file.
00001 /*
00002 $Id: EnclosingLayout.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.ctrlview.bidim.*;
00033 import fr.ove.openmath.jome.ctrlview.bidim.selection.events.SelectionEvent;
00034 import fr.ove.openmath.jome.model.*;
00035 import fr.ove.openmath.jome.behaviour.*;
00036 
00044 public abstract class EnclosingLayout extends HorizontalLayout {
00048     private SymbolDisplay opening;
00049     
00053     private SymbolDisplay closing;
00054     
00058     public SymbolDisplay getOpening() {
00059         return opening;
00060     }
00061     
00065     public SymbolDisplay getClosing() {
00066         return closing;
00067     }
00068     
00077     public void initDisplay(Display displayToLay) {
00078         super.initDisplay(displayToLay);
00079         
00080         FormulaTreeStructure fts = (FormulaTreeStructure) displayToLay.getListener();
00081         if (((Maskable) fts).isVisible()) {
00082             opening = createOpening();
00083 
00084             // On met un listener à l'opening
00085             // En fait, il n'y en a pas besoin, dans le sens où il n'y a pas spécifiquement de fts qui
00086             // écoute le comportement de ce display. Néanmoins, il s'avère nécessaire qu'il en ait
00087             // un, par exemple lors de l'iconification, car c'est le display qui reçoit la demande
00088             // d'iconification qui envoie l'événement correspondant à la FTS. Or si ce display n'a pas
00089             // d'écouteur, alors pb. Par cohérence, l'écouteur du display d'opérateur, est le fts qui
00090             // représente cette opération. Par contre, la fts en question, n'écoute pas le display
00091             // d'opérateur.
00092             opening.addControlListener(fts);
00093             this.displayToLay.add(opening);
00094             
00095             closing = createClosing();
00096             closing.addControlListener(fts);
00097             this.displayToLay.add(closing);
00098         }
00099     }
00100     
00104     public void validateSelection() {
00105         SelectionEvent selEvt = new SelectionEvent(displayToLay);
00106 
00107         if (((Maskable) displayToLay.getListener()).isVisible()) {
00108             // La validité de la sélection est triviale.
00109             // Si l'une ou l'autre des parenthèse est sélectionnée, alors on sélectionne
00110             // tout.
00111             if (opening.isSelected() || closing.isSelected()) {
00112                 // Sélectionne le display.
00113                 displayToLay.select();
00114                 // On purge la liste des éléments sélectionnés.
00115                 selEvt.setAction(SelectionEvent.PURGE, null);
00116                 displayToLay.fireSelectionEvent(selEvt);
00117                 // On y ajoute nos parenthèses
00118                 selEvt.setAction(SelectionEvent.ADD, displayToLay);
00119                 displayToLay.fireSelectionEvent(selEvt);
00120             }
00121         }
00122 
00123         // On a vérifié la validité de la sélection de la puissance. On doit maitenant
00124         // la contrôler au niveau supérieur, au niveau du père.
00125         Display display = displayToLay;
00126         if (displayToLay.getParent() instanceof Display) {
00127             display = (Display) displayToLay.getParent();
00128             FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
00129             if (fts.getFather() != null)
00130                 ((DisplayLayout) display.getLayout()).validateSelection();
00131         }
00132 
00133         // On met à jour l'affichage.
00134         display.repaint();
00135     }
00136 
00141     public void validateDeselection(Display display) {
00142         Display father = displayToLay;
00143         Display tmp;
00144         SelectionEvent selEvt = new SelectionEvent(displayToLay);
00145 
00146         // Si les parenthèses sont sélectionnées, alors il faut les déselectionner.
00147         if (father.isSelected()) {
00148             father.setNotSelected();
00149             // On enlève le display père de la liste des display sélectionnés.
00150             selEvt.setAction(SelectionEvent.REMOVE, father);
00151             father.fireSelectionEvent(selEvt);
00152 
00153             if (((Maskable) displayToLay.getListener()).isVisible()) {
00154                 if (display == opening)
00155                     closing.setNotSelected();
00156                 else
00157                     opening.setNotSelected();
00158                     
00159                 // L'opérande est mis dans la liste des sélectionnés
00160                 selEvt.setAction(SelectionEvent.ADD, (Display) father.getComponent(2));
00161                 father.fireSelectionEvent(selEvt);
00162             }
00163 
00164             // Comme pour la sélection, on contrôle la validité de la désélection.
00165             if (father.getParent() instanceof Display) {
00166                 father = (Display) father.getParent();
00167                 FormulaTreeStructure fts = (FormulaTreeStructure) father.getListener();
00168                 if (fts.getFather() != null)
00169                     ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
00170             }
00171 
00172             // Hé oui, on contrôle la validité de la sélection... dans une désélection.
00173             // Toujours le même pb, est-ce que le nouvel état de la sélection (après
00174             // désélection donc) est syntaxiquement cohérent ?
00175             validateSelection();
00176 
00177             // On met à jour l'affichage.
00178             father.repaint();
00179         }
00180 
00181     }
00182 
00188     public Dimension computeAttributes() {
00189         Display display = null;
00190 
00191         if (((Maskable) displayToLay.getListener()).isVisible()) {
00192             Displayable openingSymbol = opening.getSymbol();
00193             Displayable closingSymbol = closing.getSymbol();
00194             
00195             // On met la hauteur à 0, pour que dans tous les cas, le super.computeAttributes() ne soit pas
00196             // biaisée par une éventuelle nouvelle taille des éléments qui composent la liste.
00197             // Comme c'est plus loin qu'on leur fixe la taille....
00198             openingSymbol.setHeight(0);
00199             opening.setHeight(0);
00200             closingSymbol.setHeight(0);
00201             closing.setHeight(0);
00202             
00203             // même remarque que ci-dessus
00204             opening.setAttributes(0, 0, 0, 0);
00205             closing.setAttributes(0, 0, 0, 0);
00206             ((Display) displayToLay.getComponent(2)).setShiftX(0);
00207             
00208             Dimension dim = super.computeAttributes();
00209             
00210             // Par contre, par rapport à comment est calculée la taille display, dim comprend
00211             // déjà la largeur de opening et closing
00212             
00213             openingSymbol.setAscent(displayToLay.getAscent());
00214             openingSymbol.setDescent(displayToLay.getDescent());
00215             openingSymbol.setHeight(displayToLay.getHeight());
00216             opening.setComputeAttributes(true);
00217             opening.invalidate();
00218             opening.setSize(opening.getPreferredSize());
00219 
00220             closingSymbol.setAscent(displayToLay.getAscent());
00221             closingSymbol.setDescent(displayToLay.getDescent());
00222             closingSymbol.setHeight(displayToLay.getHeight());
00223             closing.setComputeAttributes(true);
00224             closing.invalidate();
00225             closing.setSize(closing.getPreferredSize());
00226             
00227             // Cette taille là correspond au décalage qu'il faut appliquer à closing
00228             closing.setShiftX(dim.width - 2*closing.getWidth());
00229             // Mais il faut l'enlever au display du milieu qui doit être contre l'opening (because HonrizontalLayout)
00230             ((Display) displayToLay.getComponent(2)).setShiftX(-closing.getShiftX() - closing.getWidth());
00231             
00232             return dim;
00233         }
00234         else
00235             return super.computeAttributes();
00236     }
00237 
00241     public void rebuildDisplay() {
00242         // La taille des displays est probablement différente de ceux qui étaient
00243         // précédemment. On demande alors le recalcul des display ancêtres.
00244         displayToLay.computeAncestorsAttributes();
00245     }
00246         
00247     // ############################################
00248     // ### Les différentes méthodes abstraites  ###
00249     // ############################################
00250     
00254     public abstract SymbolDisplay createOpening();
00255     
00259     public abstract SymbolDisplay createClosing();
00260 }