From 0d7ba9a3d137699bf20239df9ee779831768dda0 Mon Sep 17 00:00:00 2001 From: Chloe Fontenot Date: Mon, 4 Nov 2024 02:05:14 -0600 Subject: [PATCH] init --- .gitignore | 1 + .vscode/launch.json | 45 +++++++++++++++ Cargo.lock | 109 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 +++ src/main.rs | 130 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 294 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c0c1d5c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'hello-rust'", + "cargo": { + "args": [ + "build", + "--bin=hello-rust", + "--package=hello-rust" + ], + "filter": { + "name": "hello-rust", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug unit tests in executable 'hello-rust'", + "cargo": { + "args": [ + "test", + "--no-run", + "--bin=hello-rust", + "--package=hello-rust" + ], + "filter": { + "name": "hello-rust", + "kind": "bin" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..674c22b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,109 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "device_query" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0500656e17fa3bf720de64b28b6fb28c3602307fc7afbb078c6643d836acaa28" +dependencies = [ + "input-event-codes", + "pkg-config", + "readkey", + "readmouse", + "winapi", + "x11", +] + +[[package]] +name = "hello-rust" +version = "0.1.0" +dependencies = [ + "device_query", + "substring", + "text_io", +] + +[[package]] +name = "input-event-codes" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5ce56b9cb50796f260af5d7ccd957727d5390e575b1917f2722bd9813faabd" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "readkey" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d401b6d6a1725a59f1b4e813275d289dff3ad09c72b373a10a7a8217ba3146" + +[[package]] +name = "readmouse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be105c72a1e6a5a1198acee3d5b506a15676b74a02ecd78060042a447f408d94" + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "text_io" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f0c8eb2ad70c12a6a69508f499b3051c924f4b1cfeae85bfad96e6bc5bba46" + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..5cfee9c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "text_scroller" +version = "0.1.0" +edition = "2024" + +[dependencies] +device_query = "0.2.0" +substring = "1.4.5" +text_io = "0.1.12" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f3ef044 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,130 @@ +use std::thread; +use std::time::Duration; +use substring::Substring; +use device_query::{DeviceQuery, DeviceState, Keycode}; +use std::sync::mpsc; + +#[macro_use] extern crate text_io; +macro_rules! either { + ($test:expr => $true_expr:expr; $false_expr:expr) => { + if $test { + $true_expr + } + else { + $false_expr + } + } +} +fn main() { + + print!("Use the up/down arrow keys to adjust the update speed!\nleft/right controls the scroll direction!\nPlease enter a string: "); + let mut input: String = read!("{}\n"); + // check the final character, add a space if there isn't one. + if input.chars().nth(input.len()) != Some(' ') { + input.push(' '); + } + + let mut i: i64 = 0; + + let (tx, rx) = mpsc::sync_channel(0); + + let initial_polling_rate: u64 = 50; + let initial_scroll_left: bool = true; + + // polling thread + thread::spawn(move || { + let mut polling_rate = initial_polling_rate; + let mut scroll_left = initial_scroll_left; + let device_state = DeviceState::new(); + + loop { + // Poll for input + let keys = device_state.get_keys(); // poll the keys + (polling_rate, scroll_left) = detect_keys(keys, polling_rate, scroll_left); + let _ = tx.send((polling_rate, scroll_left)); + thread::sleep(Duration::from_millis(100)); // poll every 50 ms + } + + }); + // main thread + let mut polling_rate = initial_polling_rate; + let mut scroll_left = initial_scroll_left; + loop { + // Get data from the polling thread + match rx.try_recv() { + Ok((new_rate, new_scroll)) => { + polling_rate = new_rate; + scroll_left = new_scroll; + } + Err(mpsc::TryRecvError::Empty) => { + //eprintln!("No new data. ;("); + } + Err(mpsc::TryRecvError::Disconnected) => { + eprintln!("Channel has been closed."); + break; + } + } + thread::sleep(Duration::from_millis(polling_rate)); + + println!("i: {}, upd: {}ms, scrll: {}, {}", {i +=1; i}, polling_rate, either!(scroll_left => "L"; "R"), input); + // Scroll text + if scroll_left { + input = shift_left(input); + } else { + input = shift_right(input); + } + } +} + +fn shift_left(mut input: String) -> String { + let tmp: char = input.chars().nth(0).expect("char"); + input = input.substring(1,input.len()).to_string(); + input.push_str(&tmp.to_string()); + return input; +} + +fn shift_right(mut input: String) -> String { + let tmp: String = input.substring(0, input.len() - 1).to_string(); + input = input.chars().nth(input.len() - 1).expect("char").to_string(); + input.push_str(&tmp); + return input; +} + +fn detect_keys(keys: Vec, mut polling_rate: u64, mut scroll_left: bool) -> (u64, bool) { + //detecting keydown events + //println!("{} {} ", polling_rate, scroll_left); + if keys.is_empty() { + return (polling_rate, scroll_left); + } + if keys.contains(&Keycode::Up) { + polling_rate = increase_poll(polling_rate); + } + if keys.contains(&Keycode::Down) { + polling_rate = decrease_poll(polling_rate) + } + if keys.contains(&Keycode::Left) { + scroll_left = true; + } + if keys.contains(&Keycode::Right) { + scroll_left = false; + } + return (polling_rate, scroll_left); +} + +fn increase_poll(mut polling_rate: u64) -> u64 { + if polling_rate < 1000 { + polling_rate += 5; + } else { + eprintln!("polling rate can't go higher!"); + } + return polling_rate; +} + +fn decrease_poll(mut polling_rate: u64) -> u64 { + if polling_rate > 0 { + polling_rate -= 5; + } else { + eprintln!("polling rate can't go lower!"); + } + return polling_rate; +} \ No newline at end of file