Integrate the demo gtk project into beanconqueror

This commit is contained in:
David Holland 2022-10-05 14:47:12 +02:00
parent 590c2b37e0
commit 6da6fd8326
Signed by: DustVoice
GPG Key ID: 47068995A14EDCA9
6 changed files with 1080 additions and 39 deletions

526
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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::<Vec<&str>>());
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::<Vec<f64>>();
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::<Vec<f64>>();
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<f64>) -> Option<Data> {
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<f64>) -> Option<Data> {
}
}
#[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<dyn Error + 'a>> {
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: &gtk::Application) {
let builder = gtk::Builder::from_string(UI_SOURCE);
let window: gtk::Window = builder
.object::<gtk::Window>("MainWindow")
.unwrap();
window.set_title(Some("Beanconqueror GUI (gtk4)"));
let drawing_area: gtk::DrawingArea = builder.object("MainDrawingArea").unwrap();
let pitch_scale = builder.object::<gtk::Scale>("PitchScale").unwrap();
let yaw_scale = builder.object::<gtk::Scale>("YawScale").unwrap();
let mean_x_scale = builder.object::<gtk::Scale>("MeanXScale").unwrap();
let mean_y_scale = builder.object::<gtk::Scale>("MeanYScale").unwrap();
let std_x_scale = builder.object::<gtk::Scale>("SDXScale").unwrap();
let std_y_scale = builder.object::<gtk::Scale>("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: &gtk::Scale, how: Box<dyn Fn(&mut PlottingState) -> &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();
}

View File

@ -0,0 +1,156 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project version="0.10.3" target_tk="gtk-4.0">
<ui>
(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)
</ui>
<object>
(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)
</object>
<object_property>
(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)
</object_property>
<object_layout_property>
(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)
</object_layout_property>
</cambalache-project>

214
src/ui/beanconqueror-gtk.ui Normal file
View File

@ -0,0 +1,214 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.3 -->
<interface>
<!-- interface-name beanconqueror-gtk.ui -->
<requires lib="gtk" version="4.6"/>
<object class="GtkWindow" id="MainWindow">
<property name="can-focus">False</property>
<child>
<object class="GtkBox">
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkExpander">
<property name="accessible-role">progress-bar</property>
<child>
<object class="GtkGrid">
<property name="can-focus">False</property>
<property name="column-homogeneous">True</property>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">SD Y</property>
<layout>
<property name="column">2</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">SD X</property>
<layout>
<property name="column">2</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Mean Y</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Mean X</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="MeanXScale">
<property name="adjustment">MeanX</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="MeanYScale">
<property name="adjustment">MeanY</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="SDXScale">
<property name="adjustment">SDX</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">3</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="SDYScale">
<property name="adjustment">SDY</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">3</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label">Pitch</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="can-focus">False</property>
<property name="label" translatable="yes">Roll</property>
<layout>
<property name="column">2</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="PitchScale">
<property name="adjustment">Pitch</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkScale" id="YawScale">
<property name="adjustment">Yaw</property>
<property name="digits">4</property>
<property name="round-digits">1</property>
<property name="value-pos">left</property>
<layout>
<property name="column">3</property>
<property name="row">2</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkDrawingArea" id="MainDrawingArea">
<property name="can-focus">False</property>
<property name="height-request">600</property>
<property name="width-request">600</property>
</object>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="MeanX">
<property name="lower">-10.0</property>
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
</object>
<object class="GtkAdjustment" id="MeanYAdjustment">
<property name="lower">-10.0</property>
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
</object>
<object class="GtkAdjustment" id="MeanXAdjustment">
<property name="lower">-10.0</property>
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
</object>
<object class="GtkAdjustment" id="MeanY">
<property name="lower">-10.0</property>
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
</object>
<object class="GtkAdjustment" id="Pitch">
<property name="lower">-3.14</property>
<property name="page-increment">10.0</property>
<property name="step-increment">0.01</property>
<property name="upper">3.14</property>
<property name="value">0.5</property>
</object>
<object class="GtkAdjustment" id="Yaw">
<property name="page-increment">10.0</property>
<property name="step-increment">0.01</property>
<property name="upper">3.14</property>
<property name="value">0.7299</property>
</object>
<object class="GtkAdjustment" id="SDX">
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
<property name="value">2.0</property>
</object>
<object class="GtkAdjustment" id="SDY">
<property name="page-increment">10.0</property>
<property name="step-increment">1.0</property>
<property name="upper">10.0</property>
<property name="value">5.0</property>
</object>
</interface>

33
src/ui/main.ui Normal file
View File

@ -0,0 +1,33 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.10.3 -->
<interface>
<requires lib="gtk" version="4.6"/>
<object class="GtkWindow" id="MainWindow">
<property name="title">Beanconqueror GUI (gtk4)</property>
<child>
<object class="GtkPaned">
<child>
<object class="GtkScrolledWindow" id="SettingsScroller">
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
<child>
<object class="GtkBox" id="SettingsPage">
<property name="orientation">vertical</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkDrawingArea" id="MainGraph">
<property name="margin-bottom">10</property>
<property name="margin-end">10</property>
<property name="margin-start">10</property>
<property name="margin-top">10</property>
</object>
</child>
</object>
</child>
</object>
</interface>