pvbemu/app/toolkit/CheckBox.js

191 lines
5.3 KiB
JavaScript

"use strict";
// On/off toggle checkbox
Toolkit.CheckBox = class CheckBox extends Toolkit.Panel {
// Object constructor
constructor(application, options) {
super(application, options);
options = options || {};
// Configure instance fields
this.changeListeners = [];
this.checked = false;
this.enabled = "enabled" in options ? !!options.enabled : true;
this.text = options.text || "";
// Configure element
this.setLayout("grid", {
columns : "max-content max-content"
});
this.setDisplay("inline-grid");
this.setHollow(false);
this.setOverflow("visible", "visible");
this.element.setAttribute("tabindex", "0");
this.element.setAttribute("role", "checkbox");
this.element.setAttribute("aria-checked", "false");
this.element.style.alignItems = "center";
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 check box
this.check = this.add(this.newLabel());
this.check.element.setAttribute("name", "check");
this.check.element.setAttribute("aria-hidden", "true");
// Configure label
this.label = this.add(this.newLabel({ localized: true }));
this.label.element.setAttribute("name", "label");
this.element.setAttribute("aria-labelledby", this.label.id);
// Configure properties
this.setChecked(options.checked);
this.setEnabled(this.enabled);
this.setText (this.text );
}
///////////////////////////// Public Methods //////////////////////////////
// Add a callback for change events
addChangeListener(listener) {
if (this.changeListeners.indexOf(listener) == -1)
this.changeListeners.push(listener);
}
// Request focus on the appropriate element
focus() {
this.element.focus();
}
// Determine whether the component is checked
isChecked() {
return this.checked;
}
// Determine whether the component is enabled
isEnabled() {
return this.enabled;
}
// Specify whether the component is checked
setChecked(checked, e) {
checked = !!checked;
if (checked == this.checked)
return;
this.checked = checked;
this.element.setAttribute("aria-checked", checked);
if (e === undefined)
return;
for (let listener of this.changeListeners)
listener(e);
}
// Specify whether the component is enabled
setEnabled(enabled) {
this.enabled = enabled = !!enabled;
this.element.setAttribute("aria-disabled", !enabled);
if (enabled)
this.element.setAttribute("tabindex", "0");
else this.element.removeAttribute("tabindex");
}
// Specify the component's display text
setText(text) {
this.text = text = text || "";
this.label.setText(text);
}
///////////////////////////// Private Methods /////////////////////////////
// Key down event handler
onkeydown(e) {
// Error checking
if (!this.enabled)
return;
// Ignore the key
if (e.key != " ")
return;
// Configure event
e.preventDefault();
e.stopPropagation();
// Toggle the checked state
this.setChecked(!this.checked, e);
}
// Pointer down event handler
onpointerdown(e) {
// Configure event
//e.preventDefault();
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) {
// Error checking
if (!this.element.hasPointerCapture(e))
return;
// Configure event
e.preventDefault();
e.stopPropagation();
// 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.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.setChecked(!this.checked, e);
}
};