Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

134 feature code editor 2 #174

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"@protobuf-ts/grpcweb-transport": "^2.9.1",
"@protobuf-ts/runtime": "^2.9.1",
"@tauri-apps/api": "^1.5.1",
"codejar": "^4.2.0",
"highlight.js": "^11.9.0",
"idb-keyval": "^6.2.1",
"svelte-google-materialdesign-icons": "^0.8.2",
"zod": "^3.22.4"
Expand Down
18 changes: 18 additions & 0 deletions src/lib/GlobalCssProperties.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@
0.39901960784,
0.43823529411
],
"--editor-keyword-color": [
"display-p3",
0.52549019608,
0.58823529411,
0.98823529412
],
"--editor-comment-color": [
"display-p3",
0.52549019608,
0.52549019608,
0.52549019608
],
"--engine-ui-underline-color": ["display-p3", 1, 1, 1],
"--engine-ui-error-underline-color": [
"display-p3",
Expand Down Expand Up @@ -247,6 +259,12 @@
0.14666666666,
0.17019607843
],
"--editor-keyword-color": [
"display-p3",
0.52549019608,
0.58823529411,
0.98823529412
],
"--engine-ui-underline-color": ["display-p3", 1, 1, 1],
"--engine-ui-error-underline-color": [
"display-p3",
Expand Down
2 changes: 2 additions & 0 deletions src/lib/classes/styling/ZodSchemas/CSSVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export const ColorVariables = z
"--sidebar-text-color": ColorAttribute,
"--sidebar-element-color": ColorAttribute,
"--sidebar-element-hover-color": ColorAttribute,
"--editor-keyword-color": ColorAttribute,
"--editor-comment-color": ColorAttribute,
"--engine-ui-underline-color": ColorAttribute,
"--engine-ui-error-underline-color": ColorAttribute,
"--engine-ui-input-text-placeholder-color": ColorAttribute,
Expand Down
8 changes: 8 additions & 0 deletions src/lib/components/canvas/Canvas.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script lang="ts">
import Editor from "../editor/Editor.svelte";
import SvgView from "$lib/components/svgView/SvgView.svelte";
import { CanvasModes, canvasModes } from "./state";
</script>

<Editor isHidden={$canvasModes !== CanvasModes.Editor} />
<SvgView isHidden={$canvasModes !== CanvasModes.Draw} />
65 changes: 65 additions & 0 deletions src/lib/components/canvas/CanvasNav.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script lang="ts">
import { Draw, Code } from "svelte-google-materialdesign-icons";
import SvgButton from "../buttons/SvgButton.svelte";

import {
CanvasModes,
CanvasSupports,
canvasModes,
canvasSupports,
} from "./state";

let supports = CanvasSupports.OnlyEditor;
let mode = CanvasModes.Editor;

canvasModes.subscribe((newMode) => {
mode = newMode;
});

canvasSupports.subscribe((newSupports) => {
supports = newSupports;
});
</script>

<nav id="canvas-nav">
<div class="buttons">
{#if supports === CanvasSupports.Both && mode !== CanvasModes.Draw}
<SvgButton
icon={Draw}
id="toggle-draw"
size={30}
click={() => {
canvasModes.set(CanvasModes.Draw);
}}
/>
{/if}
{#if supports === CanvasSupports.Both && mode !== CanvasModes.Editor}
<SvgButton
icon={Code}
id="toggle-editor"
size={30}
click={() => {
canvasModes.set(CanvasModes.Editor);
}}
/>
{/if}
</div>
</nav>

<style>
#canvas-nav {
display: flex;
justify-content: flex-end;
align-items: center;
min-height: 5em;
padding: 0 1em;
background-color: var(--canvas-topbar-color);
}

.buttons {
color: var(--navigationbar-text-color);
background: none;
border: none;
display: flex;
}
</style>
54 changes: 54 additions & 0 deletions src/lib/components/canvas/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Component, GlobalDeclarations, System } from "$lib/classes/automaton";
import { activeView } from "$lib/globalState/activeProject";
import { writable } from "svelte/store";
import { editor } from "$lib/components/editor/state";

export enum CanvasModes {
Draw,
Editor,
}

export enum CanvasSupports {
OnlyDraw,
OnlyEditor,
Both,
}

export const canvasSupports = writable(CanvasSupports.OnlyEditor);
export const canvasModes = writable(CanvasModes.Editor);

canvasSupports.subscribe((newSupports) => {
canvasModes.update((currentMode) => {
if (
newSupports == CanvasSupports.OnlyEditor &&
currentMode == CanvasModes.Draw
)
return CanvasModes.Editor;
else if (
newSupports == CanvasSupports.OnlyDraw &&
currentMode == CanvasModes.Editor
)
return CanvasModes.Draw;
else return currentMode;
});
});

activeView.subscribe((view) => {
if (view instanceof Component) {
canvasSupports.set(CanvasSupports.Both);
editor.change.set(view.declarations);
editor.push.set((code: string) => {
view.declarations = code;
});
} else if (view instanceof System) {
canvasSupports.set(CanvasSupports.OnlyDraw);
} else if (view instanceof GlobalDeclarations) {
canvasSupports.set(CanvasSupports.OnlyEditor);
editor.change.set(view.declarations);
editor.push.set((code: string) => {
view.declarations = code;
});
} else {
canvasSupports.set(CanvasSupports.OnlyEditor);
}
});
131 changes: 131 additions & 0 deletions src/lib/components/editor/Editor.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<script lang="ts">
import { onMount } from "svelte";
import { default as hljs } from "highlight.js";
import { editor } from "./state";

export let isHidden: boolean;
let editorDiv: HTMLElement;

hljs.registerLanguage("ecdar", () => {
return {
case_insensitive: false,
keywords: ["clock", "broadcast", "chan"],
contains: [hljs.COMMENT("/\\*", "\\*/"), hljs.COMMENT("//", "\\n")],
};
});

function createLineNr(i: number) {
let num = document.createElement("div");
num.innerHTML = String(i);
num.classList.add("editor-linenum");
return num;
}

onMount(async () => {
let { CodeJar } = await import("codejar");
let node = document.createElement("div");
node.style.float = "right";
node.style.width =
"calc(100% - var(--editor-lineno-width) - var(--editor-lineno-margin-right))";
node.classList.add("editor-text");

let linenr = document.createElement("div");
linenr.style.display = "flex";
linenr.style.flexDirection = "column";
linenr.style.justifyContent = "start";
linenr.style.float = "left";
linenr.style.width = "var(--editor-lineno-width)";

function updateLines(text: string) {
linenr.innerHTML = "";
if (!text.includes("\n")) {
linenr.appendChild(createLineNr(1));
return;
}
// Fixes line numbers in chrome and webkit
let substr = text.substring(text.length - 1);
if (substr == "\n") {
text = text.substring(0, text.length - 1);
}
linenr.appendChild(createLineNr(1));
let lines = 1;
for (let i = 0; i <= text.length; i++)
if (text[i] == "\n") linenr.appendChild(createLineNr(++lines));
}

function updateCode(node: HTMLElement, code: string) {
updateLines(code);
let highlight = hljs.highlight(code, { language: "ecdar" }).value;
node.innerHTML = highlight;
}

editor.change.subscribe((newCode) => {
updateCode(node, newCode);
});

updateLines("");
CodeJar(
node,
(n: HTMLElement) => {
let code = n.textContent as string;
editor.push.update((push) => (push(code), push));
updateCode(n, code);
},
{
history: false,
addClosing: false,
},
);

node.style.overflowY = "visible";
editorDiv.appendChild(linenr);
editorDiv.appendChild(node);
editorDiv.style.visibility = isHidden ? "hidden" : "visible";
});
</script>

<div
id="editor"
bind:this={editorDiv}
style={isHidden ? "visibility:hidden; height:0px;" : "visibility:visible;"}
/>

<style>
:global(:root) {
--editor-lineno-width: 2.5em;
--editor-lineno-margin-right: 0.3em;
}

#editor {
width: 100%;
height: 100%;
max-width: 80vw;
overflow: auto;
}

:global(.editor-text) {
height: 100%;
text-wrap: nowrap !important;
font-family: monospace;
font-size: 20px;
}

:global(.hljs-keyword) {
color: var(--editor-keyword-color);
font-family: monospace;
}

:global(.hljs-comment) {
color: var(--editor-comment-color);
font-family: monospace;
}

:global(.editor-linenum) {
font-size: 20px;
background-color: var(--canvas-topbar-color);
border-color: var(--canvas-topbar-color);
font-family: monospace;
text-align: right;
padding-right: var(--editor-lineno-margin-right);
}
</style>
17 changes: 17 additions & 0 deletions src/lib/components/editor/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { writable } from "svelte/store";

/**
* A handler for the editor
* */
export const editor = {
/**
* The writable containing the function that runs whenever the editor pushes
* */
push: writable((s: string) => {
s;
}),
/**
* The writable that whenever set overwrites what is displayed in the editor
* */
change: writable(""),
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<script lang="ts">
import { Description } from "svelte-google-materialdesign-icons";
import {
activeView,
globalDeclarations,
} from "$lib/globalState/activeProject";

function handleGlobalDeclarationsClick() {
console.log("Global Declarations clicked");
$activeView = $globalDeclarations;
}
</script>

Expand Down
3 changes: 3 additions & 0 deletions src/lib/components/settings/state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { writable } from "svelte/store";

export const showSettings = writable(false);
3 changes: 3 additions & 0 deletions src/lib/components/svgView/SvgView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import Location from "$lib/components/svgView/Location.svelte";
import { System } from "$lib/classes/automaton";

export let isHidden: boolean;

/**
* The parent svg element that the entire view is shown with.
*/
Expand Down Expand Up @@ -62,6 +64,7 @@
on:pointerdown={(event) => panzoom?.handleDown(event)}
on:wheel={(event) => panzoom?.zoomWithWheel(event)}
class="panzoom-parent"
style={isHidden ? "visibility:hidden; height:0px;" : "visibility:visible;"}
>
<g
bind:this={scaler}
Expand Down
Loading
Loading