package org.eclipse.uml2.diagram.sequence.internal.layout.model;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.uml2.diagram.sequence.internal.layout.GeometryConstants;
import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsElementPropertyAccess;
import org.eclipse.uml2.diagram.sequence.internal.layout.abstractgde.AbsNode;
import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLine;
import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineElement;
import org.eclipse.uml2.diagram.sequence.internal.layout.vertical.input.LifeLineIterator;
public class LMLifeLine extends LMBracketContainer implements SDVerticalLayoutInputImpl.LifeLineSupply {
LMLifeLine(AbsNode gdeLifeLine, BracketMetaObject pseudoMetaObject, LmOwner lmOwner) {
super(gdeLifeLine, lmOwner);
myPseudoMetaObject = pseudoMetaObject;
LifeLineElement.Position topElementPosition = new LifeLineElement.Position() {
public int getPositionValue() {
return getLifeLineGdeTopPos();
}
public void setPositionValue(int pos) {
if (isVirtual()) {
return;
}
setLifeLineGdeTopPos(pos);
}
public boolean isVirtual() {
return myCreationExecution != null;//execution will provide top pos
}
public boolean isFirstPrioritedPosition() {
return isJustReshaped();
}
public boolean isLastPrioritedPosition() {
return false;
}
};
myFirstLifeLineElement = new SDVerticalLayoutInputImpl.LifeLineElementGenAdapter(GeometryConstants.Lifeline.SKIP_LIFELINE_FROM_TOP, GeometryConstants.Lifeline.SKIP_LIFELINE_FROM_TOP, topElementPosition, this) {
public String toString() {
return "Lifeline("+LMLifeLine.this+")top"; //$NON-NLS-1$ //$NON-NLS-2$
}
};
LifeLineElement.Position bottomElementPosition = new LifeLineElement.Position() {
public int getPositionValue() {
return getLifeLineGdeBottomPos();
}
public void setPositionValue(int pos) {
if (isVirtual()) {
return;
}
setLifeLineGdeBottomPos(pos);
}
public boolean isVirtual() {
return myDestructionExecution != null;//execution will provide bottom pos
}
public boolean isFirstPrioritedPosition() {
return false;
}
public boolean isLastPrioritedPosition() {
return isJustReshaped();
}
};
myLastLifeLineElement = new SDVerticalLayoutInputImpl.LifeLineElementGenAdapter(20, 20, bottomElementPosition, this) {
public String toString() {
return "Lifeline("+LMLifeLine.this+")bottoms"; //$NON-NLS-1$ //$NON-NLS-2$
}
};
myDetailsLayouter = AbsElementPropertyAccess.getInstance().getLifeLineDetailsLayouter(gdeLifeLine);
myHeadLifeLineElement = new HeadLifeLineElement(myDetailsLayouter.getHeadPreferredHeight());
}
public void setJustReshaped(JustReshapedState justReshapedState) {
super.setJustReshaped(justReshapedState);
if (myBottomPosControoller != null) {
AbsNode gdeNode = myBottomPosControoller.getGdeNode();
int lifelineBottom = getBracketBottomPos();
int y = gdeNode.getY();
gdeNode.setHeight(lifelineBottom - y);
}
//It is not necessary because on lifeline top pos change all children(including
//creation execution) will be translated anyway
// if (myCreationExecution != null) {
// AbsNode gdeNode = myCreationExecution.getGdeNode();
// int creationTop = getBracketTopPos() + getHeadHeight() -1;
// gdeNode.setY(creationTop);
// }
}
void updateCreationDestruction() {
{
LMLifeLineBracket firstBracket = getCreationCandidate();
LMExecutionOccurence creationExecution = null;
if (firstBracket instanceof LMExecutionOccurence) {
LMExecutionOccurence e = (LMExecutionOccurence)firstBracket;
if (e.isCreationInModel()) {
creationExecution = e;
}
}
setCreationExecution(creationExecution);
}
{
LMLifeLineBracket lastBracket = getDestructionCandidate();
LMExecutionOccurence destructionExecution = null;
if (lastBracket instanceof LMExecutionOccurence) {
LMExecutionOccurence e = (LMExecutionOccurence)lastBracket;
if (e.isDestructionInModel()) {
destructionExecution = e;
}
}
setDestructionExecution(destructionExecution);
}
}
private void setCreationExecution(LMExecutionOccurence creationExecution) {
if (myCreationExecution == creationExecution) {
return;
}
if (myCreationExecution != null) {
myCreationExecution.setCreatedLifeline(null);
}
myCreationExecution = creationExecution;
if (myCreationExecution != null) {
myCreationExecution.setCreatedLifeline(this);
}
}
private void setDestructionExecution(LMExecutionOccurence destructionExecution) {
if (myDestructionExecution == destructionExecution) {
return;
}
if (myDestructionExecution != null) {
assert myBottomPosControoller != null;
myDestructionExecution.setDestructedLifeline(null);
myBottomPosControoller.setLifelineToProvideBottomPos(null);
}
myDestructionExecution = destructionExecution;
if (myDestructionExecution != null) {
myDestructionExecution.setDestructedLifeline(this);
myBottomPosControoller = myDestructionExecution;
LMGenCallOccurence callOccurence = myDestructionExecution;
while (callOccurence != null) {
myBottomPosControoller = callOccurence;
callOccurence = callOccurence.getContainer().getContainingCallOccurence();
}
myBottomPosControoller.setLifelineToProvideBottomPos(this);
}
}
LMLifeLineBracket getCreationCandidate() {
if (getChildBracketsList().isEmpty()) {
return null;
}
LMLifeLineBracket firstBracket = (LMLifeLineBracket) getChildBracketsList().getListView().get(0);
return firstBracket.getCreationCandidate();
}
LMLifeLineBracket getDestructionCandidate() {
if (getChildBracketsList().isEmpty()) {
return null;
}
List listView = getChildBracketsList().getListView();
LMLifeLineBracket lastBracket = (LMLifeLineBracket) listView.get(listView.size()-1);
return lastBracket.getDestructionCandidate();
}
LMGenCallOccurence getContainingCallOccurence() {
return null;
}
LMFrame getContainingFrame() {
return null;
}
int getCreationReceiveEndXPos(boolean toRightNotLeft) {
int centerPos = getGdeNode().getX() + myDetailsLayouter.getCenterRelativePos();
if (toRightNotLeft) {
return centerPos + myDetailsLayouter.getHeadHalfWidth();
} else {
return centerPos - myDetailsLayouter.getHeadHalfWidth();
}
}
public interface DetailsLayouter {
int getHeadPreferredWidth();
int getHeadPreferredHeight();
int getHeadTopPos();
/**
* Sets tail x-position relative to lifeline x-position and width
* of lifeline head. Center position cannot be absolute because it
* should take into account translation of parent figures(i.e.
* interaction).
*/
void setHorizontalPositions(int centerRelativePos, int headHalfWidth);
int getCenterRelativePos();
int getHeadHalfWidth();
}
private SDVerticalLayoutInputImpl.NullFreeIterator verticalLayoutElements() {
return new SDVerticalLayoutInputImpl.NullFreeIteratorForArray(6) {
protected Object get(int pos) {
switch (pos) {
case 0: return myFirstLifeLineElement;
case 1: return myHeadLifeLineElement;
case 2: return getClueValue();
case 3: return new LMBracketContainer.ChildBracketsNFIterator();
case 4: return VerticalClue.LIFE_LINE_TAIL_CLUE;
case 5: return myLastLifeLineElement;
}
throw new IndexOutOfBoundsException();
}
};
}
public LifeLine getVerticalLayoutLifeLine() {
return myVerticalLayoutLifeLine;
}
public String toString() {
EObject nodeEntity = getGdeNode().getModelEntity();
return "LmLL-"+nodeEntity; //$NON-NLS-1$
}
SDVerticalLayoutInputImpl.LifeLineElementGen getFirstLifeLineElement() {
return myFirstLifeLineElement;
}
SDVerticalLayoutInputImpl.LifeLineElementGen getLastLifeLineElement() {
return myLastLifeLineElement;
}
LMLifeLineBracket createChildBracketInstance(AbsNode gdeNode, View reference) {
BracketMetaObject bracketMetaObject = myPseudoMetaObject.getChildBracketMetaObject(reference);
if (bracketMetaObject == null) {
return null;
}
return bracketMetaObject.createChildBracket(gdeNode, getLmOwner());
}
public int getHeadNameWidth() {
int result = myDetailsLayouter.getHeadPreferredWidth();
if (result < GeometryConstants.Lifeline.MINIMUM_HEAD_WIDTH) {
result = GeometryConstants.Lifeline.MINIMUM_HEAD_WIDTH;
}
return result;
}
public int getHeadHeight() {
//GeometryConstants.Lifeline.HEIGHT
return myDetailsLayouter.getHeadPreferredHeight();
}
protected Integer getClueValue() {
return VerticalClue.BRACKET_MAX_CLUE;
}
LMLifeLine getLifeLine() {
return this;
}
SDVerticalLayoutInputImpl.LifeLineElementGen getObjectHorizontalConstraint() {
return myHeadLifeLineElement;
}
/*
public void setX(int x) {
getGdeNode().setX(x);
myHeadElement.setX(x);
}
public void setWidth(int width) {
getGdeNode().setWidth(width);
myHeadElement.setX(getGdeNode().getX());
myHeadElement.setWidth(width);
}
*/
public void setHorizontalPos(int centerPos, int leftHalfWidth, int rightHalfWidth, int headHalfWidth) {
int x = centerPos - leftHalfWidth;
int width = leftHalfWidth + rightHalfWidth;
getGdeNode().setX(x);
getGdeNode().setWidth(width);
getGdeNode().markUserResized();
myDetailsLayouter.setHorizontalPositions(leftHalfWidth, headHalfWidth);
}
public LmBracketsList getChildBracketsList() {
return myChildBracketsList;
}
private int getLifeLineGdeTopPos() {
return getGdeNode().getY();
}
void setLifeLineGdeTopPos(int y) {
getGdeNode().setY(y);
}
private int getLifeLineGdeBottomPos() {
return getGdeNode().getHeight() + getGdeNode().getY();
}
void setLifeLineGdeBottomPos(int y) {
getGdeNode().setHeight(y - getGdeNode().getY());
//{
// int height = y - getLineElement().getY();
// // debug!
// if (height > 10000) {
// throw new RuntimeException("Bad height: "+height);
// }
//}
}
private final SDVerticalLayoutInputImpl.LifeLineElementGen myFirstLifeLineElement;
private final SDVerticalLayoutInputImpl.LifeLineElementGen myLastLifeLineElement;
private final BracketMetaObject myPseudoMetaObject;
private final HeadLifeLineElement myHeadLifeLineElement;
private final DetailsLayouter myDetailsLayouter;
private LMExecutionOccurence myCreationExecution;
private LMExecutionOccurence myDestructionExecution;
private LMGenCallOccurence myBottomPosControoller;
private class HeadLifeLineElement extends SDVerticalLayoutInputImpl.LifeLineElementGen implements LifeLineElement.Position {
public HeadLifeLineElement(int preferredHeight) {
super(0, preferredHeight/*GeometryConstants.Lifeline.HEIGHT + GeometryConstants.Lifeline.UNDER_HEAD_SPACE*/);
}
public int getSize() {
if (myCreationExecution != null) {
return 0;
}
return super.getSize();
}
public int getPositionValue() {
return myDetailsLayouter.getHeadTopPos();
}
public void setPositionValue(int pos) {
}
public boolean isVirtual() {
return true;
}
public LifeLine getLifeLine() {
return getVerticalLayoutLifeLine();
}
public boolean isFirstPrioritedPosition() {
return false;
}
public boolean isLastPrioritedPosition() {
return false;
}
public Position getPosition() {
return this;
}
public String toString() {
return "Lifeline("+LMLifeLine.this+")head"; //$NON-NLS-1$ //$NON-NLS-2$
}
}
private final LmBracketsList myChildBracketsList = new LmBracketsListSimple();
private final LifeLine myVerticalLayoutLifeLine = new LifeLine() {
public LifeLineIterator iterator() {
return new SDVerticalLayoutInputImpl.LifeLineIteratorImpl(verticalLayoutElements());
}
public String toString() {
return "LL:" + LMLifeLine.this; //$NON-NLS-1$
}
};
}