// 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 . 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; } }