From eb3b83fa2d56f3c85ac0d5c9b62223f6bd297940 Mon Sep 17 00:00:00 2001 From: Florrie Date: Mon, 16 Sep 2019 10:34:40 -0300 Subject: Add basic Element class --- ui/DisplayElement.js | 73 ++--------------------------------------------- ui/Element.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 71 deletions(-) create mode 100644 ui/Element.js diff --git a/ui/DisplayElement.js b/ui/DisplayElement.js index b27772e..fab957e 100644 --- a/ui/DisplayElement.js +++ b/ui/DisplayElement.js @@ -1,7 +1,7 @@ -const EventEmitter = require('events') +const Element = require('./Element') const exception = require('../util/exception') -module.exports = class DisplayElement extends EventEmitter { +module.exports = class DisplayElement extends Element { // A general class that handles dealing with screen coordinates, the tree // of elements, and other common stuff. // @@ -18,9 +18,6 @@ module.exports = class DisplayElement extends EventEmitter { this[DisplayElement.lastDrawValues] = {} this[DisplayElement.scheduledDraw] = false - this.children = [] - this.parent = null - this.visible = true this.x = 0 @@ -138,54 +135,6 @@ module.exports = class DisplayElement extends EventEmitter { Object.assign(this[DisplayElement.lastDrawValues], this[DisplayElement.drawValues]) } - eachDescendant(fn) { - // Run a function on this element, all of its children, all of their - // children, etc. - fn(this) - for (const child of this.children) { - child.eachDescendant(fn) - } - } - - addChild(child, afterIndex = this.children.length, {fixLayout = true} = {}) { - // TODO Don't let a direct ancestor of this be added as a child. Don't - // let itself be one of its childs either! - - if (child === this) { - throw exception( - 'EINVALIDHIERARCHY', 'An element cannot be a child of itself') - } - - child.parent = this - - if (afterIndex === this.children.length) { - this.children.push(child) - } else { - this.children.splice(afterIndex, 0, child) - } - - if (fixLayout) { - child.fixLayout() - } - } - - removeChild(child, {fixLayout = true} = {}) { - // Removes the given child element from the children list of this - // element. It won't be rendered in the future. If the given element - // isn't a direct child of this element, nothing will happen. - - if (child.parent !== this) { - return - } - - child.parent = null - this.children.splice(this.children.indexOf(child), 1) - - if (fixLayout) { - this.fixLayout() - } - } - centerInParent() { // Utility function to center this element in its parent. Must be called // only when it has a parent. Set the width and height of the element @@ -247,24 +196,6 @@ module.exports = class DisplayElement extends EventEmitter { } } - get root() { - let el = this - while (el.parent) { - el = el.parent - } - return el - } - - get directAncestors() { - const ancestors = [] - let el = this - while (el.parent) { - el = el.parent - ancestors.push(el) - } - return ancestors - } - getElementAt(x, y) { // Gets the topmost element at the provided absolute coordinate. // Note that elements which are not visible or have the clickThrough diff --git a/ui/Element.js b/ui/Element.js new file mode 100644 index 0000000..c5beb59 --- /dev/null +++ b/ui/Element.js @@ -0,0 +1,80 @@ +const EventEmitter = require('events') + +module.exports = class Element extends EventEmitter { + // The basic class containing methods for working with an element hierarchy. + // Generally speaking, you usually want to extend DisplayElement instead of + // this class. + + constructor() { + super() + + this.children = [] + this.parent = null + } + + eachDescendant(fn) { + // Run a function on this element, all of its children, all of their + // children, etc. + fn(this) + for (const child of this.children) { + child.eachDescendant(fn) + } + } + + addChild(child, afterIndex = this.children.length, {fixLayout = true} = {}) { + // TODO Don't let a direct ancestor of this be added as a child. Don't + // let itself be one of its childs either! + + if (child === this) { + throw exception( + 'EINVALIDHIERARCHY', 'An element cannot be a child of itself') + } + + child.parent = this + + if (afterIndex === this.children.length) { + this.children.push(child) + } else { + this.children.splice(afterIndex, 0, child) + } + + if (fixLayout) { + child.fixLayout() + } + } + + removeChild(child, {fixLayout = true} = {}) { + // Removes the given child element from the children list of this + // element. It won't be rendered in the future. If the given element + // isn't a direct child of this element, nothing will happen. + + if (child.parent !== this) { + return + } + + child.parent = null + this.children.splice(this.children.indexOf(child), 1) + + if (fixLayout) { + this.fixLayout() + } + } + + get root() { + let el = this + while (el.parent) { + el = el.parent + } + return el + } + + get directAncestors() { + const ancestors = [] + let el = this + while (el.parent) { + el = el.parent + ancestors.push(el) + } + return ancestors + } +} -- cgit 1.3.0-6-gf8a5