Back to index

wims  3.65+svn20090927
DifferentiationLayout.java
Go to the documentation of this file.
00001 /*
00002 $Id: DifferentiationLayout.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 
00042 public class DifferentiationLayout extends HorizontalLayout {
00043     private boolean arrangeDisplay = true; // Au premier calcul, il faudra arranger les displays correctement
00044     private Display fracDisplay = null;
00045     
00054     public void initDisplay(Display displayToLay) {
00055         super.initDisplay(displayToLay);
00056         
00057         Differentiation diff = (Differentiation) this.displayToLay.getListener();
00058         diff.computeOrder();
00059         
00060         // Allocation d'un display, qui va correspondre à la partie fraction de la représentation
00061         fracDisplay = new BidimDisplay(displayToLay.getGraphicContext());
00062         // On met un listener à fracDisplay
00063         // En fait, il n'y en a pas besoin, dans le sens où il n'y a pas spécifiquement de fts qui
00064         // écoute le comportement de ce display. Néanmoins, il s'avère nécessaire qu'il en ait
00065         // un, par exemple lors de l'iconification, car c'est le display qui reçoit la demande
00066         // d'iconification qui envoie l'événement correspondant à la FTS. Or si ce display n'a pas
00067         // d'écouteur, alors pb. Par cohérence, l'écouteur du display d'opérateur, est le fts qui
00068         // représente cette opération. Par contre, la fts en question, n'écoute pas le display
00069         // d'opérateur.
00070         fracDisplay.addControlListener(diff);
00071         // On lui met dont un FractionLayout
00072         FractionLayout layout = new FractionLayout();
00073         layout.initDisplay(fracDisplay);
00074         fracDisplay.setLayout(layout);
00075         // On l'ajoute comme fils à display
00076         this.displayToLay.add(fracDisplay);
00077     }
00078     
00082     public void validateSelection() {
00083         SelectionEvent selEvt = new SelectionEvent(displayToLay);
00084 
00085         Display derivator = (Display) displayToLay.getComponent(0);
00086         Display func = (Display) displayToLay.getComponent(1);
00087         // Si le display de ce qui est la partie fraction de la dérivée (derivator) est sélectionnée,
00088         // alors on sélectionne tout.
00089         // Si la function et dérivator ont qque chose de sélectionné, alors on sélectionne tout.
00090         if (derivator.isSelected() || (func.gotSelectedElements() && derivator.gotSelectedElements())) {
00091             displayToLay.select();
00092             // On purge la liste des éléments sélectionnés.
00093             selEvt.setAction(SelectionEvent.PURGE, null);
00094             displayToLay.fireSelectionEvent(selEvt);
00095             // On y ajoute l'instance dans la liste des sélectionnés
00096             selEvt.setAction(SelectionEvent.ADD, displayToLay);
00097             displayToLay.fireSelectionEvent(selEvt);
00098         }
00099         
00100         // On a vérifié la validité de la sélection de l'opérateur. On doit maitenant
00101         // la contrôler au niveau supérieur, au niveau du père.
00102         Display display = displayToLay;
00103         if (displayToLay.getParent() instanceof Display) {
00104             display = (Display) displayToLay.getParent();
00105             //if (!(display.getListener() instanceof Formula))
00106             FormulaTreeStructure fts = (FormulaTreeStructure) display.getListener();
00107             if (fts.getFather() != null)
00108                 ((DisplayLayout) display.getLayout()).validateSelection();
00109         }
00110 
00111         // On met à jour l'affichage.
00112         display.repaint();
00113     }
00114     
00119     public void validateDeselection(Display display) {
00120         // father est le display de l'opérateur unaire.
00121         Display father = displayToLay;
00122         Display tmp;
00123         SelectionEvent selEvt = new SelectionEvent(father);
00124         
00125         // Si l'opérateur en entier est sélectionné, il faut le désélectionner
00126         if (father.isSelected()) {
00127             father.deselect();
00128             // On enlève le display père de la liste des display sélectionnés.
00129             selEvt.setAction(SelectionEvent.REMOVE, father);
00130             father.fireSelectionEvent(selEvt);
00131             
00132             // Si display est l'opérateur (on vient de déselectionner l'opérateur), alors
00133             // on ajoute l'opérande dans la liste des sélectionnés.
00134             if (display == displayToLay.getComponent(0)) {
00135                 ((Display) displayToLay.getComponent(1)).select();
00136                 selEvt.setAction(SelectionEvent.ADD, (Display) displayToLay.getComponent(1));
00137                 father.fireSelectionEvent(selEvt);
00138             }                
00139             
00140             // Comme pour la sélection, on contrôle la validité de la désélection.
00141             if (father.getParent() instanceof Display) {
00142                 father = (Display) father.getParent();
00143                 //((DisplayLayout) father.getLayout()).validateDeselection((Display) display.getParent());
00144                 if (!(father.getListener() instanceof Formula))
00145                     ((DisplayLayout) father.getLayout()).validateDeselection(displayToLay);
00146             }
00147             
00148             // Hé oui, on contrôle la validité de la sélection... dans une désélection.
00149             // Toujours le même pb, est-ce que le nouvel état de la sélection (après
00150             // désélection donc) est syntaxiquement cohérent ?
00151             validateSelection();
00152             
00153             // On met à jour l'affichage.
00154             father.repaint();
00155         }        
00156     }
00157         
00158     
00164     public Dimension computeAttributes() {
00165         VarDiffLayout varDiffLayout;
00166         updateLevel(displayToLay.getLevel());
00167         
00168         //if (arrangeDisplay) {
00169         if (displayToLay.getComponentCount() > 3) {
00170             // Dans l'ordre, displayToLay contient [fracDisplay, numFrac, fct, var1, var2, ...]
00171             // Il faut mettre numFrac, comme fils de fracDisplay (qui à ce stade ne contient que le display
00172             // de la barre de fraction.
00173             // Il faut creer un display avec comme layout DenominatorDiffLayout, et y ajouter tous les vari.
00174             // Ensuite, ajouter ce display à fracDisplay.
00175             // On obtient donc displayToLay = [fracDisplay, fct]
00176             // avec fracDisplay = [barDisplay, numFrac, [var1, var2, ...]]
00177             // Le display de chacun des vari est en fait le display d'un slot. On remplace le SlotLayout, par
00178             // un VarDiffLayout, pour que le "d" (ou le delta) soit rajouté devant.
00179             
00180             Display d;
00181             d = (Display) displayToLay.getComponent(1);
00182             // fracDisplay.add(d) appelle un displayToLay.remove(d).
00183             // remove(d), enlève également d de la liste des listeners de l'objet (fts) qu'il écoutait.
00184             // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple déplacement de display. 
00185             d.setDoRemoveFromListListeners(false);
00186             fracDisplay.add(d);
00187             d.setDoRemoveFromListListeners(true);
00188             //displayToLay contient [fracDisplay, fct, var1, var2, ...]
00189             int count = displayToLay.getComponentCount();
00190             Differentiation diff = (Differentiation) displayToLay.getListener();
00191             if (count == 3) {
00192                 // Ca veut dire que l'on a une dérivée du premier ordre : [fracDisplay, fct, var1]
00193                 // On a juste à mettre le display de var1 dans fracDisplay
00194                 d = (Display) displayToLay.getComponent(2);
00195                 // On modifie le layout, qui doit être un slotLayout, par un VarDiffLayout.
00196                 varDiffLayout = new VarDiffLayout(diff.isPartial());
00197                 varDiffLayout.initDisplay(d);
00198                 d.setLayout(varDiffLayout);
00199                 // fracDisplay.add(d) appelle un displayToLay.remove(d).
00200                 // remove(d), enlève également d de la liste des listeners de l'objet (fts) qu'il écoutait.
00201                 // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple déplacement de display. 
00202                 d.setDoRemoveFromListListeners(false);
00203                 fracDisplay.add(d);
00204                 d.setDoRemoveFromListListeners(true);
00205             }
00206             else {
00207                 // Ca veut dire que l'on a une dérivée d' ordre > 1 : [fracDisplay, fct, var1, var2, ...]
00208                 // Il faut créer un display pour le dénominateur
00209                 Display den = new BidimDisplay(displayToLay.getGraphicContext());
00210                 // On met un listener à den
00211                 // En fait, il n'y en a pas besoin, dans le sens où il n'y a pas spécifiquement de fts qui
00212                 // écoute le comportement de ce display. Néanmoins, il s'avère nécessaire qu'il en ait
00213                 // un, par exemple lors de l'iconification, car c'est le display qui reçoit la demande
00214                 // d'iconification qui envoie l'événement correspondant à la FTS. Or si ce display n'a pas
00215                 // d'écouteur, alors pb. Par cohérence, l'écouteur du display d'opérateur, est le fts qui
00216                 // représente cette opération. Par contre, la fts en question, n'écoute pas le display
00217                 // d'opérateur.
00218                 den.addControlListener(diff);
00219                 
00220                 DenominatorDiffLayout denLayout = new DenominatorDiffLayout();
00221                 denLayout.initDisplay(den);
00222                 den.setLayout(denLayout);
00223                 
00224                 for (int i = 2; i < displayToLay.getComponentCount(); ) {
00225                     d = (Display) displayToLay.getComponent(i);
00226                     // On modifie le layout, qui doit être un slotLayout, par un VarDiffLayout.
00227                     varDiffLayout = new VarDiffLayout(diff.isPartial());
00228                     varDiffLayout.initDisplay(d);
00229                     d.setLayout(varDiffLayout);
00230                     // den.add(d) appelle un displayToLay.remove(d).
00231                     // remove(d), enlève également d de la liste des listeners de l'objet (fts) qu'il écoutait.
00232                     // Ce qu'on ne veut pas, puisqu'il s'agit d'un simple déplacement de display. 
00233                     d.setDoRemoveFromListListeners(false);
00234                     den.add(d);
00235                     // On remet le comportement de suppression par défault.
00236                     d.setDoRemoveFromListListeners(true);
00237                 }
00238                 // On ajoute maintenant le dénominateur dans fracDisplay
00239                 fracDisplay.add(den);
00240             }
00241         }        
00242         
00243         // On a donc displayToLay = [fracDisplay, fct]
00244         // avec fracDisplay = [barDisplay, numFrac, [var1, var2, ...]]
00245         ((Display) displayToLay.getComponent(1)).setShiftX(5);
00246         Dimension dim = super.computeAttributes();
00247         
00248         return new Dimension(dim.width + 5, dim.height);
00249     }
00250     
00254     public void rebuildDisplay() {
00255         // La taille des displays est probablement différente de ceux qui étaient
00256         // précédemment. On demande alors le recalcul des display ancêtres.
00257         displayToLay.computeAncestorsAttributes();
00258     }
00259 
00260 }