/trunk/src/org/tela_botanica/client/vues/pageToolBarVue.java |
---|
104,7 → 104,6 |
*/ |
private ToolbarTextItem intervalleElements = new ToolbarTextItem("Images "+pageCourante*taillePage+" sur "+nbElement) ; |
/** |
* retourne le mediateur associe à la barre |
*/ |
113,7 → 112,6 |
return iMediateur ; |
} |
/*** |
* constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
374,7 → 372,7 |
/** |
* Renvoie les différents intervalles de pages possibles |
* @return |
* @return un tableau de tableau de string qui contient les différentes taille de pages |
*/ |
public String[][] getNbPages() |
{ |
/trunk/src/org/tela_botanica/client/vues/ListeImageVue.java |
---|
50,7 → 50,8 |
import com.gwtextux.client.data.BufferedStore; |
/** |
* Liste d'image composée de miniatures et d'information sur l'image |
* Liste d'image composée de miniatures et d'information sur l'image, implémente |
* l'interface rafraichissable et l'interface vueListable |
* |
* @author aurelien |
*/ |
57,40 → 58,85 |
public class ListeImageVue extends GridPanel implements Rafraichissable, |
VueListable { |
// instance du médiateur |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null; |
/** |
* Config de colonne |
*/ |
private ColumnConfig numImage; |
/** |
* Config de colonne |
*/ |
private ColumnConfig urlImage; |
/** |
* Config de colonne |
*/ |
private ColumnConfig lieImage; |
/** |
* Config de colonne |
*/ |
private ColumnConfig datImage; |
/** |
* Config de colonne |
*/ |
private ColumnConfig appImage; |
/** |
* Modele de colonnes |
*/ |
private ColumnModel modeleColonnes; |
/** |
* Booleen d'instanciation |
*/ |
private boolean estInstancie = false; |
// données locales |
// store qui gère les données de la liste d'images |
/** |
* Store qui contient les données à afficher |
*/ |
private Store st = null; |
/** |
* Configuration des colonnes du store |
*/ |
private ColumnConfig cl = null; |
/** |
* Barre de pagination |
*/ |
private pageToolBarVue bt = null ; |
/** |
* Constructeur sans arguments (privé car ne doit pas être utilisé) |
*/ |
private ListeImageVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec argument |
* @param im le médiateur à associer |
*/ |
public ListeImageVue(ImageMediateur im) { |
super(); |
new ListeImageVue() ; |
this.setId("listeImageGrid"); |
// on associe le médiateur |
this.iMediateur = im; |
// on place la barre de pagination |
bt = new pageToolBarVue(im); |
this.setBottomToolbar(bt) ; |
// on construit le modèle de colonnes |
numImage = new ColumnConfig("numéro", "num_image", 30, true); |
datImage = new ColumnConfig("date", "dat_image", 120, true); |
lieImage = new ColumnConfig("lieu", "lie_image", 120, true); |
appImage = new ColumnConfig("appareil", "app_image", 200, true); |
// la colonne url possède une méthode de rendu spéciale |
urlImage = new ColumnConfig("Image", "url_image_S", 30, true, |
new Renderer() { |
97,7 → 143,7 |
public String render(Object value, |
CellMetadata cellMetadata, Record record, |
int rowIndex, int colNum, Store store) { |
// on affiche une div contenant l'image pointée par l'url |
String ImgUrl = record.getAsString("url_image_S"); |
String ImgNum = record.getAsString("num_image"); |
return "<div class=\"img-list\"> <img src=\"" + ImgUrl |
106,6 → 152,7 |
}); |
// on associe le modèle de colonnes |
ColumnConfig[] cm = {numImage, urlImage, datImage, lieImage, appImage}; |
modeleColonnes = new ColumnModel(cm); |
this.setColumnModel(modeleColonnes); |
125,16 → 172,22 |
defAppImage, defUrlImageS, defUrlImageM, defUrlImage }; |
RecordDef rd = new RecordDef(defTab); |
st = new Store(rd); |
// on associe le store |
this.setStore(st); |
this.getView().setAutoFill(true); |
// on crée un masque de chargement qui s'affichera lors des mises à jour |
this.setLoadMask("chargement"); |
// on ajoute les listeners |
ajouterListeners(); |
} |
public void ajouterListeners() { |
/** |
* Ajoute les listeners pour la gestion des évènements |
*/ |
private void ajouterListeners() { |
this.addListener(new ContainerListenerAdapter() { |
public void onHide(Component component) { |
141,6 → 194,7 |
} |
// lors du premier rendu on demande les données qui sont déjà contenues dans la galerie qui est le premier élément affiché |
public void onRender(Component component) { |
if (!isEstInstancie()) { |
157,21 → 211,26 |
this.addGridRowListener(new GridRowListener() { |
// gestion du clic sur une ligne |
public void onRowClick(GridPanel grid, int rowIndex, EventObject e) { |
// on notifie le médiateur et on lui passe le nuémro de ligne |
getIMediateur().clicListeImage(rowIndex); |
} |
// gestion du clic droit |
public void onRowContextMenu(GridPanel grid, int rowIndex, |
EventObject e) { |
// on stoppe l'évenement pour empecher le navigateur d'afficher son propre menu |
e.stopEvent() ; |
// on notifie le médiateur en lui passant l'évenement |
getIMediateur().montrerContextMenu(e); |
} |
// gestion du double clic |
public void onRowDblClick(GridPanel grid, int rowIndex, |
EventObject e) { |
// on notifie le médiateur en lui passant le numéro de ligne |
getIMediateur().doubleClicListeImage(rowIndex); |
} |
}); |
178,12 → 237,17 |
this.getSelectionModel().addListener(new RowSelectionListenerAdapter() { |
// gestion de la sélection |
public void onSelectionChange(RowSelectionModel sm) { |
// si on a rien de sélectionné |
if (sm.getCount() <= 0) { |
// on notifie le médiateur (qui désactive notamment l'accès à certaines infos) |
getIMediateur().aucuneSelection(); |
} else { |
// sinon on notifie le médiateur |
getIMediateur().selection(); |
// et on lui demande de synchroniser la selection avec les autres vues |
getIMediateur().synchroniserSelection("liste"); |
} |
} |
190,10 → 254,10 |
}); |
} |
public ColumnConfig getCl() { |
return cl; |
} |
/** |
* Méthode héritée de l'interface VueListable |
* Sélectionne les images dans la galerie suivant les identifiants donnés en paramètres |
*/ |
public String[] getIdSelectionnees() { |
Record[] selection = this.getSelectionModel().getSelections(); |
int taille = selection.length; |
207,50 → 271,77 |
return id_selection; |
} |
/** |
* Accesseur pour la config de colonnes |
* @return la config de colonnes |
*/ |
public ColumnConfig getCl() { |
return cl; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé |
*/ |
public ImageMediateur getIMediateur() { |
return iMediateur; |
} |
/** |
* Accesseur pour le modèle de colonnes |
* @return le modèle de colonnes |
*/ |
public ColumnModel getModeleColonnes() { |
return modeleColonnes; |
} |
public ColumnConfig getNumImage() { |
return numImage; |
} |
/** |
* Accesseur pour le store |
* @return le store contenant les données |
*/ |
public Store getSt() { |
return st; |
} |
public ColumnConfig getUrlImage() { |
return urlImage; |
} |
/** |
* @return the estInstancie |
* Accesseur pour le booleen d'instanciation |
* @return le booleen d'instanciation |
*/ |
public boolean isEstInstancie() { |
return estInstancie; |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
* @param nouvelleDonnees les nouvelles données |
* @param repandreRafraichissement le booleen de notification du rafraichissement |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRafraichissement) { |
// si on reçoit un store |
if (nouvelleDonnees instanceof Store) { |
// on affecte celui-ci comme gestionnaire de données |
st = (Store) nouvelleDonnees; |
st.load(); |
// et on reconfigure et rafraichit la vue |
this.reconfigure(st, this.getColumnModel()); |
} |
// si on doit répandre l'évenement |
if (repandreRafraichissement) { |
// on notifie le médiateur avec une copie des données |
getIMediateur().synchroniserDonneesZoomListeGalerie( |
nouvelleDonnees, this); |
} |
} |
/** |
* Sélectionne des enregistrements donné |
* @param sel un tableau d'enregistrement à selectionner |
*/ |
public void selectionnerEnregistrements(Record[] sel) { |
if (isEstInstancie()) { |
259,6 → 350,10 |
} |
} |
/** |
* Accesseur pour la toolbar de pagination |
* @return la toolbar de pagination |
*/ |
public pageToolBarVue getToolBarVue() |
{ |
return bt ; |
265,19 → 360,11 |
} |
/** |
* @param estInstancie |
* the estInstancie to set |
* Setteur pour le booleen d'instanciation |
* @param estInstancie la nouvelle valeur du booleen |
*/ |
public void setEstInstancie(boolean estInstancie) { |
this.estInstancie = estInstancie; |
} |
/** |
* @param mediateur |
* the iMediateur to set |
*/ |
public void setIMediateur(ImageMediateur mediateur) { |
iMediateur = mediateur; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/ArbreMotsClesVue.java |
---|
1,72 → 1,104 |
package org.tela_botanica.client.vues; |
import java.util.HashMap; |
import org.tela_botanica.client.image.ImageMediateur; |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import org.tela_botanica.client.modeles.MotsClesAsynchroneDAO; |
import com.google.gwt.core.client.JavaScriptObject; |
import com.google.gwt.user.client.Window; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.core.ExtElement; |
import com.gwtext.client.data.Node; |
import com.gwtext.client.data.NodeTraversalCallback; |
import com.gwtext.client.data.Tree; |
import com.gwtext.client.dd.DD; |
import com.gwtext.client.dd.DragData; |
import com.gwtext.client.dd.DragDrop; |
import com.gwtext.client.widgets.BoxComponent; |
import com.gwtext.client.widgets.Button; |
import com.gwtext.client.widgets.Component; |
import com.gwtext.client.widgets.Container; |
import com.gwtext.client.widgets.Editor; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.ButtonListener; |
import com.gwtext.client.widgets.event.ButtonListenerAdapter; |
import com.gwtext.client.widgets.event.ComponentListener; |
import com.gwtext.client.widgets.event.ComponentListenerAdapter; |
import com.gwtext.client.widgets.event.ContainerListener; |
import com.gwtext.client.widgets.event.ContainerListenerAdapter; |
import com.gwtext.client.widgets.event.EditorListener; |
import com.gwtext.client.widgets.event.EditorListenerAdapter; |
import com.gwtext.client.widgets.event.PanelListenerAdapter; |
import com.gwtext.client.widgets.form.Field; |
import com.gwtext.client.widgets.form.TextField; |
import com.gwtext.client.widgets.layout.RowLayout; |
import com.gwtext.client.widgets.layout.RowLayoutData; |
import com.gwtext.client.widgets.menu.Menu; |
import com.gwtext.client.widgets.tree.DropNodeCallback; |
import com.gwtext.client.widgets.tree.TreeEditor; |
import com.gwtext.client.widgets.tree.TreeNode; |
import com.gwtext.client.widgets.tree.TreePanel; |
import com.gwtext.client.widgets.tree.event.TreePanelListener; |
import com.gwtext.client.widgets.tree.event.TreePanelListenerAdapter; |
/** |
* Arbre des mots clés, qui est une vue rafraichissable, |
* qui contient des mots clés cochables et réorganisables à volonté |
* @author aurelien |
* |
*/ |
public class ArbreMotsClesVue extends Panel implements Rafraichissable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
/** |
* Le treepanel qui affiche l'arbre |
*/ |
private TreePanel arbreMotsCles = null ; |
/** |
* L'éditeur qui permet de modifier les mots clés dans l'arbre |
*/ |
private TreeEditor te = null ; |
/** |
* Le textfield associé à l'éditeur |
*/ |
private TextField tfEdit = null ; |
/** |
* Bouton de validation |
*/ |
private Button valider = null ; |
/** |
* Une string permettant connaitre les mots clés cochés en cours séparés par des virgules |
*/ |
private String motsClesEnCours = "" ; |
/** |
* Tableau contenant les mots clés qui n'ont pas encore été jaouté à l'arbre |
* (sert au lazy rendering quand on reçoit des mots clés avant que le rendu du conteneur n'ai été effectué) |
*/ |
private String[] motsClesEnAttente ; |
/** |
* Booléen d'évènement qui sert à savoir si on est en train d'ajouter un noeud |
*/ |
private boolean ajoutNoeud = false ; |
/** |
* Booléen d'évènement qui sert à savoir si on est en train de modifier un noeud |
*/ |
private boolean modifNoeud = false ; |
/** |
* Booléen d'instanciation du conteneur |
*/ |
private boolean estInstancie = false ; |
/** |
* Booléen d'évènement qui sert à savoir si les mots clés ont bien été reçu |
*/ |
private boolean motsCleInitialises ; |
/** |
* Constructeur sans paramètre (privé car interdit d'utilisation) |
*/ |
private ArbreMotsClesVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
*/ |
public ArbreMotsClesVue(ImageMediateur im) |
{ |
// on crée le panel |
super("Mots clés") ; |
this.setLayout(new RowLayout()); |
iMediateur = im ; |
// on crée le conteneur de l'arbre |
arbreMotsCles = new TreePanel() ; |
// on permet le drag and drop dans l'arbre |
arbreMotsCles.setEnableDD(true) ; |
// on crée une racine pour l'arbre |
TreeNode root = new TreeNode("Tags") ; |
root.setId("racine") ; |
String[] usObject = {"Mots clés" , "racine" } ; |
76,17 → 108,25 |
arbreMotsCles.setRootVisible(false) ; |
arbreMotsCles.getRootNode().setIcon("tela.png") ; |
// on crée l'éditeur pour l'arbre |
tfEdit = new TextField() ; |
te = new TreeEditor(arbreMotsCles,tfEdit) ; |
valider = new Button("Appliquer") ; |
arbreMotsCles.add(te) ; |
// on met en forme le layout |
this.add(arbreMotsCles,new RowLayoutData("90%")) ; |
this.add(valider,new RowLayoutData("10%")) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
/** |
* Acesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
private ImageMediateur GetIMediateur() { |
return iMediateur ; |
94,7 → 134,8 |
} |
/** |
* @return the arbreMotsCles |
* Acesseur pour l'arbre des mots clés |
* @return le panel contenant l'arbre |
*/ |
public TreePanel getArbreMotsCles() { |
return arbreMotsCles; |
101,7 → 142,8 |
} |
/** |
* @return the te |
* Accesseur pour l'éditeur |
* @return l'éditeur associé à l'arbre |
*/ |
public TreeEditor getTe() { |
return te; |
108,16 → 150,21 |
} |
/** |
* @return the tfEdit |
* Acesseur pour le TextField associé à l'éditeur |
* @return le champ texte associé à l'éditeur |
*/ |
public TextField getTfEdit() { |
return tfEdit; |
} |
public void ajouterListeners() |
/** |
* Ajoute les listeners nécessaires pour la gestion des évènements |
*/ |
private void ajouterListeners() |
{ |
arbreMotsCles.addListener(new TreePanelListenerAdapter() { |
// gestion du clic sur un noeud |
public void onClick(TreeNode node, EventObject e) { |
e.stopEvent() ; |
124,7 → 171,7 |
gererClicNoeud(node); |
} |
// gestion du clic droit sur un noeud |
public void onContextMenu(TreeNode node, EventObject e) { |
e.stopEvent() ; |
132,6 → 179,7 |
} |
// gestion du double clic sur un noeud |
public void onDblClick(TreeNode node, EventObject e) { |
modifNoeud = true ; |
138,9 → 186,10 |
te.startEdit(node); |
} |
// gestion de la modification du texte d'un noeud |
public void onTextChange(TreeNode node, String text, String oldText) { |
// on récupère les informations associées au noeud |
TreeNode nd = node ; |
String[] usObject = new String[2] ; |
usObject[0] = text ; |
147,29 → 196,39 |
usObject[1] = ((String[])nd.getUserObject())[1] ; |
nd.setUserObject(usObject) ; |
// si c'est un nouveau noeud |
if(ajoutNoeud) |
{ |
// on notifie le médiateur de l'ajout et on lui passe l'arbre |
GetIMediateur().ajouterMotCleDansArbre(nd,getArbreMotsCles().getTree()) ; |
// et considière l'ajout achevé |
ajoutNoeud = false ; |
} |
// si c'est noeud déjà existant |
else |
{ |
// on notifie le médiateur de la modification et on lui passe l'arbre |
GetIMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree()) ; |
// et on considère la modification achevée |
modifNoeud = false ; |
GetIMediateur().modifierMotCleDansArbre(nd,getArbreMotsCles().getTree()) ; |
} |
} |
// gestion du déplacement d'un noeud |
public void onMoveNode(Tree tree, TreeNode node, TreeNode oldParent, TreeNode newParent,int index) |
{ |
// on notifie le médiateur et on lui passe l'arbre |
GetIMediateur().deplacerMotCleDansArbre(node, getArbreMotsCles().getTree()) ; |
} |
// gestion du changement de valeur dans la checkbox |
public void onCheckChange(TreeNode node, boolean checked) { |
// si on a coché un noeud |
if(checked) |
{ |
// on remonte pour cocher tous les parents du noeud |
node.bubble(new NodeTraversalCallback() { |
public boolean execute(Node node) |
185,15 → 244,21 |
}) ; |
// gestion de la validation |
valider.addListener(new ButtonListenerAdapter() { |
// lors du clic |
public void onClick(Button button, EventObject e) { |
// on vide les mots clés en cours |
motsClesEnCours = "" ; |
// pour chaque noeud à partir de la racine |
getArbreMotsCles().getRootNode().cascade(new NodeTraversalCallback() { |
// on éxécute une fonction |
public boolean execute(Node node) { |
// on récupère le mot clé associé au noeud et ses infos |
TreeNode tn = getArbreMotsCles().getNodeById(node.getId()) ; |
String[] usObject = (String[])tn.getUserObject() ; |
201,6 → 266,7 |
if(tn.getUI().isChecked()) |
{ |
// et les concatène à la string des mots clés en cours |
motsClesEnCours += usObject[1]+"," ; |
} |
209,6 → 275,7 |
}); |
// enfin on notifie le médiateur et on lui passe l'arbre et la liste des mots clés ainsi obtenue |
GetIMediateur().mettreAjourMotsCles(motsClesEnCours,arbreMotsCles.getTree()) ; |
} |
}) ; |
215,6 → 282,9 |
} |
/** |
* Envoie une demande au médiateur pour obtenir l'arbre des mots clés |
*/ |
public void obtenirArbreMotsCles() { |
GetIMediateur().obtenirArbreMotsCles(this) ; |
221,39 → 291,61 |
} |
/** |
* Supprime un noeud de l'arbre |
* @param n le noeud à supprimer |
*/ |
public void supprimerNoeud(TreeNode n) |
{ |
// si ça n'est pas la racine (qu'on ne peut pas supprimer) |
if(!n.getId().equals(getArbreMotsCles().getRootNode().getId())) |
{ |
// on détache le noeud et on le détruit |
n.getParentNode().removeChild(n); |
n.destroy() ; |
// puis on en notifie le médiateur en lui passant le noeud supprimé et l'arbre |
GetIMediateur().supprimerMotCleDansArbre(n, arbreMotsCles.getTree()) ; |
} |
else |
{ |
// si l'utilisateur tente de supprimer la racine, on l'avertit de son erreur |
Window.alert("Impossible de supprimer la racine de l'arbre") ; |
} |
} |
/** |
* Ajoute un noeud dans l'arbre au parent donné |
* @param parent le futur parent du noeud à ajouter |
*/ |
public void ajouterNoeud(TreeNode parent) |
{ |
// on met l'ajout du noeud à vrai |
ajoutNoeud = true ; |
// on crée un nouveau noeud vide |
TreeNode nd = new TreeNode(""); |
nd.setIcon("tela.png") ; |
nd.setChecked(true); |
// on associe un objet au noeud qui contient des infos |
String[] usObject = new String[2] ; |
// l'objet contient le nom du noeud |
usObject[0] = "" ; |
// l'identifiant d'un noeud c'est son hashcode |
usObject[1] = Integer.toString(nd.hashCode()) ; |
// l'objet associé au noeud contient aussi son identifiant |
nd.setId(usObject[1]) ; |
nd.setUserObject(usObject) ; |
// on le concatène au parent et on étend ses enfants |
parent.appendChild(nd); |
parent.expand(); |
// enfin on place le curseur et on fait apparaitre le champ d'édition pour que l'utilisateur nomme son mot clé |
te.startEdit(nd); |
} |
/** |
* Coche le noeud s'il est décoché, le décoche sinon |
* @param node |
*/ |
public void gererClicNoeud(TreeNode node) |
{ |
if(node.getUI().isChecked()) |
266,16 → 358,24 |
} |
} |
/** |
* Parcourt l'arbre et coche les noeud qui font partie de la liste des mots clés à cocher |
* @param motsClesIds un tableau contenant les identifiants des mots clés à cocher |
*/ |
public void cocherMotsCles(final String[] motsClesIds) |
{ |
if(getArbreMotsCles() != null && getArbreMotsCles().getRootNode() != null) |
{ |
// à partir de la racine |
getArbreMotsCles().getRootNode().cascade(new NodeTraversalCallback() { |
// pour chaque noeud |
public boolean execute(Node node) { |
// on parcourt le tableau des mots clés |
for(int i = 0 ; i < motsClesIds.length ; i++) |
{ |
// si le mot clé fait partie des id à cocher on le coche |
String usObject[] = (String[])node.getUserObject() ; |
String nodeId = usObject[1] ; |
287,6 → 387,7 |
return true ; |
} |
} |
// et on passe au suivant |
return true; |
} |
294,32 → 395,53 |
} |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
* @param nouvelleDonnees les nouvelles données pour l'objet |
* @param repandreRafraichissement booleen qui dit si on doit répandre l'évenement |
*/ |
public void rafraichir(Object nouvelleDonnees, |
boolean repandreRafraichissement) { |
// si on a reçu un arbre |
if(nouvelleDonnees instanceof Tree) |
{ |
Tree nouvelArbre = (Tree)nouvelleDonnees ; |
// on prend sa racine et on l'attache à l'arbre des mots clés |
getArbreMotsCles().getRootNode().appendChild(nouvelArbre.getRootNode()) ; |
getArbreMotsCles().expandAll() ; |
// si l'arbre n'était pas encore considéré comme instancié |
if(!estInstancie) |
{ |
// on signale que oui |
estInstancie = true ; |
} |
// s'il y a des mots clés en attente (lors du premier rendering) |
if(motsCleInitialises == false && motsClesEnAttente != null) |
{ |
// on les coche |
// TODO: corriger le bug qui fait que ça ne marche pas la premiere fois !!!! |
cocherMotsCles(motsClesEnAttente) ; |
motsCleInitialises = true ; |
} |
} |
// Si on reçoit un tableau de String (cas ou l'on séléectionne une nouvelle image) |
if(nouvelleDonnees instanceof String[]) |
{ |
// et que l'arbre est instancié |
if(estInstancie && nouvelleDonnees != null) |
{ |
// le tableau de String contient les id des mots clés associés à l'image |
// on coche les mots clés contenu dans le tableau |
String[] motsClesIds = (String[])nouvelleDonnees ; |
cocherMotsCles(motsClesIds) ; |
} |
// si l'arbre n'est pas encore instancié on met les mots clés en attente |
else |
{ |
motsClesEnAttente = (String[])nouvelleDonnees ; |
/trunk/src/org/tela_botanica/client/vues/MenuImageVue.java |
---|
1,23 → 1,45 |
package org.tela_botanica.client.vues; |
import org.tela_botanica.client.image.ImageMediateur; |
import com.google.gwt.user.client.ui.MenuItem; |
import com.gwtext.client.core.EventObject; |
import com.gwtext.client.widgets.Toolbar; |
import com.gwtext.client.widgets.menu.BaseItem; |
import com.gwtext.client.widgets.menu.Item; |
import com.gwtext.client.widgets.menu.Menu; |
import com.gwtext.client.widgets.menu.event.MenuListener; |
import com.gwtext.client.widgets.menu.event.MenuListenerAdapter; |
/** |
* Menu de gestion des images |
* @author aurelien |
* |
*/ |
public class MenuImageVue extends Menu { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur ; |
/** |
* Item pour l'upload |
*/ |
private Item uploaderImage = null ; |
/** |
* Item pour la suppression |
*/ |
private Item supprimerImage = null ; |
/** |
* Constructeur sans argument (privé car ne doit être utilisé) |
*/ |
private MenuImageVue() |
{ |
super(); |
} |
/** |
* Constructeur avec paramètre |
* @param im le médiateur à associer |
*/ |
public MenuImageVue(ImageMediateur im) |
{ |
super() ; |
24,54 → 46,41 |
iMediateur = im ; |
// on construit le menu |
uploaderImage = new Item("Uploader des images") ; |
supprimerImage = new Item("Supprimer les images selectionnées") ; |
addItem(uploaderImage); |
addItem(supprimerImage) ; |
// on ajoute les listeners |
ajouterListeners() ; |
} |
public void ajouterListeners() |
/** |
* Ajoute les listeners pour la gestions des évènements |
*/ |
private void ajouterListeners() |
{ |
this.addListener(new MenuListener() { |
this.addListener(new MenuListenerAdapter() { |
public void doBeforeHide(Menu menu) { |
// TODO Auto-generated method stub |
} |
public void doBeforeShow(Menu menu) { |
} |
public void onClick(Menu menu, String menuItemId, EventObject e) { |
// TODO Auto-generated method stub |
} |
public void onHide(Menu menu) { |
// TODO Auto-generated method stub |
} |
// gestion du clic sur un item |
public void onItemClick(BaseItem item, EventObject e) { |
// si c'est l'upload |
if(item.equals(uploaderImage)) |
{ |
// on notifie le médiateur |
getIMediateur().uploaderImages() ; |
// et on cache le menu |
hide() ; |
} |
// si c'est la suppression |
if(item.equals(supprimerImage)) |
{ |
// on notifie le médiateur |
getIMediateur().supprimerImages() ; |
// et on chache le menu |
hide() ; |
} |
78,28 → 87,13 |
} |
public void onMouseOut(Menu menu, BaseItem menuItem, EventObject e) { |
// TODO Auto-generated method stub |
} |
public void onMouseOver(Menu menu, BaseItem menuItem, EventObject e) { |
// TODO Auto-generated method stub |
} |
public void onShow(Menu menu) { |
} |
}) ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() |
{ |
return iMediateur ; |
/trunk/src/org/tela_botanica/client/vues/ZoomImageVue.java |
---|
5,41 → 5,121 |
import org.tela_botanica.client.interfaces.Rafraichissable; |
import com.google.gwt.core.client.JavaScriptObject; |
import com.google.gwt.user.client.DOM; |
import com.google.gwt.user.client.Event; |
import com.google.gwt.user.client.Window; |
import com.google.gwt.user.client.ui.ClickListener; |
import com.google.gwt.user.client.ui.Image; |
import com.google.gwt.user.client.ui.LoadListener; |
import com.google.gwt.user.client.ui.MouseWheelListener; |
import com.google.gwt.user.client.ui.MouseWheelVelocity; |
import com.google.gwt.user.client.ui.Widget; |
import com.gwtext.client.core.RegionPosition; |
import com.gwtext.client.widgets.BoxComponent; |
import com.gwtext.client.widgets.Button; |
import com.gwtext.client.widgets.Component; |
import com.gwtext.client.widgets.Container; |
import com.gwtext.client.widgets.Panel; |
import com.gwtext.client.widgets.event.ContainerListenerAdapter; |
import com.gwtext.client.widgets.event.PanelListener; |
import com.gwtext.client.widgets.event.PanelListenerAdapter; |
import com.gwtext.client.widgets.layout.BorderLayout; |
import com.gwtext.client.widgets.layout.BorderLayoutData; |
import com.gwtext.client.widgets.layout.FitLayout; |
import com.gwtext.client.widgets.layout.VerticalLayout; |
/** |
* Panneau d'affichage d'une image avec des boutons précdents et suivant |
* TODO: assurer le redimensionnement automatique de l'image et la centrer |
* @author aurelien |
* |
*/ |
public class ZoomImageVue extends Panel implements Rafraichissable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur iMediateur = null ; |
private Image image = null ; |
/** |
* Panneau conteneur pour l'image |
*/ |
private Panel imageConteneur = null ; |
/** |
* l'image à afficher |
*/ |
private Image image = new Image("vide.jpg") ; |
/** |
* Bouton précédent |
*/ |
private final com.google.gwt.user.client.ui.Button prev = new com.google.gwt.user.client.ui.Button("<"); |
/** |
* Bouton suivant |
*/ |
private final com.google.gwt.user.client.ui.Button suiv = new com.google.gwt.user.client.ui.Button(">"); |
/** |
* Taille originale Y de l'image |
*/ |
private int imageHeight = 0 ; |
/** |
* Taille originale X de l'image |
*/ |
private int imageWidth = 0 ; |
/** |
* Booleen d'initalisation général |
*/ |
private boolean initialise = false ; |
/** |
* Booleen d'initalisation du conteneur d'image |
*/ |
private boolean conteneurInitialise = false ; |
/** |
* Constructeur sans argument (privé car ne doit être utilisé) |
*/ |
private ZoomImageVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec argument |
* @param im le médiateur à associer à la vue |
*/ |
public ZoomImageVue(ImageMediateur im) |
{ |
super("Zoom"); |
// on associe le médiateur |
iMediateur = im ; |
iMediateur = im ; |
// on crée un image qui gère le double clic |
image = new Image() { |
public void onBrowserEvent(Event event) { |
// lors du double clic |
if (Event.ONDBLCLICK == DOM.eventGetType(event)) { |
// on notifie le médiateur |
getIMediateur().doubleClicZoomImage(); |
} |
} |
}; |
imageConteneur = new Panel() ; |
imageConteneur.add(image) ; |
imageConteneur.setId("x-view-zoom-img") ; |
// il n'existe pas de méthode pour ajouter un listener pour le double clic sur une image |
// alors on lui dit manuellement de capter l'évènement double clic |
image.sinkEvents(Event.ONDBLCLICK); |
// l'image de base est vide |
image.setUrl("vide.jpg"); |
this.setLayout(new BorderLayout()); |
48,32 → 128,58 |
suiv.setWidth("60px"); |
this.add(prev,new BorderLayoutData(RegionPosition.WEST)); |
this.add(image,new BorderLayoutData(RegionPosition.CENTER)); |
this.add(imageConteneur,new BorderLayoutData(RegionPosition.CENTER)); |
this.add(suiv,new BorderLayoutData(RegionPosition.EAST)); |
ajouterListenersBoutons(); |
// on ajoute les listeners |
ajouterListeners(); |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
* @param nouvelleDonnees les nouvelles données |
* @param repandreRafraichissement le booleen qui dit si on doit répnadre l'évènement |
*/ |
public void rafraichir(Object nouvelleDonnees, boolean repandreRafraichissement) { |
if(nouvelleDonnees instanceof String) |
// si on reçoit une string |
if(nouvelleDonnees instanceof String[]) |
{ |
getImage().setUrl((String)nouvelleDonnees); |
String[] infos = (String[])nouvelleDonnees ; |
// c'est l'url de l'image qu'on associe à la vue |
getImage().setUrl(infos[0]); |
if(infos[1] != null && infos[2] != null) |
{ |
int x = Integer.parseInt(infos[1]) ; |
int y = Integer.parseInt(infos[2]) ; |
setTailleImage(x,y) ; |
verifierEtRetaillerImage() ; |
} |
} |
else |
{ |
getImage().setUrl("/images/vide.jpeg") ; |
// sinon on met une image vide |
getImage().setUrl("vide.jpeg") ; |
} |
} |
/** |
* Desactive visuellement le panneau et les boutons |
*/ |
public void desactiverPanneau() |
{ |
getImage().setUrl("/images/vide.jpeg") ; |
getImage().setUrl("vide.jpeg") ; |
prev.setEnabled(false) ; |
suiv.setEnabled(false); |
} |
/** |
* Active visuellement le panneau et les boutons |
*/ |
public void activerPanneau() |
{ |
prev.setEnabled(true); |
80,47 → 186,173 |
suiv.setEnabled(true); |
} |
public void ajouterListenersBoutons() |
/** |
* Ajoute les listeners pour la gestions d'évènement |
*/ |
public void ajouterListeners() |
{ |
// gestion du clic sur le bouton précedent |
prev.addClickListener(new ClickListener() { |
// en cas de clic |
public void onClick(Widget sender) { |
// on notifie le médiateur |
getIMediateur().clicBoutonZoomImage("prev"); |
} |
}); |
// gestion du clic sur le bouton suivant |
suiv.addClickListener(new ClickListener() { |
// en cas de clic |
public void onClick(Widget sender) { |
// on notifie le médiateur |
getIMediateur().clicBoutonZoomImage("suiv"); |
} |
}); |
getIMediateur().clicBoutonZoomImage("suiv"); |
// gestion du redimensionnement |
this.addListener(new PanelListenerAdapter() { |
// lors d'un redimensionnement de l'application |
public void onBodyResize(Panel panel,java.lang.String width,java.lang.String height) |
{ |
// on vérifie et on retaille l'image |
verifierEtRetaillerImage() ; |
} |
}) ; |
// gestion du redimensionnement lors de l'affichage du conteneur |
imageConteneur.addListener(new PanelListenerAdapter() { |
// avant de finir d'afficher |
public void onAfterLayout(Container self) |
{ |
// on redimensionne |
verifierEtRetaillerImage() ; |
} |
}); |
} |
/** |
* Verifie si l'image est plus grande que le conteneur et la retaille le cas echeant |
*/ |
public void verifierEtRetaillerImage() |
{ |
// si l'image est nulle |
if(image == null) |
{ |
// on ne fait rien |
return ; |
} |
// on prend la taille originale de l'image |
int originalX = getTailleImage()[0] ; |
int originalY = getTailleImage()[1] ; |
// on la transforme en float (la division entre entier donne de curieux résultats) |
float fOriginalX = (new Float(originalX)).floatValue() ; |
float fOriginalY = (new Float(originalY)).floatValue() ; |
// et on fait le rapport longueur sur hauteur (pour connaitre le ratio) |
float rapportTaille = fOriginalX/fOriginalY ; |
// la nouvelle taille est pour le moment égale à l'ancienne |
int nouvelleTailleX = originalX ; |
int nouvelleTailleY = originalY ; |
// on prend la taille du conteneur |
int tailleConteneurX = imageConteneur.getWidth() ; |
int tailleConteneurY = imageConteneur.getHeight() ; |
// si celle-ci est égale à 0 (conteneur mal initialisé) |
if(imageConteneur.getHeight() == 0 && tailleConteneurX == 0) |
{ |
// on essaie de la calculer en fonction de la taille du parent et des frères |
tailleConteneurY = this.getHeight() ; |
tailleConteneurX = this.getWidth() - prev.getOffsetWidth() * 2 ; |
nouvelleTailleX = originalX ; |
nouvelleTailleY = originalY ; |
} |
// si l'image ne rentre pas telle quelle (longueur ou hauteur trop grande) |
if(originalY > tailleConteneurY || originalX > tailleConteneurX) |
{ |
// si la longueur de l'image est la plus grande des deux |
if(originalX > originalY) |
{ |
// on prend la longueur comme taille de référence, qu'on met à la longueur du conteneur |
nouvelleTailleX = tailleConteneurX ; |
// et on recalcule la hauteur, par rapport à la nouvelle longueur, en gardant le format de 'limage |
nouvelleTailleY = (int)Math.floor(nouvelleTailleX*1/rapportTaille) ; |
} |
else |
{ |
// si la hauteur est la plus grande, on fait le même genre d'opération en prenant la hauteur comme référence |
nouvelleTailleY = tailleConteneurY ; |
nouvelleTailleX = (int)Math.floor(nouvelleTailleY*rapportTaille) ; |
} |
} |
// on modifie enfin la taille de l'image pour qu'elle soit affichée |
getImage().setSize(""+nouvelleTailleX+"px", ""+nouvelleTailleY+"px") ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() { |
return iMediateur; |
} |
/** |
* Accesseur au conteneur de l'image |
* @return le conteneur de l'image |
*/ |
public Image getImage() { |
return image; |
} |
/** |
* Accesseur pour le bouton précédent |
* @return le bouton précédent |
*/ |
public com.google.gwt.user.client.ui.Button getPrev() { |
return prev; |
} |
/** |
* Accesseur pour le bouton suivant |
* @return le bouton suivant |
*/ |
public com.google.gwt.user.client.ui.Button getSuiv() { |
return suiv; |
} |
/** |
* Setter pour la taille de l'image |
* @param X la largeur en pixels |
* @param Y la hauteur en pixels |
*/ |
public void setTailleImage(int x, int y) |
{ |
imageHeight = y ; |
imageWidth = x ; |
} |
/** |
* renvoie la taille originale de l'image |
* @return un tableau de deux entiers contenant la largeur puis la hauteur |
*/ |
public int[] getTailleImage() |
{ |
int[] taille = {imageHeight,imageWidth} ; |
return taille ; |
} |
} |
/trunk/src/org/tela_botanica/client/vues/PanneauMetadonneesVue.java |
---|
28,6 → 28,7 |
import com.gwtext.client.widgets.grid.GridView; |
import com.gwtext.client.widgets.grid.PropertyGridPanel; |
import com.gwtext.client.widgets.grid.event.GridCellListener; |
import com.gwtext.client.widgets.grid.event.GridCellListenerAdapter; |
import com.gwtext.client.widgets.layout.RowLayout; |
import com.gwtext.client.widgets.layout.RowLayoutData; |
import com.gwtext.client.widgets.layout.VerticalLayout; |
36,33 → 37,89 |
import com.gwtext.client.widgets.tree.TreeNode; |
import com.gwtext.client.widgets.tree.TreePanel; |
/** |
* Panneau contenant les infos, les métadonnées et l'arbre des mots clés, il implémente l'interface rafraichissable |
* @author aurelien |
* |
*/ |
public class PanneauMetadonneesVue extends TabPanel implements Rafraichissable { |
/** |
* Le médiateur associé à la vue |
*/ |
private ImageMediateur imediateur = null ; |
/** |
* Le panneau des Exifs |
*/ |
private PropertyGridPanel ExifGrid = null ; |
/** |
* Le panneau des Iptc |
*/ |
private PropertyGridPanel IptcGrid = null ; |
/** |
* La grille pour le panneau des Exifs |
*/ |
private GridView gViewExif = null ; |
/** |
* La grille pour le panneau de Iptc |
*/ |
private GridView gViewIptc = null ; |
/** |
* L'onglet des Exifs |
*/ |
private Panel panneauExifGrid = null; |
/** |
* L'onglet des Iptc |
*/ |
private Panel panneauIptcGrid = null ; |
/** |
* L'onglet des infos |
*/ |
private Panel panneauInfoGrid = null ; |
/** |
* L'onglet des mots clés |
*/ |
private ArbreMotsClesVue panneauMotsCles = null ; |
/** |
* Le champ commentaire |
*/ |
private TextField commentaireGeneral = null ; |
/** |
* Le champ date |
*/ |
private DateField dateImage = null ; |
/** |
* Le bouton de validation |
*/ |
Button validerInfo = null ; |
/** |
* Booleen d'instanciation |
*/ |
boolean estInstancie = false ; |
/** |
* Constructeur sans argument (privé car ne doit pas être utilisé) |
*/ |
private PanneauMetadonneesVue() |
{ |
super() ; |
} |
/** |
* Constructeur avec argument |
* @param im |
*/ |
public PanneauMetadonneesVue(ImageMediateur im) |
{ |
super() ; |
// on associe le médiateur |
imediateur = im ; |
// on crée et dispose les panneaux et les champs |
panneauExifGrid = new Panel("Exif") ; |
panneauIptcGrid = new Panel("Iptc") ; |
panneauInfoGrid = new Panel("info") ; |
70,6 → 127,8 |
panneauInfoGrid.setLayout(new VerticalLayout()); |
panneauInfoGrid.setHeight(500); |
panneauInfoGrid.setMargins(5) ; |
panneauInfoGrid.setPaddings(5) ; |
Label labelComm = new Label("Commentaires :") ; |
labelComm.setHeight("20px") ; |
commentaireGeneral = new TextArea() ; |
83,15 → 142,7 |
dateImage.setFormat("d/m/y") ; |
validerInfo = new Button("OK") ; |
validerInfo.addListener(new ButtonListenerAdapter() { |
public void onClick(Button button, EventObject e) { |
getIMediateur().mettreAJourInfo(commentaireGeneral.getText(), dateImage.getRawValue()) ; |
} |
}); |
panneauInfoGrid.add(labelComm) ; |
panneauInfoGrid.add(commentaireGeneral) ; |
panneauInfoGrid.add(labelDate) ; |
115,25 → 166,64 |
ExifGrid.setAutoWidth(true); |
ExifGrid.setAutoHeight(true); |
ExifGrid.setSorted(false); |
ExifGrid.addGridCellListener(new GridCellListener() { |
gViewIptc = new GridView(); |
gViewIptc.setForceFit(true); |
IptcGrid = new PropertyGridPanel() ; |
IptcGrid.setId("meta_iptc"); |
IptcGrid.setView(gViewIptc); |
IptcGrid.setNameText("Métadonnées IPTC"); |
IptcGrid.setAutoWidth(true); |
IptcGrid.setAutoHeight(true); |
IptcGrid.setSorted(false); |
panneauExifGrid.add(ExifGrid); |
panneauIptcGrid.add(IptcGrid); |
// on ajoute les listeners |
ajouterListeners() ; |
// on effectue le rendu |
this.doLayout(true) ; |
} |
private void ajouterListeners() |
{ |
// on ajoute un écouteur |
validerInfo.addListener(new ButtonListenerAdapter() { |
// gestion du clic |
public void onClick(Button button, EventObject e) { |
// lors du clic sur le bouton valider on met à jour les commentaires et la date |
getIMediateur().mettreAJourInfo(commentaireGeneral.getText(), dateImage.getRawValue()) ; |
} |
}); |
// gestion des clics dans la grille |
ExifGrid.addGridCellListener(new GridCellListenerAdapter() { |
// lors d'un clic d'une cellule |
public void onCellClick(GridPanel grid, int rowIndex, int colIndex, |
EventObject e) { |
// on empeche l'édition |
e.stopEvent() ; |
ExifGrid.stopEditing() ; |
} |
public void onCellContextMenu(GridPanel grid, int rowIndex, |
int cellIndex, EventObject e) { |
// TODO Auto-generated method stub |
} |
// lors du double clic sur une cellule |
public void onCellDblClick(GridPanel grid, int rowIndex, |
int colIndex, EventObject e) { |
// on empêche l'édition |
e.stopEvent() ; |
ExifGrid.stopEditing() ; |
141,36 → 231,21 |
}) ; |
gViewIptc = new GridView(); |
gViewIptc.setForceFit(true); |
IptcGrid.addGridCellListener(new GridCellListenerAdapter() { |
IptcGrid = new PropertyGridPanel() ; |
IptcGrid.setId("meta_iptc"); |
IptcGrid.setView(gViewIptc); |
IptcGrid.setNameText("Métadonnées IPTC"); |
IptcGrid.setAutoWidth(true); |
IptcGrid.setAutoHeight(true); |
IptcGrid.setSorted(false); |
IptcGrid.addGridCellListener(new GridCellListener() { |
// lors d'un clic d'une cellule |
public void onCellClick(GridPanel grid, int rowIndex, int colIndex, |
EventObject e) { |
// on empeche l'édition |
e.stopEvent() ; |
ExifGrid.stopEditing() ; |
} |
public void onCellContextMenu(GridPanel grid, int rowIndex, |
int cellIndex, EventObject e) { |
// TODO Auto-generated method stub |
} |
// lors d'un double clic d'une cellule |
public void onCellDblClick(GridPanel grid, int rowIndex, |
int colIndex, EventObject e) { |
// on empeche l'édition |
e.stopEvent() ; |
ExifGrid.stopEditing() ; |
177,34 → 252,44 |
} |
}) ; |
panneauExifGrid.add(ExifGrid); |
panneauIptcGrid.add(IptcGrid); |
this.doLayout(true) ; |
} |
/** |
* Desactive visuellement ce panneau |
*/ |
public void desactiverPanneau() |
{ |
this.setDisabled(true) ; |
} |
/** |
* Active visuellement ce panneau |
*/ |
public void activerPanneau() |
{ |
this.setDisabled(false) ; |
} |
/** |
* Accesseur pour le médiateur |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() |
{ |
return imediateur ; |
} |
/** |
* Méthode héritée de l'interface rafraichissable |
* @param nouvelleDonnees les nouvelles données |
* @param repandreRafraichissement le booleen de notification de mise à jour |
*/ |
public void rafraichir(Object nouvelleDonnees, boolean repandreRafraichissement) { |
// si on reçoit un tableau d'objets |
if(nouvelleDonnees instanceof Object[]) |
{ |
// extrait infos, exifs et iptc |
Object meta[] = (Object[])nouvelleDonnees ; |
String[][] exif = (String[][])meta[0] ; |
String[][] iptc = (String[][])meta[1] ; |
241,6 → 326,7 |
dateImage.setValue(gen[1][1]) ; |
// et on met à jour les données pour l'affichage |
ExifGrid.setSource(exifSource); |
IptcGrid.setSource(iptcSource); |
248,6 → 334,7 |
} |
/** |
* Accesseur pour le panneau des mots clés |
* @return the panneauMotsCles |
*/ |
public ArbreMotsClesVue getPanneauMotsCles() { |
/trunk/src/org/tela_botanica/client/vues/BarreOutilsVue.java |
---|
21,8 → 21,17 |
*/ |
public class BarreOutilsVue extends Toolbar { |
/** |
* Un bouton qui sert à déployer le menu |
*/ |
ToolbarMenuButton images = null ; |
/** |
* Le médiateur associé à la toolbar |
*/ |
ImageMediateur iMediateur = null ; |
/** |
* Le menu de gestion des images |
*/ |
MenuImageVue imageMenu = null ; |
/** |
/trunk/src/org/tela_botanica/client/vues/GalerieImageVue.java |
---|
177,7 → 177,7 |
/** |
* Accesseur pour le médiateur |
* @return le mdéiateur associé à la vue |
* @return le médiateur associé à la vue |
*/ |
public ImageMediateur getIMediateur() { |
return iMediateur; |
185,7 → 185,7 |
/** |
* Accesseur pour le store |
* @return le store associée à la vue |
* @return le store associé à la vue |
*/ |
public Store getSt() { |
return st; |
205,7 → 205,6 |
*/ |
public void initialiser() { |
// Preparation de la dataview et du template |
// le template va créer une div contenant une image |
// pour chacune des photos |
284,20 → 283,23 |
} |
// si le com)posant doit répandre le rafraichissement |
// si le composant doit répandre le rafraichissement |
if (repandreRafraichissement) { |
// il en notifie le médiateur en lui donnant une copie des données |
// il en notifie le médiateur en lui donnant une copie des données et en notifiant qu'il en est l'expéditeur |
getIMediateur().synchroniserDonneesZoomListeGalerie( |
nouvelleDonnees, this); |
} |
// si c'est la première mise à jour que l'on reçoit |
if(!estInstancie) |
{ |
// alors le composant est considéré comme instancié |
estInstancie = true ; |
} |
} |
/** |
* Méthode héritée de l'interface VueListable |
* Sélectionne les images dans la galerie suivant les identifiants donnés en paramètres |
* @param ids les identifiants des images à sélectionner |
*/ |