Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
6.2 kB · 289 lines
TypeScript
at develop
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290import type { AttributeDefinitions } from "../AttributeDefinitions";import { DockLocation } from "../DockLocation";import type { DropInfo } from "../DropInfo";import { Orientation } from "../Orientation";import { Rect } from "../Rect";import type { IDraggable } from "./IDraggable";import type { IJsonBorderNode, IJsonRowNode, IJsonTabNode, IJsonTabSetNode } from "./IJsonModel";import type { Model } from "./Model";
export abstract class Node { /** @internal */ protected model: Model; /** @internal */ protected attributes: Record<string, any>; /** @internal */ protected parent?: Node; /** @internal */ protected children: Node[]; /** @internal */ protected rect: Rect; /** @internal */ protected path: string; /** @internal */ protected listeners: Map<string, (params: any) => void>;
/** @internal */ protected constructor(_model: Model) { this.model = _model; this.attributes = {}; this.children = []; this.rect = Rect.empty(); this.listeners = new Map(); this.path = ""; }
getId() { let id = this.attributes.id; if (id !== undefined) { return id as string; }
id = this.model.nextUniqueId(); this.setId(id);
return id as string; }
getModel() { return this.model; }
getType() { return this.attributes.type as string; }
getParent() { return this.parent; }
getChildren() { return this.children; }
getRect() { return this.rect; }
getPath() { return this.path; }
getOrientation(): Orientation { if (this.parent === undefined) { return this.model.isRootOrientationVertical() ? Orientation.VERT : Orientation.HORZ; } return Orientation.flip(this.parent.getOrientation()); }
// event can be: resize, visibility, maximize (on tabset), close setEventListener(event: string, callback: (params: any) => void) { this.listeners.set(event, callback); }
removeEventListener(event: string) { this.listeners.delete(event); }
abstract toJson(): IJsonRowNode | IJsonBorderNode | IJsonTabSetNode | IJsonTabNode | undefined;
/** @internal */ setId(id: string) { this.attributes.id = id; }
/** @internal */ fireEvent(event: string, params: any) { if (this.listeners.has(event)) { this.listeners.get(event)!(params); } }
/** @internal */ getAttr(name: string) { let val = this.attributes[name];
if (val === undefined) { const modelName = this.getAttributeDefinitions().getModelName(name); if (modelName !== undefined) { val = this.model.getAttribute(modelName); } }
return val; }
/** @internal */ forEachNode(fn: (node: Node, level: number) => void, level: number) { fn(this, level); level++; for (const node of this.children) { node.forEachNode(fn, level); } }
/** @internal */ setPaths(path: string) { let i = 0;
for (const node of this.children) { let newPath = path; if (node.getType() === "row") { if (node.getOrientation() === Orientation.VERT) { newPath += `/c${i}`; } else { newPath += `/r${i}`; } } else if (node.getType() === "tabset") { newPath += `/ts${i}`; } else if (node.getType() === "tab") { newPath += `/t${i}`; }
node.path = newPath;
node.setPaths(newPath); i++; } }
/** @internal */ setParent(parent: Node) { this.parent = parent; }
/** @internal */ setRect(rect: Rect) { this.rect = rect; }
/** @internal */ setPath(path: string) { this.path = path; }
/** @internal */ setWeight(weight: number) { this.attributes.weight = weight; }
/** @internal */ setSelected(index: number) { this.attributes.selected = index; }
/** @internal */ findDropTargetNode( windowId: string, dragNode: Node & IDraggable, x: number, y: number, ): DropInfo | undefined { let rtn: DropInfo | undefined; if (this.rect.contains(x, y)) { if (this.model.getMaximizedTabset(windowId) !== undefined) { rtn = this.model.getMaximizedTabset(windowId)!.canDrop(dragNode, x, y); } else { rtn = this.canDrop(dragNode, x, y); if (rtn === undefined) { if (this.children.length !== 0) { for (const child of this.children) { rtn = child.findDropTargetNode(windowId, dragNode, x, y); if (rtn !== undefined) { break; } } } } } }
return rtn; }
/** @internal */ canDrop(dragNode: Node & IDraggable, x: number, y: number): DropInfo | undefined { return undefined; }
/** @internal */ canDockInto(dragNode: Node & IDraggable, dropInfo: DropInfo | undefined): boolean { if (dropInfo != null) { if (dropInfo.location === DockLocation.CENTER && dropInfo.node.isEnableDrop() === false) { return false; }
// prevent named tabset docking into another tabset, since this would lose the header if ( dropInfo.location === DockLocation.CENTER && dragNode.getType() === "tabset" && dragNode.getName() !== undefined ) { return false; }
if (dropInfo.location !== DockLocation.CENTER && dropInfo.node.isEnableDivide() === false) { return false; }
// finally check model callback to check if drop allowed if (this.model.getOnAllowDrop()) { return (this.model.getOnAllowDrop() as (dragNode: Node, dropInfo: DropInfo) => boolean)( dragNode, dropInfo, ); } } return true; }
/** @internal */ removeChild(childNode: Node) { const pos = this.children.indexOf(childNode); if (pos !== -1) { this.children.splice(pos, 1); } return pos; }
/** @internal */ addChild(childNode: Node, pos?: number) { if (pos != null) { this.children.splice(pos, 0, childNode); } else { this.children.push(childNode); pos = this.children.length - 1; } childNode.parent = this; return pos; }
/** @internal */ removeAll() { this.children = []; }
/** @internal */ styleWithPosition(style?: Record<string, any>) { if (style == null) { style = {}; } return this.rect.styleWithPosition(style); }
/** @internal */ isEnableDivide() { return true; }
/** @internal */ toAttributeString() { return JSON.stringify(this.attributes, undefined, "\t"); }
// implemented by subclasses /** @internal */ abstract updateAttrs(json: any): void; /** @internal */ abstract getAttributeDefinitions(): AttributeDefinitions;}