/*
* Copyright (c) 2009-2011 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.web.client.ui.common.dialog.imagecrop;
import java.util.LinkedList;
import java.util.List;
import org.eurekastreams.commons.client.ActionProcessor;
import org.eurekastreams.server.action.request.profile.ResizeAvatarRequest;
import org.eurekastreams.server.domain.AvatarEntity;
import org.eurekastreams.server.domain.AvatarUrlGenerator;
import org.eurekastreams.server.domain.EntityType;
import org.eurekastreams.web.client.history.CreateUrlRequest;
import org.eurekastreams.web.client.ui.Session;
import org.eurekastreams.web.client.ui.common.dialog.BaseDialogContent;
import org.eurekastreams.web.client.ui.common.form.elements.avatar.strategies.ImageUploadStrategy;
import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
/**
* The insides of the image crop dialog.
*/
public class ImageCropContent extends BaseDialogContent
{
/**
* The person object.
*/
@SuppressWarnings("rawtypes")
private final ImageUploadStrategy strategy;
/**
* The content panel.
*/
private final FlowPanel content = new FlowPanel();
/**
* The command to exe on save.
*/
private Command saveCommand = null;
/**
* The JS object returned from YUI.
*/
private JavaScriptObject imgCrop;
/**
* The image itself.
*/
private final Image baseImage;
/**
* The save button.
*/
private final Hyperlink saveButton;
/**
* The close button.
*/
private final Hyperlink closeButton;
/**
* Action processor. TODO: Replace with use of models.
*/
private final ActionProcessor processor;
/**
* Default constructor.
*
* @param inStrategy
* the entity.
* @param inProcessor
* the processor.
* @param inAvatarId
* the avatar ID.
* @param inSaveCommand
* the save command.
* @param inImageWidth
* Image width.
* @param inImageHeight
* Image height.
*/
public ImageCropContent(@SuppressWarnings("rawtypes") final ImageUploadStrategy inStrategy,
final ActionProcessor inProcessor, final String inAvatarId, final Command inSaveCommand,
final String inImageWidth, final String inImageHeight)
{
saveCommand = inSaveCommand;
processor = inProcessor;
content.addStyleName(StaticResourceBundle.INSTANCE.coreCss().yuiSkinSam());
content.addStyleName(StaticResourceBundle.INSTANCE.coreCss().avatarCropModal());
strategy = inStrategy;
AvatarUrlGenerator urlGenerator = new AvatarUrlGenerator(EntityType.PERSON);
content.add(new Label(
"Drag or resize the box to change your avatar. When you are finished click the save button."));
baseImage = new Image();
baseImage.setSize(inImageWidth, inImageHeight);
baseImage.setUrl(urlGenerator.getOriginalAvatarUrl(inAvatarId));
baseImage.getElement().setAttribute("id", "avatarBase");
FlowPanel imageContainer = new FlowPanel();
imageContainer.addStyleName(StaticResourceBundle.INSTANCE.coreCss().imageContainer());
imageContainer.add(baseImage);
content.add(imageContainer);
saveButton = new Hyperlink("save", Session.getInstance().generateUrl(new CreateUrlRequest()));
saveButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formSaveButton());
saveButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton());
content.add(saveButton);
closeButton = new Hyperlink("cancel", StaticResourceBundle.INSTANCE.coreCss().settings());
closeButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formCancelButton());
closeButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton());
content.add(closeButton);
setupEvents();
}
/**
* Wire up events.
*/
private void setupEvents()
{
closeButton.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent inArg0)
{
close();
}
});
saveButton.addClickHandler(new ClickHandler()
{
public void onClick(final ClickEvent inArg0)
{
List<Integer> coords = getCoords();
ResizeAvatarRequest request = new ResizeAvatarRequest(coords.get(0), coords.get(1), coords.get(2),
Boolean.TRUE, strategy.getId());
// TODO: refactor to new simplified model design (and thus eliminiate use of the action processor here)
processor.makeRequest(strategy.getResizeAction(), request, new AsyncCallback<AvatarEntity>()
{
public void onFailure(final Throwable caught)
{
}
public void onSuccess(final AvatarEntity result)
{
strategy.setEntity(result);
saveCommand.execute();
close();
}
});
}
});
}
/**
* The title of the login dialog.
*
* @return the title.
*/
public final String getTitle()
{
return "Resize Photo";
}
/**
* The login form.
*
* @return the login form.
*/
public final Widget getBody()
{
return content;
}
/**
* Returns the form panel.
*
* @return the form panel.
*/
public FormPanel getFormPanel()
{
return null;
}
/**
* Provides a hook to fire off events when the dialog is shown.
*/
@Override
public void show()
{
imgCrop = createImageCropper("avatarBase", strategy.getX(), strategy.getY(), strategy.getCropSize());
}
/**
* Gets the coords from YUI.
*
* @return the coords of the crop.
*/
public List<Integer> getCoords()
{
List<Integer> coords = new LinkedList<Integer>();
coords.add(new Integer(getX(imgCrop)));
coords.add(new Integer(getY(imgCrop)));
coords.add(new Integer(getSize(imgCrop)));
return coords;
}
/**
* Wraps YUI and creates the image crop.
*
* @param imgId
* the ID of the image tag.
* @param x
* the start of the crop window.
* @param y
* the start of the crop window.
* @param size
* the size of the crop window.
* @return the JS obj to ref.
*/
public static native JavaScriptObject createImageCropper(final String imgId, final int x, final int y,
final int size) /*-{
var crop = new $wnd.YAHOO.widget.ImageCropper(imgId, {
status: false,
ratio: true,
minHeight: 75,
minWidth: 75,
initHeight: size,
initWidth: size,
initialXY: [x, y]
});
return crop;
}-*/;
/**
* Wraps YUI to get the X coord.
*
* @param imgCrop
* the JS object.
* @return the X coord.
*/
public static native int getX(final JavaScriptObject imgCrop) /*-{
var cropArea = imgCrop.getCropCoords();
return cropArea.left;
}-*/;
/**
* Wraps the YUI to get the Y coord.
*
* @param imgCrop
* the JS object.
* @return the Y coord.
*/
public static native int getY(final JavaScriptObject imgCrop) /*-{
var cropArea = imgCrop.getCropCoords();
return cropArea.top;
}-*/;
/**
* Wraps the YUI to get the size of the crop.
*
* @param imgCrop
* the JS object.
* @return the size of the crop.
*/
public static native int getSize(final JavaScriptObject imgCrop) /*-{
var cropArea = imgCrop.getCropCoords();
return cropArea.width;
}-*/;
/**
* Gets the CSS name for the dialog.
*
* @return the css name.
*/
@Override
public String getCssName()
{
return StaticResourceBundle.INSTANCE.coreCss().imageCropDialog();
}
}