mercoledì 27 febbraio 2008

Image Tooltip

Ho finalmente finito, più o meno, il primo applicativo "reale" con gwt.
Come anticipato ho creato un modulo gwt che per ogni immagine in una pagina web (con una determinata classe) crei un "tooltip" con l'immagine a grandezza "naturale" che compaia quando si passa con il mouse sopra l'immagine stessa.
In pratica il modulo parserizza tutta la pagina per cercare immagini con la data classe. Per ognuna di queste immagini crea un widget (una window di gwt-ext) con la stessa grandezza dell'immagine, contenente l'immagine stessa. A questo widgets viene aggiuntpo un ascoltatore per il mouse, e in caso di mouse hover si attiva (con una simpatica animazione fornita da gwt-ext), attiva una nuova window che carica la versione ad alta risoluzione dell'immagine (sul server ci devono essere quindi due immagini, l'immagine originale e una miniatura con lo stesso nome + "_th").
Funziona tutto ok... meno bene la gestione del ridimensionamento della finestra del browser... i widgets della miniatura si spostano correttamente, le dimensioni del tooltip vengono correttamente calcolate (perchè in base al viewport del browser riduco la grandezza dell'immagine originale), ma la posizione e la grandezza del gagtes "tooltip" contenitore fanno un po' quello che vogliono... ma solo in caso di ridimensionamento.

Ora comunque, visto che riesco a creare qualcosina, anche se semplice, con gwt e gwt-ext, sposto l'attenzione su XSTM



codice per IMGTOOLTIP, Versione.... diciamo 0.5



package mie.prove.client;

import java.util.ArrayList;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.WindowResizeListener;
import com.gwtext.client.widgets.layout.FitLayout;
import com.gwtext.client.widgets.Component;

public class GwtImageTooltip implements EntryPoint {

ArrayList immagineTHWList = new ArrayList();
ArrayList imgList = new ArrayList();
ArrayList TTwindowList = new ArrayList();
ArrayList immagineToolTipList = new ArrayList();
ArrayList misureOriginaliImmaginiTT = new ArrayList();
int viewportW, viewportH;

public void onModuleLoad() {
viewportW = Window.getClientWidth();
viewportH = Window.getClientHeight();
com.google.gwt.core.client.GWT.log("il viewport ha altezza" + viewportH + " e larghezza " + viewportW,null);

Element elemento = DOM.getElementById("contenuto");
imgList = getElementsByClass(elemento, "img_tooltip");
int numImg = imgList.size();
for (int i=0; i < numImg; i++){
com.google.gwt.core.client.GWT.log("processo il tooltip numero"+i,null);

String urlImmagineTH = DOM.getElementProperty((Element)imgList.get(i), "src");
String altImmagineTH = DOM.getElementProperty((Element)imgList.get(i), "alt");

int imgY = DOM.getAbsoluteTop((Element)imgList.get(i));
int imgX = DOM.getAbsoluteLeft((Element)imgList.get(i));
int[] posizioneImmagine = {imgX,imgY};
com.google.gwt.core.client.GWT.log("l'immagine"+i+" si trova in posizione "+imgX+" "+imgY,null);

Image immagineTH = new Image(urlImmagineTH);

final com.gwtext.client.widgets.Window immagineTHWindow = new com.gwtext.client.widgets.Window();
/*
//per farlo diventare esattamente come un immagine
immagineTHWindow.setFrame(false);
immagineTHWindow.setHeader(false);
immagineTHWindow.setHeaderAsText(false);
//fine per farlo diventare esattamente come un immagine
*/
immagineTHWindow.setLayout(new FitLayout());
immagineTHWindow.add(immagineTH);
//immagineTHWindow.anchorTo((Element)imgList.get(i), position, offsetXY)
immagineTHWindow.setModal(false);
immagineTHWindow.setPixelSize(immagineTH.getWidth(),immagineTH.getHeight());
immagineTHWindow.setDraggable(false);
immagineTHWindow.setClosable(false);
immagineTHWindow.setResizable(false);
immagineTHWindow.setFooter(true);
immagineTHWindow.setTitle(altImmagineTH);
immagineTHWindow.setPosition(imgX,imgY);
immagineTHWindow.show();

//aggiungo la window immagineTHWindow alla lista immagineTHWList
immagineTHWList.add(immagineTHWindow);

String urlTT = urlImmagineTH.replaceAll("_th", "");
Image immagineToolTip = new Image(urlTT);
immagineToolTip.setVisible(false);
immagineToolTipList.add(immagineToolTip);
int[] misureOriginali = {immagineToolTip.getWidth(),immagineToolTip.getHeight()};
misureOriginaliImmaginiTT.add(misureOriginali);

int [] misureTTwindow = calcolaMisuraTTwindow(posizioneImmagine,immagineToolTip);
int immagineTTW = misureTTwindow[0];
int immagineTTH = misureTTwindow[1];

immagineToolTip.setPixelSize(immagineTTW, immagineTTH);

final com.gwtext.client.widgets.Window TTwindow = new com.gwtext.client.widgets.Window();
TTwindow.setLayout(new FitLayout());
TTwindow.add(immagineToolTip);
TTwindow.setTitle(altImmagineTH);
TTwindow.setModal(false);
TTwindow.setDraggable(false);
TTwindow.setClosable(false);
TTwindow.setResizable(false);
TTwindow.setFooter(true);
TTwindow.setAnimateTarget((Element)imgList.get(i));
TTwindow.setPixelSize(immagineTTW, immagineTTH);

posizionaTTwindow(TTwindow, posizioneImmagine);

//aggiungo la window TTwindow alla lista TTwindowList
TTwindowList.add(TTwindow);

//agiungo ascoltatore eventi all'immagine per aprire tooltip
immagineTH.addMouseListener(new MouseListenerAdapter() {
public void onMouseEnter(Widget sender) {
TTwindow.show();
Component immagineToolTip = TTwindow.getComponent(0);
immagineToolTip.setVisible(true);
}
});

//agiungo ascoltatore eventi mouse al tooltip per chiuderlo
immagineToolTip.addMouseListener(new MouseListenerAdapter() {
public void onMouseLeave(Widget sender) {
TTwindow.hide();
}
});
}

//aggiungo l'ascoltatore alla finestra per spostare le immagini in caso di resize
Window.addWindowResizeListener(new WindowResizeListener(){
public void onWindowResized(int x, int y){
aggiornaPosizioneimmaginiTHWindow(immagineTHWList);
viewportW = Window.getClientWidth();
viewportH = Window.getClientHeight();
aggiornaMisureTTwindow(TTwindowList,imgList,immagineToolTipList);
aggiornaPosizioniTTwindows(TTwindowList,imgList);
}
});
}

public void aggiornaMisureTTwindow(ArrayList TTwindowList, ArrayList imgList, ArrayList immagineToolTipList){
int numImg = TTwindowList.size();
int [] posizioneImmagine = new int[2];
for (int i=0; i < numImg; i++){
com.gwtext.client.widgets.Window TTwindow = (com.gwtext.client.widgets.Window)TTwindowList.get(i);
try{
int imgY = DOM.getAbsoluteTop((Element)imgList.get(i));
int imgX = DOM.getAbsoluteLeft((Element)imgList.get(i));
posizioneImmagine[0] = imgX;
posizioneImmagine[1] = imgY;
}
catch(IndexOutOfBoundsException e){
System.err.print("IndexOutOfBoundsException: ");
System.err.println(e.getMessage());
com.google.gwt.core.client.GWT.log("IndexOutOfBoundsException: ",null);
com.google.gwt.core.client.GWT.log(e.getMessage(),null);
}
Image immagineToolTip = (Image)immagineToolTipList.get(i);
int[] misureOriginali = (int[])misureOriginaliImmaginiTT.get(i);
immagineToolTip.setPixelSize(misureOriginali[0], misureOriginali[1]);
int [] misureTTwindow = calcolaMisuraTTwindow(posizioneImmagine,immagineToolTip);
int immagineTTW = misureTTwindow[0];
int immagineTTH = misureTTwindow[1];
com.google.gwt.core.client.GWT.log("misure ricalcolate: imgx="+immagineTTW+" imgy="+immagineTTH,null);
immagineToolTip.setPixelSize(immagineTTW, immagineTTH);
TTwindow.setPixelSize(immagineTTW, immagineTTH);
}
}

public int[] calcolaMisuraTTwindow(int[] posizioneImmagine, Image immagineToolTip){
float resize = 1; //% di resize in caso l'immagine sia troppo grande
int immagineTTH = immagineToolTip.getHeight();
int immagineTTW = immagineToolTip.getWidth();
String url = immagineToolTip.getUrl();

com.google.gwt.core.client.GWT.log("L'immagine tooltip ha altezza" + immagineTTH + " e larghezza " + immagineTTW + " e url = " +url,null);

//se l'immagine è più grande del viewport, devo scalarla e posizionarla centrata
if ((immagineTTW > viewportW-10) || (immagineTTH > viewportH-10)){
if (immagineTTW > viewportW-10){
resize = (float)immagineTTW / ((float)viewportW-10);
}
else {
resize = (float)immagineTTH/((float)viewportH-10);
}
float temp = (immagineTTW/resize);
immagineTTW = Math.round(temp);
temp = (immagineTTH/resize);
immagineTTH = Math.round(temp);
}
int [] misureTTwindow = {immagineTTW,immagineTTH};
return misureTTwindow;
}

public void aggiornaPosizioniTTwindows(ArrayList TTwindowList, ArrayList imgList){
int numImg = TTwindowList.size();
for (int i=0; i < numImg; i++){
com.gwtext.client.widgets.Window TTwindow = (com.gwtext.client.widgets.Window)TTwindowList.get(i);
int imgY = DOM.getAbsoluteTop((Element)imgList.get(i));
int imgX = DOM.getAbsoluteLeft((Element)imgList.get(i));
int [] posizioneImmagine = {imgX,imgY};
posizionaTTwindow(TTwindow,posizioneImmagine);
Component immagineToolTip = TTwindow.getComponent(0);
immagineToolTip.setVisible(false);
}
}

public void posizionaTTwindow(com.gwtext.client.widgets.Window TTwindow, int[] posizioneImmagine){
int posTTX = posizioneImmagine[0]; //posizione X del tooltip
int posTTY = posizioneImmagine[1]; //posizione Y del tooltip
int spostTTX = 0; //spostamento del tooltip nel caso l'immagine sia larga
int ttwindowWidth = TTwindow.getWidth(); //larghezza tooltip
//se l'immagine TT è troppo larga per stare nella posizione dell'immagine TH, la sposto a sinistra
if (posTTX + ttwindowWidth > viewportW-5){
spostTTX = posTTX + ttwindowWidth - (viewportW-5);
}
TTwindow.setPagePosition(posTTX-spostTTX,posTTY);
}

//imgList e immagineTHWList hanno gli stessi indici
public void aggiornaPosizioneimmaginiTHWindow(ArrayList immagineTHWList){
int numImg = immagineTHWList.size();
for (int i=0; i < numImg; i++){
int imgY = DOM.getAbsoluteTop((Element)imgList.get(i));
int imgX = DOM.getAbsoluteLeft((Element)imgList.get(i));
com.gwtext.client.widgets.Window currentWindow = (com.gwtext.client.widgets.Window)immagineTHWList.get(i);
currentWindow.setPosition(imgX,imgY);
}
}

private ArrayList getElementsByClass(Element parent, String className){
ArrayList list = new ArrayList();
Element current = DOM.getFirstChild(parent);
String classe = null;

while(current != null){
classe = DOM.getElementProperty(current, "className");
if (classe!=null){
if(classe.equals(className)){
com.google.gwt.core.client.GWT.log("trovato un img_tooltip",null);
list.add(current);
}
}
current = DOM.getNextSibling(current);
}
return list;
}
}


Nessun commento: