Skip to content

workspace sdk tiles

Andre Lafleur edited this page Apr 23, 2026 · 6 revisions

About tile extensions

Tile extensions add custom functionality to Security Desk's tile-based monitoring interface. The Workspace SDK provides three complementary component types for extending tiles: widgets for the right-side controls panel, views for content inside tiles, and properties for configuration tabs.

Use a tile extension when you need to react to the currently selected tile by adding side-panel controls, in-tile visuals, or bottom configuration tabs that depend on the tile's current content.

How tile extensions work

  1. Your module creates one or more tile component builders and registers them with Workspace.Components.
  2. Security Desk evaluates each builder against the current TilePluginContext by calling IsSupported(...).
  3. When a builder supports the current tile context, the framework creates the tile widget, tile view, or tile properties instance through CreateView().
  4. The framework calls Update(...) when the selected tile, content group, or current content changes.
  5. Your component updates its UI based on the current tile context.
  6. When the module unloads, it unregisters the builders.

Tile state and context

Security Desk displays content in tiles arranged on tile pages. Each tile has a TileState that contains the current ContentGroup, which usually exposes the active Content through its Current property. Tile extensions respond to changes in this hierarchy through the shared TilePluginContext.

Alarm and event tiles are a special case. AlarmContent and EventContent derive from SourceContent, which itself derives from ContentGroup. For those tile types, inspect context.ContentGroup to access the alarm or event metadata.

TilePluginContext

All tile components receive a TilePluginContext that provides access to the current tile state:

Member Type Description
Page TilePage The active tile page
TileState TileState The selected tile's state
ContentGroup ContentGroup Content group displayed in the tile
Content Content Current content within the group

Use these properties in your IsSupported method to determine whether your component applies to the current tile content.

Tile widgets

Tile widgets appear in Security Desk's right-side controls panel, stacked below built-in widgets like camera playback controls, PTZ controls, or door status. When you select a tile, widgets registered for that content type appear in the controls panel. Use them to display supplementary information or controls related to the tile's content.

TileWidgetBuilder

Create a builder class that inherits from TileWidgetBuilder:

public class MyTileWidgetBuilder : TileWidgetBuilder
{
    public override string Name => "My Tile Widget";
    public override Guid UniqueId => new Guid("...");
    public override string Title => "Widget Title";
    public override int Priority => 100;

    public override bool IsSupported(TilePluginContext context)
    {
        return context.Content is VideoContent;
    }

    public override TileWidget CreateView()
    {
        return new MyTileWidget();
    }
}

TileWidgetBuilder members

Member Type Description
Name string Component display name
UniqueId Guid Unique component identifier
Title string Widget header displayed in the controls panel
Priority int Display order (lower values appear first)
IsSupported(TilePluginContext) bool Return true when the widget applies
CreateView() TileWidget Factory method to create the widget

TileWidget

Implement the widget view by inheriting from TileWidget:

public class MyTileWidget : TileWidget
{
    private readonly MyWidgetControl m_control = new MyWidgetControl();

    public override UIElement View => m_control;

    protected override void OnContentChanged()
    {
        m_control.UpdateDisplay(Content);
    }
}

TileWidget members

Member Type Description
View UIElement The widget's visual content
Page TilePage Current tile page (read-only)
TileState TileState Current tile state (read-only)
ContentGroup ContentGroup Current content group (read-only)
Content Content Current content (read-only)
Update(TilePluginContext) void Called by the framework to update the widget's context

The TileWidget automatically synchronizes its properties when Update is called. The TileState property is set from the context, which triggers ContentGroup to update from TileState.Content, which in turn updates Content from ContentGroup.Current. This cascading update fires the corresponding lifecycle callbacks.

TileWidget lifecycle

TileWidget provides virtual methods that fire when the tile context changes:

Method Invoked when
OnPageChanged() The tile page changes
OnTileStateChanged() The tile state changes
OnContentGroupChanged() The content group changes
OnContentChanged() The content changes

Override these methods to update your widget's display when the tile content changes.

Tile views

Tile views render custom content directly inside the tile area itself. When you select a tile displaying supported content, tile views appear within the tile's visual space. Use them to display custom entity visualizations, overlays, or annotations on top of or instead of the default content.

TileViewBuilder

Create a builder that inherits from TileViewBuilder:

public class MyTileViewBuilder : TileViewBuilder
{
    public override string Name => "My Tile View";
    public override Guid UniqueId => new Guid("...");
    public override int Priority => 100;

    public override bool IsSupported(TilePluginContext context)
    {
        return context.Content is VideoContent;
    }

    public override TileView CreateView()
    {
        return new MyTileView();
    }
}

TileViewBuilder members

Member Type Description
Name string Component display name
UniqueId Guid Unique component identifier
Priority int Display order (lower values appear first)
IsSupported(TilePluginContext) bool Return true when the view applies
CreateView() TileView Factory method to create the view

TileView

Implement the view by inheriting from TileView:

public class MyTileView : TileView
{
    private readonly MyOverlayControl m_overlay = new MyOverlayControl();

    public MyTileView()
    {
        Placement = Placement.OverVideo;
    }

    public override UIElement View => m_overlay;

    public override void Update(TilePluginContext context)
    {
        m_overlay.UpdateOverlay(context.Content);
    }
}

TileView members

Member Type Description
View UIElement The view's visual content
Placement Placement Where the view appears in the tile
Update(TilePluginContext) void Called when the tile context changes

Placement options

The Placement property controls where the view appears within the tile:

Value Description
Normal Constrained below the tile toolbar (default)
Extended Full tile area below the toolbar
OverVideo Overlaid on top of video content

Tile properties

Tile properties add custom tabs to the bottom of Security Desk's right-side controls panel, alongside the built-in "General" tab. When you select a tile displaying supported content, your custom tab appears and provides configuration options specific to that content type.

TilePropertiesBuilder

Create a builder that inherits from TilePropertiesBuilder:

public class MyTilePropertiesBuilder : TilePropertiesBuilder
{
    public override string Name => "My Tile Properties";
    public override Guid UniqueId => new Guid("...");
    public override string Title => "My Settings";
    public override int Priority => 100;

    public override bool IsSupported(TilePluginContext context)
    {
        return context.Content is VideoContent;
    }

    public override TileProperties CreateView()
    {
        return new MyTileProperties();
    }
}

TilePropertiesBuilder members

Member Type Description
Name string Component display name
UniqueId Guid Unique component identifier
Title string Tab title displayed at the bottom of the controls panel
Priority int Tab order (lower values appear first)
IsSupported(TilePluginContext) bool Return true when the properties apply
CreateView() TileProperties Factory method to create the view

TileProperties

Implement the properties view by inheriting from TileProperties:

public class MyTileProperties : TileProperties
{
    private readonly MyPropertiesControl m_control = new MyPropertiesControl();

    public override UIElement View => m_control;

    public override void Update(TilePluginContext context)
    {
        m_control.LoadSettings(context.Content);
    }
}

TileProperties members

Member Type Description
View UIElement The properties panel content
Update(TilePluginContext) void Called when the tile context changes

Registering tile components

Important

Tile components require a valid SDK certificate.

Register tile components in your module's Load method and unregister them in Unload:

public class SampleModule : Module
{
    private MyTileWidgetBuilder m_widgetBuilder;
    private MyTileViewBuilder m_viewBuilder;
    private MyTilePropertiesBuilder m_propertiesBuilder;

    public override void Load()
    {
        m_widgetBuilder = new MyTileWidgetBuilder();
        m_widgetBuilder.Initialize(Workspace);
        Workspace.Components.Register(m_widgetBuilder);

        m_viewBuilder = new MyTileViewBuilder();
        m_viewBuilder.Initialize(Workspace);
        Workspace.Components.Register(m_viewBuilder);

        m_propertiesBuilder = new MyTilePropertiesBuilder();
        m_propertiesBuilder.Initialize(Workspace);
        Workspace.Components.Register(m_propertiesBuilder);
    }

    public override void Unload()
    {
        if (m_widgetBuilder != null)
        {
            Workspace.Components.Unregister(m_widgetBuilder);
            m_widgetBuilder = null;
        }

        if (m_viewBuilder != null)
        {
            Workspace.Components.Unregister(m_viewBuilder);
            m_viewBuilder = null;
        }

        if (m_propertiesBuilder != null)
        {
            Workspace.Components.Unregister(m_propertiesBuilder);
            m_propertiesBuilder = null;
        }
    }
}

Tile content hierarchy

The IsSupported method determines when your tile component appears. To implement this method effectively, you need to understand how Security Desk organizes content within tiles.

Content hierarchy

Tiles organize content in a hierarchy:

TilePage
└── TileState (one per tile)
    └── ContentGroup (what the tile displays)
        └── Content[] (one or more content items)
            └── Current (the active content)
Class Description
TileState Represents a tile's state, including selection and content
ContentGroup A collection of content items displayed in a tile
Content A single displayable item within a content group

ContentGroup

A ContentGroup contains one or more Content objects. When a content group has multiple items, Security Desk can cycle through them automatically (content rotation).

Member Type Description
Contents ObservableCollection<Content> All content items in the group
Current Content The currently visible content
Title string Display title for the group
Icon ImageSource Display icon for the group
Event Description
CurrentChanged Fires when the active content changes (cycling)

Content types

Content is the base class for the displayable item exposed through context.Content. Security Center also provides specialized content groups for source-driven tiles such as alarms and events.

Type Base Description
EntityContent Content Generic entity display (has EntityId)
VideoContent EntityContent Camera video with playback controls
MapContent EntityContent Map display with zoom and center
WebContent Content Web page display (has Url)
AlarmContent SourceContent (ContentGroup) Alarm-focused content group with alarm metadata
EventContent SourceContent (ContentGroup) Event-focused content group with event metadata

VideoContent properties

VideoContent is the most common content type. It provides rich video control:

Member Type Description
EntityId Guid The camera's entity identifier
VideoMode VideoMode Live or Playback mode
State VideoState Current video state (Playing, Paused, etc.)
VideoTime DateTime Current playback timestamp
CurrentTime DateTime Timeline position

EntityContentGroup

EntityContentGroup is a specialized content group for displaying entities:

var group = new EntityContentGroup(cameraGuid);
group.Initialize(Workspace);

IsSupported

The IsSupported method receives a TilePluginContext and returns whether your component should appear. Check both the ContentGroup and its Current content.

Checking content type

Check the current content type directly in IsSupported:

public override bool IsSupported(TilePluginContext context)
{
    return context.Content is VideoContent;
}

Checking entity type

Inspect the current content and then resolve the entity when needed:

public override bool IsSupported(TilePluginContext context)
{
    if (context.Content is VideoContent video)
    {
        var camera = Workspace.Sdk.GetEntity(video.EntityId) as Camera;
        return camera?.IsOnline == true;
    }

    return false;
}

Checking content group

When you need to know about all content in the tile, not just the current item:

public override bool IsSupported(TilePluginContext context)
{
    var group = context.ContentGroup;
    if (group == null)
    {
        return false;
    }

    return group.Contents.Any(c => c is VideoContent);
}

Supporting multiple content types

public override bool IsSupported(TilePluginContext context)
{
    return context.Content is VideoContent
        || context.Content is MapContent
        || context.ContentGroup is AlarmContent
        || context.ContentGroup is EventContent;
}

Responding to content changes

Tile widgets receive lifecycle callbacks when the content hierarchy changes:

Method When called
OnContentChanged() The current Content changes
OnContentGroupChanged() The entire ContentGroup changes
OnTileStateChanged() The TileState changes
OnPageChanged() The TilePage changes

Override these methods to update your widget when the user switches content or navigates to a different tile:

protected override void OnContentChanged()
{
    if (Content is VideoContent video)
    {
        m_control.ShowVideoInfo(video.EntityId, video.VideoMode);
    }
    else
    {
        m_control.ClearDisplay();
    }
}

See also

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Media Gateway

Genetec Web Player

Clone this wiki locally