Beta software, written entirely by AI.Nothing has been reviewed line by line by a human or security-audited. No warranty, no liability: you use it at your own risk.Read more
Skip to content

Icon packs: PLC Icons ​

Icon packs come only with official plugins

An icon pack is code that runs inside the server, so it can only be a C# plugin, and the server loads C# plugins only when they are official and signed. JavaScript plugins cannot add icon packs. This page shows how the official PLC Icons plugin is built, for reading.

An icon pack is the simplest useful C# plugin: no connection, no settings, no actions. The PLC Icons plugin (PLCIcons/, id plc-icons) contributes 29 ladder-logic (PLC) symbols to the editor's icon picker as their own category. This page walks through it.

What a pack is ​

Implement IIconPackSource and register it in Initialize with host.RegisterIconPack:

MemberMeaning
IdUnique id of the pack.
DisplayNameThe category name in the icon picker.
IconNamesThe names of the icons, in the order you want them listed.
GetIconSvg(name)The SVG text of one icon, or null if there is none.

The whole plugin ​

cs
using MacroGrid.Plugin.Abstractions;

namespace MacroGrid.Plugin.PlcIcons;

/// <summary>Entry point (plugin.json's "entry") — the host finds this type by reflection and instantiates it
/// with a parameterless constructor, then calls <see cref="Initialize"/> once.</summary>
public sealed class PlcIconsPlugin : IPlugin
{
    public void Initialize(IPluginHost host) => host.RegisterIconPack(new PlcIconPack());
}

/// <summary>A static icon pack: ladder-logic function block icons (coil, timers, comparisons, arithmetic),
/// embedded as SVG resources in this assembly. No connection, no settings — the icons never change at
/// runtime, so <see cref="IIconPackSource"/> is the whole plugin.</summary>
public sealed class PlcIconPack : IIconPackSource
{
    // Sorted so the picker's default ordering doesn't depend on the filesystem's own order.
    private static readonly string[] Names =
    [
        "add", "calculate", "close-branch", "coil", "convert", "divide", "empty-block", "equal",
        "f-trig", "greater", "greater-equal", "lesser", "lesser-equal", "move", "multiply", "n",
        "nc", "no", "not-equal", "open-branch", "p", "r-trig", "reset-coil", "set-coil", "subtract",
        "timer-convert", "tof-timer", "ton-timer", "tp-timer",
    ];

    public string Id => "plc-icons";

    public string DisplayName => "PLC Icons";

    public IReadOnlyList<string> IconNames => Names;

    public string? GetIconSvg(string name)
    {
        if (Array.IndexOf(Names, name) < 0) return null;

        var assembly = typeof(PlcIconPack).Assembly;
        using var stream = assembly.GetManifestResourceStream($"MacroGrid.Plugin.PlcIcons.icons.{name}.svg");
        if (stream is null) return null;

        using var reader = new StreamReader(stream);
        return reader.ReadToEnd();
    }
}
  • PlcIconsPlugin is the IPlugin entry point: one line, host.RegisterIconPack(new PlcIconPack()).
  • The names are sorted so the picker's ordering does not depend on the file system.
  • The SVGs are read from resources embedded in the assembly, so there are no loose files at run time.

The display name is written in English (the plugin's default language); the Turkish name "PLC İkonları" comes from locales/tr.json.

The project ​

The icons live in src/icons/ and are embedded with one line in the .csproj:

xml
<EmbeddedResource Include="icons\*.svg" />

The resource name is <RootNamespace>.icons.<file name> (MacroGrid.Plugin.PlcIcons.icons.coil.svg), which is what GetManifestResourceStream asks for above. plugin.json is copied to the output like in any C# plugin:

json
{
  "id": "plc-icons",
  "name": "PLC Icons",
  "description": "A static icon pack: 29 ladder-logic symbols in their own category in the editor's icon picker.",
  "author": "Deccoyi",
  "homepage": "https://github.com/Deccoyi/macro-grid-plugin/tree/main/PLCIcons",
  "defaultLanguage": "en",
  "version": "0.1.4",
  "minMacroGrid": "1.0.0",
  "sdkVersion": "^0.4.0",
  "minServerVersion": "0.3.2",
  "entry": "MacroGrid.Plugin.PlcIcons.dll",
  "kind": "csharp",
  "permissions": null
}

An icon ​

Each icon is a monochrome SVG that draws with stroke="currentColor". The editor colors the icon by setting color on the root <svg> element, so never hard-code colors. This is coil.svg:

xml
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="30" fill="none" viewBox="0 0 40 30"><path stroke="currentColor" stroke-linecap="round" stroke-width="2" d="M0 15h12m16 0h12M16 5c-5 5-5 15 0 20m8-20c5 5 5 15 0 20"/></svg>

Adding an icon ​

  1. Put a new .svg in src/icons/. Keep it monochrome and use currentColor for every stroke and fill.
  2. Add its file name (without the extension) to the Names array.
  3. Build and reinstall (or reload) the plugin.

Macro Grid sites: PC · Phone · Plugins
Released under the MIT License. Beta software, written entirely by an AI assistant, provided as is without warranty.