Compare commits

..

No commits in common. "main" and "0.2.0" have entirely different histories.
main ... 0.2.0

12 changed files with 499 additions and 545 deletions

346
Cargo.lock generated
View File

@ -1,7 +1,5 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "CoreFoundation-sys" name = "CoreFoundation-sys"
version = "0.1.4" version = "0.1.4"
@ -23,12 +21,6 @@ dependencies = [
"mach 0.1.2", "mach 0.1.2",
] ]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.2.0" version = "1.2.0"
@ -52,21 +44,23 @@ checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
[[package]] [[package]]
name = "atk" name = "atk"
version = "0.15.1" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c3d816ce6f0e2909a96830d6911c2aff044370b1ef92d7f267b43bae5addedd" checksum = "812b4911e210bd51b24596244523c856ca749e6223c50a7fbbba3f89ee37c426"
dependencies = [ dependencies = [
"atk-sys", "atk-sys",
"bitflags", "bitflags",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
] ]
[[package]] [[package]]
name = "atk-sys" name = "atk-sys"
version = "0.15.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58aeb089fb698e06db8089971c7ee317ab9644bade33383f63631437b03aafb6" checksum = "f530e4af131d94cc4fa15c5c9d0348f0ef28bac64ba660b6b2a1cf2605dedfce"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -82,28 +76,36 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]] [[package]]
name = "cairo-rs" name = "cairo-rs"
version = "0.15.6" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8b14c80d8d1a02fa6d914b9d1afeeca9bc34257f8300d9696e1e331ae114223" checksum = "c5c0f2e047e8ca53d0ff249c54ae047931d7a6ebe05d00af73e0ffeb6e34bdb8"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-sys-rs", "cairo-sys-rs",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "cairo-sys-rs" name = "cairo-sys-rs"
version = "0.15.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c55d429bef56ac9172d25fecb85dc8068307d17acd74b377866b7a1ef25d3c8" checksum = "2ed2639b9ad5f1d6efa76de95558e11339e7318426d84ac4890b86c03e828ca7"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@ -116,15 +118,6 @@ version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
[[package]]
name = "cfg-expr"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e068cb2806bbc15b439846dc16c5f89f8599f2c3e4d73d4449d38f9b2f0b6c5"
dependencies = [
"smallvec",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
@ -139,31 +132,28 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.3.2" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
] ]
[[package]] [[package]]
name = "deflate" name = "deflate"
version = "1.0.0" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
dependencies = [ dependencies = [
"adler32", "adler32",
"byteorder",
] ]
[[package]] [[package]]
name = "field-offset" name = "either"
version = "0.3.4" version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e1c54951450cbd39f3dbcf1005ac413b49487dabf18a720ad2383eccfeffb92" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
dependencies = [
"memoffset",
"rustc_version",
]
[[package]] [[package]]
name = "fuchsia-cprng" name = "fuchsia-cprng"
@ -171,6 +161,21 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "futures"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.14" version = "0.3.14"
@ -178,6 +183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25" checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink",
] ]
[[package]] [[package]]
@ -203,6 +209,24 @@ version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04" checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
[[package]]
name = "futures-macro"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.14" version = "0.3.14"
@ -215,47 +239,60 @@ version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025" checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
dependencies = [ dependencies = [
"futures-channel",
"futures-core", "futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task", "futures-task",
"memchr",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
"proc-macro-hack",
"proc-macro-nested",
"slab", "slab",
] ]
[[package]] [[package]]
name = "gdk" name = "gdk"
version = "0.15.4" version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6e05c1f572ab0e1f15be94217f0dc29088c248b14f792a5ff0af0d84bcda9e8" checksum = "db00839b2a68a7a10af3fa28dfb3febaba3a20c3a9ac2425a33b7df1f84a6b7d"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
"cairo-sys-rs",
"gdk-pixbuf", "gdk-pixbuf",
"gdk-sys", "gdk-sys",
"gio", "gio",
"gio-sys",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
"pango", "pango",
] ]
[[package]] [[package]]
name = "gdk-pixbuf" name = "gdk-pixbuf"
version = "0.15.6" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8750501d75f318c2ec0314701bc8403901303210def80bafd13f6b6059a3f45" checksum = "8f6dae3cb99dd49b758b88f0132f8d401108e63ae8edd45f432d42cdff99998a"
dependencies = [ dependencies = [
"bitflags",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
"gio", "gio",
"gio-sys",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
] ]
[[package]] [[package]]
name = "gdk-pixbuf-sys" name = "gdk-pixbuf-sys"
version = "0.15.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413424d9818621fa3cfc8a3a915cdb89a7c3c507d56761b4ec83a9a98e587171" checksum = "3bfe468a7f43e97b8d193a762b6c5cf67a7d36cacbc0b9291dbcae24bfea1e8f"
dependencies = [ dependencies = [
"gio-sys", "gio-sys",
"glib-sys", "glib-sys",
@ -266,9 +303,9 @@ dependencies = [
[[package]] [[package]]
name = "gdk-sys" name = "gdk-sys"
version = "0.15.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32e7a08c1e8f06f4177fb7e51a777b8c1689f743a7bc11ea91d44d2226073a88" checksum = "0a9653cfc500fd268015b1ac055ddbc3df7a5c9ea3f4ccef147b3957bd140d69"
dependencies = [ dependencies = [
"cairo-sys-rs", "cairo-sys-rs",
"gdk-pixbuf-sys", "gdk-pixbuf-sys",
@ -294,16 +331,20 @@ dependencies = [
[[package]] [[package]]
name = "gio" name = "gio"
version = "0.15.6" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96efd8a1c00d890f6b45671916e165b5e43ccec61957d443aff6d7e44f62d348" checksum = "1fb60242bfff700772dae5d9e3a1f7aa2e4ebccf18b89662a16acb2822568561"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"futures",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-io", "futures-io",
"futures-util",
"gio-sys", "gio-sys",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
"once_cell", "once_cell",
"thiserror", "thiserror",
@ -311,9 +352,9 @@ dependencies = [
[[package]] [[package]]
name = "gio-sys" name = "gio-sys"
version = "0.15.6" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0fa5052773f5a56b8ae47dab09d040f5d9ce1311f4f99006e16e9a08269296" checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -324,32 +365,32 @@ dependencies = [
[[package]] [[package]]
name = "glib" name = "glib"
version = "0.15.6" version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa570813c504bdf7539a9400180c2dd4b789a819556fb86da7226d7d1b037b49" checksum = "0c685013b7515e668f1b57a165b009d4d28cb139a8a989bbd699c10dad29d0c5"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-executor", "futures-executor",
"futures-task", "futures-task",
"futures-util",
"glib-macros", "glib-macros",
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
"libc", "libc",
"once_cell", "once_cell",
"smallvec",
"thiserror",
] ]
[[package]] [[package]]
name = "glib-macros" name = "glib-macros"
version = "0.15.6" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41bfd8d227dead0829ac142454e97531b93f576d0805d779c42bfd799c65c572" checksum = "41486a26d1366a8032b160b59065a59fb528530a46a49f627e7048fb8c064039"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"heck", "heck",
"itertools",
"proc-macro-crate", "proc-macro-crate",
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
@ -359,9 +400,9 @@ dependencies = [
[[package]] [[package]]
name = "glib-sys" name = "glib-sys"
version = "0.15.6" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4366377bd56697de8aaee24e673c575d2694d72e7756324ded2b0428829a7b8" checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1"
dependencies = [ dependencies = [
"libc", "libc",
"system-deps", "system-deps",
@ -369,9 +410,9 @@ dependencies = [
[[package]] [[package]]
name = "gobject-sys" name = "gobject-sys"
version = "0.15.5" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a" checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"libc", "libc",
@ -380,32 +421,37 @@ dependencies = [
[[package]] [[package]]
name = "gtk" name = "gtk"
version = "0.15.4" version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2d1326b36af927fe46ae2f89a8fec38c6f0d279ebc5ef07ffeeabb70300bfc" checksum = "2f022f2054072b3af07666341984562c8e626a79daa8be27b955d12d06a5ad6a"
dependencies = [ dependencies = [
"atk", "atk",
"bitflags", "bitflags",
"cairo-rs", "cairo-rs",
"field-offset", "cairo-sys-rs",
"futures-channel", "cc",
"gdk", "gdk",
"gdk-pixbuf", "gdk-pixbuf",
"gdk-pixbuf-sys",
"gdk-sys",
"gio", "gio",
"gio-sys",
"glib", "glib",
"glib-sys",
"gobject-sys",
"gtk-sys", "gtk-sys",
"gtk3-macros",
"libc", "libc",
"once_cell", "once_cell",
"pango", "pango",
"pango-sys",
"pkg-config", "pkg-config",
] ]
[[package]] [[package]]
name = "gtk-sys" name = "gtk-sys"
version = "0.15.3" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5bc2f0587cba247f60246a0ca11fe25fb733eabc3de12d1965fc07efab87c84" checksum = "89acda6f084863307d948ba64a4b1ef674e8527dddab147ee4cdcc194c880457"
dependencies = [ dependencies = [
"atk-sys", "atk-sys",
"cairo-sys-rs", "cairo-sys-rs",
@ -419,25 +465,14 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "gtk3-macros"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24f518afe90c23fba585b2d7697856f9e6a7bbc62f65588035e66f6afb01a2e9"
dependencies = [
"anyhow",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.4.0" version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
dependencies = [
"unicode-segmentation",
]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
@ -448,6 +483,15 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.94" version = "0.2.94"
@ -503,26 +547,17 @@ dependencies = [
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.1" version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.5.1" version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
dependencies = [ dependencies = [
"adler", "adler32",
] ]
[[package]] [[package]]
@ -556,12 +591,14 @@ checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
[[package]] [[package]]
name = "pango" name = "pango"
version = "0.15.6" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c7420fc01a390ec200da7395b64d705f5d82fe03e5d0708aee422c46538be7" checksum = "9937068580bebd8ced19975938573803273ccbcbd598c58d4906efd4ac87c438"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"glib", "glib",
"glib-sys",
"gobject-sys",
"libc", "libc",
"once_cell", "once_cell",
"pango-sys", "pango-sys",
@ -569,9 +606,9 @@ dependencies = [
[[package]] [[package]]
name = "pango-sys" name = "pango-sys"
version = "0.15.1" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7022c2fb88cd2d9d55e1a708a8c53a3ae8678234c4a54bf623400aeb7f31fac2" checksum = "24d2650c8b62d116c020abd0cea26a4ed96526afda89b1c4ea567131fdefc890"
dependencies = [ dependencies = [
"glib-sys", "glib-sys",
"gobject-sys", "gobject-sys",
@ -579,15 +616,6 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.6" version = "0.2.6"
@ -608,9 +636,9 @@ checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]] [[package]]
name = "png" name = "png"
version = "0.17.5" version = "0.16.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"crc32fast", "crc32fast",
@ -626,11 +654,10 @@ checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]] [[package]]
name = "proc-macro-crate" name = "proc-macro-crate"
version = "1.1.3" version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
dependencies = [ dependencies = [
"thiserror",
"toml", "toml",
] ]
@ -659,10 +686,22 @@ dependencies = [
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro-hack"
version = "1.0.36" version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro-nested"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]]
name = "proc-macro2"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -780,33 +819,6 @@ version = "0.6.23"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
[[package]]
name = "rustc_version"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.125" version = "1.0.125"
@ -837,16 +849,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527"
[[package]] [[package]]
name = "smallvec" name = "strum"
version = "1.8.0" version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
[[package]]
name = "strum_macros"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.86" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -855,20 +879,22 @@ dependencies = [
[[package]] [[package]]
name = "system-deps" name = "system-deps"
version = "6.0.2" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
dependencies = [ dependencies = [
"cfg-expr",
"heck", "heck",
"pkg-config", "pkg-config",
"strum",
"strum_macros",
"thiserror",
"toml", "toml",
"version-compare", "version-compare",
] ]
[[package]] [[package]]
name = "tarangam" name = "tarangam"
version = "0.3.1" version = "0.2.0"
dependencies = [ dependencies = [
"cairo-rs", "cairo-rs",
"gdk", "gdk",
@ -935,10 +961,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "ucd-trie" name = "unicode-segmentation"
version = "0.1.3" version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-xid"
@ -948,9 +974,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]] [[package]]
name = "version-compare" name = "version-compare"
version = "0.1.0" version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73" checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]] [[package]]
name = "version_check" name = "version_check"

View File

@ -1,31 +1,25 @@
[package] [package]
name = "tarangam" name = "tarangam"
version = "0.3.1" version = "0.2.0"
authors = ["PiyushXCoder <piyush.raj.kit@gmail.com>"] authors = ["PiyushXCoder <piyush.raj.kit@gmail.com>"]
license = "GPL-3.0-only" license = "GPL 3.0"
edition = "2018" edition = "2018"
description = "A simple serial plotter. एक सरल सीरीय्ल पलौटर।" documentation = "A simple serial plotter. एक सरल सीरीय्ल पलौटर।"
readme = "README.md" readme = "README.md"
repository = "https://github.com/PiyushXCoder/Tarangam" repository = "https://github.com/PiyushXCoder/Tarangam"
keywords = ["plotter", "serial", "serialplotter", "arduino", "gtk"] keywords = ["plotter","serial","serialplotter","arduino","gtk"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
tokio = { version = "1.5.0", features = [ tokio = { version = "1.5.0", features = ["rt", "rt-multi-thread", "macros", "time", "sync"] }
"rt", gtk = "0.9.2"
"rt-multi-thread", gdk = "0.13.2"
"macros", gio = "0.9.1"
"time", glib = "0.10.3"
"sync", png = "0.16.8"
] } cairo-rs = { version = "0.9.1", features = ["png"] }
gtk = "0.15"
gdk = "0.15"
gio = "0.15"
glib = "0.15"
png = "0.17"
cairo-rs = { version = "0.15", features = ["png"] }
rand = "0.8.1" rand = "0.8.1"
libmath = "0.2.1" libmath = "0.2.1"
serialport = "4.0.1" serialport = "4.0.1"

View File

@ -1,5 +1,6 @@
# Tarangam # Tarangam
It is a straightforward application to see the logs from [serial ports](https://wiki.osdev.org/Serial_Ports) and plot information on graph. You can use it with IOT boards ([Arduino](https://www.arduino.cc/), [ESP boards](https://www.espressif.com/),...) in your DIY projects. It gives many basic controls to modify the graph.
It is a simple application to see log from [serialports](https://wiki.osdev.org/Serial_Ports) and plot information on graph. You can use it with IOT boards([ardino](https://www.arduino.cc/), [esp boards](https://www.espressif.com/),...) in you DIY projects. It gives to many basic controls to control graph.
## Interface ## Interface
![1](screenshots/1.png) ![1](screenshots/1.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -1,23 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg <svg
width="256" xmlns:dc="http://purl.org/dc/elements/1.1/"
height="256" xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1000"
height="1000"
viewBox="0 0 1000 1000" viewBox="0 0 1000 1000"
version="1.1" version="1.1"
id="svg8" id="svg8"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
sodipodi:docname="chitra.svg" sodipodi:docname="icon.svg">
inkscape:export-filename="/home/piyush/Projects/tarangam/chitra-small.png"
inkscape:export-xdpi="24"
inkscape:export-ydpi="24"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs <defs
id="defs2"> id="defs2">
<linearGradient <linearGradient
@ -50,20 +47,19 @@
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="0.35" inkscape:zoom="0.35"
inkscape:cx="607.14286" inkscape:cx="605.76766"
inkscape:cy="250" inkscape:cy="248.85918"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="layer1" inkscape:current-layer="layer1"
inkscape:document-rotation="0" inkscape:document-rotation="0"
showgrid="false" showgrid="false"
inkscape:window-width="1920" inkscape:window-width="1214"
inkscape:window-height="1002" inkscape:window-height="757"
inkscape:window-x="0" inkscape:window-x="295"
inkscape:window-y="27" inkscape:window-y="198"
inkscape:window-maximized="1" inkscape:window-maximized="0"
units="px" units="px"
showguides="false" showguides="false">
inkscape:pagecheckerboard="1">
<inkscape:grid <inkscape:grid
type="xygrid" type="xygrid"
id="grid869" /> id="grid869" />

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -20,42 +20,41 @@
use gtk::prelude::*; use gtk::prelude::*;
use gtk::DrawingArea; use gtk::DrawingArea;
use std::rc::Rc;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
/// A single line /// A single line
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Line { pub struct Line {
pub(crate) points: Vec<(f64, f64)>, pub points: Vec<(f64,f64)>,
pub(crate) color: (f64, f64, f64), pub color: (f64, f64, f64)
} }
impl Line { impl Line {
pub(crate) fn new(r: f64, g: f64, b: f64, points: Vec<(f64, f64)>) -> Self { pub fn new(r: f64, g: f64, b: f64, points: Vec<(f64,f64)>) -> Self {
Line { Line {
points, points,
color: (r, g, b), color: (r,g,b)
} }
} }
} }
/// Tools to draw Graph /// Tools to draw Graph
pub(crate) struct Graph { pub struct Graph {
pub(crate) area: DrawingArea, pub area: DrawingArea,
pub(crate) scale_x_start: f64, // start of x on pankti pub scale_x_start: f64, // start of x on pankti
pub(crate) scale_x_size: f64, // size of pankti to show pub scale_x_size: f64, // size of pankti to show
pub(crate) scale_y_start: f64, // start of y on stambh pub scale_y_start: f64, // start of y on stambh
pub(crate) scale_y_size: f64, // size of stambh to show pub scale_y_size: f64, // size of stambh to show
pub(crate) draw_patch: bool, // enable to draw circle spot on line pub draw_patch: bool, // enable to draw circle spot on line
pub(crate) draw_box: bool, // enable to show boxes linke graph paper pub draw_box: bool, // enable to show boxes linke graph paper
pub(crate) draw_baarik_box: bool, // enable to show baarik(similar meaning to smaller) linke graph paper pub draw_baarik_box: bool, // enable to show baarik(similar meaning to smaller) linke graph paper
pub(crate) auto_adjust_y: bool, // enable to automatically adjust y axis pub auto_adjust_y: bool, // enable to automatically adjust y axis
pub(crate) lines: HashMap<String, Line>, pub lines: HashMap<String, Line>,
pub(crate) pankti_sankya: f64, // use used while adding to point in lines to see last count of graphable input pub pankti_sankya: f64 // use used while adding to point in lines to see last count of graphable input
} }
impl Graph { impl Graph {
pub(crate) fn new( pub fn new(area: DrawingArea,
area: DrawingArea,
scale_x_start: f64, scale_x_start: f64,
scale_x_size: f64, scale_x_size: f64,
scale_y_start: f64, scale_y_start: f64,
@ -65,8 +64,8 @@ impl Graph {
draw_baarik_box: bool, draw_baarik_box: bool,
auto_adjust_y: bool, auto_adjust_y: bool,
lines: HashMap<String, Line>, lines: HashMap<String, Line>,
pankti_sankya: f64, pankti_sankya: f64) -> Rc<RefCell<Self>> {
) -> Rc<RefCell<Self>> {
let graph = Rc::new(RefCell::new(Graph { let graph = Rc::new(RefCell::new(Graph {
area, area,
scale_x_start, scale_x_start,
@ -78,11 +77,11 @@ impl Graph {
draw_baarik_box, draw_baarik_box,
auto_adjust_y, auto_adjust_y,
lines, lines,
pankti_sankya, pankti_sankya
})); }));
let graph_tmp = Rc::clone(&graph); let graph_tmp = Rc::clone(&graph);
graph.borrow().area.connect_draw(move |area, ctx| { graph.borrow().area.connect_draw(move |area,ctx| {
Graph::draw(area, ctx, &graph_tmp); Graph::draw(area, ctx, &graph_tmp);
Inhibit(false) Inhibit(false)
}); });
@ -91,29 +90,22 @@ impl Graph {
} }
/// used to draw box and baarik box /// used to draw box and baarik box
fn draw_boxes( fn draw_boxes(ctx: &cairo::Context, area_width: f64, area_height: f64, src_x: f64, cell_size: f64, color: f64) {
ctx: &cairo::Context,
area_width: f64,
area_height: f64,
src_x: f64,
cell_size: f64,
color: f64,
) {
ctx.set_source_rgb(color, color, color); ctx.set_source_rgb(color, color, color);
ctx.set_line_width(1.0); ctx.set_line_width(1.0);
// lines parallel to stambh // lines parallel to stambh
for i in 1..math::round::ceil(area_width / cell_size, 0) as i32 { for i in 1..math::round::ceil(area_width/cell_size, 0) as i32 {
let xi = i as f64 * cell_size + src_x; let xi = i as f64 * cell_size + src_x;
ctx.move_to(xi, 0.0); ctx.move_to(xi, 0.0);
ctx.line_to(xi, area_height); ctx.line_to(xi, area_height);
} }
// lines parallel to pankti // lines parallel to pankti
for i in 1..math::round::ceil(area_height / cell_size, 0) as i32 { for i in 1..math::round::ceil(area_height/cell_size, 0) as i32 {
let yi = area_height - i as f64 * cell_size; let yi = area_height - i as f64 * cell_size;
ctx.move_to(src_x, yi); ctx.move_to(src_x, yi);
ctx.line_to(area_width + src_x, yi); ctx.line_to(area_width + src_x, yi);
} }
ctx.stroke().unwrap(); ctx.stroke();
} }
/// transform point to show on graph /// transform point to show on graph
@ -127,25 +119,27 @@ impl Graph {
scale_x_size: f64, scale_x_size: f64,
scale_y_size: f64, scale_y_size: f64,
height: f64, height: f64,
stambh_scale_width: f64, stambh_scale_width: f64) -> (f64, f64){
) -> (f64, f64) {
( (
((p - p_start) * aa_dumm_pankti) / scale_x_size + stambh_scale_width, ((p - p_start) * aa_dumm_pankti)/scale_x_size + stambh_scale_width,
height - ((s - s_start) * aa_dumm_stambh) / scale_y_size, height - ((s - s_start) * aa_dumm_stambh) / scale_y_size
) )
} }
/// callback of drawing area to draw graph /// callback of drawing area to draw graph
fn draw(area: &gtk::DrawingArea, ctx: &cairo::Context, graph: &Rc<RefCell<Graph>>) { fn draw(area: &gtk::DrawingArea,
ctx: &cairo::Context,
graph: &Rc<RefCell<Graph>>) {
let graph = graph.borrow(); let graph = graph.borrow();
ctx.set_source_rgb(0.1, 0.5, 0.5); ctx.set_source_rgb(0.1, 0.5, 0.5);
ctx.paint().unwrap(); ctx.paint();
let pankti_scale_height = 50.0; let pankti_scale_height = 50.0;
let stambh_scale_width = 60.0; let stambh_scale_width = 60.0;
let width = area.allocated_width() as f64 - stambh_scale_width; let width = area.get_allocated_width() as f64 - stambh_scale_width;
let height = area.allocated_height() as f64 - pankti_scale_height; let height = area.get_allocated_height() as f64 - pankti_scale_height;
let manjusa_maap = 50.0; let manjusa_maap = 50.0;
@ -170,10 +164,10 @@ impl Graph {
ctx.set_line_width(2.0); ctx.set_line_width(2.0);
ctx.set_line_cap(cairo::LineCap::Round); ctx.set_line_cap(cairo::LineCap::Round);
let draw_patch = graph.draw_patch; let draw_patch = graph.draw_patch;
for (_, line) in graph.lines.iter() { for (_,line) in graph.lines.iter() {
for (i, (p, s)) in line.points.iter().enumerate() { for (i, (p,s)) in line.points.iter().enumerate() {
// check if point is last poin on line // check if point is last poin on line
let (p_dumm, s_dumm) = if i < line.points.len() - 1 { let (p_dumm, s_dumm) = if i < line.points.len() - 1 {
line.points[i + 1] line.points[i + 1]
} else { } else {
line.points[i] line.points[i]
@ -208,19 +202,14 @@ impl Graph {
ctx.set_source_rgb(line.color.0, line.color.1, line.color.2); ctx.set_source_rgb(line.color.0, line.color.1, line.color.2);
ctx.move_to(bindu_dumm_t.0, bindu_dumm_t.1); ctx.move_to(bindu_dumm_t.0, bindu_dumm_t.1);
ctx.line_to(bindu_t.0, bindu_t.1); ctx.line_to(bindu_t.0, bindu_t.1);
ctx.stroke().unwrap(); ctx.stroke();
// draw circle over point // draw circle over point
if draw_patch { if draw_patch {
ctx.set_source_rgb(0.0, 0.0, 1.0); ctx.set_source_rgb(0.0, 0.0, 1.0);
ctx.arc( ctx.arc(bindu_dumm_t.0, bindu_dumm_t.1,
bindu_dumm_t.0, 5.0, 0.0, std::f64::consts::PI * 2.0);
bindu_dumm_t.1, ctx.stroke();
5.0,
0.0,
std::f64::consts::PI * 2.0,
);
ctx.stroke().unwrap();
} }
} }
} }
@ -229,41 +218,33 @@ impl Graph {
ctx.set_source_rgb(0.1, 0.4, 0.4); ctx.set_source_rgb(0.1, 0.4, 0.4);
ctx.rectangle(0.0, 0.0, stambh_scale_width, height + pankti_scale_height); ctx.rectangle(0.0, 0.0, stambh_scale_width, height + pankti_scale_height);
ctx.rectangle(stambh_scale_width, height, width, pankti_scale_height); ctx.rectangle(stambh_scale_width, height, width, pankti_scale_height);
ctx.fill().unwrap(); ctx.fill();
ctx.set_source_rgb(1.0, 1.0, 1.0); ctx.set_source_rgb(1.0, 1.0, 1.0);
// write numbers on pankti scale // write numbers on pankti scale
for i in 0..(rekha_sankhya_pankti as i32 + 1) { for i in 0..(rekha_sankhya_pankti as i32 + 1) {
let text = let text = math::round::floor(i as f64 * anupat_pankti + graph.scale_x_start, 4).to_string();
math::round::floor(i as f64 * anupat_pankti + graph.scale_x_start, 4).to_string(); let f = ctx.text_extents(&text);
let f = ctx.text_extents(&text).expect("Text dimension"); ctx.move_to(i as f64 * manjusa_maap - f.width + stambh_scale_width + f.height / 0.866, height + f.width * 0.5 + f.height);
ctx.move_to( ctx.save();
i as f64 * manjusa_maap - f.width + stambh_scale_width + f.height / 0.866,
height + f.width * 0.5 + f.height,
);
ctx.save().unwrap();
ctx.rotate(std::f64::consts::PI / -6.0); ctx.rotate(std::f64::consts::PI / -6.0);
ctx.show_text(&text).unwrap(); ctx.show_text(&text);
ctx.restore().unwrap(); ctx.restore();
} }
// write numbers on stambh scale // write numbers on stambh scale
for i in (0..aa_dumm_stambh as i32 + 1).rev() { for i in (0..aa_dumm_stambh as i32 + 1).rev() {
let text = let text = math::round::floor(i as f64 * anupat_stambh + graph.scale_y_start, 4).to_string();
math::round::floor(i as f64 * anupat_stambh + graph.scale_y_start, 4).to_string(); let f = ctx.text_extents(&text);
let f = ctx.text_extents(&text).expect("Text dimension"); ctx.move_to(stambh_scale_width - f.width, height - i as f64 * manjusa_maap + f.width * 0.5);
ctx.move_to( ctx.save();
stambh_scale_width - f.width,
height - i as f64 * manjusa_maap + f.width * 0.5,
);
ctx.save().unwrap();
ctx.rotate(std::f64::consts::PI / -6.0); ctx.rotate(std::f64::consts::PI / -6.0);
ctx.show_text(&text).unwrap(); ctx.show_text(&text);
ctx.restore().unwrap(); ctx.restore();
} }
} }
/// Adjust stambh and pankti as needed , trim lines and redraws /// Adjust stambh and pankti as needed , trim lines and redraws
pub(crate) fn redraw(&mut self) { pub fn redraw(&mut self) {
let (mx_x, mi_x, mx_y, mi_y) = self.get_extremes(); let (mx_x, mi_x, mx_y, mi_y) = self.get_extremes();
// stambh // stambh
@ -275,10 +256,10 @@ impl Graph {
// pankti // pankti
let spread = (mx_x - mi_x).abs(); let spread = (mx_x - mi_x).abs();
if spread < self.scale_x_size { if spread < self.scale_x_size {
self.scale_x_start = mi_x; self.scale_x_start = mi_x;
} else { } else {
self.scale_x_start = mx_x - self.scale_x_size; self.scale_x_start = mx_x - self.scale_x_size;
} }
self.trim_lines(); // trim self.trim_lines(); // trim
@ -286,16 +267,16 @@ impl Graph {
} }
/// find minimun and maximum value from all lines /// find minimun and maximum value from all lines
pub(crate) fn get_extremes(&self) -> (f64, f64, f64, f64) { pub fn get_extremes(&self) -> (f64, f64, f64, f64){
// trick to avoid no lines // trick to avoid no lines
if self.lines.len() == 0 { if self.lines.len() == 0 {
return (0.0, 0.0, 0.0, 0.0); return (0.0,0.0,0.0,0.0);
} }
let mut mx_x: Option<f64> = None; let mut mx_x:Option<f64> = None;
let mut mi_x: Option<f64> = None; let mut mi_x:Option<f64> = None;
let mut mx_y: Option<f64> = None; let mut mx_y:Option<f64> = None;
let mut mi_y: Option<f64> = None; let mut mi_y:Option<f64> = None;
for (_, line) in self.lines.iter() { for (_, line) in self.lines.iter() {
if line.points.len() == 0 { if line.points.len() == 0 {
@ -326,7 +307,7 @@ impl Graph {
mi_y = Some(line.points[0].1); mi_y = Some(line.points[0].1);
} }
for (x, y) in line.points.iter().skip(1) { for (x,y) in line.points.iter().skip(1) {
mx_x = Some(f64::max(mx_x.unwrap(), *x)); mx_x = Some(f64::max(mx_x.unwrap(), *x));
mi_x = Some(f64::min(mi_x.unwrap(), *x)); mi_x = Some(f64::min(mi_x.unwrap(), *x));
mx_y = Some(f64::max(mx_y.unwrap(), *y)); mx_y = Some(f64::max(mx_y.unwrap(), *y));
@ -339,16 +320,17 @@ impl Graph {
// tims line form left side of line. Why left?? to avoid wasting time in ponits in range // tims line form left side of line. Why left?? to avoid wasting time in ponits in range
// it skips i point out of screen to keep a non terminating line experience // it skips i point out of screen to keep a non terminating line experience
pub(crate) fn trim_lines(&mut self) { pub fn trim_lines(&mut self) {
for (_, line) in self.lines.iter_mut() { for (_, line) in self.lines.iter_mut() {
let mut i = 0; let mut i = 0;
while i < line.points.len() { while i < line.points.len() {
match line.points.get(i + 2) { match line.points.get(i + 2) {
Some(_) => { Some(_) => {
if line.points[i + 1].0 < self.scale_x_start { if line.points[i+1].0 < self.scale_x_start {
line.points.remove(i); line.points.remove(i);
} }
} },
None => { None => {
if line.points[line.points.len() - 1].0 < self.scale_x_start { if line.points[line.points.len() - 1].0 < self.scale_x_start {
line.points.clear(); line.points.clear();

View File

@ -17,95 +17,69 @@
//! Feel free to see through codes. Application is not written to be used as a library for other app. :) //! Feel free to see through codes. Application is not written to be used as a library for other app. :)
pub(crate) mod graph; pub mod graph;
pub(crate) mod port_util; pub mod util;
pub(crate) mod util; pub mod port_util;
use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use glib::clone;
use rand::Rng; use rand::Rng;
use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::io::BufReader;
use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
use std::rc::Rc;
use std::cell::RefCell;
use std::io::BufReader;
use std::sync::atomic::Ordering;
use graph::Graph; use graph::Graph;
use util::Config;
use port_util as putil; use port_util as putil;
use util::Properties;
// Building and propsuring GUI // Building and configuring GUI
pub fn build_ui(app: &gtk::Application) { pub fn build_ui(app: &gtk::Application, config: &Arc<Config>) {
let props = Arc::new(Properties::default()); let builder = gtk::Builder::from_file(&config.ui_file);
let ui_file = include_str!("ui.glade");
let builder = gtk::Builder::from_string(ui_file);
let win = builder let win = builder.get_object::<gtk::ApplicationWindow>("win").expect("Resource file missing!");
.object::<gtk::ApplicationWindow>("win")
.expect("Resource file missing!");
win.set_application(Some(app)); win.set_application(Some(app));
// Status Bar // Status Bar
let bar = builder let bar = builder.get_object::<gtk::Statusbar>("status_bar").expect("Resource file missing!");
.object::<gtk::Statusbar>("status_bar")
.expect("Resource file missing!");
// Logging Area // Logging Area
let log_area = builder let log_area = builder.get_object::<gtk::TextView>("log_area").expect("Resource file missing!");
.object::<gtk::TextView>("log_area")
.expect("Resource file missing!");
// About Window // About Window
let about_window = builder let about_window = builder.get_object::<gtk::AboutDialog>("about_window").expect("Resource file missing!");
.object::<gtk::AboutDialog>("about_window")
.expect("Resource file missing!");
// Save Window // Save Window
let save_window = builder let save_window = builder.get_object::<gtk::FileChooserDialog>("save_window").expect("Resource file missing!");
.object::<gtk::FileChooserDialog>("save_window")
.expect("Resource file missing!");
save_window.set_transient_for(Some(&win)); save_window.set_transient_for(Some(&win));
save_window.set_action(gtk::FileChooserAction::Save); save_window.set_action(gtk::FileChooserAction::Save);
save_window.add_button("_Save", gtk::ResponseType::Apply); save_window.add_button("_Save", gtk::ResponseType::Apply);
save_window.add_button("_Cancel", gtk::ResponseType::Cancel); save_window.add_button("_Cancel", gtk::ResponseType::Cancel);
let graph = Graph::new( let graph = Graph::new(
builder builder.get_object::<gtk::DrawingArea>("draw_area").expect("Resource file missing!"),
.object::<gtk::DrawingArea>("draw_area") 0.0, 100.0,
.expect("Resource file missing!"), 0.0, 100.0,
0.0,
100.0,
0.0,
100.0,
false, false,
true, true,
false, false,
true, true,
HashMap::new(), HashMap::new(),
0.0, 0.0
); );
win.show_all(); win.show_all();
// required by signals // required by signals
let stambh_1 = builder let stambh_1 = builder.get_object::<gtk::Entry>("stambh_1").expect("Resource file missing!");
.object::<gtk::Entry>("stambh_1") let stambh_2 = builder.get_object::<gtk::Entry>("stambh_2").expect("Resource file missing!");
.expect("Resource file missing!"); let draw_baarik_box = builder.get_object::<gtk::CheckButton>("draw_baarik_box").expect("Resource file missing!");
let stambh_2 = builder let port = builder.get_object::<gtk::ComboBoxText>("port").expect("Resource file missing!");
.object::<gtk::Entry>("stambh_2") let send_entry = builder.get_object::<gtk::Entry>("send_entry").expect("Resource file missing!");
.expect("Resource file missing!");
let draw_baarik_box = builder
.object::<gtk::CheckButton>("draw_baarik_box")
.expect("Resource file missing!");
let port = builder
.object::<gtk::ComboBoxText>("port")
.expect("Resource file missing!");
let send_entry = builder
.object::<gtk::Entry>("send_entry")
.expect("Resource file missing!");
// Signals // Signals
builder.connect_signals(|_, handler_name| { builder.connect_signals(|_, handler_name| {
match handler_name { match handler_name {
@ -129,16 +103,16 @@ pub fn build_ui(app: &gtk::Application) {
None None
})), })),
"pankti_value_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| { "pankti_value_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| {
let btn = a[0].get::<gtk::SpinButton>().unwrap(); let btn = a[0].get::<gtk::SpinButton>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
tmp_graph.scale_x_size = btn.value(); tmp_graph.scale_x_size = btn.get_value();
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
"stambh_1_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| { "stambh_1_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| {
let entry = a[0].get::<gtk::Entry>().unwrap(); let entry = a[0].get::<gtk::Entry>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
let val = entry.text().parse::<f64>().unwrap_or(0.0); let val = entry.get_text().parse::<f64>().unwrap_or(0.0);
let purana_y_start = tmp_graph.scale_y_start; let purana_y_start = tmp_graph.scale_y_start;
let y_size = tmp_graph.scale_y_size; let y_size = tmp_graph.scale_y_size;
tmp_graph.scale_y_start = val; tmp_graph.scale_y_start = val;
@ -147,44 +121,44 @@ pub fn build_ui(app: &gtk::Application) {
None None
})), })),
"stambh_2_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| { "stambh_2_changed" => Box::new(clone!(@weak graph => @default-return None, move |a| {
let entry = a[0].get::<gtk::Entry>().unwrap(); let entry = a[0].get::<gtk::Entry>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
let val = entry.text().parse::<f64>().unwrap_or(0.0); let val = entry.get_text().parse::<f64>().unwrap_or(0.0);
let y_start = tmp_graph.scale_y_start; let y_start = tmp_graph.scale_y_start;
tmp_graph.scale_y_size = (val - y_start).abs(); tmp_graph.scale_y_size = (val - y_start).abs();
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
"nimna_stambh_toggled" => Box::new(clone!(@weak graph, @weak stambh_1, @weak stambh_2 => @default-return None, move |a| { "nimna_stambh_toggled" => Box::new(clone!(@weak graph, @weak stambh_1, @weak stambh_2 => @default-return None, move |a| {
let btn = a[0].get::<gtk::CheckButton>().unwrap(); let btn = a[0].get::<gtk::CheckButton>().unwrap().unwrap();
graph.borrow_mut().auto_adjust_y = !btn.is_active(); graph.borrow_mut().auto_adjust_y = !btn.get_active();
stambh_1.set_sensitive(btn.is_active()); stambh_1.set_sensitive(btn.get_active());
stambh_2.set_sensitive(btn.is_active()); stambh_2.set_sensitive(btn.get_active());
if btn.is_active() { if btn.get_active() {
stambh_1.emit_activate(); stambh_1.emit_activate();
stambh_2.emit_activate(); stambh_2.emit_activate();
} }
None None
})), })),
"draw_patches_toggled" => Box::new(clone!(@weak graph => @default-return None, move |a| { "draw_patches_toggled" => Box::new(clone!(@weak graph => @default-return None, move |a| {
let btn = a[0].get::<gtk::CheckButton>().unwrap(); let btn = a[0].get::<gtk::CheckButton>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
tmp_graph.draw_patch = btn.is_active(); tmp_graph.draw_patch = btn.get_active();
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
"draw_box_toggled" => Box::new(clone!(@weak graph, @weak draw_baarik_box => @default-return None, move |a| { "draw_box_toggled" => Box::new(clone!(@weak graph, @weak draw_baarik_box => @default-return None, move |a| {
let btn = a[0].get::<gtk::CheckButton>().unwrap(); let btn = a[0].get::<gtk::CheckButton>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
draw_baarik_box.set_sensitive(btn.is_active()); draw_baarik_box.set_sensitive(btn.get_active());
tmp_graph.draw_box = btn.is_active(); tmp_graph.draw_box = btn.get_active();
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
"draw_baarik_box_toggled" => Box::new(clone!(@weak graph => @default-return None, move |a| { "draw_baarik_box_toggled" => Box::new(clone!(@weak graph => @default-return None, move |a| {
let btn = a[0].get::<gtk::CheckButton>().unwrap(); let btn = a[0].get::<gtk::CheckButton>().unwrap().unwrap();
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
tmp_graph.draw_baarik_box = btn.is_active(); tmp_graph.draw_baarik_box = btn.get_active();
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
@ -195,24 +169,24 @@ pub fn build_ui(app: &gtk::Application) {
tmp_graph.redraw(); tmp_graph.redraw();
None None
})), })),
"bondrate_changed" => Box::new(clone!(@weak props => @default-return None, move |a| { "bondrate_changed" => Box::new(clone!(@weak config => @default-return None, move |a| {
let btn = a[0].get::<gtk::ComboBoxText>().unwrap(); let btn = a[0].get::<gtk::ComboBoxText>().unwrap().unwrap();
props.bondrate.store(btn.active_text().unwrap().parse::<u32>().unwrap_or(9600u32), Ordering::SeqCst); config.bondrate.store(btn.get_active_text().unwrap().parse::<u32>().unwrap_or(9600u32), Ordering::SeqCst);
None None
})), })),
"port_changed" => Box::new(clone!(@weak props, @weak bar => @default-return None, move |a| { "port_changed" => Box::new(clone!(@weak config, @weak bar => @default-return None, move |a| {
let btn = a[0].get::<gtk::ComboBoxText>().unwrap(); let btn = a[0].get::<gtk::ComboBoxText>().unwrap().unwrap();
if let Some(val) = btn.active_text() { if let Some(val) = btn.get_active_text() {
match props.port.lock() { match config.port.lock() {
Ok(mut a) => { *a = val.to_string() }, Ok(mut a) => { *a = val.to_string() },
Err(_) => { bar.push(1, "Can't set Port"); } Err(_) => { bar.push(1, "Can't set Port"); }
} }
} }
None None
})), })),
"refresh_port_clicked" => Box::new(clone!(@weak port, @weak bar, @weak props => @default-return None, move |_| { "refresh_port_clicked" => Box::new(clone!(@weak port, @weak bar, @weak config => @default-return None, move |_| {
port.remove_all(); port.remove_all();
match props.status.lock() { match config.status.lock() {
Ok(mut a) => { *a = util::Status::AVRODTIH }, Ok(mut a) => { *a = util::Status::AVRODTIH },
Err(_) => { bar.push(1, "Can't Avrodhit"); return None; } Err(_) => { bar.push(1, "Can't Avrodhit"); return None; }
} }
@ -229,50 +203,53 @@ pub fn build_ui(app: &gtk::Application) {
} }
None None
})), })),
"jagrit_btn_clicked" => Box::new(clone!(@weak props, @weak graph, @weak bar => @default-return None, move |_| { "jagrit_btn_clicked" => Box::new(clone!(@weak config, @weak graph, @weak bar => @default-return None, move |_| {
let mut tmp_graph = graph.borrow_mut(); let mut tmp_graph = graph.borrow_mut();
tmp_graph.pankti_sankya = 0.0; tmp_graph.pankti_sankya = 0.0;
tmp_graph.lines.clear(); tmp_graph.lines.clear();
tmp_graph.redraw(); tmp_graph.redraw();
bar.push(1, "Jagrit"); bar.push(1, "Jagrit");
match props.status.lock() { match config.status.lock() {
Ok(mut a) => { *a = util::Status::PARIVARTIT }, Ok(mut a) => { *a = util::Status::PARIVARTIT },
Err(_) => { bar.push(1, "Can't Jagrit"); } Err(_) => { bar.push(1, "Can't Jagrit"); }
} }
None None
})), })),
"avrodith_btn_clicked" => Box::new(clone!(@weak props, @weak bar => @default-return None, move |_| { "avrodith_btn_clicked" => Box::new(clone!(@weak config, @weak bar => @default-return None, move |_| {
bar.push(1, "Avrodhit"); bar.push(1, "Avrodhit");
match props.status.lock() { match config.status.lock() {
Ok(mut a) => { *a = util::Status::AVRODTIH }, Ok(mut a) => { *a = util::Status::AVRODTIH },
Err(_) => { bar.push(1, "Can't Avrodhit"); } Err(_) => { bar.push(1, "Can't Avrodhit"); }
} }
None None
})), })),
"clear_log_clicked" => Box::new(clone!(@weak log_area => @default-return None, move |_| { "clear_log_clicked" => Box::new(clone!(@weak log_area => @default-return None, move |_| {
log_area.buffer().expect("Couldn't get window").set_text(""); log_area.get_buffer().expect("Couldn't get window").set_text("");
None None
})), })),
"send_entry_key_press_event" => Box::new(clone!(@weak props, @weak bar => @default-return None, move |a| { "send_entry_key_press_event" => Box::new(clone!(@weak config, @weak bar => @default-return None, move |a| {
let ev = a[1].get::<gdk::Event>().unwrap(); let ev = a[1].get::<gdk::Event>().unwrap().unwrap();
let ev: Result<gdk::EventKey,_> = gdk::FromEvent::from(ev); if let Some(val) = ev.get_keyval() {
if ev.unwrap().keyval() == gdk::keys::constants::Return { if let Some(val) = gdk::keys::keyval_name(val) {
let ent = a[0].get::<gtk::Entry>().unwrap(); if val == "Return" {
putil::send_text(&props, &ent, &bar); let ent = a[0].get::<gtk::Entry>().unwrap().unwrap();
putil::send_text(&config, &ent, &bar);
}
}
} }
Some(false.to_value()) Some(false.to_value())
})), })),
"send_btn_clicked" => Box::new(clone!(@weak props, @weak bar, @weak send_entry => @default-return None, move |_| { "send_btn_clicked" => Box::new(clone!(@weak config, @weak bar, @weak send_entry => @default-return None, move |_| {
putil::send_text(&props, &send_entry, &bar); putil::send_text(&config, &send_entry, &bar);
None None
})), })),
"about_window_delete" => Box::new(|a| { "about_window_delete" => Box::new(|a| {
let win = a[0].get::<gtk::AboutDialog>().unwrap(); let win = a[0].get::<gtk::AboutDialog>().unwrap().unwrap();
win.hide(); win.hide();
Some(true.to_value()) Some(true.to_value())
}), }),
"save_window_delete" => Box::new(|a| { "save_window_delete" => Box::new(|a| {
let win = a[0].get::<gtk::FileChooserDialog>().unwrap(); let win = a[0].get::<gtk::FileChooserDialog>().unwrap().unwrap();
win.hide(); win.hide();
Some(true.to_value()) Some(true.to_value())
}), }),
@ -289,29 +266,28 @@ pub fn build_ui(app: &gtk::Application) {
}); });
let tmp_log_area = log_area.clone(); let tmp_log_area = log_area.clone();
let tmp_bar = bar.clone(); let tmp_bar = bar.clone();
save_window.connect_response(move |win, res| match res { save_window.connect_response(move |win, res| {
gtk::ResponseType::Cancel => win.hide(), match res {
gtk::ResponseType::Apply => { gtk::ResponseType::Cancel => win.hide(),
if let Some(path) = win.filename() { gtk::ResponseType::Apply => {
if let Some(buf) = tmp_log_area.buffer() { if let Some(path) = win.get_filename() {
let text = buf if let Some(buf) = tmp_log_area.get_buffer() {
.text(&buf.start_iter(), &buf.end_iter(), false) let text = buf.get_text(&buf.get_start_iter(), &buf.get_end_iter(), false).unwrap().to_string();
.unwrap()
.to_string();
match std::fs::write(path, text) { match std::fs::write(path, text) {
Ok(_) => { Ok(_) => {
win.hide(); win.hide();
} },
Err(_) => { Err(_) => {
tmp_bar.push(1, "Failed to save!"); tmp_bar.push(1, "Failed to save!");
}
} }
} }
} }
} },
_ => ()
} }
_ => (),
}); });
/* /*
@ -323,28 +299,24 @@ pub fn build_ui(app: &gtk::Application) {
*/ */
let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT); let (sender, receiver) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
let tmp_props = Arc::clone(&props); let tmp_config = Arc::clone(&config);
tokio::task::spawn(async move { tokio::task::spawn(async move {
let mut bufread: Option<BufReader<Box<dyn serialport::SerialPort>>> = None; let mut bufread: Option<BufReader<Box<dyn serialport::SerialPort>>> = None;
let mut buf = String::new(); let mut buf = String::new();
loop { loop {
putil::serial_thread_work(&tmp_props, &mut bufread, &sender, &mut buf).await; putil::serial_thread_work(&tmp_config, &mut bufread, &sender, &mut buf).await;
} }
}); });
// Reciver for MessageSerialThread from the "Thread to manage Serial Port" and works accordingly // Reciver for MessageSerialThread from the "Thread to manage Serial Port" and works accordingly
let full_log = builder let full_log = builder.get_object::<gtk::CheckButton>("full_log").expect("Resource file missing!");
.object::<gtk::CheckButton>("full_log") let graph_data = builder.get_object::<gtk::TextView>("graph_data").expect("Resource file missing!");
.expect("Resource file missing!");
let graph_data = builder
.object::<gtk::TextView>("graph_data")
.expect("Resource file missing!");
let tmp_graph = Rc::clone(&graph); let tmp_graph = Rc::clone(&graph);
receiver.attach(None, move |msg| { receiver.attach(None, move |msg| {
match msg { match msg {
util::MessageSerialThread::Msg(text, msg_type) => { util::MessageSerialThread::Msg(text, msg_type) => {
receiver_for_msg(text, &msg_type, &full_log, &log_area); receiver_for_msg(text, &msg_type, &full_log, &log_area);
} },
util::MessageSerialThread::Points(points) => { util::MessageSerialThread::Points(points) => {
receiver_for_points(points, &tmp_graph, &graph_data); receiver_for_points(points, &tmp_graph, &graph_data);
} }
@ -357,13 +329,8 @@ pub fn build_ui(app: &gtk::Application) {
} }
// Receives MessageSerialThread from Serial Port managing thread adds message to text area // Receives MessageSerialThread from Serial Port managing thread adds message to text area
fn receiver_for_msg( fn receiver_for_msg(text: String, msg_type: &util::MessageSerialThreadMsgType, full_log: &gtk::CheckButton, log_area: &gtk::TextView) {
text: String, if !full_log.get_active(){
msg_type: &util::MessageSerialThreadMsgType,
full_log: &gtk::CheckButton,
log_area: &gtk::TextView,
) {
if !full_log.is_active() {
if let util::MessageSerialThreadMsgType::Point = msg_type { if let util::MessageSerialThreadMsgType::Point = msg_type {
return; return;
} }
@ -371,18 +338,15 @@ fn receiver_for_msg(
if text.len() <= 0 { if text.len() <= 0 {
return; return;
} }
let buf = log_area.buffer().expect("Couldn't get log_area"); let buf = log_area.get_buffer()
buf.insert(&mut buf.end_iter(), &format!("{}\n", text)); .expect("Couldn't get log_area");
log_area.scroll_to_iter(&mut buf.end_iter(), 0.4, true, 0.0, 0.0); buf.insert(&mut buf.get_end_iter(), &format!("{}\n",text));
log_area.scroll_to_iter(&mut buf.get_end_iter(), 0.4, true, 0.0, 0.0);
log_area.queue_draw(); log_area.queue_draw();
} }
// Receives MessageSerialThread from Serial Port managing thread and add points to draw on graph // Receives MessageSerialThread from Serial Port managing thread and add points to draw on graph
fn receiver_for_points( fn receiver_for_points(points: Vec<(String, f64)>, graph: &Rc<RefCell<Graph>>, graph_data: &gtk::TextView) {
points: Vec<(String, f64)>,
graph: &Rc<RefCell<Graph>>,
graph_data: &gtk::TextView,
) {
for (line, point) in points { for (line, point) in points {
let mut gp = graph.borrow_mut(); let mut gp = graph.borrow_mut();
@ -390,30 +354,27 @@ fn receiver_for_points(
match gp.lines.get_mut(&line) { match gp.lines.get_mut(&line) {
Some(val) => { Some(val) => {
val.points.push((sankhya, point)); val.points.push((sankhya, point));
} } None => {
None => {
let v = vec![(sankhya, point)]; let v = vec![(sankhya, point)];
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
gp.lines.insert( gp.lines.insert(line, graph::Line::new(rng.gen_range(0.0..1.0), 0.0, rng.gen_range(0.0..1.0), v));
line, let buf = graph_data.get_buffer().expect("Couldn't get graph_data");
graph::Line::new(rng.gen_range(0.0..1.0), 0.0, rng.gen_range(0.0..1.0), v),
);
let buf = graph_data.buffer().expect("Couldn't get graph_data");
buf.set_text(""); buf.set_text("");
gp.lines.iter().for_each(|(key, line)| { gp.lines.iter().for_each(|(key, line)| {
buf.insert(&mut buf.end_iter(), "##"); buf.insert(&mut buf.get_end_iter(), "##");
let tag = gtk::TextTag::new(None); let tag = gtk::TextTag::new(None);
let rgba = gdk::RGBA::new(line.color.0, line.color.1, line.color.2, 1.0); let rgba = gdk::RGBA {
tag.set_background_rgba(Some(&rgba)); red: line.color.0,
tag.set_foreground_rgba(Some(&rgba)); green: line.color.1,
buf.tag_table().unwrap().add(&tag); blue: line.color.2,
buf.apply_tag( alpha: 1.0
&tag, };
&buf.iter_at_offset(buf.end_iter().offset() - 2), tag.set_property_background_rgba(Some(&rgba));
&buf.end_iter(), tag.set_property_foreground_rgba(Some(&rgba));
); buf.get_tag_table().unwrap().add(&tag);
buf.insert(&mut buf.end_iter(), &format!(" {}, ", key)); buf.apply_tag(&tag, &buf.get_iter_at_offset(buf.get_end_iter().get_offset() - 2), &buf.get_end_iter());
buf.insert(&mut buf.get_end_iter(), &format!(" {}, ", key));
}); });
graph_data.queue_draw(); graph_data.queue_draw();
} }

View File

@ -12,16 +12,26 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#![windows_subsystem = "windows"]
use gio::{prelude::*, ApplicationFlags}; use gio::prelude::*;
use std::env::args;
use std::sync::Arc;
use tarangam::util::Config;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let app = gtk::Application::new(Some("sng.tarangm"), ApplicationFlags::default()); let conf = Arc::new(Config::default());
let app = gtk::Application::new(Some("sng.tarangm"), Default::default())
.expect("Failed to initiate gtk");
let tmp_conf = Arc::clone(&conf);
app.connect_activate(move |app| { app.connect_activate(move |app| {
tarangam::build_ui(app); tarangam::build_ui(app, &tmp_conf);
}); });
app.run();
app.run(&args().collect::<Vec<_>>());
} }

View File

@ -19,25 +19,23 @@
use gtk::prelude::*; use gtk::prelude::*;
use std::sync::Arc;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufReader; use std::io::BufReader;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::Arc;
use crate::{util, util::Properties}; use crate::{util::Config, util};
// Controls the thread and read from serial port // Controls the thread and read from serial port
pub(crate) async fn serial_thread_work( pub async fn serial_thread_work(
config: &Arc<Properties>, config: &Arc<Config>,
bufread: &mut Option<BufReader<Box<dyn serialport::SerialPort>>>, bufread: &mut Option<BufReader<Box<dyn serialport::SerialPort>>>,
sender: &glib::Sender<util::MessageSerialThread>, sender: &glib::Sender<util::MessageSerialThread>,
buf: &mut String, buf: &mut String) {
) {
let status = match config.status.try_lock() { let status = match config.status.try_lock() {
Ok(a) => a.to_owned(), Ok(a) => a.to_owned(),
Err(_) => { Err(_) => { return; }
return;
}
}; };
match status { match status {
@ -45,11 +43,9 @@ pub(crate) async fn serial_thread_work(
*bufread = None; *bufread = None;
match config.status.lock() { match config.status.lock() {
Ok(mut a) => *a = util::Status::SAYAN, Ok(mut a) => *a = util::Status::SAYAN,
Err(_) => { Err(_) => { return; }
return;
}
}; };
} },
util::Status::JAGRIT => { util::Status::JAGRIT => {
if let Some(read) = bufread { if let Some(read) = bufread {
if let Ok(_) = read.read_line(buf) { if let Ok(_) = read.read_line(buf) {
@ -71,28 +67,13 @@ pub(crate) async fn serial_thread_work(
points.push((index.to_string(), num)); points.push((index.to_string(), num));
} else if part.len() == 2 { } else if part.len() == 2 {
points.push(( points.push((part[0].trim().to_owned(), part[1].parse::<f64>().unwrap()));
part[0].trim().to_owned(),
part[1].parse::<f64>().unwrap(),
));
} }
} }
sender sender.send(util::MessageSerialThread::Points(points)).unwrap();
.send(util::MessageSerialThread::Points(points)) sender.send(util::MessageSerialThread::Msg(line.to_owned(), util::MessageSerialThreadMsgType::Point)).unwrap();
.unwrap();
sender
.send(util::MessageSerialThread::Msg(
line.to_owned(),
util::MessageSerialThreadMsgType::Point,
))
.unwrap();
} else { } else {
sender sender.send(util::MessageSerialThread::Msg(line.to_owned(), util::MessageSerialThreadMsgType::Log)).unwrap();
.send(util::MessageSerialThread::Msg(
line.to_owned(),
util::MessageSerialThreadMsgType::Log,
))
.unwrap();
} }
} }
buf.clear(); buf.clear();
@ -100,13 +81,11 @@ pub(crate) async fn serial_thread_work(
} }
tokio::time::sleep(tokio::time::Duration::from_millis(10)).await; tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
} },
util::Status::PARIVARTIT => { util::Status::PARIVARTIT => {
let port = match config.port.lock() { let port = match config.port.lock() {
Ok(a) => a.to_owned(), Ok(a) => a.to_owned(),
Err(_) => { Err(_) => { return; }
return;
}
}; };
let p = match serialport::new(&port, config.bondrate.load(Ordering::SeqCst)).open() { let p = match serialport::new(&port, config.bondrate.load(Ordering::SeqCst)).open() {
Ok(p) => p, Ok(p) => p,
@ -118,24 +97,22 @@ pub(crate) async fn serial_thread_work(
*bufread = Some(BufReader::new(p)); *bufread = Some(BufReader::new(p));
match config.status.try_lock() { match config.status.try_lock() {
Ok(mut a) => *a = util::Status::JAGRIT, Ok(mut a) => *a = util::Status::JAGRIT,
Err(_) => { Err(_) => { return; }
return;
}
}; };
} }
_ => { _ => {
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
} },
} }
} }
// // Sends text through Serial Post to device // // Sends text through Serial Post to device
pub(crate) fn send_text(config: &Arc<Properties>, entry: &gtk::Entry, bar: &gtk::Statusbar) { pub fn send_text(config: &Arc<Config>, entry: &gtk::Entry, bar: &gtk::Statusbar) {
let status = match config.status.try_lock() { let status = match config.status.try_lock() {
Ok(a) => a.to_owned(), Ok(a) => a.to_owned(),
Err(_) => { Err(_) => { return; }
return;
}
}; };
if let util::Status::JAGRIT = status { if let util::Status::JAGRIT = status {
let port = match config.port.lock() { let port = match config.port.lock() {
@ -155,9 +132,9 @@ pub(crate) fn send_text(config: &Arc<Properties>, entry: &gtk::Entry, bar: &gtk:
}; };
unsafe { unsafe {
p.write_all(entry.text().to_string().as_bytes_mut()) p.write_all(entry.get_text().to_string().as_bytes_mut()).unwrap();
.unwrap();
} }
entry.set_text(""); entry.set_text("");
} }
} }

View File

@ -21,41 +21,48 @@ use std::sync::{atomic::*, Mutex};
/// Status of Serial reading /// Status of Serial reading
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(crate) enum Status { pub enum Status {
AVRODTIH, // Mode of being stopped AVRODTIH, // Mode of being stopped
SAYAN, // Mode of Sleeping SAYAN, // Mode of Sleeping
JAGRIT, // Mode of Active JAGRIT, // Mode of Active
PARIVARTIT, // Mode of being values modified PARIVARTIT // Mode of being values modified
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct Properties { pub struct Config {
pub(crate) bondrate: AtomicU32, pub ui_file: String,
pub(crate) port: Mutex<String>, pub bondrate: AtomicU32,
pub(crate) status: Mutex<Status>, pub port: Mutex<String>,
pub status: Mutex<Status>
} }
/// For communication between mpsc of graph and serial port /// For communication between mpsc of graph and serial port
#[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum MessageSerialThread { pub enum MessageSerialThread {
Msg(String, MessageSerialThreadMsgType), Msg(String, MessageSerialThreadMsgType),
Points(Vec<(String, f64)>), Points(Vec<(String, f64)>),
Status(String), Status(String)
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum MessageSerialThreadMsgType { pub enum MessageSerialThreadMsgType {
Point, Point,
Log, Log
} }
impl Properties { impl Config {
pub(crate) fn default() -> Self { pub fn default() -> Self {
Properties { let ui_file = std::env::var("TARANGAM_UI_FILE");
Config {
ui_file: match ui_file {
Ok(val) => val,
Err(_) => std::env::current_exe().unwrap().parent().unwrap()
.join("ui.glade").to_str().unwrap().to_owned()
},
bondrate: AtomicU32::new(9600), bondrate: AtomicU32::new(9600),
port: Mutex::new(String::new()), port: Mutex::new(String::new()),
status: Mutex::new(Status::AVRODTIH), status: Mutex::new(Status::AVRODTIH)
} }
} }
} }

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 --> <!-- Generated with glade 3.38.1 -->
<interface> <interface>
<requires lib="gtk+" version="3.22"/> <requires lib="gtk+" version="3.22"/>
<object class="GtkAboutDialog" id="about_window"> <object class="GtkAboutDialog" id="about_window">
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Tarangam</property> <property name="title" translatable="yes">Tarangam</property>
<property name="icon">chitra-small.png</property> <property name="icon">chitra.svg</property>
<property name="type-hint">dialog</property> <property name="type-hint">dialog</property>
<property name="program-name">Tarangam (तरंगम्)</property> <property name="program-name">Tarangam (तरंगम्)</property>
<property name="comments" translatable="yes">A simple serial plotter. <property name="comments" translatable="yes">A simple serial plotter.
@ -54,7 +54,7 @@
</object> </object>
<object class="GtkFileChooserDialog" id="save_window"> <object class="GtkFileChooserDialog" id="save_window">
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="icon">chitra-small.png</property> <property name="icon">chitra.svg</property>
<property name="type-hint">dialog</property> <property name="type-hint">dialog</property>
<property name="action">select-folder</property> <property name="action">select-folder</property>
<signal name="close" handler="save_window_close" swapped="no"/> <signal name="close" handler="save_window_close" swapped="no"/>
@ -98,7 +98,7 @@
<property name="title" translatable="yes">Tarangam</property> <property name="title" translatable="yes">Tarangam</property>
<property name="default-width">850</property> <property name="default-width">850</property>
<property name="default-height">600</property> <property name="default-height">600</property>
<property name="icon">chitra-small.png</property> <property name="icon">chitra.svg</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>