lazy-widgets
Version:
Typescript retained mode GUI for the HTML canvas API
101 lines • 3.52 kB
JavaScript
import { ButtonClickHelper } from '../helpers/ButtonClickHelper.js';
import { BaseContainer } from './BaseContainer.js';
import { PropagationModel } from '../events/WidgetEvent.js';
import { SingleParentXMLInputConfig } from '../xml/SingleParentXMLInputConfig.js';
import { ClickEvent } from '../events/ClickEvent.js';
import { FocusEvent } from '../events/FocusEvent.js';
import { BlurEvent } from '../events/BlurEvent.js';
import { PointerEvent } from '../events/PointerEvent.js';
import { LeaveEvent } from '../events/LeaveEvent.js';
/**
* A {@link BaseContainer} which can be {@link ClickHelper | clicked} as a
* button. Since the button grabs all events, no events are propagated to the
* child.
*
* Can be constrained to a specific type of children.
*
* @category Widget
*/
export class Button extends BaseContainer {
constructor(child, properties) {
var _a;
super(child, properties);
this._clickable = (_a = properties === null || properties === void 0 ? void 0 : properties.clickable) !== null && _a !== void 0 ? _a : true;
this.clickHelper = new ButtonClickHelper(this);
this.tabFocusable = true;
}
/**
* Click the button. If the button is {@link Button#clickable}, then a
* {@link ClickEvent} will be fired.
*/
click() {
this.dispatchEvent(new ClickEvent(this));
}
activate() {
super.activate();
this.clickHelper.reset();
}
deactivate() {
super.deactivate();
this.clickHelper.reset();
}
handleEvent(event) {
if (event.propagation !== PropagationModel.Trickling) {
if (event.isa(FocusEvent)) {
this.clickHelper.onFocusGrabbed(event.focusType);
return this;
}
else if (event.isa(BlurEvent)) {
this.clickHelper.onFocusDropped(event.focusType);
return this;
}
else {
return super.handleEvent(event);
}
}
const tricklingEvent = event;
if (tricklingEvent.target !== this) {
const superCapture = super.handleEvent(event);
if (superCapture) {
if (event instanceof PointerEvent) {
// XXX simulate an unhover, since the pointer is over some
// nested button now
this.clickHelper.handleEvent(new LeaveEvent(this), this.root, this._clickable, this.bounds);
}
return superCapture;
}
if (tricklingEvent.target !== null) {
return null;
}
}
const [wasClick, capture] = this.clickHelper.handleEvent(tricklingEvent, this.root, this._clickable, this.bounds);
if (wasClick) {
this.click();
}
return capture ? this : null;
}
handlePreLayoutUpdate() {
super.handlePreLayoutUpdate();
this.clickHelper.doneProcessing();
}
/**
* Is the button clickable? True by default. Used for disabling the button
* without hiding it.
*/
get clickable() {
return this._clickable;
}
set clickable(clickable) {
if (this._clickable === clickable) {
return;
}
this._clickable = clickable;
this.clickHelper.reset();
this.markWholeAsDirty();
}
}
Button.autoXML = {
name: 'button',
inputConfig: SingleParentXMLInputConfig
};
//# sourceMappingURL=Button.js.map