From 336b940471a18332d692b3b637c34110b8bdd1a1 Mon Sep 17 00:00:00 2001
From: Aaron Fenyes <aaron.fenyes@fareycircles.ooo>
Date: Thu, 12 Sep 2024 15:24:41 -0700
Subject: [PATCH] Outline: start on editor state and outline view

---
 app-proto/sketch-outline/.gitignore    |  3 ++
 app-proto/sketch-outline/Cargo.toml    | 29 ++++++++++++
 app-proto/sketch-outline/index.html    |  9 ++++
 app-proto/sketch-outline/main.css      | 50 +++++++++++++++++++++
 app-proto/sketch-outline/src/editor.rs | 61 ++++++++++++++++++++++++++
 app-proto/sketch-outline/src/main.rs   | 13 ++++++
 6 files changed, 165 insertions(+)
 create mode 100644 app-proto/sketch-outline/.gitignore
 create mode 100644 app-proto/sketch-outline/Cargo.toml
 create mode 100644 app-proto/sketch-outline/index.html
 create mode 100644 app-proto/sketch-outline/main.css
 create mode 100644 app-proto/sketch-outline/src/editor.rs
 create mode 100644 app-proto/sketch-outline/src/main.rs

diff --git a/app-proto/sketch-outline/.gitignore b/app-proto/sketch-outline/.gitignore
new file mode 100644
index 0000000..238273d
--- /dev/null
+++ b/app-proto/sketch-outline/.gitignore
@@ -0,0 +1,3 @@
+target
+dist
+Cargo.lock
\ No newline at end of file
diff --git a/app-proto/sketch-outline/Cargo.toml b/app-proto/sketch-outline/Cargo.toml
new file mode 100644
index 0000000..522c994
--- /dev/null
+++ b/app-proto/sketch-outline/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "sketch-outline"
+version = "0.1.0"
+authors = ["Aaron"]
+edition = "2021"
+
+[features]
+default = ["console_error_panic_hook"]
+
+[dependencies]
+js-sys = "0.3.70"
+nalgebra = "0.33.0"
+sycamore = "0.9.0-beta.3"
+
+# The `console_error_panic_hook` crate provides better debugging of panics by
+# logging them with `console.error`. This is great for development, but requires
+# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
+# code size when deploying.
+console_error_panic_hook = { version = "0.1.7", optional = true }
+
+[dependencies.web-sys]
+version = "0.3.69"
+
+[dev-dependencies]
+wasm-bindgen-test = "0.3.34"
+
+[profile.release]
+opt-level = "s" # optimize for small code size
+debug = true # include debug symbols
diff --git a/app-proto/sketch-outline/index.html b/app-proto/sketch-outline/index.html
new file mode 100644
index 0000000..5474fe9
--- /dev/null
+++ b/app-proto/sketch-outline/index.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <title>Sketch outline</title>
+    <link data-trunk rel="css" href="main.css"/>
+  </head>
+  <body></body>
+</html>
diff --git a/app-proto/sketch-outline/main.css b/app-proto/sketch-outline/main.css
new file mode 100644
index 0000000..2e6aedc
--- /dev/null
+++ b/app-proto/sketch-outline/main.css
@@ -0,0 +1,50 @@
+body {
+  margin-left: 20px;
+  margin-top: 20px;
+  color: #fcfcfc;
+  background-color: #222;
+}
+
+ul {
+  width: 450px;
+  padding: 8px;
+  border: 1px solid #888;
+  border-radius: 16px;
+}
+
+li {
+  display: flex;
+  padding: 3px;
+  list-style-type: none;
+  background-color: #444;
+  border-radius: 8px;
+}
+
+li:not(:last-child) {
+  margin-bottom: 8px;
+}
+
+li > .elt-name {
+  flex-grow: 1;
+  padding: 2px 0px 2px 4px;
+}
+
+li > .elt-rep {
+  display: flex;
+}
+
+li > .elt-rep > div {
+  padding: 2px;
+  margin-left: 3px;
+  text-align: center;
+  width: 60px;
+  background-color: #333;
+}
+
+li > .elt-rep > div:first-child {
+  border-radius: 6px 0px 0px 6px;
+}
+
+li > .elt-rep > div:last-child {
+  border-radius: 0px 6px 6px 0px;
+}
\ No newline at end of file
diff --git a/app-proto/sketch-outline/src/editor.rs b/app-proto/sketch-outline/src/editor.rs
new file mode 100644
index 0000000..b0d3f2e
--- /dev/null
+++ b/app-proto/sketch-outline/src/editor.rs
@@ -0,0 +1,61 @@
+use nalgebra::DVector;
+use sycamore::{prelude::*, web::tags::div};
+
+#[derive(Clone, PartialEq)]
+struct Element {
+    id: i64,
+    name: String,
+    rep: DVector<f64>,
+    color: [f32; 3]
+}
+
+struct EditorState {
+    elements: Signal<Vec<Element>>
+}
+
+#[component]
+pub fn Editor() -> View {
+    let state = EditorState {
+        elements: create_signal(vec![
+            Element {
+                id: 1,
+                name: String::from("Central"),
+                rep: DVector::<f64>::from_column_slice(&[0.0, 0.0, 0.0, 0.25, -1.0]),
+                color: [0.75_f32, 0.75_f32, 0.75_f32]
+            },
+            Element {
+                id: 2,
+                name: String::from("Wing A"),
+                rep: DVector::<f64>::from_column_slice(&[0.5, 0.5, 0.0, 0.5, -0.25]),
+                color: [1.00_f32, 0.25_f32, 0.00_f32]
+            },
+            Element {
+                id: 3,
+                name: String::from("Wing B"),
+                rep: DVector::<f64>::from_column_slice(&[-0.5, -0.5, 0.0, 0.5, -0.25]),
+                color: [1.00_f32, 0.25_f32, 0.00_f32]
+            }
+        ])
+    };
+    
+    view! {
+        ul {
+            Keyed(
+                list=state.elements,
+                view=|elt| {
+                    let name = elt.name.clone();
+                    let rep_components = elt.rep.iter().map(
+                        |u| View::from(div().children(u.to_string().replace("-", "\u{2212}")))
+                    ).collect::<Vec<_>>();
+                    view! {
+                        li {
+                            div(class="elt-name") { (name) }
+                            div(class="elt-rep") { (rep_components) }
+                        }
+                    }
+                },
+                key=|elt| elt.id
+            )
+        }
+    }
+}
\ No newline at end of file
diff --git a/app-proto/sketch-outline/src/main.rs b/app-proto/sketch-outline/src/main.rs
new file mode 100644
index 0000000..8b7ce30
--- /dev/null
+++ b/app-proto/sketch-outline/src/main.rs
@@ -0,0 +1,13 @@
+use sycamore::prelude::*;
+
+mod editor;
+
+use editor::Editor;
+
+fn main() {
+    sycamore::render(|| {
+        view! {
+            Editor {}
+        }
+    });
+}
\ No newline at end of file