summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrothedev <grothedev@gmail.com>2025-10-02 00:15:32 -0400
committergrothedev <grothedev@gmail.com>2025-10-02 00:15:32 -0400
commit685ab63782daeb868a999ec65ef0ceb0883acb3e (patch)
tree0faa1e000a358092e81bf7f48e7cb75bbfddf817
parenta4cb0a0eb9adf4761189829d544fec187b8b4499 (diff)
header space
-rw-r--r--AGENTS.md14
-rw-r--r--Cargo.lock333
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs167
4 files changed, 499 insertions, 16 deletions
diff --git a/AGENTS.md b/AGENTS.md
index ba863d7..96e4bff 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -7,6 +7,20 @@ this is a graphical application that displays a number of sub-windows, each disp
### Implementation
we must use vulkan in order to enable multi-threaded GPU operations. this means we'll probably use webgpu. the application will be written in either rust or C++. we will decide after playing with some basic proof-of-concepts.
+there shall be a state management system similar to js react, whereby UI elements will automatically update when any state-derived value shown on it is updated in the global state model.
+
+
+#### Modules
+
+ - rendering
+ - UI layout defining
+ - data input
+ - file, stdin, message queue, unix socket, network socket
+ - user control input
+ - keyboard, mouse, gamepad,
+ - service connection management
+ - state management
+
### Data inputs
diff --git a/Cargo.lock b/Cargo.lock
index 22613a1..f99e0bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -408,6 +408,48 @@ dependencies = [
]
[[package]]
+name = "cosmic-text"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2"
+dependencies = [
+ "bitflags 2.9.4",
+ "fontdb",
+ "log",
+ "rangemap",
+ "rayon",
+ "rustc-hash 1.1.0",
+ "rustybuzz",
+ "self_cell",
+ "swash",
+ "sys-locale",
+ "ttf-parser 0.21.1",
+ "unicode-bidi",
+ "unicode-linebreak",
+ "unicode-script",
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
+dependencies = [
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -467,6 +509,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -506,6 +554,25 @@ dependencies = [
]
[[package]]
+name = "etagere"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc89bf99e5dc15954a60f707c1e09d7540e5cd9af85fa75caa0b510bc08c5342"
+dependencies = [
+ "euclid",
+ "svg_fmt",
+]
+
+[[package]]
+name = "euclid"
+version = "0.22.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
name = "find-msvc-tools"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -518,6 +585,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
+name = "font-types"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "fontconfig-parser"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
+dependencies = [
+ "roxmltree",
+]
+
+[[package]]
+name = "fontdb"
+version = "0.16.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
+dependencies = [
+ "fontconfig-parser",
+ "log",
+ "memmap2",
+ "slotmap",
+ "tinyvec",
+ "ttf-parser 0.20.0",
+]
+
+[[package]]
name = "foreign-types"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -599,6 +698,19 @@ dependencies = [
]
[[package]]
+name = "glyphon"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b11b1afb04c1a1be055989042258499473d0a9447f16450b433aba10bc2a46e7"
+dependencies = [
+ "cosmic-text",
+ "etagere",
+ "lru",
+ "rustc-hash 2.1.1",
+ "wgpu",
+]
+
+[[package]]
name = "gpu-alloc"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -808,6 +920,12 @@ dependencies = [
]
[[package]]
+name = "libm"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
+
+[[package]]
name = "libredox"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -853,6 +971,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
+name = "lru"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
+
+[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -905,7 +1029,7 @@ dependencies = [
"hexf-parse",
"indexmap",
"log",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"spirv",
"termcolor",
"thiserror",
@@ -952,6 +1076,15 @@ dependencies = [
]
[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
name = "num_enum"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1212,7 +1345,7 @@ version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36820e9051aca1014ddc75770aab4d68bc1e9e632f0f5627c4086bc216fb583b"
dependencies = [
- "ttf-parser",
+ "ttf-parser 0.25.1",
]
[[package]]
@@ -1378,12 +1511,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"
[[package]]
+name = "rangemap"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223"
+
+[[package]]
name = "raw-window-handle"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539"
[[package]]
+name = "rayon"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
+dependencies = [
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
+dependencies = [
+ "crossbeam-deque",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "read-fonts"
+version = "0.22.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f"
+dependencies = [
+ "bytemuck",
+ "font-types",
+]
+
+[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1437,12 +1606,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
+name = "roxmltree"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
+
+[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
+name = "rustc-hash"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
+
+[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1475,6 +1656,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
+name = "rustybuzz"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
+dependencies = [
+ "bitflags 2.9.4",
+ "bytemuck",
+ "libm",
+ "smallvec",
+ "ttf-parser 0.21.1",
+ "unicode-bidi-mirroring",
+ "unicode-ccc",
+ "unicode-properties",
+ "unicode-script",
+]
+
+[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1509,6 +1707,12 @@ dependencies = [
]
[[package]]
+name = "self_cell"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
+
+[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1544,6 +1748,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
+name = "skrifa"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe"
+dependencies = [
+ "bytemuck",
+ "read-fonts",
+]
+
+[[package]]
name = "slab"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1620,6 +1834,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
+name = "svg_fmt"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
+
+[[package]]
+name = "swash"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2"
+dependencies = [
+ "skrifa",
+ "yazi",
+ "zeno",
+]
+
+[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1642,6 +1873,15 @@ dependencies = [
]
[[package]]
+name = "sys-locale"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1676,6 +1916,7 @@ version = "0.1.0"
dependencies = [
"bytemuck",
"env_logger",
+ "glyphon",
"pollster",
"wgpu",
"winit",
@@ -1707,6 +1948,21 @@ dependencies = [
]
[[package]]
+name = "tinyvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
name = "toml_datetime"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1754,17 +2010,65 @@ checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
[[package]]
name = "ttf-parser"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"
+
+[[package]]
+name = "ttf-parser"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
+
+[[package]]
+name = "ttf-parser"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
[[package]]
+name = "unicode-bidi"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
+
+[[package]]
+name = "unicode-bidi-mirroring"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"
+
+[[package]]
+name = "unicode-ccc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"
+
+[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-properties"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
+
+[[package]]
+name = "unicode-script"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f"
+
+[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1851,13 +2155,12 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.54"
+version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
+checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b"
dependencies = [
"cfg-if",
"js-sys",
- "once_cell",
"wasm-bindgen",
"web-sys",
]
@@ -2005,9 +2308,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.81"
+version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
+checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -2066,7 +2369,7 @@ dependencies = [
"parking_lot",
"profiling",
"raw-window-handle",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"smallvec",
"thiserror",
"wgpu-hal",
@@ -2109,7 +2412,7 @@ dependencies = [
"range-alloc",
"raw-window-handle",
"renderdoc-sys",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"smallvec",
"thiserror",
"wasm-bindgen",
@@ -2553,6 +2856,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7"
[[package]]
+name = "yazi"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c94451ac9513335b5e23d7a8a2b61a7102398b8cca5160829d313e84c9d98be1"
+
+[[package]]
+name = "zeno"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd15f8e0dbb966fd9245e7498c7e9e5055d9e5c8b676b95bd67091cd11a1e697"
+
+[[package]]
name = "zerocopy"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index bb3f6f2..92458e1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,3 +9,4 @@ winit = "0.30"
pollster = "0.3"
bytemuck = { version = "1.14", features = ["derive"] }
env_logger = "0.11"
+glyphon = "0.6"
diff --git a/src/main.rs b/src/main.rs
index 825dbb2..b74ee29 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,10 @@ use winit::{
keyboard::{KeyCode, PhysicalKey},
};
use wgpu::util::DeviceExt;
+use glyphon::{
+ Attrs, Buffer, Color as TextColor, Family, FontSystem, Metrics, Resolution, Shaping,
+ SwashCache, TextArea, TextAtlas, TextBounds, TextRenderer, Viewport
+};
#[repr(C)]
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
@@ -34,7 +38,7 @@ impl Vertex {
}
#[derive(Clone)]
-struct Viewport {
+struct SubView {
x: f32,
y: f32,
width: f32,
@@ -42,17 +46,19 @@ struct Viewport {
}
struct GraphView {
- viewport: Viewport,
+ viewport: SubView,
lines: Vec<Vec<Vertex>>,
show_grid: bool,
+ title: String,
}
impl GraphView {
- fn new(viewport: Viewport) -> Self {
+ fn new(viewport: SubView, title: String) -> Self {
Self {
viewport,
lines: Vec::new(),
show_grid: true,
+ title,
}
}
@@ -108,6 +114,10 @@ struct State {
vertex_buffer: wgpu::Buffer,
time: f32,
graphs: Vec<GraphView>,
+ font_system: FontSystem,
+ swash_cache: SwashCache,
+ text_atlas: TextAtlas,
+ text_renderer: TextRenderer,
}
impl State {
@@ -259,12 +269,44 @@ impl State {
mapped_at_creation: false,
});
- // Create 2 graph views side-by-side
+ // Create 2 graph views side-by-side with header area
+ // Reserve top 60px for header
+ let header_height = 60.0 / size.height as f32;
+ let graph_area_height = 1.0 - header_height;
+
let graphs = vec![
- GraphView::new(Viewport { x: 0.0, y: 0.0, width: 0.5, height: 1.0 }),
- GraphView::new(Viewport { x: 0.5, y: 0.0, width: 0.5, height: 1.0 }),
+ GraphView::new(
+ SubView {
+ x: 0.0,
+ y: header_height,
+ width: 0.5,
+ height: graph_area_height
+ },
+ "Frequency vs Time".to_string()
+ ),
+ GraphView::new(
+ SubView {
+ x: 0.5,
+ y: header_height,
+ width: 0.5,
+ height: graph_area_height
+ },
+ "Position vs Time".to_string()
+ ),
];
+ // Initialize text rendering
+ let mut font_system = FontSystem::new();
+ let swash_cache = SwashCache::new();
+ let cache = glyphon::Cache::new(&device);
+ let mut text_atlas = TextAtlas::new(&device, &queue, &cache, config.format);
+ let text_renderer = TextRenderer::new(
+ &mut text_atlas,
+ &device,
+ wgpu::MultisampleState::default(),
+ None,
+ );
+
Self {
surface,
device,
@@ -277,6 +319,10 @@ impl State {
vertex_buffer,
time: 0.0,
graphs,
+ font_system,
+ swash_cache,
+ text_atlas,
+ text_renderer,
}
}
@@ -348,7 +394,7 @@ impl State {
// Collect all vertex data for all graphs
struct DrawData {
- viewport: Viewport,
+ viewport: SubView,
border_offset: usize,
border_count: usize,
grid_offset: usize,
@@ -467,6 +513,113 @@ impl State {
}
}
+ // Render text (header and labels)
+ let mut text_areas = Vec::new();
+
+ // Main header
+ let mut header_buffer = Buffer::new(&mut self.font_system, Metrics::new(32.0, 40.0));
+ header_buffer.set_size(&mut self.font_system, Some(800.0), Some(50.0));
+ header_buffer.set_text(
+ &mut self.font_system,
+ "TimePlot - Waterfall Display",
+ Attrs::new().family(Family::SansSerif),
+ Shaping::Advanced,
+ );
+
+ // Graph titles - create all buffers first
+ let mut graph_buffers = Vec::new();
+ for graph in &self.graphs {
+ let x_offset = graph.viewport.x * self.size.width as f32;
+ let y_offset = graph.viewport.y * self.size.height as f32;
+ let width = graph.viewport.width * self.size.width as f32;
+
+ let mut title_buffer = Buffer::new(&mut self.font_system, Metrics::new(18.0, 24.0));
+ title_buffer.set_size(&mut self.font_system, Some(width), Some(30.0));
+ title_buffer.set_text(
+ &mut self.font_system,
+ &graph.title,
+ Attrs::new().family(Family::SansSerif),
+ Shaping::Advanced,
+ );
+ graph_buffers.push(title_buffer);
+ }
+
+ // Now create text areas with references to the buffers
+ text_areas.push(TextArea {
+ buffer: &header_buffer,
+ left: 10.0,
+ top: 15.0,
+ scale: 1.0,
+ bounds: TextBounds {
+ left: 0,
+ top: 0,
+ right: 800,
+ bottom: 50,
+ },
+ default_color: TextColor::rgb(255, 255, 255),
+ custom_glyphs: &[]
+ });
+
+ for (i, graph) in self.graphs.iter().enumerate() {
+ let x_offset = graph.viewport.x * self.size.width as f32;
+ let y_offset = graph.viewport.y * self.size.height as f32;
+ let width = graph.viewport.width * self.size.width as f32;
+
+ text_areas.push(TextArea {
+ buffer: &graph_buffers[i],
+ left: x_offset + 10.0,
+ top: y_offset + 5.0,
+ scale: 1.0,
+ bounds: TextBounds {
+ left: 0,
+ top: 0,
+ right: width as i32,
+ bottom: 30,
+ },
+ default_color: TextColor::rgb(230, 230, 230),
+ custom_glyphs: &[]
+ });
+ }
+
+ self.text_renderer
+ .prepare(
+ &self.device,
+ &self.queue,
+ &mut self.font_system,
+ &mut self.text_atlas,
+ &Viewport::new(
+ &self.device,
+ &glyphon::Cache::new(&self.device),
+ ),
+ text_areas,
+ &mut self.swash_cache,
+ )
+ .expect("Failed to prepare text");
+
+ {
+ let mut text_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
+ label: Some("Text Render Pass"),
+ color_attachments: &[Some(wgpu::RenderPassColorAttachment {
+ view: &view,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: wgpu::LoadOp::Load,
+ store: wgpu::StoreOp::Store,
+ },
+ })],
+ depth_stencil_attachment: None,
+ occlusion_query_set: None,
+ timestamp_writes: None,
+ });
+
+ self.text_renderer
+ .render(&self.text_atlas, &Viewport::new(
+ &self.device,
+ &glyphon::Cache::new(&self.device),
+ ), &mut text_pass)
+ .expect("Failed to render text");
+ }
+
self.queue.submit(std::iter::once(encoder.finish()));
output.present();