// Toggle-button 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 . // eslint-disable-next-line @typescript-eslint/no-unused-vars class ToggleButton extends BaseComponent { private pressed = false; private forcephysical = false; private text: NodeListOf | undefined; private a: WireState; private q: WireState; private p1: WireState; private p2: WireState; private p3: WireState; private p4: WireState; constructor(simulator: Simulator, id: string, param: BaseComponentParam) { super(simulator, id, param); this.pins.set('a', new TriState(this, 0, 0, undefined, { id: id + '-a' })); this.pins.set('q', new TriState(this, 0, 0, undefined, { id: id + '-q' })); this.pins.set('p1', new TriState(this, 0, 0, undefined, { id: id + '-p1' })); this.pins.set('p2', new TriState(this, 10.16, 0, undefined, { id: id + '-p2' })); this.pins.set( 'p3', new TriState(this, 10.16, -5.08 * 3, undefined, { id: id + '-p3', }) ); this.pins.set('p4', new TriState(this, 0, -5.08 * 3)); if (this.extraclass && this.extraclass.indexOf('forcephysical') !== -1) { this.forcephysical = true; } this.a = WireState.float; this.q = WireState.float; this.p1 = WireState.float; this.p2 = WireState.float; this.p3 = WireState.float; this.p4 = WireState.float; } setup(canvas: SVGElement) { super.doSetup('togglebutton', canvas); if (this.element !== null) { this.text = this.element.querySelectorAll('.inner'); this.element.addEventListener('mousedown', this.activate.bind(this)); } if (this.breadboard) { this.simulator.wire(null, [this.getPin('p1'), this.breadboard.getPin('E' + this.col)]); this.simulator.wire(null, [this.getPin('p2'), this.breadboard.getPin('E' + (2 + this.col))]); this.simulator.wire(null, [this.getPin('p3'), this.breadboard.getPin('F' + (2 + this.col))]); this.simulator.wire(null, [this.getPin('p4'), this.breadboard.getPin('F' + this.col)]); } } activate(e: Event) { // console.log(e); e.preventDefault(); this.pressed = !this.pressed; // document.text = this.text; if (this.breadboard || this.forcephysical) { if (this.text !== undefined) { this.text[1].textContent = this.pressed ? '1' : '0'; } } else { if (this.text !== undefined) { this.text[0].textContent = this.pressed ? '---' : '] ['; } } this.simulator.manualtick(); } io() { this.a = this.getPin('a').getAndReset(); this.p1 = this.getPin('p1').getAndReset(); this.p2 = this.getPin('p2').getAndReset(); this.p3 = this.getPin('p3').getAndReset(); this.p4 = this.getPin('p4').getAndReset(); // console.log(this.id, "input:", this.state.p1, this.state.p4); } update() { if (this.breadboard || this.forcephysical) { let top = this.p3; if (top !== WireState.float) { if (this.p4 !== WireState.float && this.p4 !== top) { console.log('boom ToggleButton top', this.id); } } else { top = this.p4; } const bottom = this.p1; if (bottom !== WireState.float) { if (this.p2 !== WireState.float && this.p2 !== bottom) { console.log('boom ToggleButton buttom', this.id); } } else { top = this.p2; } if (this.pressed) { let mod = false; if (top === WireState.float || top === WireState.up || top === WireState.down) { const old = top; this.p3 = bottom; this.p4 = bottom; this.getPin('p3').setState(bottom); this.getPin('p4').setState(bottom); mod = bottom !== old; } else if (bottom === WireState.float || bottom === WireState.up || bottom === WireState.down) { const old = bottom; this.p1 = top; this.p2 = top; this.getPin('p1').setState(top); this.getPin('p2').setState(top); mod = top !== old; } else { if (top === bottom) { this.p1 = top; this.p2 = top; this.p3 = top; this.p4 = top; this.getPin('p1').setState(top); this.getPin('p2').setState(top); this.getPin('p3').setState(top); this.getPin('p4').setState(top); } else { console.log('boom togglebutton', this.id, top, bottom); } } return mod; } else { return false; } } else { const oldstate = this.q; const q = this.pressed ? this.a : WireState.float; this.q = q; this.getPin('q').setState(q); return oldstate !== q; } } }