| Summary: | [visualizer] Add a new graphic object class supporting nesting, virtual bounds and automatic scaling | ||
|---|---|---|---|
| Product: | [Tools] CDT | Reporter: | Marc Dumais <marc.dumais> |
| Component: | cdt-other | Assignee: | Marc Dumais <marc.dumais> |
| Status: | RESOLVED FIXED | QA Contact: | Doug Schaefer <cdtdoug> |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | WilliamRSwanson, xraynaud |
| Version: | Next | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 432055, 432908 | ||
|
Description
Marc Dumais
Here is a simple example with one container that has 2 child objects, once of which has a child itself. Let's say we create the objects using the following virtual bounds:
parent virtual bounds: (0,0,10,10)
child1 virtual bounds: (1,1,3,3)
grandchild1 virtual bounds: (1,1,1,1) note: (x,y)=(1,1) are relative to parent. Relative to grand-parent, it's really (2,2)
child2 virtual bounds: (8,8,1,1)
Let's say this is to be displayed on a canvas of pixel-dimensions 100x100, which is set as the (w,h) bounds of the parent object.
The objects will end-up with the following canvas bounds:
parent canvas bounds: (0,0,100,100)
child1 canvas bounds: (10,10,30,30)
grandchild1 canvas bounds: (20,20,10,10)
child2 canvas bounds: (80,80,10,10)
If the canvas is re-sized to 200x200, which is set as the (w,h) bounds of the parent object, the objects will be re-sized to the following canvas-bounds:
parent canvas bounds: (0,0,200,200)
child1 canvas bounds: (20,20,60,60)
grandchild1 canvas bounds: (40,40,20,20)
child2 canvas bounds: (160,160,20,20)
Gerrit review: https://git.eclipse.org/r/#/c/25079/ Xavier asked a question on the gerrit page for this bug: "Hummm.... just a naive question: are we re-inventing draw2d ?" I hope not. I have stumbled upon draw2d sometime last fall, before starting this effort. I did a quick investigation and came out unsure if it would be a gain to use it compared to implementing the relatively small enhancements I needed for the Epiphany visualizer. Xavier, do you have experience using draw2d? Do you know if it's used already anywhere in CDT? Yes, I've some experience using drawd2. It is used in Kalray products: https://www.flickr.com/photos/109313425@N06/12655277894/ As you can see, it's very close to the multicore visualizer. As far as I know, draw2d is not used in CDT ("git grep draw2d" returns nothing). Thanks Xavier. The screenshot does looks a lot like the Epiphany Visualizer. From what you know, would it be relatively easy to use draw2d in the visualizer framework? It would be interesting to see a quick and dirty proof-of-concept of this idea. I think so. It should be relatively easy. I can try to do a proof-of-concept. However, I'm a bit busy these days - much more than last month. I can't make any promise. Working on bug 432908, I have noticed a few things to improve with the VirtualBoundsGraphicObject class. I will be pushing a new patch to address them: - I noticed an integration issue with GraphicCanvas#paintCanvas(). This class does two separate calls per graphic object: one to paint an object and a second one to paint the object's decorations, if the object reports having decorations. This doesn't work well with a VirtualBoundsGraphicObject that has no decoration, but has child object(s) that does; the decoration(s) are not be painted. I tried a few things to fix this, but none were totally satisfactory. The solution I ended-up with fixes the issue, but the ability to chose to paint the decorations separately of the object is lost. That seems a worthy trade-off, but open to suggestions. - Added a null check in VirtualBoundsGraphicObject#paint() before restoring the background/foreground color, to avoid an exception if restoring a null color. - It seems a bit strange that, by default, a VirtualBoundsGraphicObject is created with its bounds set to not being drawn (i.e. setDrawContainerBounds(false)). I think it feels more natural to do the opposite. - Added a setter to permit setting the margin to be used between a child and parent object, and renamed the field to better reflect its use. (In reply to Marc Dumais from comment #7) > > - I noticed an integration issue with GraphicCanvas#paintCanvas(). This > class does two separate calls per graphic object: one to paint an object and > a second one to paint the object's decorations, if the object reports having > decorations. This doesn't work well with a VirtualBoundsGraphicObject that > has no decoration, but has child object(s) that does; the decoration(s) are > not be painted. > I tried a few things to fix this, but none were totally satisfactory. The > solution I ended-up with fixes the issue, but the ability to chose to paint > the decorations separately of the object is lost. That seems a worthy > trade-off, but open to suggestions. Could you describe the issue(s) you encountered? My first thought is to have the parent graphic object report the logical-OR of its own hasDecorations() state and that of its direct children, and then, when the decorations need to be painted, simply delegate to its direct child objects' decoration methods even when it has no decorations of its own. If a child has nothing to draw, the parent could optimize by checking hasDecorations() on the child, or the child's decoration code could simply be a no-op that doesn't mind if it's called. Hi Bill, (In reply to William Swanson from comment #8) > > Could you describe the issue(s) you encountered? My first thought is > to have the parent graphic object report the logical-OR of its own > hasDecorations() state and that of its direct children, and then, > when the decorations need to be painted, simply delegate to its direct > child objects' decoration methods even when it has no decorations > of its own. If a child has nothing to draw, the parent could optimize > by checking hasDecorations() on the child, or the child's decoration > code could simply be a no-op that doesn't mind if it's called. Something very close to what you describe was my first though as well. The only change I had to do to get this to work was to override method VirtualBoundsGraphicObject#hasDecorations() so that it goes though its children; if any one of them has decorations, the parent returns true. The painting part, delegating the painting of decorations to each children object, was already working as you describe above (i.e. nothing further to do for that to work). The downside I saw of this way of fixing the issue is that a derived class can override VirtualBoundsGraphicObject#hasDecorations() in a parent object, possibly breaking the mechanism. (only a problem I think if the overriding method returns false and has children with decorations). I will push a new patch with that alternative version of the fix instead so you can have a look. You can tell me if you like one better than the other or have other ideas. Thanks! Marc (In reply to Marc Dumais from comment #9) > > The downside I saw of this way of fixing the issue is that a derived class > can override VirtualBoundsGraphicObject#hasDecorations() in a parent object, > possibly breaking the mechanism. (only a problem I think if the overriding > method returns false and has children with decorations). The new version (Patch #9) looks good to me. You should add a javadoc comment to the hasDecorations() override noting the recusive check of the children as behavior that a derived type will want to preserve. You might also put the child-check loop in its own method (e.g. hasChildrenWithDecorations()) just to make it blindingly obvious to someone who wants to override the method. Merged into master branch. |