Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » GMF (Graphical Modeling Framework) » Programmatically position external label
Programmatically position external label [message #154679] Wed, 10 October 2007 13:48 Go to next message
Eclipse UserFriend
Originally posted by: rob.wieringa.nxp.com

Hi,

I have an application where I want to add items in a diagran
programatically.
My model contains (named) Tasks which have (named) Ports.
The Ports are 'border' elements of the Task, and have an external Label,
and are either
'in' or 'out' ports.
I succeeded in adding a Task, and the required Ports, including all names.
The 'in' Ports are positioned at the left side of the Task, teh 'out' ones
at the right.

What I want to achieve is to move the label; it appears at the bottom of
the Port by default.
I want it to be to the right of 'in' Ports, to the left of the 'out' Ports.
I found no way to achieve that.


Some code that works:

CompoundCommand cc = new CompoundCommand("Set name");

SetRequest reqSet = new SetRequest(selectedElement.getEditingDomain(),
port, TtlgraphPackage.eINSTANCE.getPort_Id(), name);

SetValueCommand setName = new SetValueCommand(reqSet);
cc.add(new ICommandProxy(setName));

// do it:
selectedElement.getDiagramEditDomain().getDiagramCommandStac k().execute(cc);


I expected I could add something like
cc.add(new ICommandProxy(new SetBoundsCommand(...)));

before executing cc, but I can't find the proper parameters for the
SetBoundsCommand.

Any idea anyone?

Kind regards,

Rob Wieringa
Re: Programmatically position external label [message #156873 is a reply to message #154679] Wed, 24 October 2007 06:54 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: rob.wieringa.nxp.com

Posted this two weeks ago, and still struggeling....
Anyone having an idea how to solve this?

Kind regards,
Rob Wieringa
Re: Programmatically position external label [message #156911 is a reply to message #156873] Wed, 24 October 2007 09:48 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: jan.herriger.gmx.de

Did you try to set PositionConstants in ...EditPart#addBorderItem?

Rob Wieringa schrieb:
> Posted this two weeks ago, and still struggeling....
> Anyone having an idea how to solve this?
>
> Kind regards,
> Rob Wieringa
>
Re: Programmatically position external label [message #157003 is a reply to message #156911] Wed, 24 October 2007 15:23 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: rob.wieringa.nxp.com

Well,

the issue is, that the Port label positioning is not fixed, but depends on
the value of one of the Port's properties.
So I suppose that I cannot overwrite the addBorderItem function

Kind regards,
RobW
Re: Programmatically position external label [message #157051 is a reply to message #157003] Wed, 24 October 2007 19:04 Go to previous message
Eclipse UserFriend
Originally posted by: jan.herriger.gmx.de

This is a multi-part message in MIME format.
--------------070907020104000000000206
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

If I understood your problem, this should be easy.

The label, we are talking about is the port's label, right? Following
should work:

- Open PortEditPart

- change lines in addBorderItem to slt:

....
if (borderItemEditPart instanceof PortLabelEditPart) {
CenteredBorderItemLocator locator = null;
if
(((Port)resolveSemanticElement())
.getName().equals("in")) //or whatever property
locator = new CenteredBorderItemLocator(
getMainFigure(), PositionConstants.WEST);
else
locator = new CenteredBorderItemLocator(
getMainFigure(), PositionConstants.EAST);
locator.setBorderItemOffset(new Dimension(0, 0)); //whatever
borderItemContainer.add(borderItemEditPart.getFigure(), locator);
}
....

- if the position should be dynamic, add lines in handleNotificationEvent:

....
else if (YourPackage.eINSTANCE
.getPort_Name()
.equals(event.getFeature())) {
handleMajorSemanticChange();
}
....

- if you don't want the label to be moveable, go into
createLayoutEditPolicy and change createChildEditPolicy to slt:

....
protected EditPolicy createChildEditPolicy(EditPart child) {
if (child instanceof IBorderItemEditPart) {
BorderItemSelectionEditPolicy ep =
new BorderItemSelectionEditPolicy();
ep.setDragAllowed(false);
return ep;
}
...
}
....


I'm using my own locator, so I attached it.

Regards
Jan

Rob Wieringa schrieb:
> Well,
>
> the issue is, that the Port label positioning is not fixed, but depends
> on the value of one of the Port's properties.
> So I suppose that I cannot overwrite the addBorderItem function
>
> Kind regards,
> RobW
>
>


--------------070907020104000000000206
Content-Type: text/java;
name="CenteredBorderItemLocator.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="CenteredBorderItemLocator.java"

package org.memo.common.parts;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocato r;
import org.eclipse.gmf.runtime.diagram.ui.figures.LayoutHelper;
import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
import org.eclipse.jface.util.Assert;

/**
* Modification of {@link org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator }
* <p>
* Ensures that BorderItem is centered (WEST/EAST: vertically centered,
* NORTH/SOUTH: horizontally centered)
* @see org.eclipse.gmf.runtime.diagram.ui.figures.BorderItemLocator
*/
public class CenteredBorderItemLocator
implements IBorderItemLocator {

/** the figure around which this border item appears */
private IFigure parentFigure = null;

private Rectangle constraint = new Rectangle(0, 0, 0, 0);

private Dimension borderItemOffset = new Dimension(1, 1);

private int preferredSide = PositionConstants.WEST;

private int currentSide = PositionConstants.WEST;

/**
* Accessor to return the constraint location of the border item.
*
* @return the constraint
*/
protected Rectangle getConstraint() {
return constraint;
}

/**
* The preferred side determines placement of figure.
*
* @param parentFigure
*/
public CenteredBorderItemLocator(IFigure parentFigure) {
Assert.isNotNull(parentFigure);
this.parentFigure = parentFigure;
}

/**
* The preferred side determines placement of figure.
*
* @param parentFigure
* @param preferredSide
* the preferred side of the parent figure on which to place this
* border item as defined in {@link PositionConstants}
*/
public CenteredBorderItemLocator(IFigure parentFigure, int preferredSide) {
this(parentFigure);
this.preferredSide = preferredSide;
}

/**
* The preferred location overrides the preferred side.
*
* @param parentFigure
* @param constraint
*/
public CenteredBorderItemLocator(IFigure borderItem, IFigure parentFigure,
Rectangle constraint) {
this(parentFigure);
setConstraint(constraint);
}

/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocato r#resetPosition(org.eclipse.draw2d.geometry.Rectangle)
*/
public void setConstraint(Rectangle theConstraint) {
this.constraint = theConstraint;

if (theConstraint.getTopLeft().x == 0
|| theConstraint.getTopLeft().y == 0) {
setCurrentSideOfParent(getPreferredSideOfParent());
}
getParentFigure().revalidate();
}

/**
* Get the preferred location. If none has been previously set, use the
* preferred side to take an initial guess.
*
* @return point
*/
protected Point getPreferredLocation(IFigure borderItem) {
Point constraintLocation = getConstraint().getLocation();
Point ptAbsoluteLocation = this.getAbsoluteToBorder(constraintLocation);

if (constraintLocation.x == 0 || constraintLocation.y == 0) {
return getPreferredLocation(getPreferredSideOfParent(), borderItem);
} else {
return ptAbsoluteLocation;
}
}

/**
* Utility to calculate the parent bounds with consideration for the handle
* bounds inset.
*
* @return <code>Rectangle</code> that is the bounds of the parent.
*/
protected Rectangle getParentBorder() {
Rectangle bounds = getParentFigure().getBounds().getCopy();
if (getParentFigure() instanceof NodeFigure) {
bounds = ((NodeFigure) getParentFigure()).getHandleBounds()
.getCopy();
}
return bounds;
}

/**
* Get an initial location based on the side. ( choose middle of the side )
*
* @param side
* the preferred side of the parent figure on which to place this
* border item as defined in {@link PositionConstants}
* @return point
*/
protected Point getPreferredLocation(int side, IFigure borderItem) {
Rectangle bounds = getParentBorder();
int parentFigureWidth = bounds.width;
int parentFigureHeight = bounds.height;
int parentFigureX = bounds.x;
int parentFigureY = bounds.y;
int x = parentFigureX;
int y = parentFigureY;

Dimension borderItemSize = getSize(borderItem);

if (side == PositionConstants.WEST) {
x = parentFigureX - borderItemSize.width
+ getBorderItemOffset().width;
y += parentFigureHeight / 2;
} else if (side == PositionConstants.EAST) {
x = parentFigureX + parentFigureWidth - getBorderItemOffset().width;
y += parentFigureHeight / 2;
} else if (side == PositionConstants.NORTH) {
y = parentFigureY - borderItemSize.height
+ getBorderItemOffset().height;
x += parentFigureWidth / 2;
} else if (side == PositionConstants.SOUTH) {
x += parentFigureWidth / 2;
y = parentFigureY + parentFigureHeight
- getBorderItemOffset().height;
}
return new Point(x, y);
}
/**
* Ensure the suggested location actually lies on the parent boundary. The
* side takes precendence.
*
* @param suggestedLocation
* @param suggestedSide
* @return point
*/
private Point locateOnParent(Point suggestedLocation,
int suggestedSide, IFigure borderItem) {


Rectangle bounds = getParentBorder();
int parentFigureWidth = bounds.width;
int parentFigureHeight = bounds.height;
int parentFigureX = bounds.x;
int parentFigureY = bounds.y;
Dimension borderItemSize = getSize(borderItem);
int newX = suggestedLocation.x;
int newY = suggestedLocation.y;
int westX = parentFigureX - borderItemSize.width
+ getBorderItemOffset().width;
int eastX = parentFigureX + parentFigureWidth
- getBorderItemOffset().width;
int middleX = parentFigureX + (parentFigureWidth/2);
int southY = parentFigureY + parentFigureHeight
- getBorderItemOffset().height;
int northY = parentFigureY - borderItemSize.height
+ getBorderItemOffset().height;
int middleY = parentFigureY + (parentFigureHeight/2);
if (suggestedSide == PositionConstants.WEST) {
if (suggestedLocation.x != westX) {
newX = westX;
}
newY = middleY - (borderItemSize.height/2);
} else if (suggestedSide == PositionConstants.EAST) {
if (suggestedLocation.x != eastX) {
newX = eastX;
}
newY = middleY - (borderItemSize.height/2);
} else if (suggestedSide == PositionConstants.SOUTH) {
if (suggestedLocation.y != southY) {
newY = southY;
}
newX = middleX - (borderItemSize.width/2);
} else { // NORTH
if (suggestedLocation.y != northY) {
newY = northY;
}
newX = middleX - (borderItemSize.width/2);
}
return new Point(newX, newY);
}

/**
* The preferred side takes precendence.
*
* @param suggestedLocation
* @param suggestedSide
* @param circuitCount
* recursion count to avoid an infinite loop
* @return point
*/
private Point locateOnBorder(Point suggestedLocation,
int suggestedSide, int circuitCount, IFigure borderItem) {
Point recommendedLocation = locateOnParent(suggestedLocation,
suggestedSide, borderItem);
return recommendedLocation;
}

/**
* Convert the relative coords in the model to ones that are Relative to the
* container (absolute in respect to the main figure)
*
* @param ptRelativeOffset
* @return point
*/
protected Point getAbsoluteToBorder(Point ptRelativeOffset) {
Point parentOrigin = getParentBorder().getTopLeft();
return parentOrigin.translate(ptRelativeOffset);
}

/*
* (non-Javadoc)
*
* @see org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocato r#getValidLocation(org.eclipse.draw2d.geometry.Rectangle,
* org.eclipse.draw2d.IFigure)
*/
public Rectangle getValidLocation(Rectangle proposedLocation,
IFigure borderItem) {
Rectangle realLocation = new Rectangle(proposedLocation);
int side = findClosestSideOfParent(proposedLocation, getParentBorder());
Point newTopLeft = locateOnBorder(realLocation.getTopLeft(), side, 0,
borderItem);
realLocation.setLocation(newTopLeft);
return realLocation;
}

/**
* Find the closest side when x,y is inside parent.
*
* @param proposedLocation
* @param parentBorder
* @return draw constant
*/
public static int findClosestSideOfParent(Rectangle proposedLocation,
Rectangle parentBorder) {
// Rectangle parentBorder = getParentBorder();
Point parentCenter = parentBorder.getCenter();
Point childCenter = proposedLocation.getCenter();
if (childCenter.x < parentCenter.x) // West, North or South.
{
if (childCenter.y < parentCenter.y) // west or north
{
// closer to west or north?
Point parentTopLeft = parentBorder.getTopLeft();
if ((childCenter.x - parentTopLeft.x) <= (childCenter.y - parentTopLeft.y)) {
return PositionConstants.WEST;
} else {
return PositionConstants.NORTH;
}
} else { // west or south
Point parentBottomLeft = parentBorder.getBottomLeft();
if ((childCenter.x - parentBottomLeft.x) <= (parentBottomLeft.y - childCenter.y)) {
return PositionConstants.WEST;
} else {
return PositionConstants.SOUTH;
}
}
} else { // EAST, NORTH or SOUTH
if (childCenter.y < parentCenter.y) // north or east
{
Point parentTopRight = parentBorder.getTopRight();
if ((parentTopRight.x - childCenter.x) <= (childCenter.y - parentTopRight.y)) {
return PositionConstants.EAST;
} else {
return PositionConstants.NORTH;
}
} else { // south or east.
Point parentBottomRight = parentBorder.getBottomRight();
if ((parentBottomRight.x - childCenter.x) <= (parentBottomRight.y - childCenter.y)) {
return PositionConstants.EAST;
} else {
return PositionConstants.SOUTH;
}
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Locator#relocate(org.eclipse.draw2d.IFigu re)
*/
public void relocate(IFigure borderItem) {
Dimension size = getSize(borderItem);
Rectangle rectSuggested = new Rectangle(
getPreferredLocation(borderItem), size);
// int closestSide = findClosestSideOfParent(rectSuggested,
// getParentBorder());
// setPreferredSideOfParent(closestSide);

Point ptNewLocation = locateOnBorder(getPreferredLocation(borderItem),
getPreferredSideOfParent(), 0, borderItem);
borderItem.setLocation(ptNewLocation);
borderItem.setSize(size);

setCurrentSideOfParent(findClosestSideOfParent(new Rectangle(ptNewLocation, size), getParentBorder()));
setCurrentSideOfParent(getPreferredSideOfParent());
}

/**
* getter for the parent figure
*
* @return <code>IFigure</code>
*/
public IFigure getParentFigure() {
return parentFigure;
}

/**
* @return Returns the borderItemOffset.
*/
public Dimension getBorderItemOffset() {
return borderItemOffset;
}

/**
* @param borderItemOffset
* The borderItemOffset to set.
*/
public void setBorderItemOffset(Dimension borderItemOffset) {
this.borderItemOffset = borderItemOffset;
}

/**
* Returns the preferred side of the parent figure on which to place this
* border item.
*
* @return the preferred side of the parent figure on which to place this
* border item as defined in {@link PositionConstants}
*/
public int getPreferredSideOfParent() {
return preferredSide;
}

/**
* Sets the preferred side of the parent figure on which to place this
* border item.
*
* @param preferredSide
* the preferred side of the parent figure on which to place this
* border item as defined in {@link PositionConstants}
*/
public void setPreferredSideOfParent(int preferredSide) {
this.preferredSide = preferredSide;
setCurrentSideOfParent(preferredSide);
}

/* (non-Javadoc)
* @see org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocato r#getSide()
*/
public int getCurrentSideOfParent() {
return currentSide;
}

/**
* Sets the side of the parent figure on which the border item should
* appear.
*
* @param side
* the side on which this border item appears as defined in
* {@link PositionConstants}
*/
public void setCurrentSideOfParent(int side) {
this.currentSide = side;
}

/**
* Gets the size of the border item figure.
* @param borderItem
* @return the size of the border item figure.
*/
protected final Dimension getSize(IFigure borderItem) {
Dimension size = getConstraint().getSize();
if (LayoutHelper.UNDEFINED.getSize().equals(size)) {
size = borderItem.getPreferredSize();
}
return size;
}
}


--------------070907020104000000000206--
Previous Topic:How to remove a guide line from ruler?
Next Topic:TreeStyle routing ?
Goto Forum:
  


Current Time: Thu Nov 27 23:17:15 GMT 2014

Powered by FUDForum. Page generated in 0.02169 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software