UNPKG

fvtt-types

Version:
297 lines (247 loc) 9.79 kB
import type { FixedInstanceType, HandleEmptyObject, Identity, NullishProps } from "#utils"; import type { LineIntersection } from "#common/utils/geometry.d.mts"; import type { Canvas } from "#client/canvas/_module.d.mts"; import type { Cursor } from "#client/canvas/containers/_module.mjs"; import type { Ray } from "#client/canvas/geometry/_module.d.mts"; import type { CanvasLayer, InteractionLayer } from "#client/canvas/layers/_module.d.mts"; import type { Ping, Ruler } from "#client/canvas/interaction/_module.d.mts"; declare module "#configuration" { namespace Hooks { interface InteractionLayerConfig { ControlsLayer: ControlsLayer.Implementation; } } } /** * A CanvasLayer for displaying UI controls which are overlayed on top of other layers. * * We track three types of events: * 1) Cursor movement * 2) Ruler measurement * 3) Map pings */ declare class ControlsLayer extends InteractionLayer { constructor(); /** * @privateRemarks This is not overridden in foundry but reflects the real behavior. */ static get instance(): Canvas["controls"]; /** * Always interactive even if disabled for doors controls * @defaultValue `true` */ override interactiveChildren: boolean; /** * A container of DoorControl instances * @defaultValue `new PIXI.Container()` */ doors: PIXI.Container; /** * A container of cursor interaction elements. * Contains cursors, rulers, interaction rectangles, and pings * @defaultValue `new PIXI.Container()` * @remarks This Container's `eventMode` is set to `"none"` and its `mask` is set to `canvas.masks.canvas` */ cursors: PIXI.Container; /** * Ruler tools, one per connected user * @defaultValue `new PIXI.Container()` * @remarks This Container's `eventMode` is set to `"none"` */ rulers: PIXI.Container; /** * A graphics instance used for drawing debugging visualization * @defaultValue `new PIXI.Graphics()` * @remarks This Graphics's `eventMode` is set to `"none"` */ debug: PIXI.Graphics; /** * Canvas selection rectangle * @remarks Only `undefined` prior to first draw */ select: PIXI.Graphics | undefined; /** * A mapping of user IDs to Cursor instances for quick access * @defaultValue `{}` * @remarks Cursor class is non-configurable */ _cursors: Record<string, Cursor>; /** * A convenience mapping of user IDs to Ruler instances for quick access * @defaultValue `{}` * @remarks Keys are User IDs * * Foundry marked `@private` */ protected _rulers: Record<string, Ruler.Implementation>; /** * The positions of any offscreen pings we are tracking. * @remarks Keys in the format `Ping.${foundry.utils.randomID()}` * * Foundry marked `@private` */ protected _offscreenPings: Record<string, Canvas.Point>; /** * @privateRemarks This override does not exist in Foundry but reflects reality. Not automateable because of * lack of access to the constructor from the instance side */ override options: ControlsLayer.LayerOptions; /** * @defaultValue * ```js * foundry.utils.mergeObject(super.layerOptions, { * name: "controls", * zIndex: 1000 * } * ``` */ static override get layerOptions(): ControlsLayer.LayerOptions; /** * A convenience accessor to the Ruler for the active game user */ get ruler(): Ruler.Implementation | null; /** * Get the Ruler display for a specific User ID */ getRulerForUser(userId: string): Ruler.Implementation | null; protected override _draw(options: HandleEmptyObject<ControlsLayer.DrawOptions>): Promise<void>; protected override _tearDown(options: HandleEmptyObject<ControlsLayer.TearDownOptions>): Promise<void>; /** * Draw the cursors container */ drawCursors(): void; /** * Create and add Ruler graphics instances for every game User. */ drawRulers(): void; /** * Draw door control icons to the doors container. */ drawDoors(): void; /** * Draw the select rectangle given an event originated within the base canvas layer * @param coords - The rectangle coordinates of the form `{x, y, width, height}` */ drawSelect(coords: Canvas.Rectangle): void; protected override _deactivate(): void; /** * Handle mousemove events on the game canvas to broadcast activity of the user's cursor position */ protected _onMouseMove(): void; /** * Handle pinging the canvas. * @param event - The triggering canvas interaction event. * @param origin - The local canvas coordinates of the mousepress. */ protected _onLongPress(event: Canvas.Event.Pointer, origin: PIXI.Point): Promise<boolean>; /** * Handle the canvas panning to a new view. * @remarks Called externally in {@link Canvas#pan} */ protected _onCanvasPan(): void; /** * Create and draw the Cursor object for a given User * @param user - The User docuwment for whom to draw the cursor Container */ drawCursor(user: User.Implementation): Cursor; /** * Update the cursor when the user moves to a new position * @param user - The User for whom to update the cursor * @param position - The new cursor position */ updateCursor(user: User.Implementation, position: Canvas.Point | null): void; /** * Update display of an active Ruler object for a user given provided data * @see {@link Ruler#update} */ updateRuler(user: User.Implementation, rulerData?: Ruler.UpdateData | null): void; /** * Handle a broadcast ping. * @see {@link Ping.drawPing | `Ping#drawPing`} * @param user - The user who pinged. * @param position - The position on the canvas that was pinged. * @param data - The broadcast ping data. * @returns A promise which resolves once the Ping has been drawn and animated */ handlePing( user: User.Implementation, position: Canvas.Point, /** @remarks Despite being a `={}` parameter, an object containing a valid `scene` property (a scene ID) must be passed */ data: ControlsLayer.HandlePingOptions, ): Promise<boolean>; /** * Draw a ping at the edge of the viewport, pointing to the location of an off-screen ping. * @see {@link Ping.drawPing | `Ping#drawPing`} * @param position - The coordinates of the off-screen ping. * @param options - Additional options to configure how the ping is drawn. * @returns A promise which resolves once the Ping has been drawn and animated */ drawOffscreenPing( position: Canvas.Point, options?: ControlsLayer.DrawOffscreenPingOptions, // not:null (destructured) ): Promise<boolean>; /** * Draw a ping on the canvas * @see {@link Ping.animate | `Ping#animate`} * @param position - The position on the canvas that was pinged. * @param options - Additional options to configure how the ping is drawn. * @returns A promise which resolves once the Ping has been drawn and animated */ drawPing( position: Canvas.Point, options?: ControlsLayer.DrawPingOptions, // not:null (destructured) ): Promise<boolean>; /** * Given off-screen coordinates, determine the closest point at the edge of the viewport to these coordinates. * @param position - The off-screen co-ordinate. * @returns The closest point at the edge of the viewport to these coordinates and a ray cast from the centre of the screen towards it. * @remarks Foundry marked `@private` */ protected _findViewportIntersection(position: Canvas.Point): ControlsLayer.ViewportIntersectionData; } declare namespace ControlsLayer { /** @deprecated There should only be a single implementation of this class in use at one time, use {@linkcode Implementation} instead */ type Any = Internal.Any; /** @deprecated There should only be a single implementation of this class in use at one time, use {@linkcode ImplementationClass} instead */ type AnyConstructor = Internal.AnyConstructor; namespace Internal { interface Any extends AnyControlsLayer {} interface AnyConstructor extends Identity<typeof AnyControlsLayer> {} } interface ImplementationClass extends Identity<CONFIG["Canvas"]["layers"]["controls"]["layerClass"]> {} interface Implementation extends FixedInstanceType<ImplementationClass> {} interface DrawOptions extends InteractionLayer.DrawOptions {} interface TearDownOptions extends CanvasLayer.TearDownOptions {} interface LayerOptions extends InteractionLayer.LayerOptions { name: "controls"; zIndex: 1000; } interface HandlePingOptions extends User.PingData, Ping.ConstructorOptions {} /** @internal */ type _DrawPingOptions = NullishProps<{ /** * The user who pinged. * @remarks Only used to set the color of the ping. If `user?.color` ends up `undefined`, the relevant Ping class will provide a default color. * If a `color` property is passed along with this, `color` will take precedence */ user: User.Implementation; }>; interface DrawPingOptions extends _DrawPingOptions, Pick<User.PingData, "style">, Ping.ConstructorOptions {} interface DrawOffscreenPingOptions extends DrawPingOptions { /** * @defaultValue `"arrow"` * @remarks Can't be `null` as it only has a parameter default */ style?: User.PingData["style"] | undefined; } interface ViewportIntersectionData { /** A Ray from the center of the [viewport minus right sidebar] area to the point on the edge of that area in line with an offscreen ping */ ray: Ray; /** The intersection with the viewport edge, or undefined if its on-screen */ intersection: LineIntersection | undefined; } } export default ControlsLayer; declare abstract class AnyControlsLayer extends ControlsLayer { constructor(...args: never); }