Subversion Repositories eFlore/Applications.cel

Rev

Rev 2 | Rev 56 | 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;
4
import org.tela_botanica.client.interfaces.Rafraichissable;
5
 
6
import com.gwtext.client.core.EventCallback;
7
import com.gwtext.client.core.EventObject;
8
import com.gwtext.client.core.Template;
9
import com.gwtext.client.data.Record;
10
import com.gwtext.client.data.SimpleStore;
11
import com.gwtext.client.data.Store;
12
import com.gwtext.client.widgets.Button;
13
import com.gwtext.client.widgets.Toolbar;
14
import com.gwtext.client.widgets.ToolbarButton;
15
import com.gwtext.client.widgets.ToolbarTextItem;
16
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
17
import com.gwtext.client.widgets.form.ComboBox;
18
import com.gwtext.client.widgets.form.Field;
19
import com.gwtext.client.widgets.form.TextField;
20
import com.gwtext.client.widgets.form.event.ComboBoxListenerAdapter;
21
import com.gwtext.client.widgets.form.event.TextFieldListenerAdapter;
22
 
23
/**
5 aperonnet 24
 * Barre de pagination asynchrone avec filtrage des touches et accès directs et
25
 * séquentiels à une page
26
 *
2 aperonnet 27
 * @author aurelien
5 aperonnet 28
 *
2 aperonnet 29
 */
30
public class pageToolBarVue extends Toolbar implements Rafraichissable {
5 aperonnet 31
 
2 aperonnet 32
	/**
33
	 * Instance du médiateur à qui on notifie les évnènements
34
	 */
5 aperonnet 35
	private ImageMediateur iMediateur = null;
36
 
2 aperonnet 37
	/**
38
	 * Bouton précédent
39
	 */
5 aperonnet 40
	private ToolbarButton prevPage = new ToolbarButton();
2 aperonnet 41
	/**
42
	 * Bouton suivant
43
	 */
5 aperonnet 44
	private ToolbarButton suivPage = new ToolbarButton();
2 aperonnet 45
	/**
5 aperonnet 46
	 * Numéro de la page courante (attention, commence à zéro pour des raisons
47
	 * pratiques)
2 aperonnet 48
	 */
5 aperonnet 49
	private int pageCourante = 0;
2 aperonnet 50
	/**
51
	 * Nombre de page total
52
	 */
5 aperonnet 53
	private int pageTotale = 1;
2 aperonnet 54
	/**
55
	 * Nombre d'élements total
56
	 */
5 aperonnet 57
	private int nbElement = 0;
2 aperonnet 58
	/**
59
	 * Nombre d'élément par page
60
	 */
5 aperonnet 61
	private int taillePage = 0;
2 aperonnet 62
	/**
63
	 * Texte statique de la toolbar 1
64
	 */
5 aperonnet 65
	private ToolbarTextItem page = new ToolbarTextItem("Page ");
2 aperonnet 66
	/**
67
	 * Affichage de la page courante
68
	 */
5 aperonnet 69
	private TextField champPage = new TextField("" + (pageCourante + 1));
2 aperonnet 70
	/**
71
	 * Affichage de "sur pageTotale "
72
	 */
5 aperonnet 73
	private ToolbarTextItem surTotalPage = new ToolbarTextItem(" sur "
74
			+ pageTotale);
2 aperonnet 75
	/**
76
	 * Texte statique de la toolbar 2
77
	 */
5 aperonnet 78
	private ToolbarTextItem afficherNbElem = new ToolbarTextItem("Afficher ");
2 aperonnet 79
	/**
5 aperonnet 80
	 * Combobox permettant de selectionner le nombre d'élements à afficher par
81
	 * page et donc de changer la variable taillePage
2 aperonnet 82
	 */
5 aperonnet 83
	private ComboBox selecteurTaillePage = new ComboBox();
2 aperonnet 84
	/**
85
	 * Texte statique de la toolbar 3
86
	 */
5 aperonnet 87
	private ToolbarTextItem nbElemParPage = new ToolbarTextItem(
88
			" images par page ");
2 aperonnet 89
	/**
90
	 * Affiche l'intervalle des éléments contenus dans la page
91
	 */
5 aperonnet 92
	private ToolbarTextItem intervalleElements = new ToolbarTextItem("Images "
93
			+ pageCourante * taillePage + " sur " + nbElement);
2 aperonnet 94
 
95
	/**
96
	 * retourne le mediateur associe à la barre
97
	 */
5 aperonnet 98
	public ImageMediateur getImediateur() {
99
		return iMediateur;
2 aperonnet 100
	}
5 aperonnet 101
 
102
	/***************************************************************************
2 aperonnet 103
	 * constructeur sans argument (privé car ne doit pas être utilisé)
104
	 */
105
	@SuppressWarnings("unused")
5 aperonnet 106
	private pageToolBarVue() {
107
		super();
2 aperonnet 108
	}
5 aperonnet 109
 
2 aperonnet 110
	/**
111
	 * constructeur avec paramètres
5 aperonnet 112
	 *
113
	 * @param im
114
	 *            le médiateur à associer à la barre
2 aperonnet 115
	 */
5 aperonnet 116
	public pageToolBarVue(ImageMediateur im) {
117
		super();
118
 
119
		iMediateur = im;
120
 
121
		// on dispose un peu de texte et quelques espaces pour séparer les
122
		// éléments
123
		addButton(prevPage);
124
		addSpacer();
125
		addItem(page);
126
		addField(champPage);
127
		addItem(surTotalPage);
128
		addSpacer();
129
		addButton(suivPage);
130
 
131
		champPage.setWidth(30);
132
 
133
		addSpacer();
134
		addItem(afficherNbElem);
135
 
136
		prevPage.setIcon("page_prev.png");
137
		suivPage.setIcon("page_suiv.png");
138
 
2 aperonnet 139
		// le store contient les valeur possibles pour les tailles de page
5 aperonnet 140
		final Store store = new SimpleStore(new String[] { "nb_page" },
141
				getNbPages());
142
		store.load();
143
 
144
		// le template definit ce que l'on affiche pour chaque element du store
145
		// dans la combobox
146
		final Template tp = new Template("<div class=\"x-combo-list-item\">"
147
				+ "{nb_page}" + "<div class=\"x-clear\"></div></div>");
2 aperonnet 148
		tp.compile();
5 aperonnet 149
 
150
		selecteurTaillePage.setTpl(tp);
151
		selecteurTaillePage.setStore(store);
152
		selecteurTaillePage.setWidth(40);
153
		selecteurTaillePage.setEditable(false);
154
		addField(selecteurTaillePage);
155
		selecteurTaillePage.setValue("50");
156
		selecteurTaillePage.setWidth(50);
157
		addItem(nbElemParPage);
158
 
159
		// on remplit l'espace pour que l'intervalle d'élement se place à droite
160
		// de la barre
161
		addFill();
162
		addItem(intervalleElements);
163
		addSpacer();
164
 
2 aperonnet 165
		// on ajoute les différents listeners
5 aperonnet 166
		ajouterListeners();
2 aperonnet 167
	}
5 aperonnet 168
 
2 aperonnet 169
	/**
5 aperonnet 170
	 * ajoute les différents listeners nécessaires au bon fonctionnement des
171
	 * éléments de la barre de pagination
2 aperonnet 172
	 */
5 aperonnet 173
	private void ajouterListeners() {
174
		// boutons suivants et précédents
2 aperonnet 175
		prevPage.addListener(new ButtonListenerAdapter() {
176
 
177
			public void onClick(Button button, EventObject e) {
5 aperonnet 178
 
2 aperonnet 179
				// si la page courante n'est pas la première
5 aperonnet 180
				if (pageCourante > 0) {
2 aperonnet 181
					// on décrémente la page courante de 1
5 aperonnet 182
					pageCourante--;
2 aperonnet 183
					// on rafraichit l'affichage
5 aperonnet 184
					rafraichirNumeroPage();
2 aperonnet 185
					// et on notifie le médiateur de l'évenement
5 aperonnet 186
					getImediateur().changerNumeroPage(pageCourante);
187
 
2 aperonnet 188
				}
189
			}
5 aperonnet 190
		});
191
 
2 aperonnet 192
		suivPage.addListener(new ButtonListenerAdapter() {
5 aperonnet 193
 
2 aperonnet 194
			public void onClick(Button button, EventObject e) {
5 aperonnet 195
 
2 aperonnet 196
				// si la page courante n'est pas la dernière
5 aperonnet 197
				if (pageCourante < pageTotale - 1) {
2 aperonnet 198
					// on incrémente la page courante de 1
5 aperonnet 199
					pageCourante++;
2 aperonnet 200
					// on rafraichit l'affichage
5 aperonnet 201
					rafraichirNumeroPage();
2 aperonnet 202
					// et on notifie le médiateur de l'évenement
5 aperonnet 203
					getImediateur().changerNumeroPage(pageCourante);
204
 
205
				}
2 aperonnet 206
			}
5 aperonnet 207
		});
208
 
2 aperonnet 209
		champPage.addListener(new TextFieldListenerAdapter() {
210
 
211
			public void onSpecialKey(Field field, EventObject e) {
5 aperonnet 212
 
2 aperonnet 213
				// on teste si la touche entrée a été pressée
5 aperonnet 214
				if (e.getKey() == EventObject.ENTER) {
215
					int nouvellePage = pageCourante;
2 aperonnet 216
					// on teste avec parseInt si la valeur entrée est un entier
5 aperonnet 217
					try {
218
						nouvellePage = Integer
219
								.parseInt(champPage.getRawValue());
220
					}
221
					// si ce n'est pas le cas alors on remet le numéro de page
222
					// correct
223
					catch (NumberFormatException nfe) {
224
						rafraichirNumeroPage();
225
						champPage.focus(true);
226
						return;
227
					}
2 aperonnet 228
 
5 aperonnet 229
					// si la conversion reussit on verifie s'il est nécessaire
230
					// de changer de page
231
					// et si la nouvelle est comprise dans l'intervalle des
232
					// pages existantes (0..pageTotale)
233
					if (nouvellePage != pageCourante + 1 && nouvellePage > 0
234
							&& nouvellePage <= pageTotale) {
235
						// le cas échéant, on charge la nouvelle page et on
236
						// notifie le médiateur
237
						changerPageCourante(nouvellePage - 1);
238
						getImediateur().changerNumeroPage(pageCourante);
239
 
240
					} else {
241
						// sinon on reaffiche l'ancien numero de page sans rien
242
						// changer
243
						rafraichirNumeroPage();
244
						champPage.focus(true);
2 aperonnet 245
					}
246
				}
247
			}
5 aperonnet 248
 
2 aperonnet 249
			public void onFocus(Field field) {
5 aperonnet 250
 
251
				champPage.focus(true);
2 aperonnet 252
			}
5 aperonnet 253
 
2 aperonnet 254
		});
5 aperonnet 255
 
256
		// pour éviter de se compliquer la vie, on filtre tous les charactères
257
		// non numériques
2 aperonnet 258
		champPage.addKeyPressListener(new EventCallback() {
259
 
260
			public void execute(EventObject e) {
5 aperonnet 261
 
2 aperonnet 262
				// si c'est un numerique
5 aperonnet 263
				if (Character.isDigit((char) e.getCharCode())) {
2 aperonnet 264
					// on laisse passer
5 aperonnet 265
					return;
2 aperonnet 266
				}
5 aperonnet 267
 
2 aperonnet 268
				// si c'est la touche entrée ou backspace (valider ou effacer)
5 aperonnet 269
				if (e.getKey() == EventObject.ENTER
270
						|| e.getKey() == EventObject.BACKSPACE) {
2 aperonnet 271
					// on laisse passer
5 aperonnet 272
					return;
273
				} else {
274
					// sinon on remet le numero de page correct et on annule
275
					// l'évenement
276
					rafraichirNumeroPage();
277
					e.stopEvent();
2 aperonnet 278
				}
279
			}
5 aperonnet 280
 
281
		});
282
 
283
		// listener pour la selection dans la combobox
2 aperonnet 284
		selecteurTaillePage.addListener(new ComboBoxListenerAdapter() {
5 aperonnet 285
 
2 aperonnet 286
			public void onSelect(ComboBox comboBox, Record record, int index) {
5 aperonnet 287
 
288
				String nouvelleTaillePageString = comboBox.getStore()
289
						.getRecordAt(index).getAsString("nb_page");
290
				int nouvelleTaillePage = Integer
291
						.parseInt(nouvelleTaillePageString);
292
 
2 aperonnet 293
				// si la taille de page est différente de l'ancienne
5 aperonnet 294
				if (nouvelleTaillePage != taillePage) {
2 aperonnet 295
					// on la change
5 aperonnet 296
					changerTaillePage(nouvelleTaillePage);
2 aperonnet 297
				}
298
				// et on met la valeur à jour dans la combobox
5 aperonnet 299
				comboBox.setValue(nouvelleTaillePageString);
2 aperonnet 300
			}
5 aperonnet 301
 
302
		});
2 aperonnet 303
	}
5 aperonnet 304
 
2 aperonnet 305
	/**
5 aperonnet 306
	 * Met à jour les affichage sur les numéros de pages et d'intervalle
307
	 * d'éléments à partir des variables de classes
2 aperonnet 308
	 */
5 aperonnet 309
	public void rafraichirNumeroPage() {
310
		surTotalPage.setText(" sur " + pageTotale);
311
 
312
		if (nbElement == 0) {
313
			champPage.setValue("" + (0));
314
			// on met simplement à jour l'intervalle qui contient toujours le
315
			// même nombre d'éléments
316
			intervalleElements.setText("Images 0 - 0 sur 0");
317
		} else {
318
			champPage.setValue("" + (pageCourante + 1));
319
 
320
			// si la page n'est pas la dernière
321
			if (pageCourante + 1 != pageTotale) {
322
				// sauf pour la dernière page qui contient souvent moins
323
				// d'élements que le nombre d'élements par page
324
				intervalleElements.setText("Images " + pageCourante
325
						* taillePage + " - " + (pageCourante + 1) * taillePage
326
						+ " sur " + nbElement);
327
			} else {
328
				// on met simplement à jour l'intervalle qui contient toujours
329
				// le même nombre d'éléments
330
				intervalleElements.setText("Images " + pageCourante
331
						* taillePage + " - " + nbElement + " sur " + nbElement);
332
			}
2 aperonnet 333
		}
334
	}
5 aperonnet 335
 
2 aperonnet 336
	/**
5 aperonnet 337
	 * Met à jour la page en cours
338
	 *
339
	 * @param nouvellePageCourante
340
	 *            la nouvelle page en cours
2 aperonnet 341
	 */
5 aperonnet 342
	public void changerPageCourante(int nouvellePageCourante) {
343
		pageCourante = nouvellePageCourante;
2 aperonnet 344
	}
5 aperonnet 345
 
2 aperonnet 346
	/**
347
	 * Methode héritée de l'interface rafraichissable
348
	 */
349
	public void rafraichir(Object nouvelleDonnees,
350
			boolean repandreRaffraichissement) {
5 aperonnet 351
 
2 aperonnet 352
		// si on reçoit un tableau de int
5 aperonnet 353
		if (nouvelleDonnees instanceof int[]) {
354
			int[] page = (int[]) nouvelleDonnees;
355
			// le premier élement est le nombre de pages totales
356
			pageTotale = page[0];
2 aperonnet 357
			// le second la page en cours
5 aperonnet 358
			pageCourante = page[1];
2 aperonnet 359
			// le troisième la taille de la page
5 aperonnet 360
			taillePage = page[2];
2 aperonnet 361
			// et le dernier le nombre total d'éléments
5 aperonnet 362
			nbElement = page[3];
363
 
364
			// si la page courante dépasse la page totale (cas normalement
365
			// improbable car géré en amont)
366
			// on met le numéro de page à la page courante -1 (car la page
367
			// courante est comptée à partir
2 aperonnet 368
			// de zéro)
5 aperonnet 369
			if (pageCourante >= pageTotale && pageCourante != 0) {
370
				pageCourante = pageTotale - 1;
2 aperonnet 371
				// le cas échéant on en notifie le médiateur
5 aperonnet 372
				getImediateur().changerNumeroPage(pageCourante);
2 aperonnet 373
			}
374
		}
5 aperonnet 375
 
376
		// enfin on rafraichit les informations affichées à partir des nouvelles
377
		// variables de classes mises à jour
378
		rafraichirNumeroPage();
2 aperonnet 379
	}
5 aperonnet 380
 
2 aperonnet 381
	/**
382
	 * Renvoie les différents intervalles de pages possibles
5 aperonnet 383
	 *
384
	 * @return un tableau de tableau de string qui contient les différentes
385
	 *         taille de pages
2 aperonnet 386
	 */
5 aperonnet 387
	public String[][] getNbPages() {
388
		String[][] pages = { { "200" }, { "100" }, { "50" }, { "20" }, { "10" } };
389
 
390
		return pages;
2 aperonnet 391
	}
392
 
393
	/**
5 aperonnet 394
	 * Envoie au médiateur une demande pour modifier la taille de la page (qui
395
	 * va à son tour faire les modifications nécessaires)
396
	 *
397
	 * @param nouvelleTaillePage
398
	 *            la nouvelle taille de page (élement appartenant au tableau
399
	 *            renvoyé par getNbPages())
2 aperonnet 400
	 */
401
	public void changerTaillePage(int nouvelleTaillePage) {
5 aperonnet 402
 
403
		getImediateur().changerTaillePage(nouvelleTaillePage);
404
 
2 aperonnet 405
	}
5 aperonnet 406
 
2 aperonnet 407
	/**
5 aperonnet 408
	 * Selectionne la valeur correspond à celle passée en paramètre dans la
409
	 * combobox (si elle existe)
410
	 *
411
	 * @param nouvelleTaillePage
412
	 *            la nouvelle taille de page
2 aperonnet 413
	 */
414
	public void selectionnerTaillePage(int nouvelleTaillePage) {
5 aperonnet 415
 
416
		selecteurTaillePage.setValue("" + nouvelleTaillePage);
2 aperonnet 417
	}
5 aperonnet 418
 
2 aperonnet 419
}