Skip to content

General Options ​

Options shared by every UI element. These properties apply to all ui.add*() calls — addText, addImage, addButton, addBitmap, addBar, addLine, addAreaGraph, addHistogram, addRotator, addRoundLine, addShape, addInputBox, and addLayoutBox.

For shared image-processing fields (imageAlpha, imageTint, imageFlip, colorMatrix, etc.) see General Image Options below.

javascript
ui.addText({
  id: "label",
  x: 16, y: 14,
  width: 260, height: 28,
  fontSize: 14,
  fontColor: "rgb(230,230,230)"
});

Table of Contents ​

Layout and Positioning ​

id # string

Unique identifier for the element. While not technically required by the parser, it is needed in practice to update or remove the element later. Creating an element with an id that already exists replaces the previous element.

x # number
Default: 0

Horizontal position in pixels, relative to the top-left corner of the widget window.

y # number
Default: 0

Vertical position in pixels, relative to the top-left corner of the widget window.

width # number
Default: 0

Element width in pixels. When 0 or omitted, the engine sizes the element to fit its content.

height # number
Default: 0

Element height in pixels. When 0 or omitted, the engine sizes the element to fit its content.

padding # number | number[]
Default: 0

Inner spacing between the element bounds and its rendered content. Accepts three forms:

  • padding: 10 — all four sides equal
  • padding: [horizontal, vertical] — left/right = first, top/bottom = second
  • padding: [left, top, right, bottom] — each side individually

Arrays shorter than 2 are ignored. Arrays of 3 are treated as 2.

javascript
padding: 8                    // all sides
padding: [12, 4]              // left/right 12, top/bottom 4
padding: [8, 4, 8, 4]         // explicit per side
rotate # number
Default: 0

Rotation angle in degrees, applied around the element center. When both rotate and transformMatrix are set, transformMatrix takes effect because it is applied last.

transformMatrix # number[]

Six-element affine transformation matrix [m11, m12, m21, m22, dx, dy]. Enables translation, scaling, rotation, and shearing in a single operation. Requires exactly 6 values — fewer than 6 are silently ignored.

javascript
// 45-degree shear
transformMatrix: [1, 0.5, 0, 1, 0, 0]

Overrides rotate

When both rotate and transformMatrix are present, transformMatrix is applied last and wins. Use one or the other, not both.

Visibility ​

show # boolean
Default: true

Controls element visibility. false hides the element without removing it. Hidden elements still occupy their position and receive no mouse events. Set show: true to reveal a hidden element.

javascript
ui.setElementProperties("panel", { show: false });   // hide
ui.setElementProperties("panel", { show: true });    // show again

Grouping and Containers ​

group # string
Default: ""

Logical group name for batch operations via ui.setElementPropertiesByGroup() and ui.removeElementsByGroup(). Grouping is organizational only and has no effect on rendering or clipping.

Cannot be cleared via setElementProperties

The parser ignores empty strings for group. Passing group: "" does not remove an element from its group.

javascript
ui.addText({ id: "title", group: "stats", text: "CPU" });
ui.addBar({ id: "bar",   group: "stats", value: 0.5 });

// Update all elements in the group at once
ui.setElementPropertiesByGroup("stats", { show: false });
container # string
Default: ""

ID of an existing container element (addLayoutBox). The child element is clipped to the container bounds and moves with it.

The container must already exist when the child is created. An element cannot be its own container. Passing container: "" via setElementProperties has no effect.

Appearance ​

antiAlias # boolean
Default: true

Enables anti-aliased rendering for smoother edges. Disable only when rendering pixel-perfect bitmaps where sub-pixel smoothing would cause blurring.

pixelHitTest # boolean
Default: false

Selects the hit-testing mode for mouse interactions.

  • false — bounding-box hit testing. Fast and broad.
  • true — pixel-aware hit testing that follows the visible shape of the element.

Only set when explicitly present

Omitting pixelHitTest from an add* or setElementProperties call preserves the element's existing value. Only an explicit true or false changes it.

backgroundColor # string
Default: ""

Background fill drawn behind all element content. Supports rgb(), rgba(), hex, linearGradient(), and radialGradient(). An empty string draws no background.

javascript
backgroundColor: "rgba(30,30,40,0.9)"
backgroundColor: "rgb(20,20,28)"
backgroundColor: "#1e1e2c"
backgroundColorRadius # number
Default: 0

Corner radius in pixels for the background fill. 0 produces square corners.

bevelType # string
Default: "none"

Draws a decorative border effect around the element.

Value Appearance
"none" No bevel (default)
"raised" Raised button appearance
"sunken" Sunken or pressed appearance
"emboss" Embossed border
"pillow" Pillow or cushion border

Unrecognized non-empty strings map to no bevel.

bevelWidth # number
Default: 0

Thickness of the bevel in pixels.

bevelColor # string

Highlight edge color for the bevel (top and left edges when bevelType is "raised"). Defaults to rgba(255,255,255,200). Only parsed when non-empty. Supports gradients.

bevelColor2 # string

Shadow edge color for the bevel (bottom and right edges when bevelType is "raised"). Defaults to rgba(0,0,0,150). Only parsed when non-empty. Supports gradients.

Tooltip ​

Tooltips appear on hover. tooltipText must be non-empty for any tooltip to display — tooltipTitle or tooltipIcon alone will not show anything.

tooltipText # string
Default: ""

Tooltip body text shown on hover. This is the gating condition — all other tooltip properties are ignored when this is empty.

javascript
ui.addBar({
  id: "cpu",
  value: 0.72,
  tooltipText: "CPU usage: 72%"
});
tooltipTitle # string
Default: ""

Bold title line shown above tooltipText.

tooltipIcon # string
Default: "none"

Icon displayed next to the tooltip title. Valid values: "none", "info", "warning", "error".

tooltipBalloon # boolean
Default: false

true renders a cartoon balloon-style tooltip instead of the standard flat style.

tooltipMaxWidth # number
Default: 0

Maximum tooltip width in pixels. Text wraps beyond this limit. A value of 0 (the default) applies a runtime limit of 1000 px.

tooltipMaxHeight # number
Default: 0

Maximum tooltip height in pixels. A value of 0 (the default) applies a runtime limit of 1000 px.

tooltipDisabled # boolean
Default: false

Disables tooltip display for this element even when tooltipText is set.

Cursor ​

Cursor options only take effect when the element has at least one mouse callback registered.

mouseEventCursor # boolean
Default: true

true shows the cursor defined by mouseEventCursorName when hovering over an interactive element. false suppresses cursor changes even when callbacks are registered.

mouseEventCursorName # string
Default: ""

Name of the cursor to display on hover. When empty, defaults to the hand cursor.

Built-in cursor names: hand, text, help, busy, cross, pen, no, size_all, size_nesw, size_ns, size_nwse, size_we, uparrow, wait

When cursorsDir is set, this name is looked up as a file in that folder.

cursorsDir # string
Default: ""

Directory containing custom .cur or .ani cursor files. Relative paths are resolved against the widget's script directory. When set, mouseEventCursorName is looked up as a file inside this folder instead of using a built-in cursor.

Mouse Events ​

All mouse callbacks are optional. Each receives an event object — see Global Variables for the full list of event properties (__clientX, __clientY, __screenX, __screenY, __offsetX, __offsetY, __offsetXPercent, __offsetYPercent).

onLeftMouseUp # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onLeftMouseUp(event): void

Fired when the left mouse button is released over the element. This is the standard click handler.

javascript
ui.addText({
  id: "btn",
  text: "Click me",
  onLeftMouseUp: (e) => {
    ipcRenderer.send("btn-clicked");
  }
});
onLeftMouseDown # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onLeftMouseDown(event): void

Fired when the left mouse button is pressed down over the element.

onLeftDoubleClick # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onLeftDoubleClick(event): void

Fired on a left-button double-click over the element.

onRightMouseUp # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onRightMouseUp(event): void

Fired when the right mouse button is released over the element.

onRightMouseDown # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onRightMouseDown(event): void

Fired when the right mouse button is pressed down over the element.

onRightDoubleClick # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onRightDoubleClick(event): void

Fired on a right-button double-click over the element.

onMiddleMouseUp # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onMiddleMouseUp(event): void

Fired when the middle mouse button is released over the element.

onMiddleMouseDown # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onMiddleMouseDown(event): void

Fired when the middle mouse button is pressed down over the element.

onMiddleDoubleClick # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onMiddleDoubleClick(event): void

Fired on a middle-button double-click over the element.

onX1MouseUp / onX1MouseDown / onX1DoubleClick # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onX1MouseUp(event): void

Events for the X1 (Back) side button.

onX2MouseUp / onX2MouseDown / onX2DoubleClick # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onX2MouseUp(event): void

Events for the X2 (Forward) side button.

onMouseOver # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onMouseOver(event): void

Fired when the cursor enters the element bounds.

javascript
onMouseOver: (e) => {
  ui.setElementProperties("btn", { backgroundColor: "rgba(255,255,255,0.1)" });
}
onMouseLeave # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onMouseLeave(event): void

Fired when the cursor leaves the element bounds.

javascript
onMouseLeave: (e) => {
  ui.setElementProperties("btn", { backgroundColor: "" });
}
onScrollUp # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onScrollUp(event): void

Fired when the mouse wheel is scrolled up over the element.

onScrollDown # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onScrollDown(event): void

Fired when the mouse wheel is scrolled down over the element.

onScrollLeft # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onScrollLeft(event): void

Fired on horizontal scroll left over the element.

onScrollRight # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onScrollRight(event): void

Fired on horizontal scroll right over the element.

Drag & Drop ​

Drag and drop properties control whether an element can be dragged or act as a drop target. Drag callbacks fire when the user holds a mouse button on the element and moves the mouse.

dragArea # boolean
Default: false

true makes this element draggable. The user can click and drag the element to move it. The element does not snap or reposition automatically — use the onDrag callback to update the element position or send drag data via IPC.

javascript
ui.addShape({
  id: "handle",
  dragArea: true,
  onDrag: (e) => {
    ui.setElementProperties("handle", {
      x: e.__screenX - e.__offsetX,
      y: e.__screenY - e.__offsetY
    });
  }
});
dropTarget # boolean
Default: false

true registers this element as a drop target. When another element is dragged over it, the drop-related callbacks fire. Use this for file drop zones, reordering lists, or any drag-and-drop interaction.

javascript
ui.addShape({
  id: "drop-zone",
  dropTarget: true,
  backgroundColor: "rgba(0,180,255,0.1)",
  onDragEnter: () => {
    ui.setElementProperties("drop-zone", { backgroundColor: "rgba(0,180,255,0.3)" });
  },
  onDragLeave: () => {
    ui.setElementProperties("drop-zone", { backgroundColor: "rgba(0,180,255,0.1)" });
  },
  onDrop: (e) => {
    console.log("Dropped at:", e.__offsetX, e.__offsetY);
  }
});
onDrop # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDrop(event): void

Fired when the user releases a drag over this drop target element.

onDragEnter # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDragEnter(event): void

Fired when a dragged element enters the bounds of this drop target.

onDragOver # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDragOver(event): void

Fired continuously while a dragged element is over this drop target.

onDragLeave # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDragLeave(event): void

Fired when a dragged element leaves the bounds of this drop target.

Drag Events (on element being dragged) ​

Drag callbacks fire when the user holds a mouse button on the element and moves the mouse. They are useful for sliders, handles, and custom drag interactions.

onDragStart # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDragStart(event): void

Fired once when a drag begins.

javascript
onDragStart: (e) => {
  console.log("Drag started at", e.__offsetX, e.__offsetY);
}
onDrag # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDrag(event): void

Fired continuously while the user is dragging. Use e.__offsetXPercent and e.__offsetYPercent for normalized 0–100 position within the element.

javascript
onDrag: (e) => {
  const value = Math.max(0, Math.min(100, e.__offsetXPercent)) / 100;
  ui.setElementProperty("vol-bar", "value", value);
  ipcRenderer.send("volume-change", { value });
}
onDragEnd # FUNCTION OPTIONAL
CALLBACK

SIGNATURE

onDragEnd(event): void

Fired once when the mouse button is released after a drag.

javascript
onDragEnd: (e) => {
  console.log("Drag ended at", e.__offsetXPercent.toFixed(1) + "%");
}

Scroll & Overflow ​

When child elements extend beyond the bounds of a container (or addLayoutBox), scroll and overflow properties control whether scrollbars appear and how content is clipped.

overflow # string
Default: "visible"

Shorthand that sets both overflowX and overflowY at once. Case-insensitive.

Value Behavior
"visible" Content overflows the element bounds and is not clipped (default)
"hidden" Content is clipped at the element bounds, no scrollbar
"scroll" Content is clipped and scrollbars appear when needed
"auto" Scrollbars appear only when content overflows
overflowX # string
Default: "visible"

Horizontal overflow mode. Same values as overflow. Overrides overflow for the horizontal axis.

overflowY # string
Default: "visible"

Vertical overflow mode. Same values as overflow. Overrides overflow for the vertical axis.

scrollX # number
Default: 0

Initial horizontal scroll offset in pixels.

scrollY # number
Default: 0

Initial vertical scroll offset in pixels.

scrollStep # number
Default: 24

Number of pixels scrolled per mouse wheel notch.

showScrollbar # boolean
Default: true

Shorthand that sets both showScrollbarX and showScrollbarY at once.

showScrollbarX # boolean
Default: true

Show the horizontal scrollbar when horizontal content overflows.

showScrollbarY # boolean
Default: true

Show the vertical scrollbar when vertical content overflows.

Scrollbar Styling ​

scrollbarWidth # number
Default: 6

Scrollbar thickness in pixels.

scrollbarHoverWidth # number
Default: -1

Scrollbar thickness when hovered. -1 keeps the normal width.

scrollbarRadius # number
Default: 3

Corner radius of the scrollbar thumb.

scrollbarTrackRadius # number
Default: -1

Corner radius of the scrollbar track. -1 uses the default.

scrollbarInset # number
Default: 2

Spacing between the scrollbar and the element edge in pixels.

scrollbarMinThumbLength # number
Default: 20

Minimum thumb length in pixels.

scrollbarColor # string
Default: "rgba(255,255,255,100)"

Scrollbar thumb color. Supports rgb(), rgba(), and hex.

scrollbarHoverColor # string
Default: "rgba(255,255,255,180)"

Scrollbar thumb color when hovered.

scrollbarActiveColor # string
Default: "rgba(255,255,255,240)"

Scrollbar thumb color when actively dragged.

scrollbarTrackColor # string
Default: "rgba(0,0,0,0)"

Scrollbar track background color.

showScrollbarButtons # boolean
Default: false

Show arrow buttons at the ends of the scrollbar.

scrollbarButtonSize # number
Default: 14

Size of the scrollbar arrow buttons in pixels.

scrollbarButtonRadius # number
Default: 2

Corner radius of the scrollbar arrow buttons.

scrollbarArrowColor # string
Default: "rgba(255,255,255,150)"

Color of the scrollbar arrow icons.

scrollbarArrowHoverColor # string
Default: "rgba(255,255,255,220)"

Color of the scrollbar arrow icons when hovered.

scrollbarArrowActiveColor # string
Default: "rgba(255,255,255,255)"

Color of the scrollbar arrow icons when pressed.

scrollbarButtonBgColor # string
Default: "rgba(0,0,0,0)"

Background color of the scrollbar arrow buttons.

scrollbarButtonHoverBgColor # string
Default: "rgba(255,255,255,30)"

Background color of the scrollbar arrow buttons when hovered.

javascript
// Scrollable container with custom scrollbar
ui.addLayoutBox({
  id: "scroll-area",
  x: 16, y: 16,
  width: 300, height: 200,
  overflow: "scroll",
  scrollbarWidth: 8,
  scrollbarColor: "rgba(255,255,255,80)",
  scrollbarHoverColor: "rgba(255,255,255,160)",
  scrollbarRadius: 4
});

Practical Examples ​

Hover highlight

javascript
ui.addShape({
  id: "btn",
  shapeType: "rectangle",
  x: 16, y: 16,
  width: 120, height: 36,
  radiusX: 6, radiusY: 6,
  fillColor: "rgba(60,120,200,0.8)",
  onMouseOver: () => {
    ui.setElementProperties("btn", { fillColor: "rgba(80,150,240,0.9)" });
  },
  onMouseLeave: () => {
    ui.setElementProperties("btn", { fillColor: "rgba(60,120,200,0.8)" });
  },
  onLeftMouseUp: () => {
    ipcRenderer.send("btn-action");
  }
});

Drag slider

javascript
ui.addImage({
  id: "slider",
  path: "./assets/slider-track.png",
  x: 16, y: 60,
  width: 260, height: 20,
  tooltipText: "Drag to adjust volume",
  onDrag: (e) => {
    const value = Math.max(0, Math.min(100, e.__offsetXPercent)) / 100;
    ui.setElementProperty("vol-fill", "value", value);
    ipcRenderer.send("set-volume", { value });
  }
});

Tooltip with title and icon

javascript
ui.addText({
  id: "cpu-label",
  text: "CPU",
  x: 16, y: 14,
  width: 60, height: 20,
  fontSize: 12,
  fontColor: "rgb(180,180,180)",
  tooltipTitle: "CPU Usage",
  tooltipText: "Current processor load as a percentage of total capacity.",
  tooltipIcon: "info"
});

Grouped elements for batch show/hide

javascript
ui.beginUpdate();

ui.addText({ id: "stat-1", group: "stats", text: "CPU: 72%",  x: 16, y: 40, fontSize: 13, fontColor: "rgb(200,200,200)" });
ui.addText({ id: "stat-2", group: "stats", text: "RAM: 58%",  x: 16, y: 60, fontSize: 13, fontColor: "rgb(200,200,200)" });
ui.addText({ id: "stat-3", group: "stats", text: "Disk: 34%", x: 16, y: 80, fontSize: 13, fontColor: "rgb(200,200,200)" });

ui.endUpdate();

// Toggle all stats at once
ipcRenderer.on("toggle-stats", (event, payload) => {
  ui.setElementPropertiesByGroup("stats", { show: payload.visible });
});

Image Options ​

Options shared by all image-based elements: ui.addImage(), ui.addButton(), ui.addBitmap(), and ui.addRotator().

Use these alongside the Element Options above which covers position, visibility, tooltip, mouse events, and more.

Table of Contents ​

Opacity and Visibility ​

imageAlpha # number
Default: 255

Image opacity in the range 0–255. 255 is fully opaque, 0 is fully transparent. Values are clamped to this range.

javascript
ui.addImage({
  id: "logo",
  path: "./assets/logo.png",
  x: 16, y: 16,
  width: 64, height: 64,
  imageAlpha: 180
});

Fallback ​

fallbackPath # string
Default: ""

Path to an alternative image file shown when the primary image cannot be loaded. Supports local file paths and HTTP/HTTPS URLs. Relative paths are resolved against the widget's script directory.

javascript
ui.addImage({
  id: "avatar",
  path: "./assets/user.png",
  fallbackPath: "./assets/default-avatar.png",
  x: 16, y: 16,
  width: 48, height: 48
});
fallbackAspectRatio # string
Default: "stretch"

How the fallback image (defined by fallbackPath) is scaled when displayed. Operates independently from the main image's preserveAspectRatio.

Value Aliases Behavior
"stretch" — Fills bounds exactly, ignoring aspect ratio (default)
"preserve" "fit", "contain" Scales uniformly to fit within bounds, centered
"crop" "cover" Scales uniformly to fill bounds, cropping excess from center
javascript
ui.addImage({
  id: "banner",
  path: "https://example.com/banner.png",
  fallbackPath: "./assets/fallback.png",
  fallbackAspectRatio: "preserve",
  preserveAspectRatio: "crop",
  width: 300, height: 100
});

Color Adjustments ​

grayscale # boolean
Default: false

true renders the image without color — all pixels are converted to shades of gray. Useful for representing disabled or inactive states.

javascript
ui.addImage({
  id: "icon",
  path: "./assets/icon.png",
  grayscale: true
});
imageTint # string
Default: ""

A color overlaid on the image. Accepts rgb(), rgba(), hex, linearGradient(), and radialGradient(). Only applied when the string is non-empty and parses as a valid color.

javascript
ui.addImage({
  id: "icon",
  path: "./assets/icon.png",
  imageTint: "rgba(0,180,255,0.5)"   // blue tint at 50% opacity
});
colorMatrix # number[]
Default: []

A Direct2D 5x4 color transformation matrix applied to the image. Enables advanced effects: hue rotation, saturation, brightness, contrast, channel swaps, and inversion.

Provide exactly 20 numbers in row-major order. Fewer than 20 values are silently ignored and no matrix is applied.

The matrix layout is:

[ R→R, G→R, B→R, A→R, bias_R,
  R→G, G→G, B→G, A→G, bias_G,
  R→B, G→B, B→B, A→B, bias_B,
  R→A, G→A, B→A, A→A, bias_A ]

The identity matrix (no change):

javascript
colorMatrix: [
  1, 0, 0, 0, 0,
  0, 1, 0, 0, 0,
  0, 0, 1, 0, 0,
  0, 0, 0, 1, 0
]

Invert all colors:

javascript
ui.addImage({
  id: "inverted",
  path: "./photo.png",
  colorMatrix: [
    -1,  0,  0, 0, 1,
     0, -1,  0, 0, 1,
     0,  0, -1, 0, 1,
     0,  0,  0, 1, 0
  ]
});

Desaturate (grayscale via matrix):

javascript
colorMatrix: [
  0.33, 0.33, 0.33, 0, 0,
  0.33, 0.33, 0.33, 0, 0,
  0.33, 0.33, 0.33, 0, 0,
  0,    0,    0,    1, 0
]

TIP

The grayscale property is a simpler alternative to a desaturate matrix when you only need black-and-white rendering.

Flip ​

imageFlip # string
Default: "none"

Mirrors the image before rendering. Matching is case-insensitive.

Value Effect
"none" No flip (default)
"horizontal" Mirror left to right
"vertical" Mirror top to bottom
"both" Mirror both horizontally and vertically
javascript
ui.addImage({
  id: "arrow-right",
  path: "./assets/arrow-left.png",
  imageFlip: "horizontal"   // reuse the left arrow as a right arrow
});

Crop ​

imageCrop # number[]
Default: []

Crops the source image to a rectangular region before rendering. Coordinates are in source image pixels.

Accepted forms:

  • [x, y, width, height] — crop from the given origin (default: top-left)
  • [x, y, width, height, origin] — crop with an explicit reference corner

The optional fifth element sets the reference corner for the x/y coordinates:

Value Reference corner
0 Top-left (default)
1 Top-right
2 Bottom-right
3 Bottom-left
4 Center

Values outside the 0–4 range are clamped. An empty or missing array disables cropping.

Not supported on addBitmap or addRotator

imageCrop is accepted but ignored by ui.addBitmap() and ui.addRotator(). It only applies to ui.addImage() and ui.addButton().

javascript
// Show only the top-left 64x64 region
ui.addImage({
  id: "sprite",
  path: "./assets/spritesheet.png",
  imageCrop: [0, 0, 64, 64]
});

// Crop 32x32 from the center of the source image
ui.addImage({
  id: "center-crop",
  path: "./assets/photo.png",
  imageCrop: [0, 0, 32, 32, 4]   // origin = center
});

Orientation ​

useExifOrientation # boolean
Default: false

true applies the rotation/flip specified in the EXIF metadata embedded in the image file. Useful for photos taken on mobile devices that store their orientation in EXIF data rather than in the pixel arrangement.

javascript
ui.addImage({
  id: "photo",
  path: "./assets/photo.jpg",
  useExifOrientation: true
});

Practical Examples ​

Grayscale inactive icon that highlights on hover

javascript
ui.addImage({
  id: "settings-icon",
  path: "./assets/settings.png",
  x: 16, y: 16,
  width: 24, height: 24,
  grayscale: true,
  onMouseOver: () => {
    ui.setElementProperties("settings-icon", { grayscale: false });
  },
  onMouseLeave: () => {
    ui.setElementProperties("settings-icon", { grayscale: true });
  }
});

Tinted status indicator updated from IPC

javascript
ui.addImage({
  id: "status-dot",
  path: "./assets/circle.png",
  x: 8, y: 8,
  width: 12, height: 12,
  imageTint: "rgba(100,100,100,1)"
});

ipcRenderer.on("status-update", (event, payload) => {
  const tint = payload.online
    ? "rgba(0,200,100,1)"
    : "rgba(200,60,60,1)";
  ui.setElementProperties("status-dot", { imageTint: tint });
});

Sprite sheet crop for different states

javascript
// Single sprite sheet with frames at x=0, 64, 128
function setButtonState(state) {
  const frameX = state === "normal" ? 0 : state === "hover" ? 64 : 128;
  ui.setElementProperties("btn-img", {
    imageCrop: [frameX, 0, 64, 32]
  });
}

ui.addImage({
  id: "btn-img",
  path: "./assets/button-states.png",
  x: 16, y: 60,
  width: 64, height: 32,
  imageCrop: [0, 0, 64, 32],
  onMouseOver: () => setButtonState("hover"),
  onMouseLeave: () => setButtonState("normal"),
  onLeftMouseDown: () => setButtonState("pressed"),
  onLeftMouseUp: () => setButtonState("hover")
});

Fallback for user-provided images

javascript
ui.addImage({
  id: "wallpaper",
  path: path.join(__mainScriptDirPath, "config", "wallpaper.jpg"),
  fallbackPath: "./assets/default-wallpaper.jpg",
  x: 0, y: 0,
  width: 400, height: 300,
  preserveAspectRatio: "crop"
});