Files: 3ec707eee442688f2cf820a4336c7e69b3703ec0 / src / interface.rs
3804 bytesRaw
1 | extern crate ncurses; |
2 | |
3 | use ncurses::{WchResult}; |
4 | use std::sync::mpsc::{channel, Sender, Receiver}; |
5 | use std::thread::{sleep, spawn}; |
6 | |
7 | use clock; |
8 | use control; |
9 | |
10 | // https://unicode.org/charts/PDF/U0000.pdf |
11 | static CHAR_SPACE: u32 = 0x0020; |
12 | static CHAR_RETURN: u32 = 0x000D; |
13 | static CHAR_NEWLINE: u32 = 0x000A; |
14 | |
15 | |
16 | pub struct TerminalInterface { |
17 | pub tx: Sender<InterfaceMessage> |
18 | } |
19 | |
20 | impl TerminalInterface { |
21 | pub fn start (signature: clock::ClockSignature, control_tx: Sender<control::ControlMessage>) -> Self { |
22 | let (tx, rx) = channel(); |
23 | |
24 | let interface = Self { |
25 | tx |
26 | }; |
27 | |
28 | spawn(move|| { |
29 | /* Setup ncurses. */ |
30 | ncurses::initscr(); |
31 | |
32 | let locale_conf = ncurses::LcCategory::all; |
33 | ncurses::setlocale(locale_conf, "en_US.UTF-8"); |
34 | |
35 | /* Enable mouse events. */ |
36 | ncurses::mousemask(ncurses::ALL_MOUSE_EVENTS as ncurses::mmask_t, None); |
37 | |
38 | /* Allow for extended keyboard (like F1). */ |
39 | ncurses::keypad(ncurses::stdscr(), true); |
40 | ncurses::noecho(); |
41 | |
42 | loop { |
43 | let ch = ncurses::wget_wch(ncurses::stdscr()); |
44 | |
45 | match ch { |
46 | Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => { |
47 | control_tx.send(control::ControlMessage::TapTempo).unwrap(); |
48 | } |
49 | |
50 | // https://github.com/jeaye/ncurses-rs/blob/master/src/constants.rs |
51 | Some(WchResult::KeyCode(_)) => {} |
52 | |
53 | // Some(WchResult::KeyCode(KEY_ENTER)) => beat(), |
54 | Some(WchResult::Char(ch)) => { |
55 | if (ch == CHAR_SPACE || ch == CHAR_NEWLINE) { |
56 | control_tx.send(control::ControlMessage::TapTempo).unwrap(); |
57 | } |
58 | } |
59 | |
60 | None => {} |
61 | } |
62 | |
63 | ncurses::refresh(); |
64 | } |
65 | |
66 | ncurses::endwin(); |
67 | }); |
68 | |
69 | spawn(move|| { |
70 | for interface_message in rx { |
71 | match interface_message { |
72 | InterfaceMessage::Time(time) => { |
73 | ncurses::clear(); |
74 | ncurses::mv(0, 0); |
75 | if time.ticks == 0 { |
76 | ncurses::printw("BEAT"); |
77 | } |
78 | ncurses::printw("\n"); |
79 | print_time(time); |
80 | print_signature(signature); |
81 | }, |
82 | InterfaceMessage::Signature(signature) => { |
83 | } |
84 | } |
85 | |
86 | ncurses::refresh(); |
87 | } |
88 | }); |
89 | |
90 | interface |
91 | } |
92 | } |
93 | |
94 | pub fn print_time (time: clock::ClockTime) { |
95 | ncurses::printw("nanos: "); |
96 | ncurses::printw(format!("{}\n", time.nanos).as_ref()); |
97 | ncurses::printw("ticks: "); |
98 | ncurses::printw(format!("{}\n", time.ticks + 1).as_ref()); |
99 | ncurses::printw("beats: "); |
100 | ncurses::printw(format!("{}\n", time.beats + 1).as_ref()); |
101 | ncurses::printw("bars: "); |
102 | ncurses::printw(format!("{}\n", time.bars + 1).as_ref()); |
103 | } |
104 | |
105 | pub fn print_signature (signature: clock::ClockSignature) { |
106 | ncurses::printw("beats per minute: "); |
107 | ncurses::printw(format!("{}\n", signature.to_beats_per_minute()).as_ref()); |
108 | ncurses::printw("ticks per beat: "); |
109 | ncurses::printw(format!("{}\n", signature.ticks_per_beat).as_ref()); |
110 | ncurses::printw("beats per bar: "); |
111 | ncurses::printw(format!("{}\n", signature.beats_per_bar).as_ref()); |
112 | ncurses::printw("bars per loop: "); |
113 | ncurses::printw(format!("{}\n", signature.bars_per_loop).as_ref()); |
114 | } |
115 | |
116 | |
117 | pub enum InterfaceMessage { |
118 | Time(clock::ClockTime), |
119 | Signature(clock::ClockSignature), |
120 | } |
121 |
Built with git-ssb-web