r_matrix/
config.rs

1use pancurses::*;
2
3use structopt::StructOpt;
4
5#[derive(Debug, StructOpt)]
6#[structopt(
7    name = "rmatrix",
8    about = "Shows a scrolling 'Matrix' like screen in linux"
9)]
10/// The struct for handling command line arguments
11struct Opt {
12    #[structopt(short = "b", parse(from_occurrences))]
13    /// Bold characters on
14    bold: isize,
15
16    #[structopt(short = "l", long = "console")]
17    /// Linux mode (use matrix console font)
18    console: bool,
19
20    #[structopt(short = "o", long = "oldstyle")]
21    /// Use old-style scrolling
22    oldstyle: bool,
23
24    #[structopt(short = "s", long = "screensaver")]
25    /// "Screensaver" mode, exits on first keystroke
26    screensaver: bool,
27
28    #[structopt(short = "x", long = "xwindow")]
29    /// X window mode, use if your xterm is using mtx.pcf
30    xwindow: bool,
31
32    #[structopt(
33        short = "u",
34        long = "update",
35        default_value = "4",
36        parse(try_from_str = validate_update)
37    )]
38    /// Screen update delay
39    update: usize,
40
41    #[structopt(
42        short = "C",
43        long = "colour",
44        default_value = "green",
45        possible_values = &["green", "red", "blue", "white", "yellow", "cyan", "magenta", "black"]
46    )]
47    colour: String,
48
49    #[structopt(short = "r", long = "rainbow")]
50    /// Rainbow mode
51    rainbow: bool,
52}
53
54fn validate_update(n: &str) -> Result<usize, &'static str> {
55    if let Ok(n) = n.parse::<usize>() {
56        if n <= 10 {
57            return Ok(n);
58        }
59    }
60    Err("must be a number between 1 and 10")
61}
62
63/// The global state object
64pub struct Config {
65    pub bold: isize,
66    pub console: bool,
67    pub oldstyle: bool,
68    pub screensaver: bool,
69    pub xwindow: bool,
70    pub update: usize,
71    pub colour: i16,
72    pub rainbow: bool,
73    pub pause: bool,
74}
75
76impl Default for Config {
77    /// Get the new config object based on command line arguments
78    fn default() -> Self {
79        let opt = Opt::from_args();
80
81        let colour = match opt.colour.as_ref() {
82            "green" => COLOR_GREEN,
83            "red" => COLOR_RED,
84            "blue" => COLOR_BLUE,
85            "white" => COLOR_WHITE,
86            "yellow" => COLOR_YELLOW,
87            "cyan" => COLOR_CYAN,
88            "magenta" => COLOR_MAGENTA,
89            "black" => COLOR_BLACK,
90            _ => unreachable!(),
91        };
92
93        Config {
94            bold: opt.bold,
95            console: opt.console,
96            oldstyle: opt.oldstyle,
97            screensaver: opt.screensaver,
98            xwindow: opt.xwindow,
99            update: opt.update,
100            rainbow: opt.rainbow,
101            colour,
102            pause: false,
103        }
104    }
105}
106
107impl Config {
108    /// Update the config based on any keypresses
109    pub fn handle_keypress(&mut self, keypress: char) {
110        // Exit if in screensaver mode
111        if self.screensaver {
112            super::finish();
113        }
114
115        match keypress {
116            'q' => super::finish(),
117            'b' => self.bold = 1,
118            'B' => self.bold = 2,
119            'n' => self.bold = 0,
120            '!' => {
121                self.colour = COLOR_RED;
122                self.rainbow = false;
123            }
124            '@' => {
125                self.colour = COLOR_GREEN;
126                self.rainbow = false;
127            }
128            '#' => {
129                self.colour = COLOR_YELLOW;
130                self.rainbow = false;
131            }
132            '$' => {
133                self.colour = COLOR_BLUE;
134                self.rainbow = false;
135            }
136            '%' => {
137                self.colour = COLOR_MAGENTA;
138                self.rainbow = false;
139            }
140            'r' => {
141                self.rainbow = true;
142            }
143            '^' => {
144                self.colour = COLOR_CYAN;
145                self.rainbow = false;
146            }
147            '&' => {
148                self.colour = COLOR_WHITE;
149                self.rainbow = false;
150            }
151            'p' | 'P' => self.pause = !self.pause,
152            '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '0' => {
153                self.update = keypress as usize - 48 // Sneaky way to avoid parsing
154            }
155            _ => {}
156        }
157    }
158}