Skip to main content
Version: 0.1

Screen designer

This page describes the screen editor in the dashboard: where screens are listed and created, what the editor's panels and canvas do, how a widget property is bound to a tag, and how saving behaves when two people edit the same screen. It is for engineers. Editing screens needs the engineer or administrator role; a viewer or operator who opens the editor URL sees "You can run this screen, not change it".

The API calls a screen a view: routes live under /api/v1/views. See the Screens API.

The Screens list​

Open Screens, then Editor in the dashboard rail (/views; the page itself is titled Screens). It has a folder tree on the left and a detail pane on the right.

  • New screen opens a form with Name and Canvas size. Size presets are 1920 × 1080 (Full HD), 1600 × 900, 1366 × 768, 1280 × 720 (HD), 1024 × 768 and Custom size… (width and height, at least 8 px). Creating a screen opens it in the editor.
  • Names must be unique once slugified: screens open by name (/hmi/<slug>), and the form refuses a name whose slug already exists. The slug is the name in lower case, spaces as -, everything except a-z, 0-9 and - removed.
  • A right click on a screen offers Design, Open, Rename, Pin / Unpin, Move to… and Delete. A right click on a folder offers New screen here and New Subfolder. Screens can also be dragged onto a folder.
  • New folder at the foot of the tree creates a folder path (Area/Line). Folders come from GET /api/v1/views/folders plus the folders implied by existing screens.
  • Selecting a screen shows a scaled preview, Design, Open, Pin and delete, its size, component count and last update, and editable Folder and Description.
  • Pinned screens opens the start-screen pane; see Start screens.
  • With no screens yet, Create the example plant builds a small water-treatment overview with its own memory tags, labelled "Example" wherever it is listed.

Deleting a screen asks first: pins that open it, and other screens that embed it, will point at nothing.

The editor​

The editor fills the window. Its title bar has Back to screens, the screen name (editable in place), a save state (Saved, Unsaved changes, Saving, Not saved), who else is editing, Discard changes, Preview / Stop preview, Open screen and Save.

Panels​

Four panel groups can be docked in the left or right column, floated, or hidden; the layout is remembered.

PanelWhat it holds
ComponentsThe palette of widgets, grouped, with search. Click to place, or drag onto the canvas. See Widgets.
TagsA tag browser with live values. Drag a tag onto the canvas or onto a widget.
StructureThe component tree (hierarchy) with containers, groups and layers; rename, lock, hide and reorder here.
PropertiesThe screen's own settings when nothing is selected; the selected widget's settings otherwise.

A status bar under the canvas shows the cursor position in screen coordinates, the component count or n selected, a count of broken references when there are any, and the zoom percentage.

Canvas​

  • Zoom runs from 10% to 400%. Ctrl + scroll zooms toward the cursor; + and - step by 10%; 0 returns to 100%; F fits the screen in view and Shift+F fits the selection.
  • Pan with Space + drag, or by scrolling (Shift + scroll pans horizontally).
  • Grid and snap: the grid is 8 px. G shows or hides it, S turns snapping on or off. While dragging, alignment guides to neighbouring components win over the grid; hold Ctrl to ignore guides. Hold Alt to measure distances to edges or to what is under the pointer.
  • Selection: click selects; Shift+click adds or removes; a marquee dragged left to right selects what is fully inside, right to left selects what it touches. Ctrl+A selects everything on unlocked, visible layers. Tab and Shift+Tab step through components. F6 moves focus off the canvas to the next panel.
  • Align and distribute: the toolbar aligns the selection left, center, right, top, middle or bottom, and distributes it with equal spacing horizontally or vertically.
  • Groups: Ctrl+G groups the selection into a container; Ctrl+Shift+G ungroups.
  • Z-order: Ctrl+] and Ctrl+[ move one step forward or backward; Ctrl+Shift+] and Ctrl+Shift+[ move to front or back. The Z-index field in the properties panel sets it directly.
  • Layers live in the screen's metadata; each can be hidden or locked, and a locked layer's components cannot be selected on the canvas.
  • Copy, paste, duplicate: Ctrl+C, Ctrl+V (pasted at the cursor when it is over the canvas, otherwise offset), Ctrl+D duplicates 24 px down and right. Ctrl+Alt+C and Ctrl+Alt+V copy and paste only the style. Pipe connections follow a copy only when both ends were copied.
  • Undo and redo: Ctrl+Z and Ctrl+Y (or Ctrl+Shift+Z). The history keeps 60 steps; typing and nudging collapse into one step per burst.
  • Transform: arrows move 1 px, Shift + arrows 10 px; R rotates 90° (Shift+R the other way); H and V flip; Shift while dragging a corner keeps proportions; L locks; F2 renames.
  • Drawing tools: P starts the pipe tool; A opens quick-add, a search box that places a widget by name at the cursor. While drawing a polyline, polygon or pipe, Backspace takes back a point and Enter or a double click finishes; hold Shift to draw several shapes in a row. Esc returns to select.
  • ? opens the full list of shortcuts.

New components get an ISA-style name: P-101, P-102 for symbols with a prefix, label1, label2 otherwise.

Screen settings​

With nothing selected, the Properties panel shows the Screen and Parameters sections.

SettingValues
Size, Width, HeightPresets (including Faceplate 480 × 360) or custom pixels. Components are placed in this coordinate space.
BackgroundA CSS color; empty means the app background.
Color schemeInherit from app, Force dark, Force light.
In the viewerOperator's choice (the viewer offers Fit or Actual size), Always fit (scale to the window, keeping the aspect ratio), Stretch (fill the window).
Used asOperator screen, Faceplate popup, Template. Faceplates and templates are parts: they are left out of the viewer's navigation and of the pin list.

Parameters​

A screen can declare parameters. Each has a name and, optionally, a tag type (UDT) path such as @types.Motors.Motor. Write {name} inside a tag path anywhere on the screen, for example {motor}.speed. When the screen runs, the parameter values are substituted into tag paths, expression bindings and action tags; they are never substituted into script source. A parameter typed to a tag type offers an instance picker when the template is placed, and the tag path input completes {motor}. to the type's members. See Templates and popups.

Screens with parameters are not listed as places to navigate to.

Binding a property to a tag​

Many widgets have a primary Tag path, and most of their visible properties (text, unit, min, max, decimals, colors, border, font size, padding, transform scale and offset, tooltip, image source) are bindable: each can be a static value, a tag binding or an expression.

  • Drag from the Tags panel onto a widget to set its tag path (onto a tank it sets the level tag). Drop it on empty canvas and the editor asks which widget to create for it. Only tags of kind opcua, mqtt, derived, expression, system, memory, client or external can be dragged; folders and types open instead.
  • Type a path in the Tag field, or press the browse button to pick one. Paths are full tag paths (plant.area.tag); {param} prefixes are completed from the screen's parameters.
  • Bind another property: each bindable field has a small mode button at its right edge with Static, Tag and Expression. A tag binding is stored as {"_b":"tag","path":"..."}; an expression as {"_b":"expr","code":"..."}.
  • Expressions run in the browser with tag(path) (current value), tags (every subscribed value) and val (the widget's primary tag value). Code containing return is treated as a function body; otherwise it is one expression. Paths written as tag("...") literals are subscribed automatically. An expression that throws falls back to the property's default.

A path or template reference that points at nothing is a broken reference; the status bar counts them and a save with broken references warns after saving.

Visibility​

The Visibility section sets Show when: Always, or a comparison (=, ≠, >, ≥, <, ≤) of the widget's primary tag value against a Value. This is stored as showWhen: {when, value}. A widget's showWhen can also carry an expr string: the widget is shown while that expression is truthy, using the same tag, tags and val as a binding, and then when and value are not needed. The expression form is stored on the component; the panel edits the comparison form.

Style and transform​

The Style section covers background, foreground, border color, width, style and radius, font size and weight, alignment, padding, line height, letter spacing and opacity. The Transform section scales, offsets and clamps a numeric value before display and sets a Format string. Layout fields depend on the parent: X, Y, W, H and Rotation ° in a coordinate container, Grow, Shrink, Basis and Align self inside a flex container.

Events and actions​

A widget's Events section lists On click and, for input widgets, On value change. Each event holds an ordered list of actions. A screen also has open, close and timer events (the timer interval is timerMs, default 5000 ms, floor 250 ms).

ActionWhat it does
Write tagWrites a value to a tag. "1" becomes 1, "true" becomes true; an empty value writes 1.
Toggle tagReads the current value and writes its inverse (booleans flip; 1/0 swap).
NavigateOpens another screen by id or name, optionally passing parameters (tag-path references).
Open popupOpens a screen as a popup with optional width, height, modal flag and parameters.
Open URLOpens a URL, in the same or a new tab.
Set variableWrites a value to a tag used as a variable (user or session scope is resolved by the gateway).
ConfirmAsks the operator; No stops the rest of the list.
Script (server)Runs the stored script on the gateway. Only the script's address is sent; see Screen scripts.

Each action can have a then chain that runs after it. Actions run in order. A role that cannot write tags does not run an event list that contains a write, toggle or variable action.

Preview​

Preview runs the working copy with live tag values, including unsaved edits, scaled to fit. Writes are not sent: a control shows a toast "Preview: would write ... to ...", and scripts return nothing. The design canvas stays mounted underneath, so selection and undo history survive a preview. Open screen opens the saved screen as operators see it and is disabled while there are unsaved changes.

Saving and conflicts​

Save (or Ctrl+S, from anywhere in the editor) sends PUT /api/v1/views/{id} with the name, metadata, components and baseUpdatedAt, the version the editor loaded or last saved. If someone else has saved since, the gateway writes nothing and answers 409 CONFLICT with the current screen. The editor then shows Someone else saved this screen with the time of their save and a list of what differs: the name, the screen settings, and each component that is only in your version, only in theirs, or different in both. Choose:

  • Keep mine: saves again with force: true, overwriting their version.
  • Use their version: replaces your working copy with theirs; your unsaved changes are discarded.
  • Cancel: keeps editing without saving.

Leaving the editor with unsaved changes asks first, both for in-app navigation and for closing the tab.

Who else is editing​

While a screen is open, the editor reports to POST /api/v1/views/{id}/presence every 15 seconds and shows the other editors in the title bar ("Ann is also editing"). An editor that stops reporting is forgotten after 45 seconds; closing the editor sends DELETE on the same route. Presence is a courtesy: the conflict check at save time is what protects the data.

Make template​

The toolbar's Make template turns the selection into a reusable screen: it creates a new screen in the Templates folder with the selected components, turns the tag prefix they share into a {tag} parameter, and replaces them with a template widget pointing at it. See Templates and popups.