Subversion Repositories eFlore/Applications.cel

Rev

Rev 722 | 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
 
268 aurelien 3
 
2 aperonnet 4
import org.tela_botanica.client.image.ImageMediateur;
5
import org.tela_botanica.client.interfaces.Rafraichissable;
6
 
408 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;
11
import com.google.gwt.event.dom.client.MouseWheelEvent;
12
import com.google.gwt.event.dom.client.MouseWheelHandler;
207 aurelien 13
import com.google.gwt.user.client.Timer;
2 aperonnet 14
import com.google.gwt.user.client.ui.Image;
5 aperonnet 15
import com.gwtext.client.core.EventObject;
207 aurelien 16
import com.gwtext.client.core.Ext;
17
import com.gwtext.client.core.ExtElement;
18
 
2 aperonnet 19
import com.gwtext.client.core.RegionPosition;
5 aperonnet 20
import com.gwtext.client.dd.DragData;
21
import com.gwtext.client.dd.DragSource;
22
import com.gwtext.client.dd.DropTarget;
23
import com.gwtext.client.dd.DropTargetConfig;
2 aperonnet 24
import com.gwtext.client.widgets.Container;
25
import com.gwtext.client.widgets.Panel;
99 jpm 26
import com.gwtext.client.widgets.ToolTip;
268 aurelien 27
import com.gwtext.client.widgets.Toolbar;
28
import com.gwtext.client.widgets.ToolbarButton;
29
import com.gwtext.client.widgets.ToolbarTextItem;
2 aperonnet 30
import com.gwtext.client.widgets.event.PanelListenerAdapter;
5 aperonnet 31
import com.gwtext.client.widgets.grid.GridDragData;
2 aperonnet 32
import com.gwtext.client.widgets.layout.BorderLayout;
33
import com.gwtext.client.widgets.layout.BorderLayoutData;
34
 
35
/**
36
 * Panneau d'affichage d'une image avec des boutons précdents et suivant
5 aperonnet 37
 *
2 aperonnet 38
 * @author aurelien
5 aperonnet 39
 *
2 aperonnet 40
 */
41
public class ZoomImageVue extends Panel implements Rafraichissable {
5 aperonnet 42
 
2 aperonnet 43
	/**
44
	 * Le médiateur associé à la vue
45
	 */
5 aperonnet 46
	private ImageMediateur iMediateur = null;
47
 
2 aperonnet 48
	/**
49
	 * Panneau conteneur pour l'image
50
	 */
5 aperonnet 51
	private Panel imageConteneur = null;
2 aperonnet 52
	/**
53
	 * l'image à afficher
54
	 */
5 aperonnet 55
	private Image image = new Image("vide.jpg");
2 aperonnet 56
	/**
57
	 * Bouton précédent
58
	 */
59
	private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button();
60
	/**
61
	 * Bouton suivant
62
	 */
63
	private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button();
5 aperonnet 64
 
2 aperonnet 65
	/**
66
	 * Taille originale Y de l'image
67
	 */
5 aperonnet 68
	private int imageHeight = 0;
69
 
2 aperonnet 70
	/**
71
	 * Taille originale X de l'image
72
	 */
5 aperonnet 73
	private int imageWidth = 0;
2 aperonnet 74
 
75
	/**
5 aperonnet 76
	 * Identifiant de l'image
77
	 */
78
	private String idImage = "0" ;
79
 
80
	/**
2 aperonnet 81
	 * Booleen d'initalisation général
82
	 */
5 aperonnet 83
	private boolean initialise = false;
408 aurelien 84
 
85
	private Panel infosTaxon = new Panel();
5 aperonnet 86
 
2 aperonnet 87
	/**
88
	 * Booleen d'initalisation du conteneur d'image
89
	 */
5 aperonnet 90
	private boolean conteneurInitialise = false;
99 jpm 91
 
92
	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>") ;
207 aurelien 93
 
94
	/**.
95
	 * boolean de gestion du double clic
96
	 */
97
	private boolean enClic = false;
98
 
268 aurelien 99
	private ToolbarButton modeZoom = null;
100
 
101
	private ToolbarTextItem valeurZoom = new ToolbarTextItem("x 1");
102
 
103
	protected boolean scroll = false;
104
 
207 aurelien 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
 
2 aperonnet 140
		// l'image de base est vide
141
		image.setUrl("vide.jpg");
5 aperonnet 142
 
2 aperonnet 143
		this.setLayout(new BorderLayout());
5 aperonnet 144
 
2 aperonnet 145
		prev.setWidth("60px");
146
		suiv.setWidth("60px");
5 aperonnet 147
 
268 aurelien 148
 
149
		modeZoom = new ToolbarButton("Mode Zoom");
150
		Toolbar tb = new Toolbar();
151
		tb.addButton(modeZoom);
152
		tb.addItem(valeurZoom);
153
 
154
		//setTopToolbar(tb);
155
 
408 aurelien 156
		infosTaxon = new Panel();
157
		infosTaxon.setHeader(false);
158
		//infosTaxon.setBorder(false);
159
		infosTaxon.setHeight("30px");
160
 
5 aperonnet 161
		this.add(prev, new BorderLayoutData(RegionPosition.WEST));
162
		this.add(imageConteneur, new BorderLayoutData(RegionPosition.CENTER));
163
		this.add(suiv, new BorderLayoutData(RegionPosition.EAST));
408 aurelien 164
		this.add(infosTaxon, new BorderLayoutData(RegionPosition.SOUTH));
5 aperonnet 165
 
166
		imageConteneur.setMaskDisabled(true);
2 aperonnet 167
		this.setBorder(false);
5 aperonnet 168
 
169
		conteneurInitialise = true;
170
		initialise = true;
2 aperonnet 171
 
5 aperonnet 172
		configDragAndDrop() ;
173
 
2 aperonnet 174
		// on ajoute les listeners
175
		ajouterListeners();
99 jpm 176
 
268 aurelien 177
		tp.setDismissDelay(1050);
99 jpm 178
		tp.applyTo(image.getElement()) ;
2 aperonnet 179
 
180
	}
181
 
182
	/**
183
	 * Méthode héritée de l'interface rafraichissable
5 aperonnet 184
	 *
185
	 * @param nouvelleDonnees
186
	 *            les nouvelles données
187
	 * @param repandreRafraichissement
188
	 *            le booleen qui dit si on doit répnadre l'évènement
2 aperonnet 189
	 */
1292 aurelien 190
	@Override
5 aperonnet 191
	public void rafraichir(Object nouvelleDonnees,
192
			boolean repandreRafraichissement) {
193
 
268 aurelien 194
		//niveauZoom = 1;
2 aperonnet 195
		// si on reçoit une string
5 aperonnet 196
		if (nouvelleDonnees instanceof String[] && initialise
197
				&& conteneurInitialise) {
722 aurelien 198
 
5 aperonnet 199
			String[] infos = (String[]) nouvelleDonnees;
408 aurelien 200
 
2 aperonnet 201
			// c'est l'url de l'image qu'on associe à la vue
5 aperonnet 202
			if (infos[0] != null && infos[1] != null && infos[2] != null && infos[3] != null) {
203
				getImage().setUrl(infos[0]);
204
				int x = Integer.parseInt(infos[1]);
205
				int y = Integer.parseInt(infos[2]);
206
 
207
				setTailleImage(x, y);
2 aperonnet 208
 
5 aperonnet 209
				setIdImage(infos[3]) ;
408 aurelien 210
 
211
				String infosTaxon = "" ;
212
 
213
				if(infos.length == 5 && infos[4] != null)  {
214
					infosTaxon = infos[4];
215
				}
216
 
217
				setInfosTaxon(infosTaxon);
218
				verifierEtRetaillerImage();
2 aperonnet 219
			}
220
		}
221
	}
5 aperonnet 222
 
2 aperonnet 223
	/**
224
	 * Desactive visuellement le panneau et les boutons
225
	 */
5 aperonnet 226
	public void desactiverPanneau() {
638 aurelien 227
		getImage().setUrl("vide.jpg");
5 aperonnet 228
		prev.setEnabled(false);
2 aperonnet 229
		suiv.setEnabled(false);
230
	}
5 aperonnet 231
 
2 aperonnet 232
	/**
233
	 * Active visuellement le panneau et les boutons
234
	 */
5 aperonnet 235
	public void activerPanneau() {
2 aperonnet 236
		prev.setEnabled(true);
237
		suiv.setEnabled(true);
238
	}
225 aurelien 239
 
240
	public void masquerChargement() {
241
		ExtElement imgEl = Ext.get(imageConteneur.getElement());
324 aurelien 242
		if(imgEl != null) {
225 aurelien 243
			imgEl.mask("Chargement");
244
		}
245
	}
246
 
247
	public void demasquerChargement() {
248
		ExtElement imgEl = Ext.get(imageConteneur.getElement());
324 aurelien 249
		if(imgEl != null) {
225 aurelien 250
			imgEl.unmask();
251
		}
252
	}
5 aperonnet 253
 
2 aperonnet 254
	/**
255
	 * Ajoute les listeners pour la gestions d'évènement
256
	 */
5 aperonnet 257
	public void ajouterListeners() {
207 aurelien 258
 
408 aurelien 259
		image.addClickHandler(new ClickHandler() {
207 aurelien 260
 
1292 aurelien 261
			@Override
408 aurelien 262
			public void onClick(ClickEvent event) {
722 aurelien 263
 
268 aurelien 264
				if(!scroll) {
207 aurelien 265
					if(enClic) {
266
						getIMediateur().doubleClicZoomImage();
267
					} else {
268
						Timer t = new Timer() {
1292 aurelien 269
							@Override
207 aurelien 270
							public void run() {
271
								enClic = false;
272
							}
273
 
274
						};
275
						enClic = true;
276
						t.schedule(800);
277
					}
268 aurelien 278
				}
207 aurelien 279
			}
280
		});
281
 
408 aurelien 282
		image.addLoadHandler(new LoadHandler() {
283
 
1292 aurelien 284
			@Override
408 aurelien 285
			public void onLoad(LoadEvent event) {
207 aurelien 286
 
408 aurelien 287
				verifierEtRetaillerImage();
288
				Ext.get(image.getElement()).center(imageConteneur.getElement());
289
				demasquerChargement();
207 aurelien 290
			}
291
		});
292
 
408 aurelien 293
		image.addMouseWheelHandler(new MouseWheelHandler() {
294
 
1292 aurelien 295
			@Override
408 aurelien 296
			public void onMouseWheel(MouseWheelEvent event) {
268 aurelien 297
 
408 aurelien 298
				if(event.isNorth()) {
299
					masquerChargement();
300
					getIMediateur().clicBoutonZoomImage("suiv");
301
				} else {
302
					masquerChargement();
303
					getIMediateur().clicBoutonZoomImage("prev");
304
				}
268 aurelien 305
			}
306
		});
307
 
2 aperonnet 308
		// gestion du clic sur le bouton précedent
408 aurelien 309
		prev.addClickHandler(new ClickHandler() {
2 aperonnet 310
 
311
			// en cas de clic
1292 aurelien 312
			@Override
408 aurelien 313
			public void onClick(ClickEvent event) {
2 aperonnet 314
				// on notifie le médiateur
225 aurelien 315
				masquerChargement();
2 aperonnet 316
				getIMediateur().clicBoutonZoomImage("prev");
317
			}
318
		});
5 aperonnet 319
 
2 aperonnet 320
		// gestion du clic sur le bouton suivant
408 aurelien 321
		suiv.addClickHandler(new ClickHandler() {
2 aperonnet 322
 
323
			// en cas de clic
1292 aurelien 324
			@Override
408 aurelien 325
			public void onClick(ClickEvent event) {
5 aperonnet 326
				// on notifie le médiateur
225 aurelien 327
				masquerChargement();
2 aperonnet 328
				getIMediateur().clicBoutonZoomImage("suiv");
329
			}
5 aperonnet 330
 
2 aperonnet 331
		});
5 aperonnet 332
 
2 aperonnet 333
		// gestion du redimensionnement
334
		this.addListener(new PanelListenerAdapter() {
5 aperonnet 335
 
2 aperonnet 336
			// lors d'un redimensionnement de l'application
5 aperonnet 337
 
1292 aurelien 338
			@Override
5 aperonnet 339
			public void onBodyResize(Panel panel, java.lang.String width,
340
					java.lang.String height) {
2 aperonnet 341
				// on vérifie et on retaille l'image
5 aperonnet 342
				verifierEtRetaillerImage();
2 aperonnet 343
			}
5 aperonnet 344
		});
345
 
2 aperonnet 346
		// gestion du redimensionnement lors de l'affichage du conteneur
347
		imageConteneur.addListener(new PanelListenerAdapter() {
5 aperonnet 348
 
2 aperonnet 349
			// avant de finir d'afficher
5 aperonnet 350
 
1292 aurelien 351
			@Override
5 aperonnet 352
			public void onAfterLayout(Container self) {
2 aperonnet 353
				// on redimensionne
5 aperonnet 354
				verifierEtRetaillerImage();
2 aperonnet 355
			}
5 aperonnet 356
		});
2 aperonnet 357
	}
358
 
359
	/**
5 aperonnet 360
	 * Verifie si l'image est plus grande que le conteneur et la retaille le cas
361
	 * echeant
2 aperonnet 362
	 */
5 aperonnet 363
	public void verifierEtRetaillerImage() {
408 aurelien 364
 
2 aperonnet 365
		// si l'image est nulle
5 aperonnet 366
		if (image == null) {
2 aperonnet 367
			// on ne fait rien
5 aperonnet 368
			return;
369
		}
408 aurelien 370
 
2 aperonnet 371
		// on modifie enfin la taille de l'image pour qu'elle soit affichée
268 aurelien 372
		int max = Math.min(imageConteneur.getHeight(), imageConteneur.getWidth());
373
 
374
		int[] tailleImage = new int[2];
375
 
408 aurelien 376
		if(Ext.isIE()) {
377
			image.setHeight(calculerDimensions(getTailleImage(),max,max)[1]+"px");
378
			image.setWidth(calculerDimensions(getTailleImage(),max,max)[0]+"px");
268 aurelien 379
		} else {
408 aurelien 380
 
381
			if(max == imageConteneur.getHeight()) {
382
				tailleImage[0] = getTailleImage()[0];
383
				tailleImage[1] = max;
384
				image.setHeight(max+"px");
385
 
386
			} else {
387
				tailleImage[1] = getTailleImage()[0];
388
				tailleImage[0] = max;
389
				image.setWidth(max+"px");
390
			}
268 aurelien 391
		}
2 aperonnet 392
	}
5 aperonnet 393
 
207 aurelien 394
	public int[] calculerDimensions(int[] tailleXY, double tailleMax, double tailleConteneur) {
395
 
396
		float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
397
        float tailleOr = Math.min(new Float(tailleMax),new Float(tailleConteneur)) ;
398
        float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
399
        float[] XYresize = new float[2];
400
 
401
        if(maxTaille == tailleXY[0]) {
402
            float rapport = tailleXYf[1]/tailleXYf[0] ;
403
            XYresize[0] = tailleOr ;
404
            XYresize[1] = tailleOr*rapport ;
405
        }else {
406
            float rapport = tailleXYf[0]/tailleXYf[1] ;
407
            XYresize[1] = tailleOr ;
408
            XYresize[0] = tailleOr*rapport ;
409
        }
410
 
1292 aurelien 411
        int[] res = {Math.round(XYresize[0]),Math.round(XYresize[1])} ;
207 aurelien 412
 
413
        return res;
414
    }
415
 
5 aperonnet 416
	public void configDragAndDrop()
417
	{
2 aperonnet 418
 
5 aperonnet 419
		// on fabrique la nouvelle configuration
420
		// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroup
421
		DropTargetConfig dtc = new DropTargetConfig();
422
		dtc.setdDdGroup("DragGroupName");
423
 
424
		//La drop target permet de gérer l'évenement onDrop sur l'élement courant
425
		@SuppressWarnings("unused")
426
		DropTarget tg = new DropTarget(this, dtc)
427
		{
1292 aurelien 428
			@Override
5 aperonnet 429
			public boolean notifyDrop(DragSource source, EventObject e, DragData data){
430
 
431
				// si on reçoit des données provenant d'une grille
432
				if(data instanceof GridDragData)
433
		    	  {
434
		    		  		// on appelle le médiateur
435
		    		  		return iMediateur.lierObsDD(source, e, data,getId()) ;
436
		    	  }
437
				return false ;
438
			}
439
 
1292 aurelien 440
			@Override
5 aperonnet 441
			public String notifyOver(DragSource source, EventObject e, DragData data){
442
			    return "x-dd-drop-ok";
443
			}
444
		};
445
 
446
	}
447
 
2 aperonnet 448
	/**
449
	 * Accesseur pour le médiateur
5 aperonnet 450
	 *
2 aperonnet 451
	 * @return le médiateur associé à la vue
452
	 */
453
	public ImageMediateur getIMediateur() {
454
		return iMediateur;
455
	}
456
 
457
	/**
458
	 * Accesseur au conteneur de l'image
5 aperonnet 459
	 *
2 aperonnet 460
	 * @return le conteneur de l'image
461
	 */
462
	public Image getImage() {
463
		return image;
464
	}
5 aperonnet 465
 
466
	/**
467
	 * Acesseurs pour l'identifiant de l'image
468
	 * @return l'id de l'image
469
	 */
470
	public String getIdImage()
471
	{
472
		return idImage ;
473
	}
2 aperonnet 474
 
475
	/**
476
	 * Accesseur pour le bouton précédent
5 aperonnet 477
	 *
2 aperonnet 478
	 * @return le bouton précédent
479
	 */
480
	public com.google.gwt.user.client.ui.Button getPrev() {
481
		return prev;
482
	}
483
 
484
	/**
485
	 * Accesseur pour le bouton suivant
5 aperonnet 486
	 *
2 aperonnet 487
	 * @return le bouton suivant
488
	 */
489
	public com.google.gwt.user.client.ui.Button getSuiv() {
490
		return suiv;
491
	}
5 aperonnet 492
 
2 aperonnet 493
	/**
494
	 * Setter pour la taille de l'image
5 aperonnet 495
	 *
7 aperonnet 496
	 * @param x
5 aperonnet 497
	 *            la largeur en pixels
7 aperonnet 498
	 * @param y
5 aperonnet 499
	 *            la hauteur en pixels
2 aperonnet 500
	 */
5 aperonnet 501
	public void setTailleImage(int x, int y) {
502
		imageHeight = y;
503
		imageWidth = x;
2 aperonnet 504
	}
505
 
506
	/**
5 aperonnet 507
	 * Setteur pour l'identifiant de l'image
508
	 * @param id le nouvel identifiant
509
	 */
510
	public void setIdImage(String id)
511
	{
512
		idImage = id ;
513
	}
408 aurelien 514
 
515
	public void setInfosTaxon(String nomTaxon) {
516
 
517
		if(nomTaxon != null && !nomTaxon.equals("")) {
518
			nomTaxon = getNomsObservationsFormatees(nomTaxon);
519
		}
520
 
521
		infosTaxon.setHtml("<div id='infos_taxon'><span class='texte_info_taxon'>"+nomTaxon+"</span></div>");
522
		infosTaxon.doLayout();
523
	}
5 aperonnet 524
 
525
	/**
2 aperonnet 526
	 * renvoie la taille originale de l'image
5 aperonnet 527
	 *
2 aperonnet 528
	 * @return un tableau de deux entiers contenant la largeur puis la hauteur
529
	 */
5 aperonnet 530
	public int[] getTailleImage() {
531
		int[] taille = { imageHeight, imageWidth };
532
 
533
		return taille;
2 aperonnet 534
	}
5 aperonnet 535
 
408 aurelien 536
	public boolean estPortrait() {
537
		return imageHeight > imageWidth;
538
	}
539
 
540
	public boolean estPaysage() {
541
		return !estPortrait();
542
	}
543
 
5 aperonnet 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
	}
268 aurelien 553
 
408 aurelien 554
	private String getNomsObservationsFormatees(String nomObs) {
555
 
556
		String htmlInfobulle = "";
557
 
558
		String[][] obs = getObservationsAssociees(nomObs);
559
 
560
		for(int i = 0; i < obs.length; i++) {
561
 
562
			if(obs[i].length == 3 && obs[i][1] != null && !obs[i][1].equals("")) {
563
				htmlInfobulle += ", "+obs[i][1];
268 aurelien 564
			}
565
		}
408 aurelien 566
 
567
		htmlInfobulle = htmlInfobulle.replaceFirst(", ", "");
568
 
569
		return htmlInfobulle;
268 aurelien 570
	}
408 aurelien 571
 
572
	private String[][] getObservationsAssociees(String nomObs) {
573
 
574
		if(nomObs.trim().equals("")) {
575
			return new String[0][0];
268 aurelien 576
		}
408 aurelien 577
 
578
		String[] obsTab = nomObs.split(";;");
579
		String[][] obsAnalysees = new String[obsTab.length][3];
580
 
581
		for(int i = 0; i < obsTab.length; i++) {
582
 
583
			obsAnalysees[i] = obsTab[i].split("#");
584
 
585
		}
586
 
587
		return obsAnalysees;
268 aurelien 588
	}
589
 
408 aurelien 590
	private boolean[] estAssocieeTransmise(String nomObs) {
268 aurelien 591
 
408 aurelien 592
		String[][] obs = getObservationsAssociees(nomObs);
593
		boolean[] associeesTranmises = {false, false};
268 aurelien 594
 
408 aurelien 595
		if(obs.length > 0) {
596
			associeesTranmises[0] = true;
268 aurelien 597
		}
598
 
408 aurelien 599
		for(int i = 0; i < obs.length; i++) {
268 aurelien 600
 
408 aurelien 601
			if(obs[i].length == 3 && obs[i][2] != null && obs[i][2].equals("1")) {
602
				associeesTranmises[1] = true;
268 aurelien 603
			}
604
		}
408 aurelien 605
 
606
		return associeesTranmises;
268 aurelien 607
	}
2 aperonnet 608
}