|
3 | 3 | <head> |
4 | 4 | <meta charset="UTF-8"> |
5 | 5 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
6 | | - <title>Editor — C++ Mode for Processing</title> |
| 6 | + <title>Editor - C++ Mode for Processing</title> |
7 | 7 | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css"> |
8 | 8 | <link rel="stylesheet" href="../assets/cppmode-theme.css"> |
9 | 9 | <style> |
10 | 10 | * { margin: 0; padding: 0; box-sizing: border-box; } |
11 | 11 | body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #fff; color: #111; height: 100vh; display: flex; flex-direction: column; overflow: hidden; } |
12 | | - #site-nav { border-bottom: 1px solid #e0e0e0; padding: 0 2rem; display: flex; align-items: center; justify-content: space-between; height: 52px; background: #fff; flex-shrink: 0; } |
13 | | - #site-nav a { color: #111; text-decoration: none; font-size: 14px; } |
14 | | - #site-nav .logo { font-weight: 600; font-size: 15px; } |
| 12 | + |
| 13 | + /* Override nav.js nav to not be sticky in the editor - it already has fixed height */ |
| 14 | + #site-nav { flex-shrink: 0; position: static !important; } |
| 15 | + |
| 16 | + /* Hide the sidebar - editor uses full width */ |
| 17 | + #site-sidebar { display: none; } |
| 18 | + |
15 | 19 | .editor-layout { display: flex; flex: 1; overflow: hidden; } |
| 20 | + |
16 | 21 | .editor-pane { display: flex; flex-direction: column; width: 50%; border-right: 1px solid #e0e0e0; } |
17 | 22 | .preview-pane { display: flex; flex-direction: column; width: 50%; } |
18 | | - .pane-toolbar { display: flex; align-items: center; gap: 0.75rem; padding: 0.5rem 0.75rem; background: #f5f5f5; border-bottom: 1px solid #e0e0e0; flex-shrink: 0; } |
19 | | - .pane-label { font-size: 12px; color: #888; flex: 1; font-family: monospace; } |
| 23 | + |
| 24 | + .pane-toolbar { |
| 25 | + display: flex; |
| 26 | + align-items: center; |
| 27 | + gap: 0.75rem; |
| 28 | + padding: 0.5rem 0.75rem; |
| 29 | + background: #f7f7f7; |
| 30 | + border-bottom: 1px solid #e0e0e0; |
| 31 | + flex-shrink: 0; |
| 32 | + } |
| 33 | + .pane-label { font-size: 12px; color: #888; flex: 1; font-family: "SF Mono", "Fira Code", monospace; } |
| 34 | + |
20 | 35 | #status { font-size: 12px; color: #888; } |
21 | 36 | #status.compiling { color: #c07000; } |
22 | 37 | #status.error { color: #c00; } |
23 | | - #status.ok { color: #080; } |
24 | | - .btn-run { background: #e8b400; color: #111; border: none; padding: 0.4rem 1.1rem; border-radius: 5px; font-size: 13px; font-weight: 700; cursor: pointer; } |
25 | | - .btn-run:hover { background: #f5c400; } |
26 | | - .btn-run:disabled { background: #ccc; color: #888; cursor: not-allowed; } |
27 | | - .btn-stop { background: #eee; color: #555; border: 1px solid #ccc; padding: 0.4rem 0.9rem; border-radius: 5px; font-size: 12px; cursor: pointer; } |
28 | | - .btn-stop:hover { background: #ddd; } |
29 | | - .CodeMirror { flex: 1; height: 100%; font-size: 13px; line-height: 1.55; } |
| 38 | + #status.ok { color: #3a3; } |
| 39 | + |
| 40 | + .btn-run { |
| 41 | + background: #e8b400; |
| 42 | + color: #111; |
| 43 | + border: none; |
| 44 | + padding: 0.4rem 1.1rem; |
| 45 | + border-radius: 6px; |
| 46 | + font-size: 13px; |
| 47 | + font-weight: 700; |
| 48 | + cursor: pointer; |
| 49 | + } |
| 50 | + .btn-run:hover { background: #d4a300; } |
| 51 | + .btn-run:disabled { background: #e0e0e0; color: #aaa; cursor: not-allowed; } |
| 52 | + |
| 53 | + .btn-stop { |
| 54 | + background: #f0f0f0; |
| 55 | + color: #555; |
| 56 | + border: 1px solid #e0e0e0; |
| 57 | + padding: 0.4rem 0.9rem; |
| 58 | + border-radius: 6px; |
| 59 | + font-size: 12px; |
| 60 | + cursor: pointer; |
| 61 | + } |
| 62 | + .btn-stop:hover { background: #e6e6e6; } |
| 63 | + |
| 64 | + .CodeMirror { flex: 1; height: 100%; font-size: 13px; line-height: 1.6; } |
30 | 65 | .CodeMirror-scroll { height: 100% !important; } |
31 | | - #preview-area { flex: 1; background: #e8e8e8; display: flex; align-items: center; justify-content: center; overflow: hidden; } |
| 66 | + |
| 67 | + #preview-area { |
| 68 | + flex: 1; |
| 69 | + background: #111; |
| 70 | + display: flex; |
| 71 | + align-items: center; |
| 72 | + justify-content: center; |
| 73 | + overflow: hidden; |
| 74 | + } |
32 | 75 | #preview-area canvas { display: block !important; } |
33 | | - #preview-placeholder { color: #aaa; font-size: 13px; text-align: center; line-height: 2; } |
34 | | - #preview-placeholder kbd { background: #fff; border: 1px solid #ccc; padding: 2px 6px; border-radius: 3px; font-size: 12px; color: #666; } |
35 | | - #error-panel { display: none; background: #fff5f5; border-top: 1px solid #ffcccc; padding: 0.6rem 1rem; font-family: monospace; font-size: 11.5px; color: #c00; max-height: 130px; overflow-y: auto; white-space: pre; flex-shrink: 0; } |
| 76 | + |
| 77 | + #preview-placeholder { color: #555; font-size: 13px; text-align: center; line-height: 2.2; } |
| 78 | + #preview-placeholder kbd { |
| 79 | + background: #222; |
| 80 | + border: 1px solid #444; |
| 81 | + padding: 2px 6px; |
| 82 | + border-radius: 3px; |
| 83 | + font-size: 12px; |
| 84 | + color: #bbb; |
| 85 | + font-family: "SF Mono", "Fira Code", monospace; |
| 86 | + } |
| 87 | + |
| 88 | + #error-panel { |
| 89 | + display: none; |
| 90 | + background: #fff5f5; |
| 91 | + border-top: 1px solid #fcc; |
| 92 | + padding: 0.6rem 1rem; |
| 93 | + font-family: "SF Mono", "Fira Code", monospace; |
| 94 | + font-size: 11.5px; |
| 95 | + color: #c00; |
| 96 | + max-height: 130px; |
| 97 | + overflow-y: auto; |
| 98 | + white-space: pre; |
| 99 | + flex-shrink: 0; |
| 100 | + } |
36 | 101 | </style> |
37 | 102 | </head> |
38 | 103 | <body> |
39 | | - |
40 | | -<nav id="site-nav"> |
41 | | - <a class="logo" href="/">C++ Mode for Processing</a> |
42 | | - <a href="/reference" style="color:#888;font-size:13px;">Reference</a> |
43 | | -</nav> |
| 104 | +<nav id="site-nav"></nav> |
44 | 105 |
|
45 | 106 | <div class="editor-layout"> |
46 | 107 | <div class="editor-pane"> |
47 | 108 | <div class="pane-toolbar"> |
48 | | - <span class="pane-label">sketch.cpp</span> |
| 109 | + <span class="pane-label">sketch.pde</span> |
49 | 110 | <span id="status"></span> |
| 111 | + <button class="btn-stop" onclick="stopSketch()">Stop</button> |
50 | 112 | <button class="btn-run" id="btn-run" onclick="runSketch()">▶ Run</button> |
51 | 113 | </div> |
52 | | - <textarea id="code-editor"></textarea> |
| 114 | + <textarea id="code"></textarea> |
53 | 115 | <div id="error-panel"></div> |
54 | 116 | </div> |
| 117 | + |
55 | 118 | <div class="preview-pane"> |
56 | 119 | <div class="pane-toolbar"> |
57 | | - <span class="pane-label">Output</span> |
58 | | - <button class="btn-stop" onclick="stopSketch()">■ Stop</button> |
| 120 | + <span class="pane-label">preview</span> |
59 | 121 | </div> |
60 | 122 | <div id="preview-area"> |
61 | | - <div id="preview-placeholder">Press <kbd>Run</kbd> or <kbd>Ctrl+Enter</kbd></div> |
| 123 | + <div id="preview-placeholder"> |
| 124 | + Press <kbd>Ctrl+Enter</kbd> to run your sketch |
| 125 | + </div> |
62 | 126 | </div> |
63 | 127 | </div> |
64 | 128 | </div> |
65 | 129 |
|
66 | 130 | <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script> |
67 | 131 | <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/clike/clike.min.js"></script> |
68 | 132 | <script src="../assets/cppmode-keywords.js"></script> |
| 133 | +<script src="../assets/cm-cppmode.js"></script> |
69 | 134 | <script src="../assets/cppmode.js"></script> |
| 135 | +<script src="../assets/nav.js"></script> |
70 | 136 | <script> |
71 | 137 | const API = 'https://bench-volumes-pontiac-riders.trycloudflare.com'; |
72 | 138 |
|
73 | | -const DEFAULT = `float angle = 0; |
74 | | -
|
75 | | -void setup() { |
76 | | - size(500, 400, P3D); |
77 | | -} |
78 | | -
|
79 | | -void draw() { |
80 | | - background(20); |
81 | | - lights(); |
82 | | - translate(width/2, height/2); |
83 | | - rotateX(angle * 0.7f); |
84 | | - rotateY(angle); |
85 | | - fill(232, 180, 0); |
86 | | - box(130); |
87 | | - angle += 0.02f; |
88 | | -}`; |
89 | | - |
90 | | -const editor = CodeMirror.fromTextArea(document.getElementById('code-editor'), { |
91 | | - mode: 'text/x-cppmode', |
| 139 | +const editor = CodeMirror.fromTextArea(document.getElementById('code'), { |
| 140 | + mode: 'cppmode', |
92 | 141 | theme: 'cppmode', |
93 | 142 | lineNumbers: true, |
94 | 143 | indentUnit: 2, |
95 | 144 | tabSize: 2, |
96 | 145 | indentWithTabs: false, |
97 | 146 | autofocus: true, |
| 147 | + matchBrackets: true, |
| 148 | + autoCloseBrackets: true, |
| 149 | + lineWrapping: false, |
| 150 | + extraKeys: { |
| 151 | + 'Ctrl-Enter': runSketch, |
| 152 | + 'Cmd-Enter': runSketch, |
| 153 | + 'Tab': cm => cm.execCommand('indentMore'), |
| 154 | + 'Shift-Tab': cm => cm.execCommand('indentLess'), |
| 155 | + }, |
98 | 156 | }); |
99 | | -editor.setValue(DEFAULT); |
100 | | -editor.setSize('100%', '100%'); |
101 | | - |
102 | | -// Patch Event.prototype.preventDefault so Emscripten GLFW keydown handlers |
103 | | -// can't prevent default when the CodeMirror textarea is focused. |
104 | | -const _origPreventDefault = Event.prototype.preventDefault; |
105 | | -Event.prototype.preventDefault = function() { |
106 | | - if (this.type === 'keydown' || this.type === 'keyup' || this.type === 'keypress') { |
107 | | - const ta = document.querySelector('.CodeMirror textarea'); |
108 | | - if (ta && document.activeElement === ta) return; |
109 | | - } |
110 | | - return _origPreventDefault.call(this); |
111 | | -}; |
| 157 | + |
| 158 | +editor.setValue(`void setup() { |
| 159 | + size(640, 360); |
| 160 | +} |
| 161 | +
|
| 162 | +void draw() { |
| 163 | + background(20); |
| 164 | + fill(255, 140, 0); |
| 165 | + circle(mouseX, mouseY, 40); |
| 166 | +}`); |
112 | 167 |
|
113 | 168 | function setStatus(msg, cls) { |
114 | 169 | const el = document.getElementById('status'); |
|
118 | 173 |
|
119 | 174 | function stopSketch() { |
120 | 175 | const area = document.getElementById('preview-area'); |
121 | | - area.innerHTML = '<div id="preview-placeholder">Press <kbd>Run</kbd> or <kbd>Ctrl+Enter</kbd></div>'; |
| 176 | + const canvas = area.querySelector('canvas'); |
| 177 | + if (canvas) canvas.remove(); |
| 178 | + const placeholder = document.getElementById('preview-placeholder'); |
| 179 | + if (placeholder) placeholder.style.display = ''; |
122 | 180 | window.Module = undefined; |
123 | 181 | setStatus(''); |
124 | 182 | editor.focus(); |
|
161 | 219 | stopSketch(); |
162 | 220 |
|
163 | 221 | const area = document.getElementById('preview-area'); |
| 222 | + const placeholder = document.getElementById('preview-placeholder'); |
| 223 | + if (placeholder) placeholder.style.display = 'none'; |
| 224 | + |
164 | 225 | const canvas = document.createElement('canvas'); |
165 | 226 | canvas.id = 'canvas'; |
166 | 227 | canvas.setAttribute('tabindex', '-1'); |
|
176 | 237 | print: t => console.log('[sketch]', t), |
177 | 238 | printErr: t => console.warn('[sketch]', t), |
178 | 239 | }; |
| 240 | + |
179 | 241 | if (dataBytes) { |
180 | 242 | window.Module.getPreloadedPackage = function(name, size) { return dataBytes.buffer; }; |
181 | 243 | } |
|
0 commit comments