pvbemu/app/toolkit/Component.js

153 lines
4.4 KiB
JavaScript
Raw Normal View History

2021-08-23 23:56:36 +00:00
"use strict";
// Base features for all components
Toolkit.Component = class Component {
// Object constructor
2021-08-26 19:23:18 +00:00
constructor(application, tagname, options) {
options = options || {};
2021-08-23 23:56:36 +00:00
// Configure instance fields
this.application = application;
this.containers = [ this ];
2021-08-26 19:23:18 +00:00
this.display = null;
2021-08-23 23:56:36 +00:00
this.element = document.createElement(tagname);
this.id = this.element.id = Toolkit.id();
this.parent = null;
this.properties = {};
this.resizeListeners = [];
2021-08-26 19:23:18 +00:00
this.resizeObserver = null;
this.visible = "visible" in options ? !!options.visible : true;
2021-08-23 23:56:36 +00:00
// Configure component
this.element.component = this;
2021-08-26 19:23:18 +00:00
this.setVisible(this.visible);
2021-08-23 23:56:36 +00:00
}
///////////////////////////// Public Methods //////////////////////////////
// Add a callback for resize events
addResizeListener(listener) {
if (this.resizeListeners.indexOf(listener) != -1)
return;
2021-08-26 19:23:18 +00:00
if (this.resizeObserver == null) {
this.resizeObserver = new ResizeObserver(()=>this.onresized());
this.resizeObserver.observe(this.element);
}
2021-08-23 23:56:36 +00:00
this.resizeListeners.push(listener);
}
// Remove the component from its parent
remove() {
this.parent && this.parent.remove(this);
}
// Retrieve the bounding box of the element
getBounds() {
return this.element.getBoundingClientRect();
}
2021-08-26 19:23:18 +00:00
// Retrieve the display CSS property of the visible element
getDisplay() {
return this.display;
}
// Determine whether the component is visible
isVisible() {
for (let comp = this; comp != null; comp = comp.parent)
if (!comp.visible)
return false;
return true;
}
// Specify the display CSS property of the visible element
setDisplay(display) {
this.display = display || null;
this.setVisible(this.visible);
}
2021-08-23 23:56:36 +00:00
// Specify the height of the element
setHeight(height) {
if (height === null)
this.element.style.removeProperty("height");
2021-08-26 19:23:18 +00:00
else this.element.style.height =
typeof height == "number" ? height + "px" : height
}
// Specify the horizontal position of the component
setLeft(left) {
if (left === null)
this.element.style.removeProperty("left");
else this.element.style.left =
typeof left == "number" ? left + "px" : left ;
}
// Specify the absolute position of the component
setLocation(left, top) {
this.setLeft(left);
this.setTop (top );
}
// Specify both the width and the height of the component
setSize(width, height) {
this.setHeight(height);
this.setWidth (width );
}
// Specify the vertical position of the component
setTop(top) {
if (top === null)
this.element.style.removeProperty("top");
else this.element.style.top =
typeof top == "number" ? top + "px" : top ;
}
// Specify whether the component is visible
setVisible(visible) {
this.visible = visible = !!visible;
if (visible) {
if (this.display == null)
this.element.style.removeProperty("display");
else this.element.style.display = this.display;
} else this.element.style.display = "none";
2021-08-23 23:56:36 +00:00
}
// Specify the width of the element
setWidth(width) {
if (width === null)
this.element.style.removeProperty("width");
2021-08-26 19:23:18 +00:00
else this.element.style.width =
typeof width == "number" ? width + "px" : width ;
2021-08-23 23:56:36 +00:00
}
///////////////////////////// Package Methods /////////////////////////////
// Determine whether this component contains another
contains(comp) {
if (comp == null)
return false;
if (comp instanceof Toolkit.Component)
comp = comp.element;
for (let cont of this.containers)
if ((cont instanceof Toolkit.Component ? cont.element : cont)
.contains(comp)) return true;
return false;
}
///////////////////////////// Private Methods /////////////////////////////
// Resize event handler
2021-08-26 19:23:18 +00:00
onresized() {
2021-08-23 23:56:36 +00:00
let bounds = this.getBounds();
for (let listener of this.resizeListeners)
listener(bounds, this);
}
};