Add a resource (icons svg lib) for the new API

I would like to add a resource (icons svg lib) for the new API.

Resource will be added in C:\Program Files\Inductive Automation\Ignition\data\config\resources\core\com.inductiveautomation.perspective\icons\

pseudo code


import com.inductiveautomation.ignition.common.resourcecollection.Resource
import com.inductiveautomation.ignition.common.resourcecollection.ResourceBuilder

res = ResourceBuilder().setType("icons").setPath("...testicons").setData(u"blabla").setLastModified(System.currentTimeMillis()).build()

cfg = context.getConfigurationManager()
cfg.addSystemResources(Collections.singletonList(res));

it is the right method to add such kind of ressources ?
What is the type and path to provide ?

The first question is how you want your resource to behave.

Do you want end users to be able to overwrite or override your icons, or do you want to guarantee that they're available? That dictates whether to add them to the SYSTEM collection, or add them in core.

I want to guarantee that they're available.

Okay, then you want to add them to system as you are, but note that the system collection only exists in memory - you won't ever see them on disk:

com.inductiveautomation.perspective.gateway.assets.icons.IconManagerImpl#RESOURCE_TYPE is the shared reference; you could construct an equivalent ResourceType if that's not exposed with new ResourceType("com.inductiveautomation.perspective", "icons").

So without knowing offhand what's exposed outside the Perspective module, this should get you there:

        ResourceType type = new ResourceType("com.inductiveautomation.perspective", "icons");
        String mySvgData = "...";
        String fileName = "mySvgData.svg";
        JsonObject configObject = new JsonObject();
        configObject.addProperty("svgFileName", fileName);

        var resource = Resource.newBuilder()
            .setResourcePath(type.childPath("myIcons"))
            .putData(fileName, mySvgData)
            .putData(Resource.DEFAULT_JSON_KEY, configObject.toString())
            .build();

        context.getConfigurationManager().addSystemResources(List.of(resource));
3 Likes

In fact those icones where here in core:

C:\Program Files\Inductive Automation\Ignition\data\config\resources\core\com.inductiveautomation.perspective\icons\

due to a migration from 8.1.

It's probably better the user can modify them and that the resources are visibles on disk.
So I will need to add them to the core...

I suppose I need to use other method than ConfigurationManager::addSystemResources...?

Yes. Much the same, but specify a collection name in the builder and use push:

        var resource = Resource.newBuilder()
            .setResourceCollectionName(ConfigurationManager.CORE)
            .setResourcePath(type.childPath("myIcons"))
            .putData(fileName, mySvgData)
            .putData(Resource.DEFAULT_JSON_KEY, configObject.toString())
            .build();

        ChangeOperation.CreateResourceOperation createOp = ChangeOperation.newCreateOp(resource);
        try {
            context.getConfigurationManager().push(List.of(createOp));
        } catch (PushException e) {
            throw new RuntimeException(e);
        }
2 Likes

to create on hand without module a new Custom Icon Repository,
the good practice is to copy another one, change the resource.json, and config.json and svg files and rescan on the gateway ?

ressources.attributes can be leave empty ?

Basically.

Hypothetical question: what if I wanted to add globally available Perspective style classes?

We have a theme that allows configuration via style classes, it could be cool to have the theme + PSC's wrapped up as a module.

I'm guessing this concept doesn't apply though, since style classes are a project resource.

Correct. New to 8.3, modules can contribute an entire project, which acts more or less like a 'system' level resource...but it's an entire project, not a piece of one. You should be able to have it participate in inheritance, though.

1 Like