package org.gcube.portlets.widgets.imagepreviewerwidget.client.ui; import java.util.ArrayList; import java.util.List; import org.gcube.portlets.widgets.imagepreviewerwidget.client.CarouselInterface; import org.gcube.portlets.widgets.imagepreviewerwidget.client.EnhancedImage; import org.gcube.portlets.widgets.imagepreviewerwidget.client.ImageService; import org.gcube.portlets.widgets.imagepreviewerwidget.client.ImageServiceAsync; import org.gcube.portlets.widgets.imagepreviewerwidget.client.resources.Resources; import org.gcube.portlets.widgets.imagepreviewerwidget.shared.Orientation; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.Image; import com.github.gwtbootstrap.client.ui.Modal; import com.github.gwtbootstrap.client.ui.constants.Device; import com.github.gwtbootstrap.client.ui.constants.IconSize; import com.github.gwtbootstrap.client.ui.constants.IconType; import com.github.gwtbootstrap.client.ui.resources.ButtonSize; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.NodeList; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; /** * A carousel for image/file previews. * @author Costantino Perciante at ISTI-CNR * (costantino.perciante@isti.cnr.it) * */ public class Carousel extends Composite implements CarouselInterface { private static CarouselUiBinder uiBinder = GWT .create(CarouselUiBinder.class); interface CarouselUiBinder extends UiBinder { } private final ImageServiceAsync imageServices = GWT.create(ImageService.class); @UiField Modal mainModalPanel; @UiField Button prevButton; @UiField Button nextButton; @UiField Button downloadButton; @UiField Button closeButton; @UiField Button downloadButtonSmart; @UiField Button closeButtonSmart; @UiField Image shownImage; @UiField Image loadingImage; @UiField HorizontalPanel commands; // list of enhanced images to show private List listOfAttachmentsToShow; // index of the image shown private int currentPreviewPosition; // other resources private Resources resources = GWT.create(Resources.class); /** * Build a carousel to show EnhancedImages. * @param imagesToShow */ public Carousel() { initWidget(uiBinder.createAndBindUi(this)); listOfAttachmentsToShow = new ArrayList<>(); // add custom styles to gwt-bootstrap-modal (just once) mainModalPanel.addStyleName("modal-custom"); ((Element)mainModalPanel.getElement().getChildNodes().getItem(1)).addClassName("modal-body-custom"); // set vertical alignment commands.setCellVerticalAlignment(nextButton, VerticalPanel.ALIGN_MIDDLE); commands.setCellVerticalAlignment(prevButton, VerticalPanel.ALIGN_MIDDLE); // set alignment of the horizontal panel's children commands.setCellHorizontalAlignment(closeButton, HorizontalPanel.ALIGN_CENTER); commands.setCellHorizontalAlignment(downloadButton, HorizontalPanel.ALIGN_CENTER); commands.setCellHorizontalAlignment(closeButtonSmart, HorizontalPanel.ALIGN_CENTER); commands.setCellHorizontalAlignment(downloadButtonSmart, HorizontalPanel.ALIGN_CENTER); commands.setCellHorizontalAlignment(prevButton, HorizontalPanel.ALIGN_LEFT); commands.setCellHorizontalAlignment(nextButton, HorizontalPanel.ALIGN_RIGHT); // set sizes downloadButton.setWidth("90px"); closeButton.setWidth("90px"); downloadButtonSmart.setWidth("15px"); closeButtonSmart.setWidth("15px"); closeButtonSmart.setSize(ButtonSize.LARGE); // set icons downloadButton.setIcon(IconType.DOWNLOAD_ALT); closeButton.setIcon(IconType.COLLAPSE); downloadButtonSmart.setIcon(IconType.DOWNLOAD_ALT); closeButtonSmart.setIcon(IconType.COLLAPSE); prevButton.setIcon(IconType.CHEVRON_LEFT); prevButton.setSize(ButtonSize.LARGE); nextButton.setIcon(IconType.CHEVRON_RIGHT); nextButton.setSize(ButtonSize.LARGE); // set icons'size prevButton.setIconSize(IconSize.LARGE); nextButton.setIconSize(IconSize.LARGE); // choose devices closeButtonSmart.setShowOn(Device.PHONE); downloadButtonSmart.setShowOn(Device.PHONE); downloadButton.setShowOn(Device.DESKTOP); closeButton.setShowOn(Device.DESKTOP); downloadButton.setHideOn(Device.PHONE); closeButton.setHideOn(Device.PHONE); // add some other css style downloadButton.addStyleName("buttons-style"); closeButton.addStyleName("buttons-style"); downloadButtonSmart.addStyleName("buttons-style"); closeButtonSmart.addStyleName("buttons-style"); //on user click on the image, go on shownImage.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { if(nextButton.isVisible()) nextButton.click(); } }); // set url of the loading image loadingImage.setResource(resources.loadingImage()); } @UiHandler("closeButton") public void hideOnClick(ClickEvent e){ closeButtonClickHanderBody(); } @UiHandler("closeButtonSmart") public void hideOnClickSmart(ClickEvent e){ closeButtonClickHanderBody(); } /** * Close button click handler body */ private void closeButtonClickHanderBody(){ mainModalPanel.hide(); } @UiHandler("downloadButton") /** * When the user pushes this button, try to download the file. * @param e */ public void downloadOnClick(ClickEvent e){ downloadButtonClickHanderBody(); } @UiHandler("downloadButtonSmart") /** * When the user pushes this button, try to download the file. * @param e */ public void downloadOnClickSmart(ClickEvent e){ downloadButtonClickHanderBody(); } /** * Download button click handler body */ public void downloadButtonClickHanderBody(){ String downloadUrl = listOfAttachmentsToShow.get(currentPreviewPosition).getDownloadUrl(); if(downloadUrl != null){ Window.open(downloadUrl, "_blank", ""); } } @Override public void onClickPrev() { // evaluate prev index currentPreviewPosition = currentPreviewPosition == 0 ? listOfAttachmentsToShow.size() - 1 : currentPreviewPosition - 1; // show the image showImage(currentPreviewPosition); } @Override public void onClickNext() { // evaluate next index currentPreviewPosition = currentPreviewPosition == listOfAttachmentsToShow.size() -1 ? 0 : currentPreviewPosition + 1; // show the image showImage(currentPreviewPosition); } @UiHandler("prevButton") /** * Show the previous image, if any. * @param e */ public void onClickPrev(ClickEvent e) { GWT.log("onClickPrev classic"); onClickPrev(); } @UiHandler("nextButton") /** * Show the next image, if any. * @param e */ public void onClickNext(ClickEvent e){ onClickNext(); } /** * Used to show this carousel (starting from the initial image). */ public void show(){ mainModalPanel.show(); // take the first image currentPreviewPosition = 0; // show the image showImage(currentPreviewPosition); } /** * Used to show a specific image of this carousel. */ public void show(EnhancedImage image){ GWT.log("image=" + image.getDownloadUrl()); GWT.log("image=" + image.getThumbnailUrl()); // evaluate where this image is int index = evaluateImagePosition(image); GWT.log("index=" + index); if(index == -1) { listOfAttachmentsToShow.clear(); listOfAttachmentsToShow.add(image); index = 0; showImage(index); } else { // take the first object currentPreviewPosition = index; // show the image showImage(currentPreviewPosition); } // show the panel mainModalPanel.show(); } /** * Retrieve the index of such image. * @param image * @return -1 if no image matches */ private int evaluateImagePosition(EnhancedImage image) { for(int index = 0; index < listOfAttachmentsToShow.size(); index++){ if(listOfAttachmentsToShow.get(index).equals(image)) return index; } return -1; } /** * Change the set of images to show. * @param imagesToShow */ public void updateImages(List imagesToShow){ listOfAttachmentsToShow = imagesToShow; } /** * use showArrows(boolean visible) */ @Deprecated public void hideArrows() { nextButton.setVisible(false); prevButton.setVisible(false); } /** * Hide/Show Previous and Next arrows of the carousel. * @param visible the visibility of the command arrows */ public void showArrows(boolean visible) { nextButton.setVisible(visible); prevButton.setVisible(visible); } /** * Show image function. * @param index the index of the image to show */ private void showImage(int index){ showLoader(); final EnhancedImage imageToShow = listOfAttachmentsToShow.get(index); final String url = imageToShow.getImageUrl(); // when image is downloaded ... shownImage.addLoadHandler(new LoadHandler() { @Override public void onLoad(LoadEvent event) { // call only if undefined if(imageToShow.getOrientation().equals(Orientation.UNDEFINED)){ imageServices.getImageOrientation(url, new AsyncCallback() { @Override public void onSuccess(Orientation result) { imageToShow.setOrientation(result); setOrientation(imageToShow, result); } @Override public void onFailure(Throwable caught) { imageToShow.setOrientation(Orientation.DO_NOT_ROTATE); setOrientation(imageToShow, Orientation.DO_NOT_ROTATE); } }); }else{ setOrientation(imageToShow, imageToShow.getOrientation()); } } }); // fetch the image from the url shownImage.setUrl(url); // change image tooltip shownImage.setTitle(imageToShow.getToolTipToShow()); // change the title to the modal String shownTitle = imageToShow.getTitleToShow().length() > 80 ? imageToShow.getTitleToShow().substring(0, 80) + "..." : imageToShow.getTitleToShow(); mainModalPanel.setTitle(shownTitle); // to set the tooltip we have to lookup the title in the header (it's a

element) NodeList list = mainModalPanel.getElement().getElementsByTagName("h3"); list.getItem(0).setTitle(imageToShow.getTitleToShow()); // change header style ((Element)mainModalPanel.getElement().getChildNodes().getItem(0)).addClassName("modal-header-custom"); } /** * Show image loader */ protected void showLoader() { loadingImage.setVisible(true); shownImage.setVisible(false); } /** * Remove image loader */ protected void removeLoader() { shownImage.setVisible(true); loadingImage.setVisible(false); } /** * Set the orientation * @param img * @param o */ private void setOrientation(EnhancedImage img, Orientation o){ // remove all the possible secondary styles.. shownImage.removeStyleName("rotate-0"); shownImage.removeStyleName("rotate-90"); shownImage.removeStyleName("rotate-180"); shownImage.removeStyleName("rotate-270"); switch(o){ case ROTATE_90: shownImage.addStyleName("rotate-90"); break; case ROTATE_180: shownImage.addStyleName("rotate-180"); break; case ROTATE_270: shownImage.addStyleName("rotate-270"); break; default: shownImage.addStyleName("rotate-0"); } // few ms are needed to remove/add the style, after that we remove the loading image Timer t = new Timer() { @Override public void run() { removeLoader(); } }; t.schedule(500); } }