From: Brendan Hansen Date: Mon, 6 Sep 2021 01:15:23 +0000 (-0500) Subject: big ui upgrades X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=a8d812c12502d7ac79c53e3ccf54853fb8bc8da1;p=onyx-live.git big ui upgrades --- diff --git a/docs/todo b/docs/todo new file mode 100644 index 0000000..3b9cc86 --- /dev/null +++ b/docs/todo @@ -0,0 +1,27 @@ +A small wishlist of things I wish the onyx live environment could do: + + ☑ Quick Examples dropdown + ☑ Quickly load examples from the Onyx source repo + ☑ Make it easier for someone to get into the language if they can + easily see the basic examples + ☑ This will require reworking the current menu system + + ☑ Persistant sessions + ☑ Store current file state into local storage + ☑ Maybe add multiple persistant files, so you can save multiple things + to your location storage. Keep the option to save to disk however. + + - Simple canvas rendering for visual programs + - Add a basic API only available in Onyx live that give you basic + canvas draw calls, like draw rect, draw circle, change color, etc. + - Would allow for more interesting example programs. + - Also, make the API available as just a drop in module, so someone + can simpley include it, set the canvas name, and being doing canvas + things. + + ☑ Full UI theme changing + ☑ Should be able to pull the colors from the ace-editor-theme class and + use them throughout the UI + + - Better error handling for browsers that do not support SharedInputBuffer. + - I'm looking at you Safari... diff --git a/serve.py b/serve.py index 3d27024..b5e5219 100644 --- a/serve.py +++ b/serve.py @@ -20,6 +20,30 @@ def get_homepage(): response.headers['Cross-Origin-Opener-Policy'] = "same-origin" return response +@app.route("/list_examples") +def list_examples(): + import os, json + + example_folder = os.path.join(app.config['ONYX_SOURCE_FOLDER'], 'examples') + filenames = [f for f in os.listdir(example_folder) if os.path.isfile(os.path.join(example_folder, f))] + filenames.sort() + filenames = list(map(lambda x: x.rstrip(".onyx"), filenames)) + return json.dumps(filenames) + +@app.route("/example") +def load_example(): + import os + + example = request.args.get('example') + example_file_path = f"{app.config['ONYX_SOURCE_FOLDER']}/examples/{example}.onyx" + + if os.path.isfile(example_file_path): + with open(example_file_path) as f: + filedata = f.read() + return filedata + + else: + return "", 500 @app.route("/compile", methods=['POST']) def post_compile_onyx(): diff --git a/static/css/index.css b/static/css/index.css index b6401b6..79ae516 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -8,13 +8,35 @@ * { margin: 0; padding: 0; + box-sizing: border-box; +} + +.ui-dark-theme { + --terminal-background-color: #070707; + --terminal-foreground-color: #ffffff; + + --background-color: #111; + --light-background-color: #222; + --active-color: #444; + --foreground-color: #fff; +} + +.ui-light-theme { + --terminal-background-color: #dddddd; + --terminal-foreground-color: #000000; + + --background-color: #f0f0f0; + --light-background-color: #e0e0e0; + --active-color: #cccccc; + --foreground-color: #000000; } body { - background: #111; - color: #fff; + background: var(--background-color); + color: var(--foreground-color); overflow: hidden; + font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace; } select { @@ -23,36 +45,43 @@ select { min-width: 64px; border: none; - color: white; - background: #222; + color: var(--foreground-color); + background: var(--light-background-color); + + border-radius: 6px; transition: all 0.5s; } select:hover { - background: #444; + background: var(--active-color); cursor: pointer; } -button { +.menu-bar button, .menu-bar a { margin: calc((var(--menu-bar-height) - 24px) / 2); height: 24px; min-width: 64px; border: none; - color: white; - background: #222; + background: var(--background-color); + color: var(--foreground-color); transition: all 0.5s; } -button:hover { - background: #444; +.menu-bar button, .menu-bar a { + min-width: 24px; + border-radius: 50%; +} + +.menu-bar button:hover, .menu-bar a:hover { + background: var(--active-color); cursor: pointer; } .left-half, .right-half { - height: calc(100% - var(--menu-bar-height)); + height: calc(100vh - var(--menu-bar-height)); float: left; display: inline-block; } @@ -62,11 +91,11 @@ button:hover { } .right-half { - width: calc((100% - var(--left-half-width)) - var(--divider-size) / 2); + width: calc((100vw - var(--left-half-width)) - var(--divider-size) / 2); } .top-half, .bottom-half { - width: 100%; + width: 100vw; float: left; display: inline-block; } @@ -80,10 +109,12 @@ button:hover { } #code-result { - height: 100%; - max-height: calc(100% - var(--menu-bar-height) - var(--input-bar-height)); /* subtract the padding */ - background: #070707; - color: #fff; + height: 100vh; + max-height: calc(100vh - var(--menu-bar-height) - var(--input-bar-height)); /* subtract the padding */ + + background: var(--terminal-background-color); + color: var(--terminal-foreground-color); + font-size: 16px; font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace; @@ -99,7 +130,7 @@ button:hover { #horizontal-divider { min-width: var(--divider-size); - height: 100%; + height: calc(100vh - var(--menu-bar-height)); background-color: #777; cursor: col-resize; @@ -108,13 +139,13 @@ button:hover { } #input-bar { - background-color: #181818; - color: #fff; + background-color: var(--background-color); + color: var(--foreground-color); outline: none; border: none; min-height: var(--input-bar-height); - width: 80%; + width: 100%; padding: 8px; float: left; @@ -122,26 +153,71 @@ button:hover { font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace; } -#input-submit { - background-color: #272727; - color: #fff; +.jquery-modal.blocker.current { + z-index: 100 !important; +} + +.modal { + z-index: 200 !important; + + background: var(--background-color) !important; + color: var(--foreground-color) !important; +} + +.modal input { + background-color: var(--light-background-color); + color: var(--foreground-color); outline: none; border: none; - float: left; - width: 20%; - padding: 8px; - margin: 0; min-height: var(--input-bar-height); + width: 100%; + padding: 8px; + float: left; font-size: 16px; font-family: Monaco, Menlo, "Ubuntu Mono", Consolas, source-code-pro, monospace; +} + +.modal button { + margin: 8px 0; + height: 24px; + min-width: 64px; + + border: none; + color: var(--foreground-color); + background: var(--light-background-color); transition: all 0.5s; } -#input-submit:hover { - background: #444; +.modal button:hover { + background: var(--active-background-color); cursor: pointer; } +.modal .file-list { + max-height: 400px; + overflow: auto; +} + +.modal .file-list button { + display: block; + width: 100%; +} + +.modal .file-list .file-select { + float: left; + width: 85%; +} + +.modal .file-list .file-delete { + float: left; + width: 15%; + + background: #802424; +} + +.modal .file-list .file-delete:hover { + background: #a04444; +} diff --git a/static/src/index.js b/static/src/index.js index edb6c0a..8bd78c0 100644 --- a/static/src/index.js +++ b/static/src/index.js @@ -1,6 +1,7 @@ let wasm_worker = null; let editor_keybind_mode = "normal"; let editor_theme = "chrome"; +let ui_theme = "dark"; let input_shared_buffer = new SharedArrayBuffer(1024 * Uint8Array.BYTES_PER_ELEMENT); @@ -14,6 +15,8 @@ async function write_output(msg, has_error) { let elem = document.getElementById('code-result'); if (has_error != null && has_error) elem.className = "errored"; elem.innerHTML += msg; + + elem.scrollTop = elem.scrollHeight - elem.clientHeight; } async function run_wasm(wasm_bytes) { @@ -52,6 +55,8 @@ async function run_wasm(wasm_bytes) { } async function submit_code() { + if (wasm_worker != null) return; + clear_output(); let editor = ace.edit('code-editor'); let code = editor.getValue(); @@ -108,12 +113,12 @@ async function kill_code() { } function update_running_msg() { - let elem = document.getElementById('running-msg'); + let elem = document.getElementById('run-button'); if (wasm_worker == null) { - elem.innerHTML = ""; + elem.innerHTML = ""; } else { - elem.innerHTML = "Running..."; + elem.innerHTML = ""; } } @@ -150,17 +155,37 @@ function change_keybindings(value) { persist_settings(); } +function change_ui_theme(value) { + let elem = document.getElementById('ui-theme'); + + if (value == null) { + value = elem.value; + } else { + document.querySelector(`#ui-theme option[value="${value}"]`).selected = true; + } + + $("body").removeClass(); + if (value == "light") $("body").addClass("ui-light-theme"); + if (value == "dark") $("body").addClass("ui-dark-theme"); + + ui_theme = value; + persist_settings(); +} + function persist_settings() { localStorage["editor_theme"] = editor_theme; localStorage["editor_keybind_mode"] = editor_keybind_mode; + localStorage["ui_theme"] = ui_theme; } function load_settings() { editor_theme = localStorage["editor_theme"]; editor_keybind_mode = localStorage["editor_keybind_mode"]; + ui_theme = localStorage["ui_theme"] || ui_theme; change_editor_theme(editor_theme); change_keybindings(editor_keybind_mode); + change_ui_theme(ui_theme); } async function handle_drop(e) { @@ -177,28 +202,6 @@ function handle_dragover(e) { return false; } -function prompt_download() { - let editor = ace.edit('code-editor'); - let code = editor.getValue(); - - let blob = new Blob([ code ], { - type: 'text/plain' - }); - - let download_link = document.createElement('a'); - download_link.download = `onyx-${Date.now()}.onyx`; - download_link.href = window.URL.createObjectURL(blob); - download_link.onclick = function(e) { - // revokeObjectURL needs a delay to work properly - setTimeout(() => { - window.URL.revokeObjectURL(this.href); - }, 1500); - }; - - download_link.click(); - download_link.remove(); -} - function submit_input() { let inputbar = document.getElementById("input-bar"); let input = inputbar.value; @@ -218,6 +221,34 @@ function submit_input() { inputbar.value = ""; } +function populate_examples() { + fetch("/list_examples") + .then(x => x.json()) + .then(examples => { + let $selector = $("#examples-selector"); + + for (let ex of examples) { + $selector.append($('