Author Topic: Extending the Model with a new Element  (Read 4717 times)

bobovo

  • Newbie
  • *
  • Posts: 1
Re: Extending the Model with a new Element
« Reply #15 on: May 17, 2017, 19:34:40 PM »
Hi, only for inspiration.

In Sparx Enterprise Architect users can change in configuration a presentation of elements or relationship on a diagram via a ShapeScript or a Metafile. ShapeScripts have mostly used also when defining a UML profile that extends UML or another modelling language.

How ShapeScripts look like for ArchiMate, ArchiMate 2 and ArchiMate 3 is possible to see in ShapeScripts catalogue:

http://www.bobovo.eu/mdg_shape_scripts.aspx

But ShapeScripts are only about the presentation of elements and it is not enough for extending the model.

In the discussion mentioned Add-in for EIP (http://www.bobovo.eu/mdg_for_eip.aspx) is the example how the capability of Enterprise Architect was extended to allow creating a new model.

Best regards

Bob

Hervé

  • Hero Member
  • *****
  • Posts: 487
Re: Extending the Model with a new Element
« Reply #16 on: May 18, 2017, 08:55:39 AM »
Dear all,

Here is my comprehension of how the icons are managed.

The com.archimatetool.editor.ui.factory.ObjectUIFactory class creates the UIProviders and store them in a HashMap (method registerProviders()).

When a component is drown, the UIProvider is retreived from the class name using the class name (method getProviderForClass(EClass eClass)).

And the icon is retreived from the UIProvider (method getImage());


It's quite straight forward to surchage the factory and the UIproviders, but unfortunately, I failed to retreive promatically the EObject corresponding to the element drawn.


So I can't change the icon through a plugin.


What I suggest, is to update the getImage() and getImageDescriptor() of all the UIProviders methods, adding the element as parameter :

for instance, ApplicationInterfaceUIProvider methods are :
Code: [Select]
    @Override
    public Image getImage() {
        return getImageWithUserFillColor(IArchiImages.ICON_APPLICATION_INTERFACE);
    }

    @Override
    public ImageDescriptor getImageDescriptor() {
        return getImageDescriptorWithUserFillColor(IArchiImages.ICON_APPLICATION_INTERFACE);
    }

And would become
Code: [Select]
    @Override
    public Image getImage(EObject eObject) {
        return getImageWithUserFillColor(eObject, IArchiImages.ICON_APPLICATION_INTERFACE);
    }

    @Override
    public ImageDescriptor getImageDescriptor(EObject eObject) {
        return getImageDescriptorWithUserFillColor(eObject, IArchiImages.ICON_APPLICATION_INTERFACE);
    }

The AbstractArchimateElementUIProvider.getImageWithUserFillColor() would then be able to check the properties to calculate the image to return.

We can use the property "icon" which is quite understandable, or even choose it through an option on a preference page. As per Gilles suggestion, we could create the icons from existing standards like http://fontawesome.io/icons ou https://material.io/icons.

I could suggest :
  • "icon" = "fa:<iconName>     would create a Font Awesome icon
  • "icon" = "md:<iconName>   would create a Material Design icon
  • "icon" = "<file path>"           would create an icon from a jpg or svg file

Code: [Select]
protected Image getImageWithUserFillColor(EObject eObject, String imageName) {
        // Not a preference
        if(!Preferences.STORE.getBoolean(IPreferenceConstants.SHOW_FILL_COLORS_IN_GUI)) {
            return IArchiImages.ImageFactory.getImage(imageName);
        }

        if ( eObject instanceof IProperties ) {
                for ( IProperty prop: ((IProperties)eObject).getProperties ) {
                        if ( prop.getKey().equals("icon") ) {
                                imageName = prop.getValue();
                                break;
                        }
                }
        }
       
        Image image = fImageRegistry.get(imageName);
       
        if(image == null) {
            // Create local ImageDescriptor and try again
            getImageDescriptorWithUserFillColor(imageName);
            image = fImageRegistry.get(imageName);
           
            // If image is still null then we didn't make a new one and so need the default image
            if(image == null) {
                return IArchiImages.ImageFactory.getImage(eObject, imageName);
            }
        }

        return image;
    }
}

protected ImageDescriptor getImageDescriptorWithUserFillColor(String imageName) {
        ...

        ImageData imageData = originalImageDescriptor.getImageData();

        if ( imageName.startsWith("fa:") {
                 // create FontAwesome icon
        }
        else if ( imageName.startsWith("md:") {
                // create a MaterialDesign font
        }
        else {
                ...
        }

         ...
}

Whatever the issue (non existent icon, file not found, etc ...) will mean defaulting to the standard element icon.

Of course, all the getImage() calls will need to be replaced by getImage(element) where needed.





The advante of this solution is that the model is not impacted. Opening the dot archimate file without this icon management stuff will result in showing the standard elements icons.

The disadvantage I foresee is that the icon change will not be real-tim when one changes the "icon" property. To change the icon displayed, the view will need to be closed and re-opened.


JB, Is this something that would be acceptable for you ?


Thanks and regards
Hervé

Jean-Baptiste Sarrodie

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 647
  • Archi Evangelist and Contributor. Visionary.
    • About me...
Re: Extending the Model with a new Element
« Reply #17 on: May 18, 2017, 19:42:30 PM »
Hi,

I think several things are discussed and mixed: the icon drawn inside figures on views is managed by code while the icon seen on the palette is and image. In addition this is (again) linked to profile and concepts customization which has to be done the proper way (ie. in a way that makes possible to export to the open exchange format).

That's something that Phil and I discussed some months ago and I have a pretty clear idea on how we should do it. Only issue (for the moment) is free time or funding to do it.

I'm writing a page on Archi's wiki to share it with you. I'll post here as soon as it will be done.

Regards,

JB
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

Hervé

  • Hero Member
  • *****
  • Posts: 487
Re: Extending the Model with a new Element
« Reply #18 on: May 18, 2017, 20:10:49 PM »
Thanks JB

Jean-Baptiste Sarrodie

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 647
  • Archi Evangelist and Contributor. Visionary.
    • About me...
Re: Extending the Model with a new Element
« Reply #19 on: May 18, 2017, 21:31:18 PM »
Here it is

Good reading

Regards,

JB
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

Phil Beauvoir

  • Archi Guy
  • Hero Member
  • *****
  • Posts: 1501
  • Archi Guy
    • Archi
Re: Extending the Model with a new Element
« Reply #20 on: May 18, 2017, 21:40:33 PM »
Thanks, JB.  8)
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

Hervé

  • Hero Member
  • *****
  • Posts: 487
Re: Extending the Model with a new Element
« Reply #21 on: May 19, 2017, 07:49:56 AM »
Very nice way, indeed  ;D