From 6da6fd8326d911eb8282d4e10499a8bcadac94c1 Mon Sep 17 00:00:00 2001 From: DustVoice Date: Wed, 5 Oct 2022 14:47:12 +0200 Subject: [PATCH] Integrate the demo gtk project into beanconqueror --- Cargo.lock | 526 ++++++++++++++++++++++++++++++++++- Cargo.toml | 15 +- src/main.rs | 175 ++++++++++-- src/ui/beanconqueror-gtk.cmb | 156 +++++++++++ src/ui/beanconqueror-gtk.ui | 214 ++++++++++++++ src/ui/main.ui | 33 +++ 6 files changed, 1080 insertions(+), 39 deletions(-) create mode 100644 src/ui/beanconqueror-gtk.cmb create mode 100644 src/ui/beanconqueror-gtk.ui create mode 100644 src/ui/main.ui diff --git a/Cargo.lock b/Cargo.lock index 93530b9..7d781ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,6 +23,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anyhow" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" + [[package]] name = "approx" version = "0.5.1" @@ -49,14 +55,16 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "beanconqueror" -version = "0.2.0" +version = "0.3.0" dependencies = [ "calamine", "chrono", "colourado", "fast-float", + "gtk4", "palette", "plotters", + "plotters-cairo", "serde", "serde_derive", "toml", @@ -86,6 +94,30 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cairo-rs" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c76ee391b03d35510d9fa917357c7f1855bd9a6659c95a1b392e33f49b3369bc" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "calamine" version = "0.18.0" @@ -96,7 +128,7 @@ dependencies = [ "codepage", "encoding_rs", "log", - "quick-xml", + "quick-xml 0.19.0", "serde", "zip", ] @@ -107,6 +139,15 @@ version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +[[package]] +name = "cfg-expr" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aacacf4d96c24b2ad6eb8ee6df040e4f27b0d0b39a5710c30091baa830485db" +dependencies = [ + "smallvec", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -304,6 +345,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" +[[package]] +name = "field-offset" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" +dependencies = [ + "memoffset", + "rustc_version", +] + [[package]] name = "find-crate" version = "0.6.3" @@ -396,6 +447,116 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "futures-channel" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" + +[[package]] +name = "futures-executor" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" + +[[package]] +name = "futures-task" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" + +[[package]] +name = "futures-util" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38dd9cc8b099cceecdf41375bb6d481b1b5a7cd5cd603e10a69a9383f8619a" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140b2f5378256527150350a8346dbdb08fadc13453a7a2d73aecd5fab3c402a7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fabb7cf843c26b085a5d68abb95d0c0bf27a9ae2eeff9c4adb503a1eb580876" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efe7dcb44f5c00aeabff3f69abfc5673de46559070f89bd3fbb7b66485d9cef2" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + [[package]] name = "getrandom" version = "0.2.7" @@ -417,6 +578,210 @@ dependencies = [ "weezl", ] +[[package]] +name = "gio" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68fdbc90312d462781a395f7a16d96a2b379bb6ef8cd6310a2df272771c4283b" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "gio-sys", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32157a475271e2c4a023382e9cab31c4584ee30a97da41d3c4e9fdd605abcf8d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.15.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb0306fbad0ab5428b0ca674a23893db909a98582969c9b537be4ced78c505d" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4b192f8e65e9cf76cbf4ea71fa8e3be4a0e18ffe3d68b8da6836974cc5bad4" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d57ce44246becd17153bd035ab4d32cfee096a657fc01f2231c9278378d1e0a" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c54f9fbbeefdb62c99f892dfca35f83991e2cb5b46a8dc2a715e58612f85570" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa691fc7337ba1df599afb55c3bcb85c04f1b3f17362570e9bb0ff0d1bc3028a" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e9020d333280b3aa38d496495bfa9b50712eebf1ad63f0ec5bcddb5eb61be4" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7add39ccf60078508c838643a2dcc91f045c46ed63b5ea6ab701b2e25bda3fea" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64f0c2a3d80e899dc3febddad5bac193ffcf74a0fd7e31037f30dd34d6f7396" +dependencies = [ + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "once_cell", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fafbcc920af4eb677d7d164853e7040b9de5a22379c596f570190c675d45f7a7" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quick-xml 0.22.0", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bc8006eea634b7c72da3ff79e24606e45f21b3b832a3c5a1f543f5f97eb0f63" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "iana-time-zone" version = "0.1.47" @@ -498,6 +863,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg 1.1.0", +] + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -567,6 +941,31 @@ dependencies = [ "syn", ] +[[package]] +name = "pango" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e4045548659aee5313bde6c582b0d83a627b7904dd20dc2d9ef0895d414e4f" +dependencies = [ + "bitflags", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.15.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a00081cde4661982ed91d80ef437c20eacaf6aa1a5962c0279ae194662c3aa" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + [[package]] name = "pathfinder_geometry" version = "0.5.1" @@ -638,6 +1037,18 @@ dependencies = [ "siphasher", ] +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.25" @@ -646,9 +1057,8 @@ checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +version = "0.3.5" +source = "git+https://github.com/plotters-rs/plotters#c202b9c0602081b835d66af5bf237e35461aa066" dependencies = [ "chrono", "font-kit", @@ -667,14 +1077,12 @@ dependencies = [ [[package]] name = "plotters-backend" version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +source = "git+https://github.com/plotters-rs/plotters#c202b9c0602081b835d66af5bf237e35461aa066" [[package]] name = "plotters-bitmap" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4a1f21490a6cf4a84c272ad20bd7844ed99a3178187a4c5ab7f2051295beef" +version = "0.3.3" +source = "git+https://github.com/plotters-rs/plotters#c202b9c0602081b835d66af5bf237e35461aa066" dependencies = [ "gif", "image", @@ -682,10 +1090,18 @@ dependencies = [ ] [[package]] -name = "plotters-svg" +name = "plotters-cairo" version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +source = "git+https://github.com/plotters-rs/plotters-cairo#51326436fc6a001a2084327a3c58d6f365be858c" +dependencies = [ + "cairo-rs", + "plotters-backend", +] + +[[package]] +name = "plotters-svg" +version = "0.3.4" +source = "git+https://github.com/plotters-rs/plotters#c202b9c0602081b835d66af5bf237e35461aa066" dependencies = [ "plotters-backend", ] @@ -702,6 +1118,41 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "proc-macro-crate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.43" @@ -721,6 +1172,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "quick-xml" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.21" @@ -939,6 +1399,21 @@ version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg 1.1.0", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "syn" version = "1.0.99" @@ -950,6 +1425,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-deps" +version = "6.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + [[package]] name = "thiserror" version = "1.0.33" @@ -1008,6 +1496,18 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf" +[[package]] +name = "version-compare" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "walkdir" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index a8b0318..a9d60fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "beanconqueror" -version = "0.2.0" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -11,9 +11,16 @@ chrono = "0.4.22" colourado = "0.2.0" fast-float = "0.2.0" palette = "0.6.1" -plotters = "0.3.4" -# plotters-canvas = "*" serde = "1.0.144" serde_derive = "1.0.144" toml = "0.5.9" -# wasm-bindgen-test = "0.2" + +[dependencies.gtk] +version = "0.4.8" +package = "gtk4" + +[dependencies.plotters] +git = "https://github.com/plotters-rs/plotters" + +[dependencies.plotters-cairo] +git = "https://github.com/plotters-rs/plotters-cairo" diff --git a/src/main.rs b/src/main.rs index 11708f1..b21038e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,20 @@ use calamine::{open_workbook, Reader, Xlsx}; use chrono::{Duration, NaiveTime}; use colourado::{ColorPalette, PaletteType}; -use plotters::prelude::*; use serde_derive::Deserialize; +use std::cell::RefCell; use std::collections::HashMap; +use std::error::Error; use std::fs; +use std::rc::Rc; + +use gtk::prelude::*; + +use plotters::prelude::*; +use plotters_cairo::CairoBackend; + +const UI_SOURCE: &'static str = include_str!("ui/beanconqueror-gtk.ui"); #[derive(Deserialize)] struct Shot { @@ -68,7 +77,7 @@ fn process_sheet( data_col: usize, ) -> Vec<(f64, f64)> { let mut workbook: Xlsx<_> = - open_workbook(path).expect(&format!("Cannot open file at path \"{}\"", path)); + open_workbook(path).unwrap_or_else(|_| panic!("Cannot open file at path \"{}\"", path)); if let Some(Ok(range)) = workbook.worksheet_range_at(worksheet) { let starting_time: NaiveTime = cell_to_naivetime(range[(1, time_col)].get_string()); @@ -85,31 +94,27 @@ fn process_sheet( // println!("time column cells: {:?}", time_range.cells().next()); // println!("time column strings: {:?}", time_range.cells().map(|c| c.2.get_string().unwrap()).collect::>()); - let map_time_range = time_range - .cells() - .map(|c| { - let timestamp = cell_to_naivetime(c.2.get_string()); - let deltatime = deltatime(timestamp, starting_time); - let std_duration = deltatime.to_std().unwrap(); + let map_time_range = time_range.cells().map(|c| { + let timestamp = cell_to_naivetime(c.2.get_string()); + let deltatime = deltatime(timestamp, starting_time); + let std_duration = deltatime.to_std().unwrap(); - std_duration.as_secs_f32() as f64 - }) - .collect::>(); + std_duration.as_secs_f32() as f64 + }); let map_weight_range = weight_range .cells() .map(|c| { - c.2.get_float().expect(&format!( - "Can't get float value of weight column at position ({},{})", - c.0, c.1 - )) + c.2.get_float().unwrap_or_else(|| { + panic!( + "Can't get float value of weight column at position ({},{})", + c.0, c.1 + ) + }) }) .collect::>(); - map_time_range - .into_iter() - .zip(map_weight_range.into_iter()) - .collect() + map_time_range.zip(map_weight_range).collect() } else { vec![] } @@ -121,12 +126,12 @@ fn load_data(path: &str, cutoff: Option) -> Option { if let Some(cutoff_val) = cutoff { if cutoff_val != -1.0 { - w = w.into_iter().filter(|x| &x.0 < &cutoff_val).collect(); - fr = fr.into_iter().filter(|x| &x.0 < &cutoff_val).collect(); + w.retain(|x| x.0 < cutoff_val); + fr.retain(|x| x.0 < cutoff_val); } } - if w.len() > 0 && fr.len() > 0 { + if !w.is_empty() && !fr.is_empty() { let data = Data { weight: w, flowrate: fr, @@ -137,6 +142,123 @@ fn load_data(path: &str, cutoff: Option) -> Option { } } +#[derive(Clone, Copy)] +struct PlottingState { + mean_x: f64, + mean_y: f64, + std_x: f64, + std_y: f64, + pitch: f64, + roll: f64, +} + +impl PlottingState { + fn guassian_pdf(&self, x: f64, y: f64) -> f64 { + let x_diff = (x - self.mean_x) / self.std_x; + let y_diff = (y - self.mean_y) / self.std_y; + let exponent = -(x_diff * x_diff + y_diff * y_diff) / 2.0; + let denom = (2.0 * std::f64::consts::PI / self.std_x / self.std_y).sqrt(); + let gaussian_pdf = 1.0 / denom; + gaussian_pdf * exponent.exp() + } + fn plot_pdf<'a, DB: DrawingBackend + 'a>( + &self, + backend: DB, + ) -> Result<(), Box> { + let root = backend.into_drawing_area(); + + root.fill(&WHITE)?; + + let mut chart = ChartBuilder::on(&root).build_cartesian_3d( + -10.0f64..10.0, + 0.0f64..1.2, + -10.0f64..10.0, + )?; + + chart.with_projection(|mut p| { + p.pitch = self.pitch; + p.yaw = self.roll; + p.scale = 0.7; + p.into_matrix() // build the projection matrix + }); + + chart + .configure_axes() + .light_grid_style(BLACK.mix(0.15)) + .max_light_lines(3) + .draw()?; + let self_cloned = self.clone(); + chart.draw_series( + SurfaceSeries::xoz( + (-50..=50).map(|x| x as f64 / 5.0), + (-50..=50).map(|x| x as f64 / 5.0), + move |x, y| self_cloned.guassian_pdf(x, y), + ) + .style_func(&|&v| (&HSLColor(240.0 / 360.0 - 240.0 / 360.0 * v, 1.0, 0.7)).into()), + )?; + + root.present()?; + Ok(()) + } +} + +fn build_ui(app: >k::Application) { + let builder = gtk::Builder::from_string(UI_SOURCE); + let window: gtk::Window = builder + .object::("MainWindow") + .unwrap(); + + window.set_title(Some("Beanconqueror GUI (gtk4)")); + + let drawing_area: gtk::DrawingArea = builder.object("MainDrawingArea").unwrap(); + let pitch_scale = builder.object::("PitchScale").unwrap(); + let yaw_scale = builder.object::("YawScale").unwrap(); + let mean_x_scale = builder.object::("MeanXScale").unwrap(); + let mean_y_scale = builder.object::("MeanYScale").unwrap(); + let std_x_scale = builder.object::("SDXScale").unwrap(); + let std_y_scale = builder.object::("SDYScale").unwrap(); + + let app_state = Rc::new(RefCell::new(PlottingState { + mean_x: mean_x_scale.value(), + mean_y: mean_y_scale.value(), + std_x: std_x_scale.value(), + std_y: std_y_scale.value(), + pitch: pitch_scale.value(), + roll: yaw_scale.value(), + })); + + window.set_application(Some(app)); + + let state_cloned = app_state.clone(); + drawing_area.set_draw_func(move |widget, cr, _i, _j| { + let state = state_cloned.borrow().clone(); + let w = widget.allocated_width(); + let h = widget.allocated_height(); + let backend = CairoBackend::new(cr, (w as u32, h as u32)).unwrap(); + state.plot_pdf(backend).unwrap(); + }); + + let handle_change = + |what: >k::Scale, how: Box &mut f64 + 'static>| { + let app_state = app_state.clone(); + let drawing_area = drawing_area.clone(); + what.connect_value_changed(move |target| { + let mut state = app_state.borrow_mut(); + *how(&mut *state) = target.value(); + drawing_area.queue_draw(); + }); + }; + + handle_change(&pitch_scale, Box::new(|s| &mut s.pitch)); + handle_change(&yaw_scale, Box::new(|s| &mut s.roll)); + handle_change(&mean_x_scale, Box::new(|s| &mut s.mean_x)); + handle_change(&mean_y_scale, Box::new(|s| &mut s.mean_y)); + handle_change(&std_x_scale, Box::new(|s| &mut s.std_x)); + handle_change(&std_y_scale, Box::new(|s| &mut s.std_y)); + + window.show(); +} + fn main() { let config_file = fs::read_to_string("config.toml").expect("Can't read config.toml"); let config: Config = toml::from_str(&config_file).expect("Can't deserialize config.toml"); @@ -225,4 +347,13 @@ fn main() { .draw() .unwrap(); } + + let application = + gtk::Application::new(Some("de.dustvoice.beanconqueror-gtk"), Default::default()); + + application.connect_activate(|app| { + build_ui(app); + }); + + application.run(); } diff --git a/src/ui/beanconqueror-gtk.cmb b/src/ui/beanconqueror-gtk.cmb new file mode 100644 index 0000000..0c75b00 --- /dev/null +++ b/src/ui/beanconqueror-gtk.cmb @@ -0,0 +1,156 @@ + + + + + (1,None,"beanconqueror-gtk.ui","beanconqueror-gtk.ui",None,None,None,None,None,None), + (3,None,None,"main.ui",None,None,None,None,None,None) + + + (1,1,"GtkWindow","MainWindow",None,None,None,None,None), + (1,2,"GtkBox",None,1,None,None,None,None), + (1,9,"GtkAdjustment","MeanX",None,None,None,None,None), + (1,10,"GtkAdjustment","MeanYAdjustment",None,None,None,None,None), + (1,11,"GtkAdjustment","MeanXAdjustment",None,None,None,None,None), + (1,12,"GtkAdjustment","MeanY",None,None,None,None,None), + (1,13,"GtkAdjustment","Pitch",None,None,None,None,None), + (1,14,"GtkAdjustment","Yaw",None,None,None,None,None), + (1,15,"GtkAdjustment","SDX",None,None,None,None,None), + (1,16,"GtkAdjustment","SDY",None,None,None,None,None), + (1,39,"GtkExpander",None,2,None,None,None,None), + (1,40,"GtkGrid",None,39,None,None,None,None), + (1,41,"GtkLabel",None,40,None,None,None,None), + (1,42,"GtkLabel",None,40,None,None,None,1), + (1,43,"GtkLabel",None,40,None,None,None,2), + (1,44,"GtkLabel",None,40,None,None,None,3), + (1,45,"GtkScale","MeanXScale",40,None,None,None,4), + (1,46,"GtkScale","MeanYScale",40,None,None,None,5), + (1,47,"GtkScale","SDXScale",40,None,None,None,6), + (1,48,"GtkScale","SDYScale",40,None,None,None,7), + (1,49,"GtkLabel",None,40,None,None,None,8), + (1,50,"GtkLabel",None,40,None,None,None,9), + (1,51,"GtkScale","PitchScale",40,None,None,None,10), + (1,52,"GtkScale","YawScale",40,None,None,None,11), + (1,53,"GtkDrawingArea","MainDrawingArea",2,None,None,None,1), + (3,1,"GtkWindow","MainWindow",None,None,None,None,None), + (3,2,"GtkPaned",None,1,None,None,None,None), + (3,6,"GtkScrolledWindow","SettingsScroller",2,None,None,None,None), + (3,7,"GtkBox","SettingsPage",6,None,None,None,None), + (3,29,"GtkDrawingArea","MainGraph",2,None,None,None,1) + + + (1,1,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,2,"GtkOrientable","orientation","vertical",None,None,None,None,None), + (1,2,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,9,"GtkAdjustment","lower","-10.0",None,None,None,None,None), + (1,9,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,9,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,9,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,10,"GtkAdjustment","lower","-10.0",None,None,None,None,None), + (1,10,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,10,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,10,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,11,"GtkAdjustment","lower","-10.0",None,None,None,None,None), + (1,11,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,11,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,11,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,12,"GtkAdjustment","lower","-10.0",None,None,None,None,None), + (1,12,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,12,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,12,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,13,"GtkAdjustment","lower","-3.14",None,None,None,None,None), + (1,13,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,13,"GtkAdjustment","step-increment","0.01",None,None,None,None,None), + (1,13,"GtkAdjustment","upper","3.14",None,None,None,None,None), + (1,13,"GtkAdjustment","value","0.5",None,None,None,None,None), + (1,14,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,14,"GtkAdjustment","step-increment","0.01",None,None,None,None,None), + (1,14,"GtkAdjustment","upper","3.14",None,None,None,None,None), + (1,14,"GtkAdjustment","value","0.7299",None,None,None,None,None), + (1,15,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,15,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,15,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,15,"GtkAdjustment","value","2.0",None,None,None,None,None), + (1,16,"GtkAdjustment","page-increment","10.0",None,None,None,None,None), + (1,16,"GtkAdjustment","step-increment","1.0",None,None,None,None,None), + (1,16,"GtkAdjustment","upper","10.0",None,None,None,None,None), + (1,16,"GtkAdjustment","value","5.0",None,None,None,None,None), + (1,39,"GtkAccessible","accessible-role","progress-bar",None,None,None,None,None), + (1,40,"GtkGrid","column-homogeneous","True",None,None,None,None,None), + (1,40,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,41,"GtkLabel","label","SD Y","yes",None,None,None,None), + (1,41,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,42,"GtkLabel","label","SD X","yes",None,None,None,None), + (1,42,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,43,"GtkLabel","label","Mean Y","yes",None,None,None,None), + (1,43,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,44,"GtkLabel","label","Mean X","yes",None,None,None,None), + (1,44,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,45,"GtkRange","adjustment","9",None,None,None,None,None), + (1,45,"GtkRange","round-digits","1",None,None,None,None,None), + (1,45,"GtkScale","digits","4",None,None,None,None,None), + (1,45,"GtkScale","value-pos","left",None,None,None,None,None), + (1,46,"GtkRange","adjustment","12",None,None,None,None,None), + (1,46,"GtkRange","round-digits","1",None,None,None,None,None), + (1,46,"GtkScale","digits","4",None,None,None,None,None), + (1,46,"GtkScale","value-pos","left",None,None,None,None,None), + (1,47,"GtkRange","adjustment","15",None,None,None,None,None), + (1,47,"GtkRange","round-digits","1",None,None,None,None,None), + (1,47,"GtkScale","digits","4",None,None,None,None,None), + (1,47,"GtkScale","value-pos","left",None,None,None,None,None), + (1,48,"GtkRange","adjustment","16",None,None,None,None,None), + (1,48,"GtkRange","round-digits","1",None,None,None,None,None), + (1,48,"GtkScale","digits","4",None,None,None,None,None), + (1,48,"GtkScale","value-pos","left",None,None,None,None,None), + (1,49,"GtkLabel","label","Pitch",None,None,None,None,None), + (1,49,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,50,"GtkLabel","label","Roll","yes",None,None,None,None), + (1,50,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,51,"GtkRange","adjustment","13",None,None,None,None,None), + (1,51,"GtkRange","round-digits","1",None,None,None,None,None), + (1,51,"GtkScale","digits","4",None,None,None,None,None), + (1,51,"GtkScale","value-pos","left",None,None,None,None,None), + (1,52,"GtkRange","adjustment","14",None,None,None,None,None), + (1,52,"GtkRange","round-digits","1",None,None,None,None,None), + (1,52,"GtkScale","digits","4",None,None,None,None,None), + (1,52,"GtkScale","value-pos","left",None,None,None,None,None), + (1,53,"GtkWidget","can-focus","False",None,None,None,None,None), + (1,53,"GtkWidget","height-request","600",None,None,None,None,None), + (1,53,"GtkWidget","width-request","600",None,None,None,None,None), + (3,1,"GtkWindow","title","Beanconqueror GUI (gtk4)",None,None,None,None,None), + (3,6,"GtkWidget","margin-bottom","10",None,None,None,None,None), + (3,6,"GtkWidget","margin-end","10",None,None,None,None,None), + (3,6,"GtkWidget","margin-start","10",None,None,None,None,None), + (3,6,"GtkWidget","margin-top","10",None,None,None,None,None), + (3,7,"GtkOrientable","orientation","vertical",None,None,None,None,None), + (3,29,"GtkWidget","margin-bottom","10",None,None,None,None,None), + (3,29,"GtkWidget","margin-end","10",None,None,None,None,None), + (3,29,"GtkWidget","margin-start","10",None,None,None,None,None), + (3,29,"GtkWidget","margin-top","10",None,None,None,None,None) + + + (1,40,41,"GtkGridLayoutChild","column","2",None,None,None,None), + (1,40,41,"GtkGridLayoutChild","row","1",None,None,None,None), + (1,40,42,"GtkGridLayoutChild","column","2",None,None,None,None), + (1,40,42,"GtkGridLayoutChild","row","0",None,None,None,None), + (1,40,43,"GtkGridLayoutChild","column","0",None,None,None,None), + (1,40,43,"GtkGridLayoutChild","row","1",None,None,None,None), + (1,40,44,"GtkGridLayoutChild","column","0",None,None,None,None), + (1,40,44,"GtkGridLayoutChild","row","0",None,None,None,None), + (1,40,45,"GtkGridLayoutChild","column","1",None,None,None,None), + (1,40,45,"GtkGridLayoutChild","row","0",None,None,None,None), + (1,40,46,"GtkGridLayoutChild","column","1",None,None,None,None), + (1,40,46,"GtkGridLayoutChild","row","1",None,None,None,None), + (1,40,47,"GtkGridLayoutChild","column","3",None,None,None,None), + (1,40,47,"GtkGridLayoutChild","row","0",None,None,None,None), + (1,40,48,"GtkGridLayoutChild","column","3",None,None,None,None), + (1,40,48,"GtkGridLayoutChild","row","1",None,None,None,None), + (1,40,49,"GtkGridLayoutChild","column","0",None,None,None,None), + (1,40,49,"GtkGridLayoutChild","row","2",None,None,None,None), + (1,40,50,"GtkGridLayoutChild","column","2",None,None,None,None), + (1,40,50,"GtkGridLayoutChild","row","2",None,None,None,None), + (1,40,51,"GtkGridLayoutChild","column","1",None,None,None,None), + (1,40,51,"GtkGridLayoutChild","row","2",None,None,None,None), + (1,40,52,"GtkGridLayoutChild","column","3",None,None,None,None), + (1,40,52,"GtkGridLayoutChild","row","2",None,None,None,None) + + diff --git a/src/ui/beanconqueror-gtk.ui b/src/ui/beanconqueror-gtk.ui new file mode 100644 index 0000000..b918238 --- /dev/null +++ b/src/ui/beanconqueror-gtk.ui @@ -0,0 +1,214 @@ + + + + + + + False + + + False + vertical + + + progress-bar + + + False + True + + + False + SD Y + + 2 + 1 + + + + + + False + SD X + + 2 + 0 + + + + + + False + Mean Y + + 0 + 1 + + + + + + False + Mean X + + 0 + 0 + + + + + + MeanX + 4 + 1 + left + + 1 + 0 + + + + + + MeanY + 4 + 1 + left + + 1 + 1 + + + + + + SDX + 4 + 1 + left + + 3 + 0 + + + + + + SDY + 4 + 1 + left + + 3 + 1 + + + + + + False + Pitch + + 0 + 2 + + + + + + False + Roll + + 2 + 2 + + + + + + Pitch + 4 + 1 + left + + 1 + 2 + + + + + + Yaw + 4 + 1 + left + + 3 + 2 + + + + + + + + + + False + 600 + 600 + + + + + + + -10.0 + 10.0 + 1.0 + 10.0 + + + -10.0 + 10.0 + 1.0 + 10.0 + + + -10.0 + 10.0 + 1.0 + 10.0 + + + -10.0 + 10.0 + 1.0 + 10.0 + + + -3.14 + 10.0 + 0.01 + 3.14 + 0.5 + + + 10.0 + 0.01 + 3.14 + 0.7299 + + + 10.0 + 1.0 + 10.0 + 2.0 + + + 10.0 + 1.0 + 10.0 + 5.0 + + diff --git a/src/ui/main.ui b/src/ui/main.ui new file mode 100644 index 0000000..6c96d8c --- /dev/null +++ b/src/ui/main.ui @@ -0,0 +1,33 @@ + + + + + + Beanconqueror GUI (gtk4) + + + + + 10 + 10 + 10 + 10 + + + vertical + + + + + + + 10 + 10 + 10 + 10 + + + + + +