├── .gitignore
├── README.md
├── browserify_entries.js
├── components
├── canvas
│ ├── canvas.js
│ └── pd_canvas.html
├── dialogs
│ ├── .gitkeep
│ ├── dialog_canvas.html
│ ├── dialog_data.html
│ ├── dialog_external.html
│ ├── dialog_font.html
│ ├── dialog_gatom.html
│ ├── dialog_iemgui.html
│ ├── dialog_prefs.html
│ ├── dialog_search.html
│ └── dialog_text.html
└── menu
│ ├── menu.html
│ └── menu.js
├── css
├── c64.css
├── default.css
├── dejavu.css
├── extended.css
├── footgun.css
├── inverted.css
├── solarized.css
├── solarized_inverted.css
├── strongbad.css
├── subdued.css
├── vanilla.css
├── vanilla_inverted.css
└── webapp
│ └── webapp.css
├── dist
└── bundle.js
├── index.html
├── index.js
├── libs
├── bootstrap
│ ├── bootstrap.min.css
│ ├── bootstrap.min.js
│ └── popper.min.js
├── fa
│ └── fontawesome_1b8a796d74.js
├── jquery
│ ├── jquery-3.6.0.min.js
│ └── jquery-ui.js
└── webmidi
│ └── webmidi.min.js
├── main.data
├── main.html
├── main.js
├── main.wasm
├── package-lock.json
├── package.json
├── purr.png
├── screenshot.png
└── utils
├── actions.js
├── console_find.js
└── console_search.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # ignore all those dependencies
2 | node_modules
3 |
4 | # ignore weird mac files
5 | .DS_Store
6 |
7 | # ignore binary files
8 | main.data
9 | main.html
10 | main.js
11 | main.wasm
12 |
13 | # ignore copied files
14 | components/dialogs/dialog_*.html
15 | css/*.css
16 |
17 | # ignore build files
18 | dist/
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Purr Data
2 |
3 |
4 | ## Table of Contents
5 | - [Overview](#overview)
6 | - [Developers](#developers)
7 | - [Accomplished Milestones](#accomplished-milestones)
8 | - [Setup](#setup)
9 | - [Directory Structure](#directory-structure)
10 | - [Future Work](#future-work)
11 | - [Reporting Bugs](#reporting-bugs)
12 |
13 | ## Overview
14 | This document describes the work that was done under [Google Summer of Code 2020](https://summerofcode.withgoogle.com/) a.k.a. GSoC for organization Purr Data. The project idea was to make the native Purr Data run in a web browser by adding a WebAssembly target and HTML5 GUI framework.
15 |
16 | **Purr Data** a.k.a. **Pd-l2ork 2** is an improved version of Miller Puckette’s Pd.
17 |
18 | [Pd](https://puredata.info/) (Pure Data) is a graphical data-flow programming environment which is geared towards real-time interactive computer music and multimedia applications. It is a full-featured open-source alternative to its commercial sibling, Cycling74’s [Max](https://cycling74.com/products/max-features).
19 |
20 | [Purr Data](https://agraef.github.io/purr-data/) serves the same purpose, but offers a new and much improved graphical user interface and includes many 3rd party plug-ins. Like Pd, it runs on Linux, macOS and Windows, and is open-source throughout.
21 |
22 | The goal of this project is to make the graphical programming environment Purr Data run in a web browser so it can be more accessible to users.
23 |
24 | You can try the latest version from https://purrdata.glitch.me/
25 |
26 | ## Developers
27 | - The backend part of the software has been mainly done by Zack Lee (cuinjune@gmail.com)
28 | - The frontend part of the software has been mainly done by Hugo Carvalho (hugonvsc@gmail.com)
29 |
30 | ## Accomplished Milestones
31 | - Modified the native Purr Data and libpd codebase to make them compatible with [Emscripten](https://emscripten.org/). (Zack)
32 | - Modified and created Makefile to build for Emscripten and to generate WebAssembly(`.wasm`) binaries for external libraries. (Zack)
33 | - Cleaned the backend codebase and organized the file system so the project can be easily maintained. (Zack)
34 | - Modified the existing NW.js based source code to make them compatible with web browsers. (Hugo)
35 | - Reimplemented some elements(menu, canvas, style) specifically for the web browser. (Hugo)
36 | - Integrated the backend with the frontend. (Hugo, Zack)
37 | - Fixed some major bugs and errors in the frontend. (Hugo, Zack)
38 |
39 | ## Setup
40 |
41 | ### Installing Dependencies (Linux)
42 | ```
43 | sudo apt-get install git automake cmake fakeroot dpkg-dev libgconf-2-4
44 | ```
45 |
46 | ### Installing Node.js (macOS, Linux)
47 | ```
48 | curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
49 | ```
50 |
51 | ### Installing/Activating Emscripten (macOS, Linux)
52 | ```
53 | git clone https://github.com/emscripten-core/emsdk.git
54 | cd emsdk
55 | git pull
56 | ./emsdk install latest
57 | ./emsdk activate latest
58 | source ./emsdk_env.sh
59 | cd ..
60 | ```
61 |
62 | ### Building Purr Data for Emscripten (macOS, Linux)
63 | ```
64 | git clone https://git.purrdata.net/jwilkes/purr-data.git
65 | cd purr-data
66 | git checkout emscripten
67 | make emscripten
68 | ```
69 | ### Setting up the project (Windows)
70 | ```
71 | Method 1
72 |
73 | - git clone https://git.purrdata.net/jwilkes/purr-data.git
74 | - cd purr-data
75 | - run command npm install.
76 | - Change directory to purr-data/emscripten/project/purr-data.
77 | - run command npm run build.
78 | - run command npm start.
79 |
80 | Method 2
81 |
82 | - Follow the steps given in the link inorder to install Ubuntu LTS (https://docs.microsoft.com/en-us/windows/wsl/) .
83 | - Then follow the steps mentioned in above sections for Linux.
84 | ```
85 | ### Running Purr Data in a web browser
86 | - After the building is successfully completed, visit http://localhost:5000 in your browser.
87 | - You can run `npm start` under `purr-data/emscripten/project/purr-data` to run the app again.
88 |
89 | ## Directory Structure
90 | - components: Elements that are dynamically added to the page. (canvas, dialogs, menu)
91 | - components/dialogs: Copied dialogs files from `purr-data/pd/nw` folder.
92 | - css: Copied css files from `purr-data/pd/nw/css` folder.
93 | - css/webapp: Styles created for the web browser.
94 | - dist: Browserified Javascript files. (pdgui.js, pd_shortcuts.js, pd_canvas.js)
95 | - libs: External dependencies.
96 | - utils: Common functions used for this project.
97 |
98 | ## Future Work
99 | - Fix shortcuts so they can work identically in browsers as the native Purr Data.
100 | - Fix getting stuck in the loading screen until a mouse/key event is triggered in Firefox/Safari.
101 | - Fix the patch not responding to mouse event after the help file is opened and not being clicked.
102 | - Fix wrong mouse coordinate issue that happens in some circumstances.
103 | - Fix or disable some of the global menu items not working.
104 | - Fix graphical arrays being opened if the patch font size changes.
105 | - Ask for saving the patch when the user closes an edited patch.
106 | - Make the GUI(e.g. bang, toggle) property dialog window work.
107 | - Make the dialog windows(e.g. property, text) appear on the right side of the patch instead of the left sidebar.
108 | - Merge the patch menu into the global menu and make it work depending on the focus of patches.
109 | - Style the patch window menu bar so it can show the focus state and add some buttons (e.g. close) for convenience.
110 | - Make the patch window resizable by dragging its border.
111 | - Make the patch window rearrangeable by dragging its menu bar.
112 | - Improve the file manager so the files/folders can be added/renamed/deleted.
113 | - Clean the frontend codebase and organize the file system.
114 | - Make the work storable and shareable between users.
115 |
116 | ## Reporting Bugs
117 | If you find any bugs, please let us know. You can contact using the [mailing list](http://disis.music.vt.edu/listinfo/l2ork-dev) or create an [issue](https://git.purrdata.net/jwilkes/purr-data/-/issues).
118 |
--------------------------------------------------------------------------------
/browserify_entries.js:
--------------------------------------------------------------------------------
1 | import pdgui from "../../../pd/nw/pdgui.js"
2 | import shortcuts from "../../../pd/nw/pd_shortcuts.js"
3 | import pd_canvas from "../../../pd/nw/pd_canvas.js"
4 |
5 | export const pdgui = pdgui
6 | export const shortcuts = shortcuts
7 | export const pd_canvas = pd_canvas
8 |
--------------------------------------------------------------------------------
/components/canvas/canvas.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | window.update_canvas_id = function(cid){
4 | // Update patch id
5 | var patch = document.getElementById("patch")
6 | patch.id = patch.id + cid;
7 |
8 | // Remain elements
9 | var elems = document.getElementById("patch"+cid).getElementsByTagName("*");
10 | for (const elem of elems) {
11 | elem.id = elem.id + cid
12 | }
13 | }
14 |
15 | window.add_canvas_name = function(cid, name){
16 | // Update patch id
17 | var patch_filename = document.getElementById("patch-filename"+cid)
18 |
19 | // Remain elements
20 | patch_filename.innerHTML="";
21 | patch_filename.append(name);
22 | }
--------------------------------------------------------------------------------
/components/canvas/pd_canvas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ×
6 |
7 |
8 |
9 |
10 |
95 |
96 |
97 |
98 |
109 |
110 |
111 |
112 |
113 |
121 |
122 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/components/dialogs/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuinjune/purr-data/ef041237ab270f2533409c9bd31ee8ff5873640a/components/dialogs/.gitkeep
--------------------------------------------------------------------------------
/components/dialogs/dialog_data.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
24 |
25 |
375 |
376 |
377 |
--------------------------------------------------------------------------------
/components/dialogs/dialog_external.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
33 |
219 |
220 |
221 |
--------------------------------------------------------------------------------
/components/dialogs/dialog_font.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
88 |
89 |
202 |
203 |
204 |
--------------------------------------------------------------------------------
/components/dialogs/dialog_gatom.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
166 |
167 |
406 |
407 |
408 |
--------------------------------------------------------------------------------
/components/dialogs/dialog_text.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Do you want to save the changes you made before closing the window?
21 |
22 |
23 |
27 |
28 |
29 |
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/components/menu/menu.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
69 |
70 |
--------------------------------------------------------------------------------
/css/c64.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #a49aea;
26 | color: #cc9933;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | background-color: #3e32a2;
52 | color: #a49aea;
53 | }
54 |
55 | /* The console API allows classes for different types of messages to print.
56 | Currently the only class is "error". More may be added, especially once
57 | we port the "loglevel" functionality that was available in Pd Extended. */
58 | #console_bottom .error {
59 | color: #cc9933;
60 | }
61 |
62 | #console_bottom .error a {
63 | color: #ccc;
64 | }
65 |
66 | /* Find bar */
67 |
68 | #console_find label, #canvas_find label {
69 | font-family: "DejaVu Sans", sans-serif;
70 | font-size: 10pt;
71 | }
72 |
73 | /* marks for matches to console_find */
74 | mark {
75 | background: white !important;
76 | padding: 0 !important;
77 | }
78 |
79 | mark.console_find_current.console_find_highlighted,
80 | mark.console_find_current {
81 | background: yellow !important;
82 | }
83 |
84 | mark.console_find_highlighted {
85 | background: #6bd4e6 !important;
86 | }
87 |
88 | #console_find {
89 | width: 100%;
90 | height: 1em;
91 | padding: 0.2em;
92 | background: silver;
93 | position: fixed;
94 | bottom: 0;
95 | left: 0;
96 | }
97 |
98 | /* Pure Data Patch Window (aka canvas) */
99 |
100 | /* patch font and background color. */
101 | .patch_body {
102 | background-color: #3e32a2;
103 | }
104 |
105 | #selection_rectangle {
106 | stroke: #7c71da;
107 | }
108 |
109 | /* The outline to show the visible area for a Graph-On-Parent canvas,
110 | i.e., the "red rectangle" */
111 | .gop_rect {
112 | fill: none;
113 | stroke: #ff9933;
114 | }
115 |
116 | .cord.signal {
117 | stroke-width: 2;
118 | stroke: #7569d7;
119 | }
120 |
121 | .cord.control {
122 | stroke-width: 1;
123 | stroke: #7569d7;
124 | }
125 |
126 | /* selected connection between objects */
127 | .cord.signal.selected_line,
128 | .cord.control.selected_line,
129 | #newcord {
130 | stroke: #cc9933;
131 | }
132 |
133 | #cord_inspector_rect {
134 | fill: black;
135 | stroke: black;
136 | }
137 |
138 | #cord_inspector_text {
139 | fill: white;
140 | }
141 |
142 | #cord_inspector_text.flash {
143 | fill: #e87216;
144 | }
145 |
146 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
147 | .box_text {
148 | fill: #a49aea;
149 | }
150 |
151 | /* hyperlinks: for now, just pddplink and helplink */
152 | .pd_link text {
153 | }
154 |
155 | .pd_link text:hover {
156 | fill: red;
157 | }
158 |
159 | .pd_link.selected text {
160 | fill: #e87216 !important;
161 | }
162 |
163 | #new_object_textentry {
164 | /* max-width: 10ch; */
165 | min-width: 3ch;
166 | position: absolute;
167 | display: table-cell;
168 | padding: 3px 2px 3px 2px;
169 | /* box-shadow: inset 1px 0px 0px 1px #000; */
170 | color: #a49aea; /* text color */
171 | background-color: transparent;
172 | white-space: pre-wrap;
173 | overflow-wrap: break-word;
174 | -webkit-margin-before: 0px;
175 | }
176 |
177 | #new_object_textentry.obj {
178 | outline: 1px solid #a49aea;
179 | }
180 |
181 | #new_object_textentry.msg {
182 | outline: 0px solid #a49aea;
183 | background-image: url(../msg-box.svg);
184 | }
185 |
186 | p.msg::after {
187 | content: "";
188 | height: 100%;
189 | width: 5px;
190 | background-image: url(../msg-box-flag.svg);
191 | position: absolute;
192 | top: 0%;
193 | left: 100%;
194 | }
195 |
196 | /* not sure what this is doing here... */
197 | text {
198 | // fill: red;
199 | //cursor: default;
200 | }
201 |
202 | /* not sure if this is still needed */
203 | .selected_border {
204 | stroke: blue;
205 | stroke-dasharray: none;
206 | stroke-width: 1;
207 | }
208 |
209 | .msg .border {
210 | stroke: #7569d7;
211 | fill: #3e32a2;
212 | }
213 |
214 | /* state of msg box when clicking it */
215 | .msg.flashed .border {
216 | stroke-width: 4;
217 | }
218 |
219 | /* atom box */
220 | .atom .border {
221 | stroke: #7569d7;
222 | fill: #3e32a2;
223 | }
224 |
225 | /* for dropdown box we want to visually distinguish boxes that output
226 | the index from boxes that output the value. For now we do that by
227 | stroking the arrow for boxes that output an index. For boxes that
228 | output the value we don't need a CSS rule, as the arrow will be filled
229 | black by default */
230 | .atom .index_arrow {
231 | stroke: black;
232 | stroke-width: 1;
233 | fill: none;
234 | }
235 |
236 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
237 | .atom.activated text {
238 | fill: red;
239 | }
240 |
241 | #dropdown_list {
242 | position: absolute;
243 | border-width: 1px;
244 | border-style: solid;
245 | border-color: #7569d7;
246 | cursor: pointer;
247 | box-shadow: 2px 2px 0px #7569d7;
248 | overflow-y: auto;
249 | }
250 |
251 | #dropdown_list ol {
252 | list-style-position: inside;
253 | margin: 0;
254 | padding: 0;
255 | background: #3e32a2;
256 | outline: #7569d7;
257 | }
258 |
259 | #dropdown_list li {
260 | color: #a49aea;
261 | list-style-type: none;
262 | padding: 5px;
263 | }
264 |
265 | #dropdown_list li.highlighted {
266 | color: black;
267 | background: #e87216;
268 | }
269 |
270 | .obj .border {
271 | fill: #3e32a2;
272 | stroke: #7569d7;
273 | }
274 |
275 | .comment .border {
276 | fill: none;
277 | }
278 | svg[id^="patchsvg"].editmode .comment .border {
279 | stroke: #7569d7;
280 | stroke-dasharray: 8 4;
281 | }
282 |
283 | /* A little hack for special case of [cnv].
284 | All other iemguis have a black border, but
285 | [cnv] sets its selection rectangle to the
286 | user-supplied fill color when the object
287 | isn't selected */
288 | .iemgui .border:not(.mycanvas_border) {
289 | stroke: #7569d7;
290 | }
291 |
292 | .graph .border {
293 | stroke: #777;
294 | fill: none;
295 | }
296 |
297 | /* Graph (or subpatch) that has been opened to inspect its contents */
298 | .graph.has_window .border {
299 | stroke: #7569d7;
300 | fill: #7569d7;
301 | }
302 |
303 | /* border color for selected objects
304 | * an element with the class "border"
305 | * the element is contained within a parent element of class "selected"
306 | * that parent element is not in class "gop"
307 | in plain English:
308 | This lets us highlight an object's border, unless it is inside a gop
309 | canvas.
310 | */
311 | :not(.gop).selected .border {
312 | stroke: #cc9933;
313 | display: inline;
314 | }
315 |
316 | /* text inside selected objects */
317 | :not(.gop).selected text {
318 | fill: #cc9933;
319 | }
320 |
321 | /* for an object that didn't create */
322 | .obj .border.broken_border {
323 | fill: #3e32a2;
324 | stroke: #ff9933;
325 | stroke-dasharray: 3 2;
326 | }
327 |
328 | /* control inlet */
329 | .xlet_control {
330 | stroke: #7c71da;
331 | fill: #7c71da;
332 | // stroke-width: 1;
333 | }
334 |
335 | /* signal inlet */
336 | .xlet_signal {
337 | stroke: #7569d7;
338 | fill: #7569d7;
339 | stroke-width: 1;
340 | }
341 |
342 | /* iemgui inlet or outlet */
343 | .xlet_iemgui {
344 | stroke: #7569d7;
345 | fill: #7569d7;
346 | stroke-width: 1;
347 | }
348 |
349 | /* text label for an iemgui */
350 | .iemgui_label_selected {
351 | fill: blue;
352 | }
353 |
354 | /* test of xlet hover animation... this should
355 | probably use the web animation API instead. That
356 | way the animation won't get cut off when you
357 | move off the object */
358 | @-webkit-keyframes fizzle {
359 | 0% {
360 | stroke-width: 1;
361 | stroke-opacity: 1;
362 | rx: 1;
363 | ry: 1;
364 | }
365 | 100% {
366 | stroke-width: 20;
367 | stroke-opacity: 0.2;
368 | rx: 50;
369 | ry: 50;
370 | }
371 | }
372 |
373 | /* can't remember why this was tagged !important */
374 | .xlet_selected {
375 | stroke: #cc9933 !important;
376 | fill: #7569d7;
377 | -webkit-animation: fizzle 0.5s linear 1;
378 | }
379 |
380 | #canvas_find {
381 | width: 100%;
382 | height: 1em;
383 | padding: 3px;
384 | background: silver;
385 | position: fixed;
386 | bottom: 0;
387 | left: 0;
388 | }
389 |
390 | /* Dialog to ask to save the patch before quitting */
391 | #save_before_quit {
392 | color: white;
393 | background-color: #3e32a2;
394 | border:3px solid #cc9933;
395 | padding: 12px;
396 | margin: 12px;
397 | box-shadow: 7px 7px 5px black;
398 | }
399 |
400 | /* Search dialog */
401 |
402 | .search_body {
403 | font-family: "DejaVu Sans", sans-serif;
404 | font-size: 10pt;
405 | padding: 8px;
406 | }
407 |
408 | /* Common to all dialogs */
409 |
410 | .dialog_body {
411 | font-family: "DejaVu Sans", sans-serif;
412 | font-size: 10pt;
413 | background-color: #3e32a2;
414 | }
415 |
416 | .submit_buttons {
417 | text-align: center;
418 | padding: 8px;
419 | }
420 |
421 | fieldset {
422 | color: #a49aea;
423 | background-color: #3e32a2;
424 | border-radius:3px;
425 | border:1px solid #cc9933;
426 | margin-left:auto;
427 | margin-right:auto;
428 | padding: 10px;
429 | }
430 |
431 | .hidden {
432 | display: none;
433 | }
434 |
435 | .container{
436 | display: none;
437 | }
438 |
439 | /* Iemgui dialog */
440 |
441 | #iemgui_dialog_body {
442 | font-family:Verdana;
443 | margin: 0px;
444 | }
445 |
446 | input[type="text"]{
447 | width:3em;
448 | }
449 |
450 | input[type="number"]{
451 | width:3em;
452 | }
453 |
454 | label {
455 | text-align: right;
456 | }
457 |
458 | /* Pair of properties that are related */
459 | .pair {
460 | width: 75%;
461 | text-align: left;
462 | align: left;
463 | }
464 |
465 | .item1 {
466 | width: 50%;
467 | }
468 |
469 | .item2 {
470 | width: 50%;
471 | }
472 |
473 | input[name="x_offset"] {
474 | width: 2em;
475 | }
476 |
477 | input[name="y_offset"] {
478 | width: 2em;
479 | }
480 |
481 | input[name="send_symbol"] {
482 | width: 8em;
483 | }
484 |
485 | input[name="receive_symbol"] {
486 | width: 8em;
487 | }
488 |
489 | input[name="label"] {
490 | width: 8em;
491 | }
492 |
493 | input[name="font_size"] {
494 | width: 3em;
495 | }
496 |
497 | input[name="startup_flags"] {
498 | width: 16em;
499 | }
500 |
501 | /* Canvas dialog */
502 |
503 | div.x-scale {
504 | padding: 3px;
505 | text-align: center;
506 | }
507 |
508 | div.gop-range {
509 | }
510 |
511 | div.y1 {
512 | text-align: center;
513 | padding: 3px;
514 | }
515 |
516 | div.x1 {
517 | text-align: center;
518 | padding: 3px;
519 | }
520 |
521 | div.y2 {
522 | text-align: center;
523 | padding: 3px;
524 | }
525 |
526 | .disabled {
527 | color: #aaa;
528 | }
529 |
530 | /* Preferences dialog */
531 |
532 | #prefs_html_element {
533 | /* height: 100%; */
534 | margin: 0px;
535 | padding: 0px;
536 | height: 100vh;
537 | }
538 |
539 | .prefs_body {
540 | padding: 0px;
541 | }
542 |
543 | #prefs_container {
544 | display: table;
545 | }
546 |
547 | /* Main tab widget */
548 |
549 | /* All the display, width, and height settings below are a house of cards.
550 | I don't have the schooling to actually predict how all these CSS elements
551 | work together to create the whole. I just fudged around until I found a
552 | way to get the buttons anchored at the bottom of the dialog without
553 | triggering scrollbars to appear. If someone knows a way to do it "right"
554 | without becoming an order of magnitude more complex, do feel free... */
555 | .prefs_tab_group {
556 | display: table;
557 | width: 90%;
558 | }
559 |
560 | /* Configure the radio buttons to hide off-screen */
561 | .prefs_tab {
562 | position: absolute;
563 | left:-100px;
564 | top:-100px;
565 | }
566 |
567 | /* Configure labels to look like tabs */
568 | .prefs_tab + label {
569 | /* inline-block such that the label can be given dimensions */
570 | display: inline-block;
571 | /* A nice curved border around the tab */
572 | border: 1px solid #bbb;
573 | border-top-left-radius: 5px;
574 | border-top-right-radius: 5px;
575 | /* the bottom border is handled by the tab content div */
576 | border-bottom: 0;
577 | /* Padding around tab text */
578 | padding: 5px 10px;
579 | /* put a small margin to the left to make the first tab clear */
580 | margin-left: 4px;
581 | margin-top: 8px;
582 | margin-bottom: 0px;
583 | /* Set the background color to default gray (non-selected tab) */
584 | background-color:#7569d7;
585 | }
586 |
587 | /* Focused tabs */
588 | .prefs_tab:focus + label {
589 | border: 1px dashed #bbb;
590 | }
591 |
592 | /* Checked tabs must be white with the bottom border removed */
593 | .prefs_tab:checked + label {
594 | background-color: #cc9933;
595 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
596 | border-bottom: 1px solid #f3f3f3;
597 | margin-bottom: -1px;
598 | }
599 |
600 | /* The tab content must fill the widgets size and have a nice border */
601 | .prefs_tab_group > div {
602 | display: none;
603 | border-top: 1px solid #ddd;
604 | padding: 0px;
605 | margin: 0px;
606 | height: 100%;
607 | }
608 |
609 | /* This matches tabs displaying to their associated radio inputs */
610 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
611 | display: table;
612 | padding: 8px;
613 | line-height: 20px;
614 | width: 100%;
615 | height: 78vh;
616 | }
617 |
618 | .tab_settings {
619 | padding-top: 8px;
620 | color: #a49aea;
621 | }
622 |
623 | /* Sample rate input */
624 | input[name="rate"] {
625 | width: 4em;
626 | }
627 |
628 | #prefs_buttons {
629 | display: table;
630 | height: 10vh;
631 | padding: 0px;
632 | margin: 0px;
633 | margin-top: -10px;
634 | margin-bottom: -10px;
635 | padding: 30px;
636 | }
637 |
--------------------------------------------------------------------------------
/css/extended.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #c3c3c3;
26 | color: black;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | }
52 |
53 | /* The console API allows classes for different types of messages to print.
54 | Currently the only class is "error". More may be added, especially once
55 | we port the "loglevel" functionality that was available in Pd Extended. */
56 | #console_bottom .error {
57 | color: red;
58 | }
59 |
60 | /* Find bar */
61 |
62 | #console_find label, #canvas_find label {
63 | font-family: "DejaVu Sans", sans-serif;
64 | font-size: 10pt;
65 | }
66 |
67 | /* marks for matches to console_find */
68 | mark {
69 | background: white !important;
70 | padding: 0 !important;
71 | }
72 |
73 | mark.console_find_current.console_find_highlighted,
74 | mark.console_find_current {
75 | background: yellow !important;
76 | }
77 |
78 | mark.console_find_highlighted {
79 | background: #6bd4e6 !important;
80 | }
81 |
82 | #console_find {
83 | width: 100%;
84 | height: 1em;
85 | padding: 0.2em;
86 | background: silver;
87 | position: fixed;
88 | bottom: 0;
89 | left: 0;
90 | }
91 |
92 | /* Pure Data Patch Window (aka canvas) */
93 |
94 | /* patch font and background color. (Note: margin needs to stay at zero.) */
95 | .patch_body {
96 | font-family: "DejaVu Sans Mono";
97 | }
98 |
99 | #selection_rectangle {
100 | stroke: black;
101 | }
102 |
103 | /* The outline to show the visible area for a Graph-On-Parent canvas,
104 | i.e., the "red rectangle" */
105 | .gop_rect {
106 | fill: none;
107 | stroke: red;
108 | }
109 |
110 | .cord.signal {
111 | stroke-width: 2;
112 | stroke: #828297;
113 | }
114 |
115 | .cord.control {
116 | stroke-width: 1;
117 | stroke: #565;
118 | }
119 |
120 | /* selected connection between objects */
121 | .cord.signal.selected_line,
122 | .cord.control.selected_line {
123 | stroke: blue;
124 | }
125 |
126 | #cord_inspector_rect {
127 | fill: black;
128 | stroke: black;
129 | }
130 |
131 | #cord_inspector_text {
132 | fill: white;
133 | }
134 |
135 | #cord_inspector_text.flash {
136 | fill: #e87216;
137 | }
138 |
139 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
140 | .box_text {
141 | fill: black;
142 | }
143 |
144 | /* hyperlinks: for now, just pddplink and helplink */
145 | .pd_link text {
146 | fill: blue;
147 | }
148 |
149 | .pd_link text:hover {
150 | fill: red;
151 | }
152 |
153 | .pd_link.selected text {
154 | fill: #e87216 !important;
155 | }
156 |
157 | #new_object_textentry {
158 | /* max-width: 10ch; */
159 | min-width: 3ch;
160 | position: absolute;
161 | display: table-cell;
162 | padding: 3px 2px 3px 2px;
163 | /* box-shadow: inset 1px 0px 0px 1px #000; */
164 | background-color: transparent;
165 | white-space: pre-wrap;
166 | overflow-wrap: break-word;
167 | -webkit-margin-before: 0px;
168 | }
169 |
170 | #new_object_textentry.obj {
171 | outline: 1px solid blue;
172 | }
173 |
174 | #new_object_textentry.msg {
175 | outline: 0px solid blue;
176 | background-image: url(../msg-box.svg);
177 | }
178 |
179 | p.msg::after {
180 | content: "";
181 | height: 100%;
182 | width: 5px;
183 | background-image: url(../msg-box-flag.svg);
184 | position: absolute;
185 | top: 0%;
186 | left: 100%;
187 | }
188 |
189 | /* not sure what this is doing here... */
190 | text {
191 | // fill: red;
192 | //cursor: default;
193 | }
194 |
195 | /* not sure if this is still needed */
196 | .selected_border {
197 | stroke: blue;
198 | stroke-dasharray: none;
199 | stroke-width: 1;
200 | }
201 |
202 | .msg .border {
203 | stroke: #c1c1c1;
204 | fill: #f8f8f6;
205 | }
206 |
207 | /* state of msg box when clicking it */
208 | .msg.flashed .border {
209 | stroke-width: 4;
210 | }
211 |
212 | /* atom box */
213 | .atom .border {
214 | stroke: #c1c1c1;
215 | fill: #e0e0e0;
216 | }
217 |
218 | /* for dropdown box we want to visually distinguish boxes that output
219 | the index from boxes that output the value. For now we do that by
220 | stroking the arrow for boxes that output an index. For boxes that
221 | output the value we don't need a CSS rule, as the arrow will be filled
222 | black by default */
223 | .atom .index_arrow {
224 | stroke: black;
225 | stroke-width: 1;
226 | fill: none;
227 | }
228 |
229 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
230 | .atom.activated text {
231 | fill: red;
232 | }
233 |
234 | #dropdown_list {
235 | position: absolute;
236 | border-width: 1px;
237 | border-style: solid;
238 | border-color: #c3c3c3;
239 | cursor: pointer;
240 | box-shadow: 5px 0 5px -5px #888, 0 5px 5px -5px #888, -5px 0 5px -5px #888;
241 | overflow-y: auto;
242 | }
243 |
244 | #dropdown_list ol {
245 | list-style-position: inside;
246 | margin: 0;
247 | padding: 0;
248 | background: #eee;
249 | }
250 |
251 | #dropdown_list li {
252 | list-style-type: none;
253 | padding: 5px;
254 | }
255 |
256 | #dropdown_list li.highlighted {
257 | background: #c3c3c3;
258 | }
259 |
260 | .obj .border {
261 | fill: #f6f8f8;
262 | stroke: #c1c1c1;
263 | }
264 |
265 | .comment .border {
266 | fill: none;
267 | }
268 |
269 | svg[id^="patchsvg"].editmode .comment .border {
270 | stroke: #aaa;
271 | stroke-dasharray: 8 4;
272 | }
273 |
274 | /* A little hack for special canvas of [cnv].
275 | All other iemguis have a black border, but
276 | [cnv] sets its selection rectangle to the
277 | user-supplied fill color when the object
278 | isn't selected */
279 | .iemgui .border:not(.mycanvas_border) {
280 | stroke: black;
281 | }
282 |
283 | .graph .border {
284 | stroke: #777;
285 | fill: none;
286 | }
287 |
288 | /* Graph (or subpatch) that has been opened to inspect its contents */
289 | .graph.has_window .border {
290 | stroke: black;
291 | fill: gray;
292 | }
293 |
294 | /* border color for selected objects
295 | * an element with the class "border"
296 | * the element is contained within a parent element of class "selected"
297 | * that parent element is not in class "gop"
298 | in plain English:
299 | This lets us highlight an object's border, unless it is inside a gop
300 | canvas.
301 | */
302 | :not(.gop).selected .border {
303 | stroke: blue;
304 | display: inline;
305 | }
306 |
307 | /* text inside selected objects */
308 | :not(.gop).selected text {
309 | fill: blue;
310 | }
311 |
312 | /* for an object that didn't create */
313 | .obj .border.broken_border {
314 | fill: #f7f7f7;
315 | stroke: #f00;
316 | stroke-dasharray: 3 2;
317 | }
318 |
319 | /* control inlet */
320 | .xlet_control {
321 | stroke: #536253;
322 | fill: white;
323 | // stroke-width: 1;
324 | }
325 |
326 | /* signal inlet */
327 | .xlet_signal {
328 | stroke: #828297;
329 | fill: #808095;
330 | stroke-width: 1;
331 | }
332 |
333 | /* iemgui inlet or outlet */
334 | .xlet_iemgui {
335 | stroke: black;
336 | fill: black;
337 | stroke-width: 1;
338 | }
339 |
340 | /* text label for an iemgui */
341 | .iemgui_label_selected {
342 | fill: blue;
343 | }
344 |
345 | /* test of xlet hover animation... this should
346 | probably use the web animation API instead. That
347 | way the animation won't get cut off when you
348 | move off the object */
349 | @-webkit-keyframes fizzle {
350 | 0% {
351 | stroke-width: 1;
352 | stroke-opacity: 1;
353 | rx: 1;
354 | ry: 1;
355 | }
356 | 100% {
357 | stroke-width: 20;
358 | stroke-opacity: 0.2;
359 | rx: 50;
360 | ry: 50;
361 | }
362 | }
363 |
364 | /* can't remember why this was tagged !important */
365 | .xlet_selected {
366 | stroke: blue !important;
367 | fill: blue;
368 | -webkit-animation: fizzle 0.5s linear 1;
369 | }
370 |
371 | #canvas_find {
372 | width: 100%;
373 | height: 1em;
374 | padding: 3px;
375 | background: silver;
376 | position: fixed;
377 | bottom: 0;
378 | left: 0;
379 | }
380 |
381 | /* Search dialog */
382 |
383 | .search_body {
384 | font-family: "DejaVu Sans", sans-serif;
385 | font-size: 10pt;
386 | padding: 8px;
387 | }
388 |
389 | /* Common to all dialogs */
390 |
391 | .dialog_body {
392 | font-family: "DejaVu Sans", sans-serif;
393 | font-size: 10pt;
394 | background-color: #f3f3f3;
395 | }
396 |
397 | .submit_buttons {
398 | text-align: center;
399 | padding: 8px;
400 | }
401 |
402 | fieldset {
403 | background-color:#eeeeee;
404 | border-radius:3px;
405 | border:2px solid black;
406 | margin-left:auto;
407 | margin-right:auto;
408 | padding: 10px;
409 | }
410 |
411 | .hidden {
412 | display: none;
413 | }
414 |
415 | .container{
416 | display: none;
417 | }
418 |
419 | /* Iemgui dialog */
420 |
421 | input[type="text"]{
422 | width:3em;
423 | }
424 |
425 | input[type="number"]{
426 | width:3em;
427 | }
428 |
429 | label {
430 | text-align: right;
431 | }
432 |
433 | /* Pair of properties that are related */
434 | .pair {
435 | width: 75%;
436 | text-align: left;
437 | align: left;
438 | }
439 |
440 | .item1 {
441 | width: 50%;
442 | }
443 |
444 | .item2 {
445 | width: 50%;
446 | }
447 |
448 | input[name="x_offset"] {
449 | width: 2em;
450 | }
451 |
452 | input[name="y_offset"] {
453 | width: 2em;
454 | }
455 |
456 | input[name="send_symbol"] {
457 | width: 8em;
458 | }
459 |
460 | input[name="receive_symbol"] {
461 | width: 8em;
462 | }
463 |
464 | input[name="label"] {
465 | width: 8em;
466 | }
467 |
468 | input[name="font_size"] {
469 | width: 3em;
470 | }
471 |
472 | input[name="startup_flags"] {
473 | width: 16em;
474 | }
475 |
476 | /* Canvas dialog */
477 |
478 | div.x-scale {
479 | padding: 3px;
480 | text-align: center;
481 | }
482 |
483 | div.gop-range {
484 | }
485 |
486 | div.y1 {
487 | text-align: center;
488 | padding: 3px;
489 | }
490 |
491 | div.x1 {
492 | text-align: center;
493 | padding: 3px;
494 | }
495 |
496 | div.y2 {
497 | text-align: center;
498 | padding: 3px;
499 | }
500 |
501 | .disabled {
502 | color: #aaa;
503 | }
504 |
505 | /* Preferences dialog */
506 |
507 | #prefs_html_element {
508 | /* height: 100%; */
509 | margin: 0px;
510 | padding: 0px;
511 | height: 100vh;
512 | }
513 |
514 | .prefs_body {
515 | padding: 0px;
516 | }
517 |
518 | #prefs_container {
519 | display: table;
520 | }
521 |
522 | /* Main tab widget */
523 |
524 | /* All the display, width, and height settings below are a house of cards.
525 | I don't have the schooling to actually predict how all these CSS elements
526 | work together to create the whole. I just fudged around until I found a
527 | way to get the buttons anchored at the bottom of the dialog without
528 | triggering scrollbars to appear. If someone knows a way to do it "right"
529 | without becoming an order of magnitude more complex, do feel free... */
530 | .prefs_tab_group {
531 | display: table;
532 | width: 90%;
533 | }
534 |
535 | /* Configure the radio buttons to hide off-screen */
536 | .prefs_tab {
537 | position: absolute;
538 | left:-100px;
539 | top:-100px;
540 | }
541 |
542 | /* Configure labels to look like tabs */
543 | .prefs_tab + label {
544 | /* inline-block such that the label can be given dimensions */
545 | display: inline-block;
546 | /* A nice curved border around the tab */
547 | border: 1px solid #bbb;
548 | border-top-left-radius: 5px;
549 | border-top-right-radius: 5px;
550 | /* the bottom border is handled by the tab content div */
551 | border-bottom: 0;
552 | /* Padding around tab text */
553 | padding: 5px 10px;
554 | /* put a small margin to the left to make the first tab clear */
555 | margin-left: 4px;
556 | margin-top: 8px;
557 | margin-bottom: 0px;
558 | /* Set the background color to default gray (non-selected tab) */
559 | background-color:#ececec;
560 | }
561 |
562 | /* Focused tabs */
563 | .prefs_tab:focus + label {
564 | border: 1px dashed #bbb;
565 | }
566 |
567 | /* Checked tabs must be white with the bottom border removed */
568 | .prefs_tab:checked + label {
569 | background-color: #f3f3f3;
570 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
571 | border-bottom: 1px solid #f3f3f3;
572 | margin-bottom: -1px;
573 | }
574 |
575 | /* The tab content must fill the widgets size and have a nice border */
576 | .prefs_tab_group > div {
577 | display: none;
578 | border-top: 1px solid #ddd;
579 | padding: 0px;
580 | margin: 0px;
581 | height: 100%;
582 | }
583 |
584 | /* This matches tabs displaying to their associated radio inputs */
585 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
586 | display: table;
587 | padding: 8px;
588 | line-height: 20px;
589 | width: 100%;
590 | height: 78vh;
591 | }
592 |
593 | .tab_settings {
594 | padding-top: 8px;
595 | }
596 |
597 | /* Sample rate input */
598 | input[name="rate"] {
599 | width: 4em;
600 | }
601 |
602 | #prefs_buttons {
603 | display: table;
604 | height: 10vh;
605 | padding: 0px;
606 | margin: 0px;
607 | margin-top: -10px;
608 | margin-bottom: -10px;
609 | padding: 30px;
610 | }
611 |
--------------------------------------------------------------------------------
/css/solarized.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #eee8d5;
26 | color: #657b83;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | color: #657b83;
33 | background-color: #eee8d5;
34 | height: 50px;
35 | }
36 |
37 | #control_frame {
38 | padding: 12px;
39 | }
40 |
41 | #printout {
42 | margin: 8px;
43 | }
44 |
45 | #console_bottom {
46 | position: absolute;
47 | top: 50px;
48 | left: 0px;
49 | right: 0px;
50 | bottom: 0px;
51 | overflow-y: scroll;
52 | background-color: #fdf6e3;
53 | color: #657b83;
54 | }
55 |
56 | /* The console API allows classes for different types of messages to print.
57 | Currently the only class is "error". More may be added, especially once
58 | we port the "loglevel" functionality that was available in Pd Extended. */
59 | #console_bottom .error {
60 | color: #586e75;
61 | }
62 |
63 | #console_bottom .error a {
64 | color: #268bd2;
65 | font-weight: 600;
66 | }
67 |
68 | /* Find bar */
69 |
70 | #console_find label, #canvas_find label {
71 | font-family: "DejaVu Sans", sans-serif;
72 | font-size: 10pt;
73 | }
74 |
75 | /* marks for matches to console_find */
76 | mark {
77 | background: #eee8d5 !important;
78 | padding: 0 !important;
79 | }
80 |
81 | mark.console_find_current.console_find_highlighted,
82 | mark.console_find_current {
83 | background: #b58900 !important;
84 | }
85 |
86 | mark.console_find_highlighted {
87 | background: #6bd4e6 !important;
88 | }
89 |
90 | #console_find {
91 | width: 100%;
92 | height: 1em;
93 | padding: 0.2em;
94 | background: #eee8d5;
95 | position: fixed;
96 | bottom: 0;
97 | left: 0;
98 | color: #586e75;
99 | }
100 |
101 | /* Pure Data Patch Window (aka canvas) */
102 |
103 | /* patch font and background color. (Note: margin needs to stay at zero.) */
104 | .patch_body {
105 | background-color: #fdf6e3;
106 | }
107 |
108 | #selection_rectangle {
109 | stroke: #073642;
110 | }
111 |
112 | /* The outline to show the visible area for a Graph-On-Parent canvas,
113 | i.e., the "red rectangle" */
114 | .gop_rect {
115 | fill: none;
116 | stroke: #dc322f;
117 | stroke-opacity: 0.4;
118 | }
119 |
120 | .cord.signal {
121 | stroke-width: 2;
122 | stroke: #93a1a1;
123 | }
124 |
125 | .cord.control {
126 | stroke-width: 1;
127 | stroke: #93a1a1;
128 | }
129 |
130 | /* selected connection between objects */
131 | .cord.signal.selected_line,
132 | .cord.control.selected_line,
133 | #newcord {
134 | stroke: #268bd2;
135 | }
136 |
137 | #cord_inspector_rect {
138 | fill: #93a1a1;
139 | stroke: #93a1a1;
140 | }
141 |
142 | #cord_inspector_text {
143 | fill: white;
144 | }
145 |
146 | #cord_inspector_text.flash {
147 | fill: #e87216;
148 | }
149 |
150 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
151 | .box_text {
152 | fill: #657b83;
153 | }
154 |
155 | /* hyperlinks: for now, just pddplink and helplink */
156 | .pd_link text {
157 | fill: blue;
158 | }
159 |
160 | .pd_link text:hover {
161 | fill: red;
162 | }
163 |
164 | .pd_link.selected text {
165 | fill: white;
166 | }
167 |
168 | #new_object_textentry {
169 | /* max-width: 10ch; */
170 | min-width: 3ch;
171 | position: absolute;
172 | display: table-cell;
173 | padding: 3px 2px 3px 2px;
174 | /* box-shadow: inset 1px 0px 0px 1px #000; */
175 | background-color: transparent;
176 | white-space: pre-wrap;
177 | overflow-wrap: break-word;
178 | -webkit-margin-before: 0px;
179 | color: #586e75;
180 | }
181 |
182 | #new_object_textentry.obj {
183 | outline: 1px solid #268bd2;
184 | }
185 |
186 | #new_object_textentry.msg {
187 | outline: 0px solid #268bd2;
188 | background-image: url(../msg-box.svg);
189 | }
190 |
191 | p.msg::after {
192 | content: "";
193 | height: 100%;
194 | width: 5px;
195 | background-image: url(../msg-box-flag.svg);
196 | position: absolute;
197 | top: 0%;
198 | left: 100%;
199 | }
200 |
201 | /* not sure what this is doing here... */
202 | text {
203 | // fill: red;
204 | //cursor: default;
205 | }
206 |
207 | /* not sure if this is still needed */
208 | .selected_border {
209 | stroke: blue;
210 | stroke-dasharray: none;
211 | stroke-width: 1;
212 | }
213 |
214 | .msg .border {
215 | stroke: #93a1a1;
216 | fill: #fdf6e3;
217 | }
218 |
219 | /* state of msg box when clicking it */
220 | .msg.flashed .border {
221 | stroke-width: 4;
222 | }
223 |
224 | /* atom box */
225 | .atom .border {
226 | stroke: #93a1a1;
227 | fill: #fdf6e3;
228 | }
229 |
230 | /* for dropdown box we want to visually distinguish boxes that output
231 | the index from boxes that output the value. For now we do that by
232 | stroking the arrow for boxes that output an index. For boxes that
233 | output the value we don't need a CSS rule, as the arrow will be filled
234 | black by default */
235 | .atom .index_arrow {
236 | stroke: #93a1a1;
237 | stroke-width: 1;
238 | fill: none;
239 | }
240 |
241 | .atom .value_arrow {
242 | stroke: #93a1a1;
243 | fill: #93a1a1;
244 | }
245 |
246 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
247 | .atom.activated text {
248 | fill: #dc322f;
249 | }
250 |
251 | #dropdown_list {
252 | position: absolute;
253 | border-width: 1px;
254 | border-style: solid;
255 | border-color: #93a1a1;
256 | cursor: pointer;
257 | color: #586e75;
258 | overflow-y: auto;
259 | }
260 |
261 | #dropdown_list ol {
262 | list-style-position: inside;
263 | margin: 0;
264 | padding: 0;
265 | background: #fdf6e3;
266 | }
267 |
268 | #dropdown_list li {
269 | list-style-type: none;
270 | padding: 5px;
271 | }
272 |
273 | #dropdown_list li.highlighted {
274 | background: #eee8d5;
275 | }
276 |
277 | .obj .border {
278 | fill: #fdf6e3;
279 | stroke: #93a1a1;
280 | }
281 |
282 | .comment .border {
283 | fill: none;
284 | }
285 |
286 | svg[id^="patchsvg"].editmode .comment .border {
287 | stroke: #94b2b2;
288 | stroke-dasharray: 8 4;
289 | }
290 |
291 | /* A little hack for special canvas of [cnv].
292 | All other iemguis have a black border, but
293 | [cnv] sets its selection rectangle to the
294 | user-supplied fill color when the object
295 | isn't selected */
296 | .iemgui .border:not(.mycanvas_border) {
297 | stroke: #93a1a1;
298 | }
299 |
300 | .graph .border {
301 | stroke: #93a1a1;
302 | fill: none;
303 | }
304 |
305 | /* Graph (or subpatch) that has been opened to inspect its contents */
306 | .graph.has_window .border {
307 | stroke: #93a1a1;
308 | fill: #eee8d5;
309 | }
310 |
311 | /* border color for selected objects
312 | * an element with the class "border"
313 | * the element is contained within a parent element of class "selected"
314 | * that parent element is not in class "gop"
315 | in plain English:
316 | This lets us highlight an object's border, unless it is inside a gop
317 | canvas.
318 | */
319 | :not(.gop).selected .border {
320 | stroke: #268bd2;
321 | display: inline;
322 | }
323 |
324 | /* text inside selected objects */
325 | :not(.gop).selected text {
326 | fill: #268bd2;
327 | }
328 |
329 | /* for an object that didn't create */
330 | .obj .border.broken_border {
331 | fill: transparent;
332 | stroke: #dc322f;
333 | stroke-dasharray: 3 2;
334 | }
335 |
336 | /* control inlet */
337 | .xlet_control {
338 | stroke: #657b83;
339 | fill: #fdf6e3;
340 | }
341 |
342 | /* signal inlet */
343 | .xlet_signal {
344 | stroke: #657b83;
345 | fill: #657b83;
346 | stroke-width: 1;
347 | }
348 |
349 | /* iemgui inlet or outlet */
350 | .xlet_iemgui {
351 | stroke: #657b83;
352 | fill: #fdf6e3;
353 | stroke-width: 1;
354 | }
355 |
356 | /* text label for an iemgui */
357 | .iemgui_label_selected {
358 | fill: #268bd2;
359 | }
360 |
361 | /* test of xlet hover animation... this should
362 | probably use the web animation API instead. That
363 | way the animation won't get cut off when you
364 | move off the object */
365 | @-webkit-keyframes fizzle {
366 | 0% {
367 | stroke-width: 1;
368 | stroke-opacity: 1;
369 | rx: 1;
370 | ry: 1;
371 | }
372 | 100% {
373 | stroke-width: 20;
374 | stroke-opacity: 0.2;
375 | rx: 50;
376 | ry: 50;
377 | }
378 | }
379 |
380 | /* can't remember why this was tagged !important */
381 | .xlet_selected {
382 | stroke: gray !important;
383 | fill: gray;
384 | -webkit-animation: fizzle 0.5s linear 1;
385 | }
386 |
387 | #canvas_find {
388 | width: 100%;
389 | height: 1em;
390 | padding: 3px;
391 | background: #eee8d5;
392 | position: fixed;
393 | bottom: 0;
394 | left: 0;
395 | color: #586e75;
396 | }
397 |
398 | /* Dialog to ask to save the patch before quitting */
399 | #save_before_quit {
400 | background-color: #fdf6e3;
401 | border:1px solid #eee8d5;
402 | padding: 12px;
403 | margin: 12px;
404 | box-shadow: 7px 7px 5px grey;
405 | }
406 |
407 | /* Search dialog */
408 |
409 | .search_body {
410 | font-family: "DejaVu Sans", sans-serif;
411 | font-size: 10pt;
412 | padding: 8px;
413 | background: #fdf6e3;
414 | color: #657b83;
415 | }
416 |
417 | .search_body a {
418 | color: #268bd2;
419 | }
420 |
421 | /* Common to all dialogs */
422 |
423 | .dialog_body {
424 | font-family: "DejaVu Sans", sans-serif;
425 | font-size: 10pt;
426 | background: #fdf6e3;
427 | }
428 |
429 | .submit_buttons {
430 | text-align: center;
431 | padding: 8px;
432 | }
433 |
434 | fieldset {
435 | border-radius:3px;
436 | border:2px solid #eee8d5;
437 | margin-left:auto;
438 | margin-right:auto;
439 | padding: 10px;
440 | }
441 |
442 | .hidden {
443 | display: none;
444 | }
445 |
446 | .container{
447 | display: none;
448 | }
449 |
450 | /* Iemgui dialog */
451 |
452 | input[type="text"]{
453 | width:3em;
454 | }
455 |
456 | input[type="number"]{
457 | width:3em;
458 | }
459 |
460 | label {
461 | text-align: right;
462 | }
463 |
464 | /* Pair of properties that are related */
465 | .pair {
466 | width: 75%;
467 | text-align: left;
468 | align: left;
469 | }
470 |
471 | .item1 {
472 | width: 50%;
473 | }
474 |
475 | .item2 {
476 | width: 50%;
477 | }
478 |
479 | input[name="x_offset"] {
480 | width: 2em;
481 | }
482 |
483 | input[name="y_offset"] {
484 | width: 2em;
485 | }
486 |
487 | input[name="send_symbol"] {
488 | width: 8em;
489 | }
490 |
491 | input[name="receive_symbol"] {
492 | width: 8em;
493 | }
494 |
495 | input[name="label"] {
496 | width: 8em;
497 | }
498 |
499 | input[name="font_size"] {
500 | width: 3em;
501 | }
502 |
503 | input[name="startup_flags"] {
504 | width: 16em;
505 | }
506 |
507 | /* Canvas dialog */
508 |
509 | div.x-scale {
510 | padding: 3px;
511 | text-align: center;
512 | }
513 |
514 | div.gop-range {
515 | }
516 |
517 | div.y1 {
518 | text-align: center;
519 | padding: 3px;
520 | }
521 |
522 | div.x1 {
523 | text-align: center;
524 | padding: 3px;
525 | }
526 |
527 | div.y2 {
528 | text-align: center;
529 | padding: 3px;
530 | }
531 |
532 | .disabled {
533 | color: #aaa;
534 | }
535 |
536 | /* Preferences dialog */
537 |
538 | #prefs_html_element {
539 | /* height: 100%; */
540 | margin: 0px;
541 | padding: 0px;
542 | height: 100vh;
543 | }
544 |
545 | .prefs_body {
546 | padding: 0px;
547 | }
548 |
549 | #prefs_container {
550 | display: table;
551 | }
552 |
553 | /* Main tab widget */
554 |
555 | /* All the display, width, and height settings below are a house of cards.
556 | I don't have the schooling to actually predict how all these CSS elements
557 | work together to create the whole. I just fudged around until I found a
558 | way to get the buttons anchored at the bottom of the dialog without
559 | triggering scrollbars to appear. If someone knows a way to do it "right"
560 | without becoming an order of magnitude more complex, do feel free... */
561 | .prefs_tab_group {
562 | display: table;
563 | width: 90%;
564 | }
565 |
566 | /* Configure the radio buttons to hide off-screen */
567 | .prefs_tab {
568 | position: absolute;
569 | left:-100px;
570 | top:-100px;
571 | }
572 |
573 | /* Configure labels to look like tabs */
574 | .prefs_tab + label {
575 | /* inline-block such that the label can be given dimensions */
576 | display: inline-block;
577 | /* A nice curved border around the tab */
578 | border: 1px solid #bbb;
579 | border-top-left-radius: 5px;
580 | border-top-right-radius: 5px;
581 | /* the bottom border is handled by the tab content div */
582 | border-bottom: 0;
583 | /* Padding around tab text */
584 | padding: 5px 10px;
585 | /* put a small margin to the left to make the first tab clear */
586 | margin-left: 4px;
587 | margin-top: 8px;
588 | margin-bottom: 0px;
589 | /* Set the background color to default gray (non-selected tab) */
590 | background-color:#ececec;
591 | }
592 |
593 | /* Focused tabs */
594 | .prefs_tab:focus + label {
595 | border: 1px dashed #bbb;
596 | }
597 |
598 | /* Checked tabs must be white with the bottom border removed */
599 | .prefs_tab:checked + label {
600 | background-color: #f3f3f3;
601 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
602 | border-bottom: 1px solid #f3f3f3;
603 | margin-bottom: -1px;
604 | }
605 |
606 | /* The tab content must fill the widgets size and have a nice border */
607 | .prefs_tab_group > div {
608 | display: none;
609 | border-top: 1px solid #ddd;
610 | padding: 0px;
611 | margin: 0px;
612 | height: 100%;
613 | }
614 |
615 | /* This matches tabs displaying to their associated radio inputs */
616 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
617 | display: table;
618 | padding: 8px;
619 | line-height: 20px;
620 | width: 100%;
621 | height: 78vh;
622 | }
623 |
624 | .tab_settings {
625 | padding-top: 8px;
626 | }
627 |
628 | /* Sample rate input */
629 | input[name="rate"] {
630 | width: 4em;
631 | }
632 |
633 | #prefs_buttons {
634 | display: table;
635 | height: 10vh;
636 | padding: 0px;
637 | margin: 0px;
638 | margin-top: -10px;
639 | margin-bottom: -10px;
640 | padding: 30px;
641 | }
642 |
--------------------------------------------------------------------------------
/css/solarized_inverted.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #073642;
26 | color: #839496;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | color: #657b83;
33 | background-color: #073642;
34 | height: 50px;
35 | }
36 |
37 | #control_frame {
38 | padding: 12px;
39 | }
40 |
41 | #printout {
42 | margin: 8px;
43 | }
44 |
45 | #console_bottom {
46 | position: absolute;
47 | top: 50px;
48 | left: 0px;
49 | right: 0px;
50 | bottom: 0px;
51 | overflow-y: scroll;
52 | background-color: #002b36;
53 | color: #839496;
54 | }
55 |
56 | /* The console API allows classes for different types of messages to print.
57 | Currently the only class is "error". More may be added, especially once
58 | we port the "loglevel" functionality that was available in Pd Extended. */
59 | #console_bottom .error {
60 | color: #93a1a1;
61 | }
62 |
63 | #console_bottom .error a {
64 | color: #b58900;
65 | font-weight: 600;
66 | }
67 |
68 | /* Find bar */
69 |
70 | #console_find label, #canvas_find label {
71 | font-family: "DejaVu Sans", sans-serif;
72 | font-size: 10pt;
73 | }
74 |
75 | /* marks for matches to console_find */
76 | mark {
77 | background: #eee8d5 !important;
78 | padding: 0 !important;
79 | }
80 |
81 | mark.console_find_current.console_find_highlighted,
82 | mark.console_find_current {
83 | background: #b58900 !important;
84 | }
85 |
86 | mark.console_find_highlighted {
87 | background: #6bd4e6 !important;
88 | }
89 |
90 | #console_find {
91 | width: 100%;
92 | height: 1em;
93 | padding: 0.2em;
94 | background: #073642;
95 | position: fixed;
96 | bottom: 0;
97 | left: 0;
98 | color: #586e75;
99 | }
100 |
101 | /* Pure Data Patch Window (aka canvas) */
102 |
103 | /* patch font and background color. (Note: margin needs to stay at zero.) */
104 | .patch_body {
105 | background-color: #002b36;
106 | }
107 |
108 | #selection_rectangle {
109 | stroke: #b58900;
110 | }
111 |
112 | /* The outline to show the visible area for a Graph-On-Parent canvas,
113 | i.e., the "red rectangle" */
114 | .gop_rect {
115 | fill: none;
116 | stroke: #dc322f;
117 | stroke-opacity: 0.4;
118 | }
119 |
120 | .cord.signal {
121 | stroke-width: 2;
122 | stroke: #586e75;
123 | }
124 |
125 | .cord.control {
126 | stroke-width: 1;
127 | stroke: #586e75;
128 | }
129 |
130 | /* selected connection between objects */
131 | .cord.signal.selected_line,
132 | .cord.control.selected_line,
133 | #newcord {
134 | stroke: #b58900;
135 | }
136 |
137 | #cord_inspector_rect {
138 | fill: #93a1a1;
139 | stroke: #93a1a1;
140 | }
141 |
142 | #cord_inspector_text {
143 | fill: white;
144 | }
145 |
146 | #cord_inspector_text.flash {
147 | fill: #e87216;
148 | }
149 |
150 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
151 | .box_text {
152 | fill: #839496;
153 | }
154 |
155 | /* hyperlinks: for now, just pddplink and helplink */
156 | .pd_link text {
157 | fill: blue;
158 | }
159 |
160 | .pd_link text:hover {
161 | fill: red;
162 | }
163 |
164 | .pd_link.selected text {
165 | fill: white;
166 | }
167 |
168 | #new_object_textentry {
169 | /* max-width: 10ch; */
170 | min-width: 3ch;
171 | position: absolute;
172 | display: table-cell;
173 | padding: 3px 2px 3px 2px;
174 | /* box-shadow: inset 1px 0px 0px 1px #000; */
175 | background-color: transparent;
176 | white-space: pre-wrap;
177 | overflow-wrap: break-word;
178 | -webkit-margin-before: 0px;
179 | color: #93a1a1;
180 | }
181 |
182 | #new_object_textentry.obj {
183 | outline: 1px solid #b58900;
184 | }
185 |
186 | #new_object_textentry.msg {
187 | outline: 0px solid #b58900;
188 | background-image: url(../msg-box.svg);
189 | }
190 |
191 | p.msg::after {
192 | content: "";
193 | height: 100%;
194 | width: 5px;
195 | background-image: url(../msg-box-flag.svg);
196 | position: absolute;
197 | top: 0%;
198 | left: 100%;
199 | }
200 |
201 | /* not sure what this is doing here... */
202 | text {
203 | // fill: red;
204 | //cursor: default;
205 | }
206 |
207 | /* not sure if this is still needed */
208 | .selected_border {
209 | stroke: blue;
210 | stroke-dasharray: none;
211 | stroke-width: 1;
212 | }
213 |
214 | .msg .border {
215 | stroke: #586e75;
216 | fill: #002b36;
217 | }
218 |
219 | /* state of msg box when clicking it */
220 | .msg.flashed .border {
221 | stroke-width: 4;
222 | }
223 |
224 | /* atom box */
225 | .atom .border {
226 | stroke: #586e75;
227 | fill: #002b36;
228 | }
229 |
230 | /* for dropdown box we want to visually distinguish boxes that output
231 | the index from boxes that output the value. For now we do that by
232 | stroking the arrow for boxes that output an index. For boxes that
233 | output the value we don't need a CSS rule, as the arrow will be filled
234 | black by default */
235 | .atom .index_arrow {
236 | stroke: #586e75;
237 | stroke-width: 1;
238 | fill: none;
239 | }
240 |
241 | .atom .value_arrow {
242 | stroke: #586e75;
243 | fill: #586e75;
244 | }
245 |
246 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
247 | .atom.activated text {
248 | fill: #dc322f;
249 | }
250 |
251 | #dropdown_list {
252 | position: absolute;
253 | border-width: 1px;
254 | border-style: solid;
255 | border-color: #586e75;
256 | cursor: pointer;
257 | color: #93a1a1;
258 | overflow-y: auto;
259 | }
260 |
261 | #dropdown_list ol {
262 | list-style-position: inside;
263 | margin: 0;
264 | padding: 0;
265 | background: #002b36;
266 | }
267 |
268 | #dropdown_list li {
269 | list-style-type: none;
270 | padding: 5px;
271 | }
272 |
273 | #dropdown_list li.highlighted {
274 | background: #073642;
275 | }
276 |
277 | .obj .border {
278 | fill: #002b36;
279 | stroke: #586e75;
280 | }
281 |
282 | .comment .border {
283 | fill: none;
284 | }
285 |
286 | svg[id^="patchsvg"].editmode .comment .border {
287 | stroke: #475d64;
288 | stroke-dasharray: 8 4;
289 | }
290 |
291 | /* A little hack for special canvas of [cnv].
292 | All other iemguis have a black border, but
293 | [cnv] sets its selection rectangle to the
294 | user-supplied fill color when the object
295 | isn't selected */
296 | .iemgui .border:not(.mycanvas_border) {
297 | stroke: #93a1a1;
298 | }
299 |
300 | .graph .border {
301 | stroke: #586e75;
302 | fill: none;
303 | }
304 |
305 | /* Graph (or subpatch) that has been opened to inspect its contents */
306 | .graph.has_window .border {
307 | stroke: #93a1a1;
308 | fill: #eee8d5;
309 | }
310 |
311 | /* border color for selected objects
312 | * an element with the class "border"
313 | * the element is contained within a parent element of class "selected"
314 | * that parent element is not in class "gop"
315 | in plain English:
316 | This lets us highlight an object's border, unless it is inside a gop
317 | canvas.
318 | */
319 | :not(.gop).selected .border {
320 | stroke: #b58900;
321 | display: inline;
322 | }
323 |
324 | /* text inside selected objects */
325 | :not(.gop).selected text {
326 | fill: #b58900;
327 | }
328 |
329 | /* for an object that didn't create */
330 | .obj .border.broken_border {
331 | fill: transparent;
332 | stroke: #dc322f;
333 | stroke-dasharray: 3 2;
334 | }
335 |
336 | /* control inlet */
337 | .xlet_control {
338 | stroke: #586e75;
339 | fill: #002b36;
340 | }
341 |
342 | /* signal inlet */
343 | .xlet_signal {
344 | stroke: #586e75;
345 | fill: #002b36;
346 | stroke-width: 1;
347 | }
348 |
349 | /* iemgui inlet or outlet */
350 | .xlet_iemgui {
351 | stroke: #586e75;
352 | fill: #002b36;
353 | stroke-width: 1;
354 | }
355 |
356 | /* text label for an iemgui */
357 | .iemgui_label_selected {
358 | fill: #268bd2;
359 | }
360 |
361 | /* test of xlet hover animation... this should
362 | probably use the web animation API instead. That
363 | way the animation won't get cut off when you
364 | move off the object */
365 | @-webkit-keyframes fizzle {
366 | 0% {
367 | stroke-width: 1;
368 | stroke-opacity: 1;
369 | rx: 1;
370 | ry: 1;
371 | }
372 | 100% {
373 | stroke-width: 20;
374 | stroke-opacity: 0.2;
375 | rx: 50;
376 | ry: 50;
377 | }
378 | }
379 |
380 | /* can't remember why this was tagged !important */
381 | .xlet_selected {
382 | stroke: gray !important;
383 | fill: gray;
384 | -webkit-animation: fizzle 0.5s linear 1;
385 | }
386 |
387 | #canvas_find {
388 | width: 100%;
389 | height: 1em;
390 | padding: 3px;
391 | background: #073642;
392 | position: fixed;
393 | bottom: 0;
394 | left: 0;
395 | color: #586e75;
396 | }
397 |
398 | /* Dialog to ask to save the patch before quitting */
399 | #save_before_quit {
400 | color: white;
401 | background-color: #002b36;
402 | border:1px solid #839496;
403 | padding: 12px;
404 | margin: 12px;
405 | box-shadow: 7px 7px 5px grey;
406 | }
407 |
408 | /* Search dialog */
409 |
410 | .search_body {
411 | font-family: "DejaVu Sans", sans-serif;
412 | font-size: 10pt;
413 | padding: 8px;
414 | background: #fdf6e3;
415 | color: #657b83;
416 | }
417 |
418 | .search_body a {
419 | color: #268bd2;
420 | }
421 |
422 | /* Common to all dialogs */
423 |
424 | .dialog_body {
425 | font-family: "DejaVu Sans", sans-serif;
426 | font-size: 10pt;
427 | background: #fdf6e3;
428 | }
429 |
430 | .submit_buttons {
431 | text-align: center;
432 | padding: 8px;
433 | }
434 |
435 | fieldset {
436 | border-radius:3px;
437 | border:2px solid #eee8d5;
438 | margin-left:auto;
439 | margin-right:auto;
440 | padding: 10px;
441 | }
442 |
443 | .hidden {
444 | display: none;
445 | }
446 |
447 | .container{
448 | display: none;
449 | }
450 |
451 | /* Iemgui dialog */
452 |
453 | input[type="text"]{
454 | width:3em;
455 | }
456 |
457 | input[type="number"]{
458 | width:3em;
459 | }
460 |
461 | label {
462 | text-align: right;
463 | }
464 |
465 | /* Pair of properties that are related */
466 | .pair {
467 | width: 75%;
468 | text-align: left;
469 | align: left;
470 | }
471 |
472 | .item1 {
473 | width: 50%;
474 | }
475 |
476 | .item2 {
477 | width: 50%;
478 | }
479 |
480 | input[name="x_offset"] {
481 | width: 2em;
482 | }
483 |
484 | input[name="y_offset"] {
485 | width: 2em;
486 | }
487 |
488 | input[name="send_symbol"] {
489 | width: 8em;
490 | }
491 |
492 | input[name="receive_symbol"] {
493 | width: 8em;
494 | }
495 |
496 | input[name="label"] {
497 | width: 8em;
498 | }
499 |
500 | input[name="font_size"] {
501 | width: 3em;
502 | }
503 |
504 | input[name="startup_flags"] {
505 | width: 16em;
506 | }
507 |
508 | /* Canvas dialog */
509 |
510 | div.x-scale {
511 | padding: 3px;
512 | text-align: center;
513 | }
514 |
515 | div.gop-range {
516 | }
517 |
518 | div.y1 {
519 | text-align: center;
520 | padding: 3px;
521 | }
522 |
523 | div.x1 {
524 | text-align: center;
525 | padding: 3px;
526 | }
527 |
528 | div.y2 {
529 | text-align: center;
530 | padding: 3px;
531 | }
532 |
533 | .disabled {
534 | color: #aaa;
535 | }
536 |
537 | /* Preferences dialog */
538 |
539 | #prefs_html_element {
540 | /* height: 100%; */
541 | margin: 0px;
542 | padding: 0px;
543 | height: 100vh;
544 | }
545 |
546 | .prefs_body {
547 | padding: 0px;
548 | }
549 |
550 | #prefs_container {
551 | display: table;
552 | }
553 |
554 | /* Main tab widget */
555 |
556 | /* All the display, width, and height settings below are a house of cards.
557 | I don't have the schooling to actually predict how all these CSS elements
558 | work together to create the whole. I just fudged around until I found a
559 | way to get the buttons anchored at the bottom of the dialog without
560 | triggering scrollbars to appear. If someone knows a way to do it "right"
561 | without becoming an order of magnitude more complex, do feel free... */
562 | .prefs_tab_group {
563 | display: table;
564 | width: 90%;
565 | }
566 |
567 | /* Configure the radio buttons to hide off-screen */
568 | .prefs_tab {
569 | position: absolute;
570 | left:-100px;
571 | top:-100px;
572 | }
573 |
574 | /* Configure labels to look like tabs */
575 | .prefs_tab + label {
576 | /* inline-block such that the label can be given dimensions */
577 | display: inline-block;
578 | /* A nice curved border around the tab */
579 | border: 1px solid #bbb;
580 | border-top-left-radius: 5px;
581 | border-top-right-radius: 5px;
582 | /* the bottom border is handled by the tab content div */
583 | border-bottom: 0;
584 | /* Padding around tab text */
585 | padding: 5px 10px;
586 | /* put a small margin to the left to make the first tab clear */
587 | margin-left: 4px;
588 | margin-top: 8px;
589 | margin-bottom: 0px;
590 | /* Set the background color to default gray (non-selected tab) */
591 | background-color:#ececec;
592 | }
593 |
594 | /* Focused tabs */
595 | .prefs_tab:focus + label {
596 | border: 1px dashed #bbb;
597 | }
598 |
599 | /* Checked tabs must be white with the bottom border removed */
600 | .prefs_tab:checked + label {
601 | background-color: #f3f3f3;
602 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
603 | border-bottom: 1px solid #f3f3f3;
604 | margin-bottom: -1px;
605 | }
606 |
607 | /* The tab content must fill the widgets size and have a nice border */
608 | .prefs_tab_group > div {
609 | display: none;
610 | border-top: 1px solid #ddd;
611 | padding: 0px;
612 | margin: 0px;
613 | height: 100%;
614 | }
615 |
616 | /* This matches tabs displaying to their associated radio inputs */
617 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
618 | display: table;
619 | padding: 8px;
620 | line-height: 20px;
621 | width: 100%;
622 | height: 78vh;
623 | }
624 |
625 | .tab_settings {
626 | padding-top: 8px;
627 | }
628 |
629 | /* Sample rate input */
630 | input[name="rate"] {
631 | width: 4em;
632 | }
633 |
634 | #prefs_buttons {
635 | display: table;
636 | height: 10vh;
637 | padding: 0px;
638 | margin: 0px;
639 | margin-top: -10px;
640 | margin-bottom: -10px;
641 | padding: 30px;
642 | }
643 |
--------------------------------------------------------------------------------
/css/strongbad.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #4bd046;
26 | color: black;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | background: black;
52 | color: #4bd046;
53 | }
54 |
55 | /* The console API allows classes for different types of messages to print.
56 | Currently the only class is "error". More may be added, especially once
57 | we port the "loglevel" functionality that was available in Pd Extended. */
58 | #console_bottom .error {
59 | color: #cc9933;
60 | }
61 |
62 | #console_bottom .error a {
63 | color: #ccc;
64 | }
65 |
66 | /* Find bar */
67 |
68 | #console_find label, #canvas_find label {
69 | font-family: "DejaVu Sans", sans-serif;
70 | font-size: 10pt;
71 | }
72 |
73 | /* marks for matches to console_find */
74 | mark {
75 | background: white !important;
76 | padding: 0 !important;
77 | }
78 |
79 | mark.console_find_current.console_find_highlighted,
80 | mark.console_find_current {
81 | background: yellow !important;
82 | }
83 |
84 | mark.console_find_highlighted {
85 | background: #6bd4e6 !important;
86 | }
87 |
88 | #console_find {
89 | width: 100%;
90 | height: 1em;
91 | padding: 0.2em;
92 | background: silver;
93 | position: fixed;
94 | bottom: 0;
95 | left: 0;
96 | }
97 |
98 | /* Pure Data Patch Window (aka canvas) */
99 |
100 | /* patch font and background color. (Note: margin needs to stay at zero.) */
101 | .patch_body {
102 | background-color: black;
103 | }
104 |
105 | #selection_rectangle {
106 | stroke: #53b83b;
107 | }
108 |
109 | /* The outline to show the visible area for a Graph-On-Parent canvas,
110 | i.e., the "red rectangle" */
111 | .gop_rect {
112 | fill: none;
113 | stroke: red;
114 | stroke-opacity: 0.6;
115 | }
116 |
117 | .cord.signal {
118 | stroke-width: 2;
119 | stroke: green;
120 | }
121 |
122 | .cord.control {
123 | stroke-width: 1;
124 | stroke: green;
125 | }
126 |
127 | /* selected connection between objects */
128 | .cord.signal.selected_line,
129 | .cord.control.selected_line,
130 | #newcord {
131 | stroke: #53b83b;
132 | }
133 |
134 | #cord_inspector_rect {
135 | fill: black;
136 | stroke: black;
137 | }
138 |
139 | #cord_inspector_text {
140 | fill: white;
141 | }
142 |
143 | #cord_inspector_text.flash {
144 | fill: #e87216;
145 | }
146 |
147 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
148 | .box_text {
149 | fill: #4bd046;
150 | }
151 |
152 | /* hyperlinks: for now, just pddplink and helplink */
153 | .pd_link text {
154 | fill: #4bd046;
155 | }
156 |
157 | .pd_link text:hover {
158 | fill: red;
159 | }
160 |
161 | .pd_link.selected text {
162 | fill: white;
163 | }
164 |
165 | #new_object_textentry {
166 | /* max-width: 10ch; */
167 | min-width: 3ch;
168 | position: absolute;
169 | display: table-cell;
170 | padding: 3px 2px 3px 2px;
171 | /* box-shadow: inset 1px 0px 0px 1px #000; */
172 | color: #4bd046;
173 | background-color: transparent;
174 | white-space: pre-wrap;
175 | overflow-wrap: break-word;
176 | -webkit-margin-before: 0px;
177 | }
178 |
179 | #new_object_textentry.obj {
180 | outline: 1px solid #0b560b;
181 | }
182 |
183 | #new_object_textentry.msg {
184 | outline: 0px solid #0b560b;
185 | background-image: url(../msg-box.svg);
186 | }
187 |
188 | p.msg::after {
189 | content: "";
190 | height: 100%;
191 | width: 5px;
192 | background-image: url(../msg-box-flag.svg);
193 | position: absolute;
194 | top: 0%;
195 | left: 100%;
196 | }
197 |
198 | /* not sure what this is doing here... */
199 | text {
200 | // fill: red;
201 | //cursor: default;
202 | }
203 |
204 | /* not sure if this is still needed */
205 | .selected_border {
206 | stroke: blue;
207 | stroke-dasharray: none;
208 | stroke-width: 1;
209 | }
210 |
211 | .msg .border {
212 | stroke: #0b560b;
213 | fill: black;
214 | }
215 |
216 | /* state of msg box when clicking it */
217 | .msg.flashed .border {
218 | stroke-width: 4;
219 | }
220 |
221 | /* atom box */
222 | .atom .border {
223 | stroke: #0b560b;
224 | fill: black;
225 | }
226 |
227 | /* for dropdown box we want to visually distinguish boxes that output
228 | the index from boxes that output the value. For now we do that by
229 | stroking the arrow for boxes that output an index. */
230 | .atom .index_arrow {
231 | stroke: #4bd046;
232 | stroke-width: 1;
233 | fill: none;
234 | }
235 |
236 | .atom .value_arrow {
237 | fill: #4bd046;
238 | }
239 |
240 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
241 | .atom.activated text {
242 | fill: red;
243 | }
244 |
245 | #dropdown_list {
246 | position: absolute;
247 | border-width: 1px;
248 | border-style: solid;
249 | border-color: #0b560b;
250 | cursor: pointer;
251 | color: #4bd046;
252 | box-shadow: 1px 1px 1px 1px #0b560b;
253 | overflow-y: auto;
254 | }
255 |
256 | #dropdown_list ol {
257 | list-style-position: inside;
258 | margin: 0;
259 | padding: 0;
260 | background: black;
261 | }
262 |
263 | #dropdown_list li {
264 | list-style-type: none;
265 | padding: 5px;
266 | }
267 |
268 | #dropdown_list li.highlighted {
269 | background: #4bd046;
270 | color: black;
271 | }
272 |
273 | .obj .border {
274 | fill: black;
275 | stroke: #0b560b;
276 | }
277 |
278 | .comment .border {
279 | fill: none;
280 | }
281 |
282 | svg[id^="patchsvg"].editmode .comment .border {
283 | stroke: #0b560b;
284 | stroke-dasharray: 8 4;
285 | }
286 |
287 | /* A little hack for special canvas of [cnv].
288 | All other iemguis have a black border, but
289 | [cnv] sets its selection rectangle to the
290 | user-supplied fill color when the object
291 | isn't selected */
292 | .iemgui .border:not(.mycanvas_border) {
293 | stroke: #0b560b;
294 | }
295 |
296 | .graph .border {
297 | stroke: #777;
298 | fill: none;
299 | }
300 |
301 | /* Graph (or subpatch) that has been opened to inspect its contents */
302 | .graph.has_window .border {
303 | stroke: #0b560b;
304 | fill: #0b560b;
305 | }
306 |
307 | /* border color for selected objects
308 | * an element with the class "border"
309 | * the element is contained within a parent element of class "selected"
310 | * that parent element is not in class "gop"
311 | in plain English:
312 | This lets us highlight an object's border, unless it is inside a gop
313 | canvas.
314 | */
315 | :not(.gop).selected .border {
316 | stroke: green;
317 | display: inline;
318 | }
319 |
320 | /* text inside selected objects */
321 | :not(.gop).selected text {
322 | fill: green;
323 | }
324 |
325 | /* for an object that didn't create */
326 | .obj .border.broken_border {
327 | fill: transparent;
328 | stroke: #f00;
329 | stroke-dasharray: 3 2;
330 | }
331 |
332 | /* control inlet */
333 | .xlet_control {
334 | stroke: green;
335 | fill: #53b83b;
336 | // stroke-width: 1;
337 | }
338 |
339 | /* signal inlet */
340 | .xlet_signal {
341 | stroke: green;
342 | fill: #53b83b;
343 | stroke-width: 1;
344 | }
345 |
346 | /* iemgui inlet or outlet */
347 | .xlet_iemgui {
348 | stroke: green;
349 | fill: #0b560b;
350 | stroke-width: 1;
351 | }
352 |
353 | /* text label for an iemgui */
354 | .iemgui_label_selected {
355 | fill: blue;
356 | }
357 |
358 | /* test of xlet hover animation... this should
359 | probably use the web animation API instead. That
360 | way the animation won't get cut off when you
361 | move off the object */
362 | @-webkit-keyframes fizzle {
363 | 0% {
364 | stroke-width: 1;
365 | stroke-opacity: 1;
366 | rx: 1;
367 | ry: 1;
368 | }
369 | 100% {
370 | stroke-width: 20;
371 | stroke-opacity: 0.2;
372 | rx: 50;
373 | ry: 50;
374 | }
375 | }
376 |
377 | /* can't remember why this was tagged !important */
378 | .xlet_selected {
379 | stroke: #53b83b !important;
380 | fill: green;
381 | -webkit-animation: fizzle 0.5s linear 1;
382 | }
383 |
384 | #canvas_find {
385 | width: 100%;
386 | height: 1em;
387 | padding: 3px;
388 | background: silver;
389 | position: fixed;
390 | bottom: 0;
391 | left: 0;
392 | }
393 |
394 | /* Search dialog */
395 |
396 | .search_body {
397 | font-family: "DejaVu Sans", sans-serif;
398 | font-size: 10pt;
399 | padding: 8px;
400 | }
401 |
402 | /* Common to all dialogs */
403 |
404 | .dialog_body {
405 | font-family: "DejaVu Sans", sans-serif;
406 | font-size: 10pt;
407 | background-color: #f3f3f3;
408 | }
409 |
410 | .submit_buttons {
411 | text-align: center;
412 | padding: 8px;
413 | }
414 |
415 | fieldset {
416 | background-color:#eeeeee;
417 | border-radius:3px;
418 | border:2px solid black;
419 | margin-left:auto;
420 | margin-right:auto;
421 | padding: 10px;
422 | }
423 |
424 | .hidden {
425 | display: none;
426 | }
427 |
428 | .container{
429 | display: none;
430 | }
431 |
432 | /* Iemgui dialog */
433 |
434 | input[type="text"]{
435 | width:3em;
436 | }
437 |
438 | input[type="number"]{
439 | width:3em;
440 | }
441 |
442 | label {
443 | text-align: right;
444 | }
445 |
446 | /* Pair of properties that are related */
447 | .pair {
448 | width: 75%;
449 | text-align: left;
450 | align: left;
451 | }
452 |
453 | .item1 {
454 | width: 50%;
455 | }
456 |
457 | .item2 {
458 | width: 50%;
459 | }
460 |
461 | input[name="x_offset"] {
462 | width: 2em;
463 | }
464 |
465 | input[name="y_offset"] {
466 | width: 2em;
467 | }
468 |
469 | input[name="send_symbol"] {
470 | width: 8em;
471 | }
472 |
473 | input[name="receive_symbol"] {
474 | width: 8em;
475 | }
476 |
477 | input[name="label"] {
478 | width: 8em;
479 | }
480 |
481 | input[name="font_size"] {
482 | width: 3em;
483 | }
484 |
485 | input[name="startup_flags"] {
486 | width: 16em;
487 | }
488 |
489 | /* Canvas dialog */
490 |
491 | div.x-scale {
492 | padding: 3px;
493 | text-align: center;
494 | }
495 |
496 | div.gop-range {
497 | }
498 |
499 | div.y1 {
500 | text-align: center;
501 | padding: 3px;
502 | }
503 |
504 | div.x1 {
505 | text-align: center;
506 | padding: 3px;
507 | }
508 |
509 | div.y2 {
510 | text-align: center;
511 | padding: 3px;
512 | }
513 |
514 | .disabled {
515 | color: #aaa;
516 | }
517 |
518 | /* Preferences dialog */
519 |
520 | #prefs_html_element {
521 | /* height: 100%; */
522 | margin: 0px;
523 | padding: 0px;
524 | height: 100vh;
525 | }
526 |
527 | .prefs_body {
528 | padding: 0px;
529 | }
530 |
531 | #prefs_container {
532 | display: table;
533 | }
534 |
535 | /* Main tab widget */
536 |
537 | /* All the display, width, and height settings below are a house of cards.
538 | I don't have the schooling to actually predict how all these CSS elements
539 | work together to create the whole. I just fudged around until I found a
540 | way to get the buttons anchored at the bottom of the dialog without
541 | triggering scrollbars to appear. If someone knows a way to do it "right"
542 | without becoming an order of magnitude more complex, do feel free... */
543 | .prefs_tab_group {
544 | display: table;
545 | width: 90%;
546 | }
547 |
548 | /* Configure the radio buttons to hide off-screen */
549 | .prefs_tab {
550 | position: absolute;
551 | left:-100px;
552 | top:-100px;
553 | }
554 |
555 | /* Configure labels to look like tabs */
556 | .prefs_tab + label {
557 | /* inline-block such that the label can be given dimensions */
558 | display: inline-block;
559 | /* A nice curved border around the tab */
560 | border: 1px solid #bbb;
561 | border-top-left-radius: 5px;
562 | border-top-right-radius: 5px;
563 | /* the bottom border is handled by the tab content div */
564 | border-bottom: 0;
565 | /* Padding around tab text */
566 | padding: 5px 10px;
567 | /* put a small margin to the left to make the first tab clear */
568 | margin-left: 4px;
569 | margin-top: 8px;
570 | margin-bottom: 0px;
571 | /* Set the background color to default gray (non-selected tab) */
572 | background-color:#ececec;
573 | }
574 |
575 | /* Focused tabs */
576 | .prefs_tab:focus + label {
577 | border: 1px dashed #bbb;
578 | }
579 |
580 | /* Checked tabs must be white with the bottom border removed */
581 | .prefs_tab:checked + label {
582 | background-color: #f3f3f3;
583 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
584 | border-bottom: 1px solid #f3f3f3;
585 | margin-bottom: -1px;
586 | }
587 |
588 | /* The tab content must fill the widgets size and have a nice border */
589 | .prefs_tab_group > div {
590 | display: none;
591 | border-top: 1px solid #ddd;
592 | padding: 0px;
593 | margin: 0px;
594 | height: 100%;
595 | }
596 |
597 | /* This matches tabs displaying to their associated radio inputs */
598 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
599 | display: table;
600 | padding: 8px;
601 | line-height: 20px;
602 | width: 100%;
603 | height: 78vh;
604 | }
605 |
606 | .tab_settings {
607 | padding-top: 8px;
608 | }
609 |
610 | /* Sample rate input */
611 | input[name="rate"] {
612 | width: 4em;
613 | }
614 |
615 | #prefs_buttons {
616 | display: table;
617 | height: 10vh;
618 | padding: 0px;
619 | margin: 0px;
620 | margin-top: -10px;
621 | margin-bottom: -10px;
622 | padding: 30px;
623 | }
624 |
--------------------------------------------------------------------------------
/css/subdued.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #c3c3c3;
26 | color: black;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | background-color: #c0dcc0;
52 | }
53 |
54 | /* The console API allows classes for different types of messages to print.
55 | Currently the only class is "error". More may be added, especially once
56 | we port the "loglevel" functionality that was available in Pd Extended. */
57 | #console_bottom .error {
58 | color: black;
59 | }
60 |
61 | #console_bottom .error a {
62 | color: black;
63 | font-weight: 600;
64 | }
65 |
66 | /* Find bar */
67 |
68 | #console_find label, #canvas_find label {
69 | font-family: "DejaVu Sans", sans-serif;
70 | font-size: 10pt;
71 | }
72 |
73 | /* marks for matches to console_find */
74 | mark {
75 | background: white !important;
76 | padding: 0 !important;
77 | }
78 |
79 | mark.console_find_current.console_find_highlighted,
80 | mark.console_find_current {
81 | background: yellow !important;
82 | }
83 |
84 | mark.console_find_highlighted {
85 | background: #6bd4e6 !important;
86 | }
87 |
88 | #console_find {
89 | width: 100%;
90 | height: 1em;
91 | padding: 0.2em;
92 | background: silver;
93 | position: fixed;
94 | bottom: 0;
95 | left: 0;
96 | }
97 |
98 | /* Pure Data Patch Window (aka canvas) */
99 |
100 | /* patch font and background color. (Note: margin needs to stay at zero.) */
101 | .patch_body {
102 | background-color: #c0dcc0;
103 | }
104 |
105 | #selection_rectangle {
106 | stroke: #333333;
107 | }
108 |
109 | /* The outline to show the visible area for a Graph-On-Parent canvas,
110 | i.e., the "red rectangle" */
111 | .gop_rect {
112 | fill: none;
113 | stroke: blue;
114 | stroke-opacity: 0.4;
115 | }
116 |
117 | .cord.signal {
118 | stroke-width: 2;
119 | stroke: #666666;
120 | }
121 |
122 | .cord.control {
123 | stroke-width: 1;
124 | stroke: #333333;
125 | }
126 |
127 | /* selected connection between objects */
128 | .cord.signal.selected_line,
129 | .cord.control.selected_line,
130 | #newcord {
131 | stroke: blue;
132 | }
133 |
134 | #cord_inspector_rect {
135 | fill: black;
136 | stroke: black;
137 | }
138 |
139 | #cord_inspector_text {
140 | fill: white;
141 | }
142 |
143 | #cord_inspector_text.flash {
144 | fill: #e87216;
145 | }
146 |
147 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
148 | .box_text {
149 | fill: black;
150 | }
151 |
152 | /* hyperlinks: for now, just pddplink and helplink */
153 | .pd_link text {
154 | fill: blue;
155 | }
156 |
157 | .pd_link text:hover {
158 | fill: red;
159 | }
160 |
161 | .pd_link.selected text {
162 | fill: white;
163 | }
164 |
165 | #new_object_textentry {
166 | /* max-width: 10ch; */
167 | min-width: 3ch;
168 | position: absolute;
169 | display: table-cell;
170 | padding: 3px 2px 3px 2px;
171 | /* box-shadow: inset 1px 0px 0px 1px #000; */
172 | background-color: transparent;
173 | white-space: pre-wrap;
174 | overflow-wrap: break-word;
175 | -webkit-margin-before: 0px;
176 | }
177 |
178 | #new_object_textentry.obj {
179 | outline: 1px solid blue;
180 | }
181 |
182 | #new_object_textentry.msg {
183 | outline: 0px solid blue;
184 | background-image: url(../msg-box.svg);
185 | }
186 |
187 | p.msg::after {
188 | content: "";
189 | height: 100%;
190 | width: 5px;
191 | background-image: url(../msg-box-flag.svg);
192 | position: absolute;
193 | top: 0%;
194 | left: 100%;
195 | }
196 |
197 | /* not sure what this is doing here... */
198 | text {
199 | // fill: red;
200 | //cursor: default;
201 | }
202 |
203 | /* not sure if this is still needed */
204 | .selected_border {
205 | stroke: blue;
206 | stroke-dasharray: none;
207 | stroke-width: 1;
208 | }
209 |
210 | .msg .border {
211 | stroke: #666666;
212 | fill: #c0dcc0;
213 | }
214 |
215 | /* state of msg box when clicking it */
216 | .msg.flashed .border {
217 | stroke-width: 4;
218 | }
219 |
220 | /* atom box */
221 | .atom .border {
222 | stroke: #b1d3b1;
223 | fill: #9fc79f;
224 | }
225 |
226 | /* for dropdown box we want to visually distinguish boxes that output
227 | the index from boxes that output the value. For now we do that by
228 | stroking the arrow for boxes that output an index. For boxes that
229 | output the value we don't need a CSS rule, as the arrow will be filled
230 | black by default */
231 | .atom .index_arrow {
232 | stroke: black;
233 | stroke-width: 1;
234 | fill: none;
235 | }
236 |
237 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
238 | .atom.activated text {
239 | fill: red;
240 | }
241 |
242 | #dropdown_list {
243 | position: absolute;
244 | border-width: 1px;
245 | border-style: solid;
246 | border-color: #b1d3b1;
247 | cursor: pointer;
248 | overflow-y: auto;
249 | }
250 |
251 | #dropdown_list ol {
252 | list-style-position: inside;
253 | margin: 0;
254 | padding: 0;
255 | background: #9fc79f;
256 | }
257 |
258 | #dropdown_list li {
259 | list-style-type: none;
260 | padding: 5px;
261 | }
262 |
263 | #dropdown_list li.highlighted {
264 | background: #c3c3c3;
265 | }
266 |
267 | .obj .border {
268 | fill: #c0dcc0;
269 | stroke: #666666;
270 | }
271 |
272 | .comment .border {
273 | fill: none;
274 | }
275 |
276 | svg[id^="patchsvg"].editmode .comment .border {
277 | stroke: #777;
278 | stroke-dasharray: 8 4;
279 | }
280 |
281 | /* A little hack for special canvas of [cnv].
282 | All other iemguis have a black border, but
283 | [cnv] sets its selection rectangle to the
284 | user-supplied fill color when the object
285 | isn't selected */
286 | .iemgui .border:not(.mycanvas_border) {
287 | stroke: #666666;
288 | }
289 |
290 | .graph .border {
291 | stroke: #777;
292 | fill: none;
293 | }
294 |
295 | /* Graph (or subpatch) that has been opened to inspect its contents */
296 | .graph.has_window .border {
297 | stroke: black;
298 | fill: #bbb;
299 | }
300 |
301 | /* border color for selected objects
302 | * an element with the class "border"
303 | * the element is contained within a parent element of class "selected"
304 | * that parent element is not in class "gop"
305 | in plain English:
306 | This lets us highlight an object's border, unless it is inside a gop
307 | canvas.
308 | */
309 | :not(.gop).selected .border {
310 | stroke: blue;
311 | display: inline;
312 | }
313 |
314 | /* text inside selected objects */
315 | :not(.gop).selected text {
316 | fill: blue;
317 | }
318 |
319 | /* for an object that didn't create */
320 | .obj .border.broken_border {
321 | fill: transparent;
322 | stroke: #f00;
323 | stroke-dasharray: 3 2;
324 | }
325 |
326 | /* control inlet */
327 | .xlet_control {
328 | stroke: #333333;
329 | fill: #333333;
330 | // stroke-width: 1;
331 | }
332 |
333 | /* signal inlet */
334 | .xlet_signal {
335 | stroke: #666666;
336 | fill: #666666;
337 | stroke-width: 1;
338 | }
339 |
340 | /* iemgui inlet or outlet */
341 | .xlet_iemgui {
342 | stroke: #666666;
343 | fill: #666666;
344 | stroke-width: 1;
345 | }
346 |
347 | /* text label for an iemgui */
348 | .iemgui_label_selected {
349 | fill: blue;
350 | }
351 |
352 | /* test of xlet hover animation... this should
353 | probably use the web animation API instead. That
354 | way the animation won't get cut off when you
355 | move off the object */
356 | @-webkit-keyframes fizzle {
357 | 0% {
358 | stroke-width: 1;
359 | stroke-opacity: 1;
360 | rx: 1;
361 | ry: 1;
362 | }
363 | 100% {
364 | stroke-width: 20;
365 | stroke-opacity: 0.2;
366 | rx: 50;
367 | ry: 50;
368 | }
369 | }
370 |
371 | /* can't remember why this was tagged !important */
372 | .xlet_selected {
373 | stroke: gray !important;
374 | fill: gray;
375 | -webkit-animation: fizzle 0.5s linear 1;
376 | }
377 |
378 | #canvas_find {
379 | width: 100%;
380 | height: 1em;
381 | padding: 3px;
382 | background: silver;
383 | position: fixed;
384 | bottom: 0;
385 | left: 0;
386 | }
387 |
388 | /* Dialog to ask to save the patch before quitting */
389 | #save_before_quit {
390 | background-color: #c0dcc0;
391 | border:1px solid black;
392 | padding: 12px;
393 | margin: 12px;
394 | box-shadow: 7px 7px 5px grey;
395 | }
396 |
397 | /* Search dialog */
398 |
399 | .search_body {
400 | font-family: "DejaVu Sans", sans-serif;
401 | font-size: 10pt;
402 | padding: 8px;
403 | }
404 |
405 | /* Common to all dialogs */
406 |
407 | .dialog_body {
408 | font-family: "DejaVu Sans", sans-serif;
409 | font-size: 10pt;
410 | background-color: #f3f3f3;
411 | }
412 |
413 | .submit_buttons {
414 | text-align: center;
415 | padding: 8px;
416 | }
417 |
418 | fieldset {
419 | background-color:#eeeeee;
420 | border-radius:3px;
421 | border:2px solid black;
422 | margin-left:auto;
423 | margin-right:auto;
424 | padding: 10px;
425 | }
426 |
427 | .hidden {
428 | display: none;
429 | }
430 |
431 | .container{
432 | display: none;
433 | }
434 |
435 | /* Iemgui dialog */
436 |
437 | input[type="text"]{
438 | width:3em;
439 | }
440 |
441 | input[type="number"]{
442 | width:3em;
443 | }
444 |
445 | label {
446 | text-align: right;
447 | }
448 |
449 | /* Pair of properties that are related */
450 | .pair {
451 | width: 75%;
452 | text-align: left;
453 | align: left;
454 | }
455 |
456 | .item1 {
457 | width: 50%;
458 | }
459 |
460 | .item2 {
461 | width: 50%;
462 | }
463 |
464 | input[name="x_offset"] {
465 | width: 2em;
466 | }
467 |
468 | input[name="y_offset"] {
469 | width: 2em;
470 | }
471 |
472 | input[name="send_symbol"] {
473 | width: 8em;
474 | }
475 |
476 | input[name="receive_symbol"] {
477 | width: 8em;
478 | }
479 |
480 | input[name="label"] {
481 | width: 8em;
482 | }
483 |
484 | input[name="font_size"] {
485 | width: 3em;
486 | }
487 |
488 | input[name="startup_flags"] {
489 | width: 16em;
490 | }
491 |
492 | /* Canvas dialog */
493 |
494 | div.x-scale {
495 | padding: 3px;
496 | text-align: center;
497 | }
498 |
499 | div.gop-range {
500 | }
501 |
502 | div.y1 {
503 | text-align: center;
504 | padding: 3px;
505 | }
506 |
507 | div.x1 {
508 | text-align: center;
509 | padding: 3px;
510 | }
511 |
512 | div.y2 {
513 | text-align: center;
514 | padding: 3px;
515 | }
516 |
517 | .disabled {
518 | color: #aaa;
519 | }
520 |
521 | /* Preferences dialog */
522 |
523 | #prefs_html_element {
524 | /* height: 100%; */
525 | margin: 0px;
526 | padding: 0px;
527 | height: 100vh;
528 | }
529 |
530 | .prefs_body {
531 | padding: 0px;
532 | }
533 |
534 | #prefs_container {
535 | display: table;
536 | }
537 |
538 | /* Main tab widget */
539 |
540 | /* All the display, width, and height settings below are a house of cards.
541 | I don't have the schooling to actually predict how all these CSS elements
542 | work together to create the whole. I just fudged around until I found a
543 | way to get the buttons anchored at the bottom of the dialog without
544 | triggering scrollbars to appear. If someone knows a way to do it "right"
545 | without becoming an order of magnitude more complex, do feel free... */
546 | .prefs_tab_group {
547 | display: table;
548 | width: 90%;
549 | }
550 |
551 | /* Configure the radio buttons to hide off-screen */
552 | .prefs_tab {
553 | position: absolute;
554 | left:-100px;
555 | top:-100px;
556 | }
557 |
558 | /* Configure labels to look like tabs */
559 | .prefs_tab + label {
560 | /* inline-block such that the label can be given dimensions */
561 | display: inline-block;
562 | /* A nice curved border around the tab */
563 | border: 1px solid #bbb;
564 | border-top-left-radius: 5px;
565 | border-top-right-radius: 5px;
566 | /* the bottom border is handled by the tab content div */
567 | border-bottom: 0;
568 | /* Padding around tab text */
569 | padding: 5px 10px;
570 | /* put a small margin to the left to make the first tab clear */
571 | margin-left: 4px;
572 | margin-top: 8px;
573 | margin-bottom: 0px;
574 | /* Set the background color to default gray (non-selected tab) */
575 | background-color:#ececec;
576 | }
577 |
578 | /* Focused tabs */
579 | .prefs_tab:focus + label {
580 | border: 1px dashed #bbb;
581 | }
582 |
583 | /* Checked tabs must be white with the bottom border removed */
584 | .prefs_tab:checked + label {
585 | background-color: #f3f3f3;
586 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
587 | border-bottom: 1px solid #f3f3f3;
588 | margin-bottom: -1px;
589 | }
590 |
591 | /* The tab content must fill the widgets size and have a nice border */
592 | .prefs_tab_group > div {
593 | display: none;
594 | border-top: 1px solid #ddd;
595 | padding: 0px;
596 | margin: 0px;
597 | height: 100%;
598 | }
599 |
600 | /* This matches tabs displaying to their associated radio inputs */
601 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
602 | display: table;
603 | padding: 8px;
604 | line-height: 20px;
605 | width: 100%;
606 | height: 78vh;
607 | }
608 |
609 | .tab_settings {
610 | padding-top: 8px;
611 | }
612 |
613 | /* Sample rate input */
614 | input[name="rate"] {
615 | width: 4em;
616 | }
617 |
618 | #prefs_buttons {
619 | display: table;
620 | height: 10vh;
621 | padding: 0px;
622 | margin: 0px;
623 | margin-top: -10px;
624 | margin-bottom: -10px;
625 | padding: 30px;
626 | }
627 |
--------------------------------------------------------------------------------
/css/vanilla.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: #c3c3c3;
26 | color: black;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | }
52 |
53 | /* The console API allows classes for different types of messages to print.
54 | Currently the only class is "error". More may be added, especially once
55 | we port the "loglevel" functionality that was available in Pd Extended. */
56 | #console_bottom .error {
57 | color: red;
58 | }
59 |
60 | /* Find bar */
61 |
62 | #console_find label, #canvas_find label {
63 | font-family: "DejaVu Sans", sans-serif;
64 | font-size: 10pt;
65 | }
66 |
67 | /* marks for matches to console_find */
68 | mark {
69 | background: white !important;
70 | padding: 0 !important;
71 | }
72 |
73 | mark.console_find_current.console_find_highlighted,
74 | mark.console_find_current {
75 | background: yellow !important;
76 | }
77 |
78 | mark.console_find_highlighted {
79 | background: #6bd4e6 !important;
80 | }
81 |
82 | #console_find {
83 | width: 100%;
84 | height: 1em;
85 | padding: 0.2em;
86 | background: silver;
87 | position: fixed;
88 | bottom: 0;
89 | left: 0;
90 | }
91 |
92 | /* Pure Data Patch Window (aka canvas) */
93 |
94 | /* canvas font and background color. (Note: margin needs to stay at zero.) */
95 | .patch_body {
96 | background-color: white;
97 | }
98 |
99 | #selection_rectangle {
100 | stroke: black;
101 | }
102 |
103 | /* The outline to show the visible area for a Graph-On-Parent canvas,
104 | i.e., the "red rectangle" */
105 | .gop_rect {
106 | fill: none;
107 | stroke: red;
108 | }
109 |
110 | .cord.signal {
111 | stroke-width: 2;
112 | stroke: black;
113 | }
114 |
115 | .cord.control {
116 | stroke-width: 1;
117 | stroke: black;
118 | }
119 |
120 | /* selected connection between objects */
121 | .cord.signal.selected_line,
122 | .cord.control.selected_line {
123 | stroke: blue;
124 | }
125 |
126 | #cord_inspector_rect {
127 | fill: black;
128 | stroke: black;
129 | }
130 |
131 | #cord_inspector_text {
132 | fill: white;
133 | }
134 |
135 | #cord_inspector_text.flash {
136 | fill: #e87216;
137 | }
138 |
139 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
140 | .box_text {
141 | fill: black;
142 | }
143 |
144 | /* hyperlinks: for now, just pddplink and helplink */
145 | .pd_link text {
146 | fill: blue;
147 | }
148 |
149 | .pd_link text:hover {
150 | fill: red;
151 | }
152 |
153 | .pd_link.selected text {
154 | fill: #e87216 !important;
155 | }
156 |
157 |
158 | #new_object_textentry {
159 | /* max-width: 10ch; */
160 | min-width: 3ch;
161 | position: absolute;
162 | display: table-cell;
163 | padding: 3px 2px 3px 2px;
164 | /* box-shadow: inset 1px 0px 0px 1px #000; */
165 | background-color: transparent;
166 | white-space: pre-wrap;
167 | overflow-wrap: break-word;
168 | -webkit-margin-before: 0px;
169 | }
170 |
171 | #new_object_textentry.obj {
172 | outline: 1px solid blue;
173 | }
174 |
175 | #new_object_textentry.msg {
176 | outline: 0px solid blue;
177 | background-image: url(../msg-box.svg);
178 | }
179 |
180 | p.msg::after {
181 | content: "";
182 | height: 100%;
183 | width: 5px;
184 | background-image: url(../msg-box-flag.svg);
185 | position: absolute;
186 | top: 0%;
187 | left: 100%;
188 | }
189 |
190 | /* not sure what this is doing here... */
191 | text {
192 | // fill: red;
193 | //cursor: default;
194 | }
195 |
196 | /* not sure if this is still needed */
197 | .selected_border {
198 | stroke: blue;
199 | stroke-dasharray: none;
200 | stroke-width: 1;
201 | }
202 |
203 | .msg .border {
204 | stroke: black;
205 | fill: none;
206 | }
207 |
208 | /* state of msg box when clicking it */
209 | .msg.flashed .border {
210 | stroke-width: 4;
211 | }
212 |
213 | /* atom box */
214 | .atom .border {
215 | stroke: black;
216 | fill: none;
217 | }
218 |
219 | /* for dropdown box we want to visually distinguish boxes that output
220 | the index from boxes that output the value. For now we do that by
221 | stroking the arrow for boxes that output an index. For boxes that
222 | output the value we don't need a CSS rule, as the arrow will be filled
223 | black by default */
224 | .atom .index_arrow {
225 | stroke: black;
226 | stroke-width: 1;
227 | fill: none;
228 | }
229 |
230 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
231 | .atom.activated text {
232 | fill: red;
233 | }
234 |
235 | #dropdown_list {
236 | position: absolute;
237 | border-width: 1px;
238 | border-style: solid;
239 | border-color: black;
240 | cursor: pointer;
241 | overflow-y: auto;
242 | }
243 |
244 | #dropdown_list ol {
245 | list-style-position: inside;
246 | margin: 0;
247 | padding: 0;
248 | background: white;
249 | }
250 |
251 | #dropdown_list li {
252 | list-style-type: none;
253 | padding: 5px;
254 | }
255 |
256 | #dropdown_list li.highlighted {
257 | background: #c3c3c3;
258 | }
259 |
260 | .obj .border {
261 | fill: none;
262 | stroke: black;
263 | }
264 |
265 | .comment .border {
266 | fill: none;
267 | }
268 |
269 | svg[id^="patchsvg"].editmode .comment .border {
270 | stroke: black;
271 | stroke-dasharray: 8 4;
272 | }
273 |
274 | /* A little hack for special canvas of [cnv].
275 | All other iemguis have a black border, but
276 | [cnv] sets its selection rectangle to the
277 | user-supplied fill color when the object
278 | isn't selected */
279 | .iemgui .border:not(.mycanvas_border) {
280 | stroke: black;
281 | }
282 |
283 | /* text inside selected objects */
284 | :not(.gop).selected text {
285 | fill: black;
286 | }
287 |
288 | .graph .border {
289 | stroke: black;
290 | fill: none;
291 | }
292 |
293 | /* Graph (or subpatch) that has been opened to inspect its contents */
294 | .graph.has_window .border {
295 | stroke: black;
296 | fill: none;
297 | }
298 |
299 | /* border color for selected objects
300 | * an element with the class "border"
301 | * the element is contained within a parent element of class "selected"
302 | * that parent element is not in class "gop"
303 | in plain English:
304 | This lets us highlight an object's border, unless it is inside a gop
305 | canvas.
306 | */
307 | :not(.gop).selected .border {
308 | stroke: blue;
309 | display: inline;
310 | }
311 |
312 | /* for an object that didn't create */
313 | .obj .border.broken_border {
314 | fill: none;
315 | stroke: #f00;
316 | stroke-dasharray: 3 2;
317 | }
318 |
319 | /* control inlet */
320 | .xlet_control {
321 | stroke: black;
322 | fill: black;
323 | // stroke-width: 1;
324 | }
325 |
326 | /* signal inlet */
327 | .xlet_signal {
328 | stroke: black;
329 | fill: black;
330 | stroke-width: 1;
331 | }
332 |
333 | /* iemgui inlet or outlet */
334 | .xlet_iemgui {
335 | stroke: black;
336 | fill: black;
337 | stroke-width: 1;
338 | }
339 |
340 | /* text label for an iemgui */
341 | .iemgui_label_selected {
342 | fill: blue;
343 | }
344 |
345 | /* test of xlet hover animation... this should
346 | probably use the web animation API instead. That
347 | way the animation won't get cut off when you
348 | move off the object */
349 | @-webkit-keyframes fizzle {
350 | 0% {
351 | stroke-width: 1;
352 | stroke-opacity: 1;
353 | rx: 1;
354 | ry: 1;
355 | }
356 | 100% {
357 | stroke-width: 20;
358 | stroke-opacity: 0.2;
359 | rx: 50;
360 | ry: 50;
361 | }
362 | }
363 |
364 | /* can't remember why this was tagged !important */
365 | .xlet_selected {
366 | stroke: purple !important;
367 | fill: purple;
368 | -webkit-animation: fizzle 0.5s linear 1;
369 | }
370 |
371 | #canvas_find {
372 | width: 100%;
373 | height: 1em;
374 | padding: 3px;
375 | background: silver;
376 | position: fixed;
377 | bottom: 0;
378 | left: 0;
379 | }
380 |
381 | /* Search dialog */
382 |
383 | .search_body {
384 | font-family: "DejaVu Sans", sans-serif;
385 | font-size: 10pt;
386 | padding: 8px;
387 | }
388 |
389 | /* Common to all dialogs */
390 |
391 | .dialog_body {
392 | font-family: "DejaVu Sans", sans-serif;
393 | font-size: 10pt;
394 | background-color: #f3f3f3;
395 | }
396 |
397 | .submit_buttons {
398 | text-align: center;
399 | padding: 8px;
400 | }
401 |
402 | fieldset {
403 | background-color:#eeeeee;
404 | border-radius:3px;
405 | border:2px solid black;
406 | margin-left:auto;
407 | margin-right:auto;
408 | padding: 10px;
409 | }
410 |
411 | .hidden {
412 | display: none;
413 | }
414 |
415 | .container{
416 | display: none;
417 | }
418 |
419 | /* Iemgui dialog */
420 |
421 | input[type="text"]{
422 | width:3em;
423 | }
424 |
425 | input[type="number"]{
426 | width:3em;
427 | }
428 |
429 | label {
430 | text-align: right;
431 | }
432 |
433 | /* Pair of properties that are related */
434 | .pair {
435 | width: 75%;
436 | text-align: left;
437 | align: left;
438 | }
439 |
440 | .item1 {
441 | width: 50%;
442 | }
443 |
444 | .item2 {
445 | width: 50%;
446 | }
447 |
448 | input[name="x_offset"] {
449 | width: 2em;
450 | }
451 |
452 | input[name="y_offset"] {
453 | width: 2em;
454 | }
455 |
456 | input[name="send_symbol"] {
457 | width: 8em;
458 | }
459 |
460 | input[name="receive_symbol"] {
461 | width: 8em;
462 | }
463 |
464 | input[name="label"] {
465 | width: 8em;
466 | }
467 |
468 | input[name="font_size"] {
469 | width: 3em;
470 | }
471 |
472 | input[name="startup_flags"] {
473 | width: 16em;
474 | }
475 |
476 | /* Canvas dialog */
477 |
478 | div.x-scale {
479 | padding: 3px;
480 | text-align: center;
481 | }
482 |
483 | div.gop-range {
484 | }
485 |
486 | div.y1 {
487 | text-align: center;
488 | padding: 3px;
489 | }
490 |
491 | div.x1 {
492 | text-align: center;
493 | padding: 3px;
494 | }
495 |
496 | div.y2 {
497 | text-align: center;
498 | padding: 3px;
499 | }
500 |
501 | .disabled {
502 | color: #aaa;
503 | }
504 |
505 | /* Preferences dialog */
506 |
507 | #prefs_html_element {
508 | /* height: 100%; */
509 | margin: 0px;
510 | padding: 0px;
511 | height: 100vh;
512 | }
513 |
514 | .prefs_body {
515 | padding: 0px;
516 | }
517 |
518 | #prefs_container {
519 | display: table;
520 | }
521 |
522 | /* Main tab widget */
523 |
524 | /* All the display, width, and height settings below are a house of cards.
525 | I don't have the schooling to actually predict how all these CSS elements
526 | work together to create the whole. I just fudged around until I found a
527 | way to get the buttons anchored at the bottom of the dialog without
528 | triggering scrollbars to appear. If someone knows a way to do it "right"
529 | without becoming an order of magnitude more complex, do feel free... */
530 | .prefs_tab_group {
531 | display: table;
532 | width: 90%;
533 | }
534 |
535 | /* Configure the radio buttons to hide off-screen */
536 | .prefs_tab {
537 | position: absolute;
538 | left:-100px;
539 | top:-100px;
540 | }
541 |
542 | /* Configure labels to look like tabs */
543 | .prefs_tab + label {
544 | /* inline-block such that the label can be given dimensions */
545 | display: inline-block;
546 | /* A nice curved border around the tab */
547 | border: 1px solid #bbb;
548 | border-top-left-radius: 5px;
549 | border-top-right-radius: 5px;
550 | /* the bottom border is handled by the tab content div */
551 | border-bottom: 0;
552 | /* Padding around tab text */
553 | padding: 5px 10px;
554 | /* put a small margin to the left to make the first tab clear */
555 | margin-left: 4px;
556 | margin-top: 8px;
557 | margin-bottom: 0px;
558 | /* Set the background color to default gray (non-selected tab) */
559 | background-color:#ececec;
560 | }
561 |
562 | /* Focused tabs */
563 | .prefs_tab:focus + label {
564 | border: 1px dashed #bbb;
565 | }
566 |
567 | /* Checked tabs must be white with the bottom border removed */
568 | .prefs_tab:checked + label {
569 | background-color: #f3f3f3;
570 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
571 | border-bottom: 1px solid #f3f3f3;
572 | margin-bottom: -1px;
573 | }
574 |
575 | /* The tab content must fill the widgets size and have a nice border */
576 | .prefs_tab_group > div {
577 | display: none;
578 | border-top: 1px solid #ddd;
579 | padding: 0px;
580 | margin: 0px;
581 | height: 100%;
582 | }
583 |
584 | /* This matches tabs displaying to their associated radio inputs */
585 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
586 | display: table;
587 | padding: 8px;
588 | line-height: 20px;
589 | width: 100%;
590 | height: 78vh;
591 | }
592 |
593 | .tab_settings {
594 | padding-top: 8px;
595 | }
596 |
597 | /* Sample rate input */
598 | input[name="rate"] {
599 | width: 4em;
600 | }
601 |
602 | #prefs_buttons {
603 | display: table;
604 | height: 10vh;
605 | padding: 0px;
606 | margin: 0px;
607 | margin-top: -10px;
608 | margin-bottom: -10px;
609 | padding: 30px;
610 | }
611 |
--------------------------------------------------------------------------------
/css/vanilla_inverted.css:
--------------------------------------------------------------------------------
1 | /* Global CSS */
2 |
3 | /*
4 | @font-face {
5 | font-family: "DejaVu Sans Mono";
6 | src: url("../DejaVuSansMono.ttf");
7 | }
8 | */
9 |
10 | body {
11 | margin: 0px;
12 | font-family: "DejaVu Sans Mono";
13 | }
14 |
15 | .noselect {
16 | -webkit-touch-callout: none;
17 | -webkit-user-select: none;
18 | -khtml-user-select: none;
19 | -moz-user-select: none;
20 | -ms-user-select: none;
21 | user-select: none;
22 | }
23 |
24 | ::selection {
25 | background: white;
26 | color: black;
27 | }
28 |
29 | /* The main Pd Window */
30 |
31 | #console_controls {
32 | background-color: LightGray;
33 | height: 50px;
34 | }
35 |
36 | #control_frame {
37 | padding: 12px;
38 | }
39 |
40 | #printout {
41 | margin: 8px;
42 | }
43 |
44 | #console_bottom {
45 | position: absolute;
46 | top: 50px;
47 | left: 0px;
48 | right: 0px;
49 | bottom: 0px;
50 | overflow-y: scroll;
51 | background: black;
52 | color: white;
53 | }
54 |
55 | /* The console API allows classes for different types of messages to print.
56 | Currently the only class is "error". More may be added, especially once
57 | we port the "loglevel" functionality that was available in Pd Extended. */
58 | #console_bottom .error {
59 | color: blue;
60 | }
61 |
62 | #console_bottom .error a {
63 | color: red;
64 | }
65 |
66 | /* Find bar */
67 |
68 | #console_find label, #canvas_find label {
69 | font-family: "DejaVu Sans", sans-serif;
70 | font-size: 10pt;
71 | }
72 |
73 | /* marks for matches to console_find */
74 | mark {
75 | background: white !important;
76 | padding: 0 !important;
77 | }
78 |
79 | mark.console_find_current.console_find_highlighted,
80 | mark.console_find_current {
81 | background: yellow !important;
82 | }
83 |
84 | mark.console_find_highlighted {
85 | background: #6bd4e6 !important;
86 | }
87 |
88 | #console_find {
89 | width: 100%;
90 | height: 1em;
91 | padding: 0.2em;
92 | background: silver;
93 | position: fixed;
94 | bottom: 0;
95 | left: 0;
96 | }
97 |
98 | /* Pure Data Patch Window (aka canvas) */
99 |
100 | /* canvas font and background color. (Note: margin needs to stay at zero.) */
101 | .patch_body {
102 | background-color: black;
103 | }
104 |
105 | #selection_rectangle {
106 | stroke: white;
107 | }
108 |
109 | /* The outline to show the visible area for a Graph-On-Parent canvas,
110 | i.e., the "red rectangle" */
111 | .gop_rect {
112 | fill: none;
113 | stroke: blue;
114 | stroke-opacity: 0.8;
115 | }
116 |
117 | .cord.signal {
118 | stroke-width: 2;
119 | stroke: white;
120 | }
121 |
122 | .cord.control {
123 | stroke-width: 1;
124 | stroke: white;
125 | }
126 |
127 | /* selected connection between objects */
128 | .cord.signal.selected_line,
129 | .cord.control.selected_line {
130 | stroke: blue;
131 | }
132 |
133 | #cord_inspector_rect {
134 | fill: white;
135 | stroke: white;
136 | }
137 |
138 | #cord_inspector_text {
139 | fill: black;
140 | }
141 |
142 | #cord_inspector_text.flash {
143 | fill: #e87216;
144 | }
145 |
146 | /* text inside boxes: message boxes, object boxes, graphs, comments, etc. */
147 | .box_text {
148 | fill: white;
149 | }
150 |
151 | /* hyperlinks: for now, just pddplink and helplink */
152 | .pd_link text {
153 | fill: white;
154 | }
155 |
156 | .pd_link text:hover {
157 | fill: red;
158 | }
159 |
160 | .pd_link.selected text {
161 | fill: yellow;
162 | }
163 |
164 | #bubbles {
165 | stroke: red;
166 | }
167 |
168 | #new_object_textentry {
169 | /* max-width: 10ch; */
170 | min-width: 3ch;
171 | position: absolute;
172 | display: table-cell;
173 | padding: 3px 2px 3px 2px;
174 | /* box-shadow: inset 1px 0px 0px 1px #000; */
175 | color: white; /* text color */
176 | background-color: transparent;
177 | white-space: pre-wrap;
178 | overflow-wrap: break-word;
179 | -webkit-margin-before: 0px;
180 | }
181 |
182 | #new_object_textentry.obj {
183 | outline: 1px solid yellow;
184 | }
185 |
186 | #new_object_textentry.msg {
187 | outline: 0px solid yellow;
188 | background-image: url(../msg-box.svg);
189 | }
190 |
191 | p.msg::after {
192 | content: "";
193 | height: 100%;
194 | width: 5px;
195 | background-image: url(../msg-box-flag.svg);
196 | position: absolute;
197 | top: 0%;
198 | left: 100%;
199 | }
200 |
201 | /* not sure what this is doing here... */
202 | text {
203 | // fill: red;
204 | //cursor: default;
205 | }
206 |
207 | /* not sure if this is still needed */
208 | .selected_border {
209 | stroke: blue;
210 | stroke-dasharray: none;
211 | stroke-width: 1;
212 | }
213 |
214 | .msg .border {
215 | stroke: white;
216 | fill: none;
217 | }
218 |
219 | /* state of msg box when clicking it */
220 | .msg.flashed .border {
221 | stroke-width: 4;
222 | }
223 |
224 | /* atom box */
225 | .atom .border {
226 | stroke: white;
227 | fill: none;
228 | }
229 |
230 | /* for dropdown box we want to visually distinguish boxes that output
231 | the index from boxes that output the value. For now we do that by
232 | stroking the arrow for boxes that output an index. For boxes that
233 | output the value we don't need a CSS rule, as the arrow will be filled
234 | black by default */
235 | .atom .index_arrow {
236 | stroke: white;
237 | stroke-width: 1;
238 | fill: none;
239 | }
240 |
241 | .atom .value_arrow {
242 | fill: white;
243 | }
244 |
245 | /* gatom "activated" text (i.e., when it has the keyboard focus) */
246 | .atom.activated text {
247 | fill: red;
248 | }
249 |
250 | #dropdown_list {
251 | position: absolute;
252 | border-width: 1px;
253 | border-style: solid;
254 | border-color: white;
255 | cursor: pointer;
256 | color: white;
257 | overflow-y: auto;
258 | }
259 |
260 | #dropdown_list ol {
261 | list-style-position: inside;
262 | margin: 0;
263 | padding: 0;
264 | background: black;
265 | }
266 |
267 | #dropdown_list li {
268 | list-style-type: none;
269 | padding: 5px;
270 | }
271 |
272 | #dropdown_list li.highlighted {
273 | background: #c3c3c3;
274 | color: black;
275 | }
276 |
277 | .obj .border {
278 | fill: none;
279 | stroke: white;
280 | }
281 |
282 | .comment .border {
283 | fill: none;
284 | }
285 |
286 | svg[id^="patchsvg"].editmode .comment .border {
287 | stroke: white;
288 | stroke-dasharray: 8 4;
289 | }
290 |
291 | /* A little hack for special canvas of [cnv].
292 | All other iemguis have a black border, but
293 | [cnv] sets its selection rectangle to the
294 | user-supplied fill color when the object
295 | isn't selected */
296 | .iemgui .border:not(.mycanvas_border) {
297 | stroke: white;
298 | }
299 |
300 | /* text inside selected objects */
301 | :not(.gop).selected text {
302 | fill: white;
303 | }
304 |
305 | .graph .border {
306 | stroke: white;
307 | fill: none;
308 | }
309 |
310 | /* Graph (or subpatch) that has been opened to inspect its contents */
311 | .graph.has_window .border {
312 | stroke: white;
313 | fill: gray;
314 | }
315 |
316 | /* border color for selected objects
317 | * an element with the class "border"
318 | * the element is contained within a parent element of class "selected"
319 | * that parent element is not in class "gop"
320 | in plain English:
321 | This lets us highlight an object's border, unless it is inside a gop
322 | canvas.
323 | */
324 | :not(.gop).selected .border {
325 | stroke: yellow;
326 | display: inline;
327 | }
328 |
329 | /* for an object that didn't create */
330 | .obj .border.broken_border {
331 | fill: none;
332 | stroke: #f00;
333 | stroke-dasharray: 3 2;
334 | }
335 |
336 | /* control inlet */
337 | .xlet_control {
338 | stroke: white;
339 | fill: white;
340 | // stroke-width: 1;
341 | }
342 |
343 | /* signal inlet */
344 | .xlet_signal {
345 | stroke: white;
346 | fill: white;
347 | stroke-width: 1;
348 | }
349 |
350 | /* iemgui inlet or outlet */
351 | .xlet_iemgui {
352 | stroke: white;
353 | fill: white;
354 | stroke-width: 1;
355 | }
356 |
357 | /* text label for an iemgui */
358 | .iemgui_label_selected {
359 | fill: blue;
360 | }
361 |
362 | /* test of xlet hover animation... this should
363 | probably use the web animation API instead. That
364 | way the animation won't get cut off when you
365 | move off the object */
366 | @-webkit-keyframes fizzle {
367 | 0% {
368 | stroke-width: 1;
369 | }
370 | 100% {
371 | stroke-width: 8;
372 | }
373 | }
374 |
375 | /* can't remember why this was tagged !important */
376 | .xlet_selected {
377 | stroke: gray !important;
378 | fill: gray;
379 | -webkit-animation: fizzle 0.5s linear 1;
380 | }
381 |
382 | #canvas_find {
383 | width: 100%;
384 | height: 1em;
385 | padding: 3px;
386 | background: silver;
387 | position: fixed;
388 | bottom: 0;
389 | left: 0;
390 | }
391 |
392 | /* Dialog to ask to save the patch before quitting */
393 | #save_before_quit {
394 | color: white;
395 | background-color: black;
396 | border:1px solid white;
397 | }
398 |
399 | /* Search dialog */
400 |
401 | .search_body {
402 | font-family: "DejaVu Sans", sans-serif;
403 | font-size: 10pt;
404 | padding: 8px;
405 | }
406 |
407 | /* Common to all dialogs */
408 |
409 | .dialog_body {
410 | font-family: "DejaVu Sans", sans-serif;
411 | font-size: 10pt;
412 | background-color: #f3f3f3;
413 | }
414 |
415 | .submit_buttons {
416 | text-align: center;
417 | padding: 8px;
418 | }
419 |
420 | fieldset {
421 | background-color:#eeeeee;
422 | border-radius:3px;
423 | border:2px solid black;
424 | margin-left:auto;
425 | margin-right:auto;
426 | padding: 10px;
427 | }
428 |
429 | .hidden {
430 | display: none;
431 | }
432 |
433 | .container{
434 | display: none;
435 | }
436 |
437 | /* Iemgui dialog */
438 |
439 | input[type="text"]{
440 | width:3em;
441 | }
442 |
443 | input[type="number"]{
444 | width:3em;
445 | }
446 |
447 | label {
448 | text-align: right;
449 | }
450 |
451 | /* Pair of properties that are related */
452 | .pair {
453 | width: 75%;
454 | text-align: left;
455 | align: left;
456 | }
457 |
458 | .item1 {
459 | width: 50%;
460 | }
461 |
462 | .item2 {
463 | width: 50%;
464 | }
465 |
466 | input[name="x_offset"] {
467 | width: 2em;
468 | }
469 |
470 | input[name="y_offset"] {
471 | width: 2em;
472 | }
473 |
474 | input[name="send_symbol"] {
475 | width: 8em;
476 | }
477 |
478 | input[name="receive_symbol"] {
479 | width: 8em;
480 | }
481 |
482 | input[name="label"] {
483 | width: 8em;
484 | }
485 |
486 | input[name="font_size"] {
487 | width: 3em;
488 | }
489 |
490 | input[name="startup_flags"] {
491 | width: 16em;
492 | }
493 |
494 | /* Canvas dialog */
495 |
496 | div.x-scale {
497 | padding: 3px;
498 | text-align: center;
499 | }
500 |
501 | div.gop-range {
502 | }
503 |
504 | div.y1 {
505 | text-align: center;
506 | padding: 3px;
507 | }
508 |
509 | div.x1 {
510 | text-align: center;
511 | padding: 3px;
512 | }
513 |
514 | div.y2 {
515 | text-align: center;
516 | padding: 3px;
517 | }
518 |
519 | .disabled {
520 | color: #aaa;
521 | }
522 |
523 | /* Preferences dialog */
524 |
525 | #prefs_html_element {
526 | /* height: 100%; */
527 | margin: 0px;
528 | padding: 0px;
529 | height: 100vh;
530 | }
531 |
532 | .prefs_body {
533 | padding: 0px;
534 | }
535 |
536 | #prefs_container {
537 | display: table;
538 | }
539 |
540 | /* Main tab widget */
541 |
542 | /* All the display, width, and height settings below are a house of cards.
543 | I don't have the schooling to actually predict how all these CSS elements
544 | work together to create the whole. I just fudged around until I found a
545 | way to get the buttons anchored at the bottom of the dialog without
546 | triggering scrollbars to appear. If someone knows a way to do it "right"
547 | without becoming an order of magnitude more complex, do feel free... */
548 | .prefs_tab_group {
549 | display: table;
550 | width: 90%;
551 | }
552 |
553 | /* Configure the radio buttons to hide off-screen */
554 | .prefs_tab {
555 | position: absolute;
556 | left:-100px;
557 | top:-100px;
558 | }
559 |
560 | /* Configure labels to look like tabs */
561 | .prefs_tab + label {
562 | /* inline-block such that the label can be given dimensions */
563 | display: inline-block;
564 | /* A nice curved border around the tab */
565 | border: 1px solid #bbb;
566 | border-top-left-radius: 5px;
567 | border-top-right-radius: 5px;
568 | /* the bottom border is handled by the tab content div */
569 | border-bottom: 0;
570 | /* Padding around tab text */
571 | padding: 5px 10px;
572 | /* put a small margin to the left to make the first tab clear */
573 | margin-left: 4px;
574 | margin-top: 8px;
575 | margin-bottom: 0px;
576 | /* Set the background color to default gray (non-selected tab) */
577 | background-color:#ececec;
578 | }
579 |
580 | /* Focused tabs */
581 | .prefs_tab:focus + label {
582 | border: 1px dashed #bbb;
583 | }
584 |
585 | /* Checked tabs must be white with the bottom border removed */
586 | .prefs_tab:checked + label {
587 | background-color: #f3f3f3;
588 | text-shadow: 1px 0px 0px; /* substitute for "bold" to retain div width */
589 | border-bottom: 1px solid #f3f3f3;
590 | margin-bottom: -1px;
591 | }
592 |
593 | /* The tab content must fill the widgets size and have a nice border */
594 | .prefs_tab_group > div {
595 | display: none;
596 | border-top: 1px solid #ddd;
597 | padding: 0px;
598 | margin: 0px;
599 | height: 100%;
600 | }
601 |
602 | /* This matches tabs displaying to their associated radio inputs */
603 | .tab1:checked ~ .tab1, .tab2:checked ~ .tab2, .tab3:checked ~ .tab3, .tab4:checked ~ .tab4 {
604 | display: table;
605 | padding: 8px;
606 | line-height: 20px;
607 | width: 100%;
608 | height: 78vh;
609 | }
610 |
611 | .tab_settings {
612 | padding-top: 8px;
613 | }
614 |
615 | /* Sample rate input */
616 | input[name="rate"] {
617 | width: 4em;
618 | }
619 |
620 | #prefs_buttons {
621 | display: table;
622 | height: 10vh;
623 | padding: 0px;
624 | margin: 0px;
625 | margin-top: -10px;
626 | margin-bottom: -10px;
627 | padding: 30px;
628 | }
629 |
--------------------------------------------------------------------------------
/css/webapp/webapp.css:
--------------------------------------------------------------------------------
1 | .console-webapp {
2 | position: relative;
3 | top: 0px;
4 | left: 0px;
5 | right: 0px;
6 | bottom: 0px;
7 | overflow-y: scroll;
8 | }
9 |
10 | #container {
11 | overflow: hidden;
12 | }
13 |
14 | #console_bottom{
15 | position: relative !important;
16 | top: 0px !important;
17 | }
18 |
19 | .console-find-webapp {
20 | position: relative !important;
21 | background-color: transparent !important;
22 | right: 0px;
23 | }
24 |
25 | /** Rotate */
26 | .rotate{
27 | transform: rotate(180deg);
28 | }
29 |
30 | .rotate-transition {
31 | transition: transform 0.3s linear;
32 | }
33 |
34 | .collapsing {
35 | visibility: hidden;
36 | }
37 |
38 | .highlight-find{
39 | margin-left: 10px;
40 | }
41 |
42 | #canvas_container{
43 | display: flex !important;
44 | background-color: red !important;
45 | }
46 |
47 | #sidebar-collapse{
48 | position: absolute;
49 | top: 0px;
50 | left: 0px;
51 | z-index: 5;
52 | color: #007BFF;
53 | cursor: pointer;
54 | }
55 |
56 | #sidebar-files ul{
57 | list-style-type: none;
58 | cursor: pointer;
59 | padding: 0;
60 | }
61 |
62 | #sidebar-files ul li{
63 | padding-bottom: 10px;
64 |
65 | }
66 |
67 | #sidebar-files ul li a:hover {
68 | color: #007BFF;
69 | }
70 |
71 | #file-icons {
72 | display: none;
73 | }
74 |
75 | #list-item:hover > div {
76 | display: flex;
77 | display: inline-block;
78 | }
79 |
80 | #list-item > li {
81 | max-width: 150px;
82 | }
83 |
84 | #list-item:hover > li {
85 | max-width: 75px;
86 | }
87 |
88 | #content {
89 | position: relative;
90 | }
91 |
92 | .content-webapp {
93 | height: calc(100vh - 38px);
94 | width: 100%;
95 | }
96 |
97 | #content-canvas {
98 | position: relative;
99 | }
100 |
101 | /* Webapp Menu */
102 | nav {
103 | position: relative;
104 | z-index: 999999;
105 | width: 100%;
106 | }
107 |
108 | .clearfix:after {
109 | content: '.';
110 | display: block;
111 | clear: both;
112 | height: 0;
113 | line-height: 0;
114 | font-size: 0;
115 | visibility: hidden;
116 | overflow: hidden;
117 | }
118 |
119 | #patch-menu {
120 | width: 100%;
121 | }
122 |
123 | .menu, .menu li ul, .patch-menu, .patch-menu li ul{
124 | background-color: #EFF0F1;
125 | margin: 0px;
126 | padding: 0px;
127 | list-style:none;
128 | float:left;
129 | font-size: 14px;
130 | width: 100%;
131 | border: 1px solid #C0C2C4;
132 | z-index: 1000000;
133 | }
134 |
135 | .menu li{
136 | display: none;
137 | position: relative;
138 | padding: 7px 10px;
139 | cursor: pointer;
140 | }
141 |
142 | .patch-menu li{
143 | position: relative;
144 | padding: 5px 10px;
145 | cursor: pointer;
146 | }
147 |
148 | .menu > li, .patch-menu > li {
149 | float: left;
150 | }
151 |
152 | .menu > li:hover, .patch-menu > li:hover {
153 | float: left;
154 | background-color: #6bd4e6;
155 | }
156 |
157 | .menu li ul, .patch-menu li ul{
158 | display: none;
159 | position: absolute;
160 | min-width: 250px;
161 | }
162 |
163 | .menu li ul li:hover, .patch-menu li ul li:hover{
164 | background-color: #6bd4e6;
165 | }
166 |
167 | .menu li ul li ul{
168 | top: 0;
169 | left: 100%;
170 | }
171 |
172 | .menu > li > ul > li span, .menu > li > ul > label > li span, .patch-menu > li > ul > li span {
173 | float: right;
174 | font-size: small;
175 | color: #777;
176 | }
177 |
178 | /* Input file */
179 | .menu label input[type="file"] {
180 | display: none;
181 | }
182 | .menu label {
183 | margin: 0px;
184 | width: 100%;
185 | text-align: left;
186 | }
187 |
188 | li .hr{
189 | display: block !important;
190 | margin: 0px;
191 | padding: 0px;
192 | width: 100%;
193 | }
194 |
195 | .hr > hr{
196 | margin: 0px;
197 | padding: 0px;
198 | }
199 |
200 | #pd-info{
201 | display: block;
202 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
203 | }
204 |
205 | #pd-info img{
206 | height: 50px;
207 | }
208 |
209 | /* Popup */
210 | #popup{
211 | background-color: #EFF0F1;
212 | margin: 0px;
213 | padding: 0px;
214 | font-size: 12px;
215 | border: 1px solid #C0C2C4;
216 | z-index: 999999;
217 | position: absolute;
218 | list-style:none;
219 | border-radius: 4px;
220 | box-shadow: 0 4px 8px 0 rgba(49, 49, 49, 0.15), 0 6px 20px 0 rgba(0, 0, 0, 0.14);
221 | }
222 |
223 | #popup li{
224 | position: relative;
225 | padding: 5px 10px;
226 | cursor: pointer;
227 | }
228 |
229 | #popup > li:hover{
230 | background-color: #6bd4e6;
231 | }
232 |
233 | .popup-disabled{
234 | color: #858688;
235 | }
236 | .popup-disabled:hover{
237 | background-color: transparent !important;
238 | }
239 |
240 | /* Webapp Index layout */
241 | #sidebar{
242 | background-color: transparent;
243 | min-width: 200px;
244 | max-width: 200px;
245 | margin: 0px;
246 | margin-top: 10px;
247 | border-top-width: 0ch;
248 | }
249 |
250 | #windows{
251 | max-height: 100vh !important;
252 | max-width: 100vw !important;
253 | }
254 |
255 | #canvas-content{
256 | height: 70%;
257 | }
258 |
259 | #canvas-content > .card-body{
260 | display: flex !important;
261 | }
262 |
263 | #canvas-container{
264 | min-height: 100%;
265 | flex-direction: row;
266 | }
267 |
268 | #console_controls{
269 | background-color: transparent;
270 | }
271 |
272 | #console-window{
273 | background-color: transparent;
274 | max-height: 30%;
275 | }
276 |
277 | #console-window a{
278 | text-decoration: none;
279 | }
280 |
281 | #console-header {
282 | height: 50px;
283 | }
284 | .patch{
285 | flex-basis: 100%;
286 | background-color: #f6f6f6;
287 | border-right: 2px solid hsl(220, 1%, 53%);
288 | overflow: auto;
289 | }
290 |
291 | .patch_window_svg{
292 | background-color: #f6f6f6;
293 | overflow: visible;
294 | margin-top: 35px;
295 | cursor: pointer;
296 | min-height: 100%;
297 | }
298 |
299 | .patch_window_svg > svg{
300 | min-height: 100%;
301 | position: relative;
302 | margin-top: -1px;
303 | margin-left: -1px;
304 | overflow: visible;
305 | }
306 |
307 | .patch-holder{
308 | height: 100%;
309 | font-family: Dejavu Sans Mono !important;
310 | }
311 |
312 | .patch-filename{
313 | margin: 0;
314 | padding-top: 10px;
315 | padding-bottom: 5px;
316 | cursor: move;
317 | }
318 |
319 | #div-svg-p{
320 | position: relative;
321 | z-index: 999999;
322 | }
323 |
324 | #sidebar-body {
325 | overflow: auto;
326 | }
327 |
328 | ::-webkit-scrollbar {
329 | width: 14px;
330 | height: 18px;
331 | }
332 | ::-webkit-scrollbar-thumb {
333 | height: 6px;
334 | border: 4px solid rgba(0, 0, 0, 0);
335 | background-clip: padding-box;
336 | -webkit-border-radius: 7px;
337 | background-color: rgba(0, 0, 0, 0.15);
338 | -webkit-box-shadow: inset -1px -1px 0px rgba(0, 0, 0, 0.05), inset 1px 1px 0px rgba(0, 0, 0, 0.05);
339 | }
340 | ::-webkit-scrollbar-button {
341 | width: 0;
342 | height: 0;
343 | display: none;
344 | }
345 | ::-webkit-scrollbar-corner {
346 | background-color: transparent;
347 | }
348 | *[unselectable="on"] {
349 | -moz-user-select: -moz-none;
350 | -khtml-user-select: none;
351 | -webkit-user-select: none;
352 | -ms-user-select: none;
353 | user-select: none;
354 | }
355 |
356 | /* Bootstrap */
357 | .container-fluid{
358 | background-color: transparent;
359 | padding: 0px !important;
360 | }
361 |
362 | .card {
363 | border-radius: 0px !important;
364 | }
365 |
366 | .card-body{
367 | padding: 0px 5px !important;
368 | }
369 |
370 | .card-body > .side-card{
371 | padding-top: 100px;
372 | }
373 |
374 | /* Fontawesome icons */
375 | .fa{
376 | font-size: 1.5em !important;
377 | margin-right: 20px;
378 | }
379 |
380 | #reload-i{
381 | font-size: 1em !important;
382 | cursor: pointer;
383 | transition: transform 1s linear;
384 | }
385 |
386 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // Defining create window
2 | function create_window(cid, type, width, height, xpos, ypos, attr_array) {
3 | // todo: make a separate way to format the title for OSX
4 | var my_title;
5 | if (type === "pd_canvas") {
6 | my_title = pdbundle.pdgui.format_window_title(
7 | attr_array.name,
8 | attr_array.dirty,
9 | attr_array.args,
10 | attr_array.dir);
11 | } else {
12 | my_title = type;
13 | }
14 | var my_file =
15 | type === "pd_canvas" ? "pd_canvas.html" : "dialog_" + type + ".html";
16 |
17 |
18 | var eval_string = "register_window_id(" +
19 | JSON.stringify(cid) + ", " +
20 | JSON.stringify(attr_array) + ");";
21 |
22 | var pdWindow = function(my_file, params, callback){
23 | var new_window = {params}
24 | new_window.window = window
25 | new_window.window.on = function (event, callback, record) {
26 | if (event == "loaded"){
27 | this.addEventListener('load', callback)
28 | }
29 | }
30 | callback(new_window)
31 |
32 | }
33 |
34 | function init_pd_window(f, new_win) {
35 |
36 | if (new_win === pdbundle.pdgui.get_patchwin(cid)) {
37 | // Add canvas html file
38 | $.get("./components/canvas/"+f, function(data){
39 | $("#canvas-container").append(data)
40 | update_canvas_id(cid);
41 | add_canvas_name(cid, attr_array.name)
42 | register_canvas(cid, attr_array);
43 | });
44 |
45 | // flag the window as loaded. We may want to wait until the
46 | // DOM window has finished loading for this.
47 | pdbundle.pdgui.set_window_finished_loading(cid);
48 | }else if(new_win === pdbundle.pdgui.get_dialogwin(cid)){
49 | // Add menu html file
50 | $.get("./components/dialogs/"+f, function(data){
51 | var dialog_div = new_win.window.document.getElementById("dialog-div");
52 |
53 | if(dialog_div === null){
54 | dialog_div = new_win.window.document.createElement('div')
55 | dialog_div.id = "dialog-div";
56 | }
57 |
58 | // cleaning dialog div
59 | dialog_div.innerHTML = "";
60 |
61 | $("#dialog-body").prepend(dialog_div.outerHTML)
62 | $("#dialog-div").prepend(data)
63 | var props_map = {
64 | "dialog_prefs.html": "Pd-L20rk",
65 | "dialog_canvas.html": "Canvas",
66 | "dialog_iemgui.html": "Iemgui",
67 | "dialog_gatom.html": "Atom",
68 | "dialog_font.html": "Font"
69 | };
70 | $("#dialog-title").text(props_map[f] + " Properties");
71 |
72 | $("#dialog-modal").modal("show");
73 | // initialize the dialog window
74 | register_dialog(cid,attr_array);
75 | });
76 | }else {
77 | // If the window is no longer loading, we need to go ahead
78 | // and remove the reference to it in the patchwin array.
79 | // Otherwise we get dangling references to closed windowsE vamo
80 | // and other bugs...
81 | if (!pdbundle.pdgui.window_is_loading(cid)) {
82 | if (type === "pd_canvas") {
83 | pdbundle.pdgui.set_patchwin(cid, undefined);
84 | } else {
85 | pdbundle.pdgui.set_dialogwin(cid, undefined);
86 | }
87 | }
88 | new_win.window.close(true);
89 | }
90 | }
91 |
92 | pdWindow(my_file, {
93 | title: my_title,
94 | position: "center",
95 | focus: true,
96 | width: width,
97 | // We add 23 as a kludge to account for the menubar at the top of
98 | // the window. Ideally we would just get rid of the canvas menu
99 | // altogether to simplify things. But we'd have to add some kind of
100 | // widget for the "Put" menu.
101 | height: height + 23,
102 | x: xpos,
103 | y: ypos
104 | }, function (new_win) {
105 |
106 | if (type === "pd_canvas") {
107 | pdbundle.pdgui.set_patchwin(cid, new_win);
108 | init_pd_window(my_file, new_win);
109 | } else {
110 | pdbundle.pdgui.set_dialogwin(cid, new_win);
111 | init_pd_window(my_file, new_win);
112 | }
113 | });
114 | }
115 |
116 | function add_menu(){
117 | // Add menu html file
118 | $.get("./components/menu/menu.html", function (data) {
119 | $("#menu").prepend(data)
120 | create_pd_window_menus(null, window)
121 | });
122 | }
123 |
124 | function dsp_toggle(){
125 | // DSP toggle
126 | document.getElementById("dsp_control").addEventListener("click",
127 | function(evt) {
128 | var dsp_state = evt.target.checked ? 1 : 0;
129 | pdbundle.pdgui.pdsend("pd dsp", dsp_state);
130 | }
131 | );
132 | }
133 |
134 | function create_pd_window_menus(gui, w) {
135 | var type = "web";
136 | var m = menu_options(type, w);
137 | add_shortcuts();
138 | load_menu_actions();
139 | }
140 |
141 | // Init Function
142 | function gui_init(win){
143 | // Init vars
144 | pdbundle.pdgui.set_pd_window(win);
145 | pdbundle.pdgui.set_new_window_fn(create_window);
146 | add_menu();
147 | dsp_toggle();
148 | }
149 |
150 | function initialize_webapp() {
151 | gui_init(window);
152 | };
153 |
--------------------------------------------------------------------------------
/libs/fa/fontawesome_1b8a796d74.js:
--------------------------------------------------------------------------------
1 | window.FontAwesomeCdnConfig = {
2 | autoA11y: {
3 | enabled: false
4 | },
5 | asyncLoading: {
6 | enabled: false
7 | },
8 | reporting: {
9 | enabled: false
10 | },
11 | useUrl: "use.fontawesome.com",
12 | faCdnUrl: "https://cdn.fontawesome.com:443",
13 | code: "1b8a796d74"
14 | };
15 | !function(){function a(a){var b,c=[],d=document,e=d.documentElement.doScroll,f="DOMContentLoaded",g=(e?/^loaded|^c/:/^loaded|^i|^c/).test(d.readyState);g||d.addEventListener(f,b=function(){for(d.removeEventListener(f,b),g=1;b=c.shift();)b()}),g?setTimeout(a,0):c.push(a)}function b(a,b){var c=!1;return a.split(",").forEach(function(a){var d=new RegExp(a.trim().replace(".","\\.").replace("*","(.*)"));b.match(d)&&(c=!0)}),c}function c(a){"undefined"!=typeof MutationObserver&&new MutationObserver(a).observe(document,{childList:!0,subtree:!0})}function d(a){var b,c,d,e;a=a||"fa",b=document.querySelectorAll("."+a),Array.prototype.forEach.call(b,function(a){c=a.getAttribute("title"),a.setAttribute("aria-hidden","true"),d=a.nextElementSibling?!a.nextElementSibling.classList.contains("sr-only"):!0,c&&d&&(e=document.createElement("span"),e.innerHTML=c,e.classList.add("sr-only"),a.parentNode.insertBefore(e,a.nextSibling))})}!function(){"use strict";function a(a){l.push(a),1==l.length&&k()}function b(){for(;l.length;)l[0](),l.shift()}function c(a){this.a=m,this.b=void 0,this.f=[];var b=this;try{a(function(a){f(b,a)},function(a){g(b,a)})}catch(c){g(b,c)}}function d(a){return new c(function(b,c){c(a)})}function e(a){return new c(function(b){b(a)})}function f(a,b){if(a.a==m){if(b==a)throw new TypeError;var c=!1;try{var d=b&&b.then;if(null!=b&&"object"==typeof b&&"function"==typeof d)return void d.call(b,function(b){c||f(a,b),c=!0},function(b){c||g(a,b),c=!0})}catch(e){return void(c||g(a,e))}a.a=0,a.b=b,h(a)}}function g(a,b){if(a.a==m){if(b==a)throw new TypeError;a.a=1,a.b=b,h(a)}}function h(b){a(function(){if(b.a!=m)for(;b.f.length;){var a=b.f.shift(),c=a[0],d=a[1],e=a[2],a=a[3];try{0==b.a?e("function"==typeof c?c.call(void 0,b.b):b.b):1==b.a&&("function"==typeof d?e(d.call(void 0,b.b)):a(b.b))}catch(f){a(f)}}})}function i(a){return new c(function(b,c){function d(c){return function(d){g[c]=d,f+=1,f==a.length&&b(g)}}var f=0,g=[];0==a.length&&b(g);for(var h=0;h=i?b():document.fonts.load(j(f,f.family),h).then(function(b){1<=b.length?a():setTimeout(c,25)},function(){b()})}c()}),o=new Promise(function(a,b){setTimeout(b,i)});Promise.race([o,n]).then(function(){a(f)},function(){e(f)})}else b(function(){function b(){var b;(b=-1!=q&&-1!=r||-1!=q&&-1!=s||-1!=r&&-1!=s)&&((b=q!=r&&q!=s&&r!=s)||(null===k&&(b=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),k=!!b&&(536>parseInt(b[1],10)||536===parseInt(b[1],10)&&11>=parseInt(b[2],10))),b=k&&(q==t&&r==t&&s==t||q==u&&r==u&&s==u||q==v&&r==v&&s==v)),b=!b),b&&(w.parentNode&&w.parentNode.removeChild(w),clearTimeout(x),a(f))}function m(){if((new Date).getTime()-l>=i)w.parentNode&&w.parentNode.removeChild(w),e(f);else{var a=document.hidden;!0!==a&&void 0!==a||(q=n.a.offsetWidth,r=o.a.offsetWidth,s=p.a.offsetWidth,b()),x=setTimeout(m,50)}}var n=new c(h),o=new c(h),p=new c(h),q=-1,r=-1,s=-1,t=-1,u=-1,v=-1,w=document.createElement("div"),x=0;w.dir="ltr",d(n,j(f,"sans-serif")),d(o,j(f,"serif")),d(p,j(f,"monospace")),w.appendChild(n.a),w.appendChild(o.a),w.appendChild(p.a),document.body.appendChild(w),t=n.a.offsetWidth,u=o.a.offsetWidth,v=p.a.offsetWidth,m(),g(n,function(a){q=a,b()}),d(n,j(f,'"'+f.family+'",sans-serif')),g(o,function(a){r=a,b()}),d(o,j(f,'"'+f.family+'",serif')),g(p,function(a){s=a,b()}),d(p,j(f,'"'+f.family+'",monospace'))})})},f=h}();var g={observe:function(a,b){for(var c=b.prefix,d=function(a){var b=a.weight?"-"+a.weight:"",d=a.style?"-"+a.style:"",e=a.className?"-"+a.className:"",g=a.className?"-"+a.className+b+d:"",h=document.getElementsByTagName("html")[0].classList,i=function(a){h.add(c+e+"-"+a),h.add(c+g+"-"+a)},j=function(a){h.remove(c+e+"-"+a),h.remove(c+g+"-"+a)};i("loading"),new f(a.familyName).load(a.testString).then(function(){i("ready"),j("loading")},function(){i("failed"),j("loading")})},e=0;e= 0; i--) {
84 | matches[i].classList.remove(highlight_tag);
85 | }
86 | if (state) {
87 | matches = document.getElementById("p1").getElementsByTagName("mark");
88 | for (i = 0; i < matches.length; i++) {
89 | matches[i].classList.add(highlight_tag);
90 | }
91 | }
92 | }
93 |
94 | var console_find_traverse = (function () {
95 | var count = 0,
96 | console_text = document.getElementById("p1"),
97 | wrap_tag = "mark";
98 | return {
99 | next: function () {
100 | var i, last, next,
101 | elements = console_text.getElementsByTagName(wrap_tag);
102 | count++;
103 | if (count >= elements.length) {
104 | count = 0;
105 | } else if (count < 0) {
106 | count = elements.length - 1;
107 | }
108 | if (elements.length > 0) {
109 | i = count % elements.length;
110 | elements[i].classList.add("console_find_current");
111 | if (elements.length > 1) {
112 | last = i === 0 ? elements.length - 1 : i - 1;
113 | next = (i + 1) % elements.length;
114 | elements[last].classList.remove("console_find_current");
115 | elements[next].classList.remove("console_find_current");
116 | }
117 | // adjust the scrollbar to make sure the element is visible,
118 | // but only if necessary.
119 | var isFirefox = typeof InstallTrigger !== 'undefined'; // checks if browser is Firefox or not
120 | if (isFirefox) {
121 | elements[i].scrollIntoView();
122 | } else {
123 | elements[i].scrollIntoViewIfNeeded();
124 | }
125 | }
126 | },
127 | previous: function () {
128 | var i, last, prev,
129 | elements = console_text.getElementsByTagName(wrap_tag);
130 | count--;
131 | if (count >= elements.length) {
132 | count = 0;
133 | } else if (count < 0) {
134 | count = elements.length - 1;
135 | }
136 | if (elements.length > 0) {
137 | i = count % elements.length;
138 | elements[i].classList.add("console_find_current");
139 | if (elements.length > 1) {
140 | last = i === elements.length - 1 ? 0 : i + 1;
141 | prev = (i - 1 + elements.length) % elements.length;
142 | elements[last].classList.remove("console_find_current");
143 | elements[prev].classList.remove("console_find_current");
144 | }
145 | // adjust the scrollbar to make sure the element is visible,
146 | // but only if necessary.
147 | var isFirefox = typeof InstallTrigger !== 'undefined'; // checks if browser is Firefox or not
148 | if (isFirefox) {
149 | elements[i].scrollIntoView();
150 | } else {
151 | elements[i].scrollIntoViewIfNeeded();
152 | }
153 | }
154 | },
155 | set_index: function(c) {
156 | count = c;
157 | },
158 | set_first_match: function() {
159 | var elements = console_text.getElementsByTagName(wrap_tag);
160 | if (elements.length > 0) {
161 | elements[0].classList.add("console_find_current");
162 | }
163 | // adjust the scrollbar to make sure the element is visible,
164 | // but only if necessary.
165 | var isFirefox = typeof InstallTrigger !== 'undefined'; // checks ifbrowser is Firefox or not
166 | if (isFirefox) {
167 | elements[0].scrollIntoView();
168 | } else {
169 | elements[0].scrollIntoViewIfNeeded();
170 | }
171 | }
172 | };
173 | }());
174 |
175 | function console_find_keydown(evt) {
176 | if (evt.keyCode === 13) {
177 | console_find_traverse.next();
178 | evt.stopPropagation();
179 | evt.preventDefault();
180 | return false;
181 | } else if (evt.keyCode === 27) { // escape
182 |
183 | } else if (evt.keyCode === 8 || // backspace or delete
184 | evt.keyCode === 46) {
185 | console_find_text(evt, console_find_callback);
186 | }
187 | }
188 |
189 | function console_find_below() {
190 | console_find_traverse.next();
191 | }
192 |
193 | function console_find_above() {
194 | console_find_traverse.previous();
195 | }
196 |
197 |
--------------------------------------------------------------------------------