Files: f675cb27f2640ba304b1816b279b2ef7f8c19a59 / src / interface.rs
4077 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 | print_beat(time); |
76 | print_bar(time); |
77 | print_time(time); |
78 | print_signature(signature); |
79 | }, |
80 | InterfaceMessage::Signature(signature) => { |
81 | } |
82 | } |
83 | |
84 | ncurses::refresh(); |
85 | } |
86 | }); |
87 | |
88 | interface |
89 | } |
90 | } |
91 | |
92 | pub fn print_beat (time: clock::ClockTime) { |
93 | if time.ticks == 0 { |
94 | if time.beats == 0 { |
95 | ncurses::printw("SUPER "); |
96 | } |
97 | ncurses::printw("BEAT"); |
98 | } |
99 | ncurses::printw("\n"); |
100 | } |
101 | |
102 | pub fn print_bar (time: clock::ClockTime) { |
103 | if time.bars == 0 { |
104 | ncurses::printw("YAY YAY YAY"); |
105 | } |
106 | ncurses::printw("\n"); |
107 | } |
108 | |
109 | pub fn print_time (time: clock::ClockTime) { |
110 | ncurses::printw("nanos: "); |
111 | ncurses::printw(format!("{}\n", time.nanos).as_ref()); |
112 | ncurses::printw("ticks: "); |
113 | ncurses::printw(format!("{}\n", time.ticks + 1).as_ref()); |
114 | ncurses::printw("beats: "); |
115 | ncurses::printw(format!("{}\n", time.beats + 1).as_ref()); |
116 | ncurses::printw("bars: "); |
117 | ncurses::printw(format!("{}\n", time.bars + 1).as_ref()); |
118 | } |
119 | |
120 | pub fn print_signature (signature: clock::ClockSignature) { |
121 | ncurses::printw("beats per minute: "); |
122 | ncurses::printw(format!("{}\n", signature.to_beats_per_minute()).as_ref()); |
123 | ncurses::printw("ticks per beat: "); |
124 | ncurses::printw(format!("{}\n", signature.ticks_per_beat).as_ref()); |
125 | ncurses::printw("beats per bar: "); |
126 | ncurses::printw(format!("{}\n", signature.beats_per_bar).as_ref()); |
127 | ncurses::printw("bars per loop: "); |
128 | ncurses::printw(format!("{}\n", signature.bars_per_loop).as_ref()); |
129 | } |
130 | |
131 | |
132 | pub enum InterfaceMessage { |
133 | Time(clock::ClockTime), |
134 | Signature(clock::ClockSignature), |
135 | } |
136 |
Built with git-ssb-web