blob: 24eb08ab4c9882d5a8a75cda74d726f0dbd9b6aa [file] [log] [blame]
/**
*
* Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner <florian.pirchner@gmail.com> - Initial implementation
*/
package org.eclipse.osbp.vaadin.addons.absolutelayout;
import java.io.Serializable;
import java.lang.reflect.Method;
import org.eclipse.osbp.vaadin.addons.absolutelayout.client.OAbsoluteLayoutServerRpc;
import org.eclipse.osbp.vaadin.addons.absolutelayout.client.OAbsoluteLayoutState;
import org.eclipse.osbp.vaadin.addons.absolutelayout.client.OResizeLocation;
import com.vaadin.shared.Connector;
import com.vaadin.ui.Component;
import com.vaadin.util.ReflectTools;
import fi.jasoft.dragdroplayouts.DDAbsoluteLayout;
import fi.jasoft.dragdroplayouts.client.ui.LayoutDragMode;
/**
* OS.bee AbsoluteLayout. <br>
* This layout supports resizing its elements. And also supports drag and drop
* of elemens.
* <p>
* Only DragModes NONE and COPY are allowed
*/
@SuppressWarnings("serial")
public class AbsoluteLayout extends DDAbsoluteLayout {
/** The rpc. */
private OAbsoluteLayoutServerRpc rpc = new OAbsoluteLayoutServerRpc() {
@Override
public void resized(Connector connector, int newWidth, int newHeight, int oldWidth, int oldHeight,
OResizeLocation location) {
internalResizeChild((Component) connector, newWidth, newHeight, oldWidth, oldHeight, location);
fireEvent(new ChildResizedEvent((Component) connector, newWidth, newHeight, oldWidth, oldHeight, location));
}
};
/**
* Instantiates a new absolute layout.
*/
public AbsoluteLayout() {
registerRpc(rpc);
}
/* (non-Javadoc)
* @see fi.jasoft.dragdroplayouts.DDAbsoluteLayout#getState()
*/
@Override
public OAbsoluteLayoutState getState() {
return (OAbsoluteLayoutState) super.getState();
}
/* (non-Javadoc)
* @see fi.jasoft.dragdroplayouts.DDAbsoluteLayout#getState(boolean)
*/
@Override
protected OAbsoluteLayoutState getState(boolean markAsDirty) {
return (OAbsoluteLayoutState) super.getState(markAsDirty);
}
/**
* Internal resize child.
*
* @param child the child
* @param newWidth the new width
* @param newHeight the new height
* @param oldWidth the old width
* @param oldHeight the old height
* @param location the location
*/
protected void internalResizeChild(Component child, int newWidth, int newHeight, int oldWidth, int oldHeight,
OResizeLocation location) {
switch (location) {
case TOP_LEFT:
moveLeft(oldWidth - newWidth, child);
case TOP:
moveTop(oldHeight - newHeight, child);
break;
case TOP_RIGHT:
moveTop(oldHeight - newHeight, child);
case RIGHT:
moveRight(oldWidth - newWidth, child);
break;
case BOTTOM_RIGHT:
moveRight(oldWidth - newWidth, child);
case BOTTOM:
moveBottom(oldHeight - newHeight, child);
break;
case BOTTOM_LEFT:
moveBottom(oldHeight - newHeight, child);
case LEFT:
moveLeft(oldWidth - newWidth, child);
break;
default:
break;
}
child.setWidth(newWidth, Unit.PIXELS);
child.setHeight(newHeight, Unit.PIXELS);
}
/**
* Adjusts the top position for the component when inside a
* {@link com.vaadin.ui.AbsoluteLayout} and top position was set with
* pixels.
*
* @param delta the change of top position in pixels
* @param child the component that is inside the absolute layout
*/
protected void moveTop(int delta, Component child) {
ComponentPosition position = getPosition(child);
if (position.getTopValue() != null && position.getTopUnits().equals(Unit.PIXELS)) {
float newValue = (position.getTopValue() + delta);
if (newValue < 0) {
newValue = 0;
}
position.setTopValue(newValue);
setPosition(child, position);
} else {
// position bottom set, NOOP
}
}
/**
* Adjusts the bottom position for the component when inside a
* {@link com.vaadin.ui.AbsoluteLayout} and bottom position was set with
* pixels.
*
* @param delta the change of bottom position in pixels
* @param child the component that is inside the absolute layout
*/
protected void moveBottom(int delta, Component child) {
ComponentPosition position = getPosition(child);
if (position.getBottomValue() != null && position.getBottomUnits().equals(Unit.PIXELS)) {
float newValue = (position.getBottomValue() + delta);
if (newValue < 0) {
newValue = 0;
}
position.setBottomValue(newValue);
setPosition(child, position);
} else {
// position top used, NOOP
}
}
/**
* Adjusts the right position for the component when inside a
* {@link com.vaadin.ui.AbsoluteLayout} and right position was set with
* pixels.
*
* @param delta the change of right position in pixels
* @param child the child
*/
protected void moveRight(int delta, Component child) {
ComponentPosition position = getPosition(child);
if (position.getRightValue() != null && position.getRightUnits().equals(Unit.PIXELS)) {
float newValue = (position.getRightValue() + delta);
if (newValue < 0) {
newValue = 0;
}
position.setRightValue(newValue);
setPosition(child, position);
} else {
// position left used, NOOP
}
}
/**
* Adjusts the left position for the component when inside a
* {@link com.vaadin.ui.AbsoluteLayout} and left position was set with
* pixels.
*
* @param delta the change of left position in pixels
* @param child the component that is inside the absolute layout
*/
protected void moveLeft(int delta, Component child) {
ComponentPosition position = getPosition(child);
if (position.getLeftValue() != null && position.getLeftUnits().equals(Unit.PIXELS)) {
float newValue = (position.getLeftValue() + delta);
if (newValue < 0) {
newValue = 0;
}
position.setLeftValue(newValue);
setPosition(child, position);
} else {
// position right set, NOOP
}
}
/**
* True, if the children should be resizable.
*
* @return true, if is resizable
*/
public boolean isResizable() {
return getState(false).useResizing;
}
/**
* True, if the children should be resizable.
*
* @param value the new resizable
*/
public void setResizable(boolean value) {
if (getState(false).useResizing != value) {
getState().useResizing = value;
}
}
/**
* True, if alignments should be used.
*
* @return true, if is use alignments
*/
public boolean isUseAlignments() {
return getState(false).useAlignments;
}
/**
* True, if alignments should be used.
*
* @param value the new use alignments
*/
public void setUseAlignments(boolean value) {
if (getState(false).useAlignments != value) {
getState().useAlignments = value;
}
}
/* (non-Javadoc)
* @see fi.jasoft.dragdroplayouts.DDAbsoluteLayout#setDragMode(fi.jasoft.dragdroplayouts.client.ui.LayoutDragMode)
*/
@Override
public void setDragMode(LayoutDragMode mode) {
if (mode != LayoutDragMode.NONE && mode != LayoutDragMode.CLONE) {
throw new IllegalArgumentException("Mode is not supported!");
}
super.setDragMode(mode);
}
/**
* Add listener which is being notified if a child should be resized.
*
* @param listener the listener
*/
public void addChildResizedListener(ChildResizedListener listener) {
addListener(ChildResizedEvent.class, listener, ChildResizedListener.CHILD_RESIZED_METHOD);
}
/**
* Removes listener which is being notified if a child should be resized.
*
* @param listener the listener
*/
public void removeChildResizedListener(ChildResizedListener listener) {
removeListener(ChildResizedEvent.class, listener);
}
/**
* The Class ChildResizedEvent.
*/
public static class ChildResizedEvent extends Event {
/** The new width. */
private final int newWidth;
/** The new height. */
private final int newHeight;
/** The old width. */
private final int oldWidth;
/** The old height. */
private final int oldHeight;
/** The location. */
private final OResizeLocation location;
/**
* Instantiates a new child resized event.
*
* @param source the source
* @param newWidth the new width
* @param newHeight the new height
* @param oldWidth the old width
* @param oldHeight the old height
* @param location the location
*/
public ChildResizedEvent(Component source, int newWidth, int newHeight, int oldWidth, int oldHeight,
OResizeLocation location) {
super(source);
this.newWidth = newWidth;
this.newHeight = newHeight;
this.oldWidth = oldWidth;
this.oldHeight = oldHeight;
this.location = location;
}
/**
* Gets the new width.
*
* @return the new width
*/
public int getNewWidth() {
return newWidth;
}
/**
* Gets the new height.
*
* @return the new height
*/
public int getNewHeight() {
return newHeight;
}
/**
* Gets the old width.
*
* @return the old width
*/
public int getOldWidth() {
return oldWidth;
}
/**
* Gets the old height.
*
* @return the old height
*/
public int getOldHeight() {
return oldHeight;
}
/**
* Gets the location.
*
* @return the location
*/
public OResizeLocation getLocation() {
return location;
}
}
/**
* The listener interface for receiving childResized events.
* The class that is interested in processing a childResized
* event implements this interface, and the object created
* with that class is registered with a component using the
* component's <code>addChildResizedListener</code> method. When
* the childResized event occurs, that object's appropriate
* method is invoked.
*
* @see ChildResizedEvent
*/
public interface ChildResizedListener extends Serializable {
/** The Constant CHILD_RESIZED_METHOD. */
public static final Method CHILD_RESIZED_METHOD = ReflectTools.findMethod(ChildResizedListener.class,
"childResized", ChildResizedEvent.class);
/**
* Child resized.
*
* @param event the event
*/
void childResized(ChildResizedEvent event);
}
}