Subversion Repositories eFlore/Applications.cel

Rev

Rev 989 | Blame | Last modification | View Log | RSS feed

package org.tela_botanica.client.vues.observation.indicateurs;

import org.tela_botanica.client.interfaces.Rafraichissable;
import org.tela_botanica.client.modeles.objets.ImageCarnet;
import org.tela_botanica.client.observation.ObservationMediateur;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.LoadEvent;
import com.google.gwt.event.dom.client.LoadHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.gwtext.client.core.AnimationConfig;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.core.Ext;
import com.gwtext.client.core.ExtElement;
import com.gwtext.client.core.RegionPosition;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.ToolTip;
import com.gwtext.client.widgets.layout.BorderLayout;
import com.gwtext.client.widgets.layout.BorderLayoutData;
import com.gwtext.client.widgets.menu.BaseItem;
import com.gwtext.client.widgets.menu.Item;
import com.gwtext.client.widgets.menu.Menu;
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter;

/**
 * Panneau d'affichage d'une image avec des boutons précdents et suivant
 * 
 * @author aurelien
 * 
 */
public class MiniZoomImageVue extends Panel implements Rafraichissable {

        /**
         * Le médiateur associé à la vue
         */
        private ObservationMediateur oMediateur = null;
        
        /**
         * Le titre du panneau
         */
        private static String titrePanneau = "Images liées";

        /**
         * Panneau conteneur pour l'image
         */
        private Panel imageConteneur = null;
        /**
         * l'image à afficher
         */
        private Image image = new Image("");
        /**
         * Bouton précédent
         */
        private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button();
        /**
         * Bouton suivant
         */
        private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button();

        /**
         * Taille originale Y de l'image
         */
        private int imageHeight = 0;

        /**
         * Taille originale X de l'image
         */
        private int imageWidth = 0;
        
        /**
         * Identifiant de l'image
         */
        private String idImage = "0" ;
        
        private String[] infosImages[] = null ;
        
        private int index = 0 ;

        /**
         * true pour animer les transitions
         */
        private boolean animerTransition = false;
        /**
         * Détermine la durée de la transition
         */
        private float dureeAnimation = (float) 0.15;
        
        /**
         * Booleen d'initalisation général
         */
        private boolean initialise = false;

        /**
         * Booleen d'initalisation du conteneur d'image
         */
        private boolean conteneurInitialise = false;
        
        private ToolTip tp = new ToolTip("<div class=\"x-tooltip-help\"> Double cliquez pour agrandir l'image </div>") ;
        
        com.gwtext.client.widgets.Window imgZoom = new com.gwtext.client.widgets.Window("Agrandissement") ;
        
        Image imgAgrandie = null;

        /**
         * Constructeur sans argument (privé car ne doit être utilisé)
         */
        @SuppressWarnings("unused")
        private MiniZoomImageVue() {
                super();
        }

        /**
         * Constructeur avec argument
         * 
         * @param im
         *            le médiateur à associer à la vue
         */
        public MiniZoomImageVue(ObservationMediateur im) {
                super(titrePanneau);
                setId("x-view-mini-zoom-panel");
                // on associe le médiateur
                oMediateur = im;

                prev.setStylePrimaryName("x-view-zoom-button-p");
                suiv.setStylePrimaryName("x-view-zoom-button-s");

                imgZoom.setCloseAction(com.gwtext.client.widgets.Window.HIDE) ;
                imgZoom.setConstrain(true);
                
                // on crée une image qui gère le double clic et la roulette de la souris
                image = new Image() {

                        @Override
                        public void onBrowserEvent(Event event) {

                                // lors d'un déplacement de la roulette
                                if (Event.ONMOUSEWHEEL == DOM.eventGetType(event)) {

                                        // on simule un clic sur le bouton précédent
                                        if (event.getMouseWheelVelocityY() >= 1) {
                                                prev.click();
                                        }

                                        // ou suivant
                                        if (event.getMouseWheelVelocityY() <= -1) {
                                                suiv.click();
                                        }
                                }
                                
                                if(Event.ONCONTEXTMENU == DOM.eventGetType(event)) {
                                        
                                        event.preventDefault() ;
                                        int[] xy = {event.getClientX(),event.getClientY()} ;
                                        afficherMenu(xy) ;
                                }
                                
                                // lors du double clic
                                if (Event.ONDBLCLICK == DOM.eventGetType(event)) {
                                        if(imgZoom.isVisible()) {
                                                        imgZoom.hide();
                                        } else {
                                                afficherPanneauAgrandi();
                                        }
                                }
                        }
                        
                };
                
                image.setPixelSize(150, 150);
                
                infosImages = new String[0][0] ;

                this.setHeader(true);

                imageConteneur = new Panel() ;
                imageConteneur.setBorder(false);

                imageConteneur.add(image);
                imageConteneur.setId("x-view-mini-zoom-img");

                // il n'existe pas de méthode pour ajouter un listener pour le double
                // clic sur une image
                // alors on lui dit manuellement de capter l'évènement double clic
                image.sinkEvents(Event.ONDBLCLICK);
                image.sinkEvents(Event.ONMOUSEWHEEL);
                image.sinkEvents(Event.ONCONTEXTMENU) ;

                // l'image de base est vide
                image.setUrl("");

                this.setLayout(new BorderLayout());

                prev.setWidth("15%");
                suiv.setWidth("15%");

                this.add(prev, new BorderLayoutData(RegionPosition.WEST));
                this.add(imageConteneur, new BorderLayoutData(RegionPosition.CENTER));
                this.add(suiv, new BorderLayoutData(RegionPosition.EAST));

                imageConteneur.setMaskDisabled(true);
                this.setBorder(false);

                conteneurInitialise = true;
                initialise = true;

                // on ajoute les listeners
                ajouterListeners();

        }

        /**
         * Méthode héritée de l'interface rafraichissable
         * 
         * @param nouvelleDonnees
         *            les nouvelles données
         * @param repandreRafraichissement
         *            le booleen qui dit si on doit répnadre l'évènement
         */
        @Override
        public void rafraichir(Object nouvelleDonnees,
                        boolean repandreRafraichissement) {

                // si on reçoit une string
                if (nouvelleDonnees instanceof String[][] && initialise
                                && conteneurInitialise && ((String[][])nouvelleDonnees).length != 0) {
                        infosImages = (String[][]) nouvelleDonnees;
                        index = 0 ;
                        afficherImage() ;
                        
                } else {
                        // sinon on met une image vide
                        infosImages = null ;
                        afficherImage();
                        
                }
        }

        public void afficherImage()
        {
                // c'est l'url de l'image qu'on associe à la vue
                if(infosImages != null && infosImages.length != 0)
                {
                        setTitle(titrePanneau+"         "+(index+1)+" / "+infosImages.length);
                        
                        getImage().setUrl(getUrlMiniature(index));
                        imageWidth = Integer.parseInt(infosImages[index][1]);
                        imageHeight = Integer.parseInt(infosImages[index][2]);
                        verifierEtRetaillerImage();
                        activerPanneau(true);
                } else {
                        setTitle(titrePanneau);
                        getImage().setUrl("ill_liaison.png");
                        imageWidth = getImage().getWidth();
                        imageHeight = getImage().getHeight();
                        if(imgZoom.isVisible()) {
                                agrandirImage();
                        }
                        activerPanneau(false);
                }
                
                if(infosImages != null && infosImages.length > 1) {
                        prev.setEnabled(true);
                        suiv.setEnabled(true);
                } else {
                        prev.setEnabled(false);
                        suiv.setEnabled(false);
                }
        }

        /**
         * Active visuellement le panneau et les boutons
         */
        public void activerPanneau(boolean activer) {
                if(activer) {
                        this.getEl().unmask();
                } else {
                        this.getEl().mask();
                }
        }

        /**
         * Ajoute les listeners pour la gestions d'évènement
         */
        public void ajouterListeners() {

                // gestion du clic sur le bouton précedent
                prev.addClickHandler(new ClickHandler() {

                        @Override
                        public void onClick(ClickEvent event) {
                                if(infosImages.length != 0) {
                                        if(index == 0)
                                        {
                                                index = infosImages.length - 1 ;
                                        }
                                        else
                                        {
                                                index-- ;
                                        }
                                                                        
                                        afficherImage() ;
                                }
                        }

                });

                // gestion du clic sur le bouton suivant
                suiv.addClickHandler(new ClickHandler() {

                        // en cas de clic
                        @Override
                        public void onClick(ClickEvent event) {
                                
                                if(infosImages.length != 0) {
                                        if(index == infosImages.length - 1)
                                        {
                                                index = 0 ;
                                        }
                                        else
                                        {
                                                index++ ;
                                        }
                                                                        
                                        afficherImage() ;
                                }
                                        
                        }

                });
                
        }

        /**
         * Accesseur pour le médiateur
         * 
         * @return le médiateur associé à la vue
         */
        public ObservationMediateur getIMediateur() {
                return oMediateur;
        }

        /**
         * Accesseur au conteneur de l'image
         * 
         * @return le conteneur de l'image
         */
        public Image getImage() {
                return image;
        }
        
        /**
         * Acesseurs pour l'identifiant de l'image
         * @return l'id de l'image
         */
        public String getIdImage()
        {
                return infosImages[index][0] ;
        }

        /**
         * Accesseur pour le bouton précédent
         * 
         * @return le bouton précédent
         */
        public com.google.gwt.user.client.ui.Button getPrev() {
                return prev;
        }

        /**
         * Accesseur pour le bouton suivant
         * 
         * @return le bouton suivant
         */
        public com.google.gwt.user.client.ui.Button getSuiv() {
                return suiv;
        }

        /**
         * Setter pour la taille de l'image
         * 
         * @param x
         *            la largeur en pixels
         * @param y
         *            la hauteur en pixels
         */
        public void setTailleImage(int x, int y) {
                imageHeight = y;
                imageWidth = x;
        }
        
        /**
         * Setteur pour l'identifiant de l'image
         * @param id le nouvel identifiant
         */
        public void setIdImage(String id)
        {
                idImage = id ;
        }

        /**
         * renvoie la taille originale de l'image
         * 
         * @return un tableau de deux entiers contenant la largeur puis la hauteur
         */
        public int[] getTailleImage() {
                int[] taille = { imageHeight, imageWidth };

                return taille;
        }
        
        /**
         * Accesseur pour le conteneur de l'image
         * @return le conteur de l'image
         */
        public Panel getImageConteneur() {

                return imageConteneur;

        }

        public void raz() {
                
                infosImages = new String[0][0] ;
                getImage().setUrl("");
                
        }
        
        public void supprimerLiaisonImage() {
                
                if(infosImages.length > 0) {
                        
                        getImage().setUrl("") ;
                        int nouvelleTaille = infosImages.length - 1 ;
                        int indexSupp = index ;
                        
                        String[][] nouveauInfosImages = new String[nouvelleTaille][3] ;
                        int j = 0 ;
                        
                        for(int i = 0 ; i < infosImages.length ; i++) {
                                
                                if(i != indexSupp) {
                                        
                                        nouveauInfosImages[j] = infosImages[i] ;
                                        j++ ;
                                }
                        }
                        
                        infosImages = nouveauInfosImages ;
                        index = 0 ;
                        
                        afficherImage() ;
                }
        }
        
        public void afficherMenu(int[] xy) {
                
                Menu mn = new Menu() ;
                final Item suppLiaison = new Item("Supprimer la liaison") ;
                
                mn.addItem(suppLiaison) ;
                
                mn.addListener(new MenuListenerAdapter() {
                        
                        @Override
                        public void onItemClick(BaseItem item, EventObject e) {
                                
                                // si c'est l'aide
                                if (item.equals(suppLiaison)) {
                                        // on notifie le médiateur
                                        getIMediateur().supprimerLiaisonObsImage() ;
                                }
                        }
                        
                }) ;
                
                mn.showAt(xy) ;
        }
                
        /**
         * Verifie si l'image est plus grande que le conteneur et la retaille le cas
         * echeant
         */
        public void verifierEtRetaillerImage() {
                
                // si l'image est nulle
                if (image == null) {
                        // on ne fait rien
                        return;
                }
                
                int[] dim = calculerDimensions(getTailleImage(),300,imageConteneur.getWidth());
                getImage().setSize("" + dim[0] + "px",
                                "" + dim[1] + "px");
                
                doLayout();
                
                if(imgZoom.isVisible()) {
                        agrandirImage();
                }
        }
        
        public int[] calculerDimensions(int[] tailleXY, double tailleMax, double tailleConteneur) {
            
                float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
        float tailleOr = Math.min(new Float(tailleMax),new Float(tailleConteneur)) ;
        float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
        float[] XYresize = new float[2];
        
        if(maxTaille == tailleXY[0]) {
            float rapport = tailleXYf[1]/tailleXYf[0] ;
            XYresize[0] = tailleOr ;
            XYresize[1] = tailleOr*rapport ;
        }else {
            float rapport = tailleXYf[0]/tailleXYf[1] ;
            XYresize[1] = tailleOr ;
            XYresize[0] = tailleOr*rapport ;
        }
        
        int[] res = {(int)Math.round(XYresize[0]*0.85),(int)Math.round(XYresize[1]*0.85)} ;
        
        return res;
    }
        
        protected void agrandirImage() {
                
                        String urlAgrandie = "";
                        
                        if(infosImages == null) {
                                urlAgrandie = "ill_liaison.png";
                                setTailleImage(265, 270);
                        } else {
                                urlAgrandie = getUrlAgrandie(index);
                        }
                        
                        if(imgAgrandie == null) {
                                imgAgrandie = new Image(urlAgrandie); 
                                imgZoom.add(imgAgrandie);
                                
                                imgAgrandie.addLoadHandler(new LoadHandler() {

                                        @Override
                                        public void onLoad(LoadEvent event) {
                                                int[] tailleImage = calculerDimensions(getTailleImage(),getTailleImage()[1],Window.getClientHeight()*0.75);
                                                ExtElement imgElement = Ext.get(imgAgrandie.getElement());
                                                if(animerTransition) {
                                                        AnimationConfig a = new AnimationConfig() ;
                                                        a.setDuration(dureeAnimation);
                                                        imgElement.setHeight(tailleImage[1], a);
                                                        imgElement.setWidth(tailleImage[0], a);
                                                        
                                                        ExtElement winElement = Ext.get(imgZoom.getElement());
                                                        winElement.setHeight(tailleImage[1], a);
                                                        winElement.setWidth(tailleImage[0], a);
                                                } else {
                                                        imgElement.setHeight(tailleImage[1], false);
                                                        imgElement.setWidth(tailleImage[0], false);
                                                        
                                                        ExtElement winElement = Ext.get(imgZoom.getElement());
                                                        winElement.setHeight(tailleImage[1], false);
                                                        winElement.setWidth(tailleImage[0], false);
                                                }
                                        }
                                        
                                });
                                
                        } else {
                                imgAgrandie.setUrl(urlAgrandie);
                                imgAgrandie.setVisible(true);
                        }
        }
        
        private String getUrlMiniature(int index) {
                
                String[][] paramsImage = {{"id_image",infosImages[index][0]}};
                ImageCarnet ic = new ImageCarnet(paramsImage);
                
                return ic.getUrlFormatGalerie();
        }
        
        private String getUrlAgrandie(int index) {
                String[][] paramsImage = {{"id_image",infosImages[index][0]}};
                ImageCarnet ic = new ImageCarnet(paramsImage);
                
                return ic.getUrlFormatZoom();
        }
        
        private void afficherPanneauAgrandi() {
                agrandirImage();
                imgZoom.show(this.getElement());
                imgZoom.setPosition((int)(Window.getClientWidth() - Window.getClientWidth()*0.50),(int)(Window.getClientHeight() - Window.getClientHeight()*0.85));
        }
}