/*
* Copyright 2014-2015 CyberVision, Inc.
*
* 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.kaaproject.avro.ui.gwt.client.widget;
import java.util.ArrayList;
import java.util.List;
import org.kaaproject.avro.ui.gwt.client.AvroUiResources.AvroUiStyle;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.FlowPanel;
public class ResizePanel extends FlowPanel {
private boolean resize = false;
private List<PanelResizeListener> panelResizedListeners = new ArrayList<>();
private Element resizeElement;
private int minWidth = 0;
private int minHeight = 0;
public ResizePanel(AvroUiStyle style) {
super();
DOM.sinkEvents(this.getElement(), Event.ONMOUSEDOWN | Event.ONMOUSEMOVE
| Event.ONMOUSEUP | Event.ONMOUSEOVER);
addStyleName(style.resizePanel());
resizeElement = DOM.createDiv();
resizeElement.addClassName(style.resizeHandle());
this.getElement().appendChild(resizeElement);
Event.addNativePreviewHandler(new NativePreviewHandler() {
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (resize) {
int clientX = event.getNativeEvent().getClientX();
int clientY = event.getNativeEvent().getClientY();
int originalX = getElement().getAbsoluteLeft();
int originalY = getElement().getAbsoluteTop();
if (clientX < originalX || clientY < originalY) {
event.cancel();
}
}
}
});
}
public void setMinSize(int width, int height) {
if (width >= 0) {
this.minWidth = width;
}
if (height >= 0) {
this.minHeight = height;
}
}
@Override
public void onBrowserEvent(Event event) {
final int eventType = DOM.eventGetType(event);
if (Event.ONMOUSEOVER == eventType && isCursorResize(event)) {
getElement().getStyle().setCursor(Cursor.DEFAULT);
}
if (Event.ONMOUSEDOWN == eventType) {
if (isCursorResize(event) && !resize) {
resize = true;
DOM.setCapture(this.getElement());
}
} else if (resize && Event.ONMOUSEMOVE == eventType) {
int absX = event.getClientX();
int absY = event.getClientY();
int originalX = getElement().getAbsoluteLeft();
int originalY = getElement().getAbsoluteTop();
if (absY > originalY && absX > originalX) {
int height = absY - originalY + 2 -
(getElement().getAbsoluteBottom() - resizeElement.getAbsoluteTop());
height = Math.max(minHeight, height);
this.setHeight(height + "px");
int width = Math.max(minWidth, absX - originalX + 2);
this.setWidth(width + "px");
notifyPanelResizedListeners(width, height);
event.preventDefault();
}
} else if (resize && Event.ONMOUSEUP == eventType) {
resize = false;
DOM.releaseCapture(this.getElement());
}
}
protected boolean isCursorResize(Event event) {
if (resizeElement != null) {
int cursorY = event.getClientY();
int initialY = resizeElement.getAbsoluteTop();
int height = resizeElement.getOffsetHeight();
int cursorX = event.getClientX();
int initialX = resizeElement.getAbsoluteLeft();
int width = resizeElement.getOffsetWidth();
if (cursorY >= initialY && cursorY <= (initialY + height) &&
cursorX >= initialX && cursorX <= (initialX + width)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public void addPanelResizedListener(PanelResizeListener listener) {
panelResizedListeners.add(listener);
}
private void notifyPanelResizedListeners(Integer width, Integer height) {
for (PanelResizeListener listener : panelResizedListeners) {
listener.onResized(width, height);
}
}
public interface PanelResizeListener {
public void onResized(int width, int height);
}
}