@vestra-player/sdk 1.6.10 → 1.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.11
4
+
5
+ **Who must change: nobody.** Additions only: a mount slot, a panel position, a button icon and `TestHost` support; `apiVersion` stays `vestra/1`, no new capability. A plugin that mounts `"adjust"` sets `minPlayerVersion` to `0.7.6`: older players refuse the slot (`invalid`), which fails the activation like any refused mount.
6
+
7
+ - **The adjust slot** (player 0.7.6, menu redesign step 3b): `plugin.panels.mount("adjust", file, { title })` puts a panel in the adjust column, for controls that change what is playing (picture, sound, subtitles, speed). Any number of plugins mount there, one tab each. The slot is a contract about purpose; the player decides how it looks and may change that. The rule, in [Slots](docs/explanation/ui.md#slots-what-each-one-is-for) and on `Panels.mount`: if the user still looks at the panel after closing it, it is `"sidebar"`; otherwise it is `"adjust"`. Today the player draws a second column between the video and the sidebar, with text tabs and the opening key under each title (the key of the command the panel's commands name as their `home`), no close or detach button, floating over the video in a narrow window and sliding out from the right edge in fullscreen; it starts closed and is compiled the first time it opens.
8
+ - **`plugin.panels.adjust`**: the position, the same shape as `panels.sidebar` without `setDetached` (`PanelSlot`: `state`, `panels`, `onChange`, `setVisible`, `toggle`, `activate`). `Panel.show` and `Panel.toggle` work on an adjust panel as on a sidebar tab. Players before 0.7.6 build the `plugin` object with their own SDK, which has no `adjust`: there `plugin.panels.adjust` is `undefined` and reading its `state` throws a `TypeError` (as for `commands.keys`), so declare `minPlayerVersion` 0.7.6 or test it first.
9
+ - **Wire**: `ui.mount` and `layout.set` take `slot: "adjust"`; `layout.state` reports `adjust` (a `LayoutSlot`, never `detached`); `LayoutSlot` names the adjust column.
10
+ - **`BAR_BUTTON_ICONS`** gains `"sliders"` (the player's Adjust button), and `BUILTIN_COMMANDS` the player's `host/adjust`. `@vestra/bar-buttons.slint` (synced): `BarButtonsHost.adjust`, counted in `fixed`; `@vestra/icons.slint`: `sliders`.
11
+ - **`TestHost`**: `layout.adjust` (starts hidden), `mountOther("adjust", …)`, `selectTab` for adjust tabs, `layout.set` refuses detaching the adjust column, `keepsRunning` names an open adjust column's current tab; an unknown mount slot is refused with `invalid`, as by the player.
12
+ - **Example** [adjust-panel](docs/examples/adjust-panel.md): a speed slider in the adjust column, opened and closed by its own key.
13
+
3
14
  ## 1.6.10
4
15
 
5
16
  **Who must change: nobody.** Additions only: a clip format, optional export fields, two optional `JobState` fields, an error code and a `TestHost` field. `apiVersion` stays `vestra/1`, no new capability (`media.control` covers them). A plugin that does not use them sends exactly what it sent before; one that uses them needs player 0.7.6: declare `"minPlayerVersion": "0.7.6"`, or compare `plugin.app.version` with 0.7.6 to offer them only where they exist (do not probe by trying: on an older player `plugin` comes from that player's own, older SDK, which rejects `format: "copy"` with `invalid` but builds a re-encode request without the `encoding` it does not know, so the clip is encoded with the fixed settings and no error), and leave `progress`, `start` and `end` out.
@@ -136,7 +136,9 @@ export declare const MENU_IDS: readonly ["open", "playback", "subtitles", "video
136
136
  * The icons a bottom-bar button may name (`CommandOptions.button.icon`):
137
137
  * every icon of the player's V-Line set, `@vestra/icons.slint` (draw one
138
138
  * in your own Slint with `Icon { name: "store"; }`). The player's tests check
139
- * that this list is its icon set.
139
+ * that this list is its icon set. `"sliders"` (three sliders, the player's
140
+ * Adjust button) is new in player 0.7.6 (SDK 1.6.11); older players refuse
141
+ * it as a button icon with `invalid`.
140
142
  *
141
143
  * @example Check in a test that the button's icon exists
142
144
  * The test fails before release if the plugin's bar button names an icon
@@ -154,7 +156,7 @@ export declare const MENU_IDS: readonly ["open", "playback", "subtitles", "video
154
156
  *
155
157
  * @category Testing
156
158
  */
157
- export declare const BAR_BUTTON_ICONS: readonly ["play", "pause", "stop", "back", "forward", "open", "volume", "mute", "playlist", "detach", "attach", "close", "failed", "move-top", "move-up", "move-down", "move-bottom", "search", "chapter", "bookmark", "check-task", "check-box", "menu-check", "submenu", "scroll-up", "scroll-down", "caret-down", "sort-asc", "sort-desc", "tag-remove", "preview-play", "add", "remove", "sort", "fullscreen", "exit-fullscreen", "store", "ai"];
159
+ export declare const BAR_BUTTON_ICONS: readonly ["play", "pause", "stop", "back", "forward", "open", "volume", "mute", "playlist", "detach", "attach", "close", "failed", "move-top", "move-up", "move-down", "move-bottom", "search", "chapter", "bookmark", "check-task", "check-box", "menu-check", "submenu", "scroll-up", "scroll-down", "caret-down", "sort-asc", "sort-desc", "tag-remove", "preview-play", "add", "remove", "sort", "fullscreen", "exit-fullscreen", "store", "ai", "sliders"];
158
160
  /**
159
161
  * The player's limits on bottom-bar buttons (`CommandOptions.button`), the
160
162
  * same values as the player's (its tests check that they agree). A button
package/dist/commands.js CHANGED
@@ -141,7 +141,9 @@ export const MENU_IDS = [
141
141
  * The icons a bottom-bar button may name (`CommandOptions.button.icon`):
142
142
  * every icon of the player's V-Line set, `@vestra/icons.slint` (draw one
143
143
  * in your own Slint with `Icon { name: "store"; }`). The player's tests check
144
- * that this list is its icon set.
144
+ * that this list is its icon set. `"sliders"` (three sliders, the player's
145
+ * Adjust button) is new in player 0.7.6 (SDK 1.6.11); older players refuse
146
+ * it as a button icon with `invalid`.
145
147
  *
146
148
  * @example Check in a test that the button's icon exists
147
149
  * The test fails before release if the plugin's bar button names an icon
@@ -198,6 +200,7 @@ export const BAR_BUTTON_ICONS = [
198
200
  "exit-fullscreen",
199
201
  "store",
200
202
  "ai",
203
+ "sliders",
201
204
  ];
202
205
  /**
203
206
  * The player's limits on bottom-bar buttons (`CommandOptions.button`), the
@@ -601,6 +604,7 @@ host | enter-fullscreen | (Enter Fullscreen)
601
604
  host | exit-fullscreen | (Leave Fullscreen)
602
605
  host | sidebar | (Toggle Sidebar)
603
606
  host | palette | (Command Palette) | Ctrl+Shift+P
607
+ host | adjust | (Adjust)
604
608
  vestra.info | info.brief | (Brief Info) | Shift+Tab
605
609
  vestra.playlist | playlist.play | (Play) | Enter, P | panel
606
610
  vestra.playlist | playlist.list-add | (Add Files…) | Ctrl+I | panel
Binary file
package/dist/i18n.js CHANGED
@@ -942,6 +942,7 @@ export const HOST_ZH_HANS = {
942
942
  "bottom bar": "底栏",
943
943
  sidebar: "侧栏",
944
944
  "video backdrop": "视频背景",
945
+ "adjust column": "调节栏",
945
946
  "The {} is used by {}": "{}已被 {} 使用",
946
947
  "{} is resolved by {}": "{} 已由 {} 解析",
947
948
  "File type .{}": "文件类型 .{}",
@@ -601,7 +601,7 @@ export declare class TestHost implements Transport {
601
601
  * See {@link TestHost.mounted}.
602
602
  */
603
603
  panel: (Omit<FakeWindow, "callbacks" | "userClose"> & {
604
- /** `"bottom"`, `"sidebar"` or `"backdrop"`. */
604
+ /** `"bottom"`, `"sidebar"`, `"adjust"` or `"backdrop"`. */
605
605
  slot: string;
606
606
  /** The exported component the SDK found in the file. */
607
607
  component: string;
@@ -643,6 +643,12 @@ export declare class TestHost implements Transport {
643
643
  * the current tab's (the plugin under test is owner 1).
644
644
  */
645
645
  sidebar: LayoutSlot | null;
646
+ /**
647
+ * The adjust column (SDK 1.6.11, player 0.7.6), like the sidebar but
648
+ * never `detached`. It starts hidden (`preferred: false`, `reason:
649
+ * "userHidden"`), as the player's does until the user opens it.
650
+ */
651
+ adjust: LayoutSlot | null;
646
652
  };
647
653
  /**
648
654
  * Every `osd.show` text as the player shows it (translated with the
@@ -1331,7 +1337,7 @@ export declare class TestHost implements Transport {
1331
1337
  *
1332
1338
  * @capability None.
1333
1339
  */
1334
- mountOther(slot: "bottom" | "sidebar" | "backdrop", plugin: string, options?: {
1340
+ mountOther(slot: "bottom" | "sidebar" | "adjust" | "backdrop", plugin: string, options?: {
1335
1341
  title?: string;
1336
1342
  }): void;
1337
1343
  /**
@@ -2829,7 +2835,7 @@ export declare class TestHost implements Transport {
2829
2835
  * @since 1.0.0
2830
2836
  */
2831
2837
  mounted(): Omit<FakeWindow, "callbacks" | "userClose"> & {
2832
- /** `"bottom"`, `"sidebar"` or `"backdrop"`. */
2838
+ /** `"bottom"`, `"sidebar"`, `"adjust"` or `"backdrop"`. */
2833
2839
  slot: string;
2834
2840
  /** The exported component the SDK found in the file. */
2835
2841
  component: string;
@@ -328,6 +328,7 @@ const SLOT_LABELS = {
328
328
  bottom: "bottom bar",
329
329
  sidebar: "sidebar",
330
330
  backdrop: "video backdrop",
331
+ adjust: "adjust column",
331
332
  };
332
333
  /** Texts only the test host uses, with their Chinese of SDK 1.5.8. */
333
334
  const TEST_ZH_HANS = {
@@ -550,6 +551,7 @@ export class TestHost {
550
551
  layout = {
551
552
  bottom: null,
552
553
  sidebar: null,
554
+ adjust: null,
553
555
  };
554
556
  /**
555
557
  * Every `osd.show` text as the player shows it (translated with the
@@ -1528,10 +1530,10 @@ export class TestHost {
1528
1530
  * ```
1529
1531
  */
1530
1532
  selectTab(plugin) {
1531
- const slot = this.layout.sidebar;
1533
+ const slot = [this.layout.sidebar, this.layout.adjust].find((each) => each?.panels?.some((entry) => entry.plugin === plugin));
1532
1534
  const panel = slot?.panels?.find((entry) => entry.plugin === plugin);
1533
1535
  if (!slot || !panel)
1534
- throw new Error(`${plugin} has no sidebar tab`);
1536
+ throw new Error(`${plugin} has no tab`);
1535
1537
  slot.owner = panel.owner;
1536
1538
  this.emit("window.state", this.#windowFacts());
1537
1539
  }
@@ -1539,15 +1541,18 @@ export class TestHost {
1539
1541
  const state = this.layout[slot];
1540
1542
  if (state)
1541
1543
  state.panels = [...(state.panels ?? []), panel];
1542
- else
1544
+ else {
1545
+ // The adjust column starts hidden, as the player's.
1546
+ const shown = slot !== "adjust";
1543
1547
  this.layout[slot] = {
1544
1548
  owner: panel.owner,
1545
- preferred: true,
1546
- effective: true,
1547
- reason: null,
1549
+ preferred: shown,
1550
+ effective: shown,
1551
+ reason: shown ? null : "userHidden",
1548
1552
  detached: false,
1549
1553
  panels: [panel],
1550
1554
  };
1555
+ }
1551
1556
  }
1552
1557
  #removePanel(slot, owner) {
1553
1558
  const state = this.layout[slot];
@@ -4247,11 +4252,16 @@ export class TestHost {
4247
4252
  for (const why of this.listeningWhy.get(event) ?? ["a listener"])
4248
4253
  reasons.push(`listens to ${event}: ${why}`);
4249
4254
  // A sidebar panel is never live (player 0.7.3): the current tab keeps
4250
- // the plugin running as busy work, a background tab not at all.
4255
+ // the plugin running as busy work, a background tab not at all. The
4256
+ // adjust column's current tab only while the column is open (0.7.6).
4251
4257
  if (this.panel?.slot === "sidebar") {
4252
4258
  if (this.layout.sidebar?.owner === 1)
4253
4259
  reasons.push("its sidebar tab is the current tab");
4254
4260
  }
4261
+ else if (this.panel?.slot === "adjust") {
4262
+ if (this.layout.adjust?.owner === 1 && this.layout.adjust.preferred)
4263
+ reasons.push("its adjust tab is the current tab");
4264
+ }
4255
4265
  else if (this.panel)
4256
4266
  reasons.push("a mounted panel");
4257
4267
  for (const [id, window] of this.windows)
@@ -4487,8 +4497,11 @@ export class TestHost {
4487
4497
  "ui.mount": (p) => {
4488
4498
  if (this.panel)
4489
4499
  throw new HostError("conflict", "owner already mounted");
4500
+ if (!(String(p.slot) in SLOT_LABELS))
4501
+ throw new HostError("invalid", "unknown mount slot");
4490
4502
  // Like the player: one panel in the bottom bar and the backdrop, any
4491
- // number of tabs in the sidebar (player 0.7.3; 0.4.x to 0.7.2 took 8).
4503
+ // number of tabs in the sidebar (player 0.7.3; 0.4.x to 0.7.2 took 8)
4504
+ // and in the adjust column (player 0.7.6).
4492
4505
  const holder = p.slot === "backdrop"
4493
4506
  ? this.backdrop?.owner
4494
4507
  : p.slot === "bottom"
@@ -4542,7 +4555,10 @@ export class TestHost {
4542
4555
  "ui.menu": (p) => {
4543
4556
  if (!this.panel)
4544
4557
  throw new HostError("unavailable", "panel not shown");
4545
- if (this.panel.slot === "sidebar" && this.layout.sidebar?.owner !== 1)
4558
+ const tabs = this.panel.slot === "sidebar" || this.panel.slot === "adjust"
4559
+ ? this.layout[this.panel.slot]
4560
+ : null;
4561
+ if (tabs && tabs.owner !== 1)
4546
4562
  throw new HostError("unavailable", "the panel's tab is not the current one");
4547
4563
  const items = p.items;
4548
4564
  for (const id of items)
@@ -4559,11 +4575,15 @@ export class TestHost {
4559
4575
  }),
4560
4576
  "layout.set": (p) => {
4561
4577
  const slot = String(p.slot);
4578
+ if (!["bottom", "sidebar", "adjust"].includes(slot))
4579
+ throw new HostError("invalid", "unknown slot");
4562
4580
  const state = this.layout[slot];
4563
4581
  if (!state)
4564
4582
  throw new HostError("missing", "no panel at this position");
4565
4583
  if (p.detached !== undefined && slot === "bottom")
4566
4584
  throw new HostError("invalid", "the bottom bar cannot be detached");
4585
+ if (p.detached === true && slot === "adjust")
4586
+ throw new HostError("invalid", "the adjust column cannot be detached");
4567
4587
  if (p.active !== undefined && p.active !== null) {
4568
4588
  const panel = state.panels?.find((entry) => entry.plugin === p.active);
4569
4589
  if (!panel)
@@ -2578,12 +2578,13 @@ export interface PanelState {
2578
2578
  * else the position's reason ({@link SlotState.reason}).
2579
2579
  */
2580
2580
  reason: SlotState["reason"] | "otherTab";
2581
- /** The sidebar floats in its own window (with all its tabs). */
2581
+ /** The sidebar floats in its own window (with all its tabs); always `false` in the adjust column. */
2582
2582
  detached: boolean;
2583
2583
  }
2584
2584
  /**
2585
- * The bottom bar or the sidebar position (`plugin.panels.bottom`,
2586
- * `plugin.panels.sidebar`), independent of who mounted the panel there.
2585
+ * The bottom bar, the sidebar or the adjust column position
2586
+ * (`plugin.panels.bottom`, `plugin.panels.sidebar`, `plugin.panels.adjust`),
2587
+ * independent of who mounted the panel there.
2587
2588
  *
2588
2589
  * @remarks
2589
2590
  * The position does not belong to the plugin that mounted the panel: any
@@ -4140,6 +4141,38 @@ export interface Panels {
4140
4141
  * takes no pointer or keyboard input. While it is mounted, the player does
4141
4142
  * not show the cover art of audio files itself (from the next file
4142
4143
  * opened on), so the plugin can draw it.
4144
+ * - `"adjust"` (player 0.7.6, SDK 1.6.11): **controls that change what is
4145
+ * playing**: the picture, the sound, the subtitles, the speed (the
4146
+ * player's own Picture, Audio, Subtitles and Playback panels, a colour
4147
+ * grading tool). Several plugins may mount here, one tab each, labelled
4148
+ * `title` (else the plugin's name). Declare `minPlayerVersion: "0.7.6"`:
4149
+ * older players refuse the slot (`invalid`, "unknown mount slot"), and a
4150
+ * mount refused during `activate` fails the activation.
4151
+ *
4152
+ * **Choosing between `"sidebar"` and `"adjust"`.** The slot says what the
4153
+ * panel is for; the player decides how it looks and may change that at any
4154
+ * time. Ask: after the user closes the panel, do they still look at what it
4155
+ * showed? If yes (a list, chapters, search results, another video), it is
4156
+ * content: `"sidebar"`. If it only changes what is playing, it is
4157
+ * `"adjust"`.
4158
+ *
4159
+ * **What the player shows today (may change; do not depend on it).** The
4160
+ * adjust column is a second column between the video and the sidebar
4161
+ * (`[video][adjust][sidebar]`; both can be open, the sidebar always
4162
+ * rightmost), 317 wide by default, 280 to half the window, with text tabs
4163
+ * and the key that opens each tab under its title (the key of the command
4164
+ * your other commands name as their {@link CommandOptions.home | home}). It
4165
+ * has no close or detach button: the bottom bar's Adjust button, your
4166
+ * panel's own command ({@link Panel.toggle}) and the menus open and close
4167
+ * it. It starts closed. In a window too narrow to dock it beside a video at
4168
+ * least 480 wide, it floats over the right of the video, 300 wide; in
4169
+ * fullscreen it slides out from the right edge, left of the sidebar. Its
4170
+ * width, open state, current tab and tab order are remembered across
4171
+ * launches. Its strip is always drawn, so panel coordinates (drops) start
4172
+ * below it, and the bridge global's `tabbed` property, if declared, is
4173
+ * `true`. As in the sidebar, only the current tab's plugin is kept
4174
+ * running while the column is open, and the player compiles a panel the
4175
+ * first time it is shown, not at start-up.
4143
4176
  *
4144
4177
  * @capability ui.mount
4145
4178
  *
@@ -4176,12 +4209,12 @@ export interface Panels {
4176
4209
  *
4177
4210
  * @since 1.0.0
4178
4211
  */
4179
- mount(slot: "bottom" | "sidebar" | "backdrop", file: string, options?: {
4212
+ mount(slot: "bottom" | "sidebar" | "adjust" | "backdrop", file: string, options?: {
4180
4213
  /** The exported component to mount, if the file exports several. */
4181
4214
  component?: string;
4182
4215
  /** The exported global to use as the bridge, if the file exports several. */
4183
4216
  global?: string;
4184
- /** The floating sidebar window's title (at most 128 bytes). */
4217
+ /** The tab label and the floating sidebar window's title (at most 128 bytes). */
4185
4218
  title?: string;
4186
4219
  }): Panel;
4187
4220
  /**
@@ -4193,6 +4226,51 @@ export interface Panels {
4193
4226
  readonly bottom: PanelSlot;
4194
4227
  /** The sidebar position, including its floating state; any plugin may read and toggle it. */
4195
4228
  readonly sidebar: SidebarSlot;
4229
+ /**
4230
+ * The adjust column (player 0.7.6, SDK 1.6.11), whoever mounted there;
4231
+ * any plugin may read and toggle it. The same shape as
4232
+ * {@link Panels.sidebar} without floating: the adjust column never
4233
+ * detaches.
4234
+ *
4235
+ * @remarks
4236
+ * `state` is `null` while no plugin has a panel there. Players before
4237
+ * 0.7.6 build the `plugin` object with their own SDK, which has no
4238
+ * `adjust`: there `plugin.panels.adjust` is `undefined` and reading its
4239
+ * `state` throws a `TypeError`, so declare `"minPlayerVersion": "0.7.6"`
4240
+ * (or test `plugin.panels.adjust` first). The column starts hidden (`preferred: false`, `reason:
4241
+ * "userHidden"`) until the user opens it. To open the column at your own
4242
+ * panel, call {@link Panel.show} (or {@link Panel.toggle}, which closes it
4243
+ * again when your tab is already the current one, the behaviour of the
4244
+ * player's own `Alt+1…4`).
4245
+ *
4246
+ * @example Open the adjust column at this plugin's tab with a key
4247
+ * One command opens the column at the plugin's tab, and pressing it again
4248
+ * while that tab is shown closes the column. The panel's other commands
4249
+ * name it as their `home`, so the player shows its key under the tab and
4250
+ * the command palette knows where they live.
4251
+ * ```ts
4252
+ * const panel = plugin.panels.mount("adjust", "ui/wheels.slint", { title: "Wheels" });
4253
+ * plugin.commands.add({
4254
+ * id: "wheels",
4255
+ * title: "Colour Wheels",
4256
+ * bindings: ["Alt+5"],
4257
+ * // Opens the column at this tab; closes it when this tab is shown.
4258
+ * run: () => panel.toggle(),
4259
+ * });
4260
+ * plugin.commands.add({
4261
+ * id: "wheels-reset",
4262
+ * title: "Reset Colour Wheels",
4263
+ * // Lives in the panel `wheels` opens: its key shows under the tab.
4264
+ * home: "wheels",
4265
+ * run: () => panel.set({ lift: 0 }),
4266
+ * });
4267
+ * ```
4268
+ *
4269
+ * @player 0.7.6 (declare `"minPlayerVersion": "0.7.6"`; older players
4270
+ * have no `adjust`: reading its `state` throws a `TypeError`).
4271
+ * @since 1.6.11
4272
+ */
4273
+ readonly adjust: PanelSlot;
4196
4274
  }
4197
4275
  /**
4198
4276
  * What a timeline mark stands for; readers choose colours by it.
@@ -9417,7 +9495,7 @@ export interface PluginWarning {
9417
9495
  * 0.4.1); a newer player may add codes.
9418
9496
  */
9419
9497
  code: string;
9420
- /** The panel position (`"bottom"`, `"sidebar"`, `"backdrop"`) for `slot-occupied`. */
9498
+ /** The panel position (`"bottom"`, `"backdrop"`; the sidebar and the adjust column hold any number of tabs) for `slot-occupied`. */
9421
9499
  slot?: string;
9422
9500
  /**
9423
9501
  * What was taken, for `resolver-taken`: 「文件类型 .nes」 or the
package/dist/plugin/ui.js CHANGED
@@ -991,7 +991,8 @@ class LayoutService {
991
991
  state = {
992
992
  bottom: null,
993
993
  sidebar: null,
994
- tabs: { bottom: null, sidebar: null },
994
+ adjust: null,
995
+ tabs: { bottom: null, sidebar: null, adjust: null },
995
996
  backdrop: null,
996
997
  };
997
998
  #listeners = new Set();
@@ -1051,10 +1052,16 @@ class LayoutService {
1051
1052
  active: panel.owner === slot.owner,
1052
1053
  })))
1053
1054
  : null;
1055
+ const adjust = raw.adjust ?? null;
1054
1056
  const next = {
1055
1057
  bottom: view(raw.bottom),
1056
1058
  sidebar: view(raw.sidebar),
1057
- tabs: { bottom: tabs(raw.bottom), sidebar: tabs(raw.sidebar) },
1059
+ adjust: view(adjust),
1060
+ tabs: {
1061
+ bottom: tabs(raw.bottom),
1062
+ sidebar: tabs(raw.sidebar),
1063
+ adjust: tabs(adjust),
1064
+ },
1058
1065
  backdrop: raw.backdrop
1059
1066
  ? Object.freeze({ effective: raw.backdrop.effective === true })
1060
1067
  : null,
@@ -1145,6 +1152,7 @@ export const panels = (scope) => ({
1145
1152
  mount: (position, file, options = {}) => new PanelHandle(scope, position, file, options),
1146
1153
  bottom: slot(scope, "bottom"),
1147
1154
  sidebar: slot(scope, "sidebar"),
1155
+ adjust: slot(scope, "adjust"),
1148
1156
  backdrop: backdrop(scope),
1149
1157
  });
1150
1158
  export const dialogs = (scope) => {
package/dist/wire.d.ts CHANGED
@@ -288,7 +288,10 @@ export interface LayoutPanel {
288
288
  /** The tab label: the mount's `title`, else the plugin's name. */
289
289
  title: string;
290
290
  }
291
- /** One position (bottom bar or sidebar) as `layout.state` reports it. */
291
+ /**
292
+ * One position (the bottom bar, the sidebar or, from player 0.7.6, the
293
+ * adjust column) as `layout.state` reports it.
294
+ */
292
295
  export interface LayoutSlot {
293
296
  /** The current tab's panel (the only panel of the bottom bar). */
294
297
  owner: number;
@@ -696,10 +699,13 @@ export declare function createWire(transport: Transport): {
696
699
  state: () => Promise<{
697
700
  bottom: LayoutSlot | null;
698
701
  sidebar: LayoutSlot | null;
702
+ /** Player 0.7.6 (absent from older players). */
703
+ adjust?: LayoutSlot | null;
699
704
  backdrop?: LayoutBackdrop | null;
700
705
  }>;
701
706
  set: (options: {
702
- slot: "bottom" | "sidebar";
707
+ /** `"adjust"`: player 0.7.6 (older players refuse it with `invalid`). */
708
+ slot: "bottom" | "sidebar" | "adjust";
703
709
  visible?: boolean;
704
710
  detached?: boolean;
705
711
  /** The plugin id of the panel whose tab becomes the current one. */
@@ -727,7 +733,8 @@ export declare function createWire(transport: Transport): {
727
733
  images: string[];
728
734
  }>;
729
735
  mount: (options: {
730
- slot: "bottom" | "sidebar" | "backdrop";
736
+ /** `"adjust"`: player 0.7.6 (older players refuse it with `invalid`). */
737
+ slot: "bottom" | "sidebar" | "backdrop" | "adjust";
731
738
  file: string;
732
739
  component: string;
733
740
  global: string;
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Vestra Player SDK
2
2
 
3
- > @vestra-player/sdk 1.6.10: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
3
+ > @vestra-player/sdk 1.6.11: write plugins for Vestra Player in TypeScript (plugin API `vestra/1`). A plugin is a folder with `manifest.json` and an entry module whose default export `activate(plugin)` the player calls. The documentation is a tree of short pages read by path, like `go doc`: the same pages and API as https://vestrasys.github.io/vestra-player-sdk/.
4
4
 
5
5
  ## Read the documentation
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vestra-player/sdk",
3
- "version": "1.6.10",
3
+ "version": "1.6.11",
4
4
  "description": "Plugin API types, test host and plugin CLI for Vestra Player (apiVersion vestra/1)",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -3,8 +3,8 @@
3
3
  // player's own. Since SDK 1.6.8 (menu redesign step 3a) the player draws
4
4
  // the strip itself, at the right end of the bottom slot, its 40px cells on
5
5
  // the slot's bottom edge (a bar's 40px button row), and also when no plugin
6
- // mounts a bottom bar: `[plugin buttons…][»][Command Palette][Toggle
7
- // Sidebar]`. A bottom bar places nothing: it lays its controls out left of
6
+ // mounts a bottom bar: `[plugin buttons…][»][Command Palette][Adjust]
7
+ // [Toggle Sidebar]`. A bottom bar places nothing: it lays its controls out left of
8
8
  // the strip and says how wide they must stay:
9
9
  // import { BarButtonsHost } from "@vestra/bar-buttons.slint";
10
10
  // export component MyBar inherits Rectangle {
@@ -65,12 +65,16 @@ export global BarButtonsHost {
65
65
  in property <BarButtonItem> toggle;
66
66
  // The command palette (`host/palette`; `token` "" while there is none).
67
67
  in property <BarButtonItem> palette;
68
+ // The adjust column's toggle (`host/adjust`, player 0.7.6; `token` ""
69
+ // while there is none).
70
+ in property <BarButtonItem> adjust;
68
71
  // Set when a (deprecated) `BarButtons` exists in this window.
69
72
  in-out property <bool> placed;
70
73
  // The width the player gives its strip (the player sets it).
71
74
  in-out property <length> room;
72
- // The player's own cells, always shown (step 3b adds Adjust).
73
- private property <int> own: (root.palette.token != "" ? 1 : 0) + (root.toggle.token != "" ? 1 : 0);
75
+ // The player's own cells, always shown: Command Palette, Adjust,
76
+ // Toggle Sidebar.
77
+ private property <int> own: (root.palette.token != "" ? 1 : 0) + (root.adjust.token != "" ? 1 : 0) + (root.toggle.token != "" ? 1 : 0);
74
78
  // The cells a bar must always leave free, 41px each: the player's own,
75
79
  // and the `»` cell whenever any plugin button exists (drawn only on
76
80
  // overflow, but always reserved, so `»` never covers the bar). Never
@@ -52,6 +52,9 @@ export global Icons {
52
52
  // small cross (AI), the default 14 × 12 box; bar buttons use them.
53
53
  if name == "store" { return "M 2.5 4 H 11.5 L 10.9 9.6 Q 10.8 10.5 9.9 10.5 H 4.1 Q 3.2 10.5 3.1 9.6 Z M 5.2 4 V 3.3 A 1.8 1.8 0 0 1 8.8 3.3 V 4"; }
54
54
  if name == "ai" { return "M 6 1.5 Q 6.6 5.4 10.5 6 Q 6.6 6.6 6 10.5 Q 5.4 6.6 1.5 6 Q 5.4 5.4 6 1.5 Z M 11.5 1.2 V 3.8 M 10.2 2.5 H 12.8"; }
55
+ // Three sliders with their knobs (the adjust column, `host/adjust`),
56
+ // the default 14 × 12 box.
57
+ if name == "sliders" { return "M 1.5 2.5 H 7.6 M 10.4 2.5 H 12.5 M 10.4 2.5 A 1.4 1.4 0 1 1 7.6 2.5 A 1.4 1.4 0 1 1 10.4 2.5 Z M 1.5 6 H 3.1 M 5.9 6 H 12.5 M 5.9 6 A 1.4 1.4 0 1 1 3.1 6 A 1.4 1.4 0 1 1 5.9 6 Z M 1.5 9.5 H 6.6 M 9.4 9.5 H 12.5 M 9.4 9.5 A 1.4 1.4 0 1 1 6.6 9.5 A 1.4 1.4 0 1 1 9.4 9.5 Z"; }
55
58
  return "";
56
59
  }
57
60
  // Line width.