use of cbit.vcell.graph.SpeciesContextShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method refreshLayoutChildrenFeatureShape.
public void refreshLayoutChildrenFeatureShape(FeatureShape shape) {
// calculate total height and max width of speciesContext (column1)
int scCount = 0;
List<Shape> childShapeList = shape.getChildren();
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof SpeciesContextShape) {
scCount++;
}
}
// calculate total height and max width of Membranes (column2)
int memCount = 0;
int memHeight = 0;
int memWidth = 0;
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
memHeight += child.getSpaceManager().getSize().height;
memWidth = Math.max(memWidth, child.getSpaceManager().getSize().width);
memCount++;
}
}
int centerX = shape.getSpaceManager().getSize().width / 2;
int currentY = shape.getLabelSize().height;
currentY += shape.getLabelSize().height;
int totalSpacingY;
int spacingY;
int extraSpacingY;
int currentX = shape.getSpaceManager().getSize().width / 2 - memWidth / 2;
int spacingX = StructureShape.defaultSpacingX;
// position column2 (membranes)
totalSpacingY = (shape.getSpaceManager().getSize().height - currentY) - memHeight;
if (totalSpacingY < 0) {
LayoutErrorLog.logErrorMessage("unable to fit children within container");
}
spacingY = totalSpacingY / (memCount + 1);
extraSpacingY = totalSpacingY % (memCount + 1);
centerX = currentX + memWidth / 2;
// position children (and label)
int col2Y = currentY + spacingY + extraSpacingY;
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
child.getSpaceManager().setRelPos(centerX - child.getSpaceManager().getSize().width / 2, col2Y);
col2Y += child.getSpaceManager().getSize().height + spacingY;
}
}
if (col2Y != shape.getSpaceManager().getSize().height) {
LayoutErrorLog.logErrorMessage("layout for column2 incorrect (" + shape.getLabel() + "), currentY=" + currentY + ", screenSize.height=" + shape.getSpaceManager().getSize().height);
}
if (memCount > 0) {
currentX += spacingX + memWidth;
}
if (scCount > 0) {
// The following code attempts to position SpeciesContextShapes so that their
// ovals and labels do not overlap other structures
// Calculate Mask of valid area where SpeciesContextShape may render
Area currentOval = new Area(new Ellipse2D.Double(shape.getSpaceManager().getRelX(), shape.getSpaceManager().getRelY(), shape.getSpaceManager().getSize().width, shape.getSpaceManager().getSize().height));
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
Area childArea = new Area(new Ellipse2D.Double(child.getSpaceManager().getRelX() + shape.getSpaceManager().getRelX(), child.getSpaceManager().getRelY() + shape.getSpaceManager().getRelY(), child.getSpaceManager().getSize().width, child.getSpaceManager().getSize().height));
currentOval.subtract(childArea);
}
}
//
// Position SpeciesContextShapes so they and their labels don't overlap other structures.
// If fail, try a few more times with reduced spacing between SpeciesContextShapes to see
// if we can fit
//
final int TOPOFFSET = 20;
boolean bLayoutFailed = false;
int layoutRetryCount = 0;
final int MAX_LAYOUT_RETRY = 3;
int boxSpacingX = 50;
final int X_RETRY_SPACE_REDUCTION = 10;
int boxSpacingY = 30;
final int Y_RETRY_SPACE_REDUCTION = 5;
final int XEND = currentOval.getBounds().x + currentOval.getBounds().width;
final int YEND = currentOval.getBounds().y + currentOval.getBounds().height;
while (true) {
bLayoutFailed = false;
int xCount = 0;
int boxX = 0;
int boxY = 0;
for (int i = 0; i < childShapeList.size(); i++) {
if (childShapeList.get(i) instanceof SpeciesContextShape) {
SpeciesContextShape child = (SpeciesContextShape) childShapeList.get(i);
final int XSTEP = child.getSpaceManager().getSize().width + boxSpacingX;
final int YSTEP = child.getSpaceManager().getSize().height + boxSpacingY;
while ((layoutRetryCount <= MAX_LAYOUT_RETRY && // If last try, don't check labels for overlap
(// away from structure label
boxY <= TOPOFFSET || !currentOval.contains(// SCS label not overlap other structures
boxX + child.getSmallLabelPos().x + currentOval.getBounds().getX(), boxY + child.getSmallLabelPos().y + currentOval.getBounds().getY() - child.getSmallLabelSize().height, child.getSmallLabelSize().width, child.getSmallLabelSize().height))) || !currentOval.contains(// SCS oval not overlap other structures
boxX + currentOval.getBounds().getX(), boxY + currentOval.getBounds().getY(), SpeciesContextShape.DIAMETER, SpeciesContextShape.DIAMETER)) {
if (boxY < YEND) {
boxY += YSTEP;
} else {
boxY = (xCount % 2 == 0 ? TOPOFFSET : TOPOFFSET + SpeciesContextShape.DIAMETER);
boxX += XSTEP;
xCount += 1;
}
if (boxX > XEND && boxY > YEND) {
bLayoutFailed = true;
break;
}
}
if (!bLayoutFailed) {
child.getSpaceManager().setRelPos(boxX, boxY);
boxY += YSTEP;
} else {
break;
}
}
}
if (bLayoutFailed && layoutRetryCount <= MAX_LAYOUT_RETRY) {
boxSpacingX -= X_RETRY_SPACE_REDUCTION;
boxSpacingY -= Y_RETRY_SPACE_REDUCTION;
layoutRetryCount += 1;
} else {
break;
}
}
}
}
use of cbit.vcell.graph.SpeciesContextShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method refreshLayoutChildrenMembraneShape.
public void refreshLayoutChildrenMembraneShape(MembraneShape shape) {
// this is like a row/column layout (1 column)
// find featureShape child
FeatureShape featureShape = null;
for (Shape child : shape.getChildren()) {
if (child instanceof FeatureShape) {
featureShape = (FeatureShape) child;
}
}
// calculate total height of all children (not including label)
// position featureShape (and label)
int centerX = shape.getSpaceManager().getSize().width / 2;
int currentY = MembraneShape.memSpacingY;
if (featureShape != null) {
featureShape.getSpaceManager().setRelPos(centerX - featureShape.getSpaceManager().getSize().width / 2, currentY);
currentY += featureShape.getSpaceManager().getSize().height + MembraneShape.memSpacingY;
}
// position speciesContextShapes
// angle = 0 at north pole and increases counter clockwise
int numSpeciesContexts = shape.countChildren() - 1;
if (numSpeciesContexts > 0) {
double deltaAngle = MembraneShape.TotalAngle / (numSpeciesContexts + 1);
double currentAngle = MembraneShape.BeginAngle + deltaAngle;
for (Shape child : shape.getChildren()) {
if (child instanceof SpeciesContextShape) {
child.getSpaceManager().setRelPos(shape.getRadialPosition(currentAngle));
currentAngle = (currentAngle + deltaAngle) % (2 * Math.PI);
}
}
}
}
use of cbit.vcell.graph.SpeciesContextShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getPreferedSizeReactionContainerShape.
public Dimension getPreferedSizeReactionContainerShape(ReactionContainerShape shape, Graphics2D g) {
// get size when empty
Font origFont = g.getFont();
g.setFont(shape.getLabelFont(g));
try {
Dimension emptySize = shape.getPreferedSizeSelf(g);
// make larger than empty size so that children fit
for (Shape child : shape.getChildren()) {
if (child instanceof ReactionStepShape || child instanceof SpeciesContextShape) {
emptySize.width = Math.max(emptySize.width, child.getSpaceManager().getRelPos().x + child.getSpaceManager().getSize().width);
emptySize.height = Math.max(emptySize.height, child.getSpaceManager().getRelPos().y + child.getSpaceManager().getSize().height);
}
}
emptySize.width = emptySize.width + emptySize.width / 10;
emptySize.height = emptySize.height + emptySize.height / 10;
return emptySize;
} finally {
g.setFont(origFont);
}
}
use of cbit.vcell.graph.SpeciesContextShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getPreferedSizeFeatureShape.
public Dimension getPreferedSizeFeatureShape(FeatureShape shape, Graphics2D g) throws GraphModel.NotReadyException {
Font origfont = g.getFont();
g.setFont(shape.getLabelFont(g));
FontMetrics fm = g.getFontMetrics();
shape.setLabelSize(fm.stringWidth(shape.getLabel()), fm.getMaxAscent() + fm.getMaxDescent());
shape.getLabelPos().x = shape.getSpaceManager().getSize().width / 2 - fm.stringWidth(shape.getLabel()) / 2;
shape.getLabelPos().y = 5 + fm.getMaxAscent();
try {
if (shape.countChildren() > 0) {
int structCount = 0;
int childStructureTotalHeight = shape.getLabelSize().height;
int childStructureMaxWidth = shape.getLabelSize().width;
for (Shape child : shape.getChildren()) {
if (child instanceof StructureShape) {
structCount += 1;
Dimension childDim = getPreferedSize(child, g);
childStructureTotalHeight += childDim.height + StructureShape.defaultSpacingY;
childStructureMaxWidth = Math.max(childStructureMaxWidth, childDim.width);
}
}
int scsCount = 0;
// int childSCTotalHeight = 0;
int childSCMaxWidth = 0;
int childSCMaxHeight = 0;
for (Shape child : shape.getChildren()) {
if (child instanceof SpeciesContextShape) {
scsCount += 1;
Dimension childDim = getPreferedSize(child, g);
childSCMaxHeight = Math.max(childSCMaxHeight, childDim.height + ((SpeciesContextShape) child).getSmallLabelSize().height);
childSCMaxWidth = Math.max(childSCMaxWidth, childDim.width);
childSCMaxWidth = Math.max(childSCMaxWidth, ((SpeciesContextShape) child).getSmallLabelSize().width);
}
}
Dimension box = new Dimension();
if (scsCount != 0) {
int squareBoxX = (int) Math.ceil(Math.sqrt(scsCount));
int squareBoxY = squareBoxX - (int) (((squareBoxX * squareBoxX) % scsCount) / (double) squareBoxX);
int width1 = (squareBoxX * (childSCMaxWidth + 0));
// + defaultSpacingX;
int height1 = (squareBoxY * (childSCMaxHeight + 30));
// + defaultSpacingY;
box = new Dimension(width1, height1);
}
if (structCount == 0) {
shape.getSpaceManager().setSizePreferred((box.width + StructureShape.defaultSpacingX * 2), (box.height + StructureShape.defaultSpacingY * 2));
} else {
shape.getSpaceManager().setSizePreferred((childStructureMaxWidth + box.width + StructureShape.defaultSpacingX * 2), (Math.max(childStructureTotalHeight, box.height) + StructureShape.defaultSpacingY * 2));
}
} else {
shape.getSpaceManager().setSizePreferred((shape.getLabelSize().width + StructureShape.defaultSpacingX * 2), (shape.getLabelSize().height + StructureShape.defaultSpacingY * 2));
}
return shape.getSpaceManager().getSizePreferred();
} finally {
g.setFont(origfont);
}
}
use of cbit.vcell.graph.SpeciesContextShape in project vcell by virtualcell.
the class GraphContainerLayoutReactions method getPreferedSizeReactionContainerShape.
public Dimension getPreferedSizeReactionContainerShape(ReactionContainerShape shape, Graphics2D g) {
// get size when empty
Font origFont = g.getFont();
g.setFont(shape.getLabelFont(g));
try {
Dimension preferredSize = shape.getPreferedSizeSelf(g);
// make larger than empty size so that children fit
for (Shape child : shape.getChildren()) {
if (child instanceof ReactionStepShape || child instanceof SpeciesContextShape || child instanceof RuleParticipantSignatureFullDiagramShape || child instanceof RuleParticipantSignatureShortDiagramShape || child instanceof ReactionRuleDiagramShape) {
preferredSize.width = Math.max(preferredSize.width, child.getSpaceManager().getRelPos().x + child.getSpaceManager().getSize().width);
preferredSize.height = Math.max(preferredSize.height, child.getSpaceManager().getRelPos().y + child.getSpaceManager().getSize().height);
}
}
preferredSize.width = preferredSize.width + WIDTH_PADDING;
preferredSize.height = preferredSize.height + HEIGHT_PADDING;
Structure structure = shape.getStructure();
int minWidthSum = 0;
for (Structure structure2 : shape.getStructureSuite().getStructures()) {
if (structure2 instanceof Feature) {
minWidthSum += FEATURE_MIN_WIDTH;
} else {
minWidthSum += MEMBRANE_MIN_WIDTH;
}
}
int compartmentMinWidth = 0;
if (structure instanceof Feature) {
compartmentMinWidth = FEATURE_MIN_WIDTH;
} else {
compartmentMinWidth = MEMBRANE_MIN_WIDTH;
}
int apportionedWidth = compartmentMinWidth * TOTAL_MIN_WIDTH / minWidthSum;
if (preferredSize.width < compartmentMinWidth) {
preferredSize.width = compartmentMinWidth;
}
if (preferredSize.width < apportionedWidth) {
preferredSize.width = apportionedWidth;
}
if (preferredSize.height < MIN_HEIGHT) {
preferredSize.height = MIN_HEIGHT;
}
return preferredSize;
} finally {
g.setFont(origFont);
}
}
Aggregations