View Javadoc

1   /**
2    * This file Copyright (c) 2012 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.ui.vaadin.editor;
35  
36  import info.magnolia.ui.vaadin.gwt.client.editor.VImageEditor;
37  
38  import java.io.Serializable;
39  import java.util.ArrayList;
40  import java.util.List;
41  import java.util.Map;
42  
43  import org.vaadin.rpc.ServerSideHandler;
44  import org.vaadin.rpc.ServerSideProxy;
45  import org.vaadin.rpc.client.Method;
46  
47  import com.vaadin.terminal.PaintException;
48  import com.vaadin.terminal.PaintTarget;
49  import com.vaadin.terminal.Resource;
50  import com.vaadin.ui.AbstractComponent;
51  import com.vaadin.ui.ClientWidget;
52  
53  /**
54   * Server side component for the ImageEditor widget.
55   */
56  @ClientWidget(VImageEditor.class)
57  public class ImageEditor extends AbstractComponent implements ServerSideHandler {
58  
59      private static final int DEFAULT_MIN_DIMENSION = 200;
60  
61      private int minDimension = DEFAULT_MIN_DIMENSION;
62  
63      private int marginsPx = 20;
64      
65      private boolean isCropAspectRatioLocked = false;
66  
67      private boolean isAttached = false;
68  
69      private String fileName = "";
70      
71      private String mimeType = "";
72              
73      private final ServerSideProxy proxy = new ServerSideProxy(this) {
74          {
75              register("croppedAreaReady", new Method() {
76  
77                  @Override
78                  public void invoke(String methodName, Object[] params) {
79                      final CropArea area = new CropArea(getInt(params[0]), getInt(params[1]), getInt(params[2]), getInt(params[3]));
80                      for (final CropListener listener : listeners) {
81                          listener.onCrop(area);
82                      }
83                  }
84              });
85          }
86  
87          public int getInt(Object intObj) {
88              return (Integer) intObj;
89          }
90      };
91  
92      private Resource source;
93  
94      private final List<CropListener> listeners = new ArrayList<CropListener>();
95  
96      private boolean isCropping = false;
97  
98      public ImageEditor() {
99          setImmediate(true);
100     }
101 
102     public void addCropListener(CropListener listener) {
103         listeners.add(listener);
104     }
105 
106     public void setMarginsPx(int marginsPx) {
107         this.marginsPx = marginsPx;
108         callOnceIfAttached("setMarginsPx", marginsPx);
109     }
110     
111     public void setSource(Resource source) {
112         this.source = source;
113         callOnceIfAttached("setSource", this.source);
114     }
115 
116     public void setCropping(boolean isCropping) {
117         this.isCropping = isCropping;
118         callOnceIfAttached("setCropping", isCropping);
119     }
120 
121     public void fetchCropArea() {
122         callOnceIfAttached("fetchCropArea");
123     }
124 
125     public void setCropAspectRatioLocked(boolean isLocked) {
126         this.isCropAspectRatioLocked = isLocked;
127         callOnceIfAttached("lockAspectRatio", isLocked);
128     }
129 
130     public void setMinDimension(int minDimension) {
131         this.minDimension = minDimension;
132         callOnceIfAttached("setMinDimension", minDimension);
133     }
134 
135     public void setFileName(String fileName) {
136         this.fileName = fileName;
137         callOnceIfAttached("setFileName", fileName);
138     }
139     
140     public void setMimeType(String mimeType) {
141         this.mimeType = mimeType;
142         callOnceIfAttached("setMimeType", mimeType);
143     }
144     
145     public boolean isCropping() {
146         return isCropping;
147     }
148 
149     public boolean isAspectRatioLocked() {
150         return this.isCropAspectRatioLocked;
151     }
152 
153     private void callOnceIfAttached(String methodName, Object... params) {
154         if (isAttached) {
155             proxy.callOnce(methodName, params);
156         }
157     }
158 
159     @Override
160     public void paintContent(PaintTarget target) throws PaintException {
161         super.paintContent(target);
162         proxy.paintContent(target);
163     }
164 
165     @Override
166     public void changeVariables(Object source, Map<String, Object> variables) {
167         super.changeVariables(source, variables);
168         proxy.changeVariables(source, variables);
169     }
170 
171     @Override
172     public Object[] initRequestFromClient() {
173         proxy.callOnce("setSource", this.source);
174         proxy.callOnce("setCropping", isCropping);
175         proxy.callOnce("setMinDimension", minDimension);
176         proxy.callOnce("setMarginsPx", marginsPx);
177         proxy.callOnce("setFileName", fileName);
178         proxy.callOnce("setMimeType", mimeType);
179         if (isAspectRatioLocked()) {
180             proxy.callOnce("lockAspectRatio", isCropAspectRatioLocked);
181         }
182         return new Object[] {};
183     }
184 
185     @Override
186     public void callFromClient(String method, Object[] params) {
187         throw new RuntimeException("Unhandled call from client: " + method);
188     }
189 
190     @Override
191     public void attach() {
192         super.attach();
193         this.isAttached = true;
194     }
195 
196     @Override
197     public void detach() {
198         super.detach();
199         this.isAttached = false;
200     }
201 
202     /**
203      * CropListener.
204      */
205     public interface CropListener {
206         void onCrop(final CropArea area);
207     }
208 
209     /**
210      * CropArea.
211      */
212     public static class CropArea implements Serializable {
213         private final int top;
214 
215         private final int left;
216 
217         private final int width;
218 
219         private final int height;
220 
221         public CropArea(int left, int top, int width, int height) {
222             this.top = top;
223             this.left = left;
224             this.width = width;
225             this.height = height;
226         }
227 
228         public int getTop() {
229             return top;
230         }
231 
232         public int getLeft() {
233             return left;
234         }
235 
236         public int getWidth() {
237             return width;
238         }
239 
240         public int getHeight() {
241             return height;
242         }
243 
244         @Override
245         public String toString() {
246             return "[" + "w:" + getWidth() + "h:" + getHeight() + "l:" + getLeft() + "t:" + getTop() + "]";
247         }
248     }
249 }