001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * troger 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.pictures.tiles.gwt.client.view; 021 022import java.util.HashMap; 023import java.util.Map; 024 025import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.controller.TilingController; 026import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.model.TilingModel; 027import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.model.TilingModelListener; 028import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.model.TilingModel.TilingModelEvent; 029import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.util.Point; 030import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.util.Rectangle; 031import org.nuxeo.ecm.platform.pictures.tiles.gwt.client.view.i18n.TranslationConstants; 032 033import com.allen_sauer.gwt.log.client.Log; 034import com.google.gwt.core.client.GWT; 035import com.google.gwt.user.client.Window; 036import com.google.gwt.user.client.ui.AbsolutePanel; 037import com.google.gwt.user.client.ui.Button; 038import com.google.gwt.user.client.ui.ClickListener; 039import com.google.gwt.user.client.ui.Composite; 040import com.google.gwt.user.client.ui.HorizontalPanel; 041import com.google.gwt.user.client.ui.Image; 042import com.google.gwt.user.client.ui.Widget; 043 044/** 045 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 046 */ 047public class TilingPreviewPanel extends Composite implements TilingModelListener { 048 049 private static final String DEFAULT_CLASS_NAME = "tilingPreviewPanel"; 050 051 private AbsolutePanel tilingViewPanel; 052 053 private AbsolutePanel tilingView; 054 055 private final TilingController controller; 056 057 private final TilingModel model; 058 059 private final Map<String, Image> images = new HashMap<String, Image>(); 060 061 public TilingPreviewPanel(TilingController tilingController, TilingModel tilingModel) { 062 controller = tilingController; 063 model = tilingModel; 064 model.addListener(this); 065 066 // create the panel to show the part of the image 067 tilingViewPanel = new AbsolutePanel(); 068 tilingViewPanel.setPixelSize(model.getViewAreaWidth(), model.getViewAreaHeight()); 069 tilingView = new AbsolutePanel(); 070 tilingViewPanel.add(tilingView); 071 072 tilingViewPanel.addStyleName("tilingViewPanel"); 073 074 AbsolutePanel rootPanel = new AbsolutePanel(); 075 rootPanel.setPixelSize(model.getViewAreaWidth(), model.getViewAreaHeight()); 076 rootPanel.addStyleName("tilingMasterContainer"); 077 rootPanel.add(tilingViewPanel, 0, 0); 078 079 HorizontalPanel hPanel = createZoomButtons(); 080 rootPanel.add(hPanel, 20, 20); 081 082 initWidget(rootPanel); 083 084 setStyleName(DEFAULT_CLASS_NAME); 085 } 086 087 private HorizontalPanel createZoomButtons() { 088 HorizontalPanel buttons = new HorizontalPanel(); 089 090 TranslationConstants translationContants = GWT.create(TranslationConstants.class); 091 092 Button resetZoomButton = new Button(); 093 resetZoomButton.addClickListener(new ClickListener() { 094 public void onClick(Widget arg0) { 095 Window.Location.assign(Window.Location.getHref()); 096 decorate(); 097 } 098 }); 099 resetZoomButton.addStyleName("resetZoomButton"); 100 resetZoomButton.setTitle(translationContants.zoom()); 101 buttons.add(resetZoomButton); 102 103 Button zoomInButton = new Button(); 104 zoomInButton.addClickListener(new ClickListener() { 105 public void onClick(Widget arg0) { 106 model.zoomIn(); 107 } 108 }); 109 zoomInButton.addStyleName("zoomInButton"); 110 zoomInButton.setTitle(translationContants.zoomIn()); 111 buttons.add(zoomInButton); 112 113 Button zoomOutButton = new Button(); 114 zoomOutButton.addClickListener(new ClickListener() { 115 public void onClick(Widget arg0) { 116 model.zoomOut(); 117 } 118 }); 119 zoomOutButton.addStyleName("zoomOutButton"); 120 zoomOutButton.setTitle(translationContants.zoomOut()); 121 buttons.add(zoomOutButton); 122 123 return buttons; 124 } 125 126 public void onModelChange(TilingModelEvent event, TilingModel model) { 127 switch (event) { 128 case MOVE_EVENT: 129 // update the view (move) 130 renderView(); 131 break; 132 case TILING_INFO_UPDATED: 133 // clean and reload the view 134 resetView(); 135 renderView(); 136 break; 137 } 138 } 139 140 private void renderView() { 141 int widthInTiles = model.getWidthInTiles(); 142 int heightInTiles = model.getHeightInTiles(); 143 144 int top = model.getViewAreaTop(); 145 int left = model.getViewAreaLeft(); 146 int width = model.getViewAreaWidth(); 147 int height = model.getViewAreaHeight(); 148 149 Rectangle viewableArea = new Rectangle(new Point(left, top), width, height); 150 151 tilingView.clear(); 152 for (int y = 0; y < heightInTiles; ++y) { 153 for (int x = 0; x < widthInTiles; ++x) { 154 String imageUrl = model.getBaseUrl() + "?x=" + x + "&y=" + y; 155 imageUrl += "&date=" + model.getLastModificationDate(); 156 157 int imageLeft = x * model.getTileWidth(); 158 int imageTop = y * model.getTileHeight(); 159 int imageRight = imageLeft + model.getTileWidth(); 160 int imageBottom = imageTop + model.getTileHeight(); 161 162 Point imageTopLeft = new Point(imageLeft, imageTop); 163 Point imageTopRight = new Point(imageRight, imageTop); 164 Point imageBottomLeft = new Point(imageLeft, imageBottom); 165 Point imageBottomRight = new Point(imageRight, imageBottom); 166 167 if (!viewableArea.containsAny(imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight)) { 168 // Always draw the first image. It's used to display the 169 // annotations 170 if (!(x == 0 && y == 0)) { 171 continue; 172 } 173 } 174 175 Log.debug("Getting image: " + imageUrl); 176 Image image = getImage(imageUrl); 177 178 if (x == 0 && y == 0) { 179 image.getElement().setId("annotationRootImage"); 180 } 181 182 tilingView.add(image, imageLeft, imageTop); 183 } 184 } 185 tilingViewPanel.add(tilingView, -left, -top); 186 187 decorate(); 188 } 189 190 private Image getImage(String imageUrl) { 191 Image image = images.get(imageUrl); 192 if (image == null) { 193 image = new Image(imageUrl); 194 images.put(imageUrl, image); 195 } 196 return image; 197 } 198 199 private void decorate() { 200 controller.updateAnnotationDecoration(); 201 } 202 203 private void resetView() { 204 images.clear(); 205 tilingView.clear(); 206 tilingView.setPixelSize(model.getTotalWidth(), model.getTotalHeight()); 207 } 208 209}