Replace horizontal toolbar sections with dropdown buttons (I/O, Gates, Components). Each opens a dropdown menu on click, keeping the toolbar clean and compact. Dropdowns close on outside click or after selecting a gate. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
129 lines
6.0 KiB
HTML
129 lines
6.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Logic Gates — MontLab</title>
|
|
<link rel="stylesheet" href="css/style.css">
|
|
</head>
|
|
<body>
|
|
<div id="toolbar">
|
|
<span class="logo">⚡ Logic Lab</span>
|
|
|
|
<!-- I/O Dropdown -->
|
|
<div class="toolbar-dropdown">
|
|
<button class="dropdown-toggle">I/O <span class="dropdown-arrow">▾</span></button>
|
|
<div class="dropdown-menu">
|
|
<button class="gate-btn input-btn" data-gate="INPUT">INPUT</button>
|
|
<button class="gate-btn clock-btn" data-gate="CLOCK">CLOCK</button>
|
|
<button class="gate-btn output-btn" data-gate="OUTPUT">OUTPUT</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Gates Dropdown -->
|
|
<div class="toolbar-dropdown">
|
|
<button class="dropdown-toggle">Gates <span class="dropdown-arrow">▾</span></button>
|
|
<div class="dropdown-menu">
|
|
<button class="gate-btn" data-gate="AND">AND</button>
|
|
<button class="gate-btn" data-gate="OR">OR</button>
|
|
<button class="gate-btn" data-gate="NOT">NOT</button>
|
|
<button class="gate-btn" data-gate="NAND">NAND</button>
|
|
<button class="gate-btn" data-gate="NOR">NOR</button>
|
|
<button class="gate-btn" data-gate="XOR">XOR</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Components Dropdown -->
|
|
<div class="toolbar-dropdown" id="components-section">
|
|
<button class="dropdown-toggle">Components <span class="dropdown-arrow">▾</span></button>
|
|
<div class="dropdown-menu" id="components-menu">
|
|
<button class="create-component-btn" id="create-component-btn" title="Create custom component">✚ Create</button>
|
|
<div id="saved-components"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<button class="action-btn sim-btn" id="sim-btn">Waveform</button>
|
|
<div class="toolbar-right">
|
|
<button class="action-btn export-btn" id="export-btn" title="Export circuit">↓ Export</button>
|
|
<button class="action-btn import-btn" id="import-btn" title="Import circuit">↑ Import</button>
|
|
<button class="action-btn help-btn" id="help-btn">? Help</button>
|
|
<button class="action-btn" id="clear-btn">Clear All</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Hidden file input for import -->
|
|
<input type="file" id="import-file" accept=".json" style="display:none">
|
|
|
|
<!-- Component Editor Overlay -->
|
|
<div id="component-editor-overlay" style="display:none;">
|
|
<div id="component-editor-bar">
|
|
<span id="component-editor-title">Editing Component: </span>
|
|
<button id="component-editor-save">Save</button>
|
|
<button id="component-editor-cancel">Cancel</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mode toggle will be inserted here by puzzleUI.js -->
|
|
|
|
<canvas id="canvas"></canvas>
|
|
|
|
<div id="waveform-panel">
|
|
<div id="wave-resize"></div>
|
|
<div id="wave-toolbar">
|
|
<span class="wave-title">Waveform Viewer</span>
|
|
<button class="wave-btn record active" id="wave-record">Record</button>
|
|
<button class="wave-btn" id="wave-clear">Clear</button>
|
|
<button class="wave-btn" id="wave-step">Step</button>
|
|
<button class="wave-btn" id="wave-zoom-out">Zoom -</button>
|
|
<span class="wave-info" id="wave-zoom-label" style="margin-left:0;min-width:35px;text-align:center">20px</span>
|
|
<button class="wave-btn" id="wave-zoom-in">Zoom +</button>
|
|
<div class="separator"></div>
|
|
<button class="wave-btn" id="sim-run-btn">Run</button>
|
|
<button class="wave-btn" id="sim-slower">-</button>
|
|
<span class="wave-info" id="sim-speed-label" style="margin-left:0">500ms</span>
|
|
<button class="wave-btn" id="sim-faster">+</button>
|
|
<span class="wave-info" id="wave-info">T=0 | 0 samples</span>
|
|
</div>
|
|
<div id="wave-container">
|
|
<div id="wave-labels"></div>
|
|
<canvas id="wave-canvas"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="help-modal">
|
|
<div id="help-content">
|
|
<h2>Logic Gate Simulator</h2>
|
|
<ul>
|
|
<li>Click a gate button, then click on the canvas to place it</li>
|
|
<li>Drag gates to move them around</li>
|
|
<li>Click on an <strong>output port</strong> (right), then an <strong>input port</strong> (left) to connect</li>
|
|
<li>Click an <kbd>INPUT</kbd> gate to toggle its value (0/1)</li>
|
|
<li><kbd>Delete</kbd> while hovering a gate to remove it</li>
|
|
<li>Right-click a port to delete its connections</li>
|
|
<li><kbd>Escape</kbd> to cancel placing/connecting</li>
|
|
</ul>
|
|
<h3>Clock & Simulation</h3>
|
|
<ul>
|
|
<li>Place a <kbd>CLOCK</kbd> gate — it auto-toggles 0/1 during simulation</li>
|
|
<li>Click <kbd>Run</kbd> in the waveform bar to start the clock</li>
|
|
<li>Use <kbd>-</kbd> / <kbd>+</kbd> to adjust speed (50ms-2000ms per tick)</li>
|
|
<li>Connect CLOCK to gates to see automatic signal propagation</li>
|
|
</ul>
|
|
<h3>Waveform Viewer (GTKWave-style)</h3>
|
|
<ul>
|
|
<li>Click <kbd>Waveform</kbd> to toggle the signal viewer</li>
|
|
<li><kbd>Record</kbd> captures signal changes automatically</li>
|
|
<li><kbd>Step</kbd> manually advances one time step</li>
|
|
<li>Toggle inputs to see signals change in real-time</li>
|
|
<li>Drag the top border to resize the panel</li>
|
|
<li>All CLOCK, INPUT, OUTPUT, and gate signals are tracked</li>
|
|
</ul>
|
|
<p style="margin-top: 12px; color: #666;">Built at MontLab</p>
|
|
<button id="help-close">Got it</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module" src="js/app.js"></script>
|
|
</body>
|
|
</html>
|