Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Graphiti » How to overlay images
How to overlay images [message #654961] Thu, 17 February 2011 18:51 Go to next message
Shenxue Zhou is currently offline Shenxue Zhou
Messages: 50
Registered: July 2009
Member
I use an image and some text to represent nodes in my diagram. I need to add some background image to my nodes when certain condition is true. The background image is larger than the regular node image. But I don't want to change the selection bounding box for the node when the background image is added.

I tried to use negative coordinates for the background image but that image gets clipped by the node bounding box.

Is it possible in Graphiti to render images outside of the node bounding box? Also, if I have multiple images for a node, what's the order in Graphiti to render those images?

Thank you!
Re: How to overlay images [message #655059 is a reply to message #654961] Fri, 18 February 2011 08:22 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1618
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Any graphics algorithm is always clipped at its parent's borders, so it is
not possible to render an image outside of its bounding box. Have you
throught about using some kind of ghost shape? To do that, place an
(invisible?) rectangle around your box that holds the image and add your
original box inside.

The rendering order is determined by the ordering inside the children
releationship: children will be rendered in the order they are contained
there.

Michael
Re: How to overlay images [message #655266 is a reply to message #655059] Fri, 18 February 2011 21:31 Go to previous messageGo to next message
Shenxue Zhou is currently offline Shenxue Zhou
Messages: 50
Registered: July 2009
Member
Michael,

I tried your suggestion and added an invisible rectangle to hold my background image. It worked very well. The selection bounding box of my node didn't include the background image.

Thank you!

Shenxue
Re: How to overlay images [message #658683 is a reply to message #655266] Wed, 09 March 2011 13:18 Go to previous messageGo to next message
Jan Schoubo is currently offline Jan Schoubo
Messages: 13
Registered: May 2010
Location: Stilling, Denmark
Junior Member
Shenxue, Michael,

Would any of you have a snippet of code illustrating this?
I have a similar issue (*), and no matter how I combine
the Containers and Rectangles, I always get the clipping?

Help much appreciated, Jan

(*) Not image, but need to draw a few lines outside the selection bounding box...







Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #658702 is a reply to message #658683] Wed, 09 March 2011 14:28 Go to previous messageGo to next message
Jan Schoubo is currently offline Jan Schoubo
Messages: 13
Registered: May 2010
Location: Stilling, Denmark
Junior Member
Hi,

This is as far as I have gotten - I can draw outside the selection bounding box,
by creating a Shape attached to the Diagram, not the Containing Shape. But then if I move the element, the Shape does not move along.

Any suggestions would be much appreciated.

- Jan


  @Override public PictogramElement add(IAddContext context)
  {
    (...)
    ContainerShape containerShape = peCreateService.createContainerShape(targetDiagram, true);


    // Containing rectangle
    Rectangle rectangle = gaService.createInvisibleRectangle(containerShape);
    rectangle.setFilled(false);  rectangle.setLineVisible(false);
    gaService.setLocationAndSize(rectangle, x, y, w, h);
    link(containerShape, bo);

    // Drawing within selection bounding box - is cropped
    Shape shape = peCreateService.createShape(containerShape, false);
    Polyline polyline = gaService.createPolyline(shape, ...);
    link(shape, bo);

    // Drawing outside the selection bounding box - is shown, but not moved
    Shape shape2 = peCreateService.createShape(getDiagram(), true);
    Polyline polyline = gaService.createPolyline(shape2, ...);
    gaService.setLocation(shape2.getGraphicsAlgorithm(), x-20, y-20);
    link(shape2, bo);

    layoutPictogramElement(containerShape);    

    return containerShape;
  }



Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #658732 is a reply to message #658702] Wed, 09 March 2011 15:55 Go to previous messageGo to next message
Michael Wenz is currently offline Michael Wenz
Messages: 1618
Registered: July 2009
Location: Walldorf, Germany
Senior Member
Jan,

you should create the outer shape as a parent of the outer ContainerShape
(the one that is "visualized" using the invisible rectangle) not the
diagram. This way the shape belongs to the object, in your implementation
the shape is simply another root element.

Michael

"Jan Schoubo" wrote in message news:il82dh$7dd$1@news.eclipse.org...

Hi,

This is as far as I have gotten - I can draw outside the selection bounding
box,
by creating a Shape attached to the Diagram, not the Containing Shape. But
then if I move the element, the Shape does not move along.

Any suggestions would be much appreciated.

- Jan



@Override public PictogramElement add(IAddContext context)
{
(...)
ContainerShape containerShape =
peCreateService.createContainerShape(targetDiagram, true);


// Containing rectangle
Rectangle rectangle =
gaService.createInvisibleRectangle(containerShape);
rectangle.setFilled(false); rectangle.setLineVisible(false);
gaService.setLocationAndSize(rectangle, x, y, w, h);
link(containerShape, bo);

// Drawing within selection bounding box - is cropped
Shape shape = peCreateService.createShape(containerShape, false);
Polyline polyline = gaService.createPolyline(shape, ...);
link(shape, bo);

// Drawing outside the selection bounding box - is shown, but not moved
Shape shape2 = peCreateService.createShape(getDiagram(), true);
Polyline polyline = gaService.createPolyline(shape2, ...);
gaService.setLocation(shape2.getGraphicsAlgorithm(), x-20, y-20);
link(shape2, bo);

layoutPictogramElement(containerShape);

return containerShape;
}


--
Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #658787 is a reply to message #658732] Wed, 09 March 2011 18:54 Go to previous messageGo to next message
Shenxue Zhou is currently offline Shenxue Zhou
Messages: 50
Registered: July 2009
Member
I modified TutorialAddEClassFeature to illustrate the use of the background image. Here is the code and hope it helps:

[CODE]
public PictogramElement add(IAddContext context)
{
final EClass addedClass = (EClass) context.getNewObject();
final Diagram targetDiagram = (Diagram) context.getTargetContainer();

final IPeCreateService peCreateService = Graphiti.getPeCreateService();
final ContainerShape containerShape = peCreateService.createContainerShape(targetDiagram, true);

// check whether the context has a size (e.g. from a create feature)
// otherwise define a default size for the shape
final int width = context.getWidth() <= 0 ? 65 : context.getWidth();
final int height = context.getHeight() <= 0 ? 90 : context.getHeight();

final IGaService gaService = Graphiti.getGaService();

final Rectangle invisibleRectangle = gaService.createInvisibleRectangle(containerShape);
gaService.setLocationAndSize(invisibleRectangle, context.getX(), context.getY(), width + INVISIBLE_RECT_EXTRA_WIDTH,
height + INVISIBLE_RECT_EXTRA_HEIGHT);

// add the background image to the ghost shape
Shape ghostShape = peCreateService.createShape(containerShape, false);
Image bgImage = gaService.createImage(ghostShape, TutorialImageProvider.IMG_ECLASS_BG);
gaService.setLocationAndSize(bgImage, 0, 0, 105, 102);

// create a rectangle to hold the node image
int offsetX = INVISIBLE_RECT_EXTRA_WIDTH / 2;
int offsetY = INVISIBLE_RECT_EXTRA_HEIGHT;

Rectangle rectangle = gaService.createRectangle(invisibleRectangle);
rectangle.setParentGraphicsAlgorithm(invisibleRectangle);
rectangle.setFilled(false);
rectangle.setLineVisible(false);
gaService.setLocationAndSize(rectangle, offsetX, offsetY, width, height);

Shape imageShape = peCreateService.crfinal int height = context.getHeight() <= 0 ? 90 : context.getHeight();

final IGaService gaService = Graphiti.getGaService();

final Rectangle invisibleRectangle = gaService.createInvisibleRectangle(containerShape);
gaService.setLocationAndSize(invisibleRectangle, context.getX(), context.getY(), width + INVISIBLE_RECT_EXTRA_WIDTH,
height + INVISIBLE_RECT_EXTRA_HEIGHT);

// add the background image to the ghost shape
Shape ghostShape = peCreateService.createShape(containerShape, false);
Image bgImage = gaService.createImage(ghostShape, TutorialImageProvider.IMG_ECLASS_BG);
gaService.setLocationAndSize(bgImage, 0, 0, 105, 102);

// create a rectangle to hold the node image
int offsetX = INVISIBLE_RECT_EXTRA_WIDTH / 2;
int offsetY = INVISIBLE_RECT_EXTRA_HEIGHT;

Rectangle rectangle = gaService.createRectangle(invisibleRectangle);
rectangle.setParentGraphicsAlgorithm(invisibleRectangle);
rectangle.setFilled(false);
rectangle.setLineVisible(false);
gaService.setLocationAndSize(rectangle, offsetX, offsetY, width, height);

Shape imageShape = peCreateService.createShape(containerShape, false);
Image nodeImage = gaService.createImage(imageShape, TutorialImageProvider.IMG_ECLASS);

gaService.setLocationAndSize(nodeImage, offsetX, offsetY, 65, 71);

if (addedClass.eResource() == null)
{
getDiagram().eResource().getContents().add(addedClass);
}
// create link and wire it
link(
Re: How to overlay images [message #658792 is a reply to message #658732] Wed, 09 March 2011 19:27 Go to previous messageGo to next message
Jan Schoubo is currently offline Jan Schoubo
Messages: 13
Registered: May 2010
Location: Stilling, Denmark
Junior Member
Michael,

Thanks, I have tried following your suggestion, by putting an extra ContainerShape between the diagram and the drawing shapes:

    ContainerShape outercontainerShape = peCreateService.createContainerShape(targetDiagram, true);
    ContainerShape containerShape = peCreateService.createContainerShape(outercontainerShape, false);


Now I can draw my "real" symbol in the inner container, and the "extras" in the outer,
cropping now works, and the whole drawing moves as one when I drag it,

However, when I click on any line - "real" or "extra" - I select the element, and the bounding box shows the outer limit. I would like the selection to be only "live" for the "real" part - and I think that is what Shenxue's code tries to show.

Shenxue,

Thanks for the sample, but it was garbled (probably a paste too many)?
Can you repost?

Many thanks to you both!


Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #658812 is a reply to message #658792] Wed, 09 March 2011 21:30 Go to previous messageGo to next message
Shenxue Zhou is currently offline Shenxue Zhou
Messages: 50
Registered: July 2009
Member
You can change the selection bounding box for a node by overriding getSelectionBorder() method in your tool behavior provider. The EClass tutorial sample had an example of it:

	
@Override
	public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) {
		IFeatureProvider featureProvider = getFeatureProvider();
		Object bo = featureProvider.getBusinessObjectForPictogramElement(pe);
		if (bo instanceof EClass) {
			GraphicsAlgorithm invisible = pe.getGraphicsAlgorithm();
			EList<GraphicsAlgorithm> graphicsAlgorithmChildren = invisible.getGraphicsAlgorithmChildren();
			if (!graphicsAlgorithmChildren.isEmpty()) {
				return graphicsAlgorithmChildren.get(0);
			}
		}
		return super.getSelectionBorder(pe);
	}


The code I pasted earlier was cut off. Here is the code being cut off:
		Shape imageShape = peCreateService.createShape(containerShape, false);		
		Image nodeImage = gaService.createImage(imageShape, TutorialImageProvider.IMG_ECLASS);
		
		gaService.setLocationAndSize(nodeImage, offsetX, offsetY, 65, 71);
    	
		if (addedClass.eResource() == null) 
		{
			getDiagram().eResource().getContents().add(addedClass);
		}
		// create link and wire it
		link(containerShape, addedClass);
		
		// SHAPE WITH TEXT
		{
			// create shape for text
			final Shape textShape = peCreateService.createShape(containerShape, false);

			// create and set text graphics algorithm
			final Text text = gaService.createText(textShape, addedClass.getName());
			
			text.setStyle(StyleUtil.getStyleForEClassText(getDiagram()));
			text.setHorizontalAlignment(Orientation.ALIGNMENT_CENTER);
			text.setVerticalAlignment(Orientation.ALIGNMENT_CENTER);
			gaService.setLocationAndSize(text, offsetX , offsetY + 70, width, 20);

			// create link and wire it
			link(textShape, addedClass);
		}

		// add a chopbox anchor to the shape
		peCreateService.createChopboxAnchor(containerShape);
		
		return containerShape;
Re: How to overlay images [message #659065 is a reply to message #658812] Thu, 10 March 2011 20:47 Go to previous messageGo to next message
Jan Schoubo is currently offline Jan Schoubo
Messages: 13
Registered: May 2010
Location: Stilling, Denmark
Junior Member
Thanks Michael, Shenxue,

I can now get exactly the visual appearance I want (with cleaner code), but I still miss the smaller selection box - it keeps showing the "full" box, corresponding to the top-level ContainerShape based on the targetDiagram.

Below are the main parts of the add() routine and the getSelectionBorder of the ToolBehaviourProvider.

The log from a typical run always print:
getSelectionBorder
    Is Track...
      GA: 140x140 at x,y     (which corresponds to the outer box size)

but never the follow-on "Has children", which indicates that my
pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren() has no children?

I am probably missing something obvious?

Is there any utility method to dump out the while Pictogram/GraphicsAlgorithm structure in an understandable format?

- Jan

    ....
    ContainerShape containerShape = peCreateService.createContainerShape(targetDiagram, true);
    link(containerShape, businessobject);

    // Containing rectangle
    Rectangle outerRectangle = gaService.createInvisibleRectangle(containerShape);
    outerRectangle.setFilled(false);
    outerRectangle.setLineVisible(false);
    gaService.setLocationAndSize(outerRectangle, ...);

    
    ContainerShape innerContainerShape = peCreateService.createContainerShape(containerShape, false);
    
    // Selection box
    Rectangle innerRectangle = gaService.createInvisibleRectangle(innerContainerShape);
    innerRectangle.setFilled(false);
    innerRectangle.setLineVisible(false);
    gaService.setLocationAndSize(innerRectangle, ...);
    
    
    // Visible lines in the element
    Polyline polyline = gaService.createPolyline(innerRectangle, new int[]{...});

    // Visible lines outside the element
    Polyline polyline = gaService.createPolyline(containerShape, new int[]{...});
    // also tried    = gaService.createPolyline(outerRectangle, new int[]{...});
    
    
    gaService.setLocationAndSize(containerShape.getGraphicsAlgorithm(), ...);

    businessobject.setX(...);
    businessobject.setY(...);


  @Override
  public GraphicsAlgorithm getSelectionBorder(PictogramElement pe) 
  {
    System.out.println("getSelectionBorder");

    IFeatureProvider featureProvider = getFeatureProvider();
    Object bo = featureProvider.getBusinessObjectForPictogramElement(pe);
    if (bo instanceof Track) 
    {
      System.out.println("  Is Track...");
      
      GraphicsAlgorithm outerElement = pe.getGraphicsAlgorithm();
      
      System.out.println("    GA: "+outerElement.getWidth()+"x"+outerElement.getHeight()+" at "+outerElement.getX()+","+outerElement.getY());
      
      EList<GraphicsAlgorithm> graphicsAlgorithmChildren = outerElement.getGraphicsAlgorithmChildren();
      if (!graphicsAlgorithmChildren.isEmpty()) 
      {
        System.out.println("    Has children...");
        GraphicsAlgorithm innerElement = graphicsAlgorithmChildren.get(0);
        return innerElement;
      }
    }
    return super.getSelectionBorder(pe);
  }


Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #659085 is a reply to message #659065] Thu, 10 March 2011 22:35 Go to previous messageGo to next message
Shenxue Zhou is currently offline Shenxue Zhou
Messages: 50
Registered: July 2009
Member
You created two container shapes in your add() method. I don't think you need two container shapes. Instead, remove the creation of the second container shape. And create your selection rectangle this way:

Rectangle innerRectangle = gaService.createRectangle(outerRectangle);
		innerRectangle.setParentGraphicsAlgorithm(outerRectangle);    	


Then your getSelectionBorder() method in your tool behavior class will work.
Re: How to overlay images [message #659137 is a reply to message #659085] Fri, 11 March 2011 08:56 Go to previous messageGo to next message
Jan Schoubo is currently offline Jan Schoubo
Messages: 13
Registered: May 2010
Location: Stilling, Denmark
Junior Member
That did it! Beautiful, thanks Shenxue!

setParentGraphicsAlgorithm(), eh?
I had assumed that ch = gaService.createRectangle(pr) would automatically make ch a child of pr...
I need to understand the relationship between GraphicsAlgorithm and PictogramElement better.

Thanks again for the help. I am growing very fond of Graphiti Smile

- Jan



Jan Schoubo, schoubo reasoning
Re: How to overlay images [message #659175 is a reply to message #659065] Fri, 11 March 2011 11:48 Go to previous message
Michael Wenz is currently offline Michael Wenz
Messages: 1618
Registered: July 2009
Location: Walldorf, Germany
Senior Member
You can switch on a generic outline for your diagram showing all graphical
elements in their nesting structure. Simply setin the Eclipse preferences
under "Graphiti Test Preferences" the flag "Use generic outline view". This
requires the examples common plugiin installed.

Michael


"Jan Schoubo" wrote in message news:ilbd16$nrc$1@news.eclipse.org...

Thanks Michael, Shenxue,

I can now get exactly the visual appearance I want (with cleaner code), but
I still miss the smaller selection box - it keeps showing the "full" box,
corresponding to the top-level ContainerShape based on the targetDiagram.

Below are the main parts of the add() routine and the getSelectionBorder of
the ToolBehaviourProvider.

The log from a typical run always print:

getSelectionBorder
Is Track...
GA: 140x140 at x,y (which corresponds to the outer box size)

but never the follow-on "Has children", which indicates that my
pe.getGraphicsAlgorithm().getGraphicsAlgorithmChildren() has no children?

I am probably missing something obvious?

Is there any utility method to dump out the while
Pictogram/GraphicsAlgorithm structure in an understandable format?

- Jan


....
ContainerShape containerShape =
peCreateService.createContainerShape(targetDiagram, true);
link(containerShape, businessobject);

// Containing rectangle
Rectangle outerRectangle =
gaService.createInvisibleRectangle(containerShape);
outerRectangle.setFilled(false);
outerRectangle.setLineVisible(false);
gaService.setLocationAndSize(outerRectangle, ...);


ContainerShape innerContainerShape =
peCreateService.createContainerShape(containerShape, false);

// Selection box
Rectangle innerRectangle =
gaService.createInvisibleRectangle(innerContainerShape);
innerRectangle.setFilled(false);
innerRectangle.setLineVisible(false);
gaService.setLocationAndSize(innerRectangle, ...);


// Visible lines in the element
Polyline polyline = gaService.createPolyline(innerRectangle, new
int[]{...});

// Visible lines outside the element
Polyline polyline = gaService.createPolyline(containerShape, new
int[]{...});
// also tried = gaService.createPolyline(outerRectangle, new
int[]{...});


gaService.setLocationAndSize(containerShape.getGraphicsAlgor ithm(),
....);

businessobject.setX(...);
businessobject.setY(...);



@Override
public GraphicsAlgorithm getSelectionBorder(PictogramElement pe)
{
System.out.println("getSelectionBorder");

IFeatureProvider featureProvider = getFeatureProvider();
Object bo = featureProvider.getBusinessObjectForPictogramElement(pe);
if (bo instanceof Track)
{
System.out.println(" Is Track...");

GraphicsAlgorithm outerElement = pe.getGraphicsAlgorithm();

System.out.println(" GA:
"+outerElement.getWidth()+"x"+outerElement.getHeight()+" at
"+outerElement.getX()+","+outerElement.getY());

EList<GraphicsAlgorithm> graphicsAlgorithmChildren =
outerElement.getGraphicsAlgorithmChildren();
if (!graphicsAlgorithmChildren.isEmpty())
{
System.out.println(" Has children...");
GraphicsAlgorithm innerElement = graphicsAlgorithmChildren.get(0);
return innerElement;
}
}
return super.getSelectionBorder(pe);
}

--
Jan Schoubo, schoubo reasoning
Previous Topic:Pasting Near The Mouse Pointer
Next Topic:Text versus MultiText
Goto Forum:
  


Current Time: Fri Oct 24 10:28:45 GMT 2014

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

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