add a GUI

This commit is contained in:
Daniella / Tove 2022-08-21 14:10:10 +02:00
parent 7dc768776e
commit fd4f13e4a7
4 changed files with 941 additions and 11 deletions

622
Cargo.lock generated
View file

@ -2,6 +2,626 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "addr2line"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "backtrace"
version = "0.3.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
dependencies = [
"addr2line",
"cc",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]]
name = "bindgen"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c0bb6167449588ff70803f4127f0684f9063097eca5016f37eb52b92c2cf36"
dependencies = [
"bitflags",
"cexpr",
"cfg-if 0.1.10",
"clang-sys",
"clap",
"env_logger",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"which",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cexpr"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clang-sys"
version = "0.29.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "embed-resource"
version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936c1354206a875581696369aef920e12396e93bbd251c43a7a3f3fa85023a7d"
dependencies = [
"cc",
"rustc_version",
"toml",
"vswhom",
"winreg",
]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "failure"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
dependencies = [
"backtrace",
"failure_derive",
]
[[package]]
name = "failure_derive"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
"proc-macro2",
"quote",
"syn",
"synstructure",
]
[[package]]
name = "getrandom"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if 1.0.0",
"libc",
"wasi",
]
[[package]]
name = "gimli"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]]
name = "iui"
version = "0.3.0"
source = "git+https://github.com/rust-native-ui/libui-rs#6ff94425b341cf718e29d07067dbf82f9215a6d5"
dependencies = [
"bitflags",
"failure",
"lazy_static",
"libc",
"regex",
"ui-sys",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]]
name = "libloading"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
dependencies = [
"cc",
"winapi",
]
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "miniz_oxide"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
dependencies = [
"adler",
]
[[package]]
name = "nom"
version = "5.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "object"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"memchr",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "pkg-config"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "ppv-lite86"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
[[package]]
name = "proc-macro2"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
dependencies = [
"unicode-ident",
]
[[package]]
name = "qft"
version = "0.4.6"
version = "0.4.7"
dependencies = [
"iui",
"rand",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "semver"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711"
[[package]]
name = "serde"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
[[package]]
name = "shlex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
dependencies = [
"proc-macro2",
"quote",
"syn",
"unicode-xid",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]]
name = "ui-sys"
version = "0.2.1"
source = "git+https://github.com/rust-native-ui/libui-rs#6ff94425b341cf718e29d07067dbf82f9215a6d5"
dependencies = [
"bindgen",
"cc",
"embed-resource",
"libc",
"pkg-config",
]
[[package]]
name = "unicode-ident"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "vswhom"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
dependencies = [
"libc",
"vswhom-sys",
]
[[package]]
name = "vswhom-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22025f6d8eb903ebf920ea6933b70b1e495be37e2cb4099e62c80454aaf57c39"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winreg"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
dependencies = [
"winapi",
]

View file

@ -1,9 +1,10 @@
[package]
name = "qft"
version = "0.4.6"
version = "0.4.7"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
iui.git = "https://github.com/rust-native-ui/libui-rs"
rand = "0"

301
src/gui.rs Normal file
View file

@ -0,0 +1,301 @@
use std::{env, process, thread};
use iui::{controls::*, *};
#[derive(Clone)]
struct RefMut<T> {
to: *mut T,
}
impl<T> RefMut<T> {
pub fn new(to: &mut T) -> RefMut<T> {
RefMut { to: to as *mut T }
}
pub fn get(&self) -> &mut T {
unsafe { self.to.as_mut().unwrap() }
}
}
unsafe impl<T> Sync for RefMut<T> {}
unsafe impl<T> Send for RefMut<T> {}
#[derive(Clone)]
struct Ref<T> {
to: *const T,
}
impl<T> Ref<T> {
pub fn new(to: &T) -> Ref<T> {
Ref { to: to as *const T }
}
pub fn get(&self) -> &T {
unsafe { self.to.as_ref().unwrap() }
}
}
unsafe impl<T> Sync for Ref<T> {}
unsafe impl<T> Send for Ref<T> {}
fn wrap<T: Into<Control>>(ui: &UI, s: &str, c: T) -> Group {
let mut g = Group::new(ui, s);
g.set_child(ui, c);
return g;
}
pub fn gui() -> Result<(), iui::UIError> {
let ui: UI = UI::init()?;
let mut window = Window::new(&ui, "QFT", 500, 600, WindowType::NoMenubar);
let mut vbox = VerticalBox::new(&ui);
vbox.set_padded(&ui, false);
let mut mode = Combobox::new(&ui);
let modeb = Ref::new(&mode);
mode.append(&ui, "Receive");
mode.append(&ui, "Send");
mode.set_selected(&ui, 1);
let mdb = Ref::new(&mode);
vbox.append(&ui, wrap(&ui, "Mode: ", mode), LayoutStrategy::Compact);
let mut helper_data = HorizontalBox::new(&ui);
helper_data.set_padded(&ui, true);
let mut helper = Entry::new(&ui);
let helperb = Ref::new(&helper);
helper.set_value(&ui, "tudbut.de:4277");
helper_data.append(&ui, helper, LayoutStrategy::Stretchy);
let mut phrase = Entry::new(&ui);
let phraseb = Ref::new(&phrase);
phrase.set_value(
&ui,
format!("my-cool-phrase-{}", rand::random::<u16>()).as_str(),
);
helper_data.append(&ui, phrase, LayoutStrategy::Stretchy);
vbox.append(
&ui,
wrap(&ui, "Shared Phrase: ", helper_data),
LayoutStrategy::Compact,
);
let mut path = env::current_exe()
.unwrap()
.into_os_string()
.into_string()
.unwrap();
let pathb = Ref::new(&path);
let mut select_path = Button::new(&ui, format!("Select a file ({})", path).as_str());
let bb = RefMut::new(&mut select_path);
let pb = RefMut::new(&mut path);
let wb = Ref::new(&window);
let uib = Ref::new(&ui);
select_path.on_clicked(&ui, move |_| {
let r = if mdb.get().selected(uib.get()) == 0 {
wb.get()
.save_file(uib.get())
.map(|x| x.into_os_string().into_string().unwrap())
} else {
wb.get()
.open_file(uib.get())
.map(|x| x.into_os_string().into_string().unwrap())
};
match r {
Some(path) => {
bb.get()
.set_text(uib.get(), format!("Select a file ({})", &path).as_str());
*pb.get() = path;
}
None => (),
}
});
vbox.append(
&ui,
wrap(&ui, "Path: ", select_path),
LayoutStrategy::Compact,
);
let mut speed = VerticalBox::new(&ui);
let mut speed_slider = Slider::new(&ui, 100, 10_000);
let speedb = Ref::new(&speed_slider);
let mut speed_box = Entry::new(&ui);
speed_slider.set_value(&ui, 256);
speed_box.set_value(&ui, "256");
// We know that ui.main() will wait until the UI is dead, so these are safe.
let sb = RefMut::new(&mut speed_slider);
let bb = RefMut::new(&mut speed_box);
let uib = Ref::new(&ui);
let uib1 = uib.clone();
speed_box.on_changed(&ui, move |val| {
sb.get().set_value(
uib.get(),
u16::from_str_radix(val.as_str(), 10).unwrap_or(256) as i32,
);
});
speed_slider.on_changed(&ui, move |val| {
bb.get().set_value(uib1.get(), val.to_string().as_str());
});
speed.set_padded(&ui, true);
speed.append(&ui, speed_slider, LayoutStrategy::Compact);
speed.append(&ui, speed_box, LayoutStrategy::Compact);
vbox.append(
&ui,
wrap(
&ui,
"Bitrate: (lower = more reliable, higher = faster)",
speed,
),
LayoutStrategy::Compact,
);
let mut skip = Entry::new(&ui);
let skipb = Ref::new(&skip);
skip.set_value(&ui, "0");
vbox.append(
&ui,
wrap(&ui, "Resume from: ", skip),
LayoutStrategy::Compact,
);
let mut bar = ProgressBar::new();
let barb = RefMut::new(&mut bar);
bar.set_value(&ui, ProgressBarValue::Determinate(0));
vbox.append(&ui, wrap(&ui, "Progress: ", bar), LayoutStrategy::Compact);
let mut send_button = Button::new(&ui, "Start");
let bb = RefMut::new(&mut send_button);
let uib = Ref::new(&ui);
send_button.on_clicked(&ui, move |b| {
b.disable(uib.get());
let bb = bb.clone();
let rargs = env::args().collect::<Vec<String>>();
let mut args = vec![rargs.get(0).unwrap().clone()];
let a = String::from(match modeb.get().selected(uib.get()) {
0 => "receiver",
1 => "sender",
_ => "version",
});
args.push(a);
let a = helperb.get().value(uib.get());
args.push(a);
let a = phraseb.get().value(uib.get());
args.push(a);
let a = pathb.get().clone();
args.push(a);
let a = speedb.get().value(uib.get()).to_string();
args.push(a);
let a = skipb.get().value(uib.get());
args.push(a);
println!("{:?}", args);
match modeb.get().selected(uib.get()) {
0 => {
barb.get()
.set_value(uib.get(), ProgressBarValue::Indeterminate);
let uib1 = Ref::new(uib.get());
let barb1 = RefMut::new(barb.get());
thread::spawn(move || {
crate::receiver(&args);
let uib = uib1.clone();
let barb = barb1.clone();
uib1.get().queue_main(move || {
barb
.get()
.set_value(uib.get(), ProgressBarValue::Determinate(100));
bb.get().enable(uib.get());
});
});
}
1 => {
barb.get()
.set_value(uib.get(), ProgressBarValue::Indeterminate);
let uib = uib.clone();
let barb = barb.clone();
thread::spawn(move || {
let mut last_percentage = 0;
let lpb = RefMut::new(&mut last_percentage);
let uib1 = uib.clone();
let barb1 = barb.clone();
crate::sender(&args, move |f| {
let lpb1 = lpb.clone();
let uib = uib1.clone();
let barb = barb1.clone();
uib1.get().queue_main(move || {
let percentage = (f * 100 as f32) as u32;
if percentage != *lpb1.get() {
barb.get().set_value(uib.get(), ProgressBarValue::Determinate(percentage));
*lpb1.get() = percentage;
}
})
});
let uib1 = uib.clone();
let barb1 = barb.clone();
uib.get().queue_main(move || {
barb1
.get()
.set_value(uib1.get(), ProgressBarValue::Determinate(100));
bb.get().enable(uib1.get());
});
});
}
_ => panic!("invalid mode"),
}
println!("Running.");
});
vbox.append(
&ui,
wrap(&ui, "Start: ", send_button),
LayoutStrategy::Compact,
);
let uib = Ref::new(&ui);
window.on_closing(&ui, move |_| {
let mut quit_window =
Window::new(uib.get(), "Really quit?", 300, 100, WindowType::NoMenubar);
let mut vbox = VerticalBox::new(uib.get());
let label = Label::new(uib.get(), "Do you really want to quit?");
vbox.append(uib.get(), label, LayoutStrategy::Compact);
vbox.append(uib.get(), Spacer::new(uib.get()), LayoutStrategy::Stretchy);
let mut hbox = HorizontalBox::new(uib.get());
hbox.set_padded(uib.get(), true);
let mut button1 = Button::new(uib.get(), "Quit");
let uib1 = uib.clone();
button1.on_clicked(uib.get(), move |_| {
uib1.get().quit();
process::exit(0);
});
let mut button2 = Button::new(uib.get(), "Cancel");
let uib1 = uib.clone();
// We know button2 won't be destroyed until quit_window is dead, so these are fine
let qwb = RefMut::new(&mut quit_window);
button2.on_clicked(uib.get(), move |_| quit_window.hide(uib1.get()));
let quit_window = qwb.get();
hbox.append(uib.get(), button1, LayoutStrategy::Stretchy);
hbox.append(uib.get(), button2, LayoutStrategy::Stretchy);
vbox.append(uib.get(), hbox, LayoutStrategy::Compact);
quit_window.set_child(uib.get(), vbox);
let uib1 = uib.clone();
quit_window.on_closing(uib.get(), move |w| w.hide(uib1.get()));
quit_window.show(uib.get());
});
window.set_child(&ui, vbox);
window.show(&ui);
/*si.on_should_quit(move || {
let quit_window = Window::new(&ui, "Really quit?", 300, 100, WindowType::NoMenubar);
let label = Label::new(&ui, "Do you really want to quit? Data is currently being transferred.");
ui.quit();
});*/
ui.event_loop().run(&ui);
println!("GUI done");
return Ok(());
}

View file

@ -1,3 +1,5 @@
mod gui;
use std::{
collections::HashMap,
env,
@ -159,8 +161,7 @@ impl SafeReadWrite {
self.socket
.set_read_timeout(Some(Duration::from_millis(1)))
.unwrap();
}
else {
} else {
wait = true;
}
let mut start = unix_millis();
@ -266,14 +267,15 @@ fn main() {
.as_str()
{
"helper" => helper(&args),
"sender" => sender(&args),
"sender" => sender(&args, |_| {}),
"receiver" => receiver(&args),
"gui" => gui::gui().expect("can't use gui"),
"version" => println!("QFT version: {}", env!("CARGO_PKG_VERSION")),
_ => print_args(&args),
}
}
fn helper(args: &Vec<String>) {
pub fn helper(args: &Vec<String>) {
let bind_addr = (
"0.0.0.0",
u16::from_str_radix(args[2].as_str(), 10).expect("invalid port: must be integer"),
@ -312,7 +314,7 @@ fn helper(args: &Vec<String>) {
}
}
fn sender(args: &Vec<String>) {
pub fn sender<F: Fn(f32)>(args: &Vec<String>, on_progress: F) {
let connection = holepunch(args);
let br = args
.get(5)
@ -341,6 +343,7 @@ fn sender(args: &Vec<String>) {
let mut sc = SafeReadWrite::new(connection);
let mut bytes_sent: u64 = 0;
let mut last_update = unix_millis();
loop {
let read = file.read(&mut buf).expect("file read error");
if read == 0 && !env::var("QFT_STREAM").is_ok() {
@ -356,10 +359,14 @@ fn sender(args: &Vec<String>) {
print!("\r\x1b[KSent {} bytes", bytes_sent);
stdout().flush().unwrap();
}
if unix_millis() - last_update > 100 {
on_progress(bytes_sent as f32 / file.metadata().expect("bad metadata").len() as f32);
last_update = unix_millis();
}
}
}
fn receiver(args: &Vec<String>) {
pub fn receiver(args: &Vec<String>) {
let connection = holepunch(args);
let br = args
.get(5)
@ -506,13 +513,14 @@ fn print_args(args: &Vec<String>) {
| {} helper <bind-port>\n\
| {} sender <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]\n\
| {} receiver <helper-address>:<helper-port> <phrase> <filename> [bitrate] [skip]\n\
| {} gui\n\
| {} version\n",
f, f, f, f
f, f, f, f, f
);
panic!("No arguments");
}
fn unix_millis() -> u64 {
pub fn unix_millis() -> u64 {
SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()