119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
// Single LED component for the LogicSimulator
|
|
// Copyright (C) 2022 Sascha Nitsch
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
interface LEDParam extends BaseComponentParam {
|
|
color: string;
|
|
}
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
class LED extends BaseComponent {
|
|
private color: string;
|
|
private onColor: string;
|
|
private offColor: string;
|
|
private a: boolean | null = false;
|
|
private b: boolean | null = false;
|
|
constructor(simulator: Simulator, id: string, param: LEDParam) {
|
|
super(simulator, id, param);
|
|
this.color = param.color;
|
|
switch (this.color) {
|
|
case 'red':
|
|
this.onColor = 'ffb9b9';
|
|
this.offColor = '990000';
|
|
break;
|
|
case 'blue':
|
|
this.onColor = 'b9b9ff';
|
|
this.offColor = '2222ff';
|
|
break;
|
|
case 'green':
|
|
this.onColor = 'b9ffb9';
|
|
this.offColor = '22b922';
|
|
break;
|
|
case 'orange':
|
|
this.onColor = 'ff9900';
|
|
this.offColor = 'cc5500';
|
|
break;
|
|
case 'yellow':
|
|
this.onColor = 'ffffb9';
|
|
this.offColor = 'cccc00';
|
|
break;
|
|
default:
|
|
this.onColor = 'ffffff';
|
|
this.offColor = '444444';
|
|
}
|
|
this.pins.set(
|
|
'a',
|
|
new TriState(this, 0, -10, undefined, {
|
|
type: 'LED',
|
|
id: id + '-a',
|
|
})
|
|
);
|
|
this.pins.set(
|
|
'b',
|
|
new TriState(this, 0, 10, undefined, {
|
|
type: 'LED',
|
|
id: id + '-b',
|
|
})
|
|
);
|
|
}
|
|
|
|
addGradient(canvas: SVGElement, type: string, color1: string, color2: string) {
|
|
const grad = document.createElementNS('http://www.w3.org/2000/svg', 'radialGradient');
|
|
grad.id = 'radialGradient' + type + this.color;
|
|
let stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
|
|
stop.setAttribute('offset', '0.4');
|
|
stop.setAttribute('style', 'stop-color:#' + color1 + ';stop-opacity:1');
|
|
grad.appendChild(stop);
|
|
|
|
stop = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
|
|
stop.setAttribute('offset', '1');
|
|
stop.setAttribute('style', 'stop-color:#' + color2 + ';stop-opacity:1');
|
|
grad.appendChild(stop);
|
|
canvas.appendChild(grad);
|
|
}
|
|
|
|
setup(parent: SVGElement) {
|
|
// color already registered?
|
|
const canvas = parent.ownerSVGElement;
|
|
if (canvas === null) return;
|
|
const c = canvas.getElementById('radialGradientOff' + this.color);
|
|
if (c === null) {
|
|
this.addGradient(canvas, 'Off', this.offColor, this.offColor);
|
|
this.addGradient(canvas, 'On', this.onColor, this.offColor);
|
|
}
|
|
super.doSetup('led', parent);
|
|
if (this.element) {
|
|
this.element.setAttribute('style', 'fill:url(#radialGradientOff' + this.color + ')');
|
|
}
|
|
}
|
|
|
|
io() {
|
|
this.a = this.tri(this.getPin('a').getAndReset());
|
|
this.b = this.tri(this.getPin('b').getAndReset());
|
|
}
|
|
|
|
update() {
|
|
const stateA = this.a;
|
|
const stateB = this.b;
|
|
if (this.element !== null) {
|
|
if (stateA !== stateB && stateA !== null && stateB !== null) {
|
|
this.element.setAttribute('style', 'fill:url(#radialGradientOn' + this.color + ')');
|
|
} else {
|
|
this.element.setAttribute('style', 'fill:url(#radialGradientOff' + this.color + ')');
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|