Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
2 aperonnet 1
package org.tela_botanica.client.vues;
2
 
3
import org.tela_botanica.client.image.ImageMediateur;
60 jpm 4
import org.tela_botanica.client.interfaces.ListePaginable;
2 aperonnet 5
import org.tela_botanica.client.interfaces.Rafraichissable;
6
import org.tela_botanica.client.interfaces.VueListable;
7
 
140 aurelien 8
import com.google.gwt.core.client.GWT;
2 aperonnet 9
import com.google.gwt.user.client.Element;
140 aurelien 10
import com.google.gwt.user.client.Window;
81 jpm 11
import com.google.gwt.user.client.ui.HTML;
134 aurelien 12
import com.gwtext.client.core.EventCallback;
2 aperonnet 13
import com.gwtext.client.core.EventObject;
134 aurelien 14
import com.gwtext.client.core.Ext;
15
import com.gwtext.client.core.ExtElement;
2 aperonnet 16
import com.gwtext.client.core.XTemplate;
17
import com.gwtext.client.data.FieldDef;
18
import com.gwtext.client.data.IntegerFieldDef;
19
import com.gwtext.client.data.Record;
20
import com.gwtext.client.data.RecordDef;
21
import com.gwtext.client.data.Store;
22
import com.gwtext.client.data.StringFieldDef;
5 aperonnet 23
import com.gwtext.client.dd.DragData;
24
import com.gwtext.client.dd.DragSource;
25
import com.gwtext.client.dd.DropTarget;
26
import com.gwtext.client.dd.DropTargetConfig;
2 aperonnet 27
import com.gwtext.client.util.Format;
28
import com.gwtext.client.widgets.Component;
134 aurelien 29
import com.gwtext.client.widgets.Container;
2 aperonnet 30
import com.gwtext.client.widgets.DataView;
31
import com.gwtext.client.widgets.Panel;
32
import com.gwtext.client.widgets.event.ContainerListenerAdapter;
33
import com.gwtext.client.widgets.event.DataViewListenerAdapter;
5 aperonnet 34
import com.gwtext.client.widgets.grid.GridDragData;
2 aperonnet 35
 
36
/**
5 aperonnet 37
 * Galerie d'images miniatures Avec barre de pagination
38
 *
2 aperonnet 39
 * @author aurelien
40
 */
5 aperonnet 41
public class GalerieImageVue extends Panel implements Rafraichissable,
60 jpm 42
		VueListable, ListePaginable {
2 aperonnet 43
 
44
	/**
45
	 * instance du médiateur
5 aperonnet 46
	 */
47
	private ImageMediateur iMediateur = null;
2 aperonnet 48
	/**
5 aperonnet 49
	 * Dataview, littéralement "vue de données" qui permet de définir la manière
50
	 * d'afficher les données
51
	 */
52
	private DataView dView = null;
2 aperonnet 53
	/**
5 aperonnet 54
	 * Dataview, littéralement "vue de données" qui permet de définir la manière
55
	 * d'afficher les données
56
	 */
57
	private Store st = null;
2 aperonnet 58
	/**
5 aperonnet 59
	 * Barre de pagination gérant l'affichage d'un nombre donné d'élements par
60
	 * page et la navigation entre eux
61
	 */
59 david 62
	private BarrePaginationVue pt = null;
2 aperonnet 63
	/**
64
	 * Booleen indiquant si la galerie est instanciée ou pas
5 aperonnet 65
	 */
66
	private boolean estInstancie = false;
140 aurelien 67
 
68
	private boolean garderRatio = false;
69
 
70
	private int tailleOr = 100 ;
2 aperonnet 71
 
72
	/**
73
	 * Constructeur sans argument, privé car ne doit pas être utilisé
74
	 */
75
	@SuppressWarnings("unused")
5 aperonnet 76
	private GalerieImageVue() {
77
		super();
2 aperonnet 78
	}
5 aperonnet 79
 
2 aperonnet 80
	/**
81
	 * Constructeur avec argument
5 aperonnet 82
	 *
83
	 * @param im
84
	 *            le médiateur avec lequel la vue va communiquer
2 aperonnet 85
	 */
86
	public GalerieImageVue(ImageMediateur im) {
87
		super("Galerie");
88
		iMediateur = im;
5 aperonnet 89
 
2 aperonnet 90
		// on ajoute des listeners au composant tout entier
91
		this.addListener(new ContainerListenerAdapter() {
92
 
5 aperonnet 93
			// pour gagner du temps on n'instancie la vue en elle même que lors
94
			// du premier affichage (lazy rendering)
95
 
2 aperonnet 96
			public void onShow(Component component) {
97
 
98
				if (!estInstancie) {
99
					initialiser();
100
				}
101
			}
134 aurelien 102
 
103
			public void onAfterLayout(Container c) {
104
 
105
				ExtElement lienUpload = Ext.get("lienUpload");
140 aurelien 106
				if(lienUpload != null) {
107
					lienUpload.addListener("click", new EventCallback() {
108
 
109
						public void execute(EventObject e) {
110
 
111
							getIMediateur().uploaderImages();
112
						}
134 aurelien 113
 
140 aurelien 114
					}) ;
115
				}
134 aurelien 116
			}
117
 
2 aperonnet 118
		});
5 aperonnet 119
 
2 aperonnet 120
		// et on ajoute la tool bar
60 jpm 121
		pt = new BarrePaginationVue(this);
59 david 122
		pt.setLabelElement("Images");
123
		pt.setTaillePageParDefaut(50);
5 aperonnet 124
		this.setBottomToolbar(pt);
2 aperonnet 125
 
126
	}
127
 
128
	/**
5 aperonnet 129
	 * Ajoute tous les listeners nécessaires à l'intercation utilisateur avec la
130
	 * vue de données
2 aperonnet 131
	 */
132
	public void ajouterListenersDataView() {
133
 
134
		// ajout de listeners pour la gestion de la selection
135
		// dans la galerie
136
		dView.addListener(new DataViewListenerAdapter() {
5 aperonnet 137
 
2 aperonnet 138
			// gestion du clic sur une image
5 aperonnet 139
 
2 aperonnet 140
			public void onClick(DataView source, int index, Element node,
141
					EventObject e) {
5 aperonnet 142
 
2 aperonnet 143
				// on en notifie le médiateur
144
				getIMediateur().clicGalerieImage(index, node, e);
145
 
146
			}
147
 
148
			// gestion du clic droit
5 aperonnet 149
 
2 aperonnet 150
			public void onContextMenu(DataView source, int index, Element node,
151
					EventObject e) {
152
 
5 aperonnet 153
				// on stoppe l'évenement
2 aperonnet 154
				e.stopEvent();
155
				// et on notifie le médiateur
156
				getIMediateur().montrerContextMenu(e);
157
 
158
			}
159
 
160
			// gestion du double clic
5 aperonnet 161
 
2 aperonnet 162
			public void onDblClick(DataView source, int index, Element node,
163
					EventObject e) {
164
 
165
				// on notife le mediateur
166
				getIMediateur().clicGalerieImage(index, node, e);
5 aperonnet 167
 
2 aperonnet 168
			}
169
 
170
			// gestion des actions en fonction de la selection
5 aperonnet 171
 
2 aperonnet 172
			public void onSelectionChange(DataView view, Element[] selections) {
173
 
174
				// s'il n'y a aucun élement sélectionné
175
				if (selections.length <= 0) {
176
					// on en notifie le médiateur
177
					getIMediateur().aucuneSelection();
178
				} else {
179
					// sinon on notifie le médiateur
180
					getIMediateur().selection();
5 aperonnet 181
					// et on lui demande de synchroniser la séléction avec les
182
					// autres vues
2 aperonnet 183
					getIMediateur().synchroniserSelection("galerie");
184
				}
185
			}
186
 
187
		});
188
	}
189
 
190
	/**
191
	 * Accesseur pour la dataview
5 aperonnet 192
	 *
193
	 * @return la dataview
2 aperonnet 194
	 */
195
	public DataView getDView() {
196
		return dView;
197
	}
198
 
199
	/**
200
	 * Renvoie les ids des images sélectionnées
5 aperonnet 201
	 *
202
	 * @return un tableau de String contenant les identifiants des images
203
	 *         sélectionnées
2 aperonnet 204
	 */
205
	public String[] getIdSelectionnees() {
206
		Record[] selection = getDView().getSelectedRecords();
207
		int taille = selection.length;
208
		String id_selection[] = new String[taille];
209
 
210
		for (int i = 0; i < selection.length; i++) {
211
 
212
			id_selection[i] = selection[i].getAsString("num_image");
213
		}
214
 
215
		return id_selection;
216
	}
217
 
218
	/**
219
	 * Accesseur pour le médiateur
5 aperonnet 220
	 *
2 aperonnet 221
	 * @return le médiateur associé à la vue
222
	 */
223
	public ImageMediateur getIMediateur() {
224
		return iMediateur;
225
	}
226
 
227
	/**
228
	 * Accesseur pour le store
5 aperonnet 229
	 *
2 aperonnet 230
	 * @return le store associé à la vue
231
	 */
232
	public Store getSt() {
233
		return st;
234
	}
5 aperonnet 235
 
2 aperonnet 236
	/**
5 aperonnet 237
	 * Accesseur pour la toolbar
238
	 *
2 aperonnet 239
	 * @return la toolbar associée à la vue
240
	 */
59 david 241
	public BarrePaginationVue getToolBarVue() {
5 aperonnet 242
		return pt;
2 aperonnet 243
	}
244
 
245
	/**
5 aperonnet 246
	 * Fonction d'initialisation du contenu (appelée lors du premier affichage
247
	 * de la liste)
2 aperonnet 248
	 */
249
	public void initialiser() {
5 aperonnet 250
 
2 aperonnet 251
		// Preparation de la dataview et du template
252
		// le template va créer une div contenant une image
253
		// pour chacune des photos
254
		final XTemplate template = new XTemplate(
255
				new String[] {
256
						"<tpl for='.'>",
257
						"<div class='thumb-wrap' id='{num_image}'>",
140 aurelien 258
						"<div class='thumb'><img src='{url_image_M}' width='{taille_x_s} px' height='{taille_y_s} px' title='{num_image}'></div>",
2 aperonnet 259
						"<span>{nom}</span></div>", "</tpl>",
260
						"<div class='x-clear'></div>" });
5 aperonnet 261
		// pour des raisons de performances on compile le template en une
262
		// fonction
2 aperonnet 263
		template.compile();
264
 
265
		// la dataview affichera les images en accord avec le template
266
		// cree precedemment
267
		dView = new DataView("div.thumb-wrap") {
268
 
269
			public void prepareData(Data data) {
270
				data.setProperty("shortName", Format.ellipsis(data
140 aurelien 271
						.getProperty("num_image"), 15));
272
 
273
				int[] XY = {data.getPropertyAsInt("taille_x") ,data.getPropertyAsInt("taille_y")} ;
274
				int[] XYresize ;
275
 
276
				if(garderRatio) {
277
					XYresize = calculerDimensions(XY);
278
				}
279
				else {
280
					XYresize = new int[2] ;
281
					XYresize[0] = XYresize[1] = tailleOr ;
282
 
283
				}
284
 
285
				data.setProperty("taille_x_s", XYresize[0]);
286
				data.setProperty("taille_y_s", XYresize[1]);
2 aperonnet 287
			}
5 aperonnet 288
 
2 aperonnet 289
		};
290
		dView.setTpl(template);
291
 
292
		// parametre d'affichage de la dataview
293
		this.setAutoScroll(true);
294
		dView.setAutoHeight(true);
295
		dView.setMultiSelect(true);
296
		dView.setOverCls("x-view-over");
134 aurelien 297
		dView.setEmptyText("<div class=\"avertissement\" >Aucune image à afficher. <a id=\"lienUpload\" href=# > Cliquez ici</a>  pour en ajouter ou allez dans le menu Fichier -> Ajouter des images </div>");
2 aperonnet 298
 
299
		// creation du store
300
		FieldDef defNumImage = new IntegerFieldDef("num_image");
301
		FieldDef defDatImage = new StringFieldDef("dat_image");
302
		FieldDef defLieImage = new StringFieldDef("lie_image");
303
		FieldDef defAppImage = new StringFieldDef("app_image");
304
		FieldDef defUrlImageS = new StringFieldDef("url_image_S");
305
		FieldDef defUrlImageM = new StringFieldDef("url_image_M");
306
		FieldDef defUrlImage = new StringFieldDef("url_image");
140 aurelien 307
		FieldDef defTailleX = new IntegerFieldDef("taille_x");
308
		FieldDef defTailleY = new IntegerFieldDef("taille_y");
2 aperonnet 309
		FieldDef[] defTab = { defNumImage, defDatImage, defLieImage,
140 aurelien 310
				defAppImage, defUrlImageS, defUrlImageM, defUrlImage,defTailleX,defTailleY};
2 aperonnet 311
		RecordDef rd = new RecordDef(defTab);
312
		st = new Store(rd);
313
		dView.setStore(st);
314
 
315
		this.getDView().setLoadingText("chargement");
316
 
317
		// ajouts de la gestion des evenements pour la dataview
318
		ajouterListenersDataView();
5 aperonnet 319
		configDragAndDrop() ;
2 aperonnet 320
 
321
		this.add(dView);
5 aperonnet 322
 
2 aperonnet 323
		// et on déclare le composant comme instancié
5 aperonnet 324
		estInstancie = true;
2 aperonnet 325
	}
5 aperonnet 326
 
327
	public void configDragAndDrop()
328
	{
329
		// on fabrique la nouvelle configuration
330
		// les éléments sur lesquels on fait du drag 'n drop doivent tous avoir le même ddGroup
331
		DropTargetConfig dtc = new DropTargetConfig();
332
		dtc.setdDdGroup("DragGroupName");
2 aperonnet 333
 
5 aperonnet 334
		//La drop target permet de gérer l'évenement onDrop sur l'élement courant
335
		@SuppressWarnings("unused")
336
		DropTarget tg = new DropTarget(this, dtc)
337
		{
338
			public boolean notifyDrop(DragSource source, EventObject e, DragData data){
339
 
340
				// si les données proviennent d'une grille
341
				if(data instanceof GridDragData)
342
		    	{
343
					// on appelle le médiateur
344
		    		  	return iMediateur.lierObsDD(source, e, data,getId()) ;
345
		    	}
346
				return false ;
347
			}
348
 
349
			public String notifyOver(DragSource source, EventObject e, DragData data){
350
			    return "x-dd-drop-ok";
351
			}
352
		};
353
 
354
	}
355
 
2 aperonnet 356
	/**
357
	 * Méthode héritée de l'interface rafraichissable
358
	 */
359
	public void rafraichir(Object nouvelleDonnees,
360
			boolean repandreRafraichissement) {
361
 
362
		// si l'objet reçu est un store
363
		if (nouvelleDonnees instanceof Store) {
5 aperonnet 364
 
134 aurelien 365
				st = (Store) nouvelleDonnees;
366
 
367
			if(st.getCount() != 0) {
368
 
369
				// on le charge
370
				st.load();
371
 
372
					// on l'affecte à la vue
373
					dView.setStore(st);
374
					// et on rafrachit la vue
375
					dView.refresh();
376
			}
140 aurelien 377
			else
378
			{
379
				st.removeAll();
380
				st.load();
381
				dView.setStore(st);
382
				dView.refresh();
383
			}
5 aperonnet 384
 
2 aperonnet 385
		}
386
 
387
		// si le composant doit répandre le rafraichissement
388
		if (repandreRafraichissement) {
5 aperonnet 389
			// il en notifie le médiateur en lui donnant une copie des données
390
			// et en notifiant qu'il en est l'expéditeur
2 aperonnet 391
			getIMediateur().synchroniserDonneesZoomListeGalerie(
392
					nouvelleDonnees, this);
393
		}
5 aperonnet 394
 
2 aperonnet 395
		// si c'est la première mise à jour que l'on reçoit
5 aperonnet 396
		if (!estInstancie) {
2 aperonnet 397
			// alors le composant est considéré comme instancié
5 aperonnet 398
			estInstancie = true;
2 aperonnet 399
		}
400
	}
401
 
402
	/**
5 aperonnet 403
	 * Méthode héritée de l'interface VueListable Sélectionne les images dans la
404
	 * galerie suivant les identifiants donnés en paramètres
405
	 *
406
	 * @param ids
407
	 *            les identifiants des images à sélectionner
2 aperonnet 408
	 */
409
	public void selectionnerImages(int[] ids) {
410
 
411
		getDView().select(ids);
412
 
413
	}
5 aperonnet 414
 
60 jpm 415
	public void changerNumeroPage(int pageCourante) {
416
 
417
		iMediateur.changerNumeroPage(pageCourante) ;
418
 
419
	}
420
 
421
	public void changerTaillePage(int nouvelleTaillePage) {
422
 
423
		iMediateur.changerTaillePage(nouvelleTaillePage) ;
424
	}
140 aurelien 425
 
426
	public int[] calculerDimensions(int[] tailleXY) {
427
 
428
		float[] tailleXYf = {new Float(tailleXY[0]),new Float(tailleXY[1])} ;
429
        float tailleOr = this.tailleOr ;
430
        float maxTaille = Math.max(tailleXYf[1],tailleXYf[0]) ;
431
        float[] XYresize = new float[2];
432
 
433
        if(maxTaille == tailleXY[0]) {
434
            float rapport = tailleXYf[1]/tailleXYf[0] ;
435
            XYresize[0] = tailleOr ;
436
            XYresize[1] = tailleOr*rapport ;
437
        }else {
438
            float rapport = tailleXYf[0]/tailleXYf[1] ;
439
            XYresize[1] = tailleOr ;
440
            XYresize[0] = tailleOr*rapport ;
441
        }
442
 
443
        int[] res = {Math.round(XYresize[0]),Math.round(XYresize[1])} ;
444
 
445
        return res;
446
    }
60 jpm 447
 
2 aperonnet 448
}