package ch.unifr.pai.mindmap.client.mindmap;
/*
* Copyright 2013 Oliver Schmid
* 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.
*/
import ch.unifr.pai.twice.multipointer.client.MultiCursorController;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.DragLeaveEvent;
import com.google.gwt.event.dom.client.DragLeaveHandler;
import com.google.gwt.event.dom.client.DragOverEvent;
import com.google.gwt.event.dom.client.DragOverHandler;
import com.google.gwt.event.dom.client.DropEvent;
import com.google.gwt.event.dom.client.DropHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.PushButton;
import com.google.gwt.user.client.ui.Widget;
/**
* A widget which allows (by the means of HTML5 drag and drop functionalities) to drag images from external sources (e.g. a file browser) on top of this panel.
* On drop, it stores the image as a data-url and offers it as a thumbnail to be used for the background of the canvas
*
*
* @author Oliver Schmid
*
*/
public class BackgroundImgRepo extends AbsolutePanel {
private final FocusPanel fp = new FocusPanel();
private final FlowPanel hp = new FlowPanel();
/**
* Read the data transfer files from the native transfer object
*
* @param dataTransfer
* @return
*/
private native JsArray<JavaScriptObject> getDataTransferFiles(JavaScriptObject dataTransfer)/*-{
return dataTransfer.files;
}-*/;
/**
* Reads the provided file and fills the img element
*
* @param img
* @param file
*/
public native void addBackgroundImage(Element img, JavaScriptObject file)
/*-{
var readFileSize = 0;
readFileSize += file.fileSize;
// Only process image files.
var reader = new FileReader();
//
//// Create a closure to capture the file information.
reader.onload = (function(aFile) {
return function(evt) {
img.src = evt.target.result;
}
})(file);
// Read in the image file as a data url.
reader.readAsDataURL(file);
//}
}-*/;
/**
* The background image object which is filled with the data-url if the background image changes
*/
private final Image bgImg;
/**
* The preview image which is shown above the image-buttons if the native mouse hovers them
*/
private final Image previewImage = new Image();
/**
* Add an image button to the panel with a background-image trigger button
*
* @param w
*/
public void addButton(Widget w) {
hp.insert(w, 0);
}
/**
* @param bgImg
* - the image object that shall be adapted accordingly to the chosen data-url
*/
public BackgroundImgRepo(Image bgImg) {
super();
add(fp);
add(previewImage);
getElement().getStyle().setOverflow(Overflow.VISIBLE);
this.bgImg = bgImg;
this.setHeight("100%");
this.setWidth("100%");
fp.getElement().getStyle().setBackgroundColor("grey");
fp.setWidth("100%");
fp.setHeight("100%");
fp.setWidget(hp);
hp.setWidth("100%");
hp.setHeight("100%");
fp.setWidget(hp);
previewImage.getElement().getStyle().setPosition(Position.ABSOLUTE);
previewImage.getElement().getStyle().setTop(-120, Unit.PX);
previewImage.getElement().getStyle().setHeight(110, Unit.PX);
previewImage.getElement().getStyle().setBorderWidth(2, Unit.PX);
previewImage.getElement().getStyle().setBorderColor("black");
previewImage.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
previewImage.getElement().getStyle().setDisplay(Display.NONE);
// Add a button for cleaning the browser as well
PushButton emptyBg = new PushButton(new Image(GWT.getModuleBaseURL() + "images/emptyscreen.png")) {
@Override
public void onBrowserEvent(Event event) {
if (MultiCursorController.isDefaultCursor(event)) {
super.onBrowserEvent(event);
}
}
};
emptyBg.setTitle("Remove background-image");
emptyBg.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
emptyBg.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (MultiCursorController.isDefaultCursor(event.getNativeEvent())) {
BackgroundImgRepo.this.bgImg.setVisible(false);
}
}
});
hp.add(emptyBg);
fp.addDragOverHandler(new DragOverHandler() {
@Override
public void onDragOver(DragOverEvent event) {
fp.getElement().getStyle().setBackgroundColor("darkgrey");
}
});
fp.addDragLeaveHandler(new DragLeaveHandler() {
@Override
public void onDragLeave(DragLeaveEvent event) {
fp.getElement().getStyle().setBackgroundColor("grey");
}
});
fp.addDropHandler(new DropHandler() {
/**
* Prevents the default behavior of the browser (otherwise, the browser would open the image in the current tab), reads the dragged files and adds
* them as {@link PushButton} to the panel.
*
* @see com.google.gwt.event.dom.client.DropHandler#onDrop(com.google.gwt.event.dom.client.DropEvent)
*/
/*
* (non-Javadoc)
* @see com.google.gwt.event.dom.client.DropHandler#onDrop(com.google.gwt.event.dom.client.DropEvent)
*/
@Override
public void onDrop(DropEvent event) {
// event.stopPropagation();
event.preventDefault();
fp.getElement().getStyle().setBackgroundColor("grey");
JsArray<JavaScriptObject> files = getDataTransferFiles(event.getDataTransfer());
for (int i = 0; i < files.length(); i++) {
final Image img = new Image();
PushButton button = new PushButton(img) {
@Override
public void onBrowserEvent(Event event) {
if (MultiCursorController.isDefaultCursor(event)) {
super.onBrowserEvent(event);
}
}
};
button.setTitle("Set this image as background");
button.addClickHandler(new ClickHandler() {
/**
* Set the image of the button as the current background image
*
* @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
*/
@Override
public void onClick(ClickEvent event) {
if (MultiCursorController.isDefaultCursor(event.getNativeEvent())) {
BackgroundImgRepo.this.bgImg.setVisible(true);
BackgroundImgRepo.this.bgImg.getElement().setAttribute("src", img.getElement().getAttribute("src"));
}
}
});
button.addMouseOverHandler(new MouseOverHandler() {
/**
* Show the preview image at the appropriate position and replace the data-url
*
* @see com.google.gwt.event.dom.client.MouseOverHandler#onMouseOver(com.google.gwt.event.dom.client.MouseOverEvent)
*/
@Override
public void onMouseOver(MouseOverEvent event) {
if (MultiCursorController.isDefaultCursor(event.getNativeEvent())) {
BackgroundImgRepo.this.previewImage.getElement().getStyle().setDisplay(Display.BLOCK);
BackgroundImgRepo.this.previewImage.getElement().setAttribute("src", img.getElement().getAttribute("src"));
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
previewImage
.getElement()
.getStyle()
.setLeft(
img.getAbsoluteLeft() - BackgroundImgRepo.this.getAbsoluteLeft() - previewImage.getOffsetWidth() / 2
+ img.getOffsetWidth() / 2, Unit.PX);
}
});
}
}
});
button.addMouseOutHandler(new MouseOutHandler() {
/**
* Hide the preview image
*
* @see com.google.gwt.event.dom.client.MouseOutHandler#onMouseOut(com.google.gwt.event.dom.client.MouseOutEvent)
*/
@Override
public void onMouseOut(MouseOutEvent event) {
if (MultiCursorController.isDefaultCursor(event.getNativeEvent())) {
BackgroundImgRepo.this.previewImage.getElement().getStyle().setDisplay(Display.NONE);
}
}
});
// img.getElement().getStyle().setMargin(5, Unit.PX);
// img.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
img.setHeight("35px");
button.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
hp.add(button);
addBackgroundImage(img.getElement(), files.get(i));
}
}
});
}
}