package edu.purdue.pivot.skwiki.client;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.RootPanel;
import gwt.g2d.client.graphics.Surface;
public class ResizableSurface extends Surface {
private boolean bDragDrop = false;
private boolean move = false;
private Element movingPanelElement;
private List panelResizedListeners = new ArrayList();
public ResizableSurface(int width, int height) {
super(width, height);
//listen to mouse-events
DOM.sinkEvents(this.getElement(),
Event.ONMOUSEDOWN |
Event.ONMOUSEMOVE |
Event.ONMOUSEUP |
Event.ONMOUSEOVER
);
}
@Override
public void onBrowserEvent(Event event) {
final int eventType = DOM.eventGetType(event);
if (Event.ONMOUSEOVER == eventType) {
//show different cursors
if (isCursorResize(event)) {
DOM.setStyleAttribute(this.getElement(), "cursor", "se-resize");
} else if(isCursorMove(event)){
DOM.setStyleAttribute(this.getElement(),"cursor", "se-resize");
}else {
DOM.setStyleAttribute(this.getElement(), "cursor", "default");
}
}
if (Event.ONMOUSEDOWN == eventType) {
if (isCursorResize(event)) {
//enable/disable resize
if (bDragDrop == false) {
bDragDrop = true;
DOM.setCapture(this.getElement());
}
}else if(isCursorMove(event)){
DOM.setCapture(this.getElement());
move = true;
}
} else if (Event.ONMOUSEMOVE == eventType) {
//reset cursor-type
if(!isCursorResize(event)&&!isCursorMove(event)){
DOM.setStyleAttribute(this.getElement(), "cursor", "default");
}
//calculate and set the new size
if (bDragDrop == true) {
int absX = DOM.eventGetClientX(event);
int absY = DOM.eventGetClientY(event);
int originalX = DOM.getAbsoluteLeft(this.getElement());
int originalY = DOM.getAbsoluteTop(this.getElement());
//do not allow mirror-functionality
if(absY>originalY && absX>originalX){
Integer height = absY-originalY+2;
this.setHeight(height + "px");
Integer width = absX-originalX+2;
this.setWidth(width + "px");
notifyPanelResizedListeners(width, height);
}
}else if(move == true){
RootPanel.get().setWidgetPosition(this, DOM.eventGetClientX(event),DOM.eventGetClientY(event));
}
} else if (Event.ONMOUSEUP == eventType) {
//reset states
if(move == true){
move = false;
DOM.releaseCapture(this.getElement());
}
if (bDragDrop == true) {
bDragDrop = false;
DOM.releaseCapture(this.getElement());
}
}
}
protected boolean isCursorResize(Event event) {
int cursorY = DOM.eventGetClientY(event);
int initialY = this.getAbsoluteTop();
int height = this.getOffsetHeight();
int cursorX = DOM.eventGetClientX(event);
int initialX = this.getAbsoluteLeft();
int width = this.getOffsetWidth();
// only in bottom right corner (area of 10 pixels in square)
if (((initialX + width - 10) < cursorX && cursorX <= (initialX + width))
&& ((initialY + height - 10) < cursorY && cursorY <= (initialY + height)))
return true;
else
return false;
}
public void setMovingPanelElement(Element movingPanelElement) {
this.movingPanelElement = movingPanelElement;
}
protected boolean isCursorMove(Event event) {
if (movingPanelElement != null) {
int cursorY = DOM.eventGetClientY(event);
int initialY = movingPanelElement.getAbsoluteTop();
int cursorX = DOM.eventGetClientX(event);
int initialX = movingPanelElement.getAbsoluteLeft();
if (initialY <= cursorY && initialX <= cursorX)
return true;
else
return false;
} else
return false;
}
public void addPanelResizedListener(PanelResizeListener listener) {
panelResizedListeners.add(listener);
}
/**
* Interface function to emit signal
*/
private void notifyPanelResizedListeners(Integer width, Integer height) {
for (Iterator i = panelResizedListeners.iterator(); i.hasNext();) {
((PanelResizeListener) i.next()).onResized(width, height);
}
}
public interface PanelResizeListener {
/**
* indicates a Panel has been resized
*
* @param width
* @param height
**/
public void onResized(Integer width, Integer height);
}
}