"use strict"; // Box that can contain other components Toolkit.Panel = class Panel extends Toolkit.Component { // Object constructor constructor(application) { super(application, "div"); // Configure instance fields this.application = application; this.children = []; this.crossAlign = "start"; this.direction = "row"; this.edge = "left"; this.hGap = "0"; this.layout = "split"; this.mainAlign = "start"; this.sizeable = false; this.vGap = "0"; this.wrap = false; // Configure element this.element.style.minHeight = "0"; this.element.style.minWidth = "0"; // Configure layout this.setSplitLayout("left", false); } ///////////////////////////// Public Methods ////////////////////////////// // Add a component as a child of this container add(component, index) { // Determine the ordinal position of the element within the container index = !(typeof index == "number") ? this.children.length : Math.floor(Math.min(Math.max(0, index), this.children.length)); // Add the component to the container component.parent = this; this.children.splice(index, 0, component); this.arrange(); } // Create a Button and associate it with the application newButton(options) { return new Toolkit.Button(this.application, options); } // Create a MenuBar and associate it with the application newMenuBar(options) { return new Toolkit.MenuBar(this.application, options); } // Create a Panel and associate it with the application newPanel(options) { return new Toolkit.Panel(this.application, options); } // Remove a component from the container remove(component) { // Locate the component in the children let index = this.children.indexOf(component); if (index == -1) return; // Remove the component component.parent = null; component.element.remove(); this.children.splice(index, 1); this.arrange(); } // Configure the element with a flex layout setFlexLayout(direction, mainAlign, crossAlign, gap, wrap) { // Configure instance fields this.layout = "flex"; this.crossAlign = crossAlign; this.direction = direction; this.mainAlign = mainAlign; this.wrap = wrap; // Working variables switch (crossAlign) { case "end" : crossAlign = "flex-end" ; case "start": crossAlign = "flex-start"; } switch (mainAlign) { case "end" : mainAlign = "flex-end" ; case "start": mainAlign = "flex-start"; } // Configure element this.element.style.alignItems = crossAlign; this.element.style.display = "flex"; this.element.style.flexDirection = direction; this.element.style.justifyContent = mainAlign; if (direction == "column") { this.hGap = gap; this.element.style.rowGap = gap; } if (direction == "row") { this.vGap = gap; this.element.style.columnGap = gap; } if (wrap) this.element.style.flexWrap = "wrap"; else this.element.style.removeProperty("flex-wrap"); // Manage components this.arrange(); } // Configure the element with a split layout setSplitLayout(edge, sizeable) { // Configure instance fields this.layout = "split"; this.edge = edge; this.sizeable = sizeable; // Working variables let rows = null, cols = null; let tracks = [ "max-content", "auto" ]; if (sizeable) tracks.splice(1, 0, "max-content"); // Processing by edge switch (edge) { case "bottom": tracks.reverse(); // Fallthrough case "top" : rows = tracks.join(" "); break; case "right" : tracks.reverse(); // Fallthrough case "left" : cols = tracks.join(" "); } // Configure element this.element.style.display = "grid"; if (cols != null) this.element.style.gridTemplateColumns = cols; else this.element.style.removeProperty("grid-template-columns"); if (rows != null) this.element.style.gridTemplateRows = rows; else this.element.style.removeProperty("grid-template-rows"); // Manage components this.arrange(); } ///////////////////////////// Private Methods ///////////////////////////// // Configure the panel's DOM elements arrange() { let components = []; // Remove all children from the DOM for (let comp of this.children) comp.element.remove(); // Split layout if (this.layout == "split") { components.push(this.children[0]); components.push(this.children[1]); if (this.sizeable) components.splice(1, 0, this.splitter); if (this.edge == "bottom" || this.edge == "right") components.reverse(); } // Flex and grid layouts else { for (let comp of this.children) components.push(comp); } // Add the resulting elements to the DOM for (let comp of components) if (comp) this.element.appendChild(comp.element); } };