- lib-icons/ -> libraries/icons/ (C library icon SVGs stay with their libs) - libraries/highlight/ -> vendor/highlight/ (not committed, downloaded) - lib/mathjax/ -> vendor/mathjax/ (not committed, downloaded) - vendor/download.sh fetches highlight.js v11.10.0 and MathJax v3.2.2 - index.html paths updated to vendor/ - .gitignore ignores vendor/* (except download.sh) - Removes ~1.2MB of binary font files from git tracking
536 lines
22 KiB
HTML
536 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Visual Programming Tool</title>
|
|
<link href="style.css" rel="stylesheet">
|
|
<link href="vendor/highlight/default.min.css" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ─── Flowchart node templates ─── -->
|
|
|
|
<!-- Program entry point (top of main()). -->
|
|
<template id="wc-start">
|
|
<wc-start>
|
|
START
|
|
<button class="hook" data-direction="out" data-exit="down" data-link-type="logic"></button>
|
|
</wc-start>
|
|
</template>
|
|
|
|
<!-- Program exit block with autocomplete errno input and description.
|
|
At least one end block must return 0 throughout the workspace. -->
|
|
<template id="wc-end">
|
|
<wc-end>
|
|
<button class="hook" data-direction="in" data-exit="up" data-link-type="logic"></button>
|
|
<div class="end-header">END</div>
|
|
<div class="end-exit-row">
|
|
<span class="end-exit-label">exit:</span>
|
|
<div class="end-exit-autocomplete">
|
|
<input class="end-errno-input" type="text" placeholder="0 success" autocomplete="off" spellcheck="false">
|
|
<div class="end-errno-suggestions"></div>
|
|
</div>
|
|
</div>
|
|
<div class="end-desc-row">
|
|
<span class="end-desc-text">success</span>
|
|
</div>
|
|
</wc-end>
|
|
</template>
|
|
|
|
|
|
|
|
<!-- Decision/branch block with condition, yes, no, test, and in ports. -->
|
|
<template id="wc-decision">
|
|
<wc-decision>
|
|
<p>BRANCH</p>
|
|
<div class="decision-row">
|
|
<span class="decision-label">if</span>
|
|
<button class="hook decision-data-in" data-direction="in" data-link-type="data" data-type="boolean" data-exit="left">bool</button>
|
|
</div>
|
|
<button class="hook" id="hook-fore" data-direction="in" data-exit="left" data-link-type="logic">in</button>
|
|
<div class="hook-row">
|
|
<button class="hook" id="hook-out1" data-direction="out" data-exit="down" data-link-type="logic">yes</button>
|
|
<button class="hook" id="hook-out0" data-direction="out" data-exit="down" data-link-type="logic">no</button>
|
|
</div>
|
|
</wc-decision>
|
|
</template>
|
|
|
|
<!-- ─── Measurement node templates ─── -->
|
|
|
|
<!-- Quantity definition with 7 SI dimensions and default unit. -->
|
|
<template id="wc-quantity">
|
|
<wc-quantity>
|
|
<div class="quantity-header">
|
|
<span class="quantity-label">QUANTITY</span>
|
|
<input class="quantity-name" placeholder="quantity name" value="quantity">
|
|
</div>
|
|
<div class="dims">
|
|
<label>L<input class="dim-0" type="number" value="0"></label>
|
|
<label>M<input class="dim-1" type="number" value="0"></label>
|
|
<label>T<input class="dim-2" type="number" value="0"></label>
|
|
<label>I<input class="dim-3" type="number" value="0"></label>
|
|
<label>Θ<input class="dim-4" type="number" value="0"></label>
|
|
<label>N<input class="dim-5" type="number" value="0"></label>
|
|
<label>J<input class="dim-6" type="number" value="0"></label>
|
|
</div>
|
|
<div class="range">
|
|
<input class="quantity-min" placeholder="min" value="">
|
|
<input class="quantity-max" placeholder="max" value="">
|
|
</div>
|
|
<div class="quantity-footer">
|
|
<select class="quantity-default-unit">
|
|
<option value="">(none)</option>
|
|
</select>
|
|
</div>
|
|
</wc-quantity>
|
|
</template>
|
|
|
|
<!-- Unit of measurement with type, suffix, and SI factor. -->
|
|
<template id="wc-unit">
|
|
<wc-unit>
|
|
<div class="unit-header">
|
|
<span class="unit-label">UNIT</span>
|
|
<input class="unit-fullname" placeholder="full name" value="unit">
|
|
</div>
|
|
<div class="unit-body">
|
|
<label>type <select class="unit-type"><option value="">(select quantity)</option></select></label>
|
|
<label>suffix <input class="unit-suffix" placeholder="suffix" value=""></label>
|
|
<label>SI <input class="unit-si" placeholder="1" value="1"></label>
|
|
<span class="unit-resolved"></span>
|
|
</div>
|
|
</wc-unit>
|
|
</template>
|
|
|
|
<!-- Boolean variable block: fixed boolean type, no unit/SI. -->
|
|
<template id="wc-boolean">
|
|
<wc-boolean>
|
|
<div class="datum-row">
|
|
<input class="var-name" placeholder="name" value="flag">
|
|
=
|
|
<select class="var-value">
|
|
<option value="false">false</option>
|
|
<option value="true">true</option>
|
|
</select>
|
|
</div>
|
|
<span class="var-cname">flag</span>
|
|
<input class="var-comment" placeholder="// comment">
|
|
</wc-boolean>
|
|
</template>
|
|
|
|
<!-- Scalar variable block: typed quantity with unit and SI conversion. -->
|
|
<template id="wc-scalar">
|
|
<wc-scalar>
|
|
<div class="datum-row">
|
|
<input class="var-name" placeholder="name" value="x">
|
|
=
|
|
<input class="var-value" placeholder="5 km" value="0">
|
|
<select class="var-unit">
|
|
<option value="">(unit)</option>
|
|
</select>
|
|
</div>
|
|
<div class="datum-row">
|
|
<select class="var-type">
|
|
<option value="">(no type)</option>
|
|
</select>
|
|
<span class="var-si"></span>
|
|
</div>
|
|
<span class="var-cname">x</span>
|
|
<input class="var-comment" placeholder="// comment">
|
|
</wc-scalar>
|
|
</template>
|
|
|
|
<!-- Vector variable block: N-dimensional typed vector with unit and SI conversion. -->
|
|
<template id="wc-vector">
|
|
<wc-vector>
|
|
<div class="datum-row">
|
|
<input class="var-name" placeholder="name" value="v">
|
|
[<input class="var-dim" value="3" size="3">]
|
|
=
|
|
<input class="var-value" placeholder="0 0 0" value="0">
|
|
<select class="var-unit">
|
|
<option value="">(unit)</option>
|
|
</select>
|
|
</div>
|
|
<div class="datum-row">
|
|
<select class="var-type">
|
|
<option value="">(no type)</option>
|
|
</select>
|
|
<span class="var-si"></span>
|
|
</div>
|
|
<span class="var-cname">v</span>
|
|
<input class="var-comment" placeholder="// comment">
|
|
</wc-vector>
|
|
</template>
|
|
|
|
<!-- String variable block: C string (char* + length struct). -->
|
|
<template id="wc-string">
|
|
<wc-string>
|
|
<div class="datum-row">
|
|
<input class="var-name" placeholder="name" value="s">
|
|
=
|
|
<input class="var-value" placeholder="string value" value="">
|
|
</div>
|
|
<span class="var-cname">s</span>
|
|
<input class="var-comment" placeholder="// comment">
|
|
</wc-string>
|
|
</template>
|
|
|
|
<!-- Array variable block: typed C array with tabular element editor (lives in Data tab). -->
|
|
<template id="wc-array">
|
|
<wc-array>
|
|
<div class="array-row">
|
|
<input class="var-name" placeholder="name" value="arr">
|
|
<select class="array-type">
|
|
<option value="float">float</option>
|
|
<option value="double">double</option>
|
|
<option value="int">int</option>
|
|
<option value="unsigned int">unsigned int</option>
|
|
<option value="char">char</option>
|
|
</select>
|
|
<span class="array-bracket">[]</span>
|
|
<span class="array-count">0 elements</span>
|
|
<span class="array-vec-row">
|
|
× <input class="array-vec-dim" value="1" size="2" title="vector dimension (1 = scalar)">
|
|
</span>
|
|
</div>
|
|
<span class="var-cname">arr</span>
|
|
<input class="var-comment" placeholder="// comment">
|
|
<div class="array-elements">
|
|
<!-- Element rows rendered dynamically by WCArray._renderElements() -->
|
|
</div>
|
|
</wc-array>
|
|
</template>
|
|
|
|
<!-- Variable reference block: read-only instance of a Data-tab variable with data output hook. -->
|
|
<template id="wc-varref">
|
|
<wc-varref>
|
|
<span class="varref-label">VAR</span>
|
|
<select class="varref-select">
|
|
<option value="">(select variable)</option>
|
|
</select>
|
|
<button class="hook hook-out" data-direction="out" data-link-type="data" data-type="scalar" data-exit="down">out</button>
|
|
</wc-varref>
|
|
</template>
|
|
|
|
<!-- Expression block: mathematical expression with data hooks. -->
|
|
<template id="wc-expression">
|
|
<wc-expression>
|
|
<div class="expr-varhooks"></div>
|
|
<div>EXPR</div>
|
|
<div class="expr-row">
|
|
<input class="expr-name" placeholder="result" value="res">
|
|
=
|
|
</div>
|
|
<div class="expr-formula-container">
|
|
<textarea class="expr-latex" placeholder="a + b" rows="2" spellcheck="false"></textarea>
|
|
<div class="expr-rendered"></div>
|
|
</div>
|
|
<button class="hook hook-out" id="hook-out" data-direction="out" data-link-type="data" data-type="scalar" data-exit="down">out</button>
|
|
</wc-expression>
|
|
</template>
|
|
|
|
<!-- Assignment block: assigns a value to a variable. -->
|
|
<template id="wc-assign">
|
|
<wc-assign>
|
|
<div class="assign-header">ASSIGN</div>
|
|
<div class="assign-row">
|
|
<select class="assign-target">
|
|
<option value="">(select variable)</option>
|
|
</select>
|
|
<span class="assign-eq">=</span>
|
|
<input class="assign-value" placeholder="value">
|
|
<button class="hook" data-direction="in" data-link-type="data" data-type="scalar" data-exit="left">val</button>
|
|
</div>
|
|
<div class="assign-index-area" style="display:none">
|
|
<span class="assign-bracket">[</span>
|
|
<input class="assign-index" placeholder="0" value="0">
|
|
<button class="hook" data-direction="in" data-link-type="data" data-type="scalar" data-exit="left">idx</button>
|
|
<span class="assign-bracket">]</span>
|
|
</div>
|
|
<button class="hook" id="hook-fore" data-direction="in" data-exit="left" data-link-type="logic"></button>
|
|
<div class="hook-row">
|
|
<button class="hook" id="hook-next" data-direction="out" data-exit="down" data-link-type="logic"></button>
|
|
</div>
|
|
</wc-assign>
|
|
</template>
|
|
|
|
<!-- ─── Procedure templates ─── -->
|
|
|
|
<!-- Procedure definition block (lives in the Procedures tab). -->
|
|
<template id="wc-procedure">
|
|
<wc-procedure>
|
|
<div class="proc-header">
|
|
<input class="proc-natural-name" placeholder="Procedure name" value="My Procedure">
|
|
<span class="proc-tech-name">proc</span>
|
|
</div>
|
|
<div class="proc-params">
|
|
<div class="proc-params-col">
|
|
<span class="proc-params-heading">inputs</span>
|
|
<div class="proc-inputs"></div>
|
|
<button class="proc-add-input">+ input</button>
|
|
</div>
|
|
<span class="proc-arrow">→</span>
|
|
<div class="proc-params-col">
|
|
<span class="proc-params-heading">outputs</span>
|
|
<div class="proc-outputs"></div>
|
|
<button class="proc-add-output">+ output</button>
|
|
</div>
|
|
</div>
|
|
<div class="proc-return-row">
|
|
<span class="proc-return-label">return:</span>
|
|
<select class="proc-return-style">
|
|
<option value="pointer">by pointer</option>
|
|
<option value="value">by value</option>
|
|
<option value="error">error int</option>
|
|
</select>
|
|
</div>
|
|
<button class="hook"></button>
|
|
<details class="proc-description">
|
|
<summary class="proc-desc-summary">Description</summary>
|
|
<div class="proc-desc-body"></div>
|
|
</details>
|
|
</wc-procedure>
|
|
</template>
|
|
|
|
<!-- Procedure call block (lives in the Algorithm tab). -->
|
|
<template id="wc-proccall">
|
|
<wc-proccall>
|
|
<div class="proccall-header">
|
|
<img class="proccall-icon" src="" alt="">
|
|
<span class="proccall-label">CALL</span>
|
|
<span class="proccall-nat-name" title="(select procedure)"></span>
|
|
<span class="proccall-tech-name"></span>
|
|
<button class="proccall-change-btn" title="change procedure">change</button>
|
|
</div>
|
|
<div class="proccall-name-row">
|
|
<input class="proccall-name" placeholder="result var" value="">
|
|
</div>
|
|
<div class="proccall-container">
|
|
<div class="proccall-inputs"></div>
|
|
<div class="proccall-outputs"></div>
|
|
</div>
|
|
<div class="proccall-fmtargs" style="display:none">
|
|
<div class="proccall-fmtargs-list"></div>
|
|
<button class="proccall-add-fmtarg" style="display:none">+ add arg</button>
|
|
</div>
|
|
<button class="hook hook-in" data-direction="in" data-link-type="logic" data-exit="up"></button>
|
|
<div class="hook-row">
|
|
<button class="hook hook-out" data-direction="out" data-link-type="logic" data-exit="down"></button>
|
|
<button class="hook proccall-error-hook" data-direction="out" data-link-type="logic" data-exit="down" title="error path">!</button>
|
|
</div>
|
|
</wc-proccall>
|
|
</template>
|
|
|
|
<!-- ─── Page layout ─── -->
|
|
|
|
<h1>Visual Programming Framework</h1>
|
|
|
|
<!-- Tab bar: Algorithm, Data, and Measurements tabs. -->
|
|
<div class="tab-bar">
|
|
<button class="tab-btn active" data-tab="algorithm">
|
|
<img class="tab-icon" src="icons/git-branch.svg" width="16" height="16" alt="">
|
|
Algorithm
|
|
</button>
|
|
<button class="tab-btn" data-tab="data">
|
|
<img class="tab-icon" src="icons/database.svg" width="16" height="16" alt="">
|
|
Data
|
|
</button>
|
|
<button class="tab-btn" data-tab="measurements">
|
|
<img class="tab-icon" src="icons/ruler.svg" width="16" height="16" alt="">
|
|
Measurements
|
|
</button>
|
|
<button class="tab-btn" data-tab="procedures">
|
|
<img class="tab-icon" src="icons/file-text.svg" width="16" height="16" alt="">
|
|
Procedures
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Tab content area that fills remaining vertical space. -->
|
|
<div class="tab-body">
|
|
<!-- Algorithm pane: flowchart toolbar + drawing surface with SVG connections. -->
|
|
<div class="tab-pane active" id="pane-algorithm" data-tab="algorithm">
|
|
<div class="pane-toolbar">
|
|
<button data-action="decision" title="new decision">
|
|
<img src="icons/diamond.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<button data-action="expression" title="new expression">
|
|
<img src="icons/function-square.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<button data-action="varref" title="new variable">
|
|
<img src="icons/variable.svg" width="18" height="18" alt="">
|
|
</button>
|
|
|
|
<button data-action="proccall" title="new procedure call">
|
|
<img src="icons/book-open.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<button data-action="assign" title="new assignment">
|
|
<img src="icons/arrow-right-circle.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<button data-action="end" title="new end block">
|
|
<img src="icons/stop-circle.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<span class="toolbar-sep"></span>
|
|
<button data-action="add-section" title="draw a logic section">
|
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="2"><line x1="9" y1="3" x2="9" y2="15"/><line x1="3" y1="9" x2="15" y2="9"/></svg>
|
|
</button>
|
|
</div>
|
|
<div id="draw-area">
|
|
<svg id="connections" xmlns="http://www.w3.org/2000/svg">
|
|
<defs></defs>
|
|
</svg>
|
|
<wc-program id="main-program">
|
|
</wc-program>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Data pane: toolbar for creating variables/quantities + variable area. -->
|
|
<div class="tab-pane" id="pane-data" data-tab="data">
|
|
<div class="pane-toolbar">
|
|
<div class="btn-group">
|
|
<button data-action="variable" title="new variable">
|
|
<img src="icons/variable.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<div class="submenu" data-action="variable-submenu">
|
|
<button data-action="boolean">boolean</button>
|
|
<button data-action="scalar">scalar</button>
|
|
<button data-action="string">string</button>
|
|
<button data-action="array">array</button>
|
|
<button data-action="vector">vector</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="list-header">Name Value Type/Unit C Name Comment</div>
|
|
<div id="variable-area"></div>
|
|
</div>
|
|
|
|
<!-- Measurements pane: toolbar for creating units + node area. -->
|
|
<div class="tab-pane" id="pane-measurements" data-tab="measurements">
|
|
<div class="pane-toolbar">
|
|
<button data-action="quantity" title="new quantity">
|
|
<img src="icons/sliders.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<button data-action="unit" title="new unit">
|
|
<img src="icons/grid.svg" width="18" height="18" alt="">
|
|
</button>
|
|
</div>
|
|
<div class="list-header">Quantities — Name L M T I Θ N J Min Max Default Unit</div>
|
|
<div id="data-area"></div>
|
|
</div>
|
|
|
|
<!-- Procedures pane: library sub-tabs + procedure definitions. -->
|
|
<div class="tab-pane" id="pane-procedures" data-tab="procedures">
|
|
<div class="pane-toolbar">
|
|
<button data-action="add-library" title="new library">
|
|
<img src="icons/folder-plus.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<div class="btn-group">
|
|
<button data-action="add-library-index" title="add library from index">
|
|
<img src="icons/book-open.svg" width="18" height="18" alt="">
|
|
</button>
|
|
<div class="submenu" data-action="library-index-submenu"></div>
|
|
</div>
|
|
<button data-action="add-procedure" title="new procedure">
|
|
<img src="icons/file-plus.svg" width="18" height="18" alt="">
|
|
</button>
|
|
</div>
|
|
<div class="lib-tab-bar"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bottom toolbar: code generation button and highlighted output. -->
|
|
<div class="global-toolbar">
|
|
<button data-action="generate">Generate code</button>
|
|
<button data-action="save">Save</button>
|
|
<button data-action="load">Load</button>
|
|
<button data-action="new">New</button>
|
|
<button data-action="copy-code">Copy</button>
|
|
<button data-action="run-tests">Tests</button>
|
|
<div class="code-output" id="c-code-container">
|
|
<pre><code id="c-code"></code></pre>
|
|
</div>
|
|
</div>
|
|
<div id="error-overlay" class="error-overlay">
|
|
<div class="error-box">
|
|
<span class="error-close">×</span>
|
|
<div class="error-ack">-ACK!</div>
|
|
<div class="error-msg"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Procedure browser modal: tree-based procedure picker. -->
|
|
<div id="proc-browser-overlay" class="proc-browser-overlay">
|
|
<div class="proc-browser-box">
|
|
<div class="proc-browser-header">
|
|
Select Procedure
|
|
<input class="proc-browser-search" type="text" placeholder="Search procedures..." spellcheck="false">
|
|
</div>
|
|
<div class="proc-browser-tree"></div>
|
|
<div class="proc-browser-empty"></div>
|
|
<div class="proc-browser-footer">
|
|
<button class="proc-browser-cancel">Cancel</button>
|
|
<button class="proc-browser-select">Select</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New Project modal -->
|
|
<div id="new-project-overlay" class="modal-overlay" style="display:none">
|
|
<div class="modal">
|
|
<h2>New Project</h2>
|
|
<div class="modal-field">
|
|
<label for="project-name">Project Name</label>
|
|
<input type="text" id="project-name" class="modal-input" placeholder="My Project" value="Untitled">
|
|
</div>
|
|
<div class="modal-field">
|
|
<label>Template</label>
|
|
<div class="template-list" id="template-list">
|
|
<div class="template-card selected" data-template="console">
|
|
<span class="template-icon">■</span>
|
|
<span class="template-name">Console Program</span>
|
|
<span class="template-desc">Basic C program with stdio</span>
|
|
</div>
|
|
<div class="template-card" data-template="sdl3-triangle">
|
|
<span class="template-icon">△</span>
|
|
<span class="template-name">SDL3 Hello Triangle</span>
|
|
<span class="template-desc">SDL3 + OpenGL colored triangle</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-actions">
|
|
<button class="modal-btn modal-cancel">Cancel</button>
|
|
<button class="modal-btn modal-create">Create</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
window.MathJax = {
|
|
tex: { inlineMath: [['$', '$']], displayMath: [['$$', '$$']] },
|
|
options: { enableMenu: false, ignoreHtmlClass: 'expr-latex' },
|
|
startup: { elements: [] }
|
|
};
|
|
</script>
|
|
<script src="vendor/mathjax/tex-mml-chtml.js"></script>
|
|
<script src="dom.js"></script>
|
|
<script src="helpers.js"></script>
|
|
<script src="error.js"></script>
|
|
<script src="errno-data.js"></script>
|
|
<script src="draw.js"></script>
|
|
<script src="sections.js"></script>
|
|
<script src="wcblock.js"></script>
|
|
<script src="blocks-algo.js"></script>
|
|
<script src="blocks-data.js"></script>
|
|
<script src="blocks-proc.js"></script>
|
|
<script src="wcprogram.js"></script>
|
|
<script src="persist.js"></script>
|
|
<script src="lib-loader.js"></script>
|
|
<script src="vendor/highlight/highlight.min.js"></script>
|
|
<script src="vendor/highlight/c.min.js"></script>
|
|
<script src="proc-browser.js"></script>
|
|
<script src="templates.js"></script>
|
|
<script src="app.js"></script>
|
|
<script src="tests/app/test-runner.js"></script>
|
|
</body>
|
|
</html>
|