/* * Copyright 2011 JBoss 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.jbpm.formapi.common.panels; import java.util.ArrayList; import java.util.List; import org.jbpm.formapi.common.handler.ResizeEvent; import org.jbpm.formapi.common.handler.ResizeEventHandler; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; /** * resizable panel. Handles mouse events natively to provide * resizing capabilities. Sends {@link ResizeEvent}s when resizing is done. */ public class ResizablePanel extends SimplePanel { private List<ResizeEventHandler> resizeHandlers = new ArrayList<ResizeEventHandler>(); private boolean dragAndDropBegin = false; private final Widget widget; private final Grid grid = new Grid(3, 3); public ResizablePanel(Widget widget, int initialWidth, int initialHeight) { super(); this.widget = widget; grid.setBorderWidth(0); grid.setCellPadding(0); grid.setCellSpacing(0); sinkEvents(Event.ONMOUSEOUT | Event.ONMOUSEDOWN | Event.ONMOUSEMOVE | Event.ONMOUSEUP | Event.ONMOUSEOVER); makeGrid(); setWidget(grid); setSize("" + initialWidth + "px", "" + initialHeight + "px"); } private void makeGrid() { grid.getCellFormatter().addStyleName(0, 0, "northwestCorner"); grid.setHTML(0, 0, ""); grid.getCellFormatter().addStyleName(0, 1, "horizontalLine"); grid.setHTML(0, 1, ""); grid.getCellFormatter().addStyleName(0, 2, "northeastCorner"); grid.setHTML(0, 2, ""); grid.getCellFormatter().addStyleName(1, 0, "verticalLine"); grid.setHTML(1, 0, ""); grid.setWidget(1, 1, widget); grid.getCellFormatter().addStyleName(1, 2, "verticalLine"); grid.setHTML(1, 2, ""); grid.getCellFormatter().addStyleName(2, 0, "southwestCorner"); grid.setHTML(2, 0, ""); grid.getCellFormatter().addStyleName(2, 1, "horizontalLine"); grid.setHTML(2, 1, ""); grid.getCellFormatter().addStyleName(2, 2, "smallButton"); grid.setHTML(2, 2, ""); } @Override public void onBrowserEvent(Event event) { event.stopPropagation(); event.preventDefault(); //code taken from vince.vice switch (DOM.eventGetType(event)) { case Event.ONMOUSEOVER: //show different cursors DOM.setStyleAttribute(this.getElement(), "cursor", isInPosition(event) ? "se-resize" : "default"); break; case Event.ONMOUSEOUT: DOM.setStyleAttribute(this.getElement(), "cursor", "default"); break; case Event.ONMOUSEDOWN: //enable/disable resize if (dragAndDropBegin == false) { dragAndDropBegin = true; DOM.setCapture(this.getElement()); } break; case Event.ONMOUSEMOVE: //calculate and set the new size if (dragAndDropBegin == 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; Integer width = absX-originalX+2; this.setSize(width, height); } } break; case Event.ONMOUSEUP: //reset states if (dragAndDropBegin == true) { dragAndDropBegin = false; DOM.releaseCapture(this.getElement()); notifyResize(); } }; } public boolean isInPosition(Event event) { int xCursor = DOM.eventGetClientX(event); int yCursor = DOM.eventGetClientY(event); int east = getAbsoluteLeft() + getOffsetWidth(); int west = east - 10; int south = getAbsoluteTop() + getOffsetHeight(); int north = south - 10; boolean isInWidth = xCursor > west && xCursor < east; boolean isInHeight = yCursor > north && yCursor < south; return isInWidth && isInHeight; } public void setSize(int width, int height) { int realHeight = height - 20; int realWidth = width - 20; if (realHeight > 0 && realWidth > 0) { widget.setSize("" + realWidth + "px", "" + realHeight + "px"); super.setSize("" + width + "px", "" + height + "px"); } } protected void notifyResize() { int width = widget.getOffsetWidth(); int height = widget.getOffsetHeight(); ResizeEvent event = new ResizeEvent(widget, width, height); for (ResizeEventHandler handler : resizeHandlers) { handler.onResize(event); } } public void addResizeHandler(ResizeEventHandler resizeHandler) { if (!this.resizeHandlers.contains(resizeHandler)) { this.resizeHandlers.add(resizeHandler); } } }