Book a Demo

Author Topic: Help - UML Types and shapescripts ...  (Read 6914 times)

matthew.james

  • EA User
  • **
  • Posts: 155
  • Karma: +8/-3
  • Am I supposed to say something here ... ?
    • View Profile
Help - UML Types and shapescripts ...
« on: July 13, 2018, 11:55:07 am »
Ok - so I'd like to use a Boundary (common elements) but with left aligned text rather than centre aligned.  I can't find a way to do this so I thought I'd try a shapescript with UML Types. (Or, if anyone knows of a standard way to left align text in boundaries please let me know !).

However - if I go through UML Types I can't find Boundary as a Base Class ...
(I do admit I am still quite mystified by the underlying Sparx model in terms of classes vs types vs meta-types etc - sometimes these terms seem to be used inter-changably)

Here's what I know:
- There is an archimate element (Archimate_Grouping) which has a left aligned text label controlled by the shapescript
- This element is defined (in the MDG) as metatype "Grouping" and 'Applies To' type "Boundary"
- If I remove the archimate stereotype from such an element it changes 'Type' from "Grouping" to "Boundary"
--> I should be able create something, based on Boundary but with left aligned text using a shapescript (I don't want to use the archimate grouping element as I don't want the 'package' style shape it has)

However if I go into UML Types the 'Base Class' (?) list doesn't include boundary as a class / type.  So what am I missing?
Can I do what I am seeking to do with UML Types?  If not is this something special about Boundary or generally not something that should work?


KP

  • EA Administrator
  • EA Expert
  • *****
  • Posts: 2919
  • Karma: +55/-3
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #1 on: July 13, 2018, 12:18:13 pm »
Just type boundary in the Base Class combo.
The Sparx Team
[email protected]

matthew.james

  • EA User
  • **
  • Posts: 155
  • Karma: +8/-3
  • Am I supposed to say something here ... ?
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #2 on: July 16, 2018, 10:36:03 am »
Just type boundary in the Base Class combo.
Thanks - type in "boundary" and it works fine (so is "boundary" a 'type' or a 'class'?  Is there a reason it's not in the default list?)

Next challenge is the left aligned text using a shapescript.  After looking at other scripts and much experimentation I found that this gave me most of what I was after - ie a boundary shape that looks and behaves like the standard one, but with left aligned text:
Code: [Select]
shape main
{
drawnativeshape();
print("#name#");
}

However I have two outstanding issues ...
1) The element name is now displayed twice, once by the drawnativeshape() and then again by the print() I added.  How can I suppress the label provided by the drawnativeshape()?
2) Is there a way with boundaries to set the "Boundary Style", from the default of "Solid - No Fill" to "Solid"?

matthew.james

  • EA User
  • **
  • Posts: 155
  • Karma: +8/-3
  • Am I supposed to say something here ... ?
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #3 on: July 16, 2018, 11:41:00 am »
1) The element name is now displayed twice, once by the drawnativeshape() and then again by the print() I added.  How can I suppress the label provided by the drawnativeshape()?
Ok - I fixed this one.  I can get away without the drawnativeshape() in this case as it is a simple shape, just replaced with a rectangle.  I'm still getting the boundary grouping behaviour I was after - so good.

2) Is there a way with boundaries to set the "Boundary Style", from the default of "Solid - No Fill" to "Solid"?
Still looking for an answer to this one ...
Interestingly the change above (ie not using drawnativeshape) results in a filled element - despite that "Solid - No Fill" style setting, so there must be something in the default element rendering that implements the 'no fill' part to make a standard boundary element un-filled. However, fill colour changes are still ignored by the element until the boundary style is changed to "Solid", so there must be something in the underlying element ('type', 'class', 'metatype' ...?) which controls this.  Note this doesn't prevent fill colour changes, just silently ignores them.

Uffe

  • EA Practitioner
  • ***
  • Posts: 1859
  • Karma: +133/-14
  • Flutes: 1; Clarinets: 1; Saxes: 5 and counting
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #4 on: August 02, 2018, 12:47:30 am »
2) Is there a way with boundaries to set the "Boundary Style", from the default of "Solid - No Fill" to "Solid"?

Why, yes there is. Strap in.


It's all a bit complicated. By the looks of things, the functionality to deal with boundaries has been not so much designed from scratch as patched and added to in several phases.

The Shape and Style properties are actually split between t_object and t_diagramobjects. This kinda works because boundaries are diagram-only elements, meaning they're not shown in the project browser and there is a one-to-one relationship between the t_object row and the corresponding one in t_diagramobjects.

One-to-one, I said, and by that I mean almost: it is quite possible to copy/paste diagram-only elements between diagrams, resulting in two t_diagramobjects rows referencing the same t_object one. How exactly that affects the contents of the two tables is not something I've gone into.

So. Disregarding that special case, here's how a boundary's properties are stored.

Before we move on, I should say that I haven't found anything relevant in t_object.NType, t_object.PDATAn or t_xref. But it's always possible that I've missed something.

There are three columns of interest: t_object.BorderStyle, t_object.StyleEx and t_diagramobjects.ObjectStyle. Their use is not quite consistent, as I alluded to above. In addition, t_object.Backcolor holds the background colour.

Boundaries with Shape Rectangle only use t_object.BorderStyle. This is likely because way back when boundaries were first implemented, there were no other possible shapes (and therefore no Shape attribute as such). Thus only the Style property is represented.

Shape Rectangle
Style (t_object.BorderStyles):
    0  =  Solid
    1  =  Dotted
    2  =  Dashed
    3  =  Solid - No Fill


For boundaries with other shapes, t_diagramobjects.ObjectStyle comes into play to hold the Shape property. The Style is still in t_object.BorderStyle, but now with a different set of values.

t_diagramobjects.ObjectStyle is a string containing a set of properties expressed as key=value pairs, each terminated by a semicolon. The order of these pairs does not appear to be significant. (There is always the "instance GUID", or DUID, which appears as 'DUID=xxxxxxxx;', where xxxxxxxx is an eight-digit hex number, but it appears in different positions in the list for different rows.)

Shape Rounded Rectangle, Ellipse and User Defined
Style (t_object.BorderStyles):
    4  =  Solid
    5  =  Dotted
    6  =  Dashed
    7  =  Solid - No Fill

Shape (t_diagramobjects.ObjectStyle):
    "shape=rounded;"    =  Rounded Rectangle
    "shape=ellipse;"    =  Ellipse
    "shape=freestyle;"  =  User Defined


User-defined shapes adds the last little wrinkle. They have a t_diagramobjects.ObjectStyle property 'LBL' which controls the label (and whose value is a sub-list of key=value pairs, separated by colons). I won't go into any details for this here, just note that it is created automatically for user-defined shape boundaries which means you may have to create it too if you plan to create user-defined boundaries through the API (but probably not).

User-defined shapes also get a key=value property 'Path' in t_object.StyleEx. This also contains a sub-list, a '@'-separated one of ':'-separated X/Y-coordinates. You probably do have to populate this in order to create a user-defined boundary through the API. For a rectangle, this will be something like Path=20:-398@143:-398@143:-498@20:-498;

I haven't been able to change the number of co-ordinates through the GUI, but it seems to me like it should be possible to create any polygonal shape by setting this property through the API. if you try it, please let us know how you did.


Finally, the background colour. This isn't quite consistent either, but at least it's stored in just one place: t_object.Backcolor holds a signed integer whose value is either -1 for the default colour, or an eight-bit RGB value. When accessing the data from an Intel machine, the order of bytes from most to least significant is Blue, Green, Red.

Note that the background color is handled differently for different shapes and styles. For user-defined shapes, the background colour is only used for the Solid style. For all predefined shapes, the background is only not used for the Solid - No Fill style.

The default colour also varies. For predefined shapes with style Solid (three in total), one colour is used, but all other combinations of shape and style use another one (although strictly speaking, Solid - No Fill shapes never use the fill colour). In my tests, these were pale yellow and white, respectively, but it may be controlled by the theme.


Since I haven't written any code to test this stuff, I'm not sure how to set all these properties through the API.

t_object.StyleEx is simple enough, that's just the Element.StyleEx attribute. But you only need this for user-defined shapes.

t_diagramobjects.ObjectStyle is probably DiagramObject.Style -- there's no "Style" column in t_diagramobjects and the API documentation says that this attribute is a "semi-colon delimited string" so they probably match -- although you may note that the DUID, which is stored in t_diagramobjects.ObjectStyle, has its own attribute DiagramObject.InstanceGUID.

t_object.BorderStyle is the most crucial one, and there's no attribute for it in Element. This probably means you have to write directly to the database. There's also a (slim) chance it can be set through some attribute in DiagramObject, but I think that's unlikely. Again, if you find a way to do it without invoking the dreaded Repository.Execute(), let us know.

Update -->
I forgot the background colour. That at least is straightforward: either set the DiagramObject.BackgroundColor attribute, or call the Element.SetAppearance() method.
<--

HTH,


/Uffe
« Last Edit: August 02, 2018, 06:17:41 pm by Uffe »
My theories are always correct, just apply them to the right reality.

matthew.james

  • EA User
  • **
  • Posts: 155
  • Karma: +8/-3
  • Am I supposed to say something here ... ?
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #5 on: August 02, 2018, 09:12:22 am »
Why, yes there is. Strap in.
Ok. Woah. Had to read through that a few times !
Thanks for the thorough analysis and explanation

By the looks of things, the functionality to deal with boundaries has been not so much designed from scratch as patched and added to in several phases.
I suspect that applies to a lot of functionality in EA; not surprising given how long the product has been around and how it has been forced into providing such a rich variety of features

t_object.BorderStyle is the most crucial one, and there's no attribute for it in Element. This probably means you have to write directly to the database. There's also a (slim) chance it can be set through some attribute in DiagramObject, but I think that's unlikely. Again, if you find a way to do it without invoking the dreaded Repository.Execute(), let us know.
I think I might pass - I'm trying really hard to avoid custom scripting and direct database manipulation as it is not sustainable (without building an operational support capability around the use of the tool within the organisation)

Uffe

  • EA Practitioner
  • ***
  • Posts: 1859
  • Karma: +133/-14
  • Flutes: 1; Clarinets: 1; Saxes: 5 and counting
    • View Profile
Re: Help - UML Types and shapescripts ...
« Reply #6 on: August 02, 2018, 06:36:55 pm »
t_object.BorderStyle is the most crucial one, and there's no attribute for it in Element. This probably means you have to write directly to the database. There's also a (slim) chance it can be set through some attribute in DiagramObject, but I think that's unlikely. Again, if you find a way to do it without invoking the dreaded Repository.Execute(), let us know.
I think I might pass - I'm trying really hard to avoid custom scripting and direct database manipulation as it is not sustainable (without building an operational support capability around the use of the tool within the organisation)
Well, arguably you've already crossed that threshold if you're doing shape scripts. But I hear what you're saying, and crossing a threshold is not the same as taking up residence.

/U
My theories are always correct, just apply them to the right reality.