Record tab behaviour (position, close buttons, defaults, maximumTabs, labels) and the web limits; ISS-067. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
241 lines
16 KiB
Markdown
241 lines
16 KiB
Markdown
---
|
||
task: Configure operator layouts (Layouts.xml): windows, menus, toolbars, frames, popups; open displays in frames and layouts
|
||
version: R1.03
|
||
source: Layouts.readme (installed, %TLS_WAP_PATH%\cfg\operatorInterfaces\DEPLOY\layouts); IM 36K10R30-01EN §1, §4.7; IM 36K10C50-01EN §4.12; practiced with CI-Eng-Sample (layout CIENG_Operator) in the Operator Interface (desktop) and the HTML display 2026-10-01; parameter-by-parameter test (§6) on both clients 2026-10-02, web behaviour also read from the installed web client code (mobileoperator fasttools.min.js)
|
||
status: verified (parameters tested on desktop and web 2026-10-02 except print orientation/margins, playback, multi-screen positions and the maximumTabs limit for new tabs)
|
||
---
|
||
|
||
# Operator layouts
|
||
|
||
A **layout** is a window of the Operator Interface: optional menu and toolbars, a **frame set**
|
||
(required) holding displays, and a status line. All layouts of a deployment are in one file,
|
||
`%TLS_WAP_PATH%\cfg\operatorInterfaces\DEPLOY\layouts\Layouts.xml`, used by **both** the
|
||
Operator Interface (desktop) and the HTML display (web). The complete option and command
|
||
reference is `Layouts.readme` in the same folder; `Layouts-original.xml` is the factory copy.
|
||
|
||
## 1. Rules
|
||
|
||
- `Layouts.xml` is shared by every operator: back it up and change it only with the user's
|
||
approval. Keep project layouts in a marked block so they can be removed cleanly (sample:
|
||
`examples/CI-Eng-Sample/layouts/layout.ps1` + `CIENG_Operator.xml`; the script checks the XML
|
||
is well-formed, keeps UTF-8 without BOM and CRLF, and `-Remove` restores the file byte for byte).
|
||
- **The Operator Interface reads `Layouts.xml` only when it starts.** After a change, close and
|
||
restart it. A running client does not know a new layout: opening a display in it only reloads
|
||
the current window ("blink"). The Edit Module also needs a restart to offer the new name in
|
||
the *Open display* action.
|
||
- Name the main frame **`default`**: the factory and AOG displays (alarm lists, faceplates,
|
||
toolbar commands) open their targets in a frame called `default`. At login the user profile's
|
||
*Initial display* replaces the `initialDisplay` of frame `default` (desktop; web: `?d=`).
|
||
- Layouts used by **both** clients must have the web-compatible shape (§6.1): per frame set at
|
||
most one `n*` division, and at most one nested frame set, placed in that `n*` slot. Always
|
||
set `title` and `drawBorder`.
|
||
- Menu items whose command has an on/off state (`toolbar`, `statusline`, `playback record`)
|
||
**must** be `type="check"`: otherwise the Operator Interface fails at start
|
||
(`ClassCastException … JCheckBoxMenuItem`).
|
||
|
||
## 2. Structure
|
||
|
||
```xml
|
||
<layout name="<Name>" title="<text> $default" icon="poi.png" drawBorder="true"
|
||
sizingAllowed="true" minimizingAllowed="true" closingAllowed="true" alwaysOnTop="false"
|
||
initialPosition="centreScreen" initialSize="pixels" initialSizeWidth="1600"
|
||
initialSizeHeight="900" maximumOpen="1">
|
||
<menu> <menu-item name="m.file" label="File"> <menu-item … command="exit"/> </menu-item> … </menu>
|
||
<toolbar name="t1" floatable="false" position="top"> <toolbar-item icon="ciNavLeft32.png"
|
||
tooltip="Back to $" command="navigate back default"/> … </toolbar>
|
||
<frame-set rows="1*,fitDisplay"> <!-- main area, alarm banner below -->
|
||
<frame-set cols="fitDisplay,1*"> <!-- navigation left, main right -->
|
||
<frame name="nav" initialDisplay="<NavDisplay>" zoomingAllowed="false"/>
|
||
<frame name="default" initialDisplay="<Overview>" stackSize="10" zoom="fitDisplay"/>
|
||
</frame-set>
|
||
<frame name="alarmBannerFrame" initialDisplay="AOG_AlarmBanner" zoom="stretchDisplay"/>
|
||
</frame-set>
|
||
<status-line> <status-line-item type="statusText"/> <status-line-separator/> … </status-line>
|
||
</layout>
|
||
```
|
||
|
||
- `title`: `$<frame>` = title of the display in that frame (verified: *CI-Eng-Sample - Current
|
||
Alarm Overview*).
|
||
- Window: `initialPosition` (`centreScreen`, `atCursor`, `pixelsScreen2`, `centreLayout`, …),
|
||
`initialSize` (`pixels`, `screenSize`, `desktopSize`, `fitFrames`), `maximumOpen`, `modal`,
|
||
`alwaysOnTop`, print options.
|
||
- Frame sets: `rows` / `cols` with pixels, `n*` or `fitDisplay` (fractions are not honoured and
|
||
the web client limits nesting: §6.1); a `<tab>`
|
||
holds several frames as tabs (`tabPosition`, `maximumTabs`, `closeTabAllowed`). Frame options:
|
||
`name`, `initialDisplay` (= home display), `stackSize` (back/forward history), `zoom`
|
||
(`fitDisplay`, `stretchDisplay`, `<n>%`), `zoomingAllowed`, `scrollingAllowed`, `borderStyle`.
|
||
- Menu (max. two levels; `type` normal/check/radio/sub; `mnemonic`, `accelerator` like `F5`,
|
||
`CONTROL P`) and toolbar items (`icon` from the factory set such as `ciNavLeft32.png`,
|
||
`ciProAlar32.png`, `ciZoomFull32.png`; `type` combo/editableCombo/dropdownList) run commands:
|
||
|
||
| Command | Effect |
|
||
|---|---|
|
||
| `navigate to <frame> <display> [<zoom>] [<p>=<v>;…]` | Open a display in a frame (with parameters) |
|
||
| `navigate back/forward/up/home/history <frame>` | Frame history (`$` in the tooltip = target name) |
|
||
| `reload <frame>` / `reload all` | Reload displays (keeps the session in the HTML display) |
|
||
| `zoom <level> <frame>` | 0 = fit, 1 = 100 %, 10–1000 = relative % |
|
||
| `toggleSize fullScreen [n]` / `toggleSize x,y,WxH` | Full screen / given size and back |
|
||
| `print frame|frameWithSetup|preview|setup|selectFrame` | Printing (desktop only) |
|
||
| `login`, `logout`, `exit`, `toolbar`, `statusline`, `playback record|view`, `shell client|server <cmd>`, `lookfeel <class>` | |
|
||
| `help` | Listed in the readme but fails in R1.03: *Unrecognized keyword* (ISS-062) — do not use |
|
||
|
||
The installed status line also uses item types `displayName`, `playbackIndicator` and
|
||
`dateTime`, which the readme does not list (ISS-042).
|
||
- `<translations name="nl">` blocks translate labels per locale (key = item name + `.label`).
|
||
|
||
## 3. Opening displays in frames and layouts
|
||
|
||
| From | How |
|
||
|---|---|
|
||
| Button / component (Edit Module, *Actions* sheet → *Open display*) | Display, **Layout** (empty = current window), **Frame**, parameters; stored as `<action type="actionActivateDisplay">` with `<type … value="ActivateSpecific"/>`, `<display>`, `<layout>`, `<layoutFrame>` |
|
||
| Menu / toolbar | `navigate to <frame> <display>` (current window only) |
|
||
| Login | User profile *Layout* and *Initial display* (Engineering Module, Authorization > Users); empty layout = `default` (from docs; not changed on the test system) |
|
||
| HTML display | URL `?d=<display>&l=<layout>` |
|
||
| Script on a component | *Execute command* with `ACTION <layout command>`, e.g. `ACTION toggleSize 50,50,710x520` |
|
||
|
||
Verified behaviour (desktop): a button with layout `CIENG_Operator` opened a **second window**
|
||
(1600 × 900, own menu/toolbar/frames); buttons without layout opened their display in the main
|
||
frame of the current window; **Back** returned. A button with layout `popup` opened a separate
|
||
window: always on top, only a close button, sized to the display (`fitFrames`), and minimised
|
||
together with the window that opened it — use popups only for small displays (faceplates,
|
||
setpoint dialogs).
|
||
|
||
## 4. Typical project layouts
|
||
|
||
- **Operator main window**: navigation frame + main frame `default` (+ tabs) + alarm banner,
|
||
project menu/toolbar, assigned to operators via the user profile *Layout*.
|
||
- **Kiosk / control-room screen**: `drawBorder="false"`, `alwaysOnTop="true"`,
|
||
`initialSize="screenSize"`, `closingAllowed="false"`, `minimizingAllowed="false"`.
|
||
`toggleSize fullScreen` covers the taskbar only when `alwaysOnTop="true"` (verified: with
|
||
`false` the title bar and taskbar stay).
|
||
- **Popups / faceplates**: small layout with one frame `default`, `initialSize="fitFrames"`,
|
||
`initialPosition="atCursor"`, `alwaysOnTop="true"`, `maximumOpen` > 1 for several faceplates
|
||
(factory: `popup`, `FixedPopup`, `ResizablePopup`, `faceplate`, `tuningpanel`, `Setpoint`,
|
||
`SelectMode`).
|
||
- **Several screens**: one layout per screen with `initialPosition="pixelsScreen2"` /
|
||
`centreScreen2`, or the dual-screen pattern of IM 36K10R30 §1.10.
|
||
|
||
## 5. HTML display differences
|
||
|
||
The browser window is the main layout (its size and window options are ignored); other layouts
|
||
open as windows inside the page; print, look-and-feel and the debug key are not supported; pick
|
||
the layout with `&l=`. Verified: `?d=CIENG_Tank&l=CIENG_Operator` showed the sample menu,
|
||
toolbar, navigation frame and banner.
|
||
|
||
## 6. Parameter reference: desktop vs web (tested 2026-10-02)
|
||
|
||
Test method: a marked test block in `Layouts.xml`; each layout started on the desktop with
|
||
`jwuipoi.cmd -layout <name>` (start options from the installed client: `-layout`, `-display`,
|
||
`-host`, `-port`, `-secure`, `-hide`, `-timeout`, `-readtimeout`, `-ssotoken`) and in the browser
|
||
with `?d=<display>&l=<layout>`. Desktop windows checked with window captures, web pages in the
|
||
browser and in the web client code. "n/a" = the browser window is the main layout.
|
||
|
||
### 6.1 Frames
|
||
|
||
| Parameter | Desktop | Web |
|
||
|---|---|---|
|
||
| `rows`/`cols` in pixels | exact | exact |
|
||
| `fitDisplay` | fits the display | edge panel only; default 200 px (left/right) or 50 px (top) |
|
||
| `n*` fractions (`2*,1*`) | **not honoured** (sizes follow the displays, e.g. 800:88 px) | every `n*` becomes the *main* panel; two `n*` overwrite each other, only the last display shows |
|
||
| Divisions per frame set | any | first = top/left, last = bottom/right, `n*` = main; more do not fit |
|
||
| Nested `frame-set` | anywhere, several | **always placed in the parent's main panel**; two nested sets, or one in an edge position, break the page (stays on *Loading…*) |
|
||
| Frame `zoom` (`fitDisplay`, `stretchDisplay`, `n%`) | applied | ignored (always 100 %) |
|
||
| `borderStyle` | drawn | only with `drawBorder="true"`; every value except `none` becomes a 1 px line |
|
||
| `stackSize` | honoured | honoured; default when missing = 1 |
|
||
| `zoomingAllowed="false"` | `zoom` commands on that frame do nothing | zoom not supported at all |
|
||
| `scrollingAllowed` | scrollbars when the display is larger | panel overflow auto/hidden |
|
||
| `initialDisplay` of frame `default` | replaced by the user profile's initial display | replaced by `?d=` |
|
||
|
||
### 6.2 Window (`<layout>`)
|
||
|
||
| Parameter | Desktop | Web |
|
||
|---|---|---|
|
||
| `title` | `$<frame>` → display **title** | `$<frame>` → display title or name; **missing `title` → tab shows "undefined"** and a script error |
|
||
| `icon` | title bar and taskbar | favicon |
|
||
| `drawBorder` | default **false** = no title bar and no border | frame borders only |
|
||
| `sizingAllowed`, `minimizingAllowed` | default **false** | n/a |
|
||
| `closingAllowed="false"` | close button still shown, closing is ignored; closing the last window ends the client | n/a |
|
||
| `alwaysOnTop` | topmost window | n/a |
|
||
| `initialPosition` `pixels`, `pixelsScreen1`, `centreScreen` | exact | n/a |
|
||
| `initialSize` `pixels` / `fitFrames` / `screenSize` / `desktopSize` | exact / wraps the display / whole screen incl. taskbar (same on one screen) | n/a |
|
||
| Defaults (nothing set) | borderless, at 0,0, sized to the display | works |
|
||
| `lookAndFeel` (Metal) | applied; adds a second (Metal) title bar inside the window | n/a |
|
||
|
||
### 6.3 Menu, toolbars, status line
|
||
|
||
| Item | Desktop | Web |
|
||
|---|---|---|
|
||
| `type="sub"` / `check` / `radio` | work (radio bullet, check tick) | **not shown** (items dropped) |
|
||
| `accelerator` | F11 works; F5 / ALT keys not confirmed | — |
|
||
| `$` in `tooltip` | resolved | resolved |
|
||
| Toolbar `position="top"` | shown | shown |
|
||
| Toolbar `left` / `right` | shown | **not shown** |
|
||
| Toolbar `bottom` | **not shown** (two layouts tried) | not shown |
|
||
| Toolbar item `combo`, `editableCombo`, `dropdownList` | shown | shown |
|
||
| Status line, all 8 types | shown | shown |
|
||
|
||
### 6.4 Commands
|
||
|
||
| Command | Desktop | Web |
|
||
|---|---|---|
|
||
| `navigate to <frame> <display> [zoom] [params]` | works, zoom applied | works, **zoom ignored** |
|
||
| `navigate back/forward/home/up/history/backList/forwardList` | work | work (`home` is added to the history) |
|
||
| `reload <frame>` / `reload all` | work | work |
|
||
| `zoom <level> <frame>` (0, 1, 2, 0.5, 150) | work | not supported |
|
||
| `toggleSize fullScreen [n]` | work area (taskbar stays unless `alwaysOnTop`); again = back | browser full screen; screen number ignored |
|
||
| `toggleSize x,y,WxH` | works; again = back | not possible in a browser tab |
|
||
| `toolbar` (check) | hides/shows **all** toolbars; `toolbar false` behaves as a toggle too | no effect |
|
||
| `statusline` (check) | hides/shows (a piece of the date field stays painted) | no effect |
|
||
| `print …` | preview / setup dialogs open | disabled |
|
||
| `login` / `logout` / `exit` | — / — / closes | login disabled; logout, exit work |
|
||
| `shell client <cmd>` | runs on the client (Notepad opened) | sent to the server; `shell client ACTION <layout command>` runs a layout command |
|
||
| `lookfeel <class>` | — | no effect |
|
||
| `playback record` (check) / `view` | — | not supported (view disabled) |
|
||
| `help` | **error** *Unrecognized keyword* | — |
|
||
|
||
"—" = not checked.
|
||
|
||
### 6.5 Layouts opened from a display, translations, debug key
|
||
|
||
Tested with a launcher display (copy of `CIENG_Menu` whose buttons use *Open display* with a
|
||
layout and frame `default`).
|
||
|
||
| Parameter | Desktop | Web |
|
||
|---|---|---|
|
||
| `modal="true"` | dialog window (no min/max); the opener is disabled until it closes | in-page window with a full-page lock; centred |
|
||
| `maximumOpen="2"` | 2 windows; the 3rd click: *The display '…' cannot be activated because the maximum number of windows is reached* | same (in-page windows, same message) |
|
||
| Popup size (`initialSize="pixels"`) | applied | applied (500×350, 450×300) |
|
||
| `initialPosition="centreFrame"` | **at 0,0** (not centred) | centred in the page |
|
||
| `initialPosition="centreLayout"` | near the opener, not exactly centred (opener partly off-screen) | centred in the page |
|
||
| `atCursor` / `awayFromCursor` | opened at 1677,363 near the launcher click (cursor position not logged) / at 10,890, the far bottom-left corner | — |
|
||
| `<translations name="<locale>">` | applied for the exact JVM locale (`en_AU` here): layout `title`, menu and toolbar `label`, `tooltip`; **no fallback** from `en_AU` to `en` | browser locale `en-US`: neither `en_AU` nor `en` applied |
|
||
| `debugActivationKey` (`CONTROL SHIFT F6`) | opens the *Graphics debugger* (connections and parameters of the display) | not supported (see §5) |
|
||
|
||
Keys: `<layout name>.title`, `<item name>.label|tooltip|mnemonic|accelerator`. The desktop
|
||
locale comes from Windows (the start script sets no `-Duser.language`).
|
||
|
||
### 6.6 Tabs (`<tab>`)
|
||
|
||
Factory pattern (works on both clients): a `<tab name="default">` holding frames `tab1`,
|
||
`tab2`, … in the `n*` slot of a **nested** frame set, next to the navigation frame.
|
||
|
||
| Parameter | Desktop | Web |
|
||
|---|---|---|
|
||
| Tab labels | display title (the profile's initial display goes into the first tab) | display name |
|
||
| `tabPosition` `bottom` / `left` | applied | **ignored** (always top) |
|
||
| `navigate to <tab set name> <display>` | replaces the display in the **active** tab; no new tab | — |
|
||
| `navigate to <tab frame name> <display>` | shows it in that tab | — |
|
||
| `closeTabAllowed` on a tab frame | `true` = close button, `false` = none; closing works | same |
|
||
| `closeTabAllowed` (and other defaults) on `<tab>` only | **not inherited** by the frames (no close buttons) | not inherited |
|
||
| `maximumTabs` | does not limit the initial tabs (`1` with 2 frames shows 2); the limit for new tabs was not reached by `navigate`, so not confirmed | initial tabs not limited |
|
||
| `minimumTabLabelWidth`, `tabButtonGap` | no visible effect | — |
|
||
| Frame with `initialDisplay=""` | empty tab | — |
|
||
| Tab set next to the nav frame at the **top level** (with menu, empty tab) | works | **hangs** on *Loading…* (nav frame not created); the factory shape works |
|
||
|
||
## Verified (CI-Eng-Sample, 2026-10-01)
|
||
|
||
`layout.ps1` add / remove / add (removal identical to the original, backup kept); Operator
|
||
Interface restart required before the layout was found; desktop and web windows as described
|
||
above; F11 (`toggleSize fullScreen`) worked within the taskbar limits; after restarting the
|
||
Operator Interface the main window still used the factory `default` layout (Admin profile
|
||
unchanged).
|