@scm-js/plugin-api 1.48.0 → 1.50.0
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/index.d.ts +153 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -980,6 +980,8 @@ export interface UpgradesDat {
|
|
|
980
980
|
broodWar: Uint8Array;
|
|
981
981
|
/** The upgrade's name: a 1-based `stat_txt.tbl` index, 0 for none. */
|
|
982
982
|
label: Uint16Array;
|
|
983
|
+
/** Its button picture: a frame of `unit\cmdbtns\cmdicons.grp`. */
|
|
984
|
+
icon: Uint16Array;
|
|
983
985
|
}
|
|
984
986
|
/** The columns Technology Settings shows as defaults. */
|
|
985
987
|
export interface TechdataDat {
|
|
@@ -992,6 +994,8 @@ export interface TechdataDat {
|
|
|
992
994
|
broodWar: Uint8Array;
|
|
993
995
|
/** The technology's name: a 1-based `stat_txt.tbl` index, 0 for none. */
|
|
994
996
|
label: Uint16Array;
|
|
997
|
+
/** Its button picture: a frame of `unit\cmdbtns\cmdicons.grp`. */
|
|
998
|
+
icon: Uint16Array;
|
|
995
999
|
}
|
|
996
1000
|
/**
|
|
997
1001
|
* Unit edits as invertible change lists, in the same spirit as terrain's `TileChange`.
|
|
@@ -2329,6 +2333,8 @@ export interface StatusBarCells {
|
|
|
2329
2333
|
export type PluginUpdateMode = "notify" | "manual" | "auto";
|
|
2330
2334
|
/** The revisions a new map can start on; the two older ones are for opening old files, not making new ones. */
|
|
2331
2335
|
export type NewMapVersion = Extract<MapVersion, "broodwar" | "remastered">;
|
|
2336
|
+
export type IconKind = "unit" | "upgrade" | "tech";
|
|
2337
|
+
export type IconLook = "normal" | "disabled" | "selected";
|
|
2332
2338
|
/**
|
|
2333
2339
|
* The version a host provides; a manifest that asks for a newer one is refused. It stays
|
|
2334
2340
|
* at 1 while the API is only used by the plugins in the scm-js organisation and grows
|
|
@@ -4138,6 +4144,36 @@ export interface GraphicsApi {
|
|
|
4138
4144
|
*/
|
|
4139
4145
|
requestUnit(unitId: number): boolean;
|
|
4140
4146
|
requestSprite(kind: SpriteKind, id: number): boolean;
|
|
4147
|
+
/**
|
|
4148
|
+
* The game's own button picture for a unit type, an upgrade or a technology — the icon
|
|
4149
|
+
* its command card shows — 36 × 34 at most and transparent round the edges. `look`
|
|
4150
|
+
* colours it as the game does: `"normal"` yellow (the default), `"disabled"` grey,
|
|
4151
|
+
* `"selected"` white. It does not depend on the map or its tileset. Null for an id with
|
|
4152
|
+
* no picture (a unit type past 227, a turret) and until `requestIcons` has the pictures;
|
|
4153
|
+
* null for good from a game data copy made before the editor kept them (installing the
|
|
4154
|
+
* game data again brings them). The canvas is the editor's own cached one: draw from it.
|
|
4155
|
+
*
|
|
4156
|
+
* @example
|
|
4157
|
+
* // A row of what a player researched, as the game's icons, with the names where there are no pictures.
|
|
4158
|
+
* const show = () => list.replaceChildren(...done.map((r) => {
|
|
4159
|
+
* const icon = api.graphics.icon(r.kind, r.id);
|
|
4160
|
+
* if (!icon) return api.ui.el("span", {}, r.kind === "tech" ? api.names.tech(r.id) : api.names.upgrade(r.id));
|
|
4161
|
+
* const canvas = api.ui.el("canvas", { width: icon.width, height: icon.height });
|
|
4162
|
+
* canvas.getContext("2d")?.drawImage(icon.image, 0, 0);
|
|
4163
|
+
* return canvas;
|
|
4164
|
+
* }));
|
|
4165
|
+
* api.graphics.requestIcons();
|
|
4166
|
+
* api.graphics.onImageLoaded(show);
|
|
4167
|
+
* show();
|
|
4168
|
+
*/
|
|
4169
|
+
icon(kind: IconKind, id: number, options?: {
|
|
4170
|
+
look?: IconLook;
|
|
4171
|
+
}): PluginImage | null;
|
|
4172
|
+
/**
|
|
4173
|
+
* Start fetching the icon pictures (one sheet holds them all), and say whether they are
|
|
4174
|
+
* in memory. `onImageLoaded` fires when they arrive.
|
|
4175
|
+
*/
|
|
4176
|
+
requestIcons(): boolean;
|
|
4141
4177
|
/** A GRP finished loading: anything drawn from one may look different now. */
|
|
4142
4178
|
onImageLoaded(listener: () => void): Disposable;
|
|
4143
4179
|
}
|
|
@@ -5044,6 +5080,70 @@ export interface MapViewSpec {
|
|
|
5044
5080
|
* to be called when the view goes (the plugin stops, or `dispose`).
|
|
5045
5081
|
*/
|
|
5046
5082
|
mount(element: HTMLElement): void | (() => void);
|
|
5083
|
+
/**
|
|
5084
|
+
* The view is shown in the map's place, where the map was looking: `look` is the map's view
|
|
5085
|
+
* at that moment, or the other view's (`setCamera`) when the switch came from one. Turn to
|
|
5086
|
+
* look at the same place, as near the same scale as you can, so the switch keeps the person
|
|
5087
|
+
* where they were. Not called when another map, already showing the view, comes to the front.
|
|
5088
|
+
*/
|
|
5089
|
+
onShow?(look: MapViewCamera): void;
|
|
5090
|
+
/**
|
|
5091
|
+
* What the minimap shows while the view is shown. Without it the minimap shows the map, and
|
|
5092
|
+
* its box and presses are the map's own view's (hidden behind this one).
|
|
5093
|
+
*/
|
|
5094
|
+
minimap?: MapViewMinimapSpec;
|
|
5095
|
+
}
|
|
5096
|
+
/**
|
|
5097
|
+
* Where a view looks, in map pixels (32 to a tile): the point in the middle of what it shows,
|
|
5098
|
+
* and how much of the map that is.
|
|
5099
|
+
*/
|
|
5100
|
+
export interface MapViewCamera {
|
|
5101
|
+
x: number;
|
|
5102
|
+
y: number;
|
|
5103
|
+
width: number;
|
|
5104
|
+
height: number;
|
|
5105
|
+
}
|
|
5106
|
+
/**
|
|
5107
|
+
* A map view's own minimap (`MapViewSpec.minimap`): the minimap draws the map's ground, then
|
|
5108
|
+
* `draw` over it in place of the map's units, start locations and fog, and its box where the
|
|
5109
|
+
* view looks (`MapViewHandle.setCamera`).
|
|
5110
|
+
*
|
|
5111
|
+
* @example
|
|
5112
|
+
* // A replay's units as dots, and the minimap moving the game's camera.
|
|
5113
|
+
* const view = api.ui.mapView({
|
|
5114
|
+
* title: "Replay",
|
|
5115
|
+
* mount: (el) => el.append(frame),
|
|
5116
|
+
* minimap: {
|
|
5117
|
+
* draw(ctx, m) {
|
|
5118
|
+
* for (const u of units) {
|
|
5119
|
+
* ctx.fillStyle = u.colour;
|
|
5120
|
+
* ctx.fillRect(m.x(u.x) - 1, m.y(u.y) - 1, Math.max(2, u.width * m.scale), Math.max(2, u.height * m.scale));
|
|
5121
|
+
* }
|
|
5122
|
+
* },
|
|
5123
|
+
* press: (x, y) => game.lookAt(x, y),
|
|
5124
|
+
* },
|
|
5125
|
+
* });
|
|
5126
|
+
* game.onUnits(() => view.redrawMinimap());
|
|
5127
|
+
* game.onCamera((c) => view.setCamera(c));
|
|
5128
|
+
*/
|
|
5129
|
+
export interface MapViewMinimapSpec {
|
|
5130
|
+
/** Draw over the map's ground, each time the minimap's picture is made while the view is shown. */
|
|
5131
|
+
draw?(ctx: CanvasRenderingContext2D, minimap: MinimapView): void;
|
|
5132
|
+
/**
|
|
5133
|
+
* A press on the minimap, and each move of a drag from it, at a map pixel: look there. Without
|
|
5134
|
+
* it the minimap does not move anything while the view is shown.
|
|
5135
|
+
*/
|
|
5136
|
+
press?(x: number, y: number): void;
|
|
5137
|
+
}
|
|
5138
|
+
/** Map pixels to minimap canvas pixels, for `MapViewMinimapSpec.draw`. */
|
|
5139
|
+
export interface MinimapView {
|
|
5140
|
+
/** Minimap canvas pixels per map pixel. */
|
|
5141
|
+
scale: number;
|
|
5142
|
+
/** A map pixel's x on the minimap's canvas. */
|
|
5143
|
+
x(px: number): number;
|
|
5144
|
+
y(py: number): number;
|
|
5145
|
+
/** The canvas's size in pixels, each side (the map is centred in it, letterboxed). */
|
|
5146
|
+
size: number;
|
|
5047
5147
|
}
|
|
5048
5148
|
export interface MapViewHandle extends Disposable {
|
|
5049
5149
|
/**
|
|
@@ -5061,6 +5161,14 @@ export interface MapViewHandle extends Disposable {
|
|
|
5061
5161
|
* `show` was called, or another map came to the front.
|
|
5062
5162
|
*/
|
|
5063
5163
|
onChange(listener: (shown: boolean) => void): Disposable;
|
|
5164
|
+
/**
|
|
5165
|
+
* Where the view looks now, in map pixels; call it whenever that changes. The minimap draws
|
|
5166
|
+
* its box there while the view is shown, and the map, shown again, opens on the same place at
|
|
5167
|
+
* the same scale.
|
|
5168
|
+
*/
|
|
5169
|
+
setCamera(camera: MapViewCamera): void;
|
|
5170
|
+
/** Make the minimap's picture again (`minimap.draw`), at most once a frame. Cheap: call it as the view's contents move. */
|
|
5171
|
+
redrawMinimap(): void;
|
|
5064
5172
|
}
|
|
5065
5173
|
export interface PanelHandle {
|
|
5066
5174
|
close(): void;
|
|
@@ -5565,6 +5673,24 @@ export interface UiApi {
|
|
|
5565
5673
|
* }
|
|
5566
5674
|
*/
|
|
5567
5675
|
progress(label: string, options?: ProgressOptions): ProgressHandle;
|
|
5676
|
+
/**
|
|
5677
|
+
* A tooltip in the editor's own style over an element of yours, in place of the
|
|
5678
|
+
* browser's `title`. `content` is a line of text, or a function asked for what to show
|
|
5679
|
+
* at the pointer — rows, bars, pictures, built with `el` and the widgets — which is how
|
|
5680
|
+
* a chart says what is under the pointer: it is asked again as the pointer moves, and
|
|
5681
|
+
* answering null hides the tip there. The editor places it beside the pointer, keeps it
|
|
5682
|
+
* on screen and takes it away when the pointer leaves, the element leaves the page, or
|
|
5683
|
+
* the plugin stops. `refresh()` asks again where the pointer stands (a picture arrived,
|
|
5684
|
+
* the data moved). Remove the element's `title`, or both show.
|
|
5685
|
+
*
|
|
5686
|
+
* @example
|
|
5687
|
+
* // A chart that reads out the value under the pointer.
|
|
5688
|
+
* api.ui.tooltip(canvas, (at) => {
|
|
5689
|
+
* const i = Math.floor((at.offsetX / canvas.clientWidth) * values.length);
|
|
5690
|
+
* return values[i] === undefined ? null : api.ui.el("div", {}, api.ui.el("b", {}, `${values[i]}`), " minerals");
|
|
5691
|
+
* });
|
|
5692
|
+
*/
|
|
5693
|
+
tooltip(target: HTMLElement, content: string | ((at: TooltipPointer) => HTMLElement | string | null), options?: TooltipOptions): TooltipHandle;
|
|
5568
5694
|
/** `el("div", { className: "row" }, …)`: the DOM helper the widgets are built from. */
|
|
5569
5695
|
el<K extends keyof HTMLElementTagNameMap>(tag: K, props?: Record<string, unknown>, ...children: WidgetChild[]): HTMLElementTagNameMap[K];
|
|
5570
5696
|
/** Buttons, fields, forms and lists in the editor's own styles. */
|
|
@@ -5579,6 +5705,33 @@ export interface UiApi {
|
|
|
5579
5705
|
/** Ask the viewport to repaint (a transaction does this by itself). Raises no event. */
|
|
5580
5706
|
repaint(): void;
|
|
5581
5707
|
}
|
|
5708
|
+
/** Where the pointer is, for a tooltip's `content`. */
|
|
5709
|
+
export interface TooltipPointer {
|
|
5710
|
+
/** In the page, CSS pixels (`clientX` / `clientY`). */
|
|
5711
|
+
x: number;
|
|
5712
|
+
y: number;
|
|
5713
|
+
/** From the target's top-left corner, CSS pixels. */
|
|
5714
|
+
offsetX: number;
|
|
5715
|
+
offsetY: number;
|
|
5716
|
+
/** Whether a button is held — a drag across a chart. */
|
|
5717
|
+
pressed: boolean;
|
|
5718
|
+
}
|
|
5719
|
+
export interface TooltipOptions {
|
|
5720
|
+
/**
|
|
5721
|
+
* Milliseconds the pointer rests before the tip shows. 500 for text, as the editor's own
|
|
5722
|
+
* tooltips; 0 for a function, which reads out what is under the pointer and should keep
|
|
5723
|
+
* up with it.
|
|
5724
|
+
*/
|
|
5725
|
+
delay?: number;
|
|
5726
|
+
/** A width the tip does not grow past, CSS pixels; 320 by default. */
|
|
5727
|
+
maxWidth?: number;
|
|
5728
|
+
}
|
|
5729
|
+
export interface TooltipHandle extends Disposable {
|
|
5730
|
+
/** Ask `content` again where the pointer stands; nothing when the tip is not showing. */
|
|
5731
|
+
refresh(): void;
|
|
5732
|
+
/** Take the tip away until the pointer next moves over the target. */
|
|
5733
|
+
hide(): void;
|
|
5734
|
+
}
|
|
5582
5735
|
export interface ConfirmOptions {
|
|
5583
5736
|
title?: string;
|
|
5584
5737
|
/** The primary button; `OK` by default. */
|