Auto-Layout
-
Sunday, May 06, 2012 3:56 PM
I need assistance with auto-layout of some very simple model elements (MELS)
I have top level Domain Class (named ApplicationShell). I have a mapped geometry shape for ApplicationShell (named ApplicationShellShape).
I have embedded relationship from ApplicationShell to a 2nd Domain class (named ApplicationNavigationContainer). I have a mapped geometry shape for ApplicationNavigationContainer (named ApplicationNavigationContainer Shape).
I have a domain property within the ApplicationShell which is a populated combo-box of values and using Change rules I detect when changes are made to this property and then programmatically remove any previous ApplicationNavigationContainer MELs and then create any new ApplicationNaviationContainer MELs based upon the value of the ApplicationShell domain property.
For example in the image below I have 3 related ApplicationNavigationContainer MELs which are automaticity created as part of some logic a Change rule to the ApplicationShell .
Currently all ApplicationNavigationContainerShapes Presentation Elements (PELs) are laid out on top of one another at top left which looks something like this …
My need is that I would like know how to auto-layout the ApplicationNavigationContainerShape PELs (initially only) such that the PEL for the ApplicationShellShape is located top left, and the other ApplicationNavigationContainerShape PELs are laid out to the lower right of the ApplicationShellShape PEL something similar to what is shown below (created manually for illustrative purposes …
What do I need to do to control the layout of these elements? Any assistance is greatly appreciated.
Johnny Larue
- Edited by Johnny Larue Sunday, May 06, 2012 6:25 PM
All Replies
-
Sunday, May 06, 2012 8:02 PM
I managed to figure this out, I hope this helps others ...
Basically, I create a BoundsRule for the ApplicationNavigationContainerShape which is called any time there is a change.
Using the ModelElement of the changed Shape, I locate the container (RootShell) Model Element and from that I get the RootShell Shape.
I create two variables (x and y) from the parent RootShell's Bottom and Right position(s) with a slight offset of 0.2.
Then I rip through the RootShell model element's collection of ApplicationNavigationContainers and calculate a running offset, each time moving the y axis down by the height of each ApplicatonNaviationContainerShape (plus a slight offset of 0.2).
If while processing this loop I happen to find a match to the BoundRule shape then I return the a new RectangleD with the running x and y positions but retain the bounds.
Here is the code ...
#region ApplicationNavigationContainerShape public partial class ApplicationNavigationContainerShape { public override BoundsRules BoundsRules { get { return new ApplicationNavigationContainerShapeBoundsRule(); } } } public class ApplicationNavigationContainerShapeBoundsRule : BoundsRules { public override RectangleD GetCompliantBounds(ShapeElement shape, RectangleD proposedBounds) { var applicationNavigationContainerShape = shape as ApplicationNavigationContainerShape; if (applicationNavigationContainerShape != null) { var applicationNavigationContainer = shape.ModelElement; if (applicationNavigationContainer != null) { var rootShell = applicationNavigationContainer.GetContainer<RootShell>(); if (rootShell != null) { var rootShellShape = shape.Diagram.FindShape(rootShell); if (rootShellShape != null) { var x = rootShellShape.BoundingBox.Right + 0.2; var y = rootShellShape.BoundingBox.Bottom + 0.2; foreach (var childApplicationNavigationContainer in rootShell.ApplicationNavigationContainers) { var childApplicationNaviationContainerShape = shape.Diagram.FindShape(childApplicationNavigationContainer); if (childApplicationNaviationContainerShape == null) continue; if (childApplicationNaviationContainerShape.Equals(applicationNavigationContainerShape)) { return new RectangleD( x, y, proposedBounds.Width, proposedBounds.Height); } y += childApplicationNaviationContainerShape.BoundingBox.Height + 0.2; } } } } } return proposedBounds; } } #endregionJohnny Larue
- Marked As Answer by Johnny Larue Sunday, May 06, 2012 8:05 PM
-
Sunday, May 06, 2012 8:05 PM
I only wish to do this once, so any ideas on how to test for it?
I am thinking that I will assign a hidden boolean property that I test for. Is that the recommended approach?
Johnny Larue

