diff --git a/editor-solidjs/src/Editor.jsx b/editor-solidjs/src/Editor.jsx
index 4c3213f..f625493 100644
--- a/editor-solidjs/src/Editor.jsx
+++ b/editor-solidjs/src/Editor.jsx
@@ -9,7 +9,7 @@ import LeftPane from "./LeftPane.jsx";
import MiddlePane from "./MiddlePane.jsx";
import RightPane from "./RightPane.jsx";
-import {World, Signal} from "../stackline-wasm/stackline_wasm.js";
+import {World, Pane} from "../stackline-wasm/stackline_wasm.js";
let json = await (await fetch("/stackline-wasm/prime.json")).json();
@@ -30,6 +30,7 @@ export default function Editor() {
selected: null,
time: performance.now(),
grid: true,
+ picked: null,
});
setWorld((world) => {
@@ -102,10 +103,38 @@ export default function Editor() {
}
}
+ let [left_pane, presets] = LeftPane({settings, setSettings});
+
+ let last_click = 0, last_selected = null;
+ const DOUBLE_CLICK_DURATION = 250;
+ function click() {
+ if (
+ Date.now() - last_click < DOUBLE_CLICK_DURATION
+ && settings.selected[0] == last_selected[0]
+ && settings.selected[1] == last_selected[1]
+ ) {
+ if (settings.selected !== null && settings.picked !== null) {
+ let preset = presets[settings.picked];
+
+ let pane = Pane.deserialize(preset.serialized);
+
+ setWorld((world) => {
+ pane.blit(...settings.selected, world);
+
+ return world;
+ });
+
+ pane.free();
+ }
+ }
+ last_selected = [...settings.selected];
+ last_click = Date.now();
+ }
+
return (
-
-
+ {left_pane}
+
);
diff --git a/editor-solidjs/src/LeftPane.jsx b/editor-solidjs/src/LeftPane.jsx
index f36ce3d..7d8d9f6 100644
--- a/editor-solidjs/src/LeftPane.jsx
+++ b/editor-solidjs/src/LeftPane.jsx
@@ -1,5 +1,77 @@
+import {createSignal} from "solid-js";
+import {createStore} from "solid-js/store";
+
+import styles from "./LeftPane.module.css";
+
+import {available_tiles, Pane, FullTile} from "../stackline-wasm/stackline_wasm.js";
+import TilePreset from "./TilePreset.jsx";
+
+export const BASE_TILES = [];
+
+export class Tile {
+ constructor(serialized, name) {
+ this.serialized = serialized;
+ this.name = name;
+ }
+}
+
+export function init() {
+ let pane = new Pane(1, 1);
+ BASE_TILES.push(new Tile(pane.serialize(), "Empty"));
+ pane.free();
+
+ for (let name of available_tiles().sort()) {
+ let pane = new Pane(1, 1);
+
+ let tile = new FullTile(name);
+ pane.set(0, 0, tile);
+
+ let serialized = pane.serialize();
+
+ pane.free();
+ BASE_TILES.push(new Tile(serialized, name));
+ }
+}
+
export default function LeftPane(props) {
- return (
+ let [preset, setPresets] = createStore(BASE_TILES);
+ let {settings, setSettings} = props;
+ let left_pane;
+
+ function resize() {
+ let width = document.body.clientWidth / 4;
+ if (width >= 390) {
+ width = 390;
+ } else if (width >= 255) {
+ width = 255;
+ } else {
+ width = 125;
+ }
+
+ left_pane.style.width = `${Math.round(width)}px`;
+ }
+
+ function set_resize() {
+ setTimeout(() => {
+ window.addEventListener("resize", resize);
+ resize();
+ }, 0);
+ }
+
+ function remove_resize() {
+ window.removeEventListener("resize", resize);
+ }
-
);
+ return [
+
+ {(item, index) => {
+ return item.serialized} name={() => item.name} settings={settings} setSettings={setSettings} index={index} />;
+ }}
+
+
, preset];
}
diff --git a/editor-solidjs/src/LeftPane.module.css b/editor-solidjs/src/LeftPane.module.css
new file mode 100644
index 0000000..42c8da9
--- /dev/null
+++ b/editor-solidjs/src/LeftPane.module.css
@@ -0,0 +1,49 @@
+.LeftPane_container {
+ background: #18181b;
+ color: white;
+ padding: 1.5em 1em;
+ font-family: monospace;
+ font-size: 15px;
+
+ overflow-y: scroll;
+}
+
+.LeftPane {
+ width: 25vw;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, calc(8em));
+ grid-gap: 1em;
+ justify-content: space-evenly;
+}
+
+.TilePreset {
+ width: calc(8em - 6px);
+ border: 1px solid #404040;
+ border-radius: 4px;
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ color: #d0d0d0;
+ padding: 3px;
+}
+
+.TilePreset:hover {
+ border: 1px solid #808080;
+}
+
+.preview {
+ font-family: "Stackline Classic", monospace;
+ font-size: 30px;
+ user-select: none;
+}
+
+.TilePreset.picked {
+ color: white;
+ border: 4px solid #d0d0d0;
+ padding: 0px;
+}
+
+.TilePreset.picked:hover {
+ border: 4px solid white;
+}
diff --git a/editor-solidjs/src/MiddlePane.jsx b/editor-solidjs/src/MiddlePane.jsx
index 5e40d0e..2438531 100644
--- a/editor-solidjs/src/MiddlePane.jsx
+++ b/editor-solidjs/src/MiddlePane.jsx
@@ -236,7 +236,7 @@ export default function MiddlePane(props) {
}
}
- let resize_listener = () => {
+ function resize_cb() {
if (!canvas.element) return;
setCanvas((obj) => {
return {
@@ -247,8 +247,22 @@ export default function MiddlePane(props) {
});
}
+ let resize_listener = new ResizeObserver(resize_cb);
+
+ function set_resize() {
+ setTimeout(() => {
+ resize_listener.observe(canvas.element);
+ }, 0);
+ }
+
+ function remove_resize() {
+ setTimeout(() => {
+ resize_listener.unobserve(canvas.element);
+ }, 0);
+ }
+
createEffect(() => {
- resize_listener();
+ resize_cb();
loop();
});
@@ -262,8 +276,8 @@ export default function MiddlePane(props) {
let _canvas;
return (