Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
199 david 1
package org.tela_botanica.client.vues.observation.indicateurs;
94 jpm 2
 
3
import org.tela_botanica.client.interfaces.Rafraichissable;
104 jpm 4
import org.tela_botanica.client.modeles.Configuration;
94 jpm 5
import org.tela_botanica.client.observation.ObservationMediateur;
6
 
338 aurelien 7
import com.google.gwt.event.dom.client.ClickEvent;
8
import com.google.gwt.event.dom.client.ClickHandler;
9
import com.google.gwt.event.dom.client.LoadEvent;
10
import com.google.gwt.event.dom.client.LoadHandler;
94 jpm 11
import com.google.gwt.user.client.DOM;
12
import com.google.gwt.user.client.Event;
213 aurelien 13
import com.google.gwt.user.client.Window;
94 jpm 14
import com.google.gwt.user.client.ui.ClickListener;
15
import com.google.gwt.user.client.ui.Image;
213 aurelien 16
import com.google.gwt.user.client.ui.LoadListener;
94 jpm 17
import com.google.gwt.user.client.ui.Widget;
213 aurelien 18
import com.gwtext.client.core.AnimationConfig;
94 jpm 19
import com.gwtext.client.core.EventObject;
213 aurelien 20
import com.gwtext.client.core.Ext;
21
import com.gwtext.client.core.ExtElement;
94 jpm 22
import com.gwtext.client.core.RegionPosition;
23
import com.gwtext.client.widgets.Panel;
213 aurelien 24
import com.gwtext.client.widgets.ToolTip;
94 jpm 25
import com.gwtext.client.widgets.layout.BorderLayout;
26
import com.gwtext.client.widgets.layout.BorderLayoutData;
104 jpm 27
import com.gwtext.client.widgets.menu.BaseItem;
28
import com.gwtext.client.widgets.menu.Item;
29
import com.gwtext.client.widgets.menu.Menu;
30
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter;
94 jpm 31
 
32
/**
33
 * Panneau d'affichage d'une image avec des boutons précdents et suivant
34
 *
35
 * @author aurelien
36
 *
37
 */
38
public class MiniZoomImageVue extends Panel implements Rafraichissable {
39
 
40
	/**
41
	 * Le médiateur associé à la vue
42
	 */
43
	private ObservationMediateur oMediateur = null;
245 aurelien 44
 
45
	/**
46
	 * Le titre du panneau
47
	 */
48
	private static String titrePanneau = "Images liées";
94 jpm 49
 
50
	/**
51
	 * Panneau conteneur pour l'image
52
	 */
53
	private Panel imageConteneur = null;
54
	/**
55
	 * l'image à afficher
56
	 */
97 jpm 57
	private Image image = new Image("");
94 jpm 58
	/**
59
	 * Bouton précédent
60
	 */
61
	private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button();
62
	/**
63
	 * Bouton suivant
64
	 */
65
	private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button();
66
 
67
	/**
68
	 * Taille originale Y de l'image
69
	 */
70
	private int imageHeight = 0;
71
 
72
	/**
73
	 * Taille originale X de l'image
74
	 */
75
	private int imageWidth = 0;
76
 
77
	/**
78
	 * Identifiant de l'image
79
	 */
80
	private String idImage = "0" ;
81
 
213 aurelien 82
	private String[] infosImages[] = null ;
94 jpm 83
 
84
	private int index = 0 ;
85
 
86
	/**
213 aurelien 87
	 * true pour animer les transitions
88
	 */
89
	private boolean animerTransition = false;
90
	/**
91
	 * Détermine la durée de la transition
92
	 */
93
	private float dureeAnimation = (float) 0.15;
94
 
95
	/**
94 jpm 96
	 * Booleen d'initalisation général
97
	 */
98
	private boolean initialise = false;
99
 
100
	/**
101
	 * Booleen d'initalisation du conteneur d'image
102
	 */
103
	private boolean conteneurInitialise = false;
213 aurelien 104
 
105
	private ToolTip tp = new ToolTip("<div class=\"x-tooltip-help\"> Double cliquez pour agrandir l'image </div>") ;
106
 
107
	com.gwtext.client.widgets.Window imgZoom = new com.gwtext.client.widgets.Window("Agrandissement") ;
108
 
109
	Image imgAgrandie = null;
94 jpm 110
 
111
	/**
112
	 * Constructeur sans argument (privé car ne doit être utilisé)
113
	 */
114
	@SuppressWarnings("unused")
115
	private MiniZoomImageVue() {
116
		super();
117
	}
118
 
119
	/**
120
	 * Constructeur avec argument
121
	 *
122
	 * @param im
123
	 *            le médiateur à associer à la vue
124
	 */
125
	public MiniZoomImageVue(ObservationMediateur im) {
245 aurelien 126
		super(titrePanneau);
94 jpm 127
		setId("x-view-mini-zoom-panel");
128
		// on associe le médiateur
129
		oMediateur = im;
130
 
131
		prev.setStylePrimaryName("x-view-zoom-button-p");
132
		suiv.setStylePrimaryName("x-view-zoom-button-s");
133
 
213 aurelien 134
		imgZoom.setCloseAction(com.gwtext.client.widgets.Window.HIDE) ;
298 aurelien 135
		imgZoom.setConstrain(true);
213 aurelien 136
 
94 jpm 137
		// on crée une image qui gère le double clic et la roulette de la souris
138
		image = new Image() {
139
 
140
			public void onBrowserEvent(Event event) {
141
 
142
				// lors d'un déplacement de la roulette
143
				if (Event.ONMOUSEWHEEL == DOM.eventGetType(event)) {
144
 
145
					// on simule un clic sur le bouton précédent
146
					if (event.getMouseWheelVelocityY() >= 1) {
147
						prev.click();
148
					}
149
 
150
					// ou suivant
151
					if (event.getMouseWheelVelocityY() <= -1) {
152
						suiv.click();
153
					}
154
				}
104 jpm 155
 
156
				if(Event.ONCONTEXTMENU == DOM.eventGetType(event)) {
157
 
158
					event.preventDefault() ;
159
					int[] xy = {event.getClientX(),event.getClientY()} ;
160
					afficherMenu(xy) ;
161
				}
213 aurelien 162
 
163
				// lors du double clic
164
				if (Event.ONDBLCLICK == DOM.eventGetType(event)) {
279 aurelien 165
					if(imgZoom.isVisible()) {
166
							imgZoom.hide();
167
					} else {
168
						afficherPanneauAgrandi();
169
					}
213 aurelien 170
				}
94 jpm 171
			}
172
 
173
		};
174
 
130 aurelien 175
		image.setPixelSize(150, 150);
176
 
213 aurelien 177
		infosImages = new String[0][0] ;
94 jpm 178
 
179
		this.setHeader(true);
180
 
181
		imageConteneur = new Panel() ;
182
		imageConteneur.setBorder(false);
183
 
184
		imageConteneur.add(image);
185
		imageConteneur.setId("x-view-mini-zoom-img");
186
 
187
		// il n'existe pas de méthode pour ajouter un listener pour le double
188
		// clic sur une image
189
		// alors on lui dit manuellement de capter l'évènement double clic
190
		image.sinkEvents(Event.ONDBLCLICK);
191
		image.sinkEvents(Event.ONMOUSEWHEEL);
104 jpm 192
		image.sinkEvents(Event.ONCONTEXTMENU) ;
94 jpm 193
 
194
		// l'image de base est vide
97 jpm 195
		image.setUrl("");
94 jpm 196
 
197
		this.setLayout(new BorderLayout());
198
 
130 aurelien 199
		prev.setWidth("15%");
200
		suiv.setWidth("15%");
94 jpm 201
 
202
		this.add(prev, new BorderLayoutData(RegionPosition.WEST));
203
		this.add(imageConteneur, new BorderLayoutData(RegionPosition.CENTER));
204
		this.add(suiv, new BorderLayoutData(RegionPosition.EAST));
205
 
206
		imageConteneur.setMaskDisabled(true);
207
		this.setBorder(false);
208
 
209
		conteneurInitialise = true;
210
		initialise = true;
211
 
212
		// on ajoute les listeners
213
		ajouterListeners();
214
 
215
	}
216
 
217
	/**
218
	 * Méthode héritée de l'interface rafraichissable
219
	 *
220
	 * @param nouvelleDonnees
221
	 *            les nouvelles données
222
	 * @param repandreRafraichissement
223
	 *            le booleen qui dit si on doit répnadre l'évènement
224
	 */
225
	public void rafraichir(Object nouvelleDonnees,
226
			boolean repandreRafraichissement) {
227
 
228
		// si on reçoit une string
213 aurelien 229
		if (nouvelleDonnees instanceof String[][] && initialise
230
				&& conteneurInitialise && ((String[][])nouvelleDonnees).length != 0) {
231
			infosImages = (String[][]) nouvelleDonnees;
94 jpm 232
			index = 0 ;
233
			afficherImage() ;
234
 
235
		} else {
236
			// sinon on met une image vide
213 aurelien 237
			infosImages = null ;
238
			afficherImage();
239
 
94 jpm 240
		}
241
	}
242
 
243
	public void afficherImage()
244
	{
245
		// c'est l'url de l'image qu'on associe à la vue
213 aurelien 246
		if(infosImages != null && infosImages.length != 0)
94 jpm 247
		{
245 aurelien 248
			setTitle(titrePanneau+"         "+(index+1)+" / "+infosImages.length);
249
 
213 aurelien 250
			getImage().setUrl(convertirIdEnUrl(infosImages[index][0]));
251
			imageWidth = Integer.parseInt(infosImages[index][1]);
252
			imageHeight = Integer.parseInt(infosImages[index][2]);
253
			verifierEtRetaillerImage();
245 aurelien 254
			activerPanneau(true);
213 aurelien 255
		} else {
245 aurelien 256
			setTitle(titrePanneau);
213 aurelien 257
			getImage().setUrl("ill_liaison.png");
258
			imageWidth = getImage().getWidth();
130 aurelien 259
			imageHeight = getImage().getHeight();
213 aurelien 260
			if(imgZoom.isVisible()) {
261
				agrandirImage();
262
			}
245 aurelien 263
			activerPanneau(false);
264
		}
265
 
266
		if(infosImages != null && infosImages.length > 1) {
267
			prev.setEnabled(true);
268
			suiv.setEnabled(true);
269
		} else {
213 aurelien 270
			prev.setEnabled(false);
271
			suiv.setEnabled(false);
94 jpm 272
		}
273
	}
274
 
275
	/**
276
	 * Active visuellement le panneau et les boutons
277
	 */
245 aurelien 278
	public void activerPanneau(boolean activer) {
279
		if(activer) {
280
			this.getEl().unmask();
281
		} else {
282
			this.getEl().mask();
283
		}
94 jpm 284
	}
285
 
286
	/**
287
	 * Ajoute les listeners pour la gestions d'évènement
288
	 */
289
	public void ajouterListeners() {
290
 
291
		// gestion du clic sur le bouton précedent
338 aurelien 292
		prev.addClickHandler(new ClickHandler() {
94 jpm 293
 
338 aurelien 294
			public void onClick(ClickEvent event) {
94 jpm 295
				if(infosImages.length != 0) {
296
					if(index == 0)
297
					{
298
						index = infosImages.length - 1 ;
299
					}
300
					else
301
					{
302
						index-- ;
303
					}
304
 
305
					afficherImage() ;
306
				}
307
			}
308
 
309
		});
310
 
311
		// gestion du clic sur le bouton suivant
338 aurelien 312
		suiv.addClickHandler(new ClickHandler() {
94 jpm 313
 
314
			// en cas de clic
338 aurelien 315
			public void onClick(ClickEvent event) {
94 jpm 316
 
317
				if(infosImages.length != 0) {
318
					if(index == infosImages.length - 1)
319
					{
320
						index = 0 ;
321
					}
322
					else
323
					{
324
						index++ ;
325
					}
326
 
327
					afficherImage() ;
328
				}
329
 
330
			}
331
 
332
		});
130 aurelien 333
 
94 jpm 334
	}
335
 
336
	/**
337
	 * Accesseur pour le médiateur
338
	 *
339
	 * @return le médiateur associé à la vue
340
	 */
341
	public ObservationMediateur getIMediateur() {
342
		return oMediateur;
343
	}
344
 
345
	/**
346
	 * Accesseur au conteneur de l'image
347
	 *
348
	 * @return le conteneur de l'image
349
	 */
350
	public Image getImage() {
351
		return image;
352
	}
353
 
354
	/**
355
	 * Acesseurs pour l'identifiant de l'image
356
	 * @return l'id de l'image
357
	 */
358
	public String getIdImage()
359
	{
213 aurelien 360
		return infosImages[index][0] ;
94 jpm 361
	}
362
 
363
	/**
364
	 * Accesseur pour le bouton précédent
365
	 *
366
	 * @return le bouton précédent
367
	 */
368
	public com.google.gwt.user.client.ui.Button getPrev() {
369
		return prev;
370
	}
371
 
372
	/**
373
	 * Accesseur pour le bouton suivant
374
	 *
375
	 * @return le bouton suivant
376
	 */
377
	public com.google.gwt.user.client.ui.Button getSuiv() {
378
		return suiv;
379
	}
380
 
381
	/**
382
	 * Setter pour la taille de l'image
383
	 *
384
	 * @param x
385
	 *            la largeur en pixels
386
	 * @param y
387
	 *            la hauteur en pixels
388
	 */
389
	public void setTailleImage(int x, int y) {
390
		imageHeight = y;
391
		imageWidth = x;
392
	}
393
 
394
	/**
395
	 * Setteur pour l'identifiant de l'image
396
	 * @param id le nouvel identifiant
397
	 */
398
	public void setIdImage(String id)
399
	{
400
		idImage = id ;
401
	}
402
 
403
	/**
404
	 * renvoie la taille originale de l'image
405
	 *
406
	 * @return un tableau de deux entiers contenant la largeur puis la hauteur
407
	 */
408
	public int[] getTailleImage() {
409
		int[] taille = { imageHeight, imageWidth };
410
 
411
		return taille;
412
	}
413
 
414
	/**
415
	 * Accesseur pour le conteneur de l'image
416
	 * @return le conteur de l'image
417
	 */
418
	public Panel getImageConteneur() {
419
 
420
		return imageConteneur;
421
 
422
	}
104 jpm 423
 
424
	public void raz() {
425
 
213 aurelien 426
		infosImages = new String[0][0] ;
104 jpm 427
		getImage().setUrl("");
428
 
429
	}
430
 
431
	public void supprimerLiaisonImage() {
432
 
433
		if(infosImages.length > 0) {
434
 
435
			getImage().setUrl("") ;
436
			int nouvelleTaille = infosImages.length - 1 ;
437
			int indexSupp = index ;
438
 
213 aurelien 439
			String[][] nouveauInfosImages = new String[nouvelleTaille][3] ;
104 jpm 440
			int j = 0 ;
441
 
442
			for(int i = 0 ; i < infosImages.length ; i++) {
443
 
444
				if(i != indexSupp) {
445
 
446
					nouveauInfosImages[j] = infosImages[i] ;
447
					j++ ;
448
				}
449
			}
450
 
451
			infosImages = nouveauInfosImages ;
452
			index = 0 ;
453
 
454
			afficherImage() ;
455
		}
456
	}
457
 
458
	public void afficherMenu(int[] xy) {
459
 
460
		Menu mn = new Menu() ;
461
		final Item suppLiaison = new Item("Supprimer la liaison") ;
462
 
463
		mn.addItem(suppLiaison) ;
464
 
465
		mn.addListener(new MenuListenerAdapter() {
466
 
467
			public void onItemClick(BaseItem item, EventObject e) {
468
 
469
				// si c'est l'aide
470
				if (item.equals(suppLiaison)) {
471
					// on notifie le médiateur
472
					getIMediateur().supprimerLiaisonObsImage() ;
473
				}
474
			}
475
 
476
		}) ;
477
 
478
		mn.showAt(xy) ;
479
	}
480
 
481
	public String convertirIdEnUrl(String idImg)
482
	{
483
		int maxZeros = 9 - idImg.length();
484
 
485
		for (int j = 0; j < maxZeros; j++) {
486
			idImg = "0" + idImg;
487
		}
488
 
489
		String baseUrl = Configuration.getImageBaseUrl() ;
490
 
491
		String dossierNv1 = idImg.substring(0, 3);
492
		String dossierNv2 = idImg.substring(3, 6);
493
		String fichierNv = idImg.substring(6, 9);
494
 
495
		String nomFichier = dossierNv1 + "_" + dossierNv2 + "_" + fichierNv;
496
 
497
		String[] infosFichier = { nomFichier, dossierNv1, dossierNv2 };
498
 
499
		String urlImg = baseUrl + infosFichier[1] + "/" + infosFichier[2] + "/M/"
500
		+ infosFichier[0] + "_M.jpg";
501
 
502
		return urlImg ;
503
	}
130 aurelien 504
 
505
	/**
506
	 * Verifie si l'image est plus grande que le conteneur et la retaille le cas
507
	 * echeant
508
	 */
509
	public void verifierEtRetaillerImage() {
213 aurelien 510
 
130 aurelien 511
		// si l'image est nulle
512
		if (image == null) {
513
			// on ne fait rien
514
			return;
515
		}
516
 
213 aurelien 517
		int[] dim = calculerDimensions(getTailleImage(),300,imageConteneur.getWidth());
145 aurelien 518
		getImage().setSize("" + dim[0] + "px",
519
				"" + dim[1] + "px");
130 aurelien 520
 
213 aurelien 521
		doLayout();
145 aurelien 522
 
213 aurelien 523
		if(imgZoom.isVisible()) {
524
			agrandirImage();
525
		}
130 aurelien 526
	}
145 aurelien 527
 
213 aurelien 528
	public int[] calculerDimensions(int[] tailleXY, double tailleMax, double tailleConteneur) {
145 aurelien 529
 
530
		float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
213 aurelien 531
        float tailleOr = Math.min(new Float(tailleMax),new Float(tailleConteneur)) ;
145 aurelien 532
        float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
533
        float[] XYresize = new float[2];
534
 
535
        if(maxTaille == tailleXY[0]) {
536
            float rapport = tailleXYf[1]/tailleXYf[0] ;
537
            XYresize[0] = tailleOr ;
538
            XYresize[1] = tailleOr*rapport ;
539
        }else {
540
            float rapport = tailleXYf[0]/tailleXYf[1] ;
541
            XYresize[1] = tailleOr ;
542
            XYresize[0] = tailleOr*rapport ;
543
        }
544
 
279 aurelien 545
        int[] res = {(int)Math.round(XYresize[0]*0.85),(int)Math.round(XYresize[1]*0.85)} ;
145 aurelien 546
 
547
        return res;
548
    }
213 aurelien 549
 
550
	protected void agrandirImage() {
551
 
552
			String urlAgrandie = "";
553
 
554
			if(infosImages == null) {
555
				urlAgrandie = "ill_liaison.png";
556
				setTailleImage(265, 270);
557
			} else {
558
				urlAgrandie = convertirIdEnUrl(infosImages[index][0]).replace("_M", "_L") ;
559
				urlAgrandie = urlAgrandie.replace("/M/", "/L/") ;
560
			}
561
 
562
			if(imgAgrandie == null) {
563
				imgAgrandie = new Image(urlAgrandie);
564
				imgZoom.add(imgAgrandie);
565
 
338 aurelien 566
				imgAgrandie.addLoadHandler(new LoadHandler() {
213 aurelien 567
 
338 aurelien 568
					public void onLoad(LoadEvent event) {
213 aurelien 569
						int[] tailleImage = calculerDimensions(getTailleImage(),getTailleImage()[1],Window.getClientHeight()*0.75);
570
						ExtElement imgElement = Ext.get(imgAgrandie.getElement());
571
						if(animerTransition) {
572
							AnimationConfig a = new AnimationConfig() ;
573
							a.setDuration((float) dureeAnimation);
574
							imgElement.setHeight(tailleImage[1], a);
575
							imgElement.setWidth(tailleImage[0], a);
576
 
577
							ExtElement winElement = Ext.get(imgZoom.getElement());
578
							winElement.setHeight(tailleImage[1], a);
579
							winElement.setWidth(tailleImage[0], a);
580
						} else {
581
							imgElement.setHeight(tailleImage[1], false);
582
							imgElement.setWidth(tailleImage[0], false);
583
 
584
							ExtElement winElement = Ext.get(imgZoom.getElement());
585
							winElement.setHeight(tailleImage[1], false);
586
							winElement.setWidth(tailleImage[0], false);
587
						}
588
					}
589
 
590
				});
591
 
592
			} else {
593
				imgAgrandie.setUrl(urlAgrandie);
594
				imgAgrandie.setVisible(true);
595
			}
596
	}
597
 
598
	private void afficherPanneauAgrandi() {
237 aurelien 599
		agrandirImage();
600
		imgZoom.show(this.getElement());
601
		imgZoom.setPosition((int)(Window.getClientWidth() - Window.getClientWidth()*0.50),(int)(Window.getClientHeight() - Window.getClientHeight()*0.85));
213 aurelien 602
	}
94 jpm 603
}
604