pvbemu/app/toolkit/Button.js

231 lines
6.1 KiB
JavaScript
Raw Normal View History

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