pvbemu/app/toolkit/Button.js

231 lines
6.1 KiB
JavaScript

"use strict";
// Push button
Toolkit.Button = class Button extends Toolkit.Component {
// Object constructor
constructor(application, options) {
super(application, "div", options);
options = options || {};
// Configure instance fields
this.clickListeners = [];
this.enabled = "enabled" in options ? !!options.enabled : true;
this.focusable = "focusable" in options?!!options.focusable:true;
this.name = options.name || "";
this.text = options.text || "";
this.toolTip = options.toolTip || "";
// Configure element
this.element.setAttribute("role", "button");
this.element.setAttribute("tabindex", "0");
this.element.style.cursor = "default";
this.element.style.userSelect = "none";
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.setEnabled (this.enabled );
this.setFocusable(this.focusable);
this.setName (this.name );
this.setText (this.text );
this.setToolTip (this.toolTip );
this.application.addComponent(this);
}
///////////////////////////// Public Methods //////////////////////////////
// Add a callback for click events
addClickListener(listener) {
if (this.clickListeners.indexOf(listener) == -1)
this.clickListeners.push(listener);
}
// The button was activated
click(e) {
if (!this.enabled)
return;
for (let listener of this.clickListeners)
listener(e);
}
// Request focus on the appropriate element
focus() {
this.element.focus();
}
// Retrieve the component's accessible name
getName() {
return this.name;
}
// Retrieve the component's display text
getText() {
return this.text;
}
// Retrieve the component's tool tip text
getToolTip() {
return this.toolTip;
}
// Determine whether the component is enabled
isEnabled() {
return this.enabled;
}
// Determine whether the component is focusable
isFocusable() {
return this.focusable;
}
// Specify whether the component is enabled
setEnabled(enabled) {
this.enabled = enabled = !!enabled;
this.element.setAttribute("aria-disabled", !enabled);
}
// Specify whether the component can receive focus
setFocusable(focusable) {
this.focusable = focusable = !!focusable;
if (focusable)
this.element.setAttribute("tabindex", "0");
else this.element.removeAttribute("tabindex");
}
// Specify the component's accessible name
setName(name) {
this.name = name || "";
this.localize();
}
// Specify the component's display text
setText(text) {
this.text = text || "";
this.localize();
}
// Specify the component's tool tip text
setToolTip(toolTip) {
this.toolTip = toolTip || "";
this.localize();
}
///////////////////////////// Package Methods /////////////////////////////
// Update display text with localized strings
localize() {
let name = this.name || this.text;
let text = this.text;
let toolTip = this.toolTip;
if (this.application) {
name = this.application.translate(name, this);
text = this.application.translate(text, this);
if (toolTip)
toolTip = this.application.translate(toolTip, this);
}
this.element.setAttribute("aria-label", name);
this.element.innerText = text;
if (toolTip)
this.element.setAttribute("title", toolTip);
else this.element.removeAttribute("title");
}
///////////////////////////// Private Methods /////////////////////////////
// Key down event handler
onkeydown(e) {
// Error checking
if (!this.enabled)
return;
// Processing by key
switch (e.key) {
case " ":
case "Enter":
this.click(e);
break;
default: return;
}
// Configure event
e.preventDefault();
e.stopPropagation();
}
// Pointer down event handler
onpointerdown(e) {
// Configure event
e.stopPropagation();
// Configure focus
if (this.enabled)
this.focus();
else return;
// Error checking
if (e.button != 0 || this.element.hasPointerCapture(e.captureId))
return;
// Configure element
this.element.setPointerCapture(e.pointerId);
this.element.setAttribute("active", "");
}
// Pointer move event handler
onpointermove(e) {
// Configure event
e.preventDefault();
e.stopPropagation();
// Error checking
if (!this.element.hasPointerCapture(e))
return;
// Working variables
let bounds = this.getBounds();
let active =
e.x >= bounds.x && e.x < bounds.x + bounds.width &&
e.y >= bounds.y && e.y < bounds.y + bounds.height
;
// Configure element
if (active)
this.element.setAttribute("active", "");
else this.element.removeAttribute("active");
}
// Pointer up event handler
onpointerup(e) {
// Configure event
e.preventDefault();
e.stopPropagation();
// Error checking
if (!this.element.hasPointerCapture(e.pointerId))
return;
// Configure element
this.element.releasePointerCapture(e.pointerId);
// Activate the component if it is active
if (!this.element.hasAttribute("active"))
return;
this.element.removeAttribute("active");
this.click(e);
}
};