Subversion Repositories eFlore/Applications.del

Rev

Rev 412 | Rev 446 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package org.tela_botanica.del.client.composants.pagination;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasChangeHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;

/**
 * @author gregoire Pagination GENERIQUE qui permet d'afficher un nombre donné
 *         d'éléments (pas) La méthode changerPage est abstraite et doit être
 *         définie lors de l'instanciation de la classe pagination pour
 *         permettre d'afficher la suite des éléments La méthode
 *         actualiserPasCache est abstraite car le pas est différent en fonction
 *         de la page où l'on se trouve
 * */
public abstract class PaginationPresenteur {

        public interface Vue extends IsWidget {

                public HasWidgets getZoneLiens();

                public int getNbWidgetsZoneLiens();

                public HasClickHandlers getWidgetZoneLiensHasClickHandlers(int index);

                public HasText getWidgetZoneLiensAsText(int index);

                public void changerStyleBoutonZoneLiens(int index, String style);

                public void ajouterBoutonZoneLiens(String label);

                public HasClickHandlers getBoutonSuivant();

                public HasClickHandlers getBoutonPrecedent();

                public HasClickHandlers getBoutonPremierePage();

                public HasClickHandlers getBoutonDernierePage();

                public void masquerBoutonPrecedent();

                public void afficherBoutonPrecedent();

                public void masquerBoutonSuivant();

                public void afficherBoutonSuivant();

                public boolean boutonPrecedentEstAffiche();

                public boolean boutonSuivantEstAffiche();

                public HasChangeHandlers getSelecteurPas();

                public int getPasSelectionne();

                public void changerSelecteurPas(int index);
        }

        private Vue vue;
        private int nbPage;
        private int pageCourante = 1;
        private int nbElementsTotal = 0;
        private int pas = 10;

        /**
         * Constructeur de l'application
         * 
         * @param nbElementsTotal
         *            : le nombre total des éléments à paginer
         * @param pas
         *            : le nombre d'éléments à afficher par page
         * */
        public PaginationPresenteur(Vue vue, int nbElementsTotal, int pas) {
                this.nbElementsTotal = nbElementsTotal;
                this.vue = vue;
                changerPas(this.pas);
        }

        /**
         * Methode go du modèle MVP
         * 
         * @param container
         *            : la vue ou éxécuter l'affichage
         */
        public void go(HasWidgets container) {
                gererEvenementsBoutonsStatiques();
                actualiserLiens();
                container.add(vue.asWidget());
        }

        /** Met à jour le nombre de page en fonction du pas */
        public void actualiserNbPage() {
                Double nombrePages = Math.ceil((double) nbElementsTotal / (double) pas);
                this.nbPage = nombrePages.intValue();
        }

        public void setNbPages(int nbPages) {
                this.nbPage = nbPages;
        }

        public int getNbPages() {
                return nbPage;
        }

        public Vue getVue() {
                return vue;
        }

        /**
         * Changer le pas de la pagination
         * 
         * @param pas
         *            : le nombre d'éléments à afficher par page
         */
        public void changerPas(int pas) {
                int ancienPas = this.pas;
                setPas(pas);
                actualiserNbPage();
                gererDecalagePageCourante(ancienPas, pas);
                changerPage(pas * (pageCourante - 1), pas * pageCourante);
                actualiserLiens();
                actualiserPasCache(pas);
        }

        public void setPas(int pas) {
                this.pas = pas;
                switch (pas) {
                case 5:
                        vue.changerSelecteurPas(0);
                        break;
                case 10:
                        vue.changerSelecteurPas(1);
                        break;
                case 15:
                        vue.changerSelecteurPas(2);
                        break;
                case 20:
                        vue.changerSelecteurPas(3);
                        break;
                default:
                        break;
                }
        }

        private void gererDecalagePageCourante(int ancienPas, int nouveauPas) {
                if (ancienPas != nouveauPas) {
                        double rapportPas = (double) ancienPas / (double) nouveauPas;
                        pageCourante = (int) (Math.ceil((double) pageCourante * (double) rapportPas));
                }
        }

        /**
         * Actualiser les liens pour n'afficher 5 avant et 5 après
         * */
        public void actualiserLiens() {

                HasWidgets zoneLiens = vue.getZoneLiens();
                zoneLiens.clear();

                int pageDebut = pagesAvant();
                int pageFin = pagesApres();

                for (int i = pageDebut; i < pageFin; i++) {
                        vue.ajouterBoutonZoneLiens(i + "");
                }
                setBoutonActif();
                gererEvenementsBoutonsDynamiques();
        }

        private int pagesAvant() {
                int pageDebut = pageCourante - 5;
                if (pageDebut < 1) {
                        pageDebut = 1;
                }
                if (pageCourante == 1) {
                        vue.masquerBoutonPrecedent();
                } else {
                        vue.afficherBoutonPrecedent();
                }
                return pageDebut;
        }

        private int pagesApres() {
                int pageFin = pageCourante + 5;
                vue.afficherBoutonSuivant();
                if (pageFin > nbPage) {
                        pageFin = nbPage;
                }
                if (pageCourante == nbPage - 1) {
                        vue.masquerBoutonSuivant();
                } else {
                        vue.afficherBoutonSuivant();
                }

                return pageFin;
        }

        private void setBoutonActif() {
                int nbLiens = vue.getNbWidgetsZoneLiens();
                for (int i = 0; i < nbLiens; i++) {
                        HasText boutonCourant = vue.getWidgetZoneLiensAsText(i);
                        if (boutonCourant.getText().equals(String.valueOf(pageCourante))) {
                                vue.changerStyleBoutonZoneLiens(i, "actif");
                        } else {
                                vue.changerStyleBoutonZoneLiens(i, "inactif");
                        }
                }
        }

        /**
         * Gérer les évènements sur les boutons statiques (précédent, suivant et
         * selecteur pas)
         * */
        public void gererEvenementsBoutonsStatiques() {
                vue.getSelecteurPas().addChangeHandler(new ChangeHandler() {
                        @Override
                        public void onChange(ChangeEvent event) {
                                changerPas(vue.getPasSelectionne());
                                synchroniser();
                        }
                });

                vue.getBoutonPrecedent().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                pagePrecedente();
                        }
                });

                vue.getBoutonSuivant().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                pageSuivante();
                        }
                });

                vue.getBoutonPremierePage().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                premierePage();
                        }
                });

                vue.getBoutonDernierePage().addClickHandler(new ClickHandler() {
                        @Override
                        public void onClick(ClickEvent event) {
                                dernierePage();
                        }
                });
        }

        /**
         * Gérer les évènements sur les boutons dynamiques (qui sont recréés à
         * chaque fois)
         * */
        public void gererEvenementsBoutonsDynamiques() {
                int nbLiens = vue.getNbWidgetsZoneLiens();
                for (int i = 0; i < nbLiens; i++) {
                        HasClickHandlers boutonCourant = vue.getWidgetZoneLiensHasClickHandlers(i);
                        boutonCourant.addClickHandler(new ClickHandler() {
                                @Override
                                public void onClick(ClickEvent event) {
                                        HasText boutonCourant = (HasText) event.getSource();
                                        pageCourante = Integer.parseInt(boutonCourant.getText());
                                        int debut = (Integer.parseInt(boutonCourant.getText()) - 1) * pas;
                                        int fin = (debut + pas);
                                        setBoutonActif();
                                        changerPage(debut, fin);
                                        actualiserLiens();
                                        synchroniser();
                                }
                        });
                }
        }

        public void premierePage() {
                if (pageCourante > 1) {
                        pageCourante = 1;
                        int debut = (pageCourante - 1) * pas;
                        int fin = debut + pas;
                        changerPage(debut, fin);
                        actualiserLiens();
                        synchroniser();
                }
        }

        public void dernierePage() {
                if (pageCourante < nbPage - 1) {
                        pageCourante = nbPage - 1;
                        int debut = (pageCourante - 1) * pas;
                        int fin = debut + pas;
                        changerPage(debut, fin);
                        actualiserLiens();
                        synchroniser();
                }
        }

        public void pageSuivante() {
                if (pageCourante < nbPage - 1) {
                        pageCourante++;
                        int debut = (pageCourante - 1) * pas;
                        int fin = debut + pas;
                        changerPage(debut, fin);
                        actualiserLiens();
                        synchroniser();
                }
        }

        public void pagePrecedente() {
                if (pageCourante > 1) {
                        pageCourante--;
                        int debut = (pageCourante - 1) * pas;
                        int fin = debut + pas;
                        changerPage(debut, fin);
                        actualiserLiens();
                        synchroniser();
                }
        }

        public int getPageCourante() {
                return this.pageCourante;
        }

        public int getPas() {
                return this.pas;
        }

        public void setPageCourante(int pageCourante) {
                this.pageCourante = pageCourante;
        }

        public abstract void changerPage(int debut, int fin);

        public abstract void actualiserPasCache(int pas);

        public void synchroniser() {
                setPas(getPas());
                setPageCourante(getPageCourante());
                setNbPages(getNbPages());
                actualiserLiens();
        }

}