Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ryzhpolsos/redeye/llms.txt

Use this file to discover all available pages before exploring further.

IShellWidget is the contract that every widget in RedEye must satisfy. Whether you are using a built-in widget or writing a custom one in a plugin, the shell interacts with it exclusively through this interface. It covers the full widget lifecycle: post-initialization, config reads and writes, control creation, thread-safe updates, and event registration.

IShellWidget interface

IShellWidget lives in RedEye.UI and extends IComponent. The BaseShellWidget abstract class in RedEye.UI provides a complete default implementation that you can subclass in plugin widgets.

PostInitialize

Called by the shell after all widgets in the window have been initialized and their controls added to the layout. Use it to perform tasks that depend on other widgets existing, such as reparenting a control or attaching event handlers to sibling widgets.
void PostInitialize();
Override PostInitialize() when you need to look up a sibling widget by ID using IWidgetContainer.GetWidget(). During Initialize() those other widgets may not yet exist.

GetNode / SetNode

Provides access to the ConfigNode that this widget was constructed from. The node is the live XML element in the config tree, so reading attributes from it reflects any runtime variable changes.
ConfigNode GetNode();
void SetNode(ConfigNode node);
node
ConfigNode
required
The config node associated with this widget instance.

GetConfig / SetConfig

Returns or replaces the current ShellWidgetConfig for this widget. SetConfig is called by the shell during widget construction; you can call GetConfig at any time to inspect the current state.
ShellWidgetConfig GetConfig();
void SetConfig(ShellWidgetConfig config);
config
ShellWidgetConfig
required
The new configuration to apply. If Id is empty, SetConfig assigns a new GUID automatically.

UpdateConfig

Re-reads all standard ShellWidgetConfig fields from the backing ConfigNode, evaluating any expressions in attribute values. The base class implementation handles all fields declared in ShellWidgetConfig. Override this method in a subclass to read additional widget-specific attributes.
void UpdateConfig();

GetContainer / SetContainer

Gets or sets the IContainerWidget that owns this widget. Container widgets such as panels or stack layouts call SetContainer on their children during initialization.
IContainerWidget GetContainer();
void SetContainer(IContainerWidget container);

GetWindow / SetWindow

Gets or sets the IShellWindow that hosts this widget. The shell sets this before calling Initialize().
IShellWindow GetWindow();
void SetWindow(IShellWindow window);

GetControl

Returns the underlying System.Windows.Forms.Control. When update is true (the default), UpdateControl() is called first to apply any pending config changes.
Control GetControl(bool update = true);
update
bool
default:"true"
When true, UpdateControl() is called before the control is returned. Pass false if you need the control reference without triggering a redraw.
ReturnsControl: the WinForms control that backs this widget.

UpdateControl

Applies the current ShellWidgetConfig values to the underlying WinForms control — position, size, colors, font, dock, anchor, padding, margin, and any on* event attributes declared in the config node. This method is thread-safe: it marshals to the UI thread when called from a background thread.
void UpdateControl();

Update

Calls UpdateConfig() followed by UpdateControl() in a single thread-safe operation. Use this when you want to pull fresh values from the config node and immediately reflect them in the control.
void Update();
Update() vs UpdateControl() — call Update() when the config node attributes may have changed (e.g. after setting a variable on the node) and you want both the config snapshot and the control to reflect the new values. Call UpdateControl() when you have already mutated GetConfig() directly and only need to push those values to the WinForms control.

Modify

Runs a callback with this as the argument, then calls UpdateConfig() and UpdateControl(). The entire operation is marshaled to the UI thread. Use this for atomic config mutations that must stay consistent with the visible control state.
void Modify(Action<IShellWidget> callback);
callback
Action<IShellWidget>
required
An action that receives the widget instance and may modify its config or internal state. UpdateConfig() and UpdateControl() are called automatically after the callback returns.
widget.Modify(w =>
{
    w.GetConfig().Color = "#ff0000";
    w.GetConfig().Width = 120;
});

RegisterEventHandler

Registers a callback for a named widget event. The event name corresponds to a WinForms event on the underlying control, such as "Click", "MouseEnter", or "MouseLeave". The handler receives a ShellWidgetEvent with coordinate and key information.
void RegisterEventHandler(string name, Action<ShellWidgetEvent> handler);
name
string
required
The WinForms event name to subscribe to, without the on prefix. For example, "Click" not "onClick".
handler
Action<ShellWidgetEvent>
required
The callback invoked when the event fires.
widget.RegisterEventHandler("Click", e =>
{
    Logger.LogInfo($"Clicked at {e.X},{e.Y}");
});

ShellWidgetConfig class

ShellWidgetConfig is the data class that holds the resolved values for all standard widget attributes. It is populated by UpdateConfig() from the widget’s backing ConfigNode.
Id
string
default:"\"\""
Unique identifier for the widget. Used by container widgets to look up children. If empty, a GUID is assigned automatically by SetConfig.
X
int
default:"0"
Left position of the control relative to its parent container, in pixels.
Y
int
default:"0"
Top position of the control relative to its parent container, in pixels.
Width
int
default:"0"
Width of the control in pixels. Ignored when AutoSize is true.
Height
int
default:"0"
Height of the control in pixels. Ignored when AutoSize is true.
AutoSize
bool
default:"false"
When true, the control sizes itself to fit its content.
Dock
string
default:"\"\""
Dock style as a string, e.g. "Top", "Bottom", "Fill". Maps to System.Windows.Forms.DockStyle.
Anchor
string
default:"\"\""
Anchor style as a string, e.g. "Top,Left". Maps to System.Windows.Forms.AnchorStyles.
Color
string
default:"\"\""
Foreground text color as an HTML color string, e.g. "#ffffff".
BackgroundColor
string
default:"\"\""
Background color as an HTML color string, e.g. "#1a1a1a".
Padding
string
default:"\"\""
Inner padding in the format "all" or "left,top,right,bottom", e.g. "4" or "0,4,0,4".
Margin
string
default:"\"\""
Outer margin in the same format as Padding.
Font
string
default:"\"\""
Font specification string parsed by ParseHelper.ParseFont, e.g. "Segoe UI, 10, Bold".
UpdateInterval
int
default:"0"
When greater than 0, UpdateConfig() and UpdateControl() are called on a background timer at this interval in milliseconds. Useful for widgets that display live data.
ToolTip
string
default:"\"\""
Tooltip text shown on mouse hover. Empty string disables the tooltip.
Layer
int
default:"0"
Z-order layer for this widget within its container. Higher values appear on top.
IsTransparent
bool
default:"false"
When true, the control’s background color is set to Color.Transparent.
TransparencyKey
string
default:"\"#ff00ff\""
The color used as the transparency key when IsTransparent is true. Defaults to magenta (#ff00ff).
Parent
string
default:"\"\""
ID of another widget to reparent this control to during PostInitialize. When set, the control is nested inside the named widget’s control.

ShellWidgetEvent class

ShellWidgetEvent is passed to handlers registered via RegisterEventHandler.
X
int
X coordinate of the event (e.g. mouse position within the control), in pixels.
Y
int
Y coordinate of the event.
Name
string
Name of the event that fired.
KeyName
string
Name of the key involved in key events, or an empty string for pointer events.

Implementing a custom widget

Subclass BaseShellWidget and override the methods relevant to your widget. At minimum you need to create a WinForms control in Initialize() and assign it to Control.
using System.Windows.Forms;
using RedEye.UI;
using RedEye.Core;

namespace MyPlugin
{
    public class ClockWidget : BaseShellWidget
    {
        private Label label;

        public override void Initialize()
        {
            label = new Label();
            Control = label;
            base.Initialize(); // starts the update timer if UpdateInterval > 0
        }

        public override void UpdateConfig()
        {
            base.UpdateConfig(); // reads all standard ShellWidgetConfig fields
            // Read widget-specific attributes here
        }

        protected override void UpdateControlInternal()
        {
            base.UpdateControlInternal(); // applies position, size, colors, font, etc.
            label.Text = DateTime.Now.ToString("HH:mm:ss");
        }
    }
}
Register it from Main() in your Plugin subclass:
public override void Main()
{
    ExportWidget<ClockWidget>("Clock");
}
Then reference it in RWML:
<MyPlugin.Clock id="my-clock" x="10" y="10" width="80" height="24"
                color="#ffffff" updateInterval="1000" />

Using Update() vs UpdateControl()

// Scenario 1: a node attribute changed — re-read from the node and update the control
Node.SetVariable("status", "online");
Update(); // equivalent to UpdateConfig() + UpdateControl()

// Scenario 2: you mutated the config object directly — only push to the control
GetConfig().Color = "#00ff00";
UpdateControl();

Registering a click handler from PostInitialize

public override void PostInitialize()
{
    base.PostInitialize();
    RegisterEventHandler("Click", e =>
    {
        Logger.LogInfo("Widget clicked");
    });
}

IShellWindow

The window interface that hosts widget instances.

Exporting widgets

How to register a custom IShellWidget implementation as a plugin export.

Build docs developers (and LLMs) love