lazy-widgets
Version:
Typescript retained mode GUI for the HTML canvas API
133 lines • 4.42 kB
JavaScript
import { Parent } from './Parent.js';
/**
* A specialised version of the {@link Parent} class for parents with any amount
* of children and public access to modifying this list of children.
*
* Can be constrained to a specific type of children.
*
* @category Widget
*/
export class MultiParent extends Parent {
constructor(children, properties) {
super(properties);
this._children = [...children];
for (const child of this._children) {
child.inheritedTheme = this.inheritedTheme;
}
}
[Symbol.iterator]() {
const children = [...this._children];
const childCount = children.length;
let index = 0;
return {
next() {
if (index >= childCount || index < 0) {
return { value: undefined, done: true };
}
else {
return { value: children[index++], done: false };
}
}
};
}
get childCount() {
return this._children.length;
}
/**
* Add child(ren) to this widget.
*
* {@link Widget#_layoutDirty} is set to true and each child's
* {@link Widget#inheritedTheme} is set so that new children inherit this
* widget's theme.
*
* Calls {@link Widget#markWholeAsDirty}.
*
* @param children - If this is a widget, then it is pushed to {@link MultiParent#_children}. If this is an array of widgets, then each widget is pushed to {@link MultiParent#_children}.
* @returns Returns this so that the method is chainable.
*/
add(children) {
if (Array.isArray(children)) {
const isAttached = this.attached;
for (const child of children) {
this._children.push(child);
child.inheritedTheme = this.inheritedTheme;
if (isAttached) {
child.attach(this.root, this.viewport, this);
}
}
}
else {
this._children.push(children);
children.inheritedTheme = this.inheritedTheme;
if (this.attached) {
children.attach(this.root, this.viewport, this);
}
}
this._layoutDirty = true;
this.markWholeAsDirty();
return this;
}
/**
* Remove child(ren) from this widget.
*
* Calls {@link Widget#markWholeAsDirty} and sets
* {@link Widget#_layoutDirty} to true.
*
* @param children - If this is a widget, then it is removed from {@link MultiParent#_children}. If this is an array of widgets, then each widget is removed from {@link MultiParent#_children}.
* @returns Returns this so that the method is chainable.
*/
remove(children) {
const isAttached = this.attached;
if (Array.isArray(children)) {
for (const child of children) {
const pos = this._children.indexOf(child);
if (pos !== -1) {
this._children.splice(pos, 1);
child.inheritedTheme = undefined;
if (isAttached) {
child.detach();
}
}
}
}
else {
const pos = this._children.indexOf(children);
if (pos !== -1) {
this._children.splice(pos, 1);
children.inheritedTheme = undefined;
if (isAttached) {
children.detach();
}
}
}
this._layoutDirty = true;
this.markWholeAsDirty();
return this;
}
/**
* Remove all children from this widget.
*
* Calls {@link Widget#markWholeAsDirty} and sets
* {@link Widget#_layoutDirty} to true.
*
* @returns Returns this so that the method is chainable.
*/
clearChildren() {
if (this.attached) {
for (const child of this._children) {
child.inheritedTheme = undefined;
child.detach();
}
}
else {
for (const child of this._children) {
child.inheritedTheme = undefined;
}
}
this._children.length = 0;
this._layoutDirty = true;
this.markWholeAsDirty();
return this;
}
}
//# sourceMappingURL=MultiParent.js.map