add a command to jump to an arbitrary time
[nihav-player.git] / sndplay / src / command.rs
index 802908b2de0e0ec818c8eed2e8bed4c9dfd662cd..3f5ecdeb3cdebbb48161c268da4eb2b1df4740a2 100644 (file)
@@ -1,7 +1,8 @@
 use libc::{termios, tcgetattr, tcsetattr};
 use std::sync::mpsc;
-use std::io::Read;
+use std::io::{Read, BufRead};
 use std::thread;
+use nihav_core::frame::NATimePoint;
 
 #[derive(Clone,Copy,Debug,PartialEq)]
 pub enum Command {
@@ -12,8 +13,11 @@ pub enum Command {
     Pause,
     Back(u8),
     Forward(u8),
+    Seek(u64),
     Repeat,
     Next,
+    PauseDisplay,
+    ResumeDisplay,
     Quit,
 }
 
@@ -29,6 +33,14 @@ impl CmdLineState {
         unsafe { tcsetattr(0, 0, &new_state); }
         Self { orig_state }
     }
+    pub fn new_normal() -> Self {
+        let mut orig_state: termios = unsafe { std::mem::uninitialized() };
+        unsafe { tcgetattr(0, &mut orig_state); }
+        let mut new_state = orig_state;
+        new_state.c_lflag |= libc::ECHO | libc::ICANON;
+        unsafe { tcsetattr(0, 0, &new_state); }
+        Self { orig_state }
+    }
     pub fn restore(&self) {
         unsafe { tcsetattr(0, 0, &self.orig_state); }
     }
@@ -60,6 +72,26 @@ pub fn start_reader() -> (thread::JoinHandle<()>, mpsc::Receiver<Command>) {
                         b'-' => { sender.send(Command::VolumeDown).unwrap(); },
                         b'd' | b'D' => { sender.send(Command::Debug).unwrap(); },
                         b'm' | b'M' => { sender.send(Command::Mute).unwrap(); },
+                        b'j' | b'J' => {
+                            sender.send(Command::PauseDisplay).unwrap();
+                            let cstate = CmdLineState::new_normal();
+                            // wait so that the main thread stops displaying
+                            thread::sleep(std::time::Duration::from_millis(500));
+                            print!("\nJump to: ");
+                            let mut str = String::new();
+                            let ret = file.read_line(&mut str);
+                            cstate.restore();
+                            sender.send(Command::ResumeDisplay).unwrap();
+
+                            if ret.is_ok() && str.len() > 1 {
+                                str.pop(); // newline
+                                if let Ok(NATimePoint::Milliseconds(time)) = str.parse::<NATimePoint>() {
+                                    sender.send(Command::Seek(time)).unwrap();
+                                } else {
+                                    println!("wrong time");
+                                }
+                            }
+                        },
                         _ => {},
                     };
                 },
@@ -98,4 +130,4 @@ pub fn start_reader() -> (thread::JoinHandle<()>, mpsc::Receiver<Command>) {
             }
         }
     }), cmd_receiver)
-}
\ No newline at end of file
+}