Back to index

wims  3.65+svn20090927
SuperposedOperatorLayout.java
Go to the documentation of this file.
00001 /*
00002 $Id: SuperposedOperatorLayout.java,v 1.3 2003/02/18 11:48:47 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.utils.FontInfo;
00036 
00043 public abstract class SuperposedOperatorLayout extends VerticalCenteredLayout implements OperatorDisplayCreator {
00049     public Dimension computeAttributes() {
00050         // C'est strictement la même chose, sauf que VerticalCenteredLayout place l'ascent comme étant la moitié
00051         // de la hauteur du display. Or dans le cas qui nous occupe, l'ascent du display doit ce trouver sur celui
00052         // de l'opérande
00053         Dimension dim = super.computeAttributes();
00054     
00055         displayToLay.setAscent(((Display) displayToLay.getComponent(0)).getShiftY() +
00056                   ((Display) displayToLay.getComponent(0)).getHeight() + 
00057                   ((Display) displayToLay.getComponent(1)).getShiftY() +
00058                   ((Display) displayToLay.getComponent(1)).getAscent());
00059                   
00060         displayToLay.setDescent(displayToLay.getHeight() - displayToLay.getAscent());
00061     
00062         return dim;
00063     }
00064     
00073     public void initDisplay(Display displayToLay) {
00074         super.initDisplay(displayToLay);
00075         
00076         // On récupère le fts associé (listener) au display.
00077         FormulaTreeStructure fts = (FormulaTreeStructure) displayToLay.getListener();
00078         
00079         Display displayOperator = createOperatorDisplay();
00080         
00081         // On met un listener à l'opérateur.
00082         // En fait, il n'y en a pas besoin, dans le sens où il n'y a pas spécifiquement de fts qui
00083         // écoute le comportement de ce display. Néanmoins, il s'avère nécessaire qu'il en ait
00084         // un, par exemple lors de l'iconification, car c'est le display qui reçoit la demande
00085         // d'iconification qui envoie l'événement correspondant à la FTS. Or si ce display n'a pas
00086         // d'écouteur, alors pb. Par cohérence, l'écouteur du display d'opérateur, est le fts qui
00087         // représente cette opération. Par contre, la fts en question, n'écoute pas le display
00088         // d'opérateur.
00089         displayOperator.addControlListener(fts);
00090         
00091         // On ajoute le display d'opérateur en première position
00092         // A priori, display ne contient rien, donc un add(displayOperator) suffit.
00093         this.displayToLay.add(displayOperator);
00094         
00095         this.displayToLay.computeAncestorsAttributes();
00096     }
00097     
00101     public void validateSelection() {
00102         SelectionEvent selEvt = new SelectionEvent(displayToLay);
00103 
00104         // La validité de la sélection est triviale.
00105         // Si l'opérateur est sléectionné, alors on sélectionne tout.
00106         Display displayOperator = (Display) displayToLay.getComponent(0);
00107         if (displayOperator.isSelected()) {
00108             // Sélectionne le display.
00109             displayToLay.select();
00110             // On purge la liste des éléments sélectionnés.
00111             selEvt.setAction(SelectionEvent.PURGE, null);
00112             displayToLay.fireSelectionEvent(selEvt);
00113             // On y ajoute os parenthèses
00114             selEvt.setAction(SelectionEvent.ADD, displayToLay);
00115             displayToLay.fireSelectionEvent(selEvt);
00116         }
00117 
00118         // On a vérifié la validité de la sélection de la puissance. On doit maitenant
00119         // la contrôler au niveau supérieur, au niveau du père.
00120         Display display = displayToLay;
00121         if (display.getParent() instanceof Display) {
00122             display = (Display) display.getParent();
00123             FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
00124             if (fts.getFather() != null)
00125                 ((DisplayLayout) display.getLayout()).validateSelection();
00126         }
00127 
00128         // On met à jour l'affichage.
00129         display.repaint();
00130     }
00131     
00136     public void validateDeselection(Display display) {
00137         Display father = displayToLay;
00138         SelectionEvent selEvt = new SelectionEvent(father);
00139         
00140         // Si l'opérateur est sélectionné, alors il faut le déselectionner.
00141         if (father.isSelected()) {
00142             father.setNotSelected();
00143             // On enlève le display père de la liste des display sélectionnés.
00144             selEvt.setAction(SelectionEvent.REMOVE, father);
00145             father.fireSelectionEvent(selEvt);
00146             
00147             Display displayOperator = (Display) displayToLay.getComponent(0);
00148             Display argument = (Display) displayToLay.getComponent(1);
00149             
00150             if (display == displayOperator) {
00151                 displayOperator.setNotSelected();
00152                 selEvt.setAction(SelectionEvent.ADD, argument);
00153                 father.fireSelectionEvent(selEvt);
00154             }
00155             else {
00156                 displayOperator.setNotSelected();
00157                 argument.deselect();
00158             }
00159 
00160             // Comme pour la sélection, on contrôle la validité de la désélection.
00161             if (father.getParent() instanceof Display) {
00162                 father = (Display) father.getParent();
00163                 FormulaTreeStructure fts = (FormulaTreeStructure) father.getListener();
00164                 if (fts.getFather() != null)
00165                     ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
00166             }
00167             
00168             // Hé oui, on contrôle la validité de la sélection... dans une désélection.
00169             // Toujours le même pb, est-ce que le nouvel état de la sélection (après
00170             // désélection donc) est syntaxiquement cohérent ?
00171             validateSelection();
00172             
00173             // On met à jour l'affichage.
00174             father.repaint();
00175         }        
00176 
00177     }
00178     
00182     public void rebuildDisplay() {
00183         // La taille des displays est probablement différente de ceux qui étaient
00184         // précédemment. On demande alors le recalcul des display ancêtres.
00185         displayToLay.computeAncestorsAttributes();
00186     }
00187 }