"use strict"; // Interactive splitter Toolkit.Splitter = class Splitter extends Toolkit.Component { // Object constructor constructor(application, options) { super(application, "div", options); options = options || {}; // Configure instance fields this.component = options.component || null; this.dragPointer = null; this.dragPos = 0; this.dragSize = 0; this.orientation = options.orientation || "horizontal"; this.name = options.name || ""; this.edge = options.edge || (this.orientation == "horizontal" ? "top" : "left"); // Configure element this.element.setAttribute("role" , "separator"); this.element.setAttribute("tabindex" , "0"); this.element.setAttribute("aria-valuemin", "0"); this.element.addEventListener("keydown" , e=>this.onkeydown (e)); this.element.addEventListener("pointerdown", e=>this.onpointerdown(e)); this.element.addEventListener("pointermove", e=>this.onpointermove(e)); this.element.addEventListener("pointerup" , e=>this.onpointerup (e)); // Configure properties this.setComponent (this.component ); this.setName (this.name ); this.setOrientation(this.orientation); this.application.addComponent(this); } ///////////////////////////// Public Methods ////////////////////////////// // Request focus on the appropriate element focus() { this.element.focus(); } // Retrieve the component managed by this Splitter getComponent() { return this.component; } // Retrieve the component's accessible name getName() { return this.name; } // Retrieve the component's orientation getOrientation() { return this.orientation; } // Determine the current and maximum separator values measure() { let max = 0; let now = 0; // Mesure the component if (this.component != null && this.parent != null) { let component = this.component.getBounds(); let bounds = this.getBounds(); let panel = this.parent.getBounds(); // Horizontal Splitter if (this.orientation == "horizontal") { max = panel.height - bounds.height; now = Math.max(0, Math.min(max, component.height)); this.component.setSize(null, now); } // Vertical Splitter else { max = panel.width - bounds.width; now = Math.max(0, Math.min(max, component.width)); this.component.setSize(now, null); } } // Configure element this.element.setAttribute("aria-valuemax", max); this.element.setAttribute("aria-valuenow", now); } // Specify the component managed by this Splitter setComponent(component) { this.component = component = component || null; this.element.setAttribute("aria-controls", component == null ? "" : component.id); this.measure(); } // Specify the component's accessible name setName(name) { this.name = name || ""; this.localize(); } // Specify the component's orientation setOrientation(orientation) { switch (orientation) { case "horizontal": this.orientation = "horizontal"; this.setSize(null, 3, true); this.element.setAttribute("aria-orientation", "horizontal"); this.element.style.cursor = "ew-resize"; break; case "vertical": this.orientation = "vertical"; this.setSize(3, null, true); this.element.setAttribute("aria-orientation", "vertical"); this.element.style.cursor = "ns-resize"; } this.measure(); } ///////////////////////////// Package Methods ///////////////////////////// // Update display text with localized strings localize() { let name = this.name; if (this.application) { name = this.application.translate(name, this); } this.element.setAttribute("aria-label", name); } ///////////////////////////// Private Methods ///////////////////////////// // Key press event handler onkeydown(e) { // Error checking if (this.component == null) return; let pos = this.component.getBounds(); let size = this .getBounds(); let max = this.parent .getBounds(); if (this.orientation == "horizontal") { max = max .height; pos = pos .height; size = size.height; } else { max = max .width; pos = pos .width; size = size.width; } if (this.edge == "top" || this.edge == "left") max -= size; // Processing by key if (this.component != null) switch (e.key) { case "ArrowDown": switch (this.edge) { case "bottom": this.component.setSize(null, Math.min(max, pos - 6)); break; case "top": this.component.setSize(null, Math.min(max, pos + 6)); } break; case "ArrowLeft": switch (this.edge) { case "left": this.component.setSize(Math.min(max, pos - 6), null); break; case "right": this.component.setSize(Math.min(max, pos + 6), null); } break; case "ArrowRight": switch (this.edge) { case "left": this.component.setSize(Math.min(max, pos + 6), null); break; case "right": this.component.setSize(Math.min(max, pos - 6), null); } break; case "ArrowUp": switch (this.edge) { case "bottom": this.component.setSize(null, Math.min(max, pos + 6)); break; case "top": this.component.setSize(null, Math.min(max, pos - 6)); } break; case "Escape": if (this.dragPointer === null) return; this.element.releasePointerCapture(this.dragPointer); this.dragPointer = null; if (this.orientation == "horizontal") this.component.setHeight(null, this.dragSize); else this.component.setWidth(this.dragSize, null); break; default: return; } // Configure event e.preventDefault(); e.stopPropagation(); } // Pointer down event handler onpointerdown(e) { // Request focus this.focus(); // Configure event e.stopPropagation(); // Error checking if ( this.component == null || e.button != 0 || this.element.hasPointerCapture(e.pointerId) ) return; // Capture the pointer this.element.setPointerCapture(e.pointerId); this.dragPointer = e.pointerId; let bounds = this.component.getBounds(); if (this.orientation == "horizontal") { this.dragPos = e.y; this.dragSize = bounds.height; } else { this.dragPos = e.x; this.dragSize = bounds.width; } } // Pointer move event handler onpointermove(e) { // Configure event e.preventDefault(); e.stopPropagation(); // Error checking if ( this.component == null || !this.element.hasPointerCapture(e.pointerId) ) return; // Resize the component let bounds = this.getBounds(); let panel = this.parent.getBounds(); switch (this.edge) { case "bottom": this.component.setSize(null, Math.max(0, Math.min( this.dragSize - e.y + this.dragPos, panel.height - bounds.height ))); break; case "left": this.component.setSize(Math.max(0, Math.min( this.dragSize + e.x - this.dragPos, panel.width - bounds.width )), null); break; case "right": this.component.setSize(Math.max(0, Math.min( this.dragSize - e.x + this.dragPos, panel.width - bounds.width )), null); break; case "top": this.component.setSize(null, Math.max(0, Math.min( this.dragSize + e.y - this.dragPos, panel.height - bounds.height ))); break; } this.measure(); } // Pointer up event handler onpointerup(e) { e.preventDefault(); e.stopPropagation(); this.element.releasePointerCapture(e.pointerId); this.dragPointer = null; } };