package org.gudy.azureus2.ui.swt.shells;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.gudy.azureus2.ui.swt.Utils;
import com.aelitis.azureus.ui.swt.UIFunctionsManagerSWT;
import com.aelitis.azureus.ui.swt.UIFunctionsSWT;
/**
* A utility class that helps in docking a given <code>Shell</code> to a given <code>Control</code>
* @author khai
*
*/
public class ShellDocker
{
private DockPosition anchorControlPosition = new DockPosition();
private boolean isDocked = true;
private boolean moveWithShell = true;
private boolean resizeWithShell = false;
private Listener dockingEnabler = null;
private Control anchorControl = null;
private Shell dockedShell = null;
private Shell mainShell = null;
public ShellDocker(Control anchorControl, Shell dockedShell) {
if (null == anchorControl || true == anchorControl.isDisposed()) {
throw new NullPointerException("anchorControl cannot be null or disposed");
}
if (null == dockedShell || true == dockedShell.isDisposed()) {
throw new NullPointerException("dockedShell cannot be null or disposed");
}
this.anchorControl = anchorControl;
this.dockedShell = dockedShell;
mainShell = anchorControl.getShell();
}
/**
* Opens the shell
*/
public void openShell() {
openShell(isDocked(), false);
}
/**
* Opens the shell as docked
* @param isDocked
*/
public void openShell(boolean isDocked) {
openShell(isDocked, false);
}
/**
* Opens the shell as docked and animated
* @param isDocked
* @param isAnimated
*/
public void openShell(boolean isDocked, boolean isAnimated) {
setDocked(isDocked);
if (false == isDocked) {
/*
* Centers the window by default
*/
UIFunctionsSWT uiFunctions = UIFunctionsManagerSWT.getUIFunctionsSWT();
if (null == uiFunctions) {
/*
* Centers on the active monitor
*/
Utils.centreWindow(dockedShell);
} else {
/*
* Centers on the main application window
*/
Utils.centerWindowRelativeTo(dockedShell, uiFunctions.getMainShell());
}
}
if (false == isAnimated) {
dockedShell.open();
} else {
//TODO: implement any fancy animation FX here; this is currently just opening the shell normally
dockedShell.open();
}
}
public boolean isDocked() {
return isDocked;
}
public void setDocked(boolean isDocked) {
this.isDocked = isDocked;
if (true == isDocked) {
performDocking();
if (null == dockingEnabler) {
dockingEnabler = new Listener() {
public void handleEvent(Event event) {
if (event.type == SWT.Resize) {
if (true == isResizeWithShell()) {
System.out.println("resizing");//KN: sysout
} else {
performDocking();
}
} else if (event.type == SWT.Move) {
performDocking();
}
}
};
}
if (null != mainShell && false == mainShell.isDisposed()) {
if (true == isMoveWithShell()) {
mainShell.addListener(SWT.Move, dockingEnabler);
}
if (true == isResizeWithShell()) {
mainShell.addListener(SWT.Resize, dockingEnabler);
}
anchorControl.addListener(SWT.Move, dockingEnabler);
anchorControl.addListener(SWT.Resize, dockingEnabler);
}
anchorControl.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
setDocked(false);
}
});
dockedShell.addListener(SWT.Close, new Listener() {
public void handleEvent(Event e) {
setDocked(false);
}
});
} else {
if (null != mainShell && false == mainShell.isDisposed()) {
if (null != dockingEnabler) {
mainShell.removeListener(SWT.Move, dockingEnabler);
mainShell.removeListener(SWT.Resize, dockingEnabler);
}
}
if (null != anchorControl && false == anchorControl.isDisposed()) {
if (null != dockingEnabler) {
anchorControl.removeListener(SWT.Move, dockingEnabler);
anchorControl.removeListener(SWT.Resize, dockingEnabler);
}
}
}
}
private void performDocking() {
if (true == isAlive()) {
switch (anchorControlPosition.getPosition()) {
case DockPosition.TOP_LEFT:
dockedShell.setLocation(mainShell.toDisplay(anchorControl.getLocation()));
break;
case DockPosition.TOP_RIGHT:
break;
case DockPosition.BOTTOM_LEFT: {
Point p = mainShell.toDisplay(anchorControl.getLocation());
p.x += anchorControlPosition.getOffset().xOffset;
p.y += anchorControlPosition.getOffset().yOffset;
p.y += anchorControl.getSize().y;
dockedShell.setLocation(p);
}
break;
case DockPosition.BOTTOM_RIGHT: {
Point p = mainShell.toDisplay(anchorControl.getLocation());
p.x += anchorControlPosition.getOffset().xOffset;
p.y += anchorControlPosition.getOffset().yOffset;
p.x += anchorControl.getSize().x;
p.y += anchorControl.getSize().y;
dockedShell.setLocation(p);
}
break;
default:
break;
}
}
}
private boolean isAlive() {
if (null == mainShell || true == mainShell.isDisposed()) {
System.err.println("\tmainshell is disposed?");//KN: sysout
return false;
}
if (null == dockedShell || true == dockedShell.isDisposed()) {
System.err.println("\tdockedShell is disposed?");//KN: sysout
return false;
}
if (null == anchorControl || true == anchorControl.isDisposed()) {
System.err.println("\tanchorControl is disposed?");//KN: sysout
return false;
}
return true;
}
public boolean isMoveWithShell() {
return moveWithShell;
}
public void setMoveWithShell(boolean moveWithShell) {
this.moveWithShell = moveWithShell;
}
public boolean isResizeWithShell() {
return resizeWithShell;
}
public void setResizeWithShell(boolean resizeWithShell) {
this.resizeWithShell = resizeWithShell;
}
public DockPosition getAnchorControlPosition() {
return anchorControlPosition;
}
public void setAnchorControlPosition(DockPosition anchorControlPosition) {
this.anchorControlPosition = anchorControlPosition;
}
}