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