malwoden
Version:
   
206 lines (205 loc) • 7.47 kB
TypeScript
import { Vector2 } from "../struct";
import { KeyboardContext, KeyboardHandler, MouseContext, MouseContextCallback, MouseHandler, MouseHandlerEvent } from "../input";
import { BaseTerminal, Glyph } from "../terminal";
/**
* Generic used to create widget constructors.
*/
export interface WidgetConfig<S> {
initialState: S;
origin?: Vector2;
}
/**
* Generic used to create widget updateFuncs
*/
export interface WidgetUpdateFunc<S> {
(): Partial<S>;
}
/**
* A Widget represents a reusable component able to draw to a terminal. These don't have to be used
* if you prefer to directly write to the terminal itself, but can simplify the process. The abstract class
* here contains basic shared methods related to Widgets, like adding/removing children, calculating
* position, etc.
*
* While Malwoden provides several widgets out of the box, this class can be easily extended to make
* custom widgets of all shapes and sizes.
*/
export declare abstract class Widget<S> {
protected absoluteOrigin: Vector2;
protected origin: Vector2;
protected updateFunc?: WidgetUpdateFunc<S>;
protected parent?: Widget<any>;
protected children: Widget<any>[];
protected state: S;
protected disabled: boolean;
protected mouseRegistration?: {
mouseContext: MouseContext;
mouseOnUp: MouseContextCallback;
mouseOnDown: MouseContextCallback;
};
protected keyboardContext?: KeyboardContext;
protected terminal?: BaseTerminal;
protected mouseHandler?: MouseHandler;
protected keyboardHandler?: KeyboardHandler;
/**
* Creates a new Widget.
* @param config - WidgetConfig
*/
constructor(config: WidgetConfig<S>);
/**
* Sets the terminal for this widget and all children widgets. Will be passed
* to any children added in the future as well.
* @param terminal - Leave empty to clear
* @returns this
*/
setTerminal(terminal?: BaseTerminal): this;
registerMouseContext(mouseContext: MouseContext): this;
clearMouseContext(): this;
/**
* Sets the mouseHandler for this widget and all children widgets. Will be passed
* to any children added in the future as well.
* @param mouseHandler - Leave empty to clear
* @returns this
*/
setMouseHandler(mouseHandler?: MouseHandler): this;
/**
* Gets the current state of the widget. While not a copy, it's recommended to
* use setState rather than mutate this object.
* @returns
*/
getState(): S;
/**
* Sets the state of the widget. Partial values allowed.
* @param state Partial<S>
* @returns - The widget
*/
setState(state: Partial<S>): this;
/**
* Sets the disabled state.
* @param disabled - Default true
* @returns - The Widget
*/
setDisabled(disabled?: boolean): this;
/**
* Sets the local origin of the widget relative to it's parent,
* then updates the absoluteOrigin of the widget
* @param origin Vector2 - The position relative to its parent
* @returns - The widget
*/
setOrigin(origin: Vector2): this;
/**
* Gets the local origin. This will be relative to the parent's origin.
* @returns - Vector2
*/
getOrigin(): Vector2;
/**
* Whether or not the widget will update/draw
* @returns boolean
*/
isDisabled(): boolean;
/**
* Returns a Vector2 relative to true 0,0, which is usually the top left of the terminal.
* @returns - Vector2
*/
getAbsoluteOrigin(): Vector2;
/**
* Transforms the given local position to an absolute position.
* @param localPosition Vector2
* @returns Vector2
*/
localToAbsolute(localPosition: Vector2): Vector2;
/**
* Transforms a given absolute position to one relative to the
* widget's local origin.
* @param absolutePosition Vector2
* @returns Vector2
*/
absoluteToLocal(absolutePosition: Vector2): Vector2;
/**
* Updates the absoluteOrigin position, called
* whenever a widget's local origin has moved.
*/
protected updateAbsoluteOrigin(): void;
/**
* Adds the widget to a parent.
* @param parent
* @returns this - The child widget
*/
setParent<T extends Widget<any>>(parent: T): this;
/**
* Adds a child widget to this widget. Removes any existing parent from the child first.
* @param child - The child widget
* @returns The child widget
*/
addChild<T extends Widget<any>>(child: T): T;
/**
* Removes a child widget from the parent widget. Clears inherited Terminal/MouseHandler/KeyboardHandler
* @param child The child widget
* @returns The child widget if found, undefined otherwise.
*/
removeChild<T extends Widget<any>>(child: T): T | undefined;
/**
* Set a function to run whenever update or cascadeUpdate is called. Generally this is used
* with closures/currying to transform game state to function state.
* @param updateFunc - The function called on update
* @returns The widget
*/
setUpdateFunc(updateFunc: WidgetUpdateFunc<S>): this;
/**
* Clears the function run on update.
* @returns The Widget
*/
clearUpdateFunc(): this;
/**
* Calls update() for this widget and all children widgets recursively.
* Children added last will be called last. If a widget is disabled, the update
* will stop there.
*/
cascadeUpdate(): void;
/**
* Calls an updateFunc if previously given, and merges it into the
* widgets state.
*/
update(): void;
/**
* Calls the draw() method of this widget and all children widgets recursively.
* If a widget is disabled it will stop the cascade.
*/
cascadeDraw(): void;
/**
* Draws on to the given terminal using the widget's current state. Will not draw if disabled.
* @returns
*/
draw(): void;
/**
* Sends a mouse event through a tree of Widgets. If any widget's onMouseClick
* returns true, the event will be captured and stop cascading.
*
* Widgets are called in reverse order, so the last one to render will be
* the first one called for onMouseClick.
* @param mouse
*/
cascadeMouseClick(event: MouseHandlerEvent): boolean;
/**
* Calls onMouseClick if the widget is not disabled
* @param event - MouseHanderEvent
*/
mouseClick(event: MouseHandlerEvent): boolean;
/**
* Will be fired on click() or cascadeClick(). Return 'true' to capture the event, which
* will make it no longer cascade to other widgets. Return 'false' to pass the event to other widgets.
* @param absolutePosition Vector2 - The absolute position of the rendering terminal
* @returns boolean - Capture the event
*/
onMouseClick(mouse: MouseHandlerEvent): boolean;
/**
* Draws a glyph on the terminal using a position local to the widget.
* @param pos - A local position
* @param glyph - The glyph to draw
* @returns
*/
drawGlyph(pos: Vector2, glyph: Glyph): void;
/**
* A method to be implemented by widgets to render to the terminal.
*/
abstract onDraw(): void;
}