Subversion Repositories eFlore/Applications.cel

Rev

Rev 207 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
195 david 1
package org.tela_botanica.client.vues.image;
2 aperonnet 2
 
3
import org.tela_botanica.client.image.ImageMediateur;
4
import org.tela_botanica.client.interfaces.Rafraichissable;
5
 
6
import com.google.gwt.user.client.Event;
207 aurelien 7
import com.google.gwt.user.client.Timer;
8
import com.google.gwt.user.client.Window;
2 aperonnet 9
import com.google.gwt.user.client.ui.ClickListener;
10
import com.google.gwt.user.client.ui.Image;
207 aurelien 11
import com.google.gwt.user.client.ui.LoadListener;
12
import com.google.gwt.user.client.ui.MouseWheelListener;
13
import com.google.gwt.user.client.ui.MouseWheelVelocity;
2 aperonnet 14
import com.google.gwt.user.client.ui.Widget;
207 aurelien 15
import com.gwtext.client.core.AnimationConfig;
5 aperonnet 16
import com.gwtext.client.core.EventObject;
207 aurelien 17
import com.gwtext.client.core.Ext;
18
import com.gwtext.client.core.ExtElement;
19
 
2 aperonnet 20
import com.gwtext.client.core.RegionPosition;
5 aperonnet 21
import com.gwtext.client.dd.DragData;
22
import com.gwtext.client.dd.DragSource;
23
import com.gwtext.client.dd.DropTarget;
24
import com.gwtext.client.dd.DropTargetConfig;
2 aperonnet 25
import com.gwtext.client.widgets.Container;
26
import com.gwtext.client.widgets.Panel;
99 jpm 27
import com.gwtext.client.widgets.ToolTip;
2 aperonnet 28
import com.gwtext.client.widgets.event.PanelListenerAdapter;
5 aperonnet 29
import com.gwtext.client.widgets.grid.GridDragData;
2 aperonnet 30
import com.gwtext.client.widgets.layout.BorderLayout;
31
import com.gwtext.client.widgets.layout.BorderLayoutData;
32
 
33
/**
34
 * Panneau d'affichage d'une image avec des boutons précdents et suivant
5 aperonnet 35
 *
2 aperonnet 36
 * @author aurelien
5 aperonnet 37
 *
2 aperonnet 38
 */
39
public class ZoomImageVue extends Panel implements Rafraichissable {
5 aperonnet 40
 
2 aperonnet 41
	/**
42
	 * Le médiateur associé à la vue
43
	 */
5 aperonnet 44
	private ImageMediateur iMediateur = null;
45
 
2 aperonnet 46
	/**
47
	 * Panneau conteneur pour l'image
48
	 */
5 aperonnet 49
	private Panel imageConteneur = null;
2 aperonnet 50
	/**
51
	 * l'image à afficher
52
	 */
5 aperonnet 53
	private Image image = new Image("vide.jpg");
2 aperonnet 54
	/**
55
	 * Bouton précédent
56
	 */
57
	private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button();
58
	/**
59
	 * Bouton suivant
60
	 */
61
	private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button();
5 aperonnet 62
 
2 aperonnet 63
	/**
64
	 * Taille originale Y de l'image
65
	 */
5 aperonnet 66
	private int imageHeight = 0;
67
 
2 aperonnet 68
	/**
69
	 * Taille originale X de l'image
70
	 */
5 aperonnet 71
	private int imageWidth = 0;
2 aperonnet 72
 
73
	/**
5 aperonnet 74
	 * Identifiant de l'image
75
	 */
76
	private String idImage = "0" ;
77
 
78
	/**
2 aperonnet 79
	 * Booleen d'initalisation général
80
	 */
5 aperonnet 81
	private boolean initialise = false;
82
 
2 aperonnet 83
	/**
84
	 * Booleen d'initalisation du conteneur d'image
85
	 */
5 aperonnet 86
	private boolean conteneurInitialise = false;
99 jpm 87
 
88
	private ToolTip tp = new ToolTip("<div class=\"x-tooltip-help\"> Double cliquez pour revenir à la vue précédente, utilisez la roulette ou les boutons fléchés pour faire défiler les images </div>") ;
5 aperonnet 89
 
2 aperonnet 90
	/**
207 aurelien 91
	 * true pour animer les transitions des animations
92
	 */
93
	private boolean animerTransition = false;
94
 
95
	/**
96
	 * duree des animation
97
	 */
98
	private float dureeAnimation = (float) 0.15 ;
99
 
100
	/**.
101
	 * boolean de gestion du double clic
102
	 */
103
	private boolean enClic = false;
104
 
105
	/**
2 aperonnet 106
	 * Constructeur sans argument (privé car ne doit être utilisé)
107
	 */
108
	@SuppressWarnings("unused")
5 aperonnet 109
	private ZoomImageVue() {
110
		super();
2 aperonnet 111
	}
5 aperonnet 112
 
2 aperonnet 113
	/**
114
	 * Constructeur avec argument
5 aperonnet 115
	 *
116
	 * @param im
117
	 *            le médiateur à associer à la vue
2 aperonnet 118
	 */
5 aperonnet 119
	public ZoomImageVue(ImageMediateur im) {
2 aperonnet 120
		super("Zoom");
5 aperonnet 121
		setId("x-view-zoom-panel");
2 aperonnet 122
		// on associe le médiateur
5 aperonnet 123
		iMediateur = im;
2 aperonnet 124
 
5 aperonnet 125
		prev.setStylePrimaryName("x-view-zoom-button-p");
126
		suiv.setStylePrimaryName("x-view-zoom-button-s");
127
 
2 aperonnet 128
		// on crée une image qui gère le double clic et la roulette de la souris
207 aurelien 129
		image = new Image();
130
 
5 aperonnet 131
		this.setHeader(false);
132
 
207 aurelien 133
		imageConteneur = new Panel();
134
 
2 aperonnet 135
		imageConteneur.setBorder(false);
5 aperonnet 136
 
137
		imageConteneur.add(image);
138
		imageConteneur.setId("x-view-zoom-img");
139
 
140
		// il n'existe pas de méthode pour ajouter un listener pour le double
141
		// clic sur une image
2 aperonnet 142
		// alors on lui dit manuellement de capter l'évènement double clic
207 aurelien 143
		//imageConteneur.sinkEvents(Event.ONMOUSEWHEEL);
5 aperonnet 144
 
2 aperonnet 145
		// l'image de base est vide
146
		image.setUrl("vide.jpg");
5 aperonnet 147
 
2 aperonnet 148
		this.setLayout(new BorderLayout());
5 aperonnet 149
 
2 aperonnet 150
		prev.setWidth("60px");
151
		suiv.setWidth("60px");
5 aperonnet 152
 
153
		this.add(prev, new BorderLayoutData(RegionPosition.WEST));
154
		this.add(imageConteneur, new BorderLayoutData(RegionPosition.CENTER));
155
		this.add(suiv, new BorderLayoutData(RegionPosition.EAST));
156
 
157
		imageConteneur.setMaskDisabled(true);
2 aperonnet 158
		this.setBorder(false);
5 aperonnet 159
 
160
		conteneurInitialise = true;
161
		initialise = true;
2 aperonnet 162
 
5 aperonnet 163
		configDragAndDrop() ;
164
 
2 aperonnet 165
		// on ajoute les listeners
166
		ajouterListeners();
99 jpm 167
 
100 jpm 168
		tp.setDismissDelay(1750);
99 jpm 169
		tp.applyTo(image.getElement()) ;
2 aperonnet 170
 
171
	}
172
 
173
	/**
174
	 * Méthode héritée de l'interface rafraichissable
5 aperonnet 175
	 *
176
	 * @param nouvelleDonnees
177
	 *            les nouvelles données
178
	 * @param repandreRafraichissement
179
	 *            le booleen qui dit si on doit répnadre l'évènement
2 aperonnet 180
	 */
5 aperonnet 181
	public void rafraichir(Object nouvelleDonnees,
182
			boolean repandreRafraichissement) {
183
 
2 aperonnet 184
		// si on reçoit une string
5 aperonnet 185
		if (nouvelleDonnees instanceof String[] && initialise
186
				&& conteneurInitialise) {
187
			String[] infos = (String[]) nouvelleDonnees;
2 aperonnet 188
			// c'est l'url de l'image qu'on associe à la vue
5 aperonnet 189
			if (infos[0] != null && infos[1] != null && infos[2] != null && infos[3] != null) {
190
				getImage().setUrl(infos[0]);
191
				int x = Integer.parseInt(infos[1]);
192
				int y = Integer.parseInt(infos[2]);
193
 
194
				setTailleImage(x, y);
2 aperonnet 195
 
5 aperonnet 196
				setIdImage(infos[3]) ;
197
 
207 aurelien 198
				//verifierEtRetaillerImage();
2 aperonnet 199
			}
5 aperonnet 200
		} else {
2 aperonnet 201
			// sinon on met une image vide
40 david 202
			getImage().setUrl("vide.jpg");
2 aperonnet 203
		}
204
	}
5 aperonnet 205
 
2 aperonnet 206
	/**
207
	 * Desactive visuellement le panneau et les boutons
208
	 */
5 aperonnet 209
	public void desactiverPanneau() {
210
		getImage().setUrl("vide.jpeg");
211
		prev.setEnabled(false);
2 aperonnet 212
		suiv.setEnabled(false);
213
	}
5 aperonnet 214
 
2 aperonnet 215
	/**
216
	 * Active visuellement le panneau et les boutons
217
	 */
5 aperonnet 218
	public void activerPanneau() {
2 aperonnet 219
		prev.setEnabled(true);
220
		suiv.setEnabled(true);
221
	}
225 aurelien 222
 
223
	public void masquerChargement() {
224
		ExtElement imgEl = Ext.get(imageConteneur.getElement());
225
		if(imgEl != null && !imgEl.isMasked()) {
226
			imgEl.mask("Chargement");
227
		}
228
	}
229
 
230
	public void demasquerChargement() {
231
		ExtElement imgEl = Ext.get(imageConteneur.getElement());
232
		if(imgEl != null && imgEl.isMasked()) {
233
			imgEl.unmask();
234
		}
235
	}
5 aperonnet 236
 
2 aperonnet 237
	/**
238
	 * Ajoute les listeners pour la gestions d'évènement
239
	 */
5 aperonnet 240
	public void ajouterListeners() {
241
 
207 aurelien 242
		image.addLoadListener(new LoadListener() {
243
 
244
			public void onError(Widget sender) {
245
				// TODO Auto-generated method stub
246
			}
247
 
248
			public void onLoad(Widget sender) {
249
 
250
				int max = Math.min(imageConteneur.getHeight(), imageConteneur.getWidth());
251
				int[] tailleImage = calculerDimensions(getTailleImage(), max, max);
252
				ExtElement imgElement = Ext.get(image.getElement());
253
				if(animerTransition) {
254
					AnimationConfig a = new AnimationConfig() ;
255
					a.setDuration((float) dureeAnimation);
256
					imgElement.setHeight(tailleImage[1], a);
257
					imgElement.setWidth(tailleImage[0], a);
258
				} else {
259
					imgElement.setHeight(tailleImage[1], false);
260
					imgElement.setWidth(tailleImage[0], false);
261
				}
225 aurelien 262
				demasquerChargement();
207 aurelien 263
			}
264
 
265
		});
266
 
267
		image.addClickListener(new ClickListener() {
268
 
269
			public void onClick(Widget sender) {
270
 
271
					if(enClic) {
272
						getIMediateur().doubleClicZoomImage();
273
					} else {
274
						Timer t = new Timer() {
275
							public void run() {
276
								enClic = false;
277
							}
278
 
279
						};
280
						enClic = true;
281
						t.schedule(800);
282
					}
283
			}
284
 
285
		});
286
 
287
		image.addMouseWheelListener(new MouseWheelListener() {
288
 
289
			public void onMouseWheel(Widget sender, MouseWheelVelocity velocity) {
290
 
291
				if(velocity.getDeltaY() > 0) {
292
					suiv.click();
293
				} else {
294
					prev.click();
295
				}
296
			}
297
 
298
		});
299
 
2 aperonnet 300
		// gestion du clic sur le bouton précedent
301
		prev.addClickListener(new ClickListener() {
302
 
303
			// en cas de clic
304
			public void onClick(Widget sender) {
305
				// on notifie le médiateur
225 aurelien 306
				masquerChargement();
2 aperonnet 307
				getIMediateur().clicBoutonZoomImage("prev");
308
			}
5 aperonnet 309
 
2 aperonnet 310
		});
5 aperonnet 311
 
2 aperonnet 312
		// gestion du clic sur le bouton suivant
313
		suiv.addClickListener(new ClickListener() {
314
 
315
			// en cas de clic
316
			public void onClick(Widget sender) {
5 aperonnet 317
				// on notifie le médiateur
225 aurelien 318
				masquerChargement();
2 aperonnet 319
				getIMediateur().clicBoutonZoomImage("suiv");
320
			}
5 aperonnet 321
 
2 aperonnet 322
		});
5 aperonnet 323
 
2 aperonnet 324
		// gestion du redimensionnement
325
		this.addListener(new PanelListenerAdapter() {
5 aperonnet 326
 
2 aperonnet 327
			// lors d'un redimensionnement de l'application
5 aperonnet 328
 
329
			public void onBodyResize(Panel panel, java.lang.String width,
330
					java.lang.String height) {
2 aperonnet 331
				// on vérifie et on retaille l'image
5 aperonnet 332
				verifierEtRetaillerImage();
2 aperonnet 333
			}
5 aperonnet 334
		});
335
 
2 aperonnet 336
		// gestion du redimensionnement lors de l'affichage du conteneur
337
		imageConteneur.addListener(new PanelListenerAdapter() {
5 aperonnet 338
 
2 aperonnet 339
			// avant de finir d'afficher
5 aperonnet 340
 
341
			public void onAfterLayout(Container self) {
2 aperonnet 342
				// on redimensionne
5 aperonnet 343
				verifierEtRetaillerImage();
2 aperonnet 344
			}
5 aperonnet 345
		});
2 aperonnet 346
	}
347
 
348
	/**
5 aperonnet 349
	 * Verifie si l'image est plus grande que le conteneur et la retaille le cas
350
	 * echeant
2 aperonnet 351
	 */
5 aperonnet 352
	public void verifierEtRetaillerImage() {
2 aperonnet 353
		// si l'image est nulle
5 aperonnet 354
		if (image == null) {
2 aperonnet 355
			// on ne fait rien
5 aperonnet 356
			return;
357
		}
358
 
2 aperonnet 359
		// on prend la taille originale de l'image
5 aperonnet 360
		int originalX = getTailleImage()[0];
361
		int originalY = getTailleImage()[1];
362
 
363
		// on la transforme en float (la division entre entier donne de curieux
364
		// résultats)
365
		float fOriginalX = (new Float(originalX)).floatValue();
366
		float fOriginalY = (new Float(originalY)).floatValue();
367
 
2 aperonnet 368
		// et on fait le rapport longueur sur hauteur (pour connaitre le ratio)
5 aperonnet 369
		float rapportTaille = fOriginalX / fOriginalY;
370
 
2 aperonnet 371
		// la nouvelle taille est pour le moment égale à l'ancienne
5 aperonnet 372
		int nouvelleTailleX = originalX;
373
		int nouvelleTailleY = originalY;
374
 
2 aperonnet 375
		// on prend la taille du conteneur
5 aperonnet 376
		int tailleConteneurX = imageConteneur.getWidth();
377
		int tailleConteneurY = imageConteneur.getHeight();
378
 
2 aperonnet 379
		// si celle-ci est égale à 0 (conteneur mal initialisé)
5 aperonnet 380
		/*
381
		 * if(imageConteneur.getHeight() == 0 && tailleConteneurX == 0) { // on
382
		 * essaie de la calculer en fonction de la taille du parent et des
383
		 * frères tailleConteneurY = this.getHeight() ; tailleConteneurX =
384
		 * this.getWidth() - prev.getOffsetWidth() * 2 ;
385
		 *  }
386
		 */
387
 
388
		// si l'image ne rentre pas telle quelle (longueur ou hauteur trop
389
		// grande)
390
		if (originalY > tailleConteneurY || originalX > tailleConteneurX) {
2 aperonnet 391
			// si la longueur de l'image est la plus grande des deux
5 aperonnet 392
			if (originalX > originalY) {
393
				// on prend la longueur comme taille de référence, qu'on met à
394
				// la longueur du conteneur
395
				nouvelleTailleX = tailleConteneurX;
396
				// et on recalcule la hauteur, par rapport à la nouvelle
397
				// longueur, en gardant le format de 'limage
398
				nouvelleTailleY = (int) Math.floor(nouvelleTailleX * 1
399
						/ rapportTaille);
400
			} else {
401
				// si la hauteur est la plus grande, on fait le même genre
402
				// d'opération en prenant la hauteur comme référence
403
				nouvelleTailleY = tailleConteneurY;
404
				nouvelleTailleX = (int) Math.floor(nouvelleTailleY
405
						* rapportTaille);
2 aperonnet 406
			}
407
		}
5 aperonnet 408
 
2 aperonnet 409
		// on modifie enfin la taille de l'image pour qu'elle soit affichée
5 aperonnet 410
		getImage().setSize("" + nouvelleTailleX + "px",
411
				"" + nouvelleTailleY + "px");
2 aperonnet 412
	}
5 aperonnet 413
 
207 aurelien 414
	public int[] calculerDimensions(int[] tailleXY, double tailleMax, double tailleConteneur) {
415
 
416
		float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
417
        float tailleOr = Math.min(new Float(tailleMax),new Float(tailleConteneur)) ;
418
        float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
419
        float[] XYresize = new float[2];
420
 
421
        if(maxTaille == tailleXY[0]) {
422
            float rapport = tailleXYf[1]/tailleXYf[0] ;
423
            XYresize[0] = tailleOr ;
424
            XYresize[1] = tailleOr*rapport ;
425
        }else {
426
            float rapport = tailleXYf[0]/tailleXYf[1] ;
427
            XYresize[1] = tailleOr ;
428
            XYresize[0] = tailleOr*rapport ;
429
        }
430
 
431
        int[] res = {Math.round(XYresize[0]),Math.round(XYresize[1])} ;
432
 
433
        return res;
434
    }
435
 
5 aperonnet 436
	public void configDragAndDrop()
437
	{
2 aperonnet 438
 
5 aperonnet 439
		// on fabrique la nouvelle configuration
440
		// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroup
441
		DropTargetConfig dtc = new DropTargetConfig();
442
		dtc.setdDdGroup("DragGroupName");
443
 
444
		//La drop target permet de gérer l'évenement onDrop sur l'élement courant
445
		@SuppressWarnings("unused")
446
		DropTarget tg = new DropTarget(this, dtc)
447
		{
448
			public boolean notifyDrop(DragSource source, EventObject e, DragData data){
449
 
450
				// si on reçoit des données provenant d'une grille
451
				if(data instanceof GridDragData)
452
		    	  {
453
		    		  		// on appelle le médiateur
454
		    		  		return iMediateur.lierObsDD(source, e, data,getId()) ;
455
		    	  }
456
				return false ;
457
			}
458
 
459
			public String notifyOver(DragSource source, EventObject e, DragData data){
460
			    return "x-dd-drop-ok";
461
			}
462
		};
463
 
464
	}
465
 
2 aperonnet 466
	/**
467
	 * Accesseur pour le médiateur
5 aperonnet 468
	 *
2 aperonnet 469
	 * @return le médiateur associé à la vue
470
	 */
471
	public ImageMediateur getIMediateur() {
472
		return iMediateur;
473
	}
474
 
475
	/**
476
	 * Accesseur au conteneur de l'image
5 aperonnet 477
	 *
2 aperonnet 478
	 * @return le conteneur de l'image
479
	 */
480
	public Image getImage() {
481
		return image;
482
	}
5 aperonnet 483
 
484
	/**
485
	 * Acesseurs pour l'identifiant de l'image
486
	 * @return l'id de l'image
487
	 */
488
	public String getIdImage()
489
	{
490
		return idImage ;
491
	}
2 aperonnet 492
 
493
	/**
494
	 * Accesseur pour le bouton précédent
5 aperonnet 495
	 *
2 aperonnet 496
	 * @return le bouton précédent
497
	 */
498
	public com.google.gwt.user.client.ui.Button getPrev() {
499
		return prev;
500
	}
501
 
502
	/**
503
	 * Accesseur pour le bouton suivant
5 aperonnet 504
	 *
2 aperonnet 505
	 * @return le bouton suivant
506
	 */
507
	public com.google.gwt.user.client.ui.Button getSuiv() {
508
		return suiv;
509
	}
5 aperonnet 510
 
2 aperonnet 511
	/**
512
	 * Setter pour la taille de l'image
5 aperonnet 513
	 *
7 aperonnet 514
	 * @param x
5 aperonnet 515
	 *            la largeur en pixels
7 aperonnet 516
	 * @param y
5 aperonnet 517
	 *            la hauteur en pixels
2 aperonnet 518
	 */
5 aperonnet 519
	public void setTailleImage(int x, int y) {
520
		imageHeight = y;
521
		imageWidth = x;
2 aperonnet 522
	}
523
 
524
	/**
5 aperonnet 525
	 * Setteur pour l'identifiant de l'image
526
	 * @param id le nouvel identifiant
527
	 */
528
	public void setIdImage(String id)
529
	{
530
		idImage = id ;
531
	}
532
 
533
	/**
2 aperonnet 534
	 * renvoie la taille originale de l'image
5 aperonnet 535
	 *
2 aperonnet 536
	 * @return un tableau de deux entiers contenant la largeur puis la hauteur
537
	 */
5 aperonnet 538
	public int[] getTailleImage() {
539
		int[] taille = { imageHeight, imageWidth };
540
 
541
		return taille;
2 aperonnet 542
	}
5 aperonnet 543
 
544
	/**
545
	 * Accesseur pour le conteneur de l'image
546
	 * @return le conteur de l'image
547
	 */
548
	public Panel getImageConteneur() {
2 aperonnet 549
 
5 aperonnet 550
		return imageConteneur;
551
 
2 aperonnet 552
	}
553
}